Files
Investidor-V2/tools/territory-browser.mjs
T
nala 1106509116
tests / ci (push) Canceled after 0s
vrsao 2
2026-10-08 14:02:01 +02:00

129 lines
4.7 KiB
JavaScript

// Synthetic QA server only; never writes to the application database.
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 === '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 result = await send('Runtime.evaluate', {
expression,
returnByValue: true,
awaitPromise: true,
});
if (result.exceptionDetails)
throw Error(JSON.stringify(result.exceptionDetails));
return result.result?.value;
};
const wait = async (expression) => {
for (let n = 0; n < 100; n++) {
if (await evaluate(expression)) return;
await new Promise((resolve) => setTimeout(resolve, 100));
}
throw Error('Timed out: ' + expression);
};
const select = async (index, value) =>
evaluate(
`(()=>{const element=document.querySelectorAll('select')[${index}];Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype,'value').set.call(element,${JSON.stringify(value)});element.dispatchEvent(new Event('change',{bubbles:true}));})()`,
);
try {
await send('Runtime.enable');
await send('Page.enable');
await send('Page.navigate', { url: 'http://127.0.0.1:18027/login' });
await wait(
`document.readyState==='complete' && (location.pathname!='/login' || !!document.querySelector('input[type="password"]'))`,
);
if (await evaluate(`location.pathname==='/login'`)) {
for (const [selector, text] of [
['input[type="email"]', 'mne-browser@example.test'],
['input[type="password"]', 'SyntheticMneOnly-2026!'],
]) {
await evaluate(
`document.querySelector(${JSON.stringify(selector)}).focus()`,
);
await send('Input.insertText', { text });
}
await evaluate(
`document.querySelector('button[type="submit"]').click()`,
);
await wait(`!location.pathname.startsWith('/login')`);
}
await send('Page.navigate', {
url: 'http://127.0.0.1:18027/management/territory-associations',
});
await wait(`document.querySelectorAll('select').length===2`);
await select(0, 'clusters');
await wait(`document.querySelectorAll('select')[1].options.length>1`);
await select(1, '20000000-0000-4000-8000-000000000001');
await wait(`document.querySelectorAll('select').length===6`);
for (let level = 0; level < 4; level++) {
await wait(
`!document.querySelectorAll('select')[${level + 2}].disabled && document.querySelectorAll('select')[${level + 2}].options.length>1`,
);
await select(
level + 2,
`10000000-0000-4000-8000-${String(level + 2).padStart(12, '0')}`,
);
}
await evaluate(
`[...document.querySelectorAll('button')].find(b=>b.textContent==='Guardar localização').click()`,
);
await wait(
`document.body.innerText.includes('Localização associada e guardada.')`,
);
await select(2, '');
await wait(
`[...document.querySelectorAll('section[aria-label="Localização do investimento"] select')].slice(1).every(s=>s.value===''&&s.disabled)`,
);
const widths = [];
for (const width of [390, 1440]) {
await send('Emulation.setDeviceMetricsOverride', {
width,
height: 900,
deviceScaleFactor: 1,
mobile: width < 600,
});
widths.push({
width,
noOverflow: await evaluate(
'document.documentElement.scrollWidth<=innerWidth+1',
),
});
}
if (errors.length || widths.some((w) => !w.noOverflow))
throw Error('Browser validation failed');
console.log(
JSON.stringify({
cascade: true,
save: true,
reset_descendants: true,
widths,
javascript_errors: errors.length,
}),
);
} finally {
ws.close();
await fetch(`http://127.0.0.1:9224/json/close/${target.id}`);
}