mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-15 15:52:21 +00:00
Each script launches and closes Chrome through scripts/qa/browser.mjs, waits on the application through scripts/qa/ready.mjs instead of the loading screen and fixed pauses, and reads the contract instead of Cesium where the check is not about Cesium itself.
146 lines
4.9 KiB
JavaScript
146 lines
4.9 KiB
JavaScript
#!/usr/bin/env node
|
|
import { whenSettled } from './qa/ready.mjs';
|
|
import { launchBrowser, closeBrowser } from './qa/browser.mjs';
|
|
/** Browser proof of Layers panel replacement and subscription ownership. */
|
|
const browser = await launchBrowser({
|
|
headless: true,
|
|
args: [
|
|
'--no-sandbox',
|
|
...(process.platform === 'darwin' ? ['--enable-gpu'] : []),
|
|
],
|
|
});
|
|
const page = await browser.newPage();
|
|
let failures = 0;
|
|
const errors = [];
|
|
page.on('pageerror', (error) => errors.push(error.message));
|
|
const check = (name, passed) => {
|
|
console.log(`[${passed ? 'PASS' : 'FAIL'}] ${name}`);
|
|
if (!passed) failures++;
|
|
};
|
|
try {
|
|
await page.goto(
|
|
`${process.env.QA_BASE_URL || 'http://localhost:4173'}/?welcome=0`,
|
|
{ waitUntil: 'domcontentloaded' },
|
|
);
|
|
await page.waitForFunction(() => window.__godsEyeView?.dataManager, {
|
|
timeout: 60000,
|
|
});
|
|
await whenSettled(page);
|
|
const results = await page.evaluate(async () => {
|
|
const manager = window.__godsEyeView.dataManager;
|
|
const entry = document.querySelector(
|
|
'script[type="module"][src*="/src/main.js"]',
|
|
);
|
|
const { application } = await import(entry.src);
|
|
const { presentation } = application.getComponents().data;
|
|
const container = presentation.panel._toggleContainer;
|
|
const id = 'qa-panel-lifecycle';
|
|
let listener = null;
|
|
let enabled = 0;
|
|
window.__gevQaRegisterLayer(manager, {
|
|
id,
|
|
name: '<b>Literal layer</b>',
|
|
icon: '◌',
|
|
source: 'Local fixture',
|
|
updateInterval: -1,
|
|
init() {},
|
|
enable() {
|
|
enabled++;
|
|
},
|
|
disable() {},
|
|
update() {},
|
|
destroy() {},
|
|
getStats: () => ({ count: 1250, lastUpdate: Date.now(), stale: true }),
|
|
getRowControls: () => ({ chips: [] }),
|
|
setRowControlsListener: (callback) => {
|
|
listener = callback;
|
|
},
|
|
});
|
|
const result = [];
|
|
try {
|
|
presentation.mount(container);
|
|
const row = () => container.querySelector(`[data-layer-id="${id}"]`);
|
|
const first = row().querySelector('.data-toggle-btn');
|
|
result.push([
|
|
'descriptor text is literal content',
|
|
row().querySelector('.data-name').textContent ===
|
|
'<b>Literal layer</b>' && !row().querySelector('b'),
|
|
]);
|
|
result.push([
|
|
'row subscription is installed',
|
|
typeof listener === 'function',
|
|
]);
|
|
presentation.mount(container);
|
|
first.click();
|
|
await Promise.resolve();
|
|
result.push([
|
|
'a detached row cannot issue an enable action',
|
|
enabled === 0 && !manager.isEnabled(id),
|
|
]);
|
|
await manager.setEnabled(id, true);
|
|
result.push([
|
|
'count is presented from the supplied snapshot',
|
|
row().querySelector('.data-count').textContent === '1.3K',
|
|
]);
|
|
result.push([
|
|
'feed state reflects the settled layer snapshot',
|
|
row().querySelector('.data-toggle-btn').dataset.feedState === 'stale',
|
|
]);
|
|
const ui = window.__godsEyeView.styleManager;
|
|
const clearButton = document.getElementById('clear-selected-layers');
|
|
clearButton.click();
|
|
// The bar renders the busy state on Vue's next flush.
|
|
await Promise.resolve();
|
|
result.push([
|
|
'native clear activation presents busy state',
|
|
clearButton.getAttribute('aria-busy') === 'true' &&
|
|
!!ui._contextControls._clearSelectedLayersPromise,
|
|
]);
|
|
await ui._contextControls._clearSelectedLayersPromise;
|
|
await Promise.resolve();
|
|
result.push([
|
|
'clear settles through the existing layer transaction',
|
|
!manager.isEnabled(id) &&
|
|
clearButton.getAttribute('aria-busy') === 'false',
|
|
]);
|
|
await manager.setEnabled(id, true);
|
|
const final = row().querySelector('.data-toggle-btn');
|
|
presentation._panel.destroy();
|
|
final.click();
|
|
await Promise.resolve();
|
|
result.push([
|
|
'destroyed panel releases row subscriptions',
|
|
listener === null,
|
|
]);
|
|
result.push([
|
|
'destroyed controls cannot change the layer',
|
|
manager.isEnabled(id),
|
|
]);
|
|
} finally {
|
|
presentation._panel?.destroy();
|
|
presentation._panel = null;
|
|
await window.__gevQaUnregisterLayer(manager, id);
|
|
presentation.mount(container);
|
|
}
|
|
result.push([
|
|
'ordinary layer rows return after reassembly',
|
|
container.querySelectorAll('.data-toggle-row').length > 10,
|
|
]);
|
|
result.push([
|
|
'Directions returns to the Utilities list after reassembly',
|
|
Boolean(
|
|
document.querySelector(
|
|
'#utilities-toggles [data-layer-id="directions"]',
|
|
) && !container.querySelector('[data-layer-id="directions"]'),
|
|
),
|
|
]);
|
|
return result;
|
|
});
|
|
for (const [name, passed] of results) check(name, passed);
|
|
check('no uncaught browser errors', errors.length === 0);
|
|
} finally {
|
|
await closeBrowser(browser);
|
|
}
|
|
console.log(`RESULT: ${failures} failures`);
|
|
process.exitCode = failures ? 1 : 0;
|