cypress-ag-grid 3.2.1 → 3.3.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cypress-ag-grid",
3
- "version": "3.2.1",
3
+ "version": "3.3.1",
4
4
  "description": "Cypress plugin to interact with ag grid",
5
5
  "main": "src/index.js",
6
6
  "repository": {
@@ -1,7 +1,41 @@
1
1
  /// <reference types="cypress" />
2
- import { sort } from "./sort.enum";
3
- import { filterTab } from "./menuTab.enum";
4
2
  import { filterOperator } from "./filterOperator.enum";
3
+ import { filterTab } from "./menuTab.enum";
4
+ import { sort } from "./sort.enum";
5
+
6
+ function isRowNotDestroyed(rowElement) {
7
+ const rect = rowElement.getBoundingClientRect();
8
+ const viewPortRect = rowElement.parentElement.getBoundingClientRect();
9
+
10
+ return (
11
+ rect.top >= viewPortRect.top &&
12
+ rect.left >= viewPortRect.left &&
13
+ rect.bottom <= viewPortRect.bottom &&
14
+ rect.right <= viewPortRect.right
15
+ );
16
+ }
17
+
18
+ export const agGridWaitForAnimation = async (agGridElement) => {
19
+ if (agGridElement.get().length < 1) {
20
+ throw new Error(`Couldn't find the element ${agGridElement}`);
21
+ }
22
+
23
+ const animations = agGridElement.get()[0].getAnimations({ subtree: true });
24
+
25
+ await Promise.all(
26
+ animations.map(async (animation) => {
27
+ try {
28
+ await animation.finished;
29
+ } catch (error) {
30
+ if (error.name === "AbortError") return;
31
+ console.error("error", error, error.name);
32
+ throw error;
33
+ }
34
+ })
35
+ );
36
+
37
+ return agGridElement;
38
+ };
5
39
 
6
40
  /**
7
41
  * Uses the attribute value's index and sorts the data accordingly.
@@ -23,7 +57,8 @@ function sortElementsByAttributeValue(attribute) {
23
57
  * @param agGridElement The get() selector for which ag grid table you wish to retrieve.
24
58
  * @param options Provide an array of columns you wish to exclude from the table retrieval.
25
59
  */
26
- export const getAgGridData = (agGridElement, options = {}) => {
60
+ export const getAgGridData = async (agGridElement, options = {}) => {
61
+ await agGridWaitForAnimation(agGridElement);
27
62
  return _getAgGrid(agGridElement, options, false);
28
63
  };
29
64
 
@@ -32,7 +67,8 @@ export const getAgGridData = (agGridElement, options = {}) => {
32
67
  * @param agGridElement The get() selector for which ag grid table you wish to retrieve.
33
68
  * @param options Provide an array of columns you wish to exclude from the table retrieval.
34
69
  */
35
- export const getAgGridElements = (agGridElement, options = {}) => {
70
+ export const getAgGridElements = async (agGridElement, options = {}) => {
71
+ await agGridWaitForAnimation(agGridElement);
36
72
  return _getAgGrid(agGridElement, options, true);
37
73
  };
38
74
 
@@ -71,8 +107,18 @@ function _getAgGrid(agGridElement, options = {}, returnElements) {
71
107
 
72
108
  agGridSelectors.forEach((selector) => {
73
109
  const _rows = [
74
- ...tableElement.querySelectorAll(`${selector}:not(.ag-hidden) .ag-row`),
110
+ ...tableElement.querySelectorAll(
111
+ `${selector}:not(.ag-hidden) .ag-row:not(.ag-opacity-zero)`
112
+ ),
75
113
  ]
114
+ // When animation is enabled, ag-grid destroys rows in 2 phases,
115
+ // first it runs an animation to place rows to be destroyed just outside
116
+ // the viewport.
117
+ // In the second phase those rows are removed from the DOM.
118
+ // Because we get here AFTER all animations are finished, it is possible,
119
+ // those rows are still in the DOM, but are not visible.
120
+ // therefore those rows should be filtered out.
121
+ .filter(isRowNotDestroyed)
76
122
  // Sort rows by their row-index attribute value
77
123
  .sort(sortElementsByAttributeValue("row-index"))
78
124
  .map((row) => {
@@ -100,6 +146,14 @@ function _getAgGrid(agGridElement, options = {}, returnElements) {
100
146
  return ele.length;
101
147
  });
102
148
 
149
+ // Remove duplicate entries from allRows
150
+ // In some instances we see cell duplication for non-unique rows
151
+ allRows = allRows.map((row) => {
152
+ return row.filter((cell, index) => {
153
+ return row.indexOf(cell) === index;
154
+ });
155
+ });
156
+
103
157
  if (!allRows.length) rows = [];
104
158
  else {
105
159
  rows = allRows
@@ -116,12 +170,10 @@ function _getAgGrid(agGridElement, options = {}, returnElements) {
116
170
  })
117
171
  );
118
172
  }
119
-
120
173
  // if options.rawValues = true, return headers & rows values as arrays instead of mapping as objects
121
174
  if (options.valuesArray) {
122
175
  return { headers, rows };
123
176
  }
124
-
125
177
  // return structured object from headers and rows variables
126
178
  return rows.map((row) =>
127
179
  row.reduce((acc, curr, idx) => {
@@ -170,11 +222,10 @@ export function sortColumnBy(agGridElement, columnName, sortDirection) {
170
222
  .then((value) => {
171
223
  cy.log(`sort: ${sortDirection}`);
172
224
  if (!value.includes(`ag-header-cell-sorted-${sortDirection}`)) {
173
- getColumnHeaderElement(agGridElement, columnName).click().wait(250);
225
+ getColumnHeaderElement(agGridElement, columnName).click();
174
226
  sortColumnBy(agGridElement, columnName, sortDirection);
175
227
  }
176
- })
177
- .wait(100);
228
+ });
178
229
  } else {
179
230
  throw new Error("sortDirection must be either 'asc' or 'desc'.");
180
231
  }
@@ -257,20 +308,19 @@ function filterBySearchTerm(agGridElement, options) {
257
308
  }
258
309
 
259
310
  if (operator) {
260
- cy.get(agGridElement)
311
+ const elem = cy
312
+ .get(agGridElement)
261
313
  .find(".ag-filter")
262
314
  .find(".ag-picker-field-wrapper")
263
315
  .filter(":visible")
264
- .eq(searchInputIndex)
265
- .click();
316
+ .eq(searchInputIndex);
317
+ cy.get(agGridElement).agGridWaitForAnimation();
318
+ elem.click();
266
319
  cy.get(agGridElement)
267
- .find(".ag-popup")
320
+ .find(".ag-popup .ag-list")
268
321
  .find("span")
269
322
  .contains(operator)
270
- .then(($ele) => {
271
- //Have to use the unwrapped element, since Cypress .click() event does not appropriately select the operator
272
- $ele.trigger("click");
273
- });
323
+ .click();
274
324
  }
275
325
  // Input filter term and allow grid a moment to render the results
276
326
  cy.get(agGridElement)
@@ -291,7 +341,7 @@ function filterBySearchTerm(agGridElement, options) {
291
341
  operator !== filterOperator.notBlank
292
342
  ) {
293
343
  cy.get("@filterInput").then(($ele) => {
294
- cy.wrap($ele).eq(searchInputIndex).clear().type(filterValue).wait(500);
344
+ cy.wrap($ele).eq(searchInputIndex).clear().type(filterValue);
295
345
  });
296
346
  }
297
347
 
@@ -306,11 +356,10 @@ function applyColumnFilter(agGridElement, hasApplyButton, noMenuTabs) {
306
356
  cy.get(agGridElement)
307
357
  .find(".ag-filter-apply-panel-button")
308
358
  .contains("Apply")
309
- .click()
310
- .wait(500);
359
+ .click();
311
360
  }
312
361
  if (!noMenuTabs) {
313
- getMenuTabElement(agGridElement, filterTab.filter).click().wait(500);
362
+ getMenuTabElement(agGridElement, filterTab.filter).click();
314
363
  }
315
364
  }
316
365
 
@@ -335,8 +384,8 @@ function toggleColumnCheckboxFilter(
335
384
  .siblings("div")
336
385
  .find("input")
337
386
  .then(($ele) => {
338
- if (doSelect) cy.wrap($ele).check().wait(500);
339
- else cy.wrap($ele).uncheck().wait(500);
387
+ if (doSelect) cy.wrap($ele).check();
388
+ else cy.wrap($ele).uncheck();
340
389
  });
341
390
  }
342
391
 
@@ -556,7 +605,8 @@ export function toggleColumnFromSideBar(agGridElement, columnName, doRemove) {
556
605
  if (!$columnFilterInputField.is(":visible")) {
557
606
  cy.get(".ag-side-buttons").find("span").contains("Columns").click();
558
607
  }
559
- cy.wrap($columnFilterInputField).clear().wait(250).type(columnName);
608
+ cy.get(agGridElement).agGridWaitForAnimation();
609
+ cy.wrap($columnFilterInputField).clear().type(columnName);
560
610
  cy.get(".ag-column-select-column-label")
561
611
  .contains(columnName)
562
612
  .parent()
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference types="cypress" />
2
2
 
3
- import {getAgGridData, getAgGridElements, sortColumnBy} from "./agGrid/agGridInteractions"
3
+ import {agGridWaitForAnimation, getAgGridData, getAgGridElements, sortColumnBy} from "./agGrid/agGridInteractions"
4
4
  import {validateTablePages, validateTableExactOrder, validateEmptyTable, validateTableRowSubset} from "./agGrid/agGridValidations"
5
5
  import {filterByCheckboxColumnMenu, filterBySearchTextColumnFloatingFilter, filterBySearchTextColumnMenu, toggleColumnFromSideBar, pinColumn} from "./agGrid/agGridInteractions";
6
6
 
@@ -17,4 +17,6 @@ Cypress.Commands.add('agGridValidateRowsSubset', {prevSubject: 'optional'}, vali
17
17
  Cypress.Commands.add('agGridValidateEmptyTable', {prevSubject: 'optional'}, validateEmptyTable)
18
18
 
19
19
  Cypress.Commands.add('agGridToggleColumnsSideBar', {prevSubject: true}, toggleColumnFromSideBar)
20
- Cypress.Commands.add('agGridPinColumn', {prevSubject: true}, pinColumn)
20
+ Cypress.Commands.add('agGridPinColumn', {prevSubject: true}, pinColumn)
21
+
22
+ Cypress.Commands.add('agGridWaitForAnimation', { prevSubject: 'element' }, agGridWaitForAnimation);