demowright 2.0.4 → 2.0.6
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/config.mjs +1 -1
- package/dist/helpers.mjs +33 -11
- package/dist/{hud-registry-D74THrir.mjs → hud-registry-Wfd4b4Nu.mjs} +6 -1
- package/dist/index.mjs +2 -2
- package/dist/{setup-x03ZBQi1.mjs → setup-B6UqVosV.mjs} +1 -1
- package/dist/setup.mjs +1 -1
- package/dist/video-script.mjs +1 -1
- package/package.json +1 -2
package/dist/config.mjs
CHANGED
package/dist/helpers.mjs
CHANGED
|
@@ -1,7 +1,30 @@
|
|
|
1
|
-
import { c as isHudActive, d as storeAudioSegment, o as getTtsProvider, s as init_hud_registry } from "./hud-registry-
|
|
1
|
+
import { c as isHudActive, d as storeAudioSegment, o as getTtsProvider, s as init_hud_registry } from "./hud-registry-Wfd4b4Nu.mjs";
|
|
2
2
|
//#region src/helpers.ts
|
|
3
3
|
init_hud_registry();
|
|
4
4
|
/**
|
|
5
|
+
* Run `page.evaluate(fn, arg)` but bail out after `timeoutMs` if the page
|
|
6
|
+
* event loop is blocked (heavy SSR hydration, busy service worker, etc.).
|
|
7
|
+
*
|
|
8
|
+
* On timeout, logs a warning and resolves with `undefined` so recordings
|
|
9
|
+
* keep going instead of hitting the full Playwright test timeout. The
|
|
10
|
+
* underlying `page.evaluate` promise is left to settle on its own.
|
|
11
|
+
*/
|
|
12
|
+
async function evaluateWithTimeout(page, fn, arg, timeoutMs = 1e4, label = "page.evaluate") {
|
|
13
|
+
let timer;
|
|
14
|
+
const evalPromise = page.evaluate(fn, arg);
|
|
15
|
+
evalPromise.catch(() => {});
|
|
16
|
+
try {
|
|
17
|
+
return await Promise.race([evalPromise, new Promise((resolve) => {
|
|
18
|
+
timer = setTimeout(() => {
|
|
19
|
+
console.warn(`[demowright] ${label} timed out after ${timeoutMs}ms — page event loop likely blocked. Skipping.`);
|
|
20
|
+
resolve(void 0);
|
|
21
|
+
}, timeoutMs);
|
|
22
|
+
})]);
|
|
23
|
+
} finally {
|
|
24
|
+
if (timer) clearTimeout(timer);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
5
28
|
* Wait for `ms` milliseconds, but only when demowright is active.
|
|
6
29
|
* Use this instead of `page.waitForTimeout()` for recording-only pauses.
|
|
7
30
|
*/
|
|
@@ -183,13 +206,7 @@ async function narrate(page, text, callbackOrOptions, callback) {
|
|
|
183
206
|
else await playTtsAudio(page, wavBuf);
|
|
184
207
|
return;
|
|
185
208
|
} catch {}
|
|
186
|
-
const
|
|
187
|
-
rate: options?.rate ?? 1,
|
|
188
|
-
pitch: options?.pitch ?? 1,
|
|
189
|
-
volume: options?.volume ?? 1,
|
|
190
|
-
voice: options?.voice
|
|
191
|
-
};
|
|
192
|
-
const speechPromise = page.evaluate(([t, o]) => {
|
|
209
|
+
const speechPromise = evaluateWithTimeout(page, ([t, o]) => {
|
|
193
210
|
return new Promise((resolve) => {
|
|
194
211
|
const synth = window.speechSynthesis;
|
|
195
212
|
if (!synth) {
|
|
@@ -214,7 +231,12 @@ async function narrate(page, text, callbackOrOptions, callback) {
|
|
|
214
231
|
resolve();
|
|
215
232
|
}
|
|
216
233
|
});
|
|
217
|
-
}, [text,
|
|
234
|
+
}, [text, {
|
|
235
|
+
rate: options?.rate ?? 1,
|
|
236
|
+
pitch: options?.pitch ?? 1,
|
|
237
|
+
volume: options?.volume ?? 1,
|
|
238
|
+
voice: options?.voice
|
|
239
|
+
}], 1e4, "narrate(speechSynthesis)");
|
|
218
240
|
if (cb) await Promise.all([speechPromise, cb()]);
|
|
219
241
|
else await speechPromise;
|
|
220
242
|
}
|
|
@@ -224,7 +246,7 @@ async function narrate(page, text, callbackOrOptions, callback) {
|
|
|
224
246
|
*/
|
|
225
247
|
async function caption(page, text, durationMs = 3e3) {
|
|
226
248
|
if (!await isHudActive(page)) return;
|
|
227
|
-
await page
|
|
249
|
+
await evaluateWithTimeout(page, ([t, d]) => {
|
|
228
250
|
const el = document.createElement("div");
|
|
229
251
|
el.textContent = t;
|
|
230
252
|
el.style.cssText = [
|
|
@@ -260,7 +282,7 @@ async function caption(page, text, durationMs = 3e3) {
|
|
|
260
282
|
}
|
|
261
283
|
document.body.appendChild(el);
|
|
262
284
|
setTimeout(() => el.remove(), d);
|
|
263
|
-
}, [text, durationMs]);
|
|
285
|
+
}, [text, durationMs], 1e4, "caption");
|
|
264
286
|
}
|
|
265
287
|
/** @deprecated Use `caption()` instead. */
|
|
266
288
|
const subtitle = caption;
|
|
@@ -11,12 +11,17 @@ function registerHudPage(page, config) {
|
|
|
11
11
|
*/
|
|
12
12
|
async function isHudActive(page) {
|
|
13
13
|
if (hudPages.has(page)) return true;
|
|
14
|
+
let timer;
|
|
14
15
|
try {
|
|
15
|
-
const active = await page.evaluate(() => !!window.__qaHud)
|
|
16
|
+
const active = await Promise.race([page.evaluate(() => !!window.__qaHud).catch(() => false), new Promise((resolve) => {
|
|
17
|
+
timer = setTimeout(() => resolve(false), 5e3);
|
|
18
|
+
})]);
|
|
16
19
|
if (active) hudPages.set(page, { tts: g.__qaHudGlobal.tts || false });
|
|
17
20
|
return active;
|
|
18
21
|
} catch {
|
|
19
22
|
return false;
|
|
23
|
+
} finally {
|
|
24
|
+
if (timer) clearTimeout(timer);
|
|
20
25
|
}
|
|
21
26
|
}
|
|
22
27
|
/**
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { r as AudioWriter, t as applyHud } from "./setup-
|
|
2
|
-
import { i as getGlobalTtsProvider, s as init_hud_registry } from "./hud-registry-
|
|
1
|
+
import { r as AudioWriter, t as applyHud } from "./setup-B6UqVosV.mjs";
|
|
2
|
+
import { i as getGlobalTtsProvider, s as init_hud_registry } from "./hud-registry-Wfd4b4Nu.mjs";
|
|
3
3
|
import { buildFfmpegCommand, createVideoScript, t as init_video_script } from "./video-script.mjs";
|
|
4
4
|
import { annotate, caption, clickEl, hudWait, moveTo, moveToEl, narrate, subtitle, typeKeys } from "./helpers.mjs";
|
|
5
5
|
import { installAutoAnnotate } from "./auto-annotate.mjs";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { r as __toCommonJS } from "./chunk-C0p4GxOx.mjs";
|
|
2
|
-
import { a as getRenderJob, l as registerHudPage, n as getCurrentSpec, s as init_hud_registry, t as getAudioSegments, u as setGlobalOutputDir } from "./hud-registry-
|
|
2
|
+
import { a as getRenderJob, l as registerHudPage, n as getCurrentSpec, s as init_hud_registry, t as getAudioSegments, u as setGlobalOutputDir } from "./hud-registry-Wfd4b4Nu.mjs";
|
|
3
3
|
import { n as video_script_exports, t as init_video_script } from "./video-script.mjs";
|
|
4
4
|
import { execSync } from "node:child_process";
|
|
5
5
|
import { existsSync, mkdirSync, unlinkSync, writeFileSync } from "node:fs";
|
package/dist/setup.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as defaultOptions, t as applyHud } from "./setup-
|
|
1
|
+
import { n as defaultOptions, t as applyHud } from "./setup-B6UqVosV.mjs";
|
|
2
2
|
export { applyHud, defaultOptions };
|
package/dist/video-script.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as __exportAll, t as __esmMin } from "./chunk-C0p4GxOx.mjs";
|
|
2
|
-
import { c as isHudActive, d as storeAudioSegment, f as storeRenderJob, i as getGlobalTtsProvider, o as getTtsProvider, r as getGlobalOutputDir, s as init_hud_registry } from "./hud-registry-
|
|
2
|
+
import { c as isHudActive, d as storeAudioSegment, f as storeRenderJob, i as getGlobalTtsProvider, o as getTtsProvider, r as getGlobalOutputDir, s as init_hud_registry } from "./hud-registry-Wfd4b4Nu.mjs";
|
|
3
3
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
//#region src/video-script.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "demowright",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6",
|
|
4
4
|
"description": "Playwright video production plugin — cursor overlay, keystroke badges, TTS narration, and narration-driven video scripts for test recordings",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -45,7 +45,6 @@
|
|
|
45
45
|
"prepublishOnly": "tsdown"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@playwright/test": "^1.52.0",
|
|
49
48
|
"@types/node": "^25.5.2",
|
|
50
49
|
"@typescript/native-preview": "^7.0.0-dev.20260405.1",
|
|
51
50
|
"semantic-release": "^25.0.3",
|