Claude Sonnet 5.5
v0.11.0: real wood textures, textures baked into dssl build, CSS counters, calmer contrast lint, and the Heartwood showcase page
08132d7 Download scripts/lib/browser-harness.mjs from EHS-Studio/dssl: direct link, hf CLI and curl.
- Browser
- Download file 3.61 kB
-
https://huggingface.co/EHS-Studio/dssl/resolve/main/scripts/lib/browser-harness.mjs
- Command line
-
hf download hf://EHS-Studio/dssl/scripts/lib/browser-harness.mjs
-
curl -L -o browser-harness.mjs https://huggingface.co/EHS-Studio/dssl/resolve/main/scripts/lib/browser-harness.mjs
3.61 kB
| /* browser-harness.mjs: the one place the browser tests get a page from. | |
| * | |
| * Real behaviour (canvas pixels, SVG-filter textures, ::-webkit-slider-thumb, | |
| * rAF timing) cannot be checked in Node, so these tests drive a real Chrome. | |
| * It uses playwright-core, which ships no browser, and finds one that is | |
| * already installed. Point DSSL_CHROME at a binary if yours is somewhere odd. | |
| * | |
| * import { withBrowser } from './lib/browser-harness.mjs'; | |
| * await withBrowser(async ({ open }) => { const page = await open('/x.html'); ... }); | |
| */ | |
| import { createServer } from 'node:http'; | |
| import { readFileSync, existsSync } from 'node:fs'; | |
| import { extname, join, resolve } from 'node:path'; | |
| import { fileURLToPath } from 'node:url'; | |
| import { chromium } from 'playwright-core'; | |
| export const ROOT = resolve(fileURLToPath(new URL('../..', import.meta.url))); | |
| const MIME = { '.js': 'text/javascript', '.mjs': 'text/javascript', '.html': 'text/html', '.css': 'text/css', '.json': 'application/json', '.dssl': 'text/plain', '.svg': 'image/svg+xml' }; | |
| const CANDIDATES = [ | |
| process.env.DSSL_CHROME, | |
| '/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chromium', '/usr/bin/chromium-browser', | |
| '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', | |
| 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', | |
| ].filter(Boolean); | |
| export function findChrome() { | |
| return CANDIDATES.find((p) => existsSync(p)) || null; | |
| } | |
| /** static server: /dssl/* is public/dssl/*, /styles/* is public/styles/*, /t/* is a scratch dir of test pages */ | |
| export function startServer(pages = {}) { | |
| const server = createServer((req, res) => { | |
| const url = req.url.split('?')[0]; | |
| if (url === '/favicon.ico') { res.writeHead(204); return res.end(); } | |
| if (pages[url]) { res.writeHead(200, { 'content-type': 'text/html' }); return res.end(pages[url]); } | |
| let file; | |
| if (url.startsWith('/dssl/')) file = join(ROOT, 'public', url); | |
| else if (url.startsWith('/styles/') || url.startsWith('/showcase/')) file = join(ROOT, 'public', url); | |
| else file = join(ROOT, url); | |
| try { | |
| const body = readFileSync(file); | |
| res.writeHead(200, { 'content-type': MIME[extname(file)] || 'application/octet-stream', 'access-control-allow-origin': '*' }); | |
| res.end(body); | |
| } catch { res.writeHead(404); res.end('not found'); } | |
| }); | |
| return new Promise((ok) => server.listen(0, '127.0.0.1', () => ok({ server, port: server.address().port }))); | |
| } | |
| export async function withBrowser(fn, { pages = {}, viewport = { width: 1000, height: 700 }, reducedMotion = 'no-preference', colorScheme = 'light', deviceScaleFactor = 1 } = {}) { | |
| const exe = findChrome(); | |
| if (!exe) throw new Error('no Chrome found; set DSSL_CHROME to a Chrome or Chromium binary'); | |
| const { server, port } = await startServer(pages); | |
| const browser = await chromium.launch({ executablePath: exe, headless: true, args: ['--no-sandbox', '--disable-gpu', '--hide-scrollbars'] }); | |
| const context = await browser.newContext({ viewport, reducedMotion, colorScheme, deviceScaleFactor }); | |
| const base = `http://127.0.0.1:${port}`; | |
| const errors = []; | |
| try { | |
| const open = async (path, { wait = 'load' } = {}) => { | |
| const page = await context.newPage(); | |
| page.on('pageerror', (e) => errors.push(String(e))); | |
| page.on('console', (m) => { if (m.type() === 'error') errors.push(m.text()); }); | |
| await page.goto(base + path, { waitUntil: wait }); | |
| return page; | |
| }; | |
| return await fn({ open, base, errors, context, browser }); | |
| } finally { | |
| await browser.close(); | |
| server.close(); | |
| } | |
| } | |