@rickcedwhat/playwright-smart-table 6.20.1-next.720a2e5 → 6.20.1-next.a5f5df2
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/dist/engine/rowFinder.js +58 -62
- package/dist/engine/scanPages.d.ts +58 -0
- package/dist/engine/scanPages.js +46 -0
- package/dist/engine/tableIteration.d.ts +1 -0
- package/dist/engine/tableIteration.js +35 -20
- package/dist/filterEngine.d.ts +4 -0
- package/dist/filterEngine.js +15 -4
- package/dist/index.d.ts +6 -2
- package/dist/index.js +5 -1
- package/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/plugins/index.d.ts +51 -10
- package/dist/plugins/index.js +14 -6
- package/dist/presets/glide/index.d.ts +1 -1
- package/dist/presets/glide/index.js +2 -2
- package/dist/presets/rdg.d.ts +1 -1
- package/dist/presets/rdg.js +4 -4
- package/dist/smartRow.d.ts +2 -2
- package/dist/smartRow.js +160 -49
- package/dist/strategies/columns.d.ts +5 -9
- package/dist/strategies/columns.js +0 -10
- package/dist/strategies/contentReady.d.ts +20 -0
- package/dist/strategies/contentReady.js +62 -0
- package/dist/strategies/filter.d.ts +0 -4
- package/dist/strategies/filter.js +0 -16
- package/dist/strategies/index.d.ts +23 -15
- package/dist/strategies/index.js +9 -5
- package/dist/typeContext.d.ts +1 -1
- package/dist/typeContext.js +45 -1
- package/dist/types.d.ts +43 -1
- package/dist/useTable.js +95 -42
- package/dist/utils/resolveCellLocator.d.ts +35 -0
- package/dist/utils/resolveCellLocator.js +52 -0
- package/package.json +1 -1
package/dist/types.d.ts
CHANGED
|
@@ -269,6 +269,9 @@ export type SmartRow<T = any> = Locator & {
|
|
|
269
269
|
* Scrolls/paginates to bring this row into view.
|
|
270
270
|
* Works when row position metadata is known (e.g., from getRowByIndex, findRow,
|
|
271
271
|
* findRows, filter, or async iteration).
|
|
272
|
+
*
|
|
273
|
+
* Prefers `strategies.viewport.scrollToRow` when configured; otherwise falls back to
|
|
274
|
+
* Playwright `scrollIntoViewIfNeeded()`.
|
|
272
275
|
* @throws Error if row position metadata is unknown
|
|
273
276
|
*/
|
|
274
277
|
bringIntoView(): Promise<void>;
|
|
@@ -292,6 +295,12 @@ export type SmartRow<T = any> = Locator & {
|
|
|
292
295
|
smartFill: (data: Partial<T> | Record<string, any>, options?: FillOptions) => Promise<void>;
|
|
293
296
|
/**
|
|
294
297
|
* Get the resolved value of any column — real, override, or synthetic.
|
|
298
|
+
*
|
|
299
|
+
* When `strategies.viewport` or `strategies.navigation` is configured, runs the same
|
|
300
|
+
* cell-navigation pipeline as `toJSON` / `getCell().bringIntoView()` so off-screen
|
|
301
|
+
* virtualized cells are mounted before reading. Without those strategies, reads the
|
|
302
|
+
* current DOM cell (Playwright auto-wait).
|
|
303
|
+
*
|
|
295
304
|
* @param column - Column name (case-sensitive)
|
|
296
305
|
* @returns The column value as a string
|
|
297
306
|
*/
|
|
@@ -403,6 +412,7 @@ export interface PaginationPrimitives {
|
|
|
403
412
|
}
|
|
404
413
|
export type PaginationStrategy = PaginationPrimitives;
|
|
405
414
|
export type DedupeStrategy = (row: SmartRow) => string | number | Promise<string | number>;
|
|
415
|
+
export type ContentReadyStrategy = (row: Locator, page: Page) => Promise<void>;
|
|
406
416
|
export type FillStrategy = (options: {
|
|
407
417
|
row: SmartRow;
|
|
408
418
|
columnName: string;
|
|
@@ -467,6 +477,7 @@ export interface ColumnOverride<TValue = any> {
|
|
|
467
477
|
import { HeaderStrategy } from './strategies/headers';
|
|
468
478
|
export type { HeaderStrategy } from './strategies/headers';
|
|
469
479
|
import { NavigationPrimitives } from './strategies/columns';
|
|
480
|
+
export type { NavigationPrimitives, CellNavigationStrategy } from './strategies/columns';
|
|
470
481
|
/**
|
|
471
482
|
* Strategy to resolve column names (string or regex) to their index.
|
|
472
483
|
*/
|
|
@@ -597,6 +608,23 @@ export interface TableStrategies {
|
|
|
597
608
|
* }
|
|
598
609
|
*/
|
|
599
610
|
resolveRowIndex?: (row: Locator) => Promise<RowIndexResult | undefined>;
|
|
611
|
+
/**
|
|
612
|
+
* Waits until a row's content has stabilized before cloning in
|
|
613
|
+
* `toJSON({ atomic: true })`. Needed for recycling virtualizers where the
|
|
614
|
+
* framework updates element positions synchronously but renders cell content
|
|
615
|
+
* asynchronously (e.g. react-window, react-virtuoso with React concurrent mode).
|
|
616
|
+
*
|
|
617
|
+
* Without this, the clone captures stale content from the previous occupant of the
|
|
618
|
+
* DOM slot — the element is at the correct position but React hasn't re-rendered yet.
|
|
619
|
+
*
|
|
620
|
+
* Use `Strategies.ContentReady.textStable()` for the built-in text-polling strategy.
|
|
621
|
+
*
|
|
622
|
+
* @example
|
|
623
|
+
* strategies: {
|
|
624
|
+
* contentReady: Strategies.ContentReady.textStable({ timeout: 500 }),
|
|
625
|
+
* }
|
|
626
|
+
*/
|
|
627
|
+
contentReady?: ContentReadyStrategy;
|
|
600
628
|
/**
|
|
601
629
|
* Viewport oracle strategies for 2D virtualized tables (e.g. MUI DataGrid, AG Grid,
|
|
602
630
|
* Braintrust-style grids where both rows and columns are virtualized simultaneously).
|
|
@@ -657,6 +685,9 @@ export interface TableConfig<T = any> {
|
|
|
657
685
|
*/
|
|
658
686
|
emptyState?: Locator;
|
|
659
687
|
}
|
|
688
|
+
/**
|
|
689
|
+
* @internal Resolved config after defaults are applied. Prefer {@link TableConfig} in public code.
|
|
690
|
+
*/
|
|
660
691
|
export interface FinalTableConfig<T = any> extends TableConfig<T> {
|
|
661
692
|
headerSelector: string | ((root: Locator) => Locator);
|
|
662
693
|
rowSelector: string;
|
|
@@ -725,6 +756,11 @@ export type RowIterationOptions = {
|
|
|
725
756
|
*/
|
|
726
757
|
useBulkPagination?: boolean;
|
|
727
758
|
};
|
|
759
|
+
/**
|
|
760
|
+
* Result of {@link useTable}. Implements `AsyncIterable` — `for await (const { row } of table)`
|
|
761
|
+
* uses the same page-walk as `map` / `forEach` (`scanPages` + runMap): overscan, loading,
|
|
762
|
+
* dedupe, and EOF final scan (#427).
|
|
763
|
+
*/
|
|
728
764
|
export interface TableResult<T = any> extends AsyncIterable<{
|
|
729
765
|
row: SmartRow<T>;
|
|
730
766
|
rowIndex: number;
|
|
@@ -762,6 +798,9 @@ export interface TableResult<T = any> extends AsyncIterable<{
|
|
|
762
798
|
* @note The sync path cannot compute a real `rowIndex`, so the returned SmartRow's
|
|
763
799
|
* `rowIndex` is `undefined` (virtual-scroll positioning via `bringIntoView()` is limited).
|
|
764
800
|
* Use `findRow()` (async) when you need a row with an accurate `rowIndex`.
|
|
801
|
+
* @note Cannot filter by `syntheticColumns` or `columnOverrides.read` keys — those need
|
|
802
|
+
* async evaluation via `findRow()` / `findRows()`. DOM filters use `strategies.getCellLocator`
|
|
803
|
+
* when configured (column-virtualized grids), otherwise `cellSelector` + column index.
|
|
765
804
|
*/
|
|
766
805
|
getRow: (filters: Record<string, FilterValue>, options?: {
|
|
767
806
|
exact?: boolean;
|
|
@@ -823,7 +862,9 @@ export interface TableResult<T = any> extends AsyncIterable<{
|
|
|
823
862
|
useBulkPagination?: boolean;
|
|
824
863
|
}) => Promise<SmartRowArray<T>>;
|
|
825
864
|
/**
|
|
826
|
-
*
|
|
865
|
+
* Resolves the named column and scrolls it into view.
|
|
866
|
+
* Prefers `strategies.viewport.scrollToColumn` when configured; otherwise scrolls the
|
|
867
|
+
* header cell via Playwright `scrollIntoViewIfNeeded()`.
|
|
827
868
|
*/
|
|
828
869
|
scrollToColumn: (columnName: string) => Promise<void>;
|
|
829
870
|
/**
|
|
@@ -843,6 +884,7 @@ export interface TableResult<T = any> extends AsyncIterable<{
|
|
|
843
884
|
*/
|
|
844
885
|
mapColumn<R = string>(columnName: string, options?: RowIterationOptions): Promise<R[]>;
|
|
845
886
|
/**
|
|
887
|
+
* @deprecated Use `mapColumn` (or `map`) instead. Will be removed in v7.0.0.
|
|
846
888
|
* Iterates over rows and extracts the value of a single column as strings.
|
|
847
889
|
* @param columnName - The name of the column to extract
|
|
848
890
|
* @param options - Iteration options
|
package/dist/useTable.js
CHANGED
|
@@ -28,10 +28,10 @@ const tableMapper_1 = require("./engine/tableMapper");
|
|
|
28
28
|
const rowFinder_1 = require("./engine/rowFinder");
|
|
29
29
|
const tableIteration_1 = require("./engine/tableIteration");
|
|
30
30
|
const rowResolution_1 = require("./engine/rowResolution");
|
|
31
|
+
const scanPages_1 = require("./engine/scanPages");
|
|
31
32
|
const debugUtils_1 = require("./utils/debugUtils");
|
|
32
33
|
const smartRowArray_1 = require("./utils/smartRowArray");
|
|
33
34
|
const elementTracker_1 = require("./utils/elementTracker");
|
|
34
|
-
const navigationBarrier_1 = require("./utils/navigationBarrier");
|
|
35
35
|
// Helper to safely serialize objects containing functions for logging
|
|
36
36
|
const safeStringify = (obj) => {
|
|
37
37
|
try {
|
|
@@ -145,11 +145,11 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
145
145
|
// Placeholder for the final table object
|
|
146
146
|
let finalTable = null;
|
|
147
147
|
// Helper factory
|
|
148
|
-
const _makeSmart = (rowLocator, map, rowIndex, tablePageIndex, barrier, rowSelector) => {
|
|
148
|
+
const _makeSmart = (rowLocator, map, rowIndex, tablePageIndex, barrier, rowSelector, renderWindowPosition = false) => {
|
|
149
149
|
const effectiveLocator = rowSelector
|
|
150
150
|
? rootLocator.locator(rowSelector)
|
|
151
151
|
: rowLocator;
|
|
152
|
-
const sr = (0, smartRow_1.default)(effectiveLocator, map, rowIndex, config, rootLocator, resolve, finalTable, tablePageIndex, barrier);
|
|
152
|
+
const sr = (0, smartRow_1.default)(effectiveLocator, map, rowIndex, config, rootLocator, resolve, finalTable, tablePageIndex, barrier, renderWindowPosition);
|
|
153
153
|
if (rowSelector)
|
|
154
154
|
sr._selfHealing = true;
|
|
155
155
|
return sr;
|
|
@@ -277,12 +277,19 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
277
277
|
return result;
|
|
278
278
|
},
|
|
279
279
|
scrollToColumn: async (columnName) => {
|
|
280
|
+
var _a;
|
|
280
281
|
log(`scrollToColumn: column="${columnName}"`);
|
|
281
282
|
const map = await tableMapper.getMap();
|
|
282
283
|
const idx = map.get(columnName);
|
|
283
284
|
if (idx === undefined)
|
|
284
285
|
throw _createColumnError(columnName, map);
|
|
285
|
-
//
|
|
286
|
+
// Prefer viewport strategy when configured (#430). Raw scrollIntoViewIfNeeded on a
|
|
287
|
+
// header can shift Y and evict virtualized rows; viewport.scrollToColumn is X-aware.
|
|
288
|
+
const viewportScroll = (_a = config.strategies.viewport) === null || _a === void 0 ? void 0 : _a.scrollToColumn;
|
|
289
|
+
if (viewportScroll) {
|
|
290
|
+
await viewportScroll(createStrategyContext(), idx);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
286
293
|
const headerCell = resolve(config.headerSelector, rootLocator).nth(idx);
|
|
287
294
|
await headerCell.scrollIntoViewIfNeeded();
|
|
288
295
|
},
|
|
@@ -381,19 +388,34 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
381
388
|
let pagesScanned = 1;
|
|
382
389
|
let paginationError;
|
|
383
390
|
try {
|
|
384
|
-
|
|
391
|
+
const scanned = await (0, scanPages_1.scanPages)({
|
|
392
|
+
advancePage: _advancePage,
|
|
393
|
+
getCurrentPageIndex: () => tableState.currentPageIndex,
|
|
394
|
+
config,
|
|
395
|
+
waitForReady: async () => {
|
|
396
|
+
if (!isTableLoading)
|
|
397
|
+
return;
|
|
398
|
+
const ctx = createStrategyContext();
|
|
399
|
+
while (await isTableLoading(ctx)) {
|
|
400
|
+
log('countRows: table is loading... waiting');
|
|
401
|
+
await rootLocator.page().waitForTimeout(200);
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
}, async ({ pagesScanned: pageNum }) => {
|
|
385
405
|
const rowLocators = resolveRows();
|
|
386
406
|
const newIndices = await tracker.getUnseenIndices(rowLocators);
|
|
387
407
|
const candidates = await rowLocators.all();
|
|
388
408
|
const matched = await countPostFilterMatches(candidates, newIndices);
|
|
389
409
|
total += matched;
|
|
390
|
-
log(`countRows: page ${
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
410
|
+
log(`countRows: page ${pageNum} — ${matched} row(s) (running total: ${total})`);
|
|
411
|
+
return 'continue';
|
|
412
|
+
}, {
|
|
413
|
+
maxPages: effectiveMaxPages,
|
|
414
|
+
useBulk: false,
|
|
415
|
+
label: 'countRows',
|
|
416
|
+
finalScanOnEof: true,
|
|
417
|
+
});
|
|
418
|
+
pagesScanned = scanned.pagesScanned;
|
|
397
419
|
}
|
|
398
420
|
catch (e) {
|
|
399
421
|
paginationError = e;
|
|
@@ -437,6 +459,10 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
437
459
|
return (text || '').trim();
|
|
438
460
|
}, options);
|
|
439
461
|
},
|
|
462
|
+
/**
|
|
463
|
+
* @deprecated Use `mapColumn` (or `map`) instead. Will be removed in v7.0.0.
|
|
464
|
+
* Iterates over rows and extracts the value of a single column as strings.
|
|
465
|
+
*/
|
|
440
466
|
getColumnValues: async (columnName, options = {}) => {
|
|
441
467
|
log(`getColumnValues: column="${columnName}" options=${safeStringify(options)}`);
|
|
442
468
|
const values = await result.mapColumn(columnName, options);
|
|
@@ -472,6 +498,11 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
472
498
|
throw new Error(`getRow() cannot filter by synthetic column(s): ${syntheticKeys.join(', ')}. ` +
|
|
473
499
|
`Use findRow() instead — synthetic columns require async evaluation.`);
|
|
474
500
|
}
|
|
501
|
+
const overrideKeys = Object.keys(filters).filter(k => { var _a, _b; return (_b = (_a = config.columnOverrides) === null || _a === void 0 ? void 0 : _a[k]) === null || _b === void 0 ? void 0 : _b.read; });
|
|
502
|
+
if (overrideKeys.length > 0) {
|
|
503
|
+
throw new Error(`getRow() cannot filter by columnOverrides.read column(s): ${overrideKeys.join(', ')}. ` +
|
|
504
|
+
`Use findRow() instead — override columns require async evaluation.`);
|
|
505
|
+
}
|
|
475
506
|
const map = tableMapper.getMapSync();
|
|
476
507
|
if (!map)
|
|
477
508
|
throw new Error('Initialization Error: You attempted to access a row before the table structure was mapped. Please call "await table.init()" once before using synchronous row access.');
|
|
@@ -485,7 +516,7 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
485
516
|
if (!map)
|
|
486
517
|
throw new Error('Initialization Error: You attempted to access a row before the table structure was mapped. Please call "await table.init()" once before using synchronous row access.');
|
|
487
518
|
const rowLocator = resolve(config.rowSelector, rootLocator).nth(index);
|
|
488
|
-
return _makeSmart(rowLocator, map, index);
|
|
519
|
+
return _makeSmart(rowLocator, map, index, undefined, undefined, undefined, true);
|
|
489
520
|
},
|
|
490
521
|
findRowByIndex: async (index, options) => {
|
|
491
522
|
var _a, _b;
|
|
@@ -606,43 +637,65 @@ const useTable = (rootLocator, configOptions = {}) => {
|
|
|
606
637
|
}
|
|
607
638
|
},
|
|
608
639
|
// ─── Shared async row iterator ───────────────────────────────────────────
|
|
640
|
+
/**
|
|
641
|
+
* Streams rows using the same page-walk + collection path as `map` / `forEach`
|
|
642
|
+
* (`scanPages` + runMap): overscan filtering, loading-before-dedupe, EOF final
|
|
643
|
+
* scan, and config dedupe. Concurrency is sequential so yields stay ordered. (#427)
|
|
644
|
+
*/
|
|
609
645
|
[Symbol.asyncIterator]() {
|
|
610
646
|
return __asyncGenerator(this, arguments, function* _a() {
|
|
611
|
-
var _b;
|
|
612
647
|
yield __await(_autoInit());
|
|
613
|
-
|
|
614
|
-
const
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
648
|
+
log(`iterator: starting via runMap (maxPages=${config.maxPages})`);
|
|
649
|
+
const queue = [];
|
|
650
|
+
let notify;
|
|
651
|
+
let release;
|
|
652
|
+
let finished = false;
|
|
653
|
+
let cancelled = false;
|
|
654
|
+
let runError;
|
|
655
|
+
const wake = () => {
|
|
656
|
+
notify === null || notify === void 0 ? void 0 : notify();
|
|
657
|
+
notify = undefined;
|
|
658
|
+
};
|
|
659
|
+
const runPromise = (0, tableIteration_1.runMap)({
|
|
660
|
+
getRowLocators: () => resolve(config.rowSelector, rootLocator),
|
|
661
|
+
getMap: () => tableMapper.getMapSync(),
|
|
662
|
+
advancePage: _advancePage,
|
|
663
|
+
makeSmartRow: (loc, map, idx, pageIdx, barrier, sel) => _makeSmart(loc, map, idx, pageIdx, barrier, sel),
|
|
664
|
+
createSmartRowArray: smartRowArray_1.createSmartRowArray,
|
|
665
|
+
config,
|
|
666
|
+
getPage: () => rootLocator.page(),
|
|
667
|
+
getCurrentPageIndex: () => tableState.currentPageIndex,
|
|
668
|
+
getContext: () => createStrategyContext(),
|
|
669
|
+
}, async (ctx) => {
|
|
670
|
+
queue.push({
|
|
671
|
+
row: ctx.row,
|
|
672
|
+
index: ctx.index,
|
|
673
|
+
rowIndex: ctx.rowIndex,
|
|
674
|
+
pageIndex: ctx.pageIndex,
|
|
675
|
+
});
|
|
676
|
+
wake();
|
|
677
|
+
await new Promise((resolve) => { release = resolve; });
|
|
678
|
+
if (cancelled)
|
|
679
|
+
ctx.stop();
|
|
680
|
+
}, { concurrency: 'sequential' }, 'iterator').then(() => { finished = true; wake(); }, (err) => { runError = err; finished = true; wake(); });
|
|
618
681
|
try {
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
// index = visit-order counter; rowIndex = logical/data index (B-hybrid, #362).
|
|
628
|
-
const resolved = yield __await((0, rowResolution_1.resolveLogicalRowIndex)(pageRows[idx], config, () => rowIndex));
|
|
629
|
-
const logical = (_b = resolved === null || resolved === void 0 ? void 0 : resolved.index) !== null && _b !== void 0 ? _b : rowIndex;
|
|
630
|
-
const sr = _makeSmart(pageRows[idx], map, logical, tableState.currentPageIndex, barrier, resolved === null || resolved === void 0 ? void 0 : resolved.selector);
|
|
631
|
-
// Iterator rows share one per-page DOM snapshot (positional locators); disable
|
|
632
|
-
// toJSON's scroll-back recovery so reading one row can't invalidate the others (#366).
|
|
633
|
-
sr._inBatch = true;
|
|
634
|
-
yield yield __await({ row: sr, index: rowIndex, rowIndex: logical, pageIndex: tableState.currentPageIndex });
|
|
635
|
-
rowIndex++;
|
|
682
|
+
while (!finished || queue.length > 0) {
|
|
683
|
+
if (queue.length === 0) {
|
|
684
|
+
yield __await(new Promise((resolve) => { notify = resolve; }));
|
|
685
|
+
}
|
|
686
|
+
while (queue.length > 0) {
|
|
687
|
+
yield yield __await(queue.shift());
|
|
688
|
+
release === null || release === void 0 ? void 0 : release();
|
|
689
|
+
release = undefined;
|
|
636
690
|
}
|
|
637
|
-
if (
|
|
638
|
-
|
|
639
|
-
if (!(yield __await(_advancePage(useBulk))))
|
|
640
|
-
break;
|
|
641
|
-
pagesScanned++;
|
|
691
|
+
if (runError)
|
|
692
|
+
throw runError;
|
|
642
693
|
}
|
|
643
694
|
}
|
|
644
695
|
finally {
|
|
645
|
-
|
|
696
|
+
cancelled = true;
|
|
697
|
+
release === null || release === void 0 ? void 0 : release();
|
|
698
|
+
yield __await(runPromise.catch(() => { }));
|
|
646
699
|
}
|
|
647
700
|
});
|
|
648
701
|
},
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { Locator, Page } from '@playwright/test';
|
|
2
|
+
import type { FinalTableConfig, Selector } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a cell locator for a concrete row — prefers `strategies.getCellLocator`,
|
|
5
|
+
* otherwise `cellSelector` + `.nth(columnIndex)`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveCellLocator(args: {
|
|
8
|
+
config: FinalTableConfig;
|
|
9
|
+
resolve: (selector: Selector, parent: Locator | Page) => Locator;
|
|
10
|
+
row: Locator;
|
|
11
|
+
root: Locator;
|
|
12
|
+
columnName: string;
|
|
13
|
+
columnIndex: number;
|
|
14
|
+
rowIndex?: number;
|
|
15
|
+
page?: Page;
|
|
16
|
+
}): Locator;
|
|
17
|
+
/**
|
|
18
|
+
* Cell locator for Playwright `rows.filter({ has })`.
|
|
19
|
+
*
|
|
20
|
+
* When `getCellLocator` is set, pass `page.locator(':scope')` as the row so the
|
|
21
|
+
* strategy's `row.locator(...)` chain stays relative to each candidate row under
|
|
22
|
+
* `filter({ has })`. Using the rows collection or a document-rooted parent nests
|
|
23
|
+
* the row selector and matches nothing.
|
|
24
|
+
*
|
|
25
|
+
* Without `getCellLocator`, keeps the historical page-scoped `cellSelector.nth(i)`
|
|
26
|
+
* template that Playwright re-bases into each row.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveCellLocatorForFilter(args: {
|
|
29
|
+
config: FinalTableConfig;
|
|
30
|
+
resolve: (selector: Selector, parent: Locator | Page) => Locator;
|
|
31
|
+
page: Page;
|
|
32
|
+
root?: Locator;
|
|
33
|
+
columnName: string;
|
|
34
|
+
columnIndex: number;
|
|
35
|
+
}): Locator;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.resolveCellLocator = resolveCellLocator;
|
|
4
|
+
exports.resolveCellLocatorForFilter = resolveCellLocatorForFilter;
|
|
5
|
+
/**
|
|
6
|
+
* Resolve a cell locator for a concrete row — prefers `strategies.getCellLocator`,
|
|
7
|
+
* otherwise `cellSelector` + `.nth(columnIndex)`.
|
|
8
|
+
*/
|
|
9
|
+
function resolveCellLocator(args) {
|
|
10
|
+
var _a, _b;
|
|
11
|
+
const { config, resolve, row, root, columnName, columnIndex, rowIndex } = args;
|
|
12
|
+
const page = (_a = args.page) !== null && _a !== void 0 ? _a : root.page();
|
|
13
|
+
if ((_b = config.strategies) === null || _b === void 0 ? void 0 : _b.getCellLocator) {
|
|
14
|
+
return config.strategies.getCellLocator({
|
|
15
|
+
row,
|
|
16
|
+
root,
|
|
17
|
+
columnName,
|
|
18
|
+
columnIndex,
|
|
19
|
+
rowIndex,
|
|
20
|
+
page,
|
|
21
|
+
config,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return resolve(config.cellSelector, row).nth(columnIndex);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Cell locator for Playwright `rows.filter({ has })`.
|
|
28
|
+
*
|
|
29
|
+
* When `getCellLocator` is set, pass `page.locator(':scope')` as the row so the
|
|
30
|
+
* strategy's `row.locator(...)` chain stays relative to each candidate row under
|
|
31
|
+
* `filter({ has })`. Using the rows collection or a document-rooted parent nests
|
|
32
|
+
* the row selector and matches nothing.
|
|
33
|
+
*
|
|
34
|
+
* Without `getCellLocator`, keeps the historical page-scoped `cellSelector.nth(i)`
|
|
35
|
+
* template that Playwright re-bases into each row.
|
|
36
|
+
*/
|
|
37
|
+
function resolveCellLocatorForFilter(args) {
|
|
38
|
+
var _a;
|
|
39
|
+
const { config, resolve, page, root, columnName, columnIndex } = args;
|
|
40
|
+
if ((_a = config.strategies) === null || _a === void 0 ? void 0 : _a.getCellLocator) {
|
|
41
|
+
const scopeRow = page.locator(':scope');
|
|
42
|
+
return config.strategies.getCellLocator({
|
|
43
|
+
row: scopeRow,
|
|
44
|
+
root: root !== null && root !== void 0 ? root : scopeRow,
|
|
45
|
+
columnName,
|
|
46
|
+
columnIndex,
|
|
47
|
+
page,
|
|
48
|
+
config,
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return resolve(config.cellSelector, page).nth(columnIndex);
|
|
52
|
+
}
|
package/package.json
CHANGED