@rickcedwhat/playwright-smart-table 6.20.1-next.e170fdd → 6.20.1-next.e946424

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.
@@ -37,6 +37,7 @@ async function runMap(env, callback, options = {}, label = 'map') {
37
37
  const tracker = new elementTracker_1.ElementTracker(label);
38
38
  log(env.config, `${label}: starting (maxPages=${effectiveMaxPages}, mode=${concurrency}, dedupe=${!!dedupeStrategy})`);
39
39
  const results = [];
40
+ const seenLogicalIndices = new Set();
40
41
  try {
41
42
  let rowIndex = 0;
42
43
  let stopped = false;
@@ -63,9 +64,12 @@ async function runMap(env, callback, options = {}, label = 'map') {
63
64
  // #384: overscan rows ABOVE the visible range have already scrolled past and will never
64
65
  // re-enter the viewport — collect them now. Only defer rows BELOW the visible range
65
66
  // (they'll scroll into view on a later page).
67
+ //
68
+ // #417 follow-up: skip viewport filtering on the final scan — there are no more pages
69
+ // to defer to, so collect all remaining unseen rows regardless of visibility.
66
70
  let candidateIndices = allIndices;
67
71
  const getVisibleRowIndices = (_f = env.config.strategies.viewport) === null || _f === void 0 ? void 0 : _f.getVisibleRowIndices;
68
- if (getVisibleRowIndices) {
72
+ if (getVisibleRowIndices && !reachedEnd) {
69
73
  const visible = new Set(await getVisibleRowIndices(env.getContext()));
70
74
  const minVisible = visible.size > 0 ? Math.min(...visible) : Infinity;
71
75
  candidateIndices = allIndices.filter(idx => visible.has(idx) || idx < minVisible);
@@ -111,6 +115,13 @@ async function runMap(env, callback, options = {}, label = 'map') {
111
115
  if (stopped && enumIndex > stoppedIndex) {
112
116
  return SKIP;
113
117
  }
118
+ // When resolveRowIndex is configured, identical logical indices across pages
119
+ // indicate the same record (e.g. re-created DOM elements in recycling
120
+ // virtualizers whose WeakMap entry was GC'd). Skip without processing.
121
+ if (row.rowIndex !== undefined && seenLogicalIndices.has(row.rowIndex)) {
122
+ log(env.config, `${label}: skipping duplicate logical row ${row.rowIndex}`);
123
+ return SKIP;
124
+ }
114
125
  // Wait for the row to finish loading BEFORE evaluating its dedupe key (Bug #355).
115
126
  // map/forEach/filter process a still-loading row when no timeout is set (unlike
116
127
  // findRows, which skips) — see resolveRowLoading's `noTimeoutAction`.
@@ -141,6 +152,9 @@ async function runMap(env, callback, options = {}, label = 'map') {
141
152
  if (dedupeKeys && dedupeKey !== undefined && result !== SKIP) {
142
153
  dedupeKeys.add(dedupeKey);
143
154
  }
155
+ if (row.rowIndex !== undefined && result !== SKIP) {
156
+ seenLogicalIndices.add(row.rowIndex);
157
+ }
144
158
  return result;
145
159
  }
146
160
  finally {
@@ -3,4 +3,4 @@
3
3
  * Generated by scripts/embed-version.mjs from package.json
4
4
  */
5
5
  /** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
6
- export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.20.1-next.e170fdd";
6
+ export declare const PLAYWRIGHT_SMART_TABLE_VERSION: "6.20.1-next.e946424";
@@ -6,4 +6,4 @@ exports.PLAYWRIGHT_SMART_TABLE_VERSION = void 0;
6
6
  * Generated by scripts/embed-version.mjs from package.json
7
7
  */
8
8
  /** Semver of this package. Use in logs or diagnostics to confirm the installed build. */
9
- exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.20.1-next.e170fdd";
9
+ exports.PLAYWRIGHT_SMART_TABLE_VERSION = "6.20.1-next.e946424";
@@ -83,6 +83,7 @@ exports.PaginationStrategies = {
83
83
  const scrollTarget = options.scrollTarget
84
84
  ? resolve(options.scrollTarget, root)
85
85
  : root;
86
+ const beforeScrollTop = await scrollTarget.evaluate((el) => el.scrollTop);
86
87
  const doScroll = async () => {
87
88
  const box = await scrollTarget.boundingBox();
88
89
  const scrollValue = amount * directionMultiplier;
@@ -98,8 +99,16 @@ exports.PaginationStrategies = {
98
99
  await page.mouse.wheel(0, scrollValue);
99
100
  }
100
101
  };
101
- // Stabilization: Wait
102
- return await stabilization(context, doScroll);
102
+ // Stabilization: Wait for content to settle
103
+ const stabilizationResult = await stabilization(context, doScroll);
104
+ // EOF detection: use scroll position, not stabilization result.
105
+ // Stabilization may time out for recycling virtualizers when the scroll
106
+ // amount is small enough to stay within the overscan window (no new rows
107
+ // rendered), but the scroll position still changed — we haven't reached
108
+ // the end of the data.
109
+ const afterScrollTop = await scrollTarget.evaluate((el) => el.scrollTop);
110
+ const scrollMoved = Math.abs(afterScrollTop - beforeScrollTop) >= 1;
111
+ return scrollMoved || stabilizationResult;
103
112
  };
104
113
  };
105
114
  const createGoToFirst = () => {
@@ -18,7 +18,8 @@ class ElementTracker {
18
18
  const seenMap = win[trackerId];
19
19
  const newIndices = [];
20
20
  elements.forEach((el, index) => {
21
- const signature = el.textContent || '';
21
+ const htmlEl = el;
22
+ const signature = htmlEl.offsetTop + '|' + (el.textContent || '');
22
23
  if (seenMap.get(el) !== signature) {
23
24
  newIndices.push(index);
24
25
  }
@@ -39,8 +40,10 @@ class ElementTracker {
39
40
  const seenMap = win[trackerId];
40
41
  for (const index of indicesToCommit) {
41
42
  const el = elements[index];
42
- if (el)
43
- seenMap.set(el, el.textContent || '');
43
+ if (el) {
44
+ const htmlEl = el;
45
+ seenMap.set(el, htmlEl.offsetTop + '|' + (el.textContent || ''));
46
+ }
44
47
  }
45
48
  }, [this.id, indices]);
46
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rickcedwhat/playwright-smart-table",
3
- "version": "6.20.1-next.e170fdd",
3
+ "version": "6.20.1-next.e946424",
4
4
  "description": "Smart, column-aware table interactions for Playwright",
5
5
  "author": "Cedrick Catalan",
6
6
  "license": "MIT",