37 lines
4.3 KiB
JavaScript
37 lines
4.3 KiB
JavaScript
// Read-only checks against the local public portal and real reference names.
|
|
const base = 'http://127.0.0.1:8000';
|
|
const provinces = await (await fetch(`${base}/api/v1/investment/territory-options?type=province`)).json();
|
|
if (provinces.data.length !== 11 || provinces.data.some(p => /^\d+$/.test(p.name))) throw Error('Province designations invalid');
|
|
const province = provinces.data.find(p => p.name === 'Zambezia');
|
|
if (!province) throw Error('Expected source designation missing');
|
|
const result = await (await fetch(`${base}/api/v1/investment/search?province_id=${province.id}`)).json();
|
|
if (result.total < 1) throw Error('Existing opportunities not linked to province');
|
|
const target = await (await fetch('http://127.0.0.1:9224/json/new?about:blank', { method: 'PUT' })).json();
|
|
const ws = new WebSocket(target.webSocketDebuggerUrl);
|
|
await new Promise(resolve => ws.addEventListener('open', resolve, { once: true }));
|
|
let sequence = 0;
|
|
const pending = new Map();
|
|
const errors = [];
|
|
ws.onmessage = event => { const message = JSON.parse(event.data); if (message.method === 'Network.requestWillBeSent' && message.params.request.url.includes('/oportunidades?')) console.log(message.params.request.url); if (message.method === 'Runtime.exceptionThrown') errors.push(message.params.exceptionDetails.text); if (message.id) { const callback = pending.get(message.id); pending.delete(message.id); message.error ? callback.reject(message.error) : callback.resolve(message.result); } };
|
|
const send = (method, params = {}) => new Promise((resolve, reject) => { const id = ++sequence; pending.set(id, { resolve, reject }); ws.send(JSON.stringify({ id, method, params })); });
|
|
const evaluate = async expression => { const response = await send('Runtime.evaluate', { expression, returnByValue: true, awaitPromise: true }); if (response.exceptionDetails) throw Error(JSON.stringify(response.exceptionDetails)); return response.result?.value; };
|
|
const wait = async expression => { for (let i = 0; i < 100; i++) { if (await evaluate(expression)) return; await new Promise(resolve => setTimeout(resolve, 150)); } throw Error('Timed out: '+expression); };
|
|
const element = label => `document.getElementById([...document.querySelectorAll('label')].find(l=>l.textContent===${JSON.stringify(label)})?.htmlFor)`;
|
|
try {
|
|
await send('Runtime.enable'); await send('Page.enable'); await send('Network.enable');
|
|
await send('Page.navigate', { url: `${base}/oportunidades` });
|
|
await wait(`${element('Província')}?.options.length===12`);
|
|
await evaluate(`(()=>{const e=${element('Província')};Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,'value').set.call(e,${JSON.stringify(province.id)});e.dispatchEvent(new Event('change',{bubbles:true}));})()`);
|
|
await wait(`${element('Distrito')}?.options.length>1`);
|
|
const districtNames = await evaluate(`[...${element('Distrito')}.options].slice(1).map(o=>o.textContent)`);
|
|
if (districtNames.some(n => /^\d+$/.test(n))) throw Error('District designations invalid');
|
|
await evaluate(`[...document.querySelectorAll('button')].find(b=>b.textContent.trim()==='Aplicar filtros').click()`);
|
|
await wait(`location.search.includes('province_id=') && ${element('Província')}?.value===${JSON.stringify(province.id)}`);
|
|
await send('Page.reload');
|
|
await wait(`${element('Província')}?.value===${JSON.stringify(province.id)} && ${element('Distrito')}?.options.length>1`);
|
|
const layouts = [];
|
|
for (const width of [390, 1440]) { await send('Emulation.setDeviceMetricsOverride', { width, height: 900, deviceScaleFactor: 1, mobile: width < 600 }); layouts.push({ width, noOverflow: await evaluate('document.documentElement.scrollWidth<=innerWidth+1') }); }
|
|
if (errors.length || layouts.some(l=>!l.noOverflow)) throw Error('Browser check failed');
|
|
console.log(JSON.stringify({ named_provinces: 11, named_district_options: districtNames.length, matching_opportunities: result.total, persisted_url_filter: true, layouts, javascript_errors: errors.length }));
|
|
} catch (error) { console.log(JSON.stringify(await evaluate(`({url:location.href,alerts:[...document.querySelectorAll('[role="alert"]')].map(e=>e.textContent),selected:[...document.querySelectorAll('select')].map(e=>e.value)})`))); throw error; } finally { ws.close(); await fetch(`http://127.0.0.1:9224/json/close/${target.id}`); }
|