@norskvideo/ctl-dev-kit 0.2.23 → 0.2.24
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/doc-guide/doc-guide.d.ts +13 -0
- package/doc-guide/doc-guide.js +35 -2
- package/package.json +1 -1
package/doc-guide/doc-guide.d.ts
CHANGED
|
@@ -62,6 +62,19 @@ export declare function livePictureFailure(selector: string, phase: string | nul
|
|
|
62
62
|
export declare function awaitLivePicture(page: Page, selector: string, opts?: {
|
|
63
63
|
timeoutMs?: number;
|
|
64
64
|
}): Promise<void>;
|
|
65
|
+
/** How long a capture waits for web fonts before shooting anyway. */
|
|
66
|
+
export declare const FONTS_READY_TIMEOUT_MS = 10000;
|
|
67
|
+
/** `document.fonts.ready`, bounded. True when the fonts settled in time.
|
|
68
|
+
*
|
|
69
|
+
* Unbounded, this hung commentary's composition guide for its whole 360s test
|
|
70
|
+
* budget on 2026-10-03 (CI only, after the Take, with the page about to render
|
|
71
|
+
* the advanced compositor): `fonts.ready` resolves only once every pending font
|
|
72
|
+
* load has finished, a request that never answers never finishes, and
|
|
73
|
+
* `page.evaluate` has no timeout of its own. The test then timed out, its
|
|
74
|
+
* teardown with it, and the instance ran on for hours. A capture in a fallback
|
|
75
|
+
* font is a far smaller failure than that, so bound the wait inside the page
|
|
76
|
+
* AND around the call -- a wedged renderer never answers the call at all. */
|
|
77
|
+
export declare function awaitFontsReady(page: Pick<Page, "evaluate">, timeoutMs?: number): Promise<boolean>;
|
|
65
78
|
/** Produce the screenshot bytes for a capture, applying its treatment. Split out
|
|
66
79
|
* from `DocGuide.capture` (which also gates on DOCS_GENERATE and writes the file)
|
|
67
80
|
* so the treatment geometry is testable on its own. */
|
package/doc-guide/doc-guide.js
CHANGED
|
@@ -79,14 +79,47 @@ async function spotlightOn(page, selector, pad) {
|
|
|
79
79
|
async function spotlightOff(page) {
|
|
80
80
|
await page.evaluate((id) => document.getElementById(id)?.remove(), SPOTLIGHT_ID);
|
|
81
81
|
}
|
|
82
|
+
/** How long a capture waits for web fonts before shooting anyway. */
|
|
83
|
+
export const FONTS_READY_TIMEOUT_MS = 10_000;
|
|
84
|
+
/** `document.fonts.ready`, bounded. True when the fonts settled in time.
|
|
85
|
+
*
|
|
86
|
+
* Unbounded, this hung commentary's composition guide for its whole 360s test
|
|
87
|
+
* budget on 2026-10-03 (CI only, after the Take, with the page about to render
|
|
88
|
+
* the advanced compositor): `fonts.ready` resolves only once every pending font
|
|
89
|
+
* load has finished, a request that never answers never finishes, and
|
|
90
|
+
* `page.evaluate` has no timeout of its own. The test then timed out, its
|
|
91
|
+
* teardown with it, and the instance ran on for hours. A capture in a fallback
|
|
92
|
+
* font is a far smaller failure than that, so bound the wait inside the page
|
|
93
|
+
* AND around the call -- a wedged renderer never answers the call at all. */
|
|
94
|
+
export async function awaitFontsReady(page, timeoutMs = FONTS_READY_TIMEOUT_MS) {
|
|
95
|
+
let timer;
|
|
96
|
+
const late = new Promise((resolve) => {
|
|
97
|
+
timer = setTimeout(() => resolve(false), timeoutMs);
|
|
98
|
+
});
|
|
99
|
+
const ready = page
|
|
100
|
+
.evaluate((ms) => Promise.race([
|
|
101
|
+
document.fonts.ready.then(() => true),
|
|
102
|
+
new Promise((resolve) => setTimeout(() => resolve(false), ms)),
|
|
103
|
+
]), timeoutMs)
|
|
104
|
+
.catch(() => false);
|
|
105
|
+
try {
|
|
106
|
+
return await Promise.race([ready, late]);
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
clearTimeout(timer);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
82
112
|
/** Produce the screenshot bytes for a capture, applying its treatment. Split out
|
|
83
113
|
* from `DocGuide.capture` (which also gates on DOCS_GENERATE and writes the file)
|
|
84
114
|
* so the treatment geometry is testable on its own. */
|
|
85
115
|
export async function screenshotFor(page, treat) {
|
|
86
116
|
if (treat?.livePicture)
|
|
87
117
|
await awaitLivePicture(page, treat.livePicture, { timeoutMs: treat.livePictureTimeoutMs });
|
|
88
|
-
// Wait for web fonts, else the snapshot catches a fallback font mid-swap
|
|
89
|
-
|
|
118
|
+
// Wait for web fonts, else the snapshot catches a fallback font mid-swap --
|
|
119
|
+
// but not forever (see awaitFontsReady).
|
|
120
|
+
if (!(await awaitFontsReady(page))) {
|
|
121
|
+
console.warn(`[doc-guide] web fonts not ready after ${FONTS_READY_TIMEOUT_MS}ms; capturing with what has loaded`);
|
|
122
|
+
}
|
|
90
123
|
if (treat?.crop)
|
|
91
124
|
return page.locator(treat.crop).first().screenshot();
|
|
92
125
|
if (treat?.spotlight) {
|