Files
stack/packages/webui/tests/helpers/w15-project-remote.mjs

44 lines
3.6 KiB
JavaScript

import { fixture } from '../fixture.mjs';
import { browser } from '../browser.mjs';
// The conversations slice supplies the real mount point at integration. This fixture
// installs one in the actual Console document and stubs only its network boundary.
export async function remoteFixture(t, width) {
const f = await fixture(); t.after(() => f.close());
const b = await browser({ machine: false }); t.after(() => b.close());
const errors = [], network = [];
b.on('Runtime.exceptionThrown', p => errors.push(p.exceptionDetails?.exception?.description ?? p.exceptionDetails?.text ?? 'exception'));
b.on('Fetch.requestPaused', p => {
if (p.request.url.startsWith(f.base + '/')) b.call('Fetch.continueRequest', { requestId: p.requestId }).catch(() => {});
else { network.push(p.request.url); b.call('Fetch.failRequest', { requestId: p.requestId, errorReason: 'BlockedByClient' }).catch(() => {}); }
});
await b.call('Fetch.enable', { patterns: [{ urlPattern: '*' }] });
await b.call('Page.addScriptToEvaluateOnNewDocument', { source: `(() => {
window.__remote = { project: 'stack', remote: null, revision: '${'a'.repeat(64)}', firstSaveAllowed: true };
window.__writes = []; window.__mode = 'success'; window.__writeEnabled = true;
window.fetch = async (url, options = {}) => {
const path = String(url), method = options.method || 'GET';
const reply = (data, status = 200) => new Response(JSON.stringify(data), { status, headers: { 'content-type': 'application/json' } });
if (path === '/api/config') return reply({ projectRemotes: true, projectRemoteWrites: window.__writeEnabled });
if (path === '/api/project-remotes/stack') {
if (method === 'GET') return reply(window.__remote);
window.__writes.push(JSON.parse(options.body));
if (window.__mode === 'hold') await new Promise(resolve => window.__release = resolve);
if (window.__mode === 'stale') return reply({ error: 'revision-conflict' }, 409);
if (window.__mode === 'unknown') return reply({ error: 'outcome-unknown' }, 503);
if (window.__mode === 'fail') return reply({ error: 'project-remote-invalid' }, 400);
window.__remote = { ...window.__remote, remote: window.__writes.at(-1).remote, revision: '${'b'.repeat(64)}', firstSaveAllowed: false };
return reply(window.__remote);
}
return reply({ error: 'unexpected-api' }, 503);
};
})();` });
await b.viewport(width, 1000);
await b.navigate(f.base + '/#/projects/10000000-0000-4000-8000-000000000001/settings');
await b.evaluate(`new Promise((resolve,reject)=>{const link=document.createElement('link');link.rel='stylesheet';link.href='/project-remote.css';document.head.append(link);const script=document.createElement('script');script.src='/project-remote.js';script.onload=resolve;script.onerror=reject;document.head.append(script)})`);
await b.evaluate(`(()=>{const main=document.querySelector('#main');for(const child of main.children)child.style.display='none';main.hidden=false;const h=document.createElement('h1');h.textContent='Project information';const slot=document.createElement('div');slot.id='remote-fixture';main.append(h,slot);return true})()`);
const mount = async (repositoryKey = 'stack') => b.evaluate(`MosaicProjectRemote.mount({container:document.querySelector('#remote-fixture'),projectId:'10000000-0000-4000-8000-000000000001',repositoryKey:${JSON.stringify(repositoryKey)}}),true`);
const wait = expression => b.evaluate(`(async()=>{const until=Date.now()+10000;while(!(${expression})){if(Date.now()>until)throw Error('timed out');await new Promise(r=>setTimeout(r,20))}return true})()`);
return { b, f, mount, wait, errors, network };
}