diff --git a/package.json b/package.json index 511b3d696..28fd24dfb 100644 --- a/package.json +++ b/package.json @@ -88,7 +88,7 @@ "lodash.isequal": "^4.5.0", "moment-mini": "^2.22.1", "rxjs": "^6.3.3", - "slickgrid": "2.4.9", + "slickgrid": "^2.4.11", "text-encoding-utf-8": "^1.0.2", "tslib": "^1.9.3", "vinyl-paths": "^2.1.0" diff --git a/src/app/examples/grid-menu.component.html b/src/app/examples/grid-menu.component.html index a94a555d7..da5fbef28 100644 --- a/src/app/examples/grid-menu.component.html +++ b/src/app/examples/grid-menu.component.html @@ -1,22 +1,27 @@
-

{{title}}

-
+

{{title}}

+
- - + + -
- - -
+
+ + +
diff --git a/src/app/examples/grid-menu.component.ts b/src/app/examples/grid-menu.component.ts index a45cc0b2b..9bb1ed2a8 100644 --- a/src/app/examples/grid-menu.component.ts +++ b/src/app/examples/grid-menu.component.ts @@ -35,16 +35,6 @@ export class GridMenuComponent implements OnInit { ngOnInit(): void { this.columnDefinitions = [ { id: 'title', name: 'Title', field: 'title', headerKey: 'TITLE', filterable: true, type: FieldType.string }, - { - id: 'phone', name: 'Phone Number using mask', field: 'phone', - filterable: true, sortable: true, minWidth: 100, - type: FieldType.string, // because we use a mask filter, we should always assume the value is a string for it to behave correctly - formatter: Formatters.mask, params: { mask: '(000) 000-0000' }, - filter: { - model: Filters.inputMask, - operator: OperatorType.startsWith - } - }, { id: 'duration', name: 'Duration', field: 'duration', headerKey: 'DURATION', sortable: true, filterable: true, type: FieldType.string }, { id: '%', name: '% Complete', field: 'percentComplete', sortable: true, filterable: true, diff --git a/src/app/examples/grid-odata.component.html b/src/app/examples/grid-odata.component.html index 59f542aeb..c37d3bc2b 100644 --- a/src/app/examples/grid-odata.component.html +++ b/src/app/examples/grid-odata.component.html @@ -1,31 +1,35 @@

{{title}}

-
+
-
+
Status: {{status.text}}
- Statistics: {{statistics.endTime | date: 'yyyy-MM-dd HH:mm aaaaa\'m\''}} | {{statistics.executionTime}}ms | {{statistics.totalItemCount}} items - + Statistics: {{statistics.endTime | date: 'yyyy-MM-dd HH:mm aaaaa\'m\''}} | {{statistics.executionTime}}ms + | {{statistics.totalItemCount}} items +
-
- OData Query: {{odataQuery}} +
+ OData Query: {{odataQuery}}
- +
- diff --git a/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts b/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts index 895b3f090..415ff8b5b 100644 --- a/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts +++ b/src/app/modules/angular-slickgrid/extensions/__tests__/columnPickerExtension.spec.ts @@ -16,6 +16,7 @@ const gridStub = { const mockAddon = jest.fn().mockImplementation(() => ({ init: jest.fn(), destroy: jest.fn(), + updateAllTitles: jest.fn(), onColumnsChanged: new Slick.Event(), })); @@ -63,6 +64,7 @@ describe('columnPickerExtension', () => { jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock); jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(columnsMock); + jest.spyOn(SharedService.prototype, 'visibleColumns', 'get').mockReturnValue(columnsMock.slice(0, 1)); jest.spyOn(SharedService.prototype, 'columnDefinitions', 'get').mockReturnValue(columnsMock); }); @@ -81,18 +83,38 @@ describe('columnPickerExtension', () => { it('should call internal event handler subscribe and expect the "onColumnSpy" option to be called when addon notify is called', () => { const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker, 'onColumnsChanged'); + const visibleColsSpy = jest.spyOn(SharedService.prototype, 'visibleColumns', 'set'); const instance = extension.register(); - instance.onColumnsChanged.notify(columnsMock.slice(0, 1), new Slick.EventData(), gridStub); + instance.onColumnsChanged.notify({ columns: columnsMock.slice(0, 1), grid: gridStub }, new Slick.EventData(), gridStub); expect(handlerSpy).toHaveBeenCalledTimes(1); expect(handlerSpy).toHaveBeenCalledWith( { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), }, expect.anything() ); - expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), columnsMock.slice(0, 1)); + expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), { columns: columnsMock.slice(0, 1), grid: gridStub }); + expect(visibleColsSpy).not.toHaveBeenCalled(); }); + it(`should call internal event handler subscribe and expect the "onColumnSpy" option to be called when addon notify is called + and it should override "visibleColumns" when array passed as arguments is bigger than previous visible columns`, () => { + const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); + const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.columnPicker, 'onColumnsChanged'); + const visibleColsSpy = jest.spyOn(SharedService.prototype, 'visibleColumns', 'set'); + + const instance = extension.register(); + instance.onColumnsChanged.notify({ columns: columnsMock, grid: gridStub }, new Slick.EventData(), gridStub); + + expect(handlerSpy).toHaveBeenCalledTimes(1); + expect(handlerSpy).toHaveBeenCalledWith( + { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), }, + expect.anything() + ); + expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), { columns: columnsMock, grid: gridStub }); + expect(visibleColsSpy).toHaveBeenCalledWith(columnsMock); + }); + it('should dispose of the addon', () => { const instance = extension.register(); const destroySpy = jest.spyOn(instance, 'destroy'); @@ -110,11 +132,11 @@ describe('columnPickerExtension', () => { const instance = extension.register(); extension.translateColumnPicker(); - const initSpy = jest.spyOn(instance, 'init'); + const updateColsSpy = jest.spyOn(instance, 'updateAllTitles'); expect(utilitySpy).toHaveBeenCalled(); expect(translateSpy).toHaveBeenCalled(); - expect(initSpy).toHaveBeenCalledWith(gridStub); + expect(updateColsSpy).toHaveBeenCalledWith(SharedService.prototype.gridOptions.columnPicker); expect(SharedService.prototype.gridOptions.columnPicker.columnTitle).toBe('Colonnes'); expect(SharedService.prototype.gridOptions.columnPicker.forceFitTitle).toBe('Ajustement forcé des colonnes'); expect(SharedService.prototype.gridOptions.columnPicker.syncResizeTitle).toBe('Redimension synchrone'); diff --git a/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts b/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts index 7b9f30b70..02ee67fe5 100644 --- a/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts +++ b/src/app/modules/angular-slickgrid/extensions/__tests__/gridMenuExtension.spec.ts @@ -45,6 +45,7 @@ const mockAddon = jest.fn().mockImplementation(() => ({ init: jest.fn(), destroy: jest.fn(), showGridMenu: jest.fn(), + updateAllTitles: jest.fn(), onColumnsChanged: new Slick.Event(), onCommand: new Slick.Event(), onBeforeMenuShow: new Slick.Event(), @@ -155,7 +156,7 @@ describe('gridMenuExtension', () => { jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock); jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(columnsMock); - jest.spyOn(SharedService.prototype, 'visibleColumns', 'get').mockReturnValue(columnsMock); + jest.spyOn(SharedService.prototype, 'visibleColumns', 'get').mockReturnValue(columnsMock.slice(0, 1)); jest.spyOn(SharedService.prototype, 'columnDefinitions', 'get').mockReturnValue(columnsMock); }); @@ -177,20 +178,46 @@ describe('gridMenuExtension', () => { const onBeforeSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onBeforeMenuShow'); const onCloseSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onMenuClose'); const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand'); + const visibleColsSpy = jest.spyOn(SharedService.prototype, 'visibleColumns', 'set'); const instance = extension.register(); - instance.onColumnsChanged.notify(columnsMock.slice(0, 1), new Slick.EventData(), gridStub); + instance.onColumnsChanged.notify({ columns: columnsMock.slice(0, 1), grid: gridStub }, new Slick.EventData(), gridStub); expect(handlerSpy).toHaveBeenCalledTimes(4); expect(handlerSpy).toHaveBeenCalledWith( { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), }, expect.anything() ); - expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), columnsMock.slice(0, 1)); + expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), { columns: columnsMock.slice(0, 1), grid: gridStub }); expect(onBeforeSpy).not.toHaveBeenCalled(); expect(onCloseSpy).not.toHaveBeenCalled(); expect(onCommandSpy).not.toHaveBeenCalled(); - }); + expect(visibleColsSpy).not.toHaveBeenCalled(); + }); + + it(`should call internal event handler subscribe and expect the "onColumnsChanged" option to be called + and it should override "visibleColumns" when array passed as arguments is bigger than previous visible columns`, () => { + const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); + const onColumnSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onColumnsChanged'); + const onBeforeSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onBeforeMenuShow'); + const onCloseSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onMenuClose'); + const onCommandSpy = jest.spyOn(SharedService.prototype.gridOptions.gridMenu, 'onCommand'); + const visibleColsSpy = jest.spyOn(SharedService.prototype, 'visibleColumns', 'set'); + + const instance = extension.register(); + instance.onColumnsChanged.notify({ columns: columnsMock, grid: gridStub }, new Slick.EventData(), gridStub); + + expect(handlerSpy).toHaveBeenCalledTimes(4); + expect(handlerSpy).toHaveBeenCalledWith( + { notify: expect.anything(), subscribe: expect.anything(), unsubscribe: expect.anything(), }, + expect.anything() + ); + expect(onColumnSpy).toHaveBeenCalledWith(expect.anything(), { columns: columnsMock, grid: gridStub }); + expect(onBeforeSpy).not.toHaveBeenCalled(); + expect(onCloseSpy).not.toHaveBeenCalled(); + expect(onCommandSpy).not.toHaveBeenCalled(); + expect(visibleColsSpy).toHaveBeenCalledWith(columnsMock); + }); it('should call internal event handler subscribe and expect the "onBeforeMenuShow" option to be called when addon notify is called', () => { const handlerSpy = jest.spyOn(extension.eventHandler, 'subscribe'); @@ -622,11 +649,11 @@ describe('gridMenuExtension', () => { const instance = extension.register(); extension.translateGridMenu(); - const initSpy = jest.spyOn(instance, 'init'); + const updateColsSpy = jest.spyOn(instance, 'updateAllTitles'); expect(utilitySpy).toHaveBeenCalled(); expect(translateSpy).toHaveBeenCalled(); - expect(initSpy).toHaveBeenCalledWith(gridStub); + expect(updateColsSpy).toHaveBeenCalledWith(SharedService.prototype.gridOptions.gridMenu); expect(SharedService.prototype.gridOptions.gridMenu.columnTitle).toBe('Colonnes'); expect(SharedService.prototype.gridOptions.gridMenu.forceFitTitle).toBe('Ajustement forcé des colonnes'); expect(SharedService.prototype.gridOptions.gridMenu.syncResizeTitle).toBe('Redimension synchrone'); diff --git a/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts b/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts index de3e4dc93..39a9978f1 100644 --- a/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts +++ b/src/app/modules/angular-slickgrid/extensions/columnPickerExtension.ts @@ -52,10 +52,13 @@ export class ColumnPickerExtension implements Extension { if (this.sharedService.gridOptions.columnPicker.onExtensionRegistered) { this.sharedService.gridOptions.columnPicker.onExtensionRegistered(this._addon); } - this._eventHandler.subscribe(this._addon.onColumnsChanged, (e: any, args: CellArgs) => { + this._eventHandler.subscribe(this._addon.onColumnsChanged, (e: any, args: { columns: any, grid: any }) => { if (this.sharedService.gridOptions.columnPicker && typeof this.sharedService.gridOptions.columnPicker.onColumnsChanged === 'function') { this.sharedService.gridOptions.columnPicker.onColumnsChanged(e, args); } + if (args && Array.isArray(args.columns) && args.columns.length > this.sharedService.visibleColumns.length) { + this.sharedService.visibleColumns = args.columns; + } }); } return this._addon; @@ -77,11 +80,8 @@ export class ColumnPickerExtension implements Extension { // translate all columns (including hidden columns) this.extensionUtility.translateItems(this.sharedService.allColumns, 'headerKey', 'name'); - // re-initialize the Column Picker, that will recreate all the list - // doing an "init()" won't drop any existing command attached - if (this._addon.init) { - this._addon.init(this.sharedService.grid); - } + // update the Titles of each sections (command, customTitle, ...) + this._addon.updateAllTitles(this.sharedService.gridOptions.columnPicker); } } diff --git a/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts b/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts index a5827119a..8f7fe2ac2 100644 --- a/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts +++ b/src/app/modules/angular-slickgrid/extensions/gridMenuExtension.ts @@ -91,11 +91,14 @@ export class GridMenuExtension implements Extension { this.sharedService.gridOptions.gridMenu.onBeforeMenuShow(e, args); } }); - this._eventHandler.subscribe(this._addon.onColumnsChanged, (e: any, args: CellArgs) => { + this._eventHandler.subscribe(this._addon.onColumnsChanged, (e: any, args: { columns: any, grid: any }) => { this._areVisibleColumnDifferent = true; if (this.sharedService.gridOptions.gridMenu && typeof this.sharedService.gridOptions.gridMenu.onColumnsChanged === 'function') { this.sharedService.gridOptions.gridMenu.onColumnsChanged(e, args); } + if (args && Array.isArray(args.columns) && args.columns.length > this.sharedService.visibleColumns.length) { + this.sharedService.visibleColumns = args.columns; + } }); this._eventHandler.subscribe(this._addon.onCommand, (e: any, args: any) => { this.executeGridMenuInternalCustomCommands(e, args); @@ -206,11 +209,8 @@ export class GridMenuExtension implements Extension { // translate all columns (including non-visible) this.extensionUtility.translateItems(this.sharedService.allColumns, 'headerKey', 'name'); - // re-initialize the Grid Menu, that will recreate all the menus & list - // doing an "init()" won't drop any existing command attached - if (this._addon.init) { - this._addon.init(this.sharedService.grid); - } + // update the Titles of each sections (command, customTitle, ...) + this._addon.updateAllTitles(this.sharedService.gridOptions.gridMenu); } } diff --git a/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts b/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts index 08cda0e4b..0fa3e2451 100644 --- a/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts +++ b/src/app/modules/angular-slickgrid/services/__tests__/extension.service.spec.ts @@ -537,6 +537,11 @@ describe('ExtensionService', () => { }); describe('renderColumnHeaders method', () => { + beforeEach(() => { + const columnsMock = [{ id: 'field1', field: 'field1', headerKey: 'HELLO' }] as Column[]; + jest.spyOn(SharedService.prototype, 'allColumns', 'get').mockReturnValue(columnsMock); + }); + it('should call "setColumns" on the Shared Service with the Shared "columnDefinitions" when no arguments is provided', () => { const columnsMock = [{ id: 'field1', field: 'field1', headerKey: 'HELLO' }] as Column[]; jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); @@ -549,21 +554,42 @@ describe('ExtensionService', () => { expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); }); - it('should call "setColumns" on the Shared Service with the collection provided as argument', () => { - const columnsMock = [{ id: 'field1', field: 'field1', headerKey: 'HELLO' }] as Column[]; + it('should override "allColumns" on the Shared Service and call "setColumns" with the collection provided as argument', () => { + const columnsMock = [ + { id: 'field1', field: 'field1', headerKey: 'HELLO' }, + { id: 'field2', field: 'field2', headerKey: 'WORLD' } + ] as Column[]; jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); - const spyAllCols = jest.spyOn(SharedService.prototype, 'allColumns', 'set'); + const allColsSpy = jest.spyOn(SharedService.prototype, 'allColumns', 'set'); const setColumnsSpy = jest.spyOn(gridStub, 'setColumns'); service.renderColumnHeaders(columnsMock); - expect(spyAllCols).toHaveBeenCalledWith(columnsMock); expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); + expect(allColsSpy).toHaveBeenCalledWith(columnsMock); }); + it(`should call "setColumns" with the collection provided as argument but NOT override "allColumns" on the Shared Service + when collection provided is smaller than "allColumns" that already exists`, () => { + const columnsMock = [ + { id: 'field1', field: 'field1', headerKey: 'HELLO' } + ] as Column[]; + jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); + const spyAllCols = jest.spyOn(SharedService.prototype, 'allColumns', 'set'); + const setColumnsSpy = jest.spyOn(gridStub, 'setColumns'); + + service.renderColumnHeaders(columnsMock); + + expect(setColumnsSpy).toHaveBeenCalledWith(columnsMock); + expect(spyAllCols).not.toHaveBeenCalled(); + }); + it('should re-register the Column Picker when enable and method is called with new column definition collection provided as argument', () => { const gridOptionsMock = { enableColumnPicker: true } as GridOption; - const columnsMock = [{ id: 'field1', field: 'field1', headerKey: 'HELLO' }] as Column[]; + const columnsMock = [ + { id: 'field1', field: 'field1', headerKey: 'HELLO' }, + { id: 'field2', field: 'field2', headerKey: 'WORLD' } + ] as Column[]; jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock); jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); const spyCpDispose = jest.spyOn(extensionColumnPickerStub, 'dispose'); @@ -581,7 +607,10 @@ describe('ExtensionService', () => { it('should re-register the Grid Menu when enable and method is called with new column definition collection provided as argument', () => { const gridOptionsMock = { enableGridMenu: true } as GridOption; - const columnsMock = [{ id: 'field1', field: 'field1', headerKey: 'HELLO' }] as Column[]; + const columnsMock = [ + { id: 'field1', field: 'field1', headerKey: 'HELLO' }, + { id: 'field2', field: 'field2', headerKey: 'WORLD' } + ] as Column[]; jest.spyOn(SharedService.prototype, 'gridOptions', 'get').mockReturnValue(gridOptionsMock); jest.spyOn(SharedService.prototype, 'grid', 'get').mockReturnValue(gridStub); const spyGmDispose = jest.spyOn(extensionGridMenuStub, 'dispose'); diff --git a/src/app/modules/angular-slickgrid/services/extension.service.ts b/src/app/modules/angular-slickgrid/services/extension.service.ts index f58f8fdc0..e51bcdeb2 100644 --- a/src/app/modules/angular-slickgrid/services/extension.service.ts +++ b/src/app/modules/angular-slickgrid/services/extension.service.ts @@ -350,8 +350,12 @@ export class ExtensionService { collection = this.sharedService.columnDefinitions; } if (Array.isArray(collection) && this.sharedService.grid && this.sharedService.grid.setColumns) { - this.sharedService.allColumns = collection; - this.sharedService.grid.setColumns(collection); + if (collection.length > this.sharedService.allColumns.length) { + this.sharedService.allColumns = collection; + this.sharedService.grid.setColumns(collection); + } else { + this.sharedService.grid.setColumns(this.sharedService.allColumns); + } } if (this.sharedService.gridOptions.enableColumnPicker) { diff --git a/src/app/modules/angular-slickgrid/services/grid.service.ts b/src/app/modules/angular-slickgrid/services/grid.service.ts index 2821f69ed..9d50f63a1 100644 --- a/src/app/modules/angular-slickgrid/services/grid.service.ts +++ b/src/app/modules/angular-slickgrid/services/grid.service.ts @@ -1,5 +1,13 @@ import { Injectable } from '@angular/core'; -import { CellArgs, Column, GridOption, GridServiceDeleteOption, GridServiceInsertOption, GridServiceUpdateOption, OnEventArgs } from './../models/index'; +import { + CellArgs, + Column, + GridOption, + GridServiceDeleteOption, + GridServiceInsertOption, + GridServiceUpdateOption, + OnEventArgs +} from './../models/index'; import { ExtensionService } from './extension.service'; import { FilterService } from './filter.service'; import { GridStateService } from './gridState.service'; diff --git a/test/cypress/integration/example1.spec.js b/test/cypress/integration/example1.spec.js index 3f70068de..f6fc12ec7 100644 --- a/test/cypress/integration/example1.spec.js +++ b/test/cypress/integration/example1.spec.js @@ -20,13 +20,11 @@ describe('Example 1 - Basic Grids', () => { .should('have.css', 'height', '300px'); }); - it('should have exact Titles on 1st grid', () => { + it('should have exact column titles on 1st grid', () => { cy.get('#slickGridContainer-grid1') .find('.slick-header-columns') .children() - .each(($child, index) => { - expect($child.text()).to.eq(titles[index]); - }); + .each(($child, index) => expect($child.text()).to.eq(titles[index])); }); it('should hover over the Title column and click on "Sort Descending" command', () => { @@ -42,6 +40,8 @@ describe('Example 1 - Basic Grids', () => { cy.get('.slick-header-menu') .should('be.visible') .children('.slick-header-menuitem:nth-child(2)') + .children('.slick-header-menucontent') + .should('contain', 'Sort Descending') .click(); cy.get('.slick-row') @@ -62,10 +62,11 @@ describe('Example 1 - Basic Grids', () => { .invoke('show') .click(); - cy.get('#grid2') - .find('.slick-header-menu') + cy.get('.slick-header-menu') .should('be.visible') .children('.slick-header-menuitem:nth-child(1)') + .children('.slick-header-menucontent') + .should('contain', 'Sort Ascending') .click(); cy.get('#grid2') diff --git a/test/cypress/integration/example5.spec.js b/test/cypress/integration/example5.spec.js new file mode 100644 index 000000000..001dfc1de --- /dev/null +++ b/test/cypress/integration/example5.spec.js @@ -0,0 +1,98 @@ +describe('Example 5 - OData Grid', () => { + it('should display Example 5 title', () => { + cy.visit(`${Cypress.config('baseExampleUrl')}/odata`); + cy.get('h2').should('contain', 'Example 5: Grid connected to Backend Server with OData'); + }); + + it('should have default OData query', () => { + cy.get('[data-test=alert-odata-query]').should('exist'); + cy.get('[data-test=alert-odata-query]').should('contain', 'OData Query'); + + // wait for the query to finish + cy.get('[data-test=status]').should('contain', 'done'); + + cy.get('[data-test=odata-query-result]') + .should(($span) => { + expect($span.text()).to.eq(`$top=20&$skip=20&$orderby=Name asc&$filter=(Gender eq 'male')`); + }); + }); + + it('should change Pagination to next page', () => { + cy.get('.icon-seek-next').click(); + + // wait for the query to finish + cy.get('[data-test=status]').should('contain', 'done'); + + cy.get('[data-test=odata-query-result]') + .should(($span) => { + expect($span.text()).to.eq(`$top=20&$skip=40&$orderby=Name asc&$filter=(Gender eq 'male')`); + }); + }); + + it('should change Pagination to first page with 10 items', () => { + cy.get('#items-per-page-label').select('10'); + + // wait for the query to finish + cy.get('[data-test=status]').should('contain', 'done'); + + cy.get('[data-test=odata-query-result]') + .should(($span) => { + expect($span.text()).to.eq(`$top=10&$orderby=Name asc&$filter=(Gender eq 'male')`); + }); + }); + + it('should change Pagination to last page', () => { + cy.get('.icon-seek-end').click(); + + // wait for the query to finish + cy.get('[data-test=status]').should('contain', 'done'); + + cy.get('[data-test=odata-query-result]') + .should(($span) => { + expect($span.text()).to.eq(`$top=10&$skip=40&$orderby=Name asc&$filter=(Gender eq 'male')`); + }); + }); + + it('should clear all Filters', () => { + cy.get('#grid5') + .find('button.slick-gridmenu-button') + .trigger('click') + .click(); + + cy.get(`.slick-gridmenu:visible`) + .find('.slick-gridmenu-item') + .first() + .find('span') + .contains('Clear All Filters') + .click(); + + // wait for the query to finish + cy.get('[data-test=status]').should('contain', 'done'); + + cy.get('[data-test=odata-query-result]') + .should(($span) => { + expect($span.text()).to.eq(`$top=10&$orderby=Name asc`); + }); + }); + + it('should clear all Sorting', () => { + cy.get('#grid5') + .find('button.slick-gridmenu-button') + .trigger('click') + .click(); + + cy.get(`.slick-gridmenu:visible`) + .find('.slick-gridmenu-item:nth(1)') + .find('span') + .contains('Clear All Sorting') + .click(); + + // wait for the query to finish + cy.get('[data-test=status]').should('contain', 'done'); + + cy.get('[data-test=odata-query-result]') + .should(($span) => { + expect($span.text()).to.eq(`$top=10`); + }); + }); +}); diff --git a/test/cypress/integration/example9.spec.js b/test/cypress/integration/example9.spec.js new file mode 100644 index 000000000..1d57b83d7 --- /dev/null +++ b/test/cypress/integration/example9.spec.js @@ -0,0 +1,217 @@ +describe('Example 9 - Grid Menu', () => { + const fullEnglishTitles = ['Title', 'Duration', '% Complete', 'Start', 'Finish', 'Completed']; + const fullFrenchTitles = ['Titre', 'Durée', '% Complete', 'Début', 'Fin', 'Terminé']; + + describe('use English locale', () => { + + it('should display Example 9 title', () => { + cy.visit(`${Cypress.config('baseExampleUrl')}/gridmenu`); + cy.get('h2').should('contain', 'Example 9: Grid Menu Control'); + }); + + it('should have exact Column Titles in the grid', () => { + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(fullEnglishTitles[index])); + }); + + it('should hover over the Title column and click on "Hide Column" command and remove 1st column from grid', () => { + cy.get('#grid9') + .find('.slick-header-column') + .first() + .trigger('mouseover') + .children('.slick-header-menubutton') + .should('be.hidden') + .invoke('show') + .click(); + + cy.get('.slick-header-menu') + .should('be.visible') + .children('.slick-header-menuitem:nth-child(2)') + .children('.slick-header-menucontent') + .should('contain', 'Hide Column') + .click(); + + const smallerTitleList = fullEnglishTitles.slice(1); + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(smallerTitleList[index])); + }); + + it('should click on the Grid Menu to show the Title as 1st column again', () => { + cy.get('#grid9') + .find('button.slick-gridmenu-button') + .trigger('click') + .click(); + + cy.get('#grid9') + .get('.slick-gridmenu:visible') + .find('.slick-gridmenu-list') + .children('li:nth-child(1)') + .children('label') + .should('contain', 'Title') + .click(); + + cy.get('#grid9') + .get('.slick-gridmenu:visible') + .find('span.close') + .trigger('click') + .click(); + + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(fullEnglishTitles[index])); + }); + + it('should hover over the Title column and click on "Hide Column" command and remove 1st column from grid', () => { + cy.get('#grid9') + .find('.slick-header-column') + .first() + .trigger('mouseover') + .children('.slick-header-menubutton') + .should('be.hidden') + .invoke('show') + .click(); + + cy.get('.slick-header-menu') + .should('be.visible') + .children('.slick-header-menuitem:nth-child(2)') + .children('.slick-header-menucontent') + .should('contain', 'Hide Column') + .click(); + + const smallerTitleList = fullEnglishTitles.slice(1); + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(smallerTitleList[index])); + }); + + it('should click on the External Grid Menu to show the Title as 1st column again', () => { + cy.get('[data-test=external-gridmenu]') + .trigger('click') + .click(); + + cy.get('#grid9') + .get('.slick-gridmenu:visible') + .find('.slick-gridmenu-list') + .children('li:nth-child(1)') + .children('label') + .should('contain', 'Title') + .click(); + + cy.get('#grid9') + .get('.slick-gridmenu:visible') + .find('span.close') + .trigger('click') + .click(); + + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(fullEnglishTitles[index])); + }); + }); + + describe('switch to French language', () => { + it('should switch locale to French and have column header titles in French', () => { + cy.get('[data-test=language]') + .click(); + + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(fullFrenchTitles[index])); + }); + + it('should hover over the Title column and click on "Cacher la colonne" command and remove 1st column from grid', () => { + cy.get('#grid9') + .find('.slick-header-column') + .first() + .trigger('mouseover') + .children('.slick-header-menubutton') + .should('be.hidden') + .invoke('show') + .click(); + + cy.get('.slick-header-menu') + .should('be.visible') + .children('.slick-header-menuitem:nth-child(2)') + .children('.slick-header-menucontent') + .should('contain', 'Cacher la colonne') + .click(); + + const smallerTitleList = fullFrenchTitles.slice(1); + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(smallerTitleList[index])); + }); + + it('should click on the Grid Menu to show the Title as 1st column again', () => { + cy.get('#grid9') + .find('button.slick-gridmenu-button') + .trigger('click') + .click(); + + cy.get('#grid9') + .get('.slick-gridmenu:visible') + .find('.slick-gridmenu-list') + .children('li:nth-child(1)') + .children('label') + .should('contain', 'Titre') + .click(); + + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(fullFrenchTitles[index])); + }); + + it('should hover over the Title column and click on "Hide Column" command and remove 1st column from grid', () => { + cy.get('#grid9') + .find('.slick-header-column') + .first() + .trigger('mouseover') + .children('.slick-header-menubutton') + .should('be.hidden') + .invoke('show') + .click(); + + cy.get('.slick-header-menu') + .should('be.visible') + .children('.slick-header-menuitem:nth-child(2)') + .children('.slick-header-menucontent') + .should('contain', 'Cacher la colonne') + .click(); + + const smallerTitleList = fullFrenchTitles.slice(1); + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(smallerTitleList[index])); + }); + + it('should click on the External Grid Menu to show the Title as 1st column again', () => { + cy.get('[data-test=external-gridmenu]') + .trigger('click') + .click(); + + cy.get('#grid9') + .get('.slick-gridmenu:visible') + .find('.slick-gridmenu-list') + .children('li:nth-child(1)') + .children('label') + .should('contain', 'Titre') + .click(); + + cy.get('#grid9') + .find('.slick-header-columns') + .children() + .each(($child, index) => expect($child.text()).to.eq(fullFrenchTitles[index])); + }); + }); +});