158 lines
6.1 KiB
JavaScript
158 lines
6.1 KiB
JavaScript
import { createRequire } from 'node:module';
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
const require = createRequire(import.meta.url);
|
|
const {
|
|
chromium,
|
|
} = require('C:/Users/macbook/AppData/Local/Temp/investmoz-visual-qa-tools-20261004/node_modules/playwright');
|
|
const base = 'http://127.0.0.1:8000';
|
|
const out = path.resolve('docs/investmoz/pilot');
|
|
fs.mkdirSync(out, { recursive: true });
|
|
const browser = await chromium.launch({ headless: true });
|
|
const page = await browser.newPage({ viewport: { width: 1440, height: 1000 } });
|
|
const errors = [];
|
|
page.on('pageerror', (error) => errors.push(error.message));
|
|
const evidence = {
|
|
base,
|
|
testedAt: new Date().toISOString(),
|
|
pages: [],
|
|
errors,
|
|
};
|
|
async function visit(route, key) {
|
|
const response = await page.goto(base + route, {
|
|
waitUntil: 'networkidle',
|
|
});
|
|
evidence.pages.push({
|
|
key,
|
|
status: response?.status(),
|
|
title: await page.title(),
|
|
bodyTextLength: (await page.locator('body').innerText()).length,
|
|
});
|
|
if (!response?.ok())
|
|
throw new Error(`${route} returned ${response?.status()}`);
|
|
}
|
|
await visit('/oportunidades', 'catalogue');
|
|
evidence.catalogueStatus = await page
|
|
.getByText(/\d+ oportunidades publicadas/)
|
|
.innerText();
|
|
evidence.navigationHasCatalogueGroup =
|
|
(await page.getByText('Catálogos territoriais e económicos').count()) === 1;
|
|
evidence.publishedOpportunityCount = await page.locator('article').count();
|
|
await visit('/carteira?kind=cluster', 'clusters');
|
|
evidence.clusterRecords = await page.locator('article').count();
|
|
for (const [legacy, expected] of [
|
|
['/clusters', '/carteira?kind=cluster'],
|
|
['/corredores', '/carteira?kind=corridor'],
|
|
['/projectos-ancora', '/carteira?kind=project'],
|
|
]) {
|
|
await page.goto(base + legacy, { waitUntil: 'networkidle' });
|
|
evidence[`legacy${legacy.replaceAll('/', '')}Redirect`] =
|
|
new URL(page.url()).pathname + new URL(page.url()).search === expected;
|
|
}
|
|
await visit('/carteira?kind=cluster', 'clusters-again');
|
|
const province = page.getByLabel('Província');
|
|
await province.waitFor({ timeout: 5000 });
|
|
const provinceValue = await province
|
|
.locator('option')
|
|
.nth(1)
|
|
.getAttribute('value');
|
|
if (provinceValue) {
|
|
await province.selectOption(provinceValue);
|
|
await page.getByRole('button', { name: 'Pesquisar' }).click();
|
|
await page.waitForURL((url) => url.searchParams.has('province_id'), {
|
|
timeout: 5000,
|
|
});
|
|
evidence.locationFilterApplied =
|
|
new URL(page.url()).searchParams.get('province_id') === provinceValue;
|
|
evidence.locationFilteredResults = await page.locator('article').count();
|
|
await visit('/carteira?kind=cluster', 'clusters-after-location-filter');
|
|
} else {
|
|
evidence.locationFilterApplied = false;
|
|
}
|
|
if (await page.locator('article a').count()) {
|
|
const prior = page.url();
|
|
const detailHref = await page
|
|
.locator('article a')
|
|
.first()
|
|
.getAttribute('href');
|
|
await page.locator('article a').first().click();
|
|
await page.waitForURL((url) => url.pathname.startsWith('/carteira/'), {
|
|
timeout: 5000,
|
|
});
|
|
await page.waitForLoadState('networkidle');
|
|
evidence.clusterDetailHref = detailHref;
|
|
evidence.clusterDetailUrl = page.url();
|
|
evidence.clusterDetailLoaded =
|
|
page.url() !== prior &&
|
|
!/SQLSTATE|Undefined column|500 Server Error/.test(
|
|
await page.locator('body').innerText(),
|
|
);
|
|
evidence.privateManifestationRequiresAccount =
|
|
(await page
|
|
.getByText(
|
|
/Para associar esta referência a uma manifestação privada, entre na sua conta/i,
|
|
)
|
|
.count()) === 1;
|
|
}
|
|
await visit(
|
|
'/carteira?kind=cluster&q=__sem_resultado_qa__',
|
|
'clusters-no-results',
|
|
);
|
|
evidence.usefulEmptyState =
|
|
(await page.getByText(/Ainda não existem fichas publicadas/).count()) === 1;
|
|
await visit('/carteira?kind=project', 'anchor-projects');
|
|
evidence.anchorDossiers = await page.locator('article').count();
|
|
if (await page.locator('article a').count()) {
|
|
await page.locator('article a').first().click();
|
|
await page.waitForURL((url) => url.pathname.startsWith('/carteira/'), {
|
|
timeout: 5000,
|
|
});
|
|
evidence.anchorReferenceVisible =
|
|
(await page
|
|
.getByRole('heading', { name: 'Referência de projecto âncora' })
|
|
.count()) === 1;
|
|
evidence.anchorDoesNotClaimOpenTender =
|
|
(await page
|
|
.getByText(/(?:não representa|não significa) concurso aberto/i)
|
|
.count()) === 1;
|
|
}
|
|
await visit('/zonas?category=zee', 'zee-catalogue');
|
|
evidence.zoneCountText = await page.getByRole('status').first().innerText();
|
|
await visit('/negocios', 'existing-business-marketplace');
|
|
evidence.businessListingCount = await page.locator('article').count();
|
|
await visit('/como-investir', 'investment-guide-desktop');
|
|
evidence.guideHasBothPaths =
|
|
(await page.getByLabel('Tenho uma ideia').count()) === 1 &&
|
|
(await page.getByLabel('Tenho um projecto definido').count()) === 1;
|
|
await page.getByLabel('Tenho uma ideia').check();
|
|
evidence.ideaPathRenders =
|
|
(await page
|
|
.getByRole('heading', { name: '1. Ideia e problema' })
|
|
.count()) === 1;
|
|
await page.getByLabel('Actividade (opcional)').fill('Panificação');
|
|
evidence.activityContextShown =
|
|
(await page.getByText(/Actividade opcional: Panificação/).count()) === 1;
|
|
await page.setViewportSize({ width: 390, height: 844 });
|
|
await page.reload({ waitUntil: 'networkidle' });
|
|
await page.getByRole('button', { name: 'Abrir menu' }).click();
|
|
evidence.mobileMenuExpanded =
|
|
(await page
|
|
.getByRole('button', { name: 'Fechar menu' })
|
|
.getAttribute('aria-expanded')) === 'true';
|
|
await page.keyboard.press('Tab');
|
|
evidence.keyboardFocusVisible = await page.evaluate(
|
|
() => document.activeElement?.tagName !== 'BODY',
|
|
);
|
|
await page.screenshot({
|
|
path: path.join(out, 'investmoz-guide-mobile-2026-10-04.png'),
|
|
fullPage: true,
|
|
});
|
|
evidence.pageErrors = errors;
|
|
await browser.close();
|
|
fs.writeFileSync(
|
|
path.join(out, 'investmoz-catalogue-guide-browser-2026-10-04.json'),
|
|
JSON.stringify(evidence, null, 2) + '\n',
|
|
);
|
|
console.log(JSON.stringify(evidence, null, 2));
|