182 lines
7.1 KiB
JavaScript
182 lines
7.1 KiB
JavaScript
const {
|
|
chromium,
|
|
} = require('C:/Users/macbook/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright');
|
|
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const base = 'http://127.0.0.1:18092';
|
|
const dir = 'storage/app/private/investmoz-v2';
|
|
void (async () => {
|
|
const browser = await chromium.launch({
|
|
headless: true,
|
|
executablePath:
|
|
'C:/Users/macbook/AppData/Local/ms-playwright/chromium-1243/chrome-win64/chrome.exe',
|
|
});
|
|
const errors = [];
|
|
async function login(role) {
|
|
const context = await browser.newContext({
|
|
viewport: { width: 1440, height: 1000 },
|
|
});
|
|
await context.route('**/*', (r) =>
|
|
r.request().url().startsWith(base) ? r.continue() : r.abort(),
|
|
);
|
|
const page = await context.newPage();
|
|
page.on('pageerror', (e) => errors.push(e.message));
|
|
const response = await page.goto(base + '/login');
|
|
assert.equal(
|
|
response.headers()['x-investmoz-qa-target'],
|
|
'investmoz_v2_20261008_test:55441',
|
|
);
|
|
await page
|
|
.locator('input[type=email]')
|
|
.fill(`guidance-qa-${role}@example.invalid`);
|
|
await page.locator('input[type=password]').fill('QA-Guidance-2026!');
|
|
await page.locator('button[type=submit]').click();
|
|
await page.waitForURL((url) => !url.pathname.startsWith('/login'));
|
|
return page;
|
|
}
|
|
try {
|
|
const owner = await login('investor');
|
|
const manager = await login('manager');
|
|
const id = await owner.evaluate(async () => {
|
|
const token = decodeURIComponent(
|
|
document.cookie
|
|
.split('; ')
|
|
.find((c) => c.startsWith('XSRF-TOKEN='))
|
|
.slice(11),
|
|
);
|
|
const response = await fetch('/balcao-virtual/dossiers', {
|
|
method: 'POST',
|
|
headers: {
|
|
Accept: 'application/json',
|
|
'Content-Type': 'application/json',
|
|
'X-XSRF-TOKEN': token,
|
|
},
|
|
body: JSON.stringify({
|
|
title: 'Segunda entrega sintética QA',
|
|
reuse_consent: true,
|
|
client_key: crypto.randomUUID(),
|
|
}),
|
|
});
|
|
if (response.status !== 201) throw new Error('QA creation failed');
|
|
return (await response.json()).id;
|
|
});
|
|
await owner.goto(`${base}/balcao-virtual/dossiers/${id}`);
|
|
await owner
|
|
.getByText('Corrigir pressupostos ou registar uma alternativa', {
|
|
exact: true,
|
|
})
|
|
.click();
|
|
for (const [label, value] of Object.entries({
|
|
'Procura declarada (quantidade, não previsão)': '100',
|
|
'Capacidade declarada na mesma unidade e período': '50',
|
|
'Unidade comum da procura e capacidade': 'toneladas',
|
|
'Período comum da procura e capacidade': 'ano',
|
|
'Financiamento necessário declarado': '100.50',
|
|
'Financiamento comprometido declarado': '100.49',
|
|
'Moeda comum do financiamento': 'MZN',
|
|
})) {
|
|
await owner.getByLabel(label, { exact: true }).fill(value);
|
|
}
|
|
const [saved] = await Promise.all([
|
|
owner.waitForResponse(
|
|
(response) =>
|
|
response.url().endsWith('/pressupostos') &&
|
|
response.request().method() === 'POST',
|
|
),
|
|
owner
|
|
.getByRole('button', {
|
|
name: 'Guardar pressupostos corrigidos',
|
|
exact: true,
|
|
})
|
|
.click(),
|
|
]);
|
|
assert.ok(saved.status() < 400);
|
|
await owner.waitForLoadState('networkidle');
|
|
await owner.goto(`${base}/balcao-virtual/dossiers/${id}?phase=market`);
|
|
await owner
|
|
.getByText('A procura declarada excede a capacidade declarada', {
|
|
exact: false,
|
|
})
|
|
.waitFor();
|
|
await owner.goto(`${base}/balcao-virtual/dossiers/${id}?phase=finance`);
|
|
await owner
|
|
.getByText('O financiamento comprometido declarado é inferior', {
|
|
exact: false,
|
|
})
|
|
.waitFor();
|
|
await manager.goto(`${base}/balcao-virtual/dossiers/${id}`);
|
|
const review = manager.locator('form').filter({
|
|
has: manager.getByRole('button', {
|
|
name: 'Registar a minha conferência da ligação',
|
|
exact: true,
|
|
}),
|
|
});
|
|
await review
|
|
.getByLabel('Evidência e data da consulta')
|
|
.fill(
|
|
'Consulta sintética QA: endereço indisponível; nenhum pedido externo efetuado.',
|
|
);
|
|
await review
|
|
.getByLabel('Contacto alternativo com fonte')
|
|
.fill('Pedido de apoio interno; fonte fixture QA');
|
|
await review
|
|
.getByRole('button', {
|
|
name: 'Registar a minha conferência da ligação',
|
|
})
|
|
.click();
|
|
await manager.waitForLoadState('networkidle');
|
|
await owner.goto(`${base}/balcao-virtual/dossiers/${id}`);
|
|
await owner
|
|
.getByText('Pedido de apoio interno; fonte fixture QA', {
|
|
exact: false,
|
|
})
|
|
.waitFor();
|
|
await owner
|
|
.getByRole('link', {
|
|
name: 'Ligação indisponível: continuar internamente',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner.waitForLoadState('networkidle');
|
|
assert.ok(owner.url().includes('/dossiers/' + id));
|
|
await manager.goto(base + '/management/balcao-install');
|
|
await manager
|
|
.getByRole('heading', {
|
|
name: 'Instalação autenticada do Balcão e acompanhamento',
|
|
})
|
|
.waitFor();
|
|
await manager
|
|
.getByText('Destino: investmoz_v2_20261008_test', { exact: false })
|
|
.waitFor();
|
|
await manager
|
|
.getByText('Indisponível (scanner_unavailable)', { exact: false })
|
|
.waitFor();
|
|
await manager.screenshot({
|
|
path: dir + '/second-install-qa.png',
|
|
fullPage: true,
|
|
});
|
|
assert.deepEqual(errors, []);
|
|
const proof = {
|
|
passed: true,
|
|
database: 'investmoz_v2_20261008_test',
|
|
port: 55441,
|
|
errors,
|
|
checks: [
|
|
'Assumptions saved through UI; comparable declared gaps explained.',
|
|
'Human link review, fallback contact and internal continuation through UI.',
|
|
'Authenticated installation page shows actual QA target and unavailable ClamD; no active installation.',
|
|
],
|
|
};
|
|
fs.writeFileSync(
|
|
dir + '/second-browser-evidence.json',
|
|
JSON.stringify(proof, null, 2),
|
|
);
|
|
console.log(JSON.stringify(proof));
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
})().catch((error) => {
|
|
console.error(error);
|
|
process.exitCode = 1;
|
|
});
|