@globisnv/cypress-core 1.1.1 → 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
|
@@ -34,6 +34,7 @@ See [Cutting a release](#cutting-a-release) for how a bump actually gets publish
|
|
|
34
34
|
|
|
35
35
|
| Core version | Minimum globis-online version |
|
|
36
36
|
| --- | --- |
|
|
37
|
+
| `2.0.0` | `11.0.3` |
|
|
37
38
|
| `0.0.1` | `11.0.2` |
|
|
38
39
|
|
|
39
40
|
The floor is recorded in `package.json` under `globisOnline.minVersion` (machine-readable, in case tooling wants to check it later) and here in this table (human-readable, updated on every release alongside `CHANGELOG.md`). `globis-cypress` stays pinned to the latest core version — since it's Globis's own suite, it's the first thing to catch a globis-online release breaking something, before any customer repo would.
|
|
@@ -33,6 +33,9 @@ const isGridRowSelector = (baseSelector, index) => {
|
|
|
33
33
|
// rendered-but-scrolled-past rows as hidden (measured: 14 of 21 rendered rows drop out of `:visible`
|
|
34
34
|
// after scrolling a grid to the bottom). Filter on the container, which is what both were after.
|
|
35
35
|
const isInOpenContainer = (_, el) => !el.closest('[hidden]');
|
|
36
|
+
// Data rows of an AG Grid 36 body. Group rows (full-width) share the scrolling container with the data rows,
|
|
37
|
+
// so they are excluded to keep row indexes and counts about data rows only.
|
|
38
|
+
const gridDataRows = '.ag-grid-scrolling-container [row-index]:not(.ag-full-width-row)';
|
|
36
39
|
const pickByRowIndex = (chain, index, log = false, timeout = defaultTimeout) => {
|
|
37
40
|
if (log)
|
|
38
41
|
Cypress.log({ name: 'idx', message: String(index) });
|
|
@@ -756,7 +759,7 @@ const navItem = (topBottom, programName, tabNumber, mode) => {
|
|
|
756
759
|
throw new Error(`Incorrect type for GLO_${mode}Program. Available types: top, bottom`);
|
|
757
760
|
const location = topBottom === top ? 0 : 1;
|
|
758
761
|
const regex = new RegExp(`^${Cypress._.escapeRegExp(programName)}$`);
|
|
759
|
-
cy.get('
|
|
762
|
+
cy.get('[navigation] > [nodelist]')
|
|
760
763
|
.eq(location)
|
|
761
764
|
.within(() => {
|
|
762
765
|
const items = cy
|
|
@@ -1072,13 +1075,13 @@ Cypress.Commands.add('GLO_selectProgram', (topBottom, programName, tabnumber) =>
|
|
|
1072
1075
|
navItem(topBottom, programName, tabnumber, 'select');
|
|
1073
1076
|
});
|
|
1074
1077
|
Cypress.Commands.add('GLO_getRowInGrid', (rowFilter) => {
|
|
1075
|
-
const rows = cy.get(
|
|
1078
|
+
const rows = cy.get(gridDataRows).filter(isInOpenContainer);
|
|
1076
1079
|
return typeof rowFilter === 'number' ? rows.eq(rowFilter) : rows.filter(`:contains("${rowFilter}")`).first();
|
|
1077
1080
|
});
|
|
1078
1081
|
Cypress.Commands.add('GLO_selectRowInGrid', (rowFilter) => {
|
|
1079
1082
|
let found = false;
|
|
1080
1083
|
if (typeof rowFilter === 'number') {
|
|
1081
|
-
cy.get(`[row-id="root_${rowFilter}"]`).filter(isInOpenContainer).find('[data-ref="eInput"]').click();
|
|
1084
|
+
cy.get(`[row-id="root_${rowFilter}"]`).filter(isInOpenContainer).find('.ag-grid-pinned-left-cells [data-ref="eInput"]').click();
|
|
1082
1085
|
return;
|
|
1083
1086
|
}
|
|
1084
1087
|
// Convert to array if it's a string
|
|
@@ -1092,15 +1095,8 @@ Cypress.Commands.add('GLO_selectRowInGrid', (rowFilter) => {
|
|
|
1092
1095
|
const matches = filters.every((filterValue) => cellTexts.some((val) => val.includes(filterValue)));
|
|
1093
1096
|
if (matches) {
|
|
1094
1097
|
found = true;
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
// filter above, so everything inside shares its ancestors. The re-query is only needed
|
|
1098
|
-
// because the checkbox lives in the pinned-left twin carrying the same row-id.
|
|
1099
|
-
cy.wrap($row)
|
|
1100
|
-
.closest('.ag-root')
|
|
1101
|
-
.within(() => {
|
|
1102
|
-
cy.get(`[row-id="${rowId}"]`).find('[data-ref="eInput"]').click();
|
|
1103
|
-
});
|
|
1098
|
+
// AG Grid 36 renders the pinned-left selection checkbox inside the row itself.
|
|
1099
|
+
cy.wrap($row).find('.ag-grid-pinned-left-cells [data-ref="eInput"]').click();
|
|
1104
1100
|
return false; // Stop after the first match
|
|
1105
1101
|
}
|
|
1106
1102
|
})
|
|
@@ -1150,7 +1146,7 @@ const dblClickRowInGrid = (type, value, columnId, equals) => {
|
|
|
1150
1146
|
cy.get('[row-index]:visible')
|
|
1151
1147
|
.find(`[col-id="${columnId}"]`)
|
|
1152
1148
|
.filter(filterSelector, { timeout: 10000 })
|
|
1153
|
-
.parentsUntil('.ag-
|
|
1149
|
+
.parentsUntil('.ag-grid-scrolling-container')
|
|
1154
1150
|
.filter('[row-index]')
|
|
1155
1151
|
.first()
|
|
1156
1152
|
.then(saveValues);
|
|
@@ -1173,7 +1169,7 @@ const dblClickRowInGrid = (type, value, columnId, equals) => {
|
|
|
1173
1169
|
cy.get('[row-index]:visible')
|
|
1174
1170
|
.find(columnId ? `[col-id="${columnId}"] ${span}` : span)
|
|
1175
1171
|
.contains(regex, { timeout: 10000 })
|
|
1176
|
-
.parentsUntil('.ag-
|
|
1172
|
+
.parentsUntil('.ag-grid-scrolling-container')
|
|
1177
1173
|
.filter('[row-index]')
|
|
1178
1174
|
.first()
|
|
1179
1175
|
.then(saveValues);
|
|
@@ -1198,13 +1194,13 @@ const dblClickRowInGrid = (type, value, columnId, equals) => {
|
|
|
1198
1194
|
}
|
|
1199
1195
|
// The actual dblClick on the row
|
|
1200
1196
|
cy.get('@COM_selectedRowSelector').then((selector) => {
|
|
1201
|
-
columnId ? cy.get(selector).find(`[col-id="${columnId}"]`).dblclick() : cy.get(selector).find('[aria-colindex]').eq(1).dblclick();
|
|
1197
|
+
columnId ? cy.get(selector).find(`[col-id="${columnId}"]`).dblclick() : cy.get(selector).find('.ag-grid-scrolling-cells [aria-colindex]').eq(1).dblclick();
|
|
1202
1198
|
});
|
|
1203
1199
|
};
|
|
1204
1200
|
Cypress.Commands.add('GLO_clickRowInGrid', (value, columnId) => {
|
|
1205
1201
|
if (value === undefined)
|
|
1206
1202
|
throw new Error('Value missing for GLO_clickRowInGrid');
|
|
1207
|
-
columnId ? cy.GLO_getRowInGrid(value).find(`[col-id="${columnId}"]`).click() : cy.GLO_getRowInGrid(value).children().first().click();
|
|
1203
|
+
columnId ? cy.GLO_getRowInGrid(value).find(`[col-id="${columnId}"]`).click() : cy.GLO_getRowInGrid(value).find('.ag-grid-scrolling-cells').children().first().click();
|
|
1208
1204
|
cy.GLO_checkLoadingIndicator();
|
|
1209
1205
|
});
|
|
1210
1206
|
// Shared popup-window search + grid selection logic used by GLO_popupWindow.
|
|
@@ -1217,7 +1213,9 @@ const selectFromPopupWindow = (value, columnId, equals = noEqualBool) => {
|
|
|
1217
1213
|
const loadingColumnId = () => columnId
|
|
1218
1214
|
? cy.wrap(columnId)
|
|
1219
1215
|
: cy
|
|
1220
|
-
.get('.svy-dialog.active .window-body .ag-
|
|
1216
|
+
.get('.svy-dialog.active .window-body .ag-grid-scrolling-container [row-index="0"]:not(.ag-full-width-row) .ag-grid-scrolling-cells [role="gridcell"]', {
|
|
1217
|
+
timeout: 30000
|
|
1218
|
+
})
|
|
1221
1219
|
.filter((_, el) => Cypress.$(el).text().trim().length > 0)
|
|
1222
1220
|
.first()
|
|
1223
1221
|
.invoke('attr', 'col-id');
|
|
@@ -1481,13 +1479,15 @@ Cypress.Commands.add('GLO_checkNumberOfRowsInGrid', (selector, numberToValidate,
|
|
|
1481
1479
|
const pollInterval = 5000;
|
|
1482
1480
|
const HEADER_ROWS = 2;
|
|
1483
1481
|
const getAriaRowcount = ($grid) => parseInt($grid.find('[role="grid"]').attr('aria-rowcount') || '0', 10);
|
|
1484
|
-
// Column header row + filter row
|
|
1485
|
-
|
|
1486
|
-
|
|
1482
|
+
// Column header row + filter row (AG Grid 36 renders each header row once, pinned cells included).
|
|
1483
|
+
const headerRowCount = ($grid) => $grid.find('.ag-header .ag-header-row').length || HEADER_ROWS;
|
|
1484
|
+
// Rows aria-rowcount counts that are not data rows: header rows plus pinned top/bottom rows (e.g. a totals
|
|
1485
|
+
// row), which AG Grid 36 includes in aria-rowcount. Pinned rows are never virtualised, so the DOM count is exact.
|
|
1486
|
+
const nonDataRowCount = ($grid) => headerRowCount($grid) + $grid.find('.ag-row-pinned').length;
|
|
1487
1487
|
const isLazyLoaded = ($grid) => {
|
|
1488
1488
|
const ariaRowcount = getAriaRowcount($grid);
|
|
1489
|
-
const renderedRows = $grid.find(
|
|
1490
|
-
return renderedRows > 0 && (ariaRowcount === -1 || ariaRowcount > renderedRows +
|
|
1489
|
+
const renderedRows = $grid.find(gridDataRows).length;
|
|
1490
|
+
return renderedRows > 0 && (ariaRowcount === -1 || ariaRowcount > renderedRows + nonDataRowCount($grid));
|
|
1491
1491
|
};
|
|
1492
1492
|
// When a client-side column filter is active, the tab-/datacontrol-counter still shows the
|
|
1493
1493
|
// unfiltered foundset total, so we must count the rendered (filtered) rows instead.
|
|
@@ -1509,12 +1509,12 @@ Cypress.Commands.add('GLO_checkNumberOfRowsInGrid', (selector, numberToValidate,
|
|
|
1509
1509
|
const total = parseInt(parts[1].trim(), 10);
|
|
1510
1510
|
return Number.isNaN(total) ? null : total;
|
|
1511
1511
|
};
|
|
1512
|
-
// AG Grid publishes the displayed row total (header rows included
|
|
1513
|
-
//
|
|
1514
|
-
//
|
|
1515
|
-
//
|
|
1512
|
+
// AG Grid publishes the displayed row total (header and pinned rows included) in aria-rowcount,
|
|
1513
|
+
// so a virtualised grid still reports rows the viewport never rendered. Verified on
|
|
1514
|
+
// ng$consignment_dtl_general.grid: 25 goods -> aria-rowcount 27 with 2 header rows, while only
|
|
1515
|
+
// 12 rows exist in the DOM.
|
|
1516
1516
|
const getCountFromAriaRowcount = ($grid) => {
|
|
1517
|
-
const total = getAriaRowcount($grid) -
|
|
1517
|
+
const total = getAriaRowcount($grid) - nonDataRowCount($grid);
|
|
1518
1518
|
return total >= 0 ? total : null; // An aria-rowcount of -1 means the total is unknown (infinite row model)
|
|
1519
1519
|
};
|
|
1520
1520
|
// Form-level counters (#txtCount navigator, tab "(n)" label) only match a grid on list
|
|
@@ -1558,7 +1558,7 @@ Cypress.Commands.add('GLO_checkNumberOfRowsInGrid', (selector, numberToValidate,
|
|
|
1558
1558
|
runChainAssertion(tabCount);
|
|
1559
1559
|
}
|
|
1560
1560
|
else {
|
|
1561
|
-
runChainAssertion($grid.find(
|
|
1561
|
+
runChainAssertion($grid.find(gridDataRows));
|
|
1562
1562
|
}
|
|
1563
1563
|
});
|
|
1564
1564
|
}
|
|
@@ -1569,7 +1569,7 @@ Cypress.Commands.add('GLO_checkNumberOfRowsInGrid', (selector, numberToValidate,
|
|
|
1569
1569
|
const log = Cypress.log({ name: 'checkNumberOfRowsInGrid', message: `Polling rows (${lengthCondition} ${numberToValidate})…`, autoEnd: false, timeout: 0 });
|
|
1570
1570
|
const checkStatus = (resolve, reject) => {
|
|
1571
1571
|
cy.GLO_getElement(selector, { timeout: timeOut, log: false }).then(($grid) => {
|
|
1572
|
-
const $rows = $grid.find(
|
|
1572
|
+
const $rows = $grid.find(gridDataRows);
|
|
1573
1573
|
let actual = $rows.length;
|
|
1574
1574
|
let passed = false;
|
|
1575
1575
|
try {
|
|
@@ -1768,7 +1768,7 @@ Cypress.Commands.add('GLO_selectRows', (selector, rowNumber) => {
|
|
|
1768
1768
|
}
|
|
1769
1769
|
};
|
|
1770
1770
|
cy.GLO_getElement(selector)
|
|
1771
|
-
.find('.ag-
|
|
1771
|
+
.find('.ag-grid-scrolling-rows')
|
|
1772
1772
|
.within(() => {
|
|
1773
1773
|
cy.GLO_clickRowInGrid(0); // Always click the first row
|
|
1774
1774
|
if (rowNumber !== undefined) {
|
|
@@ -1783,7 +1783,7 @@ Cypress.Commands.add('GLO_selectRows', (selector, rowNumber) => {
|
|
|
1783
1783
|
});
|
|
1784
1784
|
Cypress.Commands.add('GLO_sortGrid', (selector, headerText) => {
|
|
1785
1785
|
cy.GLO_getElement(selector)
|
|
1786
|
-
.find('.ag-header
|
|
1786
|
+
.find('.ag-header .ag-header-row.ag-header-row-column')
|
|
1787
1787
|
.within(() => {
|
|
1788
1788
|
cy.get('.ag-header-cell').contains(headerText).click();
|
|
1789
1789
|
});
|
|
@@ -1966,14 +1966,15 @@ Cypress.Commands.add('GLO_getAllRowsInGrid', (selector, timeOut = defaultTimeout
|
|
|
1966
1966
|
const deadline = Date.now() + timeOut;
|
|
1967
1967
|
return cy
|
|
1968
1968
|
.GLO_getElement(selector, { timeout: timeOut })
|
|
1969
|
-
.find(
|
|
1969
|
+
.find(gridDataRows, { timeout: timeOut + 500 })
|
|
1970
1970
|
.should(($rows) => {
|
|
1971
1971
|
if ($rows.length === 0 && Date.now() < deadline)
|
|
1972
1972
|
throw new Error('GLO_getAllRowsInGrid: waiting for rows');
|
|
1973
1973
|
});
|
|
1974
1974
|
}
|
|
1975
1975
|
else {
|
|
1976
|
-
|
|
1976
|
+
// AG Grid 36 nests cells in pinned/scrolling wrappers, so a cell's parent is no longer the row.
|
|
1977
|
+
return cy.get(`${gridDataRows}:has([role="gridcell"])`, { timeout: timeOut }).filter(isInOpenContainer);
|
|
1977
1978
|
}
|
|
1978
1979
|
});
|
|
1979
1980
|
Cypress.Commands.add('GLO_validateGridOrFail', (waitValue, failValue, rowNumber, columnId, timeOut = 600000, interval = 15000) => {
|
|
@@ -19,15 +19,15 @@ Cypress.Commands.add('GLS_mainNavigation', (value) => {
|
|
|
19
19
|
throw new Error(`Could not find menu item: ${value}`);
|
|
20
20
|
}
|
|
21
21
|
return cy
|
|
22
|
-
.get('.ag-
|
|
22
|
+
.get('.ag-grid-scrolling-rows')
|
|
23
23
|
.first()
|
|
24
24
|
.then(($viewport) => {
|
|
25
25
|
const $label = $viewport.find('label').filter((_i, el) => el.innerText.trim() === value);
|
|
26
26
|
if ($label.length > 0 && $label.is(':visible')) {
|
|
27
|
-
return cy.contains('.ag-
|
|
27
|
+
return cy.contains('.ag-grid-scrolling-rows label', value).click();
|
|
28
28
|
}
|
|
29
29
|
return cy
|
|
30
|
-
.get('.ag-
|
|
30
|
+
.get('.ag-grid-scrolling-container [role="row"][tabindex="0"]')
|
|
31
31
|
.first()
|
|
32
32
|
.focus()
|
|
33
33
|
.realPress('ArrowDown')
|
|
@@ -65,7 +65,7 @@ Cypress.Commands.add('POR_clickTopDropdownMenu', (linkText) => {
|
|
|
65
65
|
});
|
|
66
66
|
Cypress.Commands.add('POR_checkTableHasData', () => {
|
|
67
67
|
cy.GLO_getElement(['ep$consignment_lst', 'shipments_grid']).within(() => {
|
|
68
|
-
cy.get('.ag-
|
|
68
|
+
cy.get('.ag-grid-scrolling-container').POR_isNotEmpty();
|
|
69
69
|
});
|
|
70
70
|
});
|
|
71
71
|
Cypress.Commands.add('POR_isNotEmpty', { prevSubject: true }, (subject, className) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@globisnv/cypress-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Core building blocks for Globis Cypress E2E tests",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"access": "public"
|
|
16
16
|
},
|
|
17
17
|
"globisOnline": {
|
|
18
|
-
"minVersion": "11.0.
|
|
18
|
+
"minVersion": "11.0.3"
|
|
19
19
|
},
|
|
20
20
|
"exports": {
|
|
21
21
|
".": "./dist/index.js",
|