134 lines
4.9 KiB
JavaScript
134 lines
4.9 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);
|
|
if (message.error) callback.reject(message.error);
|
|
else 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}`);
|
|
}
|