cobalt-transformer-twin / web /scripts /verify-browser.mjs
SNAPKITTYWEST's picture
Add covenant SPDX headers to every remaining unmarked source file
e1aec32 verified
Raw History Blame Contribute Delete
4.31 kB
// SPDX-License-Identifier: LicenseRef-Sovereign-Leviathan-SL-AGPL3-001
// Licensing: see LICENSE in the repository root.
import { chromium } from '@playwright/test';
import assert from 'node:assert/strict';
import { startServer } from './serve.mjs';
const server = await startServer(0, '/playground/');
const browser = await chromium.launch({headless: true});
const url = 'http://127.0.0.1:' + server.address().port + '/playground/?debug=1';
async function loaded(page) {
await page.goto(url);
await page.waitForFunction(() => document.querySelector('#source').value.includes('HELLO'));
}
try {
const page = await browser.newPage();
await loaded(page);
await page.locator('#run').click();
await page.waitForFunction(() => document.querySelector('#history-count').textContent === '(1)');
assert.match(await page.locator('#status').innerText(), /ast: ok/);
await page.locator('#source').press('Control+Enter');
await page.waitForFunction(() => document.querySelector('#history-count').textContent === '(2)');
console.log('PASS button and keyboard execute on a subpath');
await page.close();
for (const asset of ['**/*.wasm', '**/pkg/cobol_transformer_wasm.js']) {
const page = await browser.newPage();
await page.route(asset, route => route.abort());
await page.goto(url);
await page.waitForFunction(() => document.querySelector('#wasm-status').textContent.includes('failed'));
await page.locator('#run').click();
assert.equal(await page.locator('#run-label').innerText(), 'Execute');
assert.match(await page.locator('#status').innerText(), /Cannot execute/);
console.log('PASS failed asset does not queue forever: ' + asset);
await page.close();
}
const missing = await browser.newPage();
await loaded(missing);
const original = await missing.locator('#source').inputValue();
await missing.route('**/samples/vector-add.cbl', route => route.fulfill({status:404,body:'not found'}));
await missing.locator('#sample-select').selectOption('vector-add');
await missing.waitForFunction(() => document.querySelector('#sample-note').textContent.includes('HTTP 404'));
assert.equal(await missing.locator('#source').inputValue(), original);
console.log('PASS sample HTTP failure preserves source');
await missing.close();
const delayed = await browser.newPage();
let release, started;
const startedPromise = new Promise(resolve => {started = resolve;});
const gate = new Promise(resolve => {release = resolve;});
await delayed.route('**/*.wasm', async route => {started(); await gate; await route.continue();});
await delayed.goto(url, {waitUntil:'domcontentloaded'});
await startedPromise;
await delayed.locator('#source').fill(original.replaceAll('HELLO','USERCODE'));
await delayed.locator('#run').click();
assert.match(await delayed.locator('#run-label').innerText(), /^Queued/);
release();
await delayed.waitForFunction(() => document.querySelector('#history-count').textContent === '(1)');
assert.match(await delayed.locator('#source').inputValue(), /USERCODE/);
assert.match(await delayed.locator('#status').innerText(), /program USERCODE/);
console.log('PASS queued startup run preserves typed source');
await delayed.close();
const racing = await browser.newPage();
await loaded(racing);
let releaseSample, sampleStarted;
const sampleStartedPromise = new Promise(resolve => {sampleStarted = resolve;});
const sampleGate = new Promise(resolve => {releaseSample = resolve;});
await racing.route('**/samples/ledger-post.cbl', async route => {sampleStarted(); await sampleGate; await route.continue();});
await racing.locator('#sample-select').selectOption('ledger-post');
await sampleStartedPromise;
await racing.locator('#sample-select').selectOption('hello');
await racing.waitForFunction(() => document.querySelector('#debug-log').textContent.includes('run-end'));
releaseSample();
await racing.waitForFunction(() => document.querySelector('#debug-log').textContent.includes('sample-discarded'));
assert.match(await racing.locator('#source').inputValue(), /PROGRAM-ID. HELLO/);
console.log('PASS stale sample download cannot replace newer selection');
await racing.close();
} finally {
await browser.close();
await new Promise(resolve => server.close(resolve));
}