@rickcedwhat/playwright-smart-table 6.20.1-next.6c56f6d → 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.
@@ -4,15 +4,23 @@ exports.Plugins = void 0;
4
4
  const presets_1 = require("../presets");
5
5
  /**
6
6
  * @deprecated Use `presets` instead. Plugins will be removed in v7.0.0.
7
- * Presets for specific table/grid libraries. Each plugin exposes:
8
- * - Plugins.X — full preset (selectors + headerTransformer if any + strategies). Spread: useTable(loc, { ...Presets.MUI, maxPages: 5 }).
9
- * - Plugins.X.Strategies — strategies only. Use with your own selectors: useTable(loc, { rowSelector: '...', strategies: Presets.MUI.Strategies }).
7
+ *
8
+ * Compatibility shim over official presets:
9
+ * - `Plugins.MUI` → `presets.muiDataGrid` (**DataGrid only** — not `presets.muiTable`)
10
+ * - `Plugins.RDG` → `presets.rdg`
11
+ * - `Plugins.Glide` → `presets.glide`
12
+ *
13
+ * Prefer: `useTable(loc, { ...presets.muiDataGrid, maxPages: 5 })`.
14
+ * Strategies only: `useTable(loc, { rowSelector: '...', strategies: presets.muiDataGrid.strategies })`.
10
15
  */
11
16
  exports.Plugins = {
12
17
  /** @deprecated Use `presets.rdg` */
13
- RDG: Object.assign(Object.assign({}, presets_1.rdg), { Strategies: presets_1.rdg.strategies }),
18
+ RDG: Object.assign(Object.assign({}, presets_1.rdg), { Strategies: presets_1.rdg.Strategies }),
14
19
  /** @deprecated Use `presets.glide` */
15
- Glide: Object.assign(Object.assign({}, presets_1.glide), { Strategies: presets_1.glide.strategies }),
16
- /** @deprecated Use `presets.muiDataGrid` */
20
+ Glide: Object.assign(Object.assign({}, presets_1.glide), { Strategies: presets_1.glide.Strategies }),
21
+ /**
22
+ * @deprecated Use `presets.muiDataGrid`.
23
+ * DataGrid only — for MUI `<Table>` use `presets.muiTable`.
24
+ */
17
25
  MUI: Object.assign(Object.assign({}, presets_1.muiDataGrid), { Strategies: presets_1.muiDataGrid.strategies }),
18
26
  };
@@ -12,7 +12,7 @@ export declare const GlideStrategies: {
12
12
  selector?: string;
13
13
  scrollAmount?: number;
14
14
  }) => Promise<string[]>;
15
- viewport: import("../../types").ViewportStrategy;
15
+ viewport: import("../..").ViewportStrategy;
16
16
  loading: {
17
17
  isHeaderLoading: () => Promise<boolean>;
18
18
  };
@@ -123,8 +123,8 @@ function createGlide(options = {}) {
123
123
  }
124
124
  /**
125
125
  * Full preset for Glide Data Grid (selectors + default strategies only).
126
- * Spread: useTable(loc, { ...Plugins.Glide, maxPages: 5 }).
127
- * Strategies only (including fillSimple): useTable(loc, { rowSelector: '...', strategies: Plugins.Glide.Strategies }).
126
+ * Spread: `useTable(loc, { ...presets.glide, maxPages: 5 })`.
127
+ * Strategies only (including fillSimple): `useTable(loc, { rowSelector: '...', strategies: presets.glide.Strategies })`.
128
128
  * For a non-64-column grid, use `createGlide({ columnCount })` instead.
129
129
  */
130
130
  const GlidePreset = {
@@ -1,6 +1,6 @@
1
1
  import type { Locator } from '@playwright/test';
2
2
  import { TableContext, TableConfig, ViewportStrategy, StrategyContext } from '../types';
3
- /** Full strategies for React Data Grid. Use when you want to supply your own selectors: strategies: Plugins.RDG.Strategies */
3
+ /** Full strategies for React Data Grid. Use when you want to supply your own selectors: `strategies: presets.rdg.Strategies` */
4
4
  export declare const RDGStrategies: {
5
5
  header: (context: TableContext) => Promise<string[]>;
6
6
  getCellLocator: ({ row, columnIndex }: {
@@ -92,20 +92,20 @@ const rdgNavigation = {
92
92
  });
93
93
  }
94
94
  };
95
- /** Default strategies for the RDG preset (used when you spread Plugins.RDG). */
95
+ /** Default strategies for the RDG preset (used when you spread `presets.rdg`). */
96
96
  const RDGDefaultStrategies = {
97
97
  header: scrollRightHeaderRDG,
98
98
  getCellLocator: rdgGetCellLocator,
99
99
  navigation: rdgNavigation,
100
100
  pagination: rdgPaginationStrategy
101
101
  };
102
- /** Full strategies for React Data Grid. Use when you want to supply your own selectors: strategies: Plugins.RDG.Strategies */
102
+ /** Full strategies for React Data Grid. Use when you want to supply your own selectors: `strategies: presets.rdg.Strategies` */
103
103
  // fallow-ignore-next-line unused-export
104
104
  exports.RDGStrategies = RDGDefaultStrategies;
105
105
  /**
106
106
  * Full preset for React Data Grid (selectors + default strategies).
107
- * Spread: useTable(loc, { ...Plugins.RDG, maxPages: 5 }).
108
- * Strategies only: useTable(loc, { rowSelector: '...', strategies: Plugins.RDG.Strategies }).
107
+ * Spread: `useTable(loc, { ...presets.rdg, maxPages: 5 })`.
108
+ * Strategies only: `useTable(loc, { rowSelector: '...', strategies: presets.rdg.Strategies })`.
109
109
  */
110
110
  const RDGPreset = {
111
111
  rowSelector: '[role="row"].rdg-row',
@@ -1,4 +1,4 @@
1
- import type { Locator, Page } from '@playwright/test';
1
+ import { type Locator, type Page } from '@playwright/test';
2
2
  import { SmartRow as SmartRowType, FinalTableConfig, TableResult } from './types';
3
3
  import { NavigationBarrier } from './utils/navigationBarrier';
4
4
  /**
@@ -9,5 +9,5 @@ import { NavigationBarrier } from './utils/navigationBarrier';
9
9
  * @internal Internal factory for creating SmartRow objects.
10
10
  * Not part of the public package surface; tests and consumers should use public APIs.
11
11
  */
12
- declare const createSmartRow: <T = any>(rowLocator: Locator, map: Map<string, number>, rowIndex: number | undefined, config: FinalTableConfig<T>, rootLocator: Locator, resolve: (item: any, parent: Locator | Page) => Locator, table: TableResult<T> | null, tablePageIndex?: number, barrier?: NavigationBarrier) => SmartRowType<T>;
12
+ declare const createSmartRow: <T = any>(rowLocator: Locator, map: Map<string, number>, rowIndex: number | undefined, config: FinalTableConfig<T>, rootLocator: Locator, resolve: (item: any, parent: Locator | Page) => Locator, table: TableResult<T> | null, tablePageIndex?: number, barrier?: NavigationBarrier, renderWindowPosition?: boolean) => SmartRowType<T>;
13
13
  export default createSmartRow;
package/dist/smartRow.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ const test_1 = require("@playwright/test");
3
4
  const rowResolution_1 = require("./engine/rowResolution");
4
5
  const fill_1 = require("./strategies/fill");
5
6
  const stringUtils_1 = require("./utils/stringUtils");
@@ -12,7 +13,7 @@ const sentinel_1 = require("./utils/sentinel");
12
13
  * Returns the target cell locator after navigation.
13
14
  */
14
15
  const _navigateToCell = async (params) => {
15
- const { config, rootLocator, page, resolve, getHeaders, column, index, rowLocator, rowIndex, barrier } = params;
16
+ const { config, rootLocator, page, resolve, getHeaders, column, index, rowLocator, rowIndex, barrier, allowMissingCell } = params;
16
17
  const rowLabel = typeof rowIndex === 'number' ? `row ${rowIndex}` : 'row ?';
17
18
  (0, debugUtils_1.logDebug)(config, 'verbose', `_navigateToCell: resolving column "${column}" (colIndex ${index}), ${rowLabel}`);
18
19
  // Get active cell if strategy is available
@@ -65,7 +66,18 @@ const _navigateToCell = async (params) => {
65
66
  ? await viewport.getVisibleRowRange(context)
66
67
  : null;
67
68
  const rowVisible = !rowRange || (rowIndex >= rowRange.first && rowIndex <= rowRange.last);
68
- if (rowVisible && await targetReached()) {
69
+ let cellAttached = rowVisible && await targetReached();
70
+ if (rowVisible && !cellAttached) {
71
+ try {
72
+ await getCellLocator().waitFor({ state: 'attached', timeout: 500 });
73
+ cellAttached = true;
74
+ }
75
+ catch (error) {
76
+ if (!(error instanceof test_1.errors.TimeoutError))
77
+ throw error;
78
+ }
79
+ }
80
+ if (cellAttached) {
69
81
  (0, debugUtils_1.logDebug)(config, 'verbose', `_navigateToCell: col ${index} in visible range [${knownColRange.first}-${knownColRange.last}], reading directly`);
70
82
  // Check in to the barrier without a moveAction — peers that need the scroll
71
83
  // still supply their own action and will trigger it when all rows arrive.
@@ -124,6 +136,8 @@ const _navigateToCell = async (params) => {
124
136
  }
125
137
  // Cell still not accessible — fall through to navigation primitives if configured.
126
138
  if (!config.strategies.navigation) {
139
+ if (allowMissingCell)
140
+ return getCellLocator();
127
141
  const colRange = viewport.getVisibleColumnRange ? await viewport.getVisibleColumnRange(context) : null;
128
142
  const rowRange = viewport.getVisibleRowRange ? await viewport.getVisibleRowRange(context) : null;
129
143
  let errMsg = `SmartTable: could not reach cell for column "${column}" (colIndex ${index}) at row ${rowIndex}.\n`;
@@ -144,15 +158,17 @@ const _navigateToCell = async (params) => {
144
158
  // Use navigation primitives if available
145
159
  if (config.strategies.navigation) {
146
160
  const nav = config.strategies.navigation;
147
- if (typeof rowIndex !== 'number') {
148
- throw new Error('Row index is required for navigation');
149
- }
150
161
  if (await targetReached()) {
151
162
  // Already there. If we have a barrier, check-in to stay in lock-step.
152
163
  if (barrier)
153
164
  await barrier.sync(index);
154
165
  return getCellLocator();
155
166
  }
167
+ if (typeof rowIndex !== 'number') {
168
+ if (allowMissingCell)
169
+ return getCellLocator();
170
+ throw new Error('Row index is required for navigation');
171
+ }
156
172
  // If getActiveCell is present but returns null (no focus), and cell is in DOM,
157
173
  // try to focus it once before entering navigation loop.
158
174
  if (config.strategies.getActiveCell) {
@@ -196,6 +212,8 @@ const _navigateToCell = async (params) => {
196
212
  currCol = ac.columnIndex;
197
213
  }
198
214
  }
215
+ // Column-0 snap is owned by the navigation primitive (scrollLeft=0, Home, etc.).
216
+ // Core must not special-case canvas/Home — that was pre-viewport Glide glue.
199
217
  if (index === 0 && nav.snapFirstColumnIntoView) {
200
218
  (0, debugUtils_1.logDebug)(config, 'verbose', '_navigateToCell: snapFirstColumnIntoView for column index 0');
201
219
  await nav.snapFirstColumnIntoView(context);
@@ -206,27 +224,6 @@ const _navigateToCell = async (params) => {
206
224
  currCol = ac.columnIndex;
207
225
  }
208
226
  }
209
- // Home moves a11y focus within the current row to column 0. If focus row !== target row
210
- // (e.g. still on previous row), Home jumps to grid origin and breaks `tr.nth(k)` reads.
211
- if (typeof rowIndex === 'number' && currRow === rowIndex) {
212
- await rootLocator.evaluate((el) => {
213
- var _a;
214
- const canvas = el.closest('canvas') || ((_a = el.parentElement) === null || _a === void 0 ? void 0 : _a.querySelector('canvas'));
215
- if (canvas instanceof HTMLCanvasElement) {
216
- canvas.tabIndex = 0;
217
- canvas.focus();
218
- }
219
- });
220
- await page.keyboard.press('Home');
221
- await page.waitForTimeout(120);
222
- if (config.strategies.getActiveCell) {
223
- const ac = await config.strategies.getActiveCell({ config, root: rootLocator, page, resolve });
224
- if (ac) {
225
- currRow = ac.rowIndex;
226
- currCol = ac.columnIndex;
227
- }
228
- }
229
- }
230
227
  }
231
228
  let cDiff = index - currCol;
232
229
  if (Math.abs(cDiff) > 12 && nav.seekColumnIndex) {
@@ -253,8 +250,8 @@ const _navigateToCell = async (params) => {
253
250
  const settleMs = (Number.isFinite(nav.settleMs) && nav.settleMs >= 0) ? nav.settleMs : computed;
254
251
  await page.waitForTimeout(settleMs);
255
252
  }
256
- // Wait for active cell to match target: poll getActiveCell or fallback to fixed delay
257
- // This is the "Midas Touch" buffer needed for Glide's async accessibility updates.
253
+ // After horizontal steps, poll until getActiveCell / DOM presence confirms the target
254
+ // (a11y trees and virtual mounts often lag the scroll). Tune via navigation.maxWaitMs.
258
255
  const pollIntervalMs = 10;
259
256
  const computedMax = Math.min(6000, 250 + horizontalSteps * 25);
260
257
  const maxWaitMs = (Number.isFinite(nav.maxWaitMs) && nav.maxWaitMs >= 0) ? nav.maxWaitMs : computedMax;
@@ -290,6 +287,8 @@ const _navigateToCell = async (params) => {
290
287
  const finalCell = getCellLocator();
291
288
  if (await finalCell.count() > 0)
292
289
  return finalCell;
290
+ if (allowMissingCell)
291
+ return finalCell;
293
292
  const colRange = viewport && viewport.getVisibleColumnRange ? await viewport.getVisibleColumnRange(context) : null;
294
293
  const rowRange = viewport && viewport.getVisibleRowRange ? await viewport.getVisibleRowRange(context) : null;
295
294
  let errMsg = `SmartTable: could not reach cell for column "${column}" (colIndex ${index}) at row ${rowIndex} after exhausting navigation strategies. Ensure navigation primitives are correctly implemented.\n`;
@@ -313,7 +312,7 @@ const _navigateToCell = async (params) => {
313
312
  * @internal Internal factory for creating SmartRow objects.
314
313
  * Not part of the public package surface; tests and consumers should use public APIs.
315
314
  */
316
- const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve, table, tablePageIndex, barrier) => {
315
+ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve, table, tablePageIndex, barrier, renderWindowPosition = false) => {
317
316
  const smart = rowLocator;
318
317
  // Attach State
319
318
  smart.rowIndex = rowIndex;
@@ -406,12 +405,22 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
406
405
  throw new Error((0, stringUtils_1.buildColumnNotFoundError)(colName, [...map.keys(), ...Object.keys((_b = config.syntheticColumns) !== null && _b !== void 0 ? _b : {})]));
407
406
  }
408
407
  const columnOverride = (_c = config.columnOverrides) === null || _c === void 0 ? void 0 : _c[colName];
409
- const cell = config.strategies.getCellLocator
410
- ? config.strategies.getCellLocator({
411
- row: rowLocator, root: rootLocator, columnName: colName,
412
- columnIndex: idx, rowIndex, page: rootLocator.page(), config,
413
- })
414
- : resolve(config.cellSelector, rowLocator).nth(idx);
408
+ const page = rootLocator.page();
409
+ // Same nav pipeline as toJSON / getCell().bringIntoView() (#430) so virtualized
410
+ // off-screen columns don't return empty/stale text.
411
+ const cell = await _navigateToCell({
412
+ config,
413
+ rootLocator,
414
+ page,
415
+ resolve,
416
+ getHeaders: table === null || table === void 0 ? void 0 : table.getHeaders,
417
+ column: colName,
418
+ index: idx,
419
+ rowLocator,
420
+ rowIndex,
421
+ barrier: smart._barrier,
422
+ allowMissingCell: !!(columnOverride === null || columnOverride === void 0 ? void 0 : columnOverride.read),
423
+ });
415
424
  if (columnOverride === null || columnOverride === void 0 ? void 0 : columnOverride.read) {
416
425
  const getCell = (name) => {
417
426
  const ci = map.get(name);
@@ -708,7 +717,8 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
708
717
  index: idx,
709
718
  rowLocator: stableRow,
710
719
  rowIndex,
711
- barrier: smart._barrier
720
+ barrier: smart._barrier,
721
+ allowMissingCell: !!mapper,
712
722
  });
713
723
  if (navigatedCell) {
714
724
  targetCell = navigatedCell;
@@ -735,8 +745,22 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
735
745
  ? rawCellTimeout
736
746
  : undefined;
737
747
  const onCellLoadingTimeout = (_h = (_g = config.strategies.loading) === null || _g === void 0 ? void 0 : _g.onCellLoadingTimeout) !== null && _h !== void 0 ? _h : 'read-as-is';
738
- if (isCellLoading && await isCellLoading(targetCell, col, smart)) {
739
- if (cellLoadingTimeout !== undefined) {
748
+ if (isCellLoading) {
749
+ let loading = await isCellLoading(targetCell, col, smart);
750
+ // First-paint race: the cell node can attach a tick before the loading
751
+ // indicator mounts. A single false-negative then reads "" and skips
752
+ // onCellLoadingTimeout. Only grace when the cell still looks empty.
753
+ if (!loading && cellLoadingTimeout !== undefined && cellLoadingTimeout > 0) {
754
+ const peek = await targetCell.evaluate((el) => (el.textContent || '').trim()).catch(() => '');
755
+ if (peek === '') {
756
+ const graceDeadline = Date.now() + Math.min(250, cellLoadingTimeout);
757
+ while (!loading && Date.now() < graceDeadline) {
758
+ await page.waitForTimeout(25);
759
+ loading = await isCellLoading(targetCell, col, smart);
760
+ }
761
+ }
762
+ }
763
+ if (loading && cellLoadingTimeout !== undefined) {
740
764
  (0, debugUtils_1.logDebug)(config, 'verbose', `toJSON: cell "${col}" — waiting up to ${cellLoadingTimeout}ms`);
741
765
  const deadline = Date.now() + cellLoadingTimeout;
742
766
  let cellResolved = !(await isCellLoading(targetCell, col, smart)); // immediate check (handles timeout=0)
@@ -849,6 +873,7 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
849
873
  (0, debugUtils_1.logDebug)(config, 'info', 'Row fill complete');
850
874
  };
851
875
  smart.bringIntoView = async () => {
876
+ var _a;
852
877
  if (rowIndex === undefined) {
853
878
  (0, debugUtils_1.logDebug)(config, 'info', 'bringIntoView called on a row with unknown rowIndex (e.g. from getRow()). ' +
854
879
  'Page navigation and scrolling will proceed, but virtual-scroll keyboard navigation will be skipped. ' +
@@ -895,8 +920,20 @@ const createSmartRow = (rowLocator, map, rowIndex, config, rootLocator, resolve,
895
920
  }
896
921
  // Delay after pagination/finding before scrolling
897
922
  await (0, debugUtils_1.debugDelay)(config, 'findRow');
898
- // Scroll row into view using Playwright's built-in method
899
- await rowLocator.scrollIntoViewIfNeeded();
923
+ // Prefer viewport.scrollToRow when configured (#430). scrollIntoViewIfNeeded adjusts
924
+ // both axes and can evict sibling rows on recycling virtualizers.
925
+ const viewport = config.strategies.viewport;
926
+ const logicalRowIndex = (viewport === null || viewport === void 0 ? void 0 : viewport.scrollToRow) && renderWindowPosition
927
+ ? (_a = (await (0, rowResolution_1.resolveLogicalRowIndex)(rowLocator, config, () => undefined))) === null || _a === void 0 ? void 0 : _a.index
928
+ : rowIndex;
929
+ if ((viewport === null || viewport === void 0 ? void 0 : viewport.scrollToRow) && typeof logicalRowIndex === 'number') {
930
+ const page = rootLocator.page();
931
+ (0, debugUtils_1.logDebug)(config, 'verbose', `bringIntoView: viewport.scrollToRow(${logicalRowIndex})`);
932
+ await viewport.scrollToRow({ root: rootLocator, config, page, resolve, getHeaders: parentTable === null || parentTable === void 0 ? void 0 : parentTable.getHeaders }, logicalRowIndex);
933
+ }
934
+ else {
935
+ await rowLocator.scrollIntoViewIfNeeded();
936
+ }
900
937
  };
901
938
  return smart;
902
939
  };
@@ -12,7 +12,9 @@ export interface NavigationPrimitives {
12
12
  goHome?: (context: StrategyContext) => Promise<void>;
13
13
  /**
14
14
  * After vertical moves, run before horizontal steps when the target column index is 0.
15
- * Use for horizontally virtualized a11y tables (e.g. Glide) so `td[aria-colindex="1"]` exists again.
15
+ * Use for horizontally virtualized tables so the first column exists in the DOM again
16
+ * (e.g. set scrollLeft = 0). If the table needs keyboard `Home` or canvas focus, put that
17
+ * here — the core orchestrator does not special-case those behaviors.
16
18
  * Do not reset vertical scroll here — RDG-style `goHome` is often unsuitable.
17
19
  */
18
20
  snapFirstColumnIntoView?: (context: StrategyContext) => Promise<void>;
@@ -33,7 +35,8 @@ export interface NavigationPrimitives {
33
35
  maxWaitMs?: number;
34
36
  }
35
37
  /**
36
- * @deprecated Use NavigationPrimitives instead. This will be removed in a future version.
38
+ * @deprecated Use NavigationPrimitives (`strategies.navigation`) instead. Removed from
39
+ * the public `Strategies` namespace in #428; this type remains for transitional typings.
37
40
  * Defines the contract for a cell navigation strategy.
38
41
  */
39
42
  export type CellNavigationStrategy = (context: StrategyContext & {
@@ -46,10 +49,3 @@ export type CellNavigationStrategy = (context: StrategyContext & {
46
49
  locator: Locator;
47
50
  } | null;
48
51
  }) => Promise<void>;
49
- export declare const CellNavigationStrategies: {
50
- /**
51
- * Default strategy: Assumes column is accessible or standard scrolling works.
52
- * No specific action taken other than what Playwright's default locator handling does.
53
- */
54
- default: () => Promise<void>;
55
- };
@@ -1,12 +1,2 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CellNavigationStrategies = void 0;
4
- exports.CellNavigationStrategies = {
5
- /**
6
- * Default strategy: Assumes column is accessible or standard scrolling works.
7
- * No specific action taken other than what Playwright's default locator handling does.
8
- */
9
- default: async () => {
10
- // No-op
11
- }
12
- };
@@ -2,12 +2,8 @@ import type { FilterStrategy } from '../types';
2
2
  /**
3
3
  * Example filter strategies.
4
4
  * - default: small convenience wrapper that mirrors the engine's default behavior.
5
- * - spy(factory): returns a strategy that marks `calledRef.called = true` when invoked.
6
5
  */
7
6
  export declare const FilterStrategies: {
8
7
  default: FilterStrategy;
9
- spy: (calledRef?: {
10
- called?: boolean;
11
- }) => FilterStrategy;
12
8
  };
13
9
  export type { FilterStrategy } from '../types';
@@ -4,7 +4,6 @@ exports.FilterStrategies = void 0;
4
4
  /**
5
5
  * Example filter strategies.
6
6
  * - default: small convenience wrapper that mirrors the engine's default behavior.
7
- * - spy(factory): returns a strategy that marks `calledRef.called = true` when invoked.
8
7
  */
9
8
  exports.FilterStrategies = {
10
9
  default: {
@@ -20,19 +19,4 @@ exports.FilterStrategies = {
20
19
  return rows.filter({ has: targetCell.getByText(textVal, { exact: true }) });
21
20
  }
22
21
  },
23
- spy: (calledRef = {}) => ({
24
- apply({ rows, filter, colIndex, tableContext }) {
25
- calledRef.called = true;
26
- // Delegate to default behaviour for actual filtering
27
- const page = tableContext.page;
28
- const resolve = tableContext.resolve;
29
- const cellTemplate = resolve(tableContext.config.cellSelector, page);
30
- const targetCell = cellTemplate.nth(colIndex);
31
- if (typeof filter.value === 'function') {
32
- return rows.filter({ has: filter.value(targetCell) });
33
- }
34
- const textVal = typeof filter.value === 'number' ? String(filter.value) : filter.value;
35
- return rows.filter({ has: targetCell.getByText(textVal, { exact: true }) });
36
- }
37
- }),
38
22
  };
@@ -3,13 +3,19 @@ export * from './sorting';
3
3
  export * from './columns';
4
4
  export * from './headers';
5
5
  export * from './fill';
6
- export * from './resolution';
6
+ export type { ColumnResolutionStrategy } from './resolution';
7
7
  export * from './dedupe';
8
8
  export * from './loading';
9
9
  export * from './stabilization';
10
10
  export * from './filter';
11
11
  export * from './viewport';
12
12
  export * from './contentReady';
13
+ /**
14
+ * Built-in strategy factories.
15
+ * @note `CellNavigation` / `Resolution` removed from this namespace in #428 (dead/no-op).
16
+ * Use `strategies.navigation` (NavigationPrimitives) and header maps instead.
17
+ * `Filter.spy` was test-only and is no longer shipped.
18
+ */
13
19
  export declare const Strategies: {
14
20
  Pagination: {
15
21
  click: (selectors: {
@@ -27,21 +33,18 @@ export declare const Strategies: {
27
33
  detectCurrentPage?: (root: import("@playwright/test").Locator) => number | Promise<number>;
28
34
  stabilization?: import("./stabilization").StabilizationStrategy;
29
35
  timeout?: number;
30
- }) => import("../types").PaginationStrategy;
36
+ }) => import("..").PaginationStrategy;
31
37
  infiniteScroll: (options?: {
32
38
  action?: "scroll" | "js-scroll";
33
39
  scrollTarget?: import("..").Selector;
34
40
  scrollAmount?: number;
35
41
  stabilization?: import("./stabilization").StabilizationStrategy;
36
42
  timeout?: number;
37
- }) => import("../types").PaginationStrategy;
43
+ }) => import("..").PaginationStrategy;
38
44
  };
39
45
  Sorting: {
40
46
  AriaSort: () => import("..").SortingStrategy;
41
47
  };
42
- CellNavigation: {
43
- default: () => Promise<void>;
44
- };
45
48
  Header: {
46
49
  visible: ({ config, resolve, root }: import("..").StrategyContext) => Promise<string[]>;
47
50
  horizontalScroll: (options?: {
@@ -51,13 +54,10 @@ export declare const Strategies: {
51
54
  }) => import("./headers").HeaderStrategy;
52
55
  };
53
56
  Fill: {
54
- default: ({ row, columnName, value, fillOptions, config, table }: Parameters<import("../types").FillStrategy>[0]) => Promise<void>;
55
- };
56
- Resolution: {
57
- default: import("./resolution").ColumnResolutionStrategy;
57
+ default: ({ row, columnName, value, fillOptions, config, table }: Parameters<import("..").FillStrategy>[0]) => Promise<void>;
58
58
  };
59
59
  Dedupe: {
60
- byTopPosition: (tolerance?: number) => import("../types").DedupeStrategy;
60
+ byTopPosition: (tolerance?: number) => import("..").DedupeStrategy;
61
61
  };
62
62
  Loading: {
63
63
  Table: {
@@ -94,12 +94,9 @@ export declare const Strategies: {
94
94
  };
95
95
  Filter: {
96
96
  default: import("./filter").FilterStrategy;
97
- spy: (calledRef?: {
98
- called?: boolean;
99
- }) => import("./filter").FilterStrategy;
100
97
  };
101
98
  Viewport: {
102
- dataAttribute: (options?: import("./viewport").DataAttributeViewportOptions) => import("../types").ViewportStrategy;
99
+ dataAttribute: (options?: import("./viewport").DataAttributeViewportOptions) => import("..").ViewportStrategy;
103
100
  };
104
101
  ContentReady: {
105
102
  textStable: (options?: {
@@ -17,10 +17,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.Strategies = void 0;
18
18
  const pagination_1 = require("./pagination");
19
19
  const sorting_1 = require("./sorting");
20
- const columns_1 = require("./columns");
21
20
  const headers_1 = require("./headers");
22
21
  const fill_1 = require("./fill");
23
- const resolution_1 = require("./resolution");
24
22
  const dedupe_1 = require("./dedupe");
25
23
  const loading_1 = require("./loading");
26
24
  const stabilization_1 = require("./stabilization");
@@ -32,20 +30,23 @@ __exportStar(require("./sorting"), exports);
32
30
  __exportStar(require("./columns"), exports);
33
31
  __exportStar(require("./headers"), exports);
34
32
  __exportStar(require("./fill"), exports);
35
- __exportStar(require("./resolution"), exports);
36
33
  __exportStar(require("./dedupe"), exports);
37
34
  __exportStar(require("./loading"), exports);
38
35
  __exportStar(require("./stabilization"), exports);
39
36
  __exportStar(require("./filter"), exports);
40
37
  __exportStar(require("./viewport"), exports);
41
38
  __exportStar(require("./contentReady"), exports);
39
+ /**
40
+ * Built-in strategy factories.
41
+ * @note `CellNavigation` / `Resolution` removed from this namespace in #428 (dead/no-op).
42
+ * Use `strategies.navigation` (NavigationPrimitives) and header maps instead.
43
+ * `Filter.spy` was test-only and is no longer shipped.
44
+ */
42
45
  exports.Strategies = {
43
46
  Pagination: pagination_1.PaginationStrategies,
44
47
  Sorting: sorting_1.SortingStrategies,
45
- CellNavigation: columns_1.CellNavigationStrategies,
46
48
  Header: headers_1.HeaderStrategies,
47
49
  Fill: fill_1.FillStrategies,
48
- Resolution: resolution_1.ResolutionStrategies,
49
50
  Dedupe: dedupe_1.DedupeStrategies,
50
51
  Loading: loading_1.LoadingStrategies,
51
52
  Stabilization: stabilization_1.StabilizationStrategies,