cypress-ag-grid 1.4.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -7,10 +7,12 @@ Cypress plugin for interacting with and validating against ag grid.
7
7
  + [Grid Interaction](#)
8
8
  - [Getting Data From the Grid](#getting-data-from-the-grid)
9
9
  - [Getting Select Row Data](#getting-select-row-data)
10
+ - [Getting Elements From the Grid](#getting-elements-from-the-grid)
10
11
  - [Sorting Columns](#sorting-columns)
11
12
  - [Filter by Text - Column Menu](#filter-by-text---column-menu)
12
13
  - [Filterby Text - Floating Filter](#filterby-text---floating-filter)
13
14
  - [Filter by Checkbox - Column Menu](#filter-by-checkbox---column-menu)
15
+ - [Filtering - Localization and Internationalization](#filtering---localization-and-internationalization)
14
16
  - [Add or Remove Columns](#add-or-remove-columns)
15
17
  + [Grid Validation](#)
16
18
  - [Validate Paginated Table](#validate-paginated-table)
@@ -70,7 +72,7 @@ The correct command will return the following:
70
72
  To only get certain rows of data, pass the header values into the `getAgGridData()` command, like so:
71
73
 
72
74
  ```javascript
73
- cy.get("#myGrid).getAgGridData({ onlyColumns: ["Year", "Make"] })
75
+ cy.get("#myGrid").getAgGridData({ onlyColumns: ["Year", "Make"] })
74
76
  ```
75
77
 
76
78
  The above command will return the follwoing:
@@ -86,6 +88,25 @@ The above command will return the follwoing:
86
88
  </br>
87
89
  </br>
88
90
 
91
+ ### Getting Elements From the Grid
92
+ To get the Ag Grid data as elements (if you want to interact with the cells themselves), you must chain `.getAgGridElements()` after the `cy.get()` command for the topmost level of the grid, including controls and headers (see selected DOM element in above image).
93
+ ```javascript
94
+ cy.get(agGridSelector)
95
+ .getAgGridElements()
96
+ .then((tableElements) => {
97
+ const porscheRow = tableElements.find(
98
+ (row) => row.Price.innerText === "72000"
99
+ );
100
+ const priceCell = porscheRow.Price;
101
+ cy.wrap(priceCell).dblclick().type("66000{enter}");
102
+ });
103
+
104
+ ```
105
+
106
+ The above example will grab the table as elements, finds the row whose `Price` equals `72000`. It then gets the `Price` cell for that row, double clicks on it to enable an editable input, and changes the value of the cell.
107
+ </br>
108
+ </br>
109
+
89
110
  ### Sorting Columns
90
111
  This command will sort the specified column by the sort direction specified.
91
112
 
@@ -128,13 +149,48 @@ The above command will filter the Model column for the value 'GLC300' and set th
128
149
  </br>
129
150
  </br>
130
151
  ### Filterby Text - Floating Filter
131
- This command will filter a column by a text value from its floating filter (if applicable).
152
+ This command will filter a column by a text value from its floating filter (if applicable). This command will filter a column by a text value from its floating menu. In the options, you must specify a `searchCriteria` object with `columnName`, `filterValue`, and optionally `operator` (i.e. Contains, Not contains, Equals, etc.) and `searchInputIndex` in the event you wish to apply multiple text conditions (see below for multi-condition example).
132
153
 
133
154
  ![alt text](./ag-grid-example-filter-text-floating.png "AG Grid Dom - Filter by Text Floating")
134
155
 
135
- <b>Definition:</b> .agGridColumnFilterTextMenu(options: {})
156
+ <b>Definition:</b> .agGridColumnFilterTextFloating(options: {})
157
+
158
+ Example:
159
+ ```
160
+ cy.get(agGridSelector).agGridColumnFilterTextFloating({
161
+ searchCriteria: {
162
+ columnName: "Make",
163
+ filterValue: "Ford",
164
+ },
165
+ hasApplyButton: true,
166
+ });
167
+ ```
168
+
169
+ The above example will search for the Make `Ford` from the floating text menu filter.
170
+
171
+ If you have the option for multiple conditions on the floating filter, you can do two searches, specifying the `searchInputIndex` parameter in the `searchCriteria` object. The below example will ssarch for any `Make` that contains `B` AND `MW`:
172
+
173
+ Example:
174
+ ```
175
+ cy.get(agGridSelector).agGridColumnFilterTextFloating({
176
+ searchCriteria: {
177
+ columnName: "Make",
178
+ filterValue: "B",
179
+ searchInputIndex: 0,
180
+ },
181
+ hasApplyButton: true,
182
+ });
183
+ cy.get(agGridSelector).agGridColumnFilterTextFloating({
184
+ searchCriteria: {
185
+ columnName: "Make",
186
+ filterValue: "MW",
187
+ searchInputIndex: 1,
188
+ },
189
+ hasApplyButton: true,
190
+ });
191
+ ```
192
+ ![alt text](./ag-grid-example-filter-text-floating-multi-condition.png "AG Grid Dom - Filter by Text Floating")
136
193
 
137
- See [Filter by Text - Column Menu](#filter-by-Text---Column-Menu) for example and usage.
138
194
  <br/>
139
195
  </br>
140
196
 
@@ -159,6 +215,20 @@ Example:
159
215
 
160
216
  ```
161
217
  </br>
218
+
219
+ ### Filtering - Localization and Internationalization
220
+ When we filter by checkbox, we first deselect the Select All checkbox to ensure we ONLY select the specified checkbox. Since AG grid allows for localization, we need a way to be able to pass in the localeText for Select All. This is the only area of this plugin that has a hard-coded value, so no other localization accommodations are needed.
221
+
222
+ ```
223
+ cy.get("#myGrid").agGridColumnFilterCheckboxMenu({
224
+ searchCriteria: {
225
+ columnName: "Model",
226
+ filterValue: "2002",
227
+ },
228
+ selectAllLocaleText: "Tout Sélectionner"
229
+ hasApplyButton: true,
230
+ });
231
+ ```
162
232
  </br>
163
233
 
164
234
  ### Add or Remove Columns
@@ -268,9 +338,9 @@ Example:
268
338
  * To combat this, in your code where the ag grid is called, check if the Cypress window is controlling the app and set the ag grid object to `.sizeColumnsToFit()`. You can see an example of this in the `app/grid.js` file of this repository. Read more [here](https://www.ag-grid.com/javascript-grid/column-sizing/#size-columns-to-fit)
269
339
  * Example:
270
340
  ```javascript
271
- if(Cypress.window){
341
+ if(window.Cypress){
272
342
  this.api.sizeColumnsToFit();
273
343
  }
274
344
  ```
275
345
  ## Credit
276
- A portion of the logic to retrieve table data was expanded upon from the project [Cypress-Get-Table](https://github.com/roggerfe/cypress-get-table) by [Rogger Fernandez](https://github.com/roggerfe).
346
+ A portion of the logic to retrieve table data was expanded upon from the project [Cypress-Get-Table](https://github.com/roggerfe/cypress-get-table) by [Rogger Fernandez](https://github.com/roggerfe).
@@ -3,7 +3,7 @@ const columnDefs = [
3
3
  { field: "year", pinned: "left" },
4
4
  { field: "make", rowGroup: false, pinned: "left" },
5
5
  { field: "model", filter: true },
6
- { field: "price", pinned: "right", floatingFilter: false, sortable: false },
6
+ { field: "price", pinned: "right", floatingFilter: false, sortable: false, editable: true, cellEditor: 'agTextCellEditor' },
7
7
  ];
8
8
 
9
9
  const autoGroupColumnDef = {
@@ -47,10 +47,10 @@ new agGrid.Grid(eGridDiv, gridOptions);
47
47
  // Grab the grid data from the supplied API endpoint
48
48
  agGrid
49
49
  .simpleHttpRequest({
50
- url: "https://api.jsonbin.io/b/608304f69a9aa933335613a6/2",
50
+ url: "https://api.jsonbin.io/v3/b/608304f69a9aa933335613a6/2",
51
51
  })
52
52
  .then((data) => {
53
- gridOptions.api.setRowData(data);
53
+ gridOptions.api.setRowData(data.record);
54
54
  });
55
55
 
56
56
  function autoSizeAllColumns() {
@@ -0,0 +1,71 @@
1
+ // specify the columns
2
+ const columnDefsGrouped = [
3
+ { field: "year", pivot: true, },
4
+ { field: "make", rowGroup: true, enableRowGroup: true },
5
+ { field: "model", filter: true },
6
+ { field: "price", editable: true, cellEditor: 'agTextCellEditor' },
7
+ ];
8
+
9
+ const autoGroupColumnDefGrouped = {
10
+ headerName: "Model",
11
+ field: "model",
12
+ cellRenderer: "agGroupCellRenderer",
13
+ cellRendererParams: {
14
+ checkbox: true,
15
+ },
16
+ };
17
+
18
+ // let the grid know which columns to use
19
+ const gridOptionsGrouped = {
20
+ defaultColDef: {
21
+ sortable: true,
22
+ filter: "agTextColumnFilter",
23
+ floatingFilter: true,
24
+ filterParams: {
25
+ buttons: ["reset", "apply"],
26
+ debounceMs: 200,
27
+ },
28
+ animateRows: true,
29
+ resizable: true,
30
+ },
31
+ groupDefaultExpanded: 2,
32
+ autoGroupColumnDef: autoGroupColumnDefGrouped,
33
+ groupSelectsChildren: true,
34
+ columnDefs: columnDefsGrouped,
35
+ rowSelection: "multiple",
36
+ domLayout: "normal",
37
+ pagination: true,
38
+ paginationPageSize: 5,
39
+ sideBar: false,
40
+ };
41
+
42
+ // lookup the container we want the Grid to use
43
+ const eGridDivGrouped = document.querySelector("#myGrid2");
44
+
45
+ // create the grid passing in the div to use together with the columns &amp; data we want to use
46
+ new agGrid.Grid(eGridDivGrouped, gridOptionsGrouped);
47
+
48
+ // Grab the grid data from the supplied API endpoint
49
+ agGrid
50
+ .simpleHttpRequest({
51
+ url: "https://api.jsonbin.io/v3/b/608304f69a9aa933335613a6/2",
52
+ })
53
+ .then((data) => {
54
+ gridOptionsGrouped.api.setRowData(data.record);
55
+ });
56
+
57
+ function autoSizeAllColumns() {
58
+ var allColumnIds = [];
59
+ gridOptionsGrouped.columnApi.getAllColumns().forEach(function (column) {
60
+ allColumnIds.push(column.colId);
61
+ });
62
+ gridOptionsGrouped.columnApi.autoSizeColumns(allColumnIds);
63
+ }
64
+
65
+ // If the Cypress test is running, ensure all columns fit within the window
66
+ if (window.Cypress) {
67
+ gridOptionsGrouped.api.sizeColumnsToFit();
68
+ } else {
69
+ // Otherwise auto-size columns the way we wish to view the grid in production.
70
+ autoSizeAllColumns();
71
+ }
package/app/index.html CHANGED
@@ -7,7 +7,9 @@
7
7
  </head>
8
8
  <body>
9
9
  <div id="myGrid" style="height: 600px;width:900px;" class="ag-theme-alpine" sideBar="true"></div>
10
- <script src="grid.js" type="text/javascript" charset="utf-8">
11
- </script>
10
+ <script src="grid-basic.js" type="text/javascript" charset="utf-8"></script>
11
+
12
+ <div id="myGrid2" style="height: 600px;width:900px;" class="ag-theme-alpine" sideBar="true"></div>
13
+ <script src="grid-grouped.js" type="text/javascript" charset="utf-8"></script>
12
14
  </body>
13
15
  </html>
@@ -10,10 +10,10 @@ import { filterOperator } from "../../src/agGrid/filterOperator.enum";
10
10
  const _pageSize = 5;
11
11
  const agGridSelector = "#myGrid";
12
12
 
13
- describe("ag-grid scenarios", () => {
13
+ describe("ag-grid get data scenarios", () => {
14
14
  beforeEach(() => {
15
15
  cy.visit("../app/index.html");
16
- cy.get(".ag-cell", {timeout: 10000}).should("be.visible");
16
+ cy.get(".ag-cell", { timeout: 10000 }).should("be.visible");
17
17
  });
18
18
 
19
19
  it("verify paginated table data - include all columns", () => {
@@ -98,38 +98,39 @@ describe("ag-grid scenarios", () => {
98
98
  columnName: "Model",
99
99
  filterValue: "2002",
100
100
  },
101
- selectAllLocaleText: 'Select All', // This is optional if you are using localText for ag grid
101
+ selectAllLocaleText: "Select All", // This is optional if you are using localText for ag grid
102
102
  hasApplyButton: true,
103
103
  });
104
104
  cy.get(agGridSelector)
105
105
  .getAgGridData()
106
106
  .then((actualTableData) => {
107
- cy.get(agGridSelector).agGridValidateRowsExactOrder(actualTableData, expectedTableData);
107
+ cy.agGridValidateRowsExactOrder(actualTableData, expectedTableData);
108
108
  });
109
109
  });
110
110
 
111
111
  it("able to filter by checkbox - multiple columns", () => {
112
112
  const expectedTableData = [
113
- { Year: "2020", Make: "BMW", Model: "3-series", Price: "45000" },
114
- { Year: "2020", Make: "BMW", Model: "3-series", Price: "32000" },
115
- { Year: "2020", Make: "BMW", Model: "2002", Price: "88001" },
113
+ { Year: "2020", Make: "BMW", Model: "3-series", Price: "45000" },
114
+ { Year: "2020", Make: "BMW", Model: "3-series", Price: "32000" },
115
+ { Year: "2020", Make: "BMW", Model: "2002", Price: "88001" },
116
116
  ];
117
117
  cy.get(agGridSelector).agGridColumnFilterCheckboxMenu({
118
- searchCriteria: [{
119
- columnName: "Model",
120
- filterValue: "2002",
121
- },
122
- {
123
- columnName: "Model",
124
- filterValue: "3-series",
125
- }
126
- ],
118
+ searchCriteria: [
119
+ {
120
+ columnName: "Model",
121
+ filterValue: "2002",
122
+ },
123
+ {
124
+ columnName: "Model",
125
+ filterValue: "3-series",
126
+ },
127
+ ],
127
128
  hasApplyButton: true,
128
129
  });
129
130
  cy.get(agGridSelector)
130
131
  .getAgGridData()
131
132
  .then((actualTableData) => {
132
- cy.get(agGridSelector).agGridValidateRowsExactOrder(actualTableData, expectedTableData, true);
133
+ cy.agGridValidateRowsExactOrder(actualTableData, expectedTableData, true);
133
134
  });
134
135
  });
135
136
 
@@ -151,7 +152,7 @@ describe("ag-grid scenarios", () => {
151
152
  cy.get(agGridSelector)
152
153
  .getAgGridData()
153
154
  .then((actualTableData) => {
154
- cy.get(agGridSelector).agGridValidateRowsExactOrder(actualTableData, expectedTableData);
155
+ cy.agGridValidateRowsExactOrder(actualTableData, expectedTableData);
155
156
  });
156
157
  });
157
158
 
@@ -161,23 +162,24 @@ describe("ag-grid scenarios", () => {
161
162
  ];
162
163
  cy.get(agGridSelector).agGridSortColumn("Model", sort.ascending);
163
164
  cy.get(agGridSelector).agGridColumnFilterTextMenu({
164
- searchCriteria: [{
165
- columnName: "Price",
166
- filterValue: "32000",
167
- operator: filterOperator.equals,
168
- },
169
- {
170
- columnName: "Make",
171
- filterValue: "BMW",
172
- operator: filterOperator.equals,
173
- }
174
- ],
165
+ searchCriteria: [
166
+ {
167
+ columnName: "Price",
168
+ filterValue: "32000",
169
+ operator: filterOperator.equals,
170
+ },
171
+ {
172
+ columnName: "Make",
173
+ filterValue: "BMW",
174
+ operator: filterOperator.equals,
175
+ },
176
+ ],
175
177
  hasApplyButton: true,
176
178
  });
177
179
  cy.get(agGridSelector)
178
180
  .getAgGridData()
179
181
  .then((actualTableData) => {
180
- cy.get(agGridSelector).agGridValidateRowsExactOrder(actualTableData, expectedTableData);
182
+ cy.agGridValidateRowsExactOrder(actualTableData, expectedTableData);
181
183
  });
182
184
  });
183
185
 
@@ -199,25 +201,56 @@ describe("ag-grid scenarios", () => {
199
201
  cy.get(agGridSelector)
200
202
  .getAgGridData()
201
203
  .then((actualTableData) => {
202
- cy.get(agGridSelector).agGridValidateRowsExactOrder(actualTableData, expectedTableData);
204
+ cy.agGridValidateRowsExactOrder(actualTableData, expectedTableData);
203
205
  });
204
206
  });
205
207
 
206
- it("able to filter by text - floating filter - multiple columns", () => {
208
+ it("able to filter by text - floating filter - multiple conditions", () => {
207
209
  const expectedTableData = [
208
- { Year: "1990", Make: "Ford", Model: "Taurus", Price: "900" },
210
+ { Year: "2020", Make: "BMW", Model: "2002", Price: "88001" },
211
+ { Year: "2020", Make: "BMW", Model: "3-series", Price: "45000" },
212
+ { Year: "2020", Make: "BMW", Model: "3-series", Price: "32000" },
209
213
  ];
210
214
  cy.get(agGridSelector).agGridSortColumn("Model", sort.ascending);
211
215
  cy.get(agGridSelector).agGridColumnFilterTextFloating({
212
- searchCriteria: [{
216
+ searchCriteria: {
213
217
  columnName: "Make",
214
- filterValue: "Ford",
218
+ filterValue: "B",
219
+ searchInputIndex: 0,
215
220
  },
216
- {
217
- columnName: "Year",
218
- filterValue: "1990",
219
- }
220
- ],
221
+ hasApplyButton: true,
222
+ });
223
+ cy.get(agGridSelector).agGridColumnFilterTextFloating({
224
+ searchCriteria: {
225
+ columnName: "Make",
226
+ filterValue: "MW",
227
+ searchInputIndex: 1,
228
+ },
229
+ hasApplyButton: true,
230
+ });
231
+ cy.get(agGridSelector)
232
+ .getAgGridData()
233
+ .then((actualTableData) => {
234
+ cy.agGridValidateRowsExactOrder(actualTableData, expectedTableData);
235
+ });
236
+ });
237
+
238
+ it("able to filter by text - floating filter - multiple columns", () => {
239
+ const expectedTableData = [
240
+ { Year: "1990", Make: "Ford", Model: "Taurus", Price: "900" },
241
+ ];
242
+ cy.get(agGridSelector).agGridSortColumn("Model", sort.ascending);
243
+ cy.get(agGridSelector).agGridColumnFilterTextFloating({
244
+ searchCriteria: [
245
+ {
246
+ columnName: "Make",
247
+ filterValue: "Ford",
248
+ },
249
+ {
250
+ columnName: "Year",
251
+ filterValue: "1990",
252
+ },
253
+ ],
221
254
  hasApplyButton: true,
222
255
  });
223
256
  cy.get(agGridSelector)
@@ -225,7 +258,7 @@ describe("ag-grid scenarios", () => {
225
258
  .then((actualTableData) => {
226
259
  cy.get(agGridSelector).agGridValidateRowsExactOrder(actualTableData, expectedTableData);
227
260
  });
228
- });
261
+ });
229
262
 
230
263
  it("able to validate empty table", () => {
231
264
  //Search for an entry that does not exist
@@ -240,7 +273,7 @@ describe("ag-grid scenarios", () => {
240
273
  cy.get(agGridSelector)
241
274
  .getAgGridData()
242
275
  .then((actualTableData) => {
243
- cy.get(agGridSelector).agGridValidateEmptyTable(actualTableData);
276
+ cy.agGridValidateEmptyTable(actualTableData);
244
277
  });
245
278
  });
246
279
 
@@ -259,7 +292,7 @@ describe("ag-grid scenarios", () => {
259
292
  cy.get(agGridSelector)
260
293
  .getAgGridData()
261
294
  .then((actualTableData) => {
262
- cy.get(agGridSelector).agGridValidateRowsExactOrder(
295
+ cy.agGridValidateRowsExactOrder(
263
296
  actualTableData,
264
297
  expectedData_sortedByAscending
265
298
  );
@@ -282,7 +315,7 @@ describe("ag-grid scenarios", () => {
282
315
  cy.get(agGridSelector)
283
316
  .getAgGridData()
284
317
  .then((actualTableData) => {
285
- cy.get(agGridSelector).agGridValidateRowsExactOrder(
318
+ cy.agGridValidateRowsExactOrder(
286
319
  actualTableData,
287
320
  expectedData_sortedByDescending
288
321
  );
@@ -300,7 +333,7 @@ describe("ag-grid scenarios", () => {
300
333
  cy.get(agGridSelector)
301
334
  .getAgGridData()
302
335
  .then((actualTableData) => {
303
- cy.get(agGridSelector).agGridValidateRowsExactOrder(
336
+ cy.agGridValidateRowsExactOrder(
304
337
  actualTableData,
305
338
  expectedData_yearColumnRemoved.slice(0, _pageSize)
306
339
  );
@@ -319,7 +352,7 @@ describe("ag-grid scenarios", () => {
319
352
  cy.get(agGridSelector)
320
353
  .getAgGridData()
321
354
  .then((actualTableData) => {
322
- cy.get(agGridSelector).agGridValidateRowsExactOrder(
355
+ cy.agGridValidateRowsExactOrder(
323
356
  actualTableData,
324
357
  expectedData_priceColumnRemoved.slice(0, _pageSize)
325
358
  );
@@ -338,7 +371,7 @@ describe("ag-grid scenarios", () => {
338
371
  cy.get(agGridSelector)
339
372
  .getAgGridData()
340
373
  .then((actualTableData) => {
341
- cy.get(agGridSelector).agGridValidateRowsExactOrder(
374
+ cy.agGridValidateRowsExactOrder(
342
375
  actualTableData,
343
376
  expectedData_multipleColumnsRemoved.slice(0, _pageSize)
344
377
  );
@@ -357,7 +390,7 @@ describe("ag-grid scenarios", () => {
357
390
  cy.get(agGridSelector)
358
391
  .getAgGridData({ onlyColumns: ["Year", "Make", "Model"] })
359
392
  .then((actualTableData) => {
360
- cy.get(agGridSelector).agGridValidateRowsSubset(actualTableData, expectedTableData);
393
+ cy.agGridValidateRowsSubset(actualTableData, expectedTableData);
361
394
  });
362
395
  });
363
396
  });
@@ -447,4 +480,4 @@ function removePropertyFromCollection(expectedTableData, columnsToExclude) {
447
480
  // .then(() => {
448
481
  // return paginatedTableData;
449
482
  // });
450
- // }
483
+ // }
@@ -0,0 +1,59 @@
1
+ import { filterOperator } from "../../src/agGrid/filterOperator.enum";
2
+
3
+ const agGridSelector = "#myGrid2";
4
+
5
+ describe("ag-grid get elements scenario", () => {
6
+ beforeEach(() => {
7
+ cy.visit("../app/index.html");
8
+ cy.get(".ag-cell", { timeout: 10000 }).should("be.visible");
9
+ });
10
+
11
+ it("able to update grid cell value", () => {
12
+ // filter to only show the porsche
13
+ cy.get(agGridSelector).agGridColumnFilterTextFloating({
14
+ searchCriteria: {
15
+ columnName: "Make",
16
+ filterValue: "Porsche",
17
+ operator: filterOperator.equals,
18
+ },
19
+ hasApplyButton: true,
20
+ });
21
+
22
+ // expected values before changing the price
23
+ const expectedTableBeforeEditing = [
24
+ { Year: "2020", Make: "Porsche", Model: "Boxter", Price: "72000" },
25
+ { Year: "2020", Make: "Porsche", Model: "Boxter", Price: "99000" },
26
+ ];
27
+
28
+ // verify values before editing
29
+ cy.get(agGridSelector)
30
+ .getAgGridData()
31
+ .then((tableData) => {
32
+ cy.agGridValidateRowsSubset(tableData, expectedTableBeforeEditing);
33
+ });
34
+
35
+ // edit the porsche boxter from 72000 to 66000
36
+ cy.get(agGridSelector)
37
+ .getAgGridElements()
38
+ .then((tableElements) => {
39
+ const porscheRow = tableElements.find(
40
+ (row) => row.Price.innerText === "72000"
41
+ );
42
+ const priceCell = porscheRow.Price;
43
+ cy.wrap(priceCell).dblclick().type("66000{enter}");
44
+ });
45
+
46
+ // expected values after changing the price
47
+ const expectedTableAfterEditing = [
48
+ { Year: "2020", Make: "Porsche", Model: "Boxter", Price: "66000" },
49
+ { Year: "2020", Make: "Porsche", Model: "Boxter", Price: "99000" },
50
+ ];
51
+
52
+ // verify values before editing
53
+ cy.get(agGridSelector)
54
+ .getAgGridData()
55
+ .then((tableData) => {
56
+ cy.agGridValidateRowsSubset(tableData, expectedTableAfterEditing);
57
+ });
58
+ });
59
+ });
File without changes
@@ -0,0 +1,11 @@
1
+ const { defineConfig } = require('cypress')
2
+
3
+ module.exports = defineConfig({
4
+ e2e: {
5
+ // We've imported your old cypress plugins here.
6
+ // You may want to clean this up later by importing these.
7
+ setupNodeEvents(on, config) {
8
+ return require('./cypress/plugins/index.js')(on, config)
9
+ },
10
+ },
11
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cypress-ag-grid",
3
- "version": "1.4.0",
3
+ "version": "2.0.0",
4
4
  "description": "Cypress plugin to interact with ag grid",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -24,6 +24,6 @@
24
24
  "author": "Kerry McKeever <kerry@kerrymckeever.com>",
25
25
  "license": "MIT",
26
26
  "devDependencies": {
27
- "cypress": "^8.5.0"
27
+ "cypress": "^10.1.0"
28
28
  }
29
29
  }
@@ -5,9 +5,9 @@ import { filterTab } from "./menuTab.enum";
5
5
  /**
6
6
  * Uses the attribute value's index and sorts the data accordingly.
7
7
  * For our purposes, we are getting the attribute with the items' indices and sorting accordingly.
8
- *
9
- * @param {*} index
10
- * @returns
8
+ *
9
+ * @param {*} index
10
+ * @returns
11
11
  */
12
12
  function sortElementsByAttributeValue(attribute) {
13
13
  return (a, b) => {
@@ -23,6 +23,19 @@ function sortElementsByAttributeValue(attribute) {
23
23
  * @param options Provide an array of columns you wish to exclude from the table retrieval.
24
24
  */
25
25
  export const getAgGridData = (agGridElement, options = {}) => {
26
+ return _getAgGrid(agGridElement, options, false);
27
+ };
28
+
29
+ /**
30
+ * Retrieves the values from the *displayed* page in ag grid and assigns each value to its respective column name.
31
+ * @param agGridElement The get() selector for which ag grid table you wish to retrieve.
32
+ * @param options Provide an array of columns you wish to exclude from the table retrieval.
33
+ */
34
+ export const getAgGridElements = (agGridElement, options = {}) => {
35
+ return _getAgGrid(agGridElement, options, true);
36
+ };
37
+
38
+ function _getAgGrid(agGridElement, options = {}, returnElements) {
26
39
  const agGridColumnSelectors =
27
40
  ".ag-pinned-left-cols-container^.ag-center-cols-clipper^.ag-pinned-right-cols-container";
28
41
  if (agGridElement.get().length > 1)
@@ -33,45 +46,59 @@ export const getAgGridData = (agGridElement, options = {}) => {
33
46
  const tableElement = agGridElement.get()[0].querySelectorAll(".ag-root")[0];
34
47
  const agGridSelectors = agGridColumnSelectors.split("^");
35
48
  const headers = [
36
- ...tableElement.querySelectorAll('.ag-header-row-column [aria-colindex]')]
37
- .sort(sortElementsByAttributeValue('aria-colindex'))
49
+ ...tableElement.querySelectorAll(".ag-header-row-column [aria-colindex]"),
50
+ ]
51
+ .sort(sortElementsByAttributeValue("aria-colindex"))
38
52
  .map((headerElement) => {
39
53
  // Check if the elements returned are already .ag-header-cell-text elements
40
54
  // If not, query for that element and return the text content
41
- let headerCells = [...headerElement.querySelectorAll(".ag-header-cell-text")]
55
+ let headerCells = [
56
+ ...headerElement.querySelectorAll(".ag-header-cell-text"),
57
+ ];
42
58
  if (headerCells.length === 0) {
43
- return [headerElement].map((e) => e.textContent.trim())
59
+ return [headerElement].map((e) => e.textContent.trim());
44
60
  } else {
45
- return [...headerElement.querySelectorAll(".ag-header-cell-text")]
46
- .map((e) => e.textContent.trim())
61
+ return [...headerElement.querySelectorAll(".ag-header-cell-text")].map(
62
+ (e) => e.textContent.trim()
63
+ );
47
64
  }
48
- }).flat()
65
+ })
66
+ .flat();
49
67
 
50
68
  let allRows = [];
51
69
  let rows = [];
52
70
 
53
71
  agGridSelectors.forEach((selector) => {
54
- const _rows = [...tableElement.querySelectorAll(`${selector}:not(.ag-hidden) .ag-row`)]
72
+ const _rows = [
73
+ ...tableElement.querySelectorAll(`${selector}:not(.ag-hidden) .ag-row`),
74
+ ]
55
75
  // Sort rows by their row-index attribute value
56
76
  .sort(sortElementsByAttributeValue("row-index"))
57
77
  .map((row) => {
58
78
  // Sort row cells by their aria-colindex attribute value
59
79
  // First check if elements returned already contain the aria-colindex
60
80
  // If not, just query for the .ag-cell
61
- let rowCells = [...row.querySelectorAll(".ag-cell [aria-colindex]")]
81
+ let rowCells = [...row.querySelectorAll(".ag-cell [aria-colindex]")];
62
82
  if (rowCells.length === 0) {
63
- rowCells = [...row.querySelectorAll(".ag-cell")]
83
+ rowCells = [...row.querySelectorAll(".ag-cell")];
64
84
  }
65
- return rowCells.sort(sortElementsByAttributeValue("aria-colindex"))
66
- .map((e)=> e.textContent.trim())
85
+ return rowCells
86
+ .sort(sortElementsByAttributeValue("aria-colindex"))
87
+ .map((e) => {
88
+ if (returnElements) {
89
+ return e;
90
+ } else {
91
+ return e.textContent.trim();
92
+ }
93
+ });
67
94
  });
68
95
  allRows.push(_rows);
69
96
  });
70
97
 
71
98
  // Remove any empty arrays before merging
72
99
  allRows = allRows.filter(function (ele) {
73
- return ele.length
74
- })
100
+ return ele.length;
101
+ });
75
102
 
76
103
  if (!allRows.length) rows = [];
77
104
  else {
@@ -102,7 +129,7 @@ export const getAgGridData = (agGridElement, options = {}) => {
102
129
  return { ...acc, [headers[idx]]: curr };
103
130
  }, {})
104
131
  );
105
- };
132
+ }
106
133
 
107
134
  /**
108
135
  * Retrieve the ag grid column header element based on its column name value
@@ -205,7 +232,12 @@ function getFilterColumnButtonElement(
205
232
  * @param operator (optional) use if using a search operator (i.e. Less Than, Equals, etc...use filterOperator.enum values)
206
233
  * @param noMenuTabs (optional) boolean indicating if the menu has tabs.
207
234
  */
208
- function filterBySearchTerm(agGridElement, filterValue, operator, noMenuTabs) {
235
+ function filterBySearchTerm(agGridElement, options) {
236
+ const filterValue = options.searchCriteria.filterValue;
237
+ const operator = options.searchCriteria.operator;
238
+ const searchInputIndex = options.searchCriteria.searchInputIndex || 0;
239
+ const noMenuTabs = options.noMenuTabs;
240
+
209
241
  // Navigate to the filter tab
210
242
  if (!noMenuTabs) {
211
243
  selectMenuTab(agGridElement, filterTab.filter);
@@ -221,7 +253,7 @@ function filterBySearchTerm(agGridElement, filterValue, operator, noMenuTabs) {
221
253
  .contains(operator)
222
254
  .then(($ele) => {
223
255
  //Have to use the unwrapped element, since Cypress .click() event does not appropriately select the operator
224
- $ele.trigger('click');
256
+ $ele.trigger("click");
225
257
  });
226
258
  }
227
259
  // Input filter term and allow grid a moment to render the results
@@ -229,6 +261,8 @@ function filterBySearchTerm(agGridElement, filterValue, operator, noMenuTabs) {
229
261
  .find(".ag-popup-child")
230
262
  .find("input")
231
263
  .filter(":visible")
264
+ .eq(searchInputIndex)
265
+ .clear()
232
266
  .type(filterValue)
233
267
  .wait(500);
234
268
  }
@@ -239,7 +273,6 @@ function applyColumnFilter(agGridElement, hasApplyButton, noMenuTabs) {
239
273
  .find(".ag-filter-apply-panel-button")
240
274
  .contains("Apply")
241
275
  .click();
242
-
243
276
  }
244
277
  if (!noMenuTabs) {
245
278
  getMenuTabElement(agGridElement, filterTab.filter).click();
@@ -272,7 +305,11 @@ function toggleColumnCheckboxFilter(
272
305
  });
273
306
  }
274
307
 
275
- function populateSearchCriteria(searchCriteria, hasApplyButton = false, noMenuTabs = false) {
308
+ function populateSearchCriteria(
309
+ searchCriteria,
310
+ hasApplyButton = false,
311
+ noMenuTabs = false
312
+ ) {
276
313
  const options = {};
277
314
  //@ts-ignore
278
315
  options.searchCriteria = {};
@@ -322,9 +359,7 @@ function _filterBySearchTextColumnMenu(agGridElement, options) {
322
359
  ).click();
323
360
  filterBySearchTerm(
324
361
  agGridElement,
325
- options.searchCriteria.filterValue,
326
- options.searchCriteria.operator,
327
- options.noMenuTabs
362
+ options
328
363
  );
329
364
  applyColumnFilter(agGridElement, options.hasApplyButton, options.noMenuTabs);
330
365
  }
@@ -336,10 +371,11 @@ function _filterBySearchTextColumnMenu(agGridElement, options) {
336
371
  * @param options.searchCriteria JSON with search properties and options
337
372
  * @param options.searchCriteria.columnName name of the column to filter
338
373
  * @param options.searchCriteria.filterValue value to input into the filter textbox
374
+ * @param options.searchCriteria.searchInputIndex [Optional] Uses 0 by default. Index of which filter box to use in event of having multiple search conditionals
339
375
  * @param options.searchCriteria.operator [Optional] Use if using a search operator (i.e. Less Than, Equals, etc...use filterOperator.enum values).
340
376
  * @param options.hasApplyButton [Optional] True if "Apply" button is used, false if filters by text input automatically.
341
377
  * @param options.noMenuTabs [Optional] True if you use for example the community edition of ag-grid, which has no menu tabs
342
- */
378
+ */
343
379
  export function filterBySearchTextColumnFloatingFilter(agGridElement, options) {
344
380
  // Check if there are multiple search criteria provided by attempting to access the columnName
345
381
  if (!options.searchCriteria.columnName) {
@@ -365,11 +401,13 @@ function _filterBySearchTextColumnFloatingFilter(agGridElement, options) {
365
401
  ).click();
366
402
  filterBySearchTerm(
367
403
  agGridElement,
368
- options.searchCriteria.filterValue,
369
- options.searchCriteria.operator,
404
+ options
405
+ );
406
+ applyColumnFilter(
407
+ agGridElement,
408
+ options.hasApplyButton,
370
409
  options.noMenuTabs
371
410
  );
372
- applyColumnFilter(agGridElement, options.hasApplyButton, options.noMenuTabs);
373
411
  });
374
412
  }
375
413
 
@@ -405,7 +443,7 @@ function _filterByCheckboxColumnMenu(agGridElement, options) {
405
443
  agGridElement,
406
444
  options.searchCriteria.columnName
407
445
  ).click();
408
- const selectAllText = options.selectAllLocaleText || 'Select All'
446
+ const selectAllText = options.selectAllLocaleText || "Select All";
409
447
  toggleColumnCheckboxFilter(
410
448
  agGridElement,
411
449
  selectAllText,
@@ -418,7 +456,11 @@ function _filterByCheckboxColumnMenu(agGridElement, options) {
418
456
  true,
419
457
  options.noMenuTabs
420
458
  );
421
- applyColumnFilter(agGridElement, options.hasApplyButton, options.noMenuTabs);
459
+ applyColumnFilter(
460
+ agGridElement,
461
+ options.hasApplyButton,
462
+ options.noMenuTabs
463
+ );
422
464
  });
423
465
  }
424
466
 
@@ -426,7 +468,11 @@ function _filterByCheckboxColumnMenu(agGridElement, options) {
426
468
  * Will perform a filter for all search criteria provided, then selects all found entries in the grid
427
469
  * @param searchCriteria a "\^" delimited string of all columns and searchCriteria to search for in the grid (i.e. "Name=John Smith^Rate Plan=Standard"
428
470
  */
429
- export function filterGridEntriesBySearchText(agGridElement, searchCriteria, isFloatingFilter = false) {
471
+ export function filterGridEntriesBySearchText(
472
+ agGridElement,
473
+ searchCriteria,
474
+ isFloatingFilter = false
475
+ ) {
430
476
  if (isFloatingFilter) {
431
477
  filterBySearchTextColumnFloatingFilter(agGridElement, searchCriteria);
432
478
  } else {
@@ -30,7 +30,7 @@ export function validateTablePages(agGridElement,expectedPaginatedTableData, onl
30
30
  .then((table) => {
31
31
  const actualPage = JSON.parse(JSON.stringify(table));
32
32
  validateTableExactOrder(agGridElement, actualPage, expectedPage, true);
33
- cy.get(".ag-icon-next").click();
33
+ cy.get(agGridElement).find(".ag-icon-next").click();
34
34
  iterator++;
35
35
  });
36
36
  });
package/src/index.d.ts CHANGED
@@ -2,7 +2,8 @@
2
2
 
3
3
  declare namespace Cypress {
4
4
  interface Chainable<Subject> {
5
- getAgGridData<E extends Node = HTMLElement>(options?: {}): Chainable<JQuery<E>>;
5
+ getAgGridData(options?: {}): Chainable<Array<Record<string, string>>>;
6
+ getAgGridElements<E extends Node = HTMLElement>(options?: {}): Chainable<JQuery<E>>;
6
7
  /**
7
8
  * * Performs sorting operation on the specified column
8
9
  * @param {*} subject The get() selector for which ag grid table you wish to retrieve.
package/src/index.js CHANGED
@@ -1,18 +1,19 @@
1
1
  /// <reference types="cypress" />
2
2
 
3
- import {getAgGridData, sortColumnBy} from "./agGrid/agGridInteractions"
3
+ import {getAgGridData, getAgGridElements, sortColumnBy} from "./agGrid/agGridInteractions"
4
4
  import {validateTablePages, validateTableExactOrder, validateEmptyTable, validateTableRowSubset} from "./agGrid/agGridValidations"
5
5
  import {filterByCheckboxColumnMenu, filterBySearchTextColumnFloatingFilter, filterBySearchTextColumnMenu, toggleColumnFromSideBar} from "./agGrid/agGridInteractions";
6
6
 
7
7
  Cypress.Commands.add('getAgGridData', { prevSubject: true }, getAgGridData);
8
+ Cypress.Commands.add('getAgGridElements', {prevSubject: true}, getAgGridElements);
8
9
  Cypress.Commands.add('agGridSortColumn', {prevSubject: true}, sortColumnBy);
9
10
  Cypress.Commands.add('agGridColumnFilterCheckboxMenu', {prevSubject: true}, filterByCheckboxColumnMenu)
10
11
  Cypress.Commands.add('agGridColumnFilterTextMenu', {prevSubject: true}, filterBySearchTextColumnMenu)
11
12
  Cypress.Commands.add('agGridColumnFilterTextFloating', {prevSubject: true}, filterBySearchTextColumnFloatingFilter)
12
13
 
13
- Cypress.Commands.add('agGridValidatePaginatedTable', {prevSubject: true}, validateTablePages)
14
- Cypress.Commands.add('agGridValidateRowsExactOrder', {prevSubject: true}, validateTableExactOrder)
15
- Cypress.Commands.add('agGridValidateRowsSubset', {prevSubject: true}, validateTableRowSubset)
16
- Cypress.Commands.add('agGridValidateEmptyTable', {prevSubject: true}, validateEmptyTable)
14
+ Cypress.Commands.add('agGridValidatePaginatedTable', {prevSubject: 'optional'}, validateTablePages)
15
+ Cypress.Commands.add('agGridValidateRowsExactOrder', {prevSubject: 'optional'}, validateTableExactOrder)
16
+ Cypress.Commands.add('agGridValidateRowsSubset', {prevSubject: 'optional'}, validateTableRowSubset)
17
+ Cypress.Commands.add('agGridValidateEmptyTable', {prevSubject: 'optional'}, validateEmptyTable)
17
18
 
18
19
  Cypress.Commands.add('agGridToggleColumnsSideBar', {prevSubject: true}, toggleColumnFromSideBar)
package/cypress.json DELETED
@@ -1 +0,0 @@
1
- {}