// 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}`); }