annotate mrjunejune/test/theme_and_webp_test.js @ 258:60a876c4587a

[ui] Add semantic primitive ownership Build a layered Zenbu token and sizing system, make authored controls use native-underneath primitives, migrate mrjunejune without imposing visual surfaces, and document/enforce HTML ownership in the catalog and wiki. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Wed, 05 Aug 2026 05:25:40 -0700
parents 30c2196d03d4
children 667156fcd3e3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
59 function primitiveOwnershipViolations(source) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
60 const violations = [];
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
61 const stack = [];
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
62 const voidElements = new Set([
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
63 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
64 'meta', 'param', 'source', 'track', 'wbr',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
65 ]);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
66 const ownerMap = {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
67 button: new Set(['zen-button']),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
68 select: new Set(['zen-field', 'zen-native-select', 'zen-select']),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
69 textarea: new Set(['zen-field', 'zen-textarea']),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
70 };
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
71
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
72 for (const token of source.matchAll(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
73 /<!--[\s\S]*?-->|<\/?([a-zA-Z][\w-]*)\b([^>]*)>/g,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
74 )) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
75 if (!token[1]) continue;
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
76 const name = token[1].toLowerCase();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
77 if (token[0].startsWith('</')) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
78 while (stack.length) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
79 if (stack.pop() === name) break;
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
80 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
81 continue;
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
82 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
83
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
84 let owners = ownerMap[name];
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
85 if (name === 'input') {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
86 const type = /\btype\s*=\s*["']?([^"'\s>]+)/i.exec(token[2])?.[1]
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
87 ?.toLowerCase() || 'text';
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
88 if (type === 'checkbox') {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
89 owners = new Set(['zen-checkbox', 'zen-field', 'zen-switch']);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
90 } else if (type === 'radio') {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
91 owners = new Set(['zen-field', 'zen-radio-group']);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
92 } else if (type === 'range') {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
93 owners = new Set(['zen-field', 'zen-slider']);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
94 } else if (type === 'date') {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
95 owners = new Set(['zen-calendar', 'zen-date-picker', 'zen-field']);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
96 } else {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
97 owners = new Set([
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
98 'zen-combobox',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
99 'zen-command',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
100 'zen-field',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
101 'zen-input',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
102 'zen-input-group',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
103 'zen-input-otp',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
104 ]);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
105 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
106 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
107 if (owners) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
108 const matchingOwners = stack.filter(ancestor => owners.has(ancestor));
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
109 if (matchingOwners.length !== 1) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
110 violations.push({
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
111 control: name,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
112 owners: matchingOwners,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
113 source: token[0],
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
114 });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
115 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
116 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
117
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
118 if (!voidElements.has(name) && !token[0].endsWith('/>')) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
119 stack.push(name);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
120 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
121 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
122 return violations;
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
123 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
124
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
125 async function sampleTheme(browser, theme) {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
126 const context = await browser.newContext({ colorScheme: 'dark' });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
127 await context.addInitScript(value => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
128 localStorage.setItem('theme-preference', value);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
129 }, theme);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
130 const page = await context.newPage();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
131 const errors = [];
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
132 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
133 page.on('console', message => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
134 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
135 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
136 page.on('requestfailed', request => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
137 errors.push(`requestfailed: ${request.url()} ${request.failure()?.errorText || ''}`);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
138 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
139 page.on('response', response => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
140 if (response.status() >= 400) {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
141 errors.push(`response: ${response.status()} ${response.url()}`);
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 await page.goto(baseUrl, { waitUntil: 'networkidle' });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
146 await page.waitForFunction(() => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
147 const canvas = document.querySelector('#background');
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
148 if (!canvas) return false;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
149 const data = canvas.getContext('2d').getImageData(
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
150 0,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
151 0,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
152 canvas.width,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
153 canvas.height,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
154 ).data;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
155 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
156 if (data[index] >= 20) return true;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
157 }
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
158 return false;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
159 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
160
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
161 const sample = await page.evaluate(() => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
162 const canvas = document.querySelector('#background');
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
163 const data = canvas.getContext('2d').getImageData(
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
164 0,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
165 0,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
166 canvas.width,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
167 canvas.height,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
168 ).data;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
169 let count = 0;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
170 let luminance = 0;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
171 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
172 if (data[index + 3] < 20) continue;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
173 count++;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
174 luminance +=
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
175 data[index] * 0.2126 +
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
176 data[index + 1] * 0.7152 +
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
177 data[index + 2] * 0.0722;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
178 }
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
179 const channels = value => value.match(/\d+(?:\.\d+)?/g)
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
180 .slice(0, 3)
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
181 .map(Number);
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
182 const colorLuminance = value => {
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
183 const converted = channels(value).map(channel => {
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
184 const normalized = channel / 255;
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
185 return normalized <= 0.04045
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
186 ? normalized / 12.92
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
187 : ((normalized + 0.055) / 1.055) ** 2.4;
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
188 });
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
189 return converted[0] * 0.2126 +
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
190 converted[1] * 0.7152 +
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
191 converted[2] * 0.0722;
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
192 };
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
193 const bodyStyle = getComputedStyle(document.body);
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
194 const themeButtonStyle = getComputedStyle(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
195 document.querySelector('#themeToggle'),
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
196 );
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
197 const foreground = colorLuminance(bodyStyle.color);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
198 const contrastProbe = document.createElement('span');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
199 contrastProbe.style.background = 'var(--zen-color-surface)';
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
200 document.body.append(contrastProbe);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
201 const background = colorLuminance(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
202 getComputedStyle(contrastProbe).backgroundColor,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
203 );
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
204 contrastProbe.remove();
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
205 return {
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
206 backgroundRepeat: bodyStyle.backgroundRepeat,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
207 backgroundSize: bodyStyle.backgroundSize,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
208 bodyCoversViewport: document.body.getBoundingClientRect().height >=
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
209 innerHeight,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
210 componentReady: Boolean(customElements.get('zen-button')),
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
211 count,
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
212 fontFamily: getComputedStyle(document.body).fontFamily,
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
213 headerPaws: document.querySelectorAll(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
214 'header [data-zen-link-decoration]',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
215 ).length,
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
216 luminance: count ? luminance / count : 0,
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
217 textContrast: (Math.max(foreground, background) + 0.05) /
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
218 (Math.min(foreground, background) + 0.05),
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
219 rootTheme: document.documentElement.dataset.zenTheme || 'auto',
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
220 enhancedLinks: document.querySelectorAll(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
221 'zen-link[effect="paw"] > a > zen-icon[name="paw"]',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
222 ).length,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
223 links: document.querySelectorAll('a').length,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
224 pawLinks: [...document.querySelectorAll('a')].filter(link =>
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
225 !link.closest('zen-button') &&
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
226 link.dataset.zenLinkEffect !== 'none'
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
227 ).length,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
228 mainBackground: getComputedStyle(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
229 document.querySelector('main'),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
230 ).backgroundColor,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
231 themeButtonBackground: themeButtonStyle.backgroundColor,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
232 themeButtonBorder: themeButtonStyle.borderTopWidth,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
233 themeButtonShadow: themeButtonStyle.boxShadow,
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
234 themeLabel: document.querySelector('#themeName')?.textContent,
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
235 };
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
236 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
237
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
238 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
239 await context.close();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
240 return sample;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
241 }
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
242
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
243 async function testThemeCycle(browser) {
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
244 const context = await browser.newContext({ colorScheme: 'light' });
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
245 const page = await context.newPage();
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
246 await page.goto(baseUrl, { waitUntil: 'networkidle' });
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
247 const expected = ['paper', 'ink', 'playful', 'auto'];
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
248 for (const theme of expected) {
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
249 await page.locator('#themeToggle').click();
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
250 assert.equal(
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
251 await page.evaluate(() =>
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
252 document.documentElement.dataset.zenTheme || 'auto'
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
253 ),
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
254 theme,
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
255 );
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
256 assert.equal(
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
257 await page.evaluate(() => localStorage.getItem('theme-preference')),
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
258 theme,
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
259 );
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
260 }
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
261 await context.close();
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
262 }
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
263
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
264 async function testPlainField(browser) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
265 const page = await browser.newPage();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
266 await page.goto(`${baseUrl}/tools/markdown_to_html`, {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
267 waitUntil: 'networkidle',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
268 });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
269 await page.waitForFunction(() => customElements.get('zen-field'));
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
270 const state = await page.locator('zen-field[appearance="plain"]').evaluate(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
271 field => {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
272 const label = field.querySelector('label');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
273 const textarea = field.querySelector('textarea');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
274 const probe = document.createElement('span');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
275 probe.style.border = '1px solid var(--accent)';
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
276 document.body.append(probe);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
277 const accent = getComputedStyle(probe).borderColor;
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
278 probe.remove();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
279 textarea.focus();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
280 return {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
281 borderColor: getComputedStyle(textarea).borderColor,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
282 display: getComputedStyle(field).display,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
283 labelFor: label.htmlFor,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
284 accent,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
285 textareaId: textarea.id,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
286 };
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
287 },
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
288 );
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
289 assert.deepEqual(state, {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
290 accent: state.borderColor,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
291 borderColor: state.borderColor,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
292 display: 'contents',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
293 labelFor: 'input',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
294 textareaId: 'input',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
295 });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
296 await page.close();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
297 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
298
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
299 async function testButtonScale(browser) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
300 const page = await browser.newPage();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
301 for (const route of [
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
302 '/talk',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
303 '/notes/login',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
304 '/tools/hls_player',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
305 '/tools/latex_editor',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
306 '/tools/markdown_to_html',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
307 '/tools/file_converter',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
308 '/offline.html',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
309 ]) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
310 await page.goto(`${baseUrl}${route}`, { waitUntil: 'networkidle' });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
311 await page.waitForFunction(() => customElements.get('zen-button'));
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
312 const controls = await page.locator(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
313 'zen-button[size] > :is(button, a):not(#themeToggle)',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
314 ).evaluateAll(elements => elements.map(control => {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
315 const host = control.parentElement;
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
316 const style = getComputedStyle(control);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
317 const hostStyle = getComputedStyle(host);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
318 return {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
319 height: control.getBoundingClientRect().height,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
320 minimum: Number.parseFloat(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
321 hostStyle.getPropertyValue('--zenbu-control-height'),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
322 ) * Number.parseFloat(getComputedStyle(document.documentElement).fontSize),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
323 paddingBlock: style.paddingBlockStart,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
324 paddingVariable: Number.parseFloat(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
325 hostStyle.getPropertyValue('--zenbu-control-padding-block'),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
326 ) * Number.parseFloat(getComputedStyle(document.documentElement).fontSize),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
327 size: host.getAttribute('size'),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
328 };
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
329 }));
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
330 assert.ok(controls.length > 0, route);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
331 for (const control of controls) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
332 assert.match(control.size, /^(?:xs|sm|md|lg|xl)$/);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
333 assert.ok(control.height >= control.minimum - 1, JSON.stringify(control));
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
334 assert.ok(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
335 Math.abs(Number.parseFloat(control.paddingBlock) -
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
336 control.paddingVariable) < 1,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
337 JSON.stringify(control),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
338 );
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
339 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
340 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
341 await page.close();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
342 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
343
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
344 async function testDynamicButtonOwnership(browser) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
345 const page = await browser.newPage();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
346 await page.goto(baseUrl, { waitUntil: 'networkidle' });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
347 await page.evaluate(() => {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
348 window.dispatchEvent(new Event('beforeinstallprompt', {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
349 cancelable: true,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
350 }));
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
351 });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
352 const state = await page.locator('#pwa-install-btn').evaluate(button => ({
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
353 ownerCount: button.closest('zen-button') ? 1 : 0,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
354 appearance: button.closest('zen-button')?.getAttribute('appearance'),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
355 size: button.closest('zen-button')?.getAttribute('size'),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
356 }));
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
357 assert.deepEqual(state, {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
358 appearance: 'plain',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
359 ownerCount: 1,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
360 size: 'md',
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
361 });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
362 await page.close();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
363 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
364
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
365 async function testResumePrint(browser) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
366 const page = await browser.newPage();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
367 await page.emulateMedia({ media: 'print' });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
368 await page.goto(`${baseUrl}/resume`, { waitUntil: 'networkidle' });
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
369 assert.equal(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
370 await page.locator('.info > a[href="/public/resume.pdf"]').isVisible(),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
371 false,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
372 );
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
373 await page.close();
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
374 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
375
242
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
376 async function testHlsPlayer(browser, siteRoot) {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
377 const page = await browser.newPage();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
378 const errors = [];
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
379 const mediaRequests = [];
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
380 let testingExpectedFailure = false;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
381 let testingExpectedReload = false;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
382 page.on('pageerror', error => errors.push(`pageerror: ${error.message}`));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
383 page.on('console', message => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
384 if (message.type() !== 'error') return;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
385 if (testingExpectedFailure &&
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
386 message.text().startsWith('Failed to load resource:')) return;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
387 errors.push(`console: ${message.text()}`);
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 page.on('requestfailed', request => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
390 if (testingExpectedReload &&
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
391 request.failure()?.errorText === 'net::ERR_ABORTED') return;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
392 errors.push(`requestfailed: ${request.url()} ${request.failure()?.errorText || ''}`);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
393 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
394 page.on('request', request => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
395 if (/\.(?:m3u8|m4s|mp4)(?:\?|$)/.test(request.url())) {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
396 mediaRequests.push(request.url());
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
397 }
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
398 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
399
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
400 const playlistResponse = await fetch(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
401 `${baseUrl}/public/hls-sample/master.m3u8`,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
402 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
403 assert.equal(playlistResponse.status, 200);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
404 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
405 playlistResponse.headers.get('content-type') || '',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
406 /^application\/vnd\.apple\.mpegurl/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
407 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
408 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
409 await playlistResponse.text(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
410 /#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
411 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
412
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
413 const variantResponse = await fetch(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
414 `${baseUrl}/public/hls-sample/vp9-stream.m3u8`,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
415 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
416 assert.equal(variantResponse.status, 200);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
417 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
418 await variantResponse.text(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
419 /#EXT-X-MAP:URI="vp9-init\.mp4"/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
420 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
421
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
422 const segmentResponse = await fetch(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
423 `${baseUrl}/public/hls-sample/vp9-segment000.m4s`,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
424 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
425 assert.equal(segmentResponse.status, 200);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
426 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
427 segmentResponse.headers.get('content-type') || '',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
428 /^video\/iso\.segment/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
429 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
430 const transportStreamResponse = await fetch(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
431 `${baseUrl}/public/hls-sample/h264-ts-segment000.ts`,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
432 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
433 assert.equal(transportStreamResponse.status, 200);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
434 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
435 transportStreamResponse.headers.get('content-type') || '',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
436 /^video\/mp2t/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
437 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
438 assert.ok((await transportStreamResponse.arrayBuffer()).byteLength > 0);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
439
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
440 await page.goto(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
441 `${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
442 {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
443 waitUntil: 'networkidle',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
444 },
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
445 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
446 await page.getByRole('button', { name: 'Sample', exact: true }).waitFor();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
447 assert.equal(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
448 await page.locator('#hlsUrl').evaluate(input => input.defaultValue),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
449 '/public/hls-sample/h264-ts-stream.m3u8',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
450 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
451 await page.waitForFunction(() => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
452 const status = document.querySelector('#hlsStatus');
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
453 return status?.dataset.state === 'ready' ||
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
454 status?.dataset.state === 'error';
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
455 }, null, { timeout: 15000 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
456 const terminalState = await page.locator('#hlsStatus').getAttribute('data-state');
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
457 if (terminalState !== 'ready') {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
458 throw new Error(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
459 `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
460 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
461 }
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
462 assert.match(await page.locator('#hlsStatus').textContent(), /Stream ready/);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
463 assert.equal(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
464 await page.locator('[data-detail="mode"]').textContent(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
465 'hls.js',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
466 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
467 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
468 await page.locator('[data-detail="segments"]').textContent(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
469 /Managed by hls\.js|adaptive levels/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
470 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
471 await page.waitForFunction(() => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
472 const video = document.querySelector('#hlsVideo');
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
473 return video.readyState >= HTMLMediaElement.HAVE_METADATA &&
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
474 Number.isFinite(video.duration) &&
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
475 video.duration >= 14;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
476 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
477 const firstFrame = await page.locator('#hlsVideo').evaluate(video => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
478 const canvas = document.createElement('canvas');
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
479 canvas.width = video.videoWidth;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
480 canvas.height = video.videoHeight;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
481 const context = canvas.getContext('2d');
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
482 context.drawImage(video, 0, 0);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
483 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
484 let total = 0;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
485 for (let index = 0; index < pixels.length; index += 4) {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
486 total += pixels[index] + pixels[index + 1] + pixels[index + 2];
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
487 }
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
488 return total / (canvas.width * canvas.height * 3);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
489 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
490 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
491 await page.locator('#hlsVideo').evaluate(video => video.play());
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
492 await page.waitForFunction(() => document.querySelector('#hlsVideo').currentTime > 0.2);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
493 await page.locator('#hlsVideo').evaluate(video => video.pause());
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
494 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
495 assert.ok(mediaRequests.some(url => url.endsWith('-stream.m3u8')));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
496 assert.ok(mediaRequests.some(url => url.endsWith('-init.mp4')));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
497 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
498
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
499 await page.evaluate(() => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
500 window.hlsPlayer.hls.trigger(window.Hls.Events.ERROR, {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
501 fatal: true,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
502 type: window.Hls.ErrorTypes.MEDIA_ERROR,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
503 details: 'testRuntimeFailure',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
504 error: new Error('runtime segment failed'),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
505 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
506 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
507 await page.locator('#hlsStatus[data-state="error"]').waitFor();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
508 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
509 await page.locator('#hlsStatus').textContent(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
510 /runtime segment failed/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
511 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
512 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
513 await page.getByRole('button', { name: 'Load', exact: true }).click();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
514 await page.locator('#hlsStatus[data-state="ready"]').waitFor();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
515
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
516 let delayedSegment = true;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
517 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
518 if (delayedSegment) {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
519 delayedSegment = false;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
520 await new Promise(resolve => setTimeout(resolve, 250));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
521 }
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
522 await route.continue();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
523 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
524 testingExpectedReload = true;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
525 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
526 await page.getByRole('button', { name: 'Load', exact: true }).click();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
527 await page.waitForTimeout(25);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
528 await page.getByRole('button', { name: 'Load', exact: true }).click();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
529 await page.locator('#hlsStatus[data-state="ready"]').waitFor();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
530 testingExpectedReload = false;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
531 assert.match(await page.locator('#hlsStatus').textContent(), /Stream ready/);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
532
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
533 await page.evaluate(() => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
534 window.__hlsObjectUrls = { created: [], revoked: [] };
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
535 const createObjectURL = URL.createObjectURL.bind(URL);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
536 const revokeObjectURL = URL.revokeObjectURL.bind(URL);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
537 URL.createObjectURL = value => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
538 const url = createObjectURL(value);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
539 window.__hlsObjectUrls.created.push(url);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
540 return url;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
541 };
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
542 URL.revokeObjectURL = url => {
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
543 window.__hlsObjectUrls.revoked.push(url);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
544 revokeObjectURL(url);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
545 };
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
546 });
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
547 const localFiles = listFiles(path.join(siteRoot, 'public/hls-sample'));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
548 await page.locator('#hlsFiles').setInputFiles(localFiles);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
549 await page.waitForFunction(() =>
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
550 document.querySelector('#hlsUrl')?.value.startsWith('Local: ')
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
551 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
552 await page.locator('#hlsStatus[data-state="ready"]').waitFor();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
553 assert.match(await page.locator('#hlsUrl').inputValue(), /^Local: /);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
554 assert.equal(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
555 await page.locator('[data-detail="mode"]').textContent(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
556 'hls.js',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
557 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
558 await page.locator('#hlsVideo').evaluate(video => video.play());
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
559 await page.waitForFunction(() => document.querySelector('#hlsVideo').currentTime > 0.3);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
560 await page.locator('#hlsVideo').evaluate(video => video.pause());
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
561 const incompleteLocalFiles = localFiles.filter(file =>
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
562 file.endsWith('master.m3u8') ||
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
563 file.endsWith('vp9-stream.m3u8')
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
564 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
565 await page.locator('#hlsFiles').setInputFiles(incompleteLocalFiles);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
566 await page.locator('#hlsStatus[data-state="error"]').waitFor();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
567 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
568 await page.locator('#hlsStatus').textContent(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
569 /Local HLS file is missing/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
570 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
571 const objectUrlCounts = await page.evaluate(() => ({
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
572 created: window.__hlsObjectUrls.created.length,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
573 revoked: window.__hlsObjectUrls.revoked.length,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
574 }));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
575 assert.ok(objectUrlCounts.created > 10, JSON.stringify(objectUrlCounts));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
576 assert.ok(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
577 objectUrlCounts.revoked >= objectUrlCounts.created,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
578 JSON.stringify(objectUrlCounts),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
579 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
580
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
581 await page.route('**/invalid.m3u8', route => route.fulfill({
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
582 status: 404,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
583 body: 'not found',
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
584 }));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
585 testingExpectedFailure = true;
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
586 await page.locator('#hlsUrl').fill(`${baseUrl}/invalid.m3u8`);
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
587 await page.getByRole('button', { name: 'Load', exact: true }).click();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
588 await page.locator('#hlsStatus[data-state="error"]').waitFor();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
589 assert.match(
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
590 await page.locator('#hlsStatus').textContent(),
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
591 /404|manifestLoadError|Playlist request failed/,
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
592 );
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
593
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
594 if (errors.length) throw new Error(errors.join('\n'));
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
595 await page.close();
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
596 }
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
597
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
598 function findFreePort() {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
599 return new Promise((resolve, reject) => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
600 const socket = net.createServer();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
601 socket.once('error', reject);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
602 socket.listen(0, '127.0.0.1', () => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
603 const address = socket.address();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
604 socket.close(error => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
605 if (error) reject(error);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
606 else resolve(String(address.port));
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
607 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
608 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
609 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
610 }
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
611
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
612 (async () => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
613 assert.ok(RUNFILES);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
614 assert.ok(WORKSPACE);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
615 const runfilesWorkspace = path.join(RUNFILES, WORKSPACE);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
616 const serverBinary = path.join(
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
617 runfilesWorkspace,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
618 'mrjunejune/mrjunejune_server',
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
619 );
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
620 const siteRoot = path.join(runfilesWorkspace, 'mrjunejune/src');
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
621 const chromiumPath = path.resolve(process.env.CHROMIUM_PATH);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
622 const serverLogs = [];
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
623 let server;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
624 let browser;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
625
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
626 try {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
627 port = await findFreePort();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
628 baseUrl = `http://127.0.0.1:${port}`;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
629 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
630 assert.deepEqual(pngFiles, [], `PNG files leaked into runfiles: ${pngFiles}`);
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
631 for (const file of listFiles(siteRoot).filter(file =>
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
632 file.endsWith('.html')
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
633 )) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
634 const source = fs.readFileSync(file, 'utf8');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
635 for (const primitive of source.matchAll(/<zen-button\b([^>]*)>/g)) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
636 assert.match(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
637 primitive[1],
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
638 /\bsize=["'](?:xs|sm|md|lg|xl)["']/,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
639 `${path.relative(siteRoot, file)} has an unsized zen-button`,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
640 );
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
641 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
642 assert.deepEqual(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
643 primitiveOwnershipViolations(source),
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
644 [],
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
645 `${path.relative(siteRoot, file)} violates primitive ownership`,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
646 );
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
647 }
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
648 for (const file of listFiles(siteRoot).filter(file =>
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
649 /\.(?:css|html|js)$/.test(file) &&
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
650 !file.includes(`${path.sep}public${path.sep}design-system${path.sep}`)
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
651 )) {
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
652 const source = fs.readFileSync(file, 'utf8');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
653 assert.doesNotMatch(
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
654 source,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
655 /var\(\s*--zen-/,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
656 `${path.relative(siteRoot, file)} consumes a deprecated token`,
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
657 );
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
658 }
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
659
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
660 server = spawn(serverBinary, [], {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
661 cwd: runfilesWorkspace,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
662 env: { ...process.env, MRJUNEJUNE_PORT: port },
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
663 stdio: ['ignore', 'pipe', 'pipe'],
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
664 });
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
665 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
666 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
667 await waitForServer(server, serverLogs);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
668
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
669 const home = await (await fetch(baseUrl)).text();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
670 const dogGame = await (
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
671 await fetch(`${baseUrl}/public/dog-game.js`)
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
672 ).text();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
673 const manifest = await (
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
674 await fetch(`${baseUrl}/public/manifest.json`)
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
675 ).text();
242
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
676 const serviceWorker = await (
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
677 await fetch(`${baseUrl}/sw.js`)
242
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
678 ).text();
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
679 for (const source of [home, dogGame, manifest]) {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
680 assert.doesNotMatch(source, /\.png(?:["')]|$)/i);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
681 }
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
682 assert.match(serviceWorker, /v6-zenbu-headless/);
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
683 assert.match(
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
684 await (
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
685 await fetch(`${baseUrl}/public/pwa-register.js`)
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
686 ).text(),
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
687 /register\('\/sw\.js', \{ scope: '\/' \}\)/,
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
688 );
242
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
689 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
690
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
691 for (const asset of [
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
692 'sprite_shiba0.webp',
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
693 'dog-treat.webp',
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
694 'start-large.webp',
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
695 'icon-192.webp',
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
696 'vscode.webp',
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
697 ]) {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
698 const response = await fetch(`${baseUrl}/public/${asset}`);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
699 assert.equal(response.status, 200, asset);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
700 assert.ok((await response.arrayBuffer()).byteLength > 0, asset);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
701 }
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
702
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
703 browser = await chromium.launch({
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
704 executablePath: chromiumPath,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
705 headless: true,
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
706 args: ['--no-sandbox'],
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
707 });
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
708 const paper = await sampleTheme(browser, 'paper');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
709 const ink = await sampleTheme(browser, 'ink');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
710 const playful = await sampleTheme(browser, 'playful');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
711 const automatic = await sampleTheme(browser, 'auto');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
712 assert.equal(paper.rootTheme, 'paper');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
713 assert.equal(ink.rootTheme, 'ink');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
714 assert.equal(playful.rootTheme, 'playful');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
715 assert.equal(automatic.rootTheme, 'auto');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
716 assert.equal(paper.themeLabel, 'Paper');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
717 assert.equal(ink.themeLabel, 'Ink');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
718 assert.equal(playful.themeLabel, 'Playful');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
719 assert.equal(automatic.themeLabel, 'Auto');
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
720 for (const sample of [paper, ink, playful, automatic]) {
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
721 assert.ok(sample.count > 0);
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
722 assert.equal(sample.backgroundRepeat, 'no-repeat');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
723 assert.equal(sample.backgroundSize, 'cover');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
724 assert.equal(sample.bodyCoversViewport, true);
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
725 assert.equal(sample.componentReady, true);
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
726 assert.ok(sample.links > 0);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
727 assert.equal(sample.enhancedLinks, sample.pawLinks);
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
728 assert.match(sample.fontFamily, /More/);
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
729 assert.equal(sample.headerPaws, 0);
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
730 assert.ok(sample.textContrast >= 4.5, JSON.stringify(sample));
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
731 assert.equal(sample.mainBackground, 'rgba(0, 0, 0, 0)');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
732 assert.equal(sample.themeButtonBackground, 'rgba(0, 0, 0, 0)');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
733 assert.equal(sample.themeButtonBorder, '0px');
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
734 assert.equal(sample.themeButtonShadow, 'none');
256
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
735 }
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
736 assert.ok(paper.luminance < 175, JSON.stringify(paper));
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
737 assert.ok(playful.luminance < 175, JSON.stringify(playful));
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
738 assert.ok(ink.luminance > 200, JSON.stringify(ink));
30c2196d03d4 [site] Integrate Zenbu themes and components
MrJuneJune <me@mrjunejune.com>
parents: 242
diff changeset
739 await testThemeCycle(browser);
258
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
740 await testPlainField(browser);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
741 await testButtonScale(browser);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
742 await testDynamicButtonOwnership(browser);
60a876c4587a [ui] Add semantic primitive ownership
MrJuneJune <me@mrjunejune.com>
parents: 256
diff changeset
743 await testResumePrint(browser);
242
543df0fe7168 [tools] Add full HLS player support
MrJuneJune <me@mrjunejune.com>
parents: 241
diff changeset
744 await testHlsPlayer(browser, siteRoot);
241
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
745 } finally {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
746 if (browser) await browser.close();
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
747 await stopProcess(server);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
748 }
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
749 })().catch(error => {
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
750 console.error(error.stack || error);
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
751 process.exitCode = 1;
9c2eec61a152 [assets] Generate site images as WebP with Bazel
MrJuneJune <me@mrjunejune.com>
parents:
diff changeset
752 });