4f822e1turing-surface-cache: reaction-diffusion solutions at a chosen end time, shared through a cloud cacheJeremy Magland 1/**
2 * Smoke-check a deployed URL in headless Chrome: load it and wait for the
e53205fShow one parameter across its range, not only at a pointJeremy Magland 3 * boot-time solve to finish — either from the cloud cache or computed locally
4 * — then do the same for the sweep page beside it. Talks to the real cache.
5 * Usage: node scripts/check-live.mjs [url]
4f822e1turing-surface-cache: reaction-diffusion solutions at a chosen end time, shared through a cloud cacheJeremy Magland 6 */
7import puppeteer from 'puppeteer-core';
9const url = process.argv[2] ?? 'https://concept-collection.github.io/turing-surface-cache/';
10const browser = await puppeteer.launch({
11 executablePath: process.env.CHROME_PATH ?? '/usr/bin/google-chrome',
12 args: ['--headless=new', '--no-sandbox', '--enable-unsafe-webgpu',
13 '--use-webgpu-adapter=swiftshader', '--enable-unsafe-swiftshader'],
b0546a9Fix the command line's file writing, and how it gets updatedJeremy Magland 14 // A wait is one CDP call lasting as long as the wait, so the default 180 s
15 // cap on a call is what a slow run trips over first.
16 protocolTimeout: 900_000,
4f822e1turing-surface-cache: reaction-diffusion solutions at a chosen end time, shared through a cloud cacheJeremy Magland 17});
e53205fShow one parameter across its range, not only at a pointJeremy Magland 18const problems = [];
19function watch(page, tag) {
20 page.on('pageerror', (e) => problems.push(`${tag}pageerror: ${e.message}`));
21 page.on('requestfailed', (r) => {
22 // The cache lookup 404s by design when the selection is not cached.
23 if (!r.url().startsWith('https://tempory.net/')) {
24 problems.push(`${tag}request failed: ${r.url()}`);
25 }
26 });
27 page.on('console', (m) => {
28 if (m.type() === 'error' && !/GL Driver|favicon|tempory\.net/.test(m.text())) {
29 problems.push(`${tag}console error: ${m.text()}`);
30 }
31 });
32}
4f822e1turing-surface-cache: reaction-diffusion solutions at a chosen end time, shared through a cloud cacheJeremy Magland 34const page = await browser.newPage();
35await page.setViewport({ width: 1100, height: 900 });
4f822e1turing-surface-cache: reaction-diffusion solutions at a chosen end time, shared through a cloud cacheJeremy Magland 37
38try {
39 await page.goto(url, { waitUntil: 'load', timeout: 60_000 });
40 // Nothing computes without the button, so any selection is safe to idle on.
41 await page.waitForSelector('#tend');
42 // Terminal statuses only — "checking the cloud cache…" is transient. A
43 // miss settles on empty windows asking for the button; nothing computes
44 // during this check.
45 await page.waitForFunction(
46 () => /from the cloud cache|press Compute solution|failed/.test(
47 document.getElementById('status')?.textContent ?? '') ||
48 (document.getElementById('err')?.textContent?.length ?? 0) > 4,
49 { timeout: 600_000 },
50 );
51 console.log('status:', await page.$eval('#status', (el) => el.textContent));
52 const err = await page.$eval('#err', (el) => el.textContent);
53 if (err) problems.push(`err: ${err}`);
54 const panels = await page.$$eval('.sphere-box canvas', (els) => els.length);
55 console.log('sphere canvases:', panels);
56 if (panels !== 2) problems.push(`expected 2 sphere canvases, got ${panels}`);
58 // The sweep page beside it, on the default sweep. Nothing computes here
59 // either: the values that are cached load, the rest stay gaps.
60 const sweepPage = await browser.newPage();
61 await sweepPage.setViewport({ width: 1100, height: 900 });
62 watch(sweepPage, 'sweep: ');
63 await sweepPage.goto(new URL('sweep.html', page.url()).href, {
64 waitUntil: 'load',
65 timeout: 60_000,
66 });
67 await sweepPage.waitForFunction(
68 () => /values (in the cloud cache|loaded)|failed/.test(
69 document.getElementById('status')?.textContent ?? '') ||
70 (document.getElementById('err')?.textContent?.length ?? 0) > 4,
71 { timeout: 600_000 },
72 );
73 console.log('sweep status:', await sweepPage.$eval('#status', (el) => el.textContent));
74 const sweepErr = await sweepPage.$eval('#err', (el) => el.textContent);
75 if (sweepErr) problems.push(`sweep err: ${sweepErr}`);
76 const ticks = await sweepPage.$$eval('.tick', (els) => els.length);
77 const cached = await sweepPage.$$eval('.tick.cached', (els) => els.length);
78 console.log(`sweep ticks: ${cached} of ${ticks} loaded`);
79 if (ticks < 2) problems.push(`sweep: expected a knob with several values, got ${ticks}`);
4f822e1turing-surface-cache: reaction-diffusion solutions at a chosen end time, shared through a cloud cacheJeremy Magland 81 if (problems.length) {
82 console.log('PROBLEMS:');
83 for (const p of new Set(problems)) console.log(' ' + p);
84 process.exitCode = 1;
85 } else {
86 console.log('LIVE CHECK: PASS');
87 }
88} catch (e) {
89 console.error(`LIVE CHECK FAIL: ${e.message}`);
90 for (const p of new Set(problems)) console.error(' ' + p);
91 process.exitCode = 1;
92} finally {
93 await browser.close();
94}