@rickcedwhat/playwright-smart-table 6.3.2 → 6.5.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 +8 -0
- package/dist/engine/rowFinder.d.ts +4 -1
- package/dist/engine/rowFinder.js +38 -15
- package/dist/filterEngine.js +9 -4
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/minimalConfigContext.d.ts +6 -0
- package/dist/minimalConfigContext.js +78 -0
- package/dist/plugins.d.ts +7 -0
- package/dist/smartRow.d.ts +1 -1
- package/dist/smartRow.js +62 -29
- package/dist/strategies/fill.d.ts +1 -1
- package/dist/strategies/fill.js +19 -3
- package/dist/strategies/index.d.ts +9 -1
- package/dist/strategies/pagination.d.ts +17 -2
- package/dist/strategies/pagination.js +65 -43
- package/dist/strategies/rdg.d.ts +14 -0
- package/dist/strategies/rdg.js +43 -1
- package/dist/typeContext.d.ts +1 -1
- package/dist/typeContext.js +61 -32
- package/dist/types.d.ts +49 -36
- package/dist/useTable.d.ts +1 -43
- package/dist/useTable.js +54 -42
- package/package.json +3 -2
package/dist/useTable.d.ts
CHANGED
|
@@ -1,48 +1,6 @@
|
|
|
1
1
|
import type { Locator } from '@playwright/test';
|
|
2
|
-
import { TableConfig,
|
|
3
|
-
import { FillStrategies } from './strategies/fill';
|
|
4
|
-
import { HeaderStrategies } from './strategies/headers';
|
|
5
|
-
import { CellNavigationStrategies } from './strategies/columns';
|
|
6
|
-
import { ResolutionStrategies } from './strategies/resolution';
|
|
7
|
-
import { Strategies } from './strategies';
|
|
2
|
+
import { TableConfig, TableResult } from './types';
|
|
8
3
|
/**
|
|
9
4
|
* Main hook to interact with a table.
|
|
10
5
|
*/
|
|
11
6
|
export declare const useTable: <T = any>(rootLocator: Locator, configOptions?: TableConfig<T>) => TableResult<T>;
|
|
12
|
-
export declare const PaginationStrategies: {
|
|
13
|
-
clickNext: (nextButtonSelector: Selector, options?: {
|
|
14
|
-
stabilization?: import("./strategies/stabilization").StabilizationStrategy;
|
|
15
|
-
timeout?: number;
|
|
16
|
-
}) => PaginationStrategy;
|
|
17
|
-
infiniteScroll: (options?: {
|
|
18
|
-
action?: "scroll" | "js-scroll";
|
|
19
|
-
scrollTarget?: Selector;
|
|
20
|
-
scrollAmount?: number;
|
|
21
|
-
stabilization?: import("./strategies/stabilization").StabilizationStrategy;
|
|
22
|
-
timeout?: number;
|
|
23
|
-
}) => PaginationStrategy;
|
|
24
|
-
};
|
|
25
|
-
export declare const LoadingStrategies: {
|
|
26
|
-
Table: {
|
|
27
|
-
hasSpinner: (selector?: string) => ({ root }: TableContext) => Promise<boolean>;
|
|
28
|
-
custom: (fn: (context: TableContext) => Promise<boolean>) => (context: TableContext) => Promise<boolean>;
|
|
29
|
-
never: () => Promise<boolean>;
|
|
30
|
-
};
|
|
31
|
-
Row: {
|
|
32
|
-
hasClass: (className?: string) => (row: SmartRowType) => Promise<boolean>;
|
|
33
|
-
hasText: (text?: string | RegExp) => (row: SmartRowType) => Promise<boolean>;
|
|
34
|
-
hasEmptyCells: () => (row: SmartRowType) => Promise<boolean>;
|
|
35
|
-
never: () => Promise<boolean>;
|
|
36
|
-
};
|
|
37
|
-
Headers: {
|
|
38
|
-
stable: (duration?: number) => (context: TableContext) => Promise<boolean>;
|
|
39
|
-
never: () => Promise<boolean>;
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
export declare const SortingStrategies: {
|
|
43
|
-
AriaSort: () => import("./types").SortingStrategy;
|
|
44
|
-
};
|
|
45
|
-
export declare const DedupeStrategies: {
|
|
46
|
-
byTopPosition: (tolerance?: number) => DedupeStrategy;
|
|
47
|
-
};
|
|
48
|
-
export { FillStrategies, HeaderStrategies, CellNavigationStrategies, ResolutionStrategies, Strategies };
|
package/dist/useTable.js
CHANGED
|
@@ -9,26 +9,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const pagination_1 = require("./strategies/pagination");
|
|
16
|
-
const dedupe_1 = require("./strategies/dedupe");
|
|
12
|
+
exports.useTable = void 0;
|
|
13
|
+
const minimalConfigContext_1 = require("./minimalConfigContext");
|
|
14
|
+
const validation_1 = require("./strategies/validation");
|
|
17
15
|
const loading_1 = require("./strategies/loading");
|
|
18
16
|
const fill_1 = require("./strategies/fill");
|
|
19
|
-
Object.defineProperty(exports, "FillStrategies", { enumerable: true, get: function () { return fill_1.FillStrategies; } });
|
|
20
17
|
const headers_1 = require("./strategies/headers");
|
|
21
|
-
Object.defineProperty(exports, "HeaderStrategies", { enumerable: true, get: function () { return headers_1.HeaderStrategies; } });
|
|
22
|
-
const columns_1 = require("./strategies/columns");
|
|
23
|
-
Object.defineProperty(exports, "CellNavigationStrategies", { enumerable: true, get: function () { return columns_1.CellNavigationStrategies; } });
|
|
24
18
|
const smartRow_1 = require("./smartRow");
|
|
25
19
|
const filterEngine_1 = require("./filterEngine");
|
|
26
20
|
const tableMapper_1 = require("./engine/tableMapper");
|
|
27
21
|
const rowFinder_1 = require("./engine/rowFinder");
|
|
28
|
-
const resolution_1 = require("./strategies/resolution");
|
|
29
|
-
Object.defineProperty(exports, "ResolutionStrategies", { enumerable: true, get: function () { return resolution_1.ResolutionStrategies; } });
|
|
30
|
-
const strategies_1 = require("./strategies");
|
|
31
|
-
Object.defineProperty(exports, "Strategies", { enumerable: true, get: function () { return strategies_1.Strategies; } });
|
|
32
22
|
const debugUtils_1 = require("./utils/debugUtils");
|
|
33
23
|
const smartRowArray_1 = require("./utils/smartRowArray");
|
|
34
24
|
/**
|
|
@@ -42,7 +32,6 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
42
32
|
const defaultStrategies = {
|
|
43
33
|
fill: fill_1.FillStrategies.default,
|
|
44
34
|
header: headers_1.HeaderStrategies.visible,
|
|
45
|
-
cellNavigation: columns_1.CellNavigationStrategies.default,
|
|
46
35
|
pagination: () => __awaiter(void 0, void 0, void 0, function* () { return false; }),
|
|
47
36
|
loading: {
|
|
48
37
|
isHeaderLoading: loading_1.LoadingStrategies.Headers.stable(200)
|
|
@@ -87,10 +76,11 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
87
76
|
// Placeholder for the final table object
|
|
88
77
|
let finalTable = null;
|
|
89
78
|
// Helper factory
|
|
90
|
-
const _makeSmart = (rowLocator, map, rowIndex) => {
|
|
91
|
-
return (0, smartRow_1.createSmartRow)(rowLocator, map, rowIndex, config, rootLocator, resolve, finalTable);
|
|
79
|
+
const _makeSmart = (rowLocator, map, rowIndex, tablePageIndex) => {
|
|
80
|
+
return (0, smartRow_1.createSmartRow)(rowLocator, map, rowIndex, config, rootLocator, resolve, finalTable, tablePageIndex);
|
|
92
81
|
};
|
|
93
|
-
const
|
|
82
|
+
const tableState = { currentPageIndex: 0 };
|
|
83
|
+
const rowFinder = new rowFinder_1.RowFinder(rootLocator, config, resolve, filterEngine, tableMapper, _makeSmart, tableState);
|
|
94
84
|
const _getCleanHtml = (loc) => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
85
|
return loc.evaluate((el) => {
|
|
96
86
|
const clone = el.cloneNode(true);
|
|
@@ -117,7 +107,7 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
117
107
|
const { output = 'console', includeTypes = true } = options;
|
|
118
108
|
let finalPrompt = content;
|
|
119
109
|
if (includeTypes) {
|
|
120
|
-
finalPrompt += `\n\n👇 Useful TypeScript Definitions 👇\n\`\`\`typescript\n${
|
|
110
|
+
finalPrompt += `\n\n👇 Useful TypeScript Definitions 👇\n\`\`\`typescript\n${minimalConfigContext_1.MINIMAL_CONFIG_CONTEXT}\n\`\`\`\n`;
|
|
121
111
|
}
|
|
122
112
|
if (output === 'error') {
|
|
123
113
|
console.log(`⚠️ Throwing error to display [${promptName}] cleanly...`);
|
|
@@ -129,6 +119,8 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
129
119
|
yield tableMapper.getMap();
|
|
130
120
|
});
|
|
131
121
|
const result = {
|
|
122
|
+
get currentPageIndex() { return tableState.currentPageIndex; },
|
|
123
|
+
set currentPageIndex(v) { tableState.currentPageIndex = v; },
|
|
132
124
|
init: (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
133
125
|
if (tableMapper.isInitialized())
|
|
134
126
|
return result;
|
|
@@ -144,14 +136,9 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
144
136
|
const idx = map.get(columnName);
|
|
145
137
|
if (idx === undefined)
|
|
146
138
|
throw _createColumnError(columnName, map);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
page: rootLocator.page(),
|
|
151
|
-
resolve,
|
|
152
|
-
column: columnName,
|
|
153
|
-
index: idx
|
|
154
|
-
});
|
|
139
|
+
// Use header cell for scrolling
|
|
140
|
+
const headerCell = resolve(config.headerSelector, rootLocator).nth(idx);
|
|
141
|
+
yield headerCell.scrollIntoViewIfNeeded();
|
|
155
142
|
}),
|
|
156
143
|
getHeaders: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
157
144
|
const map = yield tableMapper.getMap();
|
|
@@ -185,7 +172,7 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
185
172
|
throw _createColumnError(column, map);
|
|
186
173
|
const mapper = (_a = options === null || options === void 0 ? void 0 : options.mapper) !== null && _a !== void 0 ? _a : ((c) => c.innerText());
|
|
187
174
|
const effectiveMaxPages = (_b = options === null || options === void 0 ? void 0 : options.maxPages) !== null && _b !== void 0 ? _b : config.maxPages;
|
|
188
|
-
let
|
|
175
|
+
let pagesScanned = 1;
|
|
189
176
|
const results = [];
|
|
190
177
|
log(`Getting column values for '${column}' (Pages: ${effectiveMaxPages})`);
|
|
191
178
|
while (true) {
|
|
@@ -196,11 +183,23 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
196
183
|
: resolve(config.cellSelector, row).nth(colIdx);
|
|
197
184
|
results.push(yield mapper(cell));
|
|
198
185
|
}
|
|
199
|
-
if (
|
|
186
|
+
if (pagesScanned < effectiveMaxPages) {
|
|
200
187
|
const context = { root: rootLocator, config, page: rootLocator.page(), resolve };
|
|
201
|
-
|
|
188
|
+
let pageRes;
|
|
189
|
+
if (typeof config.strategies.pagination === 'function') {
|
|
190
|
+
pageRes = yield config.strategies.pagination(context);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
if (!config.strategies.pagination.goNext) {
|
|
194
|
+
log('Cannot paginate: no goNext primitive found.');
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
pageRes = yield config.strategies.pagination.goNext(context);
|
|
198
|
+
}
|
|
199
|
+
if (yield (0, validation_1.validatePaginationResult)(pageRes, 'Pagination Strategy')) {
|
|
202
200
|
_hasPaginated = true;
|
|
203
|
-
|
|
201
|
+
tableState.currentPageIndex++;
|
|
202
|
+
pagesScanned++;
|
|
204
203
|
continue;
|
|
205
204
|
}
|
|
206
205
|
}
|
|
@@ -228,11 +227,6 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
228
227
|
// @ts-ignore
|
|
229
228
|
return rowFinder.findRow(filters, options);
|
|
230
229
|
}),
|
|
231
|
-
getRows: (options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
232
|
-
console.warn('DEPRECATED: table.getRows() is deprecated and will be removed in a future version. Use table.findRows() instead.');
|
|
233
|
-
// @ts-ignore
|
|
234
|
-
return rowFinder.findRows((options === null || options === void 0 ? void 0 : options.filter) || {}, Object.assign(Object.assign({}, options), { maxPages: 1 }));
|
|
235
|
-
}),
|
|
236
230
|
findRows: (filters, options) => __awaiter(void 0, void 0, void 0, function* () {
|
|
237
231
|
return rowFinder.findRows(filters, options);
|
|
238
232
|
}),
|
|
@@ -267,13 +261,13 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
267
261
|
yield result.init();
|
|
268
262
|
const map = tableMapper.getMapSync();
|
|
269
263
|
const restrictedTable = {
|
|
264
|
+
get currentPageIndex() { return tableState.currentPageIndex; },
|
|
270
265
|
init: result.init,
|
|
271
266
|
getHeaders: result.getHeaders,
|
|
272
267
|
getHeaderCell: result.getHeaderCell,
|
|
273
268
|
getRow: result.getRow,
|
|
274
269
|
getRowByIndex: result.getRowByIndex,
|
|
275
270
|
findRow: result.findRow,
|
|
276
|
-
getRows: result.getRows,
|
|
277
271
|
findRows: result.findRows,
|
|
278
272
|
getColumnValues: result.getColumnValues,
|
|
279
273
|
isInitialized: result.isInitialized,
|
|
@@ -362,10 +356,20 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
362
356
|
let finalIsLast = isLastDueToMax;
|
|
363
357
|
if (!isLastIteration) {
|
|
364
358
|
const context = { root: rootLocator, config, page: rootLocator.page(), resolve };
|
|
365
|
-
|
|
359
|
+
if (typeof paginationStrategy === 'function') {
|
|
360
|
+
paginationResult = yield paginationStrategy(context);
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
const pageObj = paginationStrategy;
|
|
364
|
+
if (!pageObj.goNext)
|
|
365
|
+
break;
|
|
366
|
+
paginationResult = yield pageObj.goNext(context);
|
|
367
|
+
}
|
|
366
368
|
(0, debugUtils_1.logDebug)(config, 'info', `Pagination ${paginationResult ? 'succeeded' : 'failed'}`);
|
|
367
369
|
yield (0, debugUtils_1.debugDelay)(config, 'pagination');
|
|
368
370
|
finalIsLast = getIsLast({ index: callbackIndex, paginationResult }) || !paginationResult;
|
|
371
|
+
if (paginationResult)
|
|
372
|
+
tableState.currentPageIndex++;
|
|
369
373
|
}
|
|
370
374
|
if (finalIsLast && (options === null || options === void 0 ? void 0 : options.afterLast)) {
|
|
371
375
|
yield options.afterLast({ index: callbackIndex, rows: (0, smartRowArray_1.createSmartRowArray)(callbackRows), allData });
|
|
@@ -383,9 +387,21 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
383
387
|
else {
|
|
384
388
|
// Continue paginating even when batching
|
|
385
389
|
const context = { root: rootLocator, config, page: rootLocator.page(), resolve };
|
|
386
|
-
|
|
390
|
+
if (typeof paginationStrategy === 'function') {
|
|
391
|
+
paginationResult = yield paginationStrategy(context);
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
const pageObj = paginationStrategy;
|
|
395
|
+
if (!pageObj.goNext) {
|
|
396
|
+
log(`Cannot paginate: no goNext primitive found.`);
|
|
397
|
+
break;
|
|
398
|
+
}
|
|
399
|
+
paginationResult = yield pageObj.goNext(context);
|
|
400
|
+
}
|
|
387
401
|
(0, debugUtils_1.logDebug)(config, 'info', `Pagination ${paginationResult ? 'succeeded' : 'failed'} (batching mode)`);
|
|
388
402
|
yield (0, debugUtils_1.debugDelay)(config, 'pagination');
|
|
403
|
+
if (paginationResult)
|
|
404
|
+
tableState.currentPageIndex++;
|
|
389
405
|
if (!paginationResult) {
|
|
390
406
|
// Pagination failed, invoke callback with current batch
|
|
391
407
|
const callbackIndex = batchStartIndex;
|
|
@@ -438,7 +454,3 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
438
454
|
return result;
|
|
439
455
|
};
|
|
440
456
|
exports.useTable = useTable;
|
|
441
|
-
exports.PaginationStrategies = Object.assign({}, pagination_1.PaginationStrategies);
|
|
442
|
-
exports.LoadingStrategies = loading_1.LoadingStrategies;
|
|
443
|
-
exports.SortingStrategies = sorting_1.SortingStrategies;
|
|
444
|
-
exports.DedupeStrategies = dedupe_1.DedupeStrategies;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rickcedwhat/playwright-smart-table",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.5.0",
|
|
4
4
|
"description": "Smart, column-aware table interactions for Playwright",
|
|
5
5
|
"author": "Cedrick Catalan",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,12 +15,13 @@
|
|
|
15
15
|
],
|
|
16
16
|
"scripts": {
|
|
17
17
|
"generate-types": "node scripts/embed-types.mjs",
|
|
18
|
+
"generate-config-types": "node scripts/embed-config-types.mjs",
|
|
18
19
|
"generate-docs": "node scripts/generate-readme.mjs",
|
|
19
20
|
"generate-all-api-docs": "node scripts/generate-all-api-docs.mjs",
|
|
20
21
|
"update-all-api-signatures": "node scripts/update-all-api-signatures.mjs",
|
|
21
22
|
"docs:dev": "vitepress dev docs",
|
|
22
23
|
"docs:build": "vitepress build docs",
|
|
23
|
-
"build": "npm run generate-types && npm run generate-docs && npm run generate-all-api-docs && npm run update-all-api-signatures && tsc",
|
|
24
|
+
"build": "npm run generate-types && npm run generate-config-types && npm run generate-docs && npm run generate-all-api-docs && npm run update-all-api-signatures && tsc",
|
|
24
25
|
"prepublishOnly": "npm run build",
|
|
25
26
|
"test": "npm run test:unit && npx playwright test",
|
|
26
27
|
"test:unit": "vitest run --reporter=verbose --reporter=html",
|