Mercurial
comparison mrjunejune/test/theme_and_webp_test.js @ 256:30c2196d03d4
[site] Integrate Zenbu themes and components
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Tue, 04 Aug 2026 16:49:01 -0700 |
| parents | 543df0fe7168 |
| children | 60a876c4587a |
comparison
equal
deleted
inserted
replaced
| 255:5ec271d612ae | 256:30c2196d03d4 |
|---|---|
| 108 luminance += | 108 luminance += |
| 109 data[index] * 0.2126 + | 109 data[index] * 0.2126 + |
| 110 data[index + 1] * 0.7152 + | 110 data[index + 1] * 0.7152 + |
| 111 data[index + 2] * 0.0722; | 111 data[index + 2] * 0.0722; |
| 112 } | 112 } |
| 113 const channels = value => value.match(/\d+(?:\.\d+)?/g) | |
| 114 .slice(0, 3) | |
| 115 .map(Number); | |
| 116 const colorLuminance = value => { | |
| 117 const converted = channels(value).map(channel => { | |
| 118 const normalized = channel / 255; | |
| 119 return normalized <= 0.04045 | |
| 120 ? normalized / 12.92 | |
| 121 : ((normalized + 0.055) / 1.055) ** 2.4; | |
| 122 }); | |
| 123 return converted[0] * 0.2126 + | |
| 124 converted[1] * 0.7152 + | |
| 125 converted[2] * 0.0722; | |
| 126 }; | |
| 127 const bodyStyle = getComputedStyle(document.body); | |
| 128 const foreground = colorLuminance(bodyStyle.color); | |
| 129 const background = colorLuminance( | |
| 130 getComputedStyle(document.querySelector('main')).backgroundColor, | |
| 131 ); | |
| 113 return { | 132 return { |
| 133 cardCount: document.querySelectorAll('.site-link-grid zen-card').length, | |
| 134 componentReady: Boolean(customElements.get('zen-card')), | |
| 114 count, | 135 count, |
| 136 fontFamily: getComputedStyle(document.body).fontFamily, | |
| 115 luminance: count ? luminance / count : 0, | 137 luminance: count ? luminance / count : 0, |
| 116 rootClass: document.documentElement.className, | 138 textContrast: (Math.max(foreground, background) + 0.05) / |
| 139 (Math.min(foreground, background) + 0.05), | |
| 140 rootTheme: document.documentElement.dataset.zenTheme || 'auto', | |
| 141 themeLabel: document.querySelector('#themeName')?.textContent, | |
| 117 }; | 142 }; |
| 118 }); | 143 }); |
| 119 | 144 |
| 120 if (errors.length) throw new Error(`${theme}\n${errors.join('\n')}`); | 145 if (errors.length) throw new Error(`${theme}\n${errors.join('\n')}`); |
| 121 await context.close(); | 146 await context.close(); |
| 122 return sample; | 147 return sample; |
| 148 } | |
| 149 | |
| 150 async function testThemeCycle(browser) { | |
| 151 const context = await browser.newContext({ colorScheme: 'light' }); | |
| 152 const page = await context.newPage(); | |
| 153 await page.goto(baseUrl, { waitUntil: 'networkidle' }); | |
| 154 const expected = ['paper', 'ink', 'playful', 'auto']; | |
| 155 for (const theme of expected) { | |
| 156 await page.locator('#themeToggle').click(); | |
| 157 assert.equal( | |
| 158 await page.evaluate(() => | |
| 159 document.documentElement.dataset.zenTheme || 'auto' | |
| 160 ), | |
| 161 theme, | |
| 162 ); | |
| 163 assert.equal( | |
| 164 await page.evaluate(() => localStorage.getItem('theme-preference')), | |
| 165 theme, | |
| 166 ); | |
| 167 } | |
| 168 await context.close(); | |
| 123 } | 169 } |
| 124 | 170 |
| 125 async function testHlsPlayer(browser, siteRoot) { | 171 async function testHlsPlayer(browser, siteRoot) { |
| 126 const page = await browser.newPage(); | 172 const page = await browser.newPage(); |
| 127 const errors = []; | 173 const errors = []; |
| 393 ).text(); | 439 ).text(); |
| 394 const manifest = await ( | 440 const manifest = await ( |
| 395 await fetch(`${baseUrl}/public/manifest.json`) | 441 await fetch(`${baseUrl}/public/manifest.json`) |
| 396 ).text(); | 442 ).text(); |
| 397 const serviceWorker = await ( | 443 const serviceWorker = await ( |
| 398 await fetch(`${baseUrl}/public/sw.js`) | 444 await fetch(`${baseUrl}/sw.js`) |
| 399 ).text(); | 445 ).text(); |
| 400 for (const source of [home, dogGame, manifest]) { | 446 for (const source of [home, dogGame, manifest]) { |
| 401 assert.doesNotMatch(source, /\.png(?:["')]|$)/i); | 447 assert.doesNotMatch(source, /\.png(?:["')]|$)/i); |
| 402 } | 448 } |
| 403 assert.match(serviceWorker, /v4-hlsjs/); | 449 assert.match(serviceWorker, /v5-zenbu-themes/); |
| 450 assert.match( | |
| 451 await ( | |
| 452 await fetch(`${baseUrl}/public/pwa-register.js`) | |
| 453 ).text(), | |
| 454 /register\('\/sw\.js', \{ scope: '\/' \}\)/, | |
| 455 ); | |
| 404 assert.ok(serviceWorker.includes("startsWith('/tools/hls_player')")); | 456 assert.ok(serviceWorker.includes("startsWith('/tools/hls_player')")); |
| 405 | 457 |
| 406 for (const asset of [ | 458 for (const asset of [ |
| 407 'sprite_shiba0.webp', | 459 'sprite_shiba0.webp', |
| 408 'dog-treat.webp', | 460 'dog-treat.webp', |
| 418 browser = await chromium.launch({ | 470 browser = await chromium.launch({ |
| 419 executablePath: chromiumPath, | 471 executablePath: chromiumPath, |
| 420 headless: true, | 472 headless: true, |
| 421 args: ['--no-sandbox'], | 473 args: ['--no-sandbox'], |
| 422 }); | 474 }); |
| 423 const light = await sampleTheme(browser, 'light'); | 475 const paper = await sampleTheme(browser, 'paper'); |
| 424 const dark = await sampleTheme(browser, 'dark'); | 476 const ink = await sampleTheme(browser, 'ink'); |
| 425 assert.ok(light.count > 0); | 477 const playful = await sampleTheme(browser, 'playful'); |
| 426 assert.ok(dark.count > 0); | 478 const automatic = await sampleTheme(browser, 'auto'); |
| 427 assert.ok(light.luminance < 175, JSON.stringify(light)); | 479 assert.equal(paper.rootTheme, 'paper'); |
| 428 assert.ok(dark.luminance > 200, JSON.stringify(dark)); | 480 assert.equal(ink.rootTheme, 'ink'); |
| 481 assert.equal(playful.rootTheme, 'playful'); | |
| 482 assert.equal(automatic.rootTheme, 'auto'); | |
| 483 assert.equal(paper.themeLabel, 'Paper'); | |
| 484 assert.equal(ink.themeLabel, 'Ink'); | |
| 485 assert.equal(playful.themeLabel, 'Playful'); | |
| 486 assert.equal(automatic.themeLabel, 'Auto'); | |
| 487 for (const sample of [paper, ink, playful, automatic]) { | |
| 488 assert.ok(sample.count > 0); | |
| 489 assert.equal(sample.componentReady, true); | |
| 490 assert.equal(sample.cardCount, 4); | |
| 491 assert.match(sample.fontFamily, /More/); | |
| 492 assert.ok(sample.textContrast >= 4.5, JSON.stringify(sample)); | |
| 493 } | |
| 494 assert.ok(paper.luminance < 175, JSON.stringify(paper)); | |
| 495 assert.ok(playful.luminance < 175, JSON.stringify(playful)); | |
| 496 assert.ok(ink.luminance > 200, JSON.stringify(ink)); | |
| 497 await testThemeCycle(browser); | |
| 429 await testHlsPlayer(browser, siteRoot); | 498 await testHlsPlayer(browser, siteRoot); |
| 430 } finally { | 499 } finally { |
| 431 if (browser) await browser.close(); | 500 if (browser) await browser.close(); |
| 432 await stopProcess(server); | 501 await stopProcess(server); |
| 433 } | 502 } |