@parity/product-lab 0.1.1 → 0.1.2
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/CHANGELOG.md +8 -0
- package/README.md +27 -0
- package/adapters/browser/playwright/README.md +2 -0
- package/adapters/browser/playwright/src/page-frame-capture.js +10 -2
- package/adapters/chain/papi/README.md +3 -1
- package/adapters/environment/engine/README.md +1 -1
- package/adapters/features/cucumber/README.md +4 -0
- package/adapters/features/cucumber/src/steps/register-feature-steps.js +15 -1
- package/adapters/system/node/README.md +3 -3
- package/adapters/video/ffmpeg/README.md +4 -0
- package/adapters/video/ffmpeg/src/ffmpeg-video-editor.d.ts +1 -1
- package/adapters/video/ffmpeg/src/ffmpeg-video-editor.js +19 -6
- package/core/application/README.md +30 -1
- package/core/application/src/features/direct-feature-steps.d.ts +23 -0
- package/core/application/src/features/direct-feature-steps.js +25 -0
- package/core/application/src/features/feature-recording.d.ts +6 -0
- package/core/application/src/features/feature-recording.js +3 -0
- package/core/application/src/features/feature-scenario.d.ts +10 -8
- package/core/application/src/features/feature-scenario.js +11 -15
- package/core/application/src/features/feature-step-times.d.ts +11 -1
- package/core/application/src/features/feature-step-times.js +20 -6
- package/core/application/src/features/lab-feature-session.d.ts +3 -1
- package/core/application/src/features/lab-feature-session.js +5 -2
- package/core/application/src/features/run-feature-steps.d.ts +3 -1
- package/core/application/src/features/run-feature-steps.js +4 -2
- package/core/application/src/lab-runtime-use-cases.js +5 -1
- package/core/application/src/recordings/demo-markup.d.ts +8 -0
- package/core/application/src/recordings/demo-markup.js +11 -1
- package/core/application/src/recordings/demo-recording.d.ts +0 -2
- package/core/application/src/recordings/demo-recording.js +40 -23
- package/core/application/src/recordings/frame-sources.d.ts +20 -1
- package/core/application/src/recordings/frame-sources.js +89 -0
- package/core/application/src/recordings/record-runs.d.ts +7 -1
- package/core/application/src/recordings/record-runs.js +66 -11
- package/core/application/src/recordings/recording-draft.d.ts +4 -0
- package/core/application/src/recordings/recording-draft.js +13 -4
- package/core/domain/README.md +14 -0
- package/core/domain/src/recordings/demo-cut.js +6 -4
- package/core/domain/src/recordings/demo-holds.d.ts +12 -0
- package/core/domain/src/recordings/demo-holds.js +31 -0
- package/core/domain/src/recordings/index.d.ts +1 -0
- package/core/domain/src/recordings/index.js +1 -0
- package/core/domain/src/recordings/recording-data.d.ts +9 -1
- package/core/domain/src/recordings/recording-settings.d.ts +5 -1
- package/core/domain/src/recordings/recording-settings.js +7 -0
- package/core/domain/src/recordings/run-recording.d.ts +2 -0
- package/core/domain/src/recordings/run-recording.js +8 -1
- package/core/ports/README.md +6 -0
- package/core/ports/src/driven/recording/demo-ports.d.ts +2 -0
- package/core/ports/src/driven/recording/frame-capture.d.ts +4 -0
- package/core/ports/src/driving/demo.d.ts +2 -0
- package/core/ports/src/driving/feature-session.d.ts +7 -0
- package/entrypoints/cli/README.md +6 -3
- package/entrypoints/cli/src/demo-command.d.ts +1 -1
- package/entrypoints/cli/src/demo-command.js +10 -5
- package/entrypoints/mcp/README.md +3 -0
- package/entrypoints/panel/README.md +6 -3
- package/entrypoints/panel/src/visible/detached-identities.js +5 -1
- package/entrypoints/panel/src/visible/window-frames.js +14 -1
- package/package.json +1 -1
|
@@ -202,3 +202,6 @@ the file. Neither live script is part of the unit suite.
|
|
|
202
202
|
|
|
203
203
|
The reload test creates its ES-module lab in an OS temporary directory, linking this package's `node_modules`.
|
|
204
204
|
Concurrent lint can no longer discover a generated lab under the repository's `tests/` without a TypeScript project.
|
|
205
|
+
|
|
206
|
+
Design-resource hashes track the current topic text, including the distinction between passive frames-only
|
|
207
|
+
capture and awaited video capture at feature boundaries.
|
|
@@ -417,9 +417,10 @@ Every running actor's app tile has a compact, browser-like address bar in the co
|
|
|
417
417
|
(`data-frame`), so a re-created frame never receives an old frame's address. The bar never shows a guessed location.
|
|
418
418
|
|
|
419
419
|
Tests: `node --import tsx --test entrypoints/panel/tests/address-bar.test.ts` (served shell, headless Chromium,
|
|
420
|
-
loopback fixture apps on ephemeral ports
|
|
421
|
-
|
|
422
|
-
|
|
420
|
+
loopback fixture apps on ephemeral ports that count browser requests by `Sec-Fetch-Dest`, which Chromium sends
|
|
421
|
+
to these loopback origins, ignoring a local port probe without that header;
|
|
422
|
+
a normal tab and the lab window via `openLabWindow`, including real `framenavigated` reports and the acting guard).
|
|
423
|
+
Optional `ADDRESS_BAR_SCREENS=<directory>` writes review screenshots (unset: none).
|
|
423
424
|
|
|
424
425
|
## Visible execution: `@product-lab/shell/visible`
|
|
425
426
|
|
|
@@ -1771,3 +1772,5 @@ Framing reuse (item82): the framing section above retains the original item66 be
|
|
|
1771
1772
|
The drawer puts its existing tabs in a full-width row below the title and Close control. Tabs wrap at narrow widths, keeping Recordings reachable without replacing the live app frame. Watch controls the displayed app in a window opened through `openLabWindow`; the server can keep running in the background while that window remains visible.
|
|
1772
1773
|
|
|
1773
1774
|
Opening a recording displays its captured screenshots over the mounted app, with Play/Pause and previous/next screenshot controls. The viewer labels its fixed1.5s image cadence and absence of video; it cannot recover typing or clicks between captures. Back to live restores the app and run controls. Active runs are checked before and after loading the recording, using the latest panel snapshot. The run audit remains available even with zero recorded steps, and incomplete audits explicitly explain that proof is missing.
|
|
1775
|
+
|
|
1776
|
+
Recording captures of tiles and detached windows honor `CaptureOptions.loadComplete` before taking their image and report `loadComplete: true` when checked. Only video feature after-frame checks request this wait; normal captures retain their existing policy. Tests: `tests/window-frames.test.ts` and `tests/detached-identities.test.ts`.
|
|
@@ -195,6 +195,10 @@ export function detachedFrameCapture(tiles, detached, options = {}) {
|
|
|
195
195
|
const timeoutMs = captureOptions?.timeoutMs ?? options.timeoutMs ?? DETACHED_CAPTURE_TIMEOUT_MS;
|
|
196
196
|
if (signal?.aborted)
|
|
197
197
|
throw new Error(`${window.actor.name}'s detached window was not captured: the recorder stopped waiting`);
|
|
198
|
+
if (captureOptions?.loadComplete) {
|
|
199
|
+
await window.app.waitForFunction(() => document.readyState === "complete", undefined, { timeout: timeoutMs });
|
|
200
|
+
signal?.throwIfAborted();
|
|
201
|
+
}
|
|
198
202
|
const started = Date.now();
|
|
199
203
|
const unsettled = captureOptions?.settled?.selectors.length ? await settle(window.app, captureOptions.settled) : undefined;
|
|
200
204
|
if (unsettled)
|
|
@@ -211,7 +215,7 @@ export function detachedFrameCapture(tiles, detached, options = {}) {
|
|
|
211
215
|
throw new Error(`${window.actor.name}'s detached window gave no frame within ${timeoutMs} ms`, { cause: error });
|
|
212
216
|
throw new Error(`${window.actor.name}'s detached window could not be captured: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
213
217
|
}
|
|
214
|
-
return { status: "captured", mediaType: "image/png", bytes: new Uint8Array(bytes), ...settled };
|
|
218
|
+
return { status: "captured", mediaType: "image/png", bytes: new Uint8Array(bytes), ...settled, ...(captureOptions?.loadComplete ? { loadComplete: true } : {}) };
|
|
215
219
|
},
|
|
216
220
|
};
|
|
217
221
|
}
|
|
@@ -13,6 +13,19 @@ export function windowFrameCapture(page, frameSelector, media, videos, uiCalls)
|
|
|
13
13
|
video: () => windowVideo(page, videos, { source: "lab-window", scope: "window" }),
|
|
14
14
|
async capture(actorId, options) {
|
|
15
15
|
const selector = frameSelector(actorId);
|
|
16
|
+
if (options?.loadComplete) {
|
|
17
|
+
const element = await page.locator(selector).elementHandle({ timeout: options.timeoutMs });
|
|
18
|
+
try {
|
|
19
|
+
const app = await element?.contentFrame();
|
|
20
|
+
if (!app)
|
|
21
|
+
return { status: "unavailable", reason: "The displayed app has no current document" };
|
|
22
|
+
await app.waitForLoadState("load", { timeout: options.timeoutMs });
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
await element?.dispose();
|
|
26
|
+
}
|
|
27
|
+
options.signal?.throwIfAborted();
|
|
28
|
+
}
|
|
16
29
|
const started = Date.now();
|
|
17
30
|
const unsettled = options?.settled?.selectors.length ? await settle(page.frameLocator(selector), options.settled) : undefined;
|
|
18
31
|
if (unsettled)
|
|
@@ -45,7 +58,7 @@ export function windowFrameCapture(page, frameSelector, media, videos, uiCalls)
|
|
|
45
58
|
const bytes = await cutInWorker(await shot, view.width, { rect: { x, y, width, height } });
|
|
46
59
|
const after = await page.evaluate(steadyFrameBox, { selector, settleMs: 0 });
|
|
47
60
|
if (!("moving" in after) && sameBox(after, box))
|
|
48
|
-
return { status: "captured", mediaType: "image/png", bytes: new Uint8Array(bytes), ...settled };
|
|
61
|
+
return { status: "captured", mediaType: "image/png", bytes: new Uint8Array(bytes), ...settled, ...(options?.loadComplete ? { loadComplete: true } : {}) };
|
|
49
62
|
}
|
|
50
63
|
finally {
|
|
51
64
|
if (!shot)
|
package/package.json
CHANGED