@nextclaw/x-harness 0.2.55 → 0.2.56

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/SOURCE.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Corresponding source
2
2
 
3
- Version 0.2.55, commit 7fc4a6a0e9bcea24ea2ac8d739572dc15afad136.
3
+ Version 0.2.56, commit 84766d97c35a9cecbee5b8c6461aaa2e28d02c81.
4
4
 
5
- Complete source, build scripts and dependencies: https://github.com/Peiiii/x-harness/tree/7fc4a6a0e9bcea24ea2ac8d739572dc15afad136
5
+ Complete source, build scripts and dependencies: https://github.com/Peiiii/x-harness/tree/84766d97c35a9cecbee5b8c6461aaa2e28d02c81
6
6
 
7
7
  Clone this revision, run npm ci, npm run bootstrap and npm run release:build.
8
8
 
@@ -198,7 +198,9 @@ export class DOMEditing {
198
198
  .locator(`a[href=${JSON.stringify(primary)}]`)
199
199
  .filter({ has: this.#tab.playwright.locator("time") }));
200
200
  this.#session.current = null;
201
- await anchor.press("PageDown");
201
+ // A retained timestamp can be far below the viewport. Validate it, then
202
+ // scroll the page without waiting for that offscreen link to take focus.
203
+ await (await this.#unique(this.#tab.playwright.locator("body"))).press("PageDown");
202
204
  return { completed: true };
203
205
  return { completed: false, loc, submittedEditor };
204
206
  }
@@ -158,38 +158,50 @@ export class PlatformCollections {
158
158
  }
159
159
  async advanceSourceWindow(previous, seen) {
160
160
  const renderedIds = previous.renderedIds ?? [...seen];
161
- await this.#browser.act({ operation: "nextPosts" });
162
- let advanced = await this.#ready({ view: "posts", limit: 5 });
163
- if (advanced.needsStateCheck || advanced.alerts?.length)
164
- return advanced;
165
- let timedOut = false;
166
- try {
167
- // Wait for a newly rendered card, even if that source was processed on an
168
- // earlier run. Global processed IDs do not describe the current DOM window.
169
- await this.#browser.act({
170
- operation: "waitForPosts",
171
- excludeIds: renderedIds,
172
- });
173
- }
174
- catch (error) {
175
- if (!/timed out|timeout/i.test(error.message))
176
- throw error;
177
- timedOut = true;
161
+ let advanced;
162
+ for (let step = 0; step < 10; step++) {
163
+ await this.#browser.act({ operation: "nextPosts" });
164
+ advanced = await this.#ready({ view: "posts", limit: 5 });
165
+ if (advanced.needsStateCheck || advanced.alerts?.length)
166
+ return advanced;
167
+ let timedOut = false;
168
+ try {
169
+ // Wait for a newly rendered card, even if that source was processed on an
170
+ // earlier run. Global processed IDs do not describe the current DOM window.
171
+ await this.#browser.act({
172
+ operation: "waitForPosts",
173
+ excludeIds: renderedIds,
174
+ });
175
+ }
176
+ catch (error) {
177
+ if (!/timed out|timeout/i.test(error.message))
178
+ throw error;
179
+ timedOut = true;
180
+ }
181
+ advanced = await this.#ready({ view: "posts", limit: 5 });
182
+ if (timedOut &&
183
+ advanced.atRenderedTail &&
184
+ !advanced.loading &&
185
+ advanced.firstRenderedId === previous.firstRenderedId &&
186
+ advanced.renderedArticles === previous.renderedArticles)
187
+ advanced.paginationBoundary = {
188
+ kind: "stable-rendered-tail",
189
+ lastId: advanced.renderedIds?.at(-1),
190
+ renderedCount: advanced.renderedArticles,
191
+ waitMs: 5000,
192
+ scopeComplete: false,
193
+ };
194
+ if (advanced.paginationBoundary ||
195
+ !Number.isFinite(advanced.viewportScrollTop) ||
196
+ advanced.renderedArticles !== previous.renderedArticles ||
197
+ (advanced.renderedIds ?? advanced.posts?.map((p) => p.id))?.some((id) => !renderedIds.includes(id)))
198
+ return advanced;
178
199
  }
179
- advanced = await this.#ready({ view: "posts", limit: 5 });
180
- if (timedOut &&
181
- advanced.atRenderedTail &&
182
- !advanced.loading &&
183
- advanced.firstRenderedId === previous.firstRenderedId &&
184
- advanced.renderedArticles === previous.renderedArticles)
185
- advanced.paginationBoundary = {
186
- kind: "stable-rendered-tail",
187
- lastId: advanced.renderedIds?.at(-1),
188
- renderedCount: advanced.renderedArticles,
189
- waitMs: 5000,
190
- scopeComplete: false,
191
- };
192
- return advanced;
200
+ return {
201
+ ...advanced,
202
+ needsStateCheck: true,
203
+ missing: ["bounded-scroll-window-exhausted"],
204
+ };
193
205
  }
194
206
  async handleReadCreator(args) {
195
207
  if (typeof this.#browser.collectCreator !== "function")
@@ -108,6 +108,7 @@ export function readPosts({ offset = 0, limit = 5, targetId = "", } = {}) {
108
108
  ?.getAttribute("href")
109
109
  ?.match(/\/status\/(\d+)/)?.[1])
110
110
  .filter(Boolean),
111
+ viewportScrollTop: document.scrollingElement?.scrollTop,
111
112
  atRenderedTail: Boolean(document.scrollingElement) &&
112
113
  document.scrollingElement.scrollTop +
113
114
  document.scrollingElement.clientHeight >=
@@ -109,6 +109,7 @@ export const readXObservation = (query) => {
109
109
  ?.getAttribute("href")
110
110
  ?.match(/\/status\/(\d+)/)?.[1])
111
111
  .filter(Boolean),
112
+ viewportScrollTop: document.scrollingElement?.scrollTop,
112
113
  atRenderedTail: Boolean(document.scrollingElement) &&
113
114
  document.scrollingElement.scrollTop +
114
115
  document.scrollingElement.clientHeight >=
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextclaw/x-harness",
3
- "version": "0.2.55",
3
+ "version": "0.2.56",
4
4
  "type": "module",
5
5
  "description": "Typed X task harness with compact business results and explicit diagnostics.",
6
6
  "main": "./dist/index.js",
@@ -42,5 +42,5 @@
42
42
  "publishConfig": {
43
43
  "access": "public"
44
44
  },
45
- "gitHead": "7fc4a6a0e9bcea24ea2ac8d739572dc15afad136"
45
+ "gitHead": "84766d97c35a9cecbee5b8c6461aaa2e28d02c81"
46
46
  }