cypress-ag-grid 3.3.4 → 3.4.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/CHANGELOG.md +12 -0
- package/app/animation-wait/ag-owned.html +28 -0
- package/app/animation-wait/animation-grid.js +123 -0
- package/app/animation-wait/third-party-subtree.html +41 -0
- package/cypress/e2e/ag-grid-animation-wait.v35.cy.js +46 -0
- package/package.json +9 -2
- package/src/agGrid/agGridInteractions.js +27 -174
- package/.circleci/config.yml +0 -14
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# cypress-ag-grid
|
|
2
|
+
|
|
3
|
+
## 3.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 2a7e5d7: Move to monorepo structure to support more node-based testing tools for ag grid interactions and validations
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [2a7e5d7]
|
|
12
|
+
- @kpmck/ag-grid-core@1.0.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>AG Grid Animation Wait - AG Owned</title>
|
|
7
|
+
<script>
|
|
8
|
+
window.AG_GRID_LIBRARY_VERSION = "35.0.0";
|
|
9
|
+
window.ANIMATION_WAIT_SCENARIO = "ag-owned";
|
|
10
|
+
</script>
|
|
11
|
+
<script src="https://unpkg.com/ag-grid-enterprise@35.0.0/dist/ag-grid-enterprise.min.noStyle.js"></script>
|
|
12
|
+
<link rel="stylesheet" href="../ag-grid.css">
|
|
13
|
+
<link rel="stylesheet" href="../ag-theme-alpine.css">
|
|
14
|
+
<style>
|
|
15
|
+
body {
|
|
16
|
+
font-family: Arial, sans-serif;
|
|
17
|
+
margin: 16px;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
20
|
+
</head>
|
|
21
|
+
|
|
22
|
+
<body>
|
|
23
|
+
<h1>AG Grid Animation Wait - AG Owned</h1>
|
|
24
|
+
<div id="myGrid" style="height: 400px; width: 900px;" class="ag-theme-alpine"></div>
|
|
25
|
+
<script src="./animation-grid.js" type="text/javascript" charset="utf-8"></script>
|
|
26
|
+
</body>
|
|
27
|
+
|
|
28
|
+
</html>
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
const rowData = [
|
|
2
|
+
{ make: "Porsche", model: "Boxster", price: 72000 },
|
|
3
|
+
{ make: "Tesla", model: "Model 3", price: 48000 },
|
|
4
|
+
{ make: "Toyota", model: "Celica", price: 35000 },
|
|
5
|
+
];
|
|
6
|
+
|
|
7
|
+
const gridOptions = {
|
|
8
|
+
animateRows: true,
|
|
9
|
+
columnDefs: [
|
|
10
|
+
{ field: "make" },
|
|
11
|
+
{ field: "model" },
|
|
12
|
+
{ field: "price" },
|
|
13
|
+
],
|
|
14
|
+
defaultColDef: {
|
|
15
|
+
resizable: true,
|
|
16
|
+
},
|
|
17
|
+
rowData,
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const animationProbe = {
|
|
21
|
+
agFinished: false,
|
|
22
|
+
agStarted: false,
|
|
23
|
+
thirdPartyInstalled: false,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
let extraAnimations = [];
|
|
27
|
+
|
|
28
|
+
function getFirstAgRow() {
|
|
29
|
+
return document.querySelector("#myGrid .ag-center-cols-container .ag-row");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function createTrackedAnimation({ target, duration, onFinish, timingDuration = duration }) {
|
|
33
|
+
let resolveFinished;
|
|
34
|
+
const finished = new Promise((resolve) => {
|
|
35
|
+
resolveFinished = resolve;
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
setTimeout(() => {
|
|
39
|
+
if (typeof onFinish === "function") {
|
|
40
|
+
onFinish();
|
|
41
|
+
}
|
|
42
|
+
resolveFinished();
|
|
43
|
+
}, duration);
|
|
44
|
+
|
|
45
|
+
return {
|
|
46
|
+
effect: {
|
|
47
|
+
target,
|
|
48
|
+
getTiming: () => ({
|
|
49
|
+
duration: timingDuration,
|
|
50
|
+
iterations: 1,
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
finished,
|
|
54
|
+
playState: "running",
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function startAgOwnedAnimation() {
|
|
59
|
+
const row = getFirstAgRow();
|
|
60
|
+
if (!row) {
|
|
61
|
+
throw new Error("Expected an AG Grid row before starting the animation.");
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
animationProbe.agStarted = true;
|
|
65
|
+
animationProbe.agFinished = false;
|
|
66
|
+
|
|
67
|
+
extraAnimations.push(
|
|
68
|
+
createTrackedAnimation({
|
|
69
|
+
target: row,
|
|
70
|
+
duration: 350,
|
|
71
|
+
onFinish: () => {
|
|
72
|
+
animationProbe.agFinished = true;
|
|
73
|
+
},
|
|
74
|
+
})
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function installThirdPartyAnimationTrap() {
|
|
79
|
+
const grid = document.querySelector("#myGrid");
|
|
80
|
+
const overlayScrollbarsApi = window.OverlayScrollbarsGlobal?.OverlayScrollbars;
|
|
81
|
+
if (typeof overlayScrollbarsApi !== "function") {
|
|
82
|
+
throw new Error("Expected OverlayScrollbarsGlobal.OverlayScrollbars to be available.");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
overlayScrollbarsApi(grid, {});
|
|
86
|
+
|
|
87
|
+
const handle = grid.querySelector(".os-scrollbar-handle");
|
|
88
|
+
if (!handle) {
|
|
89
|
+
throw new Error("Expected OverlayScrollbars to render an .os-scrollbar-handle element.");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
extraAnimations.push({
|
|
93
|
+
effect: {
|
|
94
|
+
target: handle,
|
|
95
|
+
getTiming: () => ({
|
|
96
|
+
duration: "auto",
|
|
97
|
+
iterations: 1,
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
finished: new Promise(() => {}),
|
|
101
|
+
playState: "running",
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
animationProbe.thirdPartyInstalled = true;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
window.__animationProbe = animationProbe;
|
|
108
|
+
window.startAnimationWaitScenario = () => {
|
|
109
|
+
startAgOwnedAnimation();
|
|
110
|
+
|
|
111
|
+
if (window.ANIMATION_WAIT_SCENARIO === "third-party-subtree") {
|
|
112
|
+
installThirdPartyAnimationTrap();
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const gridElement = document.querySelector("#myGrid");
|
|
117
|
+
agGrid.createGrid(gridElement, gridOptions);
|
|
118
|
+
|
|
119
|
+
const originalGetAnimations = gridElement.getAnimations.bind(gridElement);
|
|
120
|
+
gridElement.getAnimations = (options) => [
|
|
121
|
+
...originalGetAnimations(options),
|
|
122
|
+
...extraAnimations,
|
|
123
|
+
];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>AG Grid Animation Wait - Third Party Subtree</title>
|
|
7
|
+
<script>
|
|
8
|
+
window.AG_GRID_LIBRARY_VERSION = "35.0.0";
|
|
9
|
+
window.ANIMATION_WAIT_SCENARIO = "third-party-subtree";
|
|
10
|
+
</script>
|
|
11
|
+
<script src="https://unpkg.com/ag-grid-enterprise@35.0.0/dist/ag-grid-enterprise.min.noStyle.js"></script>
|
|
12
|
+
<link rel="stylesheet" href="https://unpkg.com/overlayscrollbars/styles/overlayscrollbars.min.css">
|
|
13
|
+
<link rel="stylesheet" href="../ag-grid.css">
|
|
14
|
+
<link rel="stylesheet" href="../ag-theme-alpine.css">
|
|
15
|
+
<style>
|
|
16
|
+
body {
|
|
17
|
+
font-family: Arial, sans-serif;
|
|
18
|
+
margin: 16px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.os-scrollbar-handle {
|
|
22
|
+
background: rgba(31, 77, 143, 0.25);
|
|
23
|
+
border-radius: 999px;
|
|
24
|
+
height: 12px;
|
|
25
|
+
position: absolute;
|
|
26
|
+
right: 12px;
|
|
27
|
+
top: 12px;
|
|
28
|
+
width: 80px;
|
|
29
|
+
z-index: 10;
|
|
30
|
+
}
|
|
31
|
+
</style>
|
|
32
|
+
</head>
|
|
33
|
+
|
|
34
|
+
<body>
|
|
35
|
+
<h1>AG Grid Animation Wait - Third Party Subtree</h1>
|
|
36
|
+
<div id="myGrid" data-overlayscrollbars-initialize style="height: 400px; width: 900px;" class="ag-theme-alpine"></div>
|
|
37
|
+
<script src="https://unpkg.com/overlayscrollbars/browser/overlayscrollbars.browser.es6.min.js" type="text/javascript"></script>
|
|
38
|
+
<script src="./animation-grid.js" type="text/javascript" charset="utf-8"></script>
|
|
39
|
+
</body>
|
|
40
|
+
|
|
41
|
+
</html>
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
describe("agGridWaitForAnimation", () => {
|
|
2
|
+
it("waits for AG Grid-owned animations to finish", () => {
|
|
3
|
+
cy.visit("../app/animation-wait/ag-owned.html");
|
|
4
|
+
cy.get(".ag-cell", { timeout: 10000 }).should("be.visible");
|
|
5
|
+
|
|
6
|
+
cy.window().then((win) => {
|
|
7
|
+
win.startAnimationWaitScenario();
|
|
8
|
+
win.__animationProbe.waitStartedAt = Date.now();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
cy.get("#myGrid")
|
|
12
|
+
.agGridWaitForAnimation()
|
|
13
|
+
.then(() => {
|
|
14
|
+
cy.window().then((win) => {
|
|
15
|
+
const elapsedMs = Date.now() - win.__animationProbe.waitStartedAt;
|
|
16
|
+
expect(win.__animationProbe.agStarted).to.equal(true);
|
|
17
|
+
expect(win.__animationProbe.agFinished).to.equal(true);
|
|
18
|
+
expect(elapsedMs).to.be.greaterThan(200);
|
|
19
|
+
expect(elapsedMs).to.be.lessThan(2000);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("ignores third-party subtree animations whose finished promise never resolves", () => {
|
|
25
|
+
cy.visit("../app/animation-wait/third-party-subtree.html");
|
|
26
|
+
cy.get(".ag-cell", { timeout: 10000 }).should("be.visible");
|
|
27
|
+
|
|
28
|
+
cy.window().then((win) => {
|
|
29
|
+
win.startAnimationWaitScenario();
|
|
30
|
+
win.__animationProbe.waitStartedAt = Date.now();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
cy.get("#myGrid .os-scrollbar-handle").should("exist");
|
|
34
|
+
|
|
35
|
+
cy.get("#myGrid")
|
|
36
|
+
.agGridWaitForAnimation()
|
|
37
|
+
.then(() => {
|
|
38
|
+
cy.window().then((win) => {
|
|
39
|
+
const elapsedMs = Date.now() - win.__animationProbe.waitStartedAt;
|
|
40
|
+
expect(win.__animationProbe.agFinished).to.equal(true);
|
|
41
|
+
expect(win.__animationProbe.thirdPartyInstalled).to.equal(true);
|
|
42
|
+
expect(elapsedMs).to.be.lessThan(2000);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cypress-ag-grid",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Cypress plugin to interact with ag grid",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -18,14 +18,21 @@
|
|
|
18
18
|
"cypress aggrid"
|
|
19
19
|
],
|
|
20
20
|
"scripts": {
|
|
21
|
-
"test": "
|
|
21
|
+
"test": "npm run test:all",
|
|
22
|
+
"test:all": "npx cypress run --headless --spec \"cypress/e2e/*.cy.js\"",
|
|
22
23
|
"test:v33": "npx cypress run --headless --spec \"cypress/e2e/*.v33.cy.js\"",
|
|
23
24
|
"test:v34": "npx cypress run --headless --spec \"cypress/e2e/*.v34.cy.js\"",
|
|
24
25
|
"test:v35": "npx cypress run --headless --spec \"cypress/e2e/*.v35.cy.js\"",
|
|
25
26
|
"test:watch": "npx cypress open"
|
|
26
27
|
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public"
|
|
30
|
+
},
|
|
27
31
|
"author": "Kerry McKeever <kerry@kerrymckeever.com>",
|
|
28
32
|
"license": "MIT",
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@kpmck/ag-grid-core": "1.0.0"
|
|
35
|
+
},
|
|
29
36
|
"devDependencies": {
|
|
30
37
|
"cypress": "^15.12.0"
|
|
31
38
|
}
|
|
@@ -1,72 +1,41 @@
|
|
|
1
1
|
/// <reference types="cypress" />
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const agGridWaitForAnimation = async (agGridElement) => {
|
|
19
|
-
if (agGridElement.get().length < 1) {
|
|
2
|
+
import {
|
|
3
|
+
extractAgGridData,
|
|
4
|
+
extractAgGridElements,
|
|
5
|
+
filterOperator,
|
|
6
|
+
filterTab,
|
|
7
|
+
sort,
|
|
8
|
+
waitForAgGridAnimation,
|
|
9
|
+
} from "@kpmck/ag-grid-core";
|
|
10
|
+
|
|
11
|
+
function getSingleAgGridRootElement(agGridElement) {
|
|
12
|
+
const rootElements = agGridElement.get();
|
|
13
|
+
|
|
14
|
+
if (rootElements.length < 1) {
|
|
20
15
|
throw new Error(`Couldn't find the element ${agGridElement}`);
|
|
21
16
|
}
|
|
22
17
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
const iterations = animation.effect?.getTiming?.()?.iterations;
|
|
29
|
-
return iterations !== Infinity;
|
|
30
|
-
});
|
|
18
|
+
if (rootElements.length > 1) {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`Selector "${agGridElement.selector}" returned more than 1 element.`
|
|
21
|
+
);
|
|
22
|
+
}
|
|
31
23
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
await animation.finished;
|
|
36
|
-
} catch (error) {
|
|
37
|
-
if (error.name === "AbortError") return;
|
|
38
|
-
console.error("error", error, error.name);
|
|
39
|
-
throw error;
|
|
40
|
-
}
|
|
41
|
-
})
|
|
42
|
-
);
|
|
24
|
+
return rootElements[0];
|
|
25
|
+
}
|
|
43
26
|
|
|
27
|
+
export const agGridWaitForAnimation = async (agGridElement) => {
|
|
28
|
+
await waitForAgGridAnimation(getSingleAgGridRootElement(agGridElement));
|
|
44
29
|
return agGridElement;
|
|
45
30
|
};
|
|
46
31
|
|
|
47
|
-
/**
|
|
48
|
-
* Uses the attribute value's index and sorts the data accordingly.
|
|
49
|
-
* For our purposes, we are getting the attribute with the items' indices and sorting accordingly.
|
|
50
|
-
*
|
|
51
|
-
* @param {*} index
|
|
52
|
-
* @returns
|
|
53
|
-
*/
|
|
54
|
-
function sortElementsByAttributeValue(attribute) {
|
|
55
|
-
return (a, b) => {
|
|
56
|
-
const contentA = parseInt(a.attributes[attribute].nodeValue, 10).valueOf();
|
|
57
|
-
const contentB = parseInt(b.attributes[attribute].nodeValue, 10).valueOf();
|
|
58
|
-
return contentA < contentB ? -1 : contentA > contentB ? 1 : 0;
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
32
|
/**
|
|
63
33
|
* Retrieves the values from the *displayed* page in ag grid and assigns each value to its respective column name.
|
|
64
34
|
* @param agGridElement The get() selector for which ag grid table you wish to retrieve.
|
|
65
35
|
* @param options Provide an array of columns you wish to exclude from the table retrieval.
|
|
66
36
|
*/
|
|
67
37
|
export const getAgGridData = async (agGridElement, options = {}) => {
|
|
68
|
-
|
|
69
|
-
return _getAgGrid(agGridElement, options, false);
|
|
38
|
+
return extractAgGridData(getSingleAgGridRootElement(agGridElement), options);
|
|
70
39
|
};
|
|
71
40
|
|
|
72
41
|
/**
|
|
@@ -75,127 +44,11 @@ export const getAgGridData = async (agGridElement, options = {}) => {
|
|
|
75
44
|
* @param options Provide an array of columns you wish to exclude from the table retrieval.
|
|
76
45
|
*/
|
|
77
46
|
export const getAgGridElements = async (agGridElement, options = {}) => {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
function _getAgGrid(agGridElement, options = {}, returnElements) {
|
|
83
|
-
const agGridColumnSelectors =
|
|
84
|
-
".ag-pinned-left-cols-container^.ag-center-cols-clipper^.ag-center-cols-viewport^.ag-pinned-right-cols-container";
|
|
85
|
-
if (agGridElement.get().length > 1)
|
|
86
|
-
throw new Error(
|
|
87
|
-
`Selector "${agGridElement.selector}" returned more than 1 element.`
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
const tableElement = agGridElement.get()[0].querySelectorAll(".ag-root")[0];
|
|
91
|
-
const agGridSelectors = agGridColumnSelectors.split("^");
|
|
92
|
-
const headers = [
|
|
93
|
-
...tableElement.querySelectorAll(".ag-header-row-column [aria-colindex]"),
|
|
94
|
-
]
|
|
95
|
-
.sort(sortElementsByAttributeValue("aria-colindex"))
|
|
96
|
-
.map((headerElement) => {
|
|
97
|
-
// Check if the elements returned are already .ag-header-cell-text elements
|
|
98
|
-
// If not, query for that element and return the text content
|
|
99
|
-
let headerCells = [
|
|
100
|
-
...headerElement.querySelectorAll(".ag-header-cell-text"),
|
|
101
|
-
];
|
|
102
|
-
if (headerCells.length === 0) {
|
|
103
|
-
return [headerElement].map((e) => e.textContent.trim());
|
|
104
|
-
} else {
|
|
105
|
-
return [...headerElement.querySelectorAll(".ag-header-cell-text")].map(
|
|
106
|
-
(e) => e.textContent.trim()
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
})
|
|
110
|
-
.flat();
|
|
111
|
-
|
|
112
|
-
let allRows = [];
|
|
113
|
-
let rows = [];
|
|
114
|
-
|
|
115
|
-
agGridSelectors.forEach((selector) => {
|
|
116
|
-
const _rows = [
|
|
117
|
-
...tableElement.querySelectorAll(
|
|
118
|
-
`${selector}:not(.ag-hidden) .ag-row:not(.ag-opacity-zero)`
|
|
119
|
-
),
|
|
120
|
-
]
|
|
121
|
-
// When animation is enabled, ag-grid destroys rows in 2 phases,
|
|
122
|
-
// first it runs an animation to place rows to be destroyed just outside
|
|
123
|
-
// the viewport.
|
|
124
|
-
// In the second phase those rows are removed from the DOM.
|
|
125
|
-
// Because we get here AFTER all animations are finished, it is possible,
|
|
126
|
-
// those rows are still in the DOM, but are not visible.
|
|
127
|
-
// therefore those rows should be filtered out.
|
|
128
|
-
.filter(isRowNotDestroyed)
|
|
129
|
-
// Sort rows by their row-index attribute value
|
|
130
|
-
.sort(sortElementsByAttributeValue("row-index"))
|
|
131
|
-
.map((row) => {
|
|
132
|
-
// Sort row cells by their aria-colindex attribute value
|
|
133
|
-
// First check if elements returned already contain the aria-colindex
|
|
134
|
-
// If not, just query for the .ag-cell
|
|
135
|
-
let rowCells = [...row.querySelectorAll(".ag-cell[aria-colindex]")];
|
|
136
|
-
if (rowCells.length === 0) {
|
|
137
|
-
rowCells = [...row.querySelectorAll(".ag-cell")];
|
|
138
|
-
}
|
|
139
|
-
const rowIndex = parseInt(
|
|
140
|
-
row.attributes["row-index"].nodeValue,
|
|
141
|
-
10
|
|
142
|
-
).valueOf();
|
|
143
|
-
|
|
144
|
-
if (allRows[rowIndex]) {
|
|
145
|
-
allRows[rowIndex] = [...allRows[rowIndex], ...rowCells];
|
|
146
|
-
} else {
|
|
147
|
-
allRows[rowIndex] = rowCells;
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
// Remove any empty arrays before merging
|
|
152
|
-
allRows = allRows.filter(function (ele) {
|
|
153
|
-
return ele.length;
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
// Remove duplicate entries from allRows
|
|
157
|
-
// In some instances we see cell duplication for non-unique rows
|
|
158
|
-
allRows = allRows.map((row) => {
|
|
159
|
-
return row.filter((cell, index) => {
|
|
160
|
-
return row.indexOf(cell) === index;
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
if (!allRows.length) rows = [];
|
|
165
|
-
else {
|
|
166
|
-
rows = allRows
|
|
167
|
-
.filter((rowCells) => rowCells.length)
|
|
168
|
-
.map((rowCells) =>
|
|
169
|
-
rowCells
|
|
170
|
-
.sort(sortElementsByAttributeValue("aria-colindex"))
|
|
171
|
-
.map((e) => {
|
|
172
|
-
if (returnElements) {
|
|
173
|
-
return e;
|
|
174
|
-
} else {
|
|
175
|
-
return e.textContent.trim();
|
|
176
|
-
}
|
|
177
|
-
})
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
// if options.rawValues = true, return headers & rows values as arrays instead of mapping as objects
|
|
181
|
-
if (options.valuesArray) {
|
|
182
|
-
return { headers, rows };
|
|
183
|
-
}
|
|
184
|
-
// return structured object from headers and rows variables
|
|
185
|
-
return rows.map((row) =>
|
|
186
|
-
row.reduce((acc, curr, idx) => {
|
|
187
|
-
if (
|
|
188
|
-
//@ts-ignore
|
|
189
|
-
(options.onlyColumns && !options.onlyColumns.includes(headers[idx])) ||
|
|
190
|
-
headers[idx] === undefined
|
|
191
|
-
) {
|
|
192
|
-
// dont include columns that are not present in onlyColumns, or if the header is undefined
|
|
193
|
-
return { ...acc };
|
|
194
|
-
}
|
|
195
|
-
return { ...acc, [headers[idx]]: curr };
|
|
196
|
-
}, {})
|
|
47
|
+
return extractAgGridElements(
|
|
48
|
+
getSingleAgGridRootElement(agGridElement),
|
|
49
|
+
options
|
|
197
50
|
);
|
|
198
|
-
}
|
|
51
|
+
};
|
|
199
52
|
|
|
200
53
|
/**
|
|
201
54
|
* Retrieve the ag grid column header element based on its column name value
|
package/.circleci/config.yml
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Use the latest 2.1 version of CircleCI pipeline process engine.
|
|
2
|
-
# See: https://circleci.com/docs/2.0/configuration-reference
|
|
3
|
-
version: 2.1
|
|
4
|
-
|
|
5
|
-
orbs:
|
|
6
|
-
# "cypress-io/cypress@1" installs the latest published
|
|
7
|
-
# version "1.x.y" of the orb. We recommend you then use
|
|
8
|
-
# the strict explicit version "cypress-io/cypress@1.x.y"
|
|
9
|
-
# to lock the version and prevent unexpected CI changes
|
|
10
|
-
cypress: cypress-io/cypress@3
|
|
11
|
-
workflows:
|
|
12
|
-
run_cypress_tests:
|
|
13
|
-
jobs:
|
|
14
|
-
- cypress/run # "run" job comes from "cypress" orb
|