Mercurial
annotate mrjunejune/test/theme_and_webp_test.js @ 256:30c2196d03d4
[site] Integrate Zenbu themes and components
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 04 Aug 2026 16:49:01 -0700 |
| parents | 543df0fe7168 |
| children | 60a876c4587a |
| rev | line source |
|---|---|
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
1 const assert = require('node:assert/strict'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
2 const fs = require('node:fs'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
3 const net = require('node:net'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
4 const path = require('node:path'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
5 const { spawn } = require('node:child_process'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
6 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
7 const RUNFILES = process.env.JS_BINARY__RUNFILES; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
8 const WORKSPACE = process.env.JS_BINARY__WORKSPACE; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
9 let port; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
10 let baseUrl; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
11 const playwrightPath = path.join( |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
12 RUNFILES, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
13 WORKSPACE, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
14 'hg-web/e2e/node_modules/playwright-core', |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
15 ); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
16 const { chromium } = require(playwrightPath); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
17 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
18 function stopProcess(child) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
19 if (!child || child.exitCode !== null) return Promise.resolve(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
20 child.kill('SIGTERM'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
21 return new Promise(resolve => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
22 const timer = setTimeout(() => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
23 if (child.exitCode === null) child.kill('SIGKILL'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
24 }, 3000); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
25 child.once('exit', () => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
26 clearTimeout(timer); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
27 resolve(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
28 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
29 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
30 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
31 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
32 async function waitForServer(child, logs) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
33 const deadline = Date.now() + 15000; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
34 while (Date.now() < deadline) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
35 if (child.exitCode !== null) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
36 throw new Error(`Server exited with ${child.exitCode}\n${logs.join('')}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
37 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
38 try { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
39 const response = await fetch(baseUrl); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
40 if (response.ok) return; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
41 } catch { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
42 // Keep waiting for startup. |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
43 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
44 await new Promise(resolve => setTimeout(resolve, 100)); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
45 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
46 throw new Error(`Server startup timed out\n${logs.join('')}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
47 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
48 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
49 function listFiles(root) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
50 const files = []; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
51 for (const entry of fs.readdirSync(root, { withFileTypes: true })) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
52 const absolute = path.join(root, entry.name); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
53 if (entry.isDirectory()) files.push(...listFiles(absolute)); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
54 else files.push(absolute); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
55 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
56 return files; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
57 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
58 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
59 async function sampleTheme(browser, theme) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
60 const context = await browser.newContext({ colorScheme: 'dark' }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
61 await context.addInitScript(value => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
62 localStorage.setItem('theme-preference', value); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
63 }, theme); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
64 const page = await context.newPage(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
65 const errors = []; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
66 page.on('pageerror', error => errors.push(`pageerror: ${error.message}`)); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
67 page.on('console', message => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
68 if (message.type() === 'error') errors.push(`console: ${message.text()}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
69 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
70 page.on('requestfailed', request => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
71 errors.push(`requestfailed: ${request.url()} ${request.failure()?.errorText || ''}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
72 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
73 page.on('response', response => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
74 if (response.status() >= 400) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
75 errors.push(`response: ${response.status()} ${response.url()}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
76 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
77 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
78 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
79 await page.goto(baseUrl, { waitUntil: 'networkidle' }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
80 await page.waitForFunction(() => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
81 const canvas = document.querySelector('#background'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
82 if (!canvas) return false; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
83 const data = canvas.getContext('2d').getImageData( |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
84 0, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
85 0, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
86 canvas.width, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
87 canvas.height, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
88 ).data; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
89 for (let index = 3; index < data.length; index += 4) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
90 if (data[index] >= 20) return true; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
91 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
92 return false; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
93 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
94 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
95 const sample = await page.evaluate(() => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
96 const canvas = document.querySelector('#background'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
97 const data = canvas.getContext('2d').getImageData( |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
98 0, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
99 0, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
100 canvas.width, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
101 canvas.height, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
102 ).data; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
103 let count = 0; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
104 let luminance = 0; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
105 for (let index = 0; index < data.length; index += 4) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
106 if (data[index + 3] < 20) continue; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
107 count++; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
108 luminance += |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
109 data[index] * 0.2126 + |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
110 data[index + 1] * 0.7152 + |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
111 data[index + 2] * 0.0722; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
112 } |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
113 const channels = value => value.match(/\d+(?:\.\d+)?/g) |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
114 .slice(0, 3) |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
115 .map(Number); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
116 const colorLuminance = value => { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
117 const converted = channels(value).map(channel => { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
118 const normalized = channel / 255; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
119 return normalized <= 0.04045 |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
120 ? normalized / 12.92 |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
121 : ((normalized + 0.055) / 1.055) ** 2.4; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
122 }); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
123 return converted[0] * 0.2126 + |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
124 converted[1] * 0.7152 + |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
125 converted[2] * 0.0722; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
126 }; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
127 const bodyStyle = getComputedStyle(document.body); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
128 const foreground = colorLuminance(bodyStyle.color); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
129 const background = colorLuminance( |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
130 getComputedStyle(document.querySelector('main')).backgroundColor, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
131 ); |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
132 return { |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
133 cardCount: document.querySelectorAll('.site-link-grid zen-card').length, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
134 componentReady: Boolean(customElements.get('zen-card')), |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
135 count, |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
136 fontFamily: getComputedStyle(document.body).fontFamily, |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
137 luminance: count ? luminance / count : 0, |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
138 textContrast: (Math.max(foreground, background) + 0.05) / |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
139 (Math.min(foreground, background) + 0.05), |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
140 rootTheme: document.documentElement.dataset.zenTheme || 'auto', |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
141 themeLabel: document.querySelector('#themeName')?.textContent, |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
142 }; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
143 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
144 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
145 if (errors.length) throw new Error(`${theme}\n${errors.join('\n')}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
146 await context.close(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
147 return sample; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
148 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
149 |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
150 async function testThemeCycle(browser) { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
151 const context = await browser.newContext({ colorScheme: 'light' }); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
152 const page = await context.newPage(); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
153 await page.goto(baseUrl, { waitUntil: 'networkidle' }); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
154 const expected = ['paper', 'ink', 'playful', 'auto']; |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
155 for (const theme of expected) { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
156 await page.locator('#themeToggle').click(); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
157 assert.equal( |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
158 await page.evaluate(() => |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
159 document.documentElement.dataset.zenTheme || 'auto' |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
160 ), |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
161 theme, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
162 ); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
163 assert.equal( |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
164 await page.evaluate(() => localStorage.getItem('theme-preference')), |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
165 theme, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
166 ); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
167 } |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
168 await context.close(); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
169 } |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
170 |
|
242
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
171 async function testHlsPlayer(browser, siteRoot) { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
172 const page = await browser.newPage(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
173 const errors = []; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
174 const mediaRequests = []; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
175 let testingExpectedFailure = false; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
176 let testingExpectedReload = false; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
177 page.on('pageerror', error => errors.push(`pageerror: ${error.message}`)); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
178 page.on('console', message => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
179 if (message.type() !== 'error') return; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
180 if (testingExpectedFailure && |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
181 message.text().startsWith('Failed to load resource:')) return; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
182 errors.push(`console: ${message.text()}`); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
183 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
184 page.on('requestfailed', request => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
185 if (testingExpectedReload && |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
186 request.failure()?.errorText === 'net::ERR_ABORTED') return; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
187 errors.push(`requestfailed: ${request.url()} ${request.failure()?.errorText || ''}`); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
188 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
189 page.on('request', request => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
190 if (/\.(?:m3u8|m4s|mp4)(?:\?|$)/.test(request.url())) { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
191 mediaRequests.push(request.url()); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
192 } |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
193 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
194 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
195 const playlistResponse = await fetch( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
196 `${baseUrl}/public/hls-sample/master.m3u8`, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
197 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
198 assert.equal(playlistResponse.status, 200); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
199 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
200 playlistResponse.headers.get('content-type') || '', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
201 /^application\/vnd\.apple\.mpegurl/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
202 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
203 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
204 await playlistResponse.text(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
205 /#EXT-X-STREAM-INF:.*CODECS="vp09\.00\.10\.08,opus"/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
206 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
207 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
208 const variantResponse = await fetch( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
209 `${baseUrl}/public/hls-sample/vp9-stream.m3u8`, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
210 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
211 assert.equal(variantResponse.status, 200); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
212 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
213 await variantResponse.text(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
214 /#EXT-X-MAP:URI="vp9-init\.mp4"/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
215 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
216 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
217 const segmentResponse = await fetch( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
218 `${baseUrl}/public/hls-sample/vp9-segment000.m4s`, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
219 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
220 assert.equal(segmentResponse.status, 200); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
221 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
222 segmentResponse.headers.get('content-type') || '', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
223 /^video\/iso\.segment/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
224 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
225 const transportStreamResponse = await fetch( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
226 `${baseUrl}/public/hls-sample/h264-ts-segment000.ts`, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
227 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
228 assert.equal(transportStreamResponse.status, 200); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
229 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
230 transportStreamResponse.headers.get('content-type') || '', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
231 /^video\/mp2t/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
232 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
233 assert.ok((await transportStreamResponse.arrayBuffer()).byteLength > 0); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
234 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
235 await page.goto( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
236 `${baseUrl}/tools/hls_player?url=${encodeURIComponent('/public/hls-sample/master.m3u8')}`, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
237 { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
238 waitUntil: 'networkidle', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
239 }, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
240 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
241 await page.getByRole('button', { name: 'Sample', exact: true }).waitFor(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
242 assert.equal( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
243 await page.locator('#hlsUrl').evaluate(input => input.defaultValue), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
244 '/public/hls-sample/h264-ts-stream.m3u8', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
245 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
246 await page.waitForFunction(() => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
247 const status = document.querySelector('#hlsStatus'); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
248 return status?.dataset.state === 'ready' || |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
249 status?.dataset.state === 'error'; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
250 }, null, { timeout: 15000 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
251 const terminalState = await page.locator('#hlsStatus').getAttribute('data-state'); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
252 if (terminalState !== 'ready') { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
253 throw new Error( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
254 `HLS player failed: ${await page.locator('#hlsStatus').textContent()}\n${errors.join('\n')}`, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
255 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
256 } |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
257 assert.match(await page.locator('#hlsStatus').textContent(), /Stream ready/); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
258 assert.equal( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
259 await page.locator('[data-detail="mode"]').textContent(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
260 'hls.js', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
261 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
262 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
263 await page.locator('[data-detail="segments"]').textContent(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
264 /Managed by hls\.js|adaptive levels/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
265 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
266 await page.waitForFunction(() => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
267 const video = document.querySelector('#hlsVideo'); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
268 return video.readyState >= HTMLMediaElement.HAVE_METADATA && |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
269 Number.isFinite(video.duration) && |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
270 video.duration >= 14; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
271 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
272 const firstFrame = await page.locator('#hlsVideo').evaluate(video => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
273 const canvas = document.createElement('canvas'); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
274 canvas.width = video.videoWidth; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
275 canvas.height = video.videoHeight; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
276 const context = canvas.getContext('2d'); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
277 context.drawImage(video, 0, 0); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
278 const pixels = context.getImageData(0, 0, canvas.width, canvas.height).data; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
279 let total = 0; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
280 for (let index = 0; index < pixels.length; index += 4) { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
281 total += pixels[index] + pixels[index + 1] + pixels[index + 2]; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
282 } |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
283 return total / (canvas.width * canvas.height * 3); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
284 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
285 assert.ok(firstFrame > 10, `Initial HLS frame is black: ${firstFrame}`); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
286 await page.locator('#hlsVideo').evaluate(video => video.play()); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
287 await page.waitForFunction(() => document.querySelector('#hlsVideo').currentTime > 0.2); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
288 await page.locator('#hlsVideo').evaluate(video => video.pause()); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
289 assert.ok(mediaRequests.some(url => url.endsWith('/hls-sample/master.m3u8'))); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
290 assert.ok(mediaRequests.some(url => url.endsWith('-stream.m3u8'))); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
291 assert.ok(mediaRequests.some(url => url.endsWith('-init.mp4'))); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
292 assert.ok(mediaRequests.some(url => /-segment\d+\.m4s$/.test(url))); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
293 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
294 await page.evaluate(() => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
295 window.hlsPlayer.hls.trigger(window.Hls.Events.ERROR, { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
296 fatal: true, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
297 type: window.Hls.ErrorTypes.MEDIA_ERROR, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
298 details: 'testRuntimeFailure', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
299 error: new Error('runtime segment failed'), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
300 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
301 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
302 await page.locator('#hlsStatus[data-state="error"]').waitFor(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
303 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
304 await page.locator('#hlsStatus').textContent(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
305 /runtime segment failed/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
306 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
307 await page.locator('#hlsUrl').fill('/public/hls-sample/master.m3u8'); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
308 await page.getByRole('button', { name: 'Load', exact: true }).click(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
309 await page.locator('#hlsStatus[data-state="ready"]').waitFor(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
310 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
311 let delayedSegment = true; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
312 await page.route('**/hls-sample/vp9-segment000.m4s', async route => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
313 if (delayedSegment) { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
314 delayedSegment = false; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
315 await new Promise(resolve => setTimeout(resolve, 250)); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
316 } |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
317 await route.continue(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
318 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
319 testingExpectedReload = true; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
320 await page.locator('#hlsUrl').fill('/public/hls-sample/master.m3u8'); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
321 await page.getByRole('button', { name: 'Load', exact: true }).click(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
322 await page.waitForTimeout(25); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
323 await page.getByRole('button', { name: 'Load', exact: true }).click(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
324 await page.locator('#hlsStatus[data-state="ready"]').waitFor(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
325 testingExpectedReload = false; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
326 assert.match(await page.locator('#hlsStatus').textContent(), /Stream ready/); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
327 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
328 await page.evaluate(() => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
329 window.__hlsObjectUrls = { created: [], revoked: [] }; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
330 const createObjectURL = URL.createObjectURL.bind(URL); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
331 const revokeObjectURL = URL.revokeObjectURL.bind(URL); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
332 URL.createObjectURL = value => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
333 const url = createObjectURL(value); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
334 window.__hlsObjectUrls.created.push(url); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
335 return url; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
336 }; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
337 URL.revokeObjectURL = url => { |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
338 window.__hlsObjectUrls.revoked.push(url); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
339 revokeObjectURL(url); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
340 }; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
341 }); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
342 const localFiles = listFiles(path.join(siteRoot, 'public/hls-sample')); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
343 await page.locator('#hlsFiles').setInputFiles(localFiles); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
344 await page.waitForFunction(() => |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
345 document.querySelector('#hlsUrl')?.value.startsWith('Local: ') |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
346 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
347 await page.locator('#hlsStatus[data-state="ready"]').waitFor(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
348 assert.match(await page.locator('#hlsUrl').inputValue(), /^Local: /); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
349 assert.equal( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
350 await page.locator('[data-detail="mode"]').textContent(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
351 'hls.js', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
352 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
353 await page.locator('#hlsVideo').evaluate(video => video.play()); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
354 await page.waitForFunction(() => document.querySelector('#hlsVideo').currentTime > 0.3); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
355 await page.locator('#hlsVideo').evaluate(video => video.pause()); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
356 const incompleteLocalFiles = localFiles.filter(file => |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
357 file.endsWith('master.m3u8') || |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
358 file.endsWith('vp9-stream.m3u8') |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
359 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
360 await page.locator('#hlsFiles').setInputFiles(incompleteLocalFiles); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
361 await page.locator('#hlsStatus[data-state="error"]').waitFor(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
362 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
363 await page.locator('#hlsStatus').textContent(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
364 /Local HLS file is missing/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
365 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
366 const objectUrlCounts = await page.evaluate(() => ({ |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
367 created: window.__hlsObjectUrls.created.length, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
368 revoked: window.__hlsObjectUrls.revoked.length, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
369 })); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
370 assert.ok(objectUrlCounts.created > 10, JSON.stringify(objectUrlCounts)); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
371 assert.ok( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
372 objectUrlCounts.revoked >= objectUrlCounts.created, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
373 JSON.stringify(objectUrlCounts), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
374 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
375 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
376 await page.route('**/invalid.m3u8', route => route.fulfill({ |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
377 status: 404, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
378 body: 'not found', |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
379 })); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
380 testingExpectedFailure = true; |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
381 await page.locator('#hlsUrl').fill(`${baseUrl}/invalid.m3u8`); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
382 await page.getByRole('button', { name: 'Load', exact: true }).click(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
383 await page.locator('#hlsStatus[data-state="error"]').waitFor(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
384 assert.match( |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
385 await page.locator('#hlsStatus').textContent(), |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
386 /404|manifestLoadError|Playlist request failed/, |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
387 ); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
388 |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
389 if (errors.length) throw new Error(errors.join('\n')); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
390 await page.close(); |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
391 } |
|
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
392 |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
393 function findFreePort() { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
394 return new Promise((resolve, reject) => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
395 const socket = net.createServer(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
396 socket.once('error', reject); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
397 socket.listen(0, '127.0.0.1', () => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
398 const address = socket.address(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
399 socket.close(error => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
400 if (error) reject(error); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
401 else resolve(String(address.port)); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
402 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
403 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
404 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
405 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
406 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
407 (async () => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
408 assert.ok(RUNFILES); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
409 assert.ok(WORKSPACE); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
410 const runfilesWorkspace = path.join(RUNFILES, WORKSPACE); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
411 const serverBinary = path.join( |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
412 runfilesWorkspace, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
413 'mrjunejune/mrjunejune_server', |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
414 ); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
415 const siteRoot = path.join(runfilesWorkspace, 'mrjunejune/src'); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
416 const chromiumPath = path.resolve(process.env.CHROMIUM_PATH); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
417 const serverLogs = []; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
418 let server; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
419 let browser; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
420 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
421 try { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
422 port = await findFreePort(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
423 baseUrl = `http://127.0.0.1:${port}`; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
424 const pngFiles = listFiles(siteRoot).filter(file => file.endsWith('.png')); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
425 assert.deepEqual(pngFiles, [], `PNG files leaked into runfiles: ${pngFiles}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
426 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
427 server = spawn(serverBinary, [], { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
428 cwd: runfilesWorkspace, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
429 env: { ...process.env, MRJUNEJUNE_PORT: port }, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
430 stdio: ['ignore', 'pipe', 'pipe'], |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
431 }); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
432 server.stdout.on('data', chunk => serverLogs.push(chunk.toString())); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
433 server.stderr.on('data', chunk => serverLogs.push(chunk.toString())); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
434 await waitForServer(server, serverLogs); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
435 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
436 const home = await (await fetch(baseUrl)).text(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
437 const dogGame = await ( |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
438 await fetch(`${baseUrl}/public/dog-game.js`) |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
439 ).text(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
440 const manifest = await ( |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
441 await fetch(`${baseUrl}/public/manifest.json`) |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
442 ).text(); |
|
242
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
443 const serviceWorker = await ( |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
444 await fetch(`${baseUrl}/sw.js`) |
|
242
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
445 ).text(); |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
446 for (const source of [home, dogGame, manifest]) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
447 assert.doesNotMatch(source, /\.png(?:["')]|$)/i); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
448 } |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
449 assert.match(serviceWorker, /v5-zenbu-themes/); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
450 assert.match( |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
451 await ( |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
452 await fetch(`${baseUrl}/public/pwa-register.js`) |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
453 ).text(), |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
454 /register\('\/sw\.js', \{ scope: '\/' \}\)/, |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
455 ); |
|
242
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
456 assert.ok(serviceWorker.includes("startsWith('/tools/hls_player')")); |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
457 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
458 for (const asset of [ |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
459 'sprite_shiba0.webp', |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
460 'dog-treat.webp', |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
461 'start-large.webp', |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
462 'icon-192.webp', |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
463 'vscode.webp', |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
464 ]) { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
465 const response = await fetch(`${baseUrl}/public/${asset}`); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
466 assert.equal(response.status, 200, asset); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
467 assert.ok((await response.arrayBuffer()).byteLength > 0, asset); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
468 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
469 |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
470 browser = await chromium.launch({ |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
471 executablePath: chromiumPath, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
472 headless: true, |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
473 args: ['--no-sandbox'], |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
474 }); |
|
256
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
475 const paper = await sampleTheme(browser, 'paper'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
476 const ink = await sampleTheme(browser, 'ink'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
477 const playful = await sampleTheme(browser, 'playful'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
478 const automatic = await sampleTheme(browser, 'auto'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
479 assert.equal(paper.rootTheme, 'paper'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
480 assert.equal(ink.rootTheme, 'ink'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
481 assert.equal(playful.rootTheme, 'playful'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
482 assert.equal(automatic.rootTheme, 'auto'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
483 assert.equal(paper.themeLabel, 'Paper'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
484 assert.equal(ink.themeLabel, 'Ink'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
485 assert.equal(playful.themeLabel, 'Playful'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
486 assert.equal(automatic.themeLabel, 'Auto'); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
487 for (const sample of [paper, ink, playful, automatic]) { |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
488 assert.ok(sample.count > 0); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
489 assert.equal(sample.componentReady, true); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
490 assert.equal(sample.cardCount, 4); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
491 assert.match(sample.fontFamily, /More/); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
492 assert.ok(sample.textContrast >= 4.5, JSON.stringify(sample)); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
493 } |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
494 assert.ok(paper.luminance < 175, JSON.stringify(paper)); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
495 assert.ok(playful.luminance < 175, JSON.stringify(playful)); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
496 assert.ok(ink.luminance > 200, JSON.stringify(ink)); |
|
30c2196d03d4
[site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents:
242
diff
changeset
|
497 await testThemeCycle(browser); |
|
242
543df0fe7168
[tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents:
241
diff
changeset
|
498 await testHlsPlayer(browser, siteRoot); |
|
241
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
499 } finally { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
500 if (browser) await browser.close(); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
501 await stopProcess(server); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
502 } |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
503 })().catch(error => { |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
504 console.error(error.stack || error); |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
505 process.exitCode = 1; |
|
9c2eec61a152
[assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff
changeset
|
506 }); |