318 lines
12 KiB
JavaScript
318 lines
12 KiB
JavaScript
const {
|
|
chromium,
|
|
} = require('C:/Users/macbook/.cache/codex-runtimes/codex-primary-runtime/dependencies/node/node_modules/playwright');
|
|
const fs = require('node:fs');
|
|
const assert = require('node:assert/strict');
|
|
const base = 'http://127.0.0.1:18086';
|
|
const fixture = JSON.parse(
|
|
fs.readFileSync(
|
|
'storage/app/private/anchor-project-reconciliation/qa-browser-fixture.json',
|
|
),
|
|
);
|
|
(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();
|
|
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));
|
|
await page.goto(base + '/login');
|
|
await page
|
|
.locator('input[type=email]')
|
|
.fill(`partnership-qa-${role}@example.invalid`);
|
|
await page.locator('input[type=password]').fill('QA-Partnership-2026!');
|
|
await page.locator('button[type=submit]').click();
|
|
await page.waitForURL((url) => !url.pathname.startsWith('/login'));
|
|
return page;
|
|
}
|
|
try {
|
|
const owner = await login('owner'),
|
|
candidate = await login('candidate'),
|
|
moderator = await login('moderator');
|
|
const title = 'QA browser partnership ' + Date.now();
|
|
await owner.goto(base + '/carteira/' + fixture.project_dossier, {
|
|
waitUntil: 'networkidle',
|
|
});
|
|
await owner
|
|
.getByRole('link', {
|
|
name: 'Propor parceria a partir deste registo',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner.getByLabel('Título', { exact: true }).fill(title);
|
|
await owner
|
|
.getByLabel('Tipo de parceria', { exact: true })
|
|
.selectOption('joint_venture');
|
|
await owner
|
|
.getByLabel('Resumo público', { exact: true })
|
|
.fill('QA partnership: source references and local workflow');
|
|
await owner
|
|
.getByLabel('O que oferece', { exact: true })
|
|
.fill('Synthetic QA production capacity');
|
|
await owner
|
|
.getByLabel('O que procura', { exact: true })
|
|
.fill('Synthetic QA technology partner');
|
|
await owner.getByLabel(/Autorizo submeter/).check();
|
|
await owner
|
|
.getByRole('button', { name: 'Guardar rascunho', exact: true })
|
|
.click();
|
|
await owner.waitForURL(/\/parcerias\/\d+\/editar$/);
|
|
const partnershipId = Number(
|
|
new URL(owner.url()).pathname.split('/')[2],
|
|
);
|
|
await owner.reload();
|
|
assert.equal(
|
|
await owner.getByLabel('Título', { exact: true }).inputValue(),
|
|
title,
|
|
);
|
|
await owner
|
|
.getByRole('link', {
|
|
name: 'Pré-visualizar e submeter',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner
|
|
.getByLabel('Motivo da ação', { exact: true })
|
|
.fill('QA source checked and disclosure requested');
|
|
await owner
|
|
.getByRole('button', {
|
|
name: 'Submeter para publicação',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner.getByText('Estado: Submetida.', { exact: false }).waitFor();
|
|
await moderator.goto(base + '/parcerias/' + partnershipId);
|
|
await moderator
|
|
.getByLabel('Motivo da ação', { exact: true })
|
|
.fill(
|
|
'QA reviewed public content; no organization verification presumed',
|
|
);
|
|
await moderator
|
|
.getByRole('button', { name: 'Publicar', exact: true })
|
|
.click();
|
|
await moderator
|
|
.getByText('Estado: Publicada.', { exact: false })
|
|
.waitFor();
|
|
await candidate.goto(base + '/parcerias/' + partnershipId);
|
|
await candidate
|
|
.getByLabel('Proposta curta', { exact: true })
|
|
.fill('QA candidate contribution');
|
|
await candidate
|
|
.getByLabel('Capacidade disponível', { exact: true })
|
|
.fill('Declared synthetic QA capacity');
|
|
await candidate
|
|
.getByLabel(/Autorizo a partilha desta candidatura/)
|
|
.check();
|
|
await candidate
|
|
.getByRole('button', { name: 'Guardar interesse', exact: true })
|
|
.click();
|
|
await candidate
|
|
.getByRole('heading', { name: /Candidatura \d+/ })
|
|
.waitFor();
|
|
await owner.reload();
|
|
await owner
|
|
.getByLabel('Motivo da decisão ou pedido de esclarecimento', {
|
|
exact: true,
|
|
})
|
|
.fill('QA shortlist; unknown evidence remains pending');
|
|
await owner
|
|
.getByRole('button', {
|
|
name: 'Adicionar à lista curta',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner
|
|
.getByRole('heading', { name: /Candidatura \d+ · Lista curta/ })
|
|
.waitFor();
|
|
await owner
|
|
.getByLabel('Motivo da decisão ou pedido de esclarecimento', {
|
|
exact: true,
|
|
})
|
|
.fill('QA private negotiation authorized');
|
|
await owner
|
|
.getByRole('button', { name: 'Abrir negociação', exact: true })
|
|
.click();
|
|
await owner
|
|
.getByRole('link', { name: 'Abrir conexão privada', exact: true })
|
|
.click();
|
|
const roomId = Number(new URL(owner.url()).pathname.split('/').pop());
|
|
await owner
|
|
.getByLabel('Mensagem privada', { exact: true })
|
|
.fill('QA private discussion');
|
|
await owner
|
|
.getByRole('button', { name: 'Enviar mensagem', exact: true })
|
|
.click();
|
|
await owner
|
|
.getByText('QA private discussion', { exact: true })
|
|
.waitFor();
|
|
await owner
|
|
.getByLabel('Título do instrumento', { exact: true })
|
|
.fill('QA pilot agreement');
|
|
await owner
|
|
.getByLabel('Condições e plano de valor', { exact: true })
|
|
.fill(
|
|
'Parties, deliverables, responsibilities, risk and exit conditions. Synthetic QA only.',
|
|
);
|
|
await owner
|
|
.getByLabel('Motivo da ação', { exact: true })
|
|
.fill('QA terms recorded');
|
|
await owner
|
|
.getByRole('button', {
|
|
name: 'Registar versão do acordo',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner
|
|
.getByRole('button', {
|
|
name: 'Confirmar pela minha parte',
|
|
exact: true,
|
|
})
|
|
.waitFor();
|
|
await owner
|
|
.getByLabel('Motivo da ação', { exact: true })
|
|
.fill('QA proponent acknowledgement');
|
|
await owner
|
|
.getByRole('button', {
|
|
name: 'Confirmar pela minha parte',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await candidate.goto(base + '/parcerias/salas/' + roomId);
|
|
await candidate
|
|
.getByText('QA private discussion', { exact: true })
|
|
.waitFor();
|
|
await candidate
|
|
.getByLabel('Motivo da ação', { exact: true })
|
|
.fill('QA candidate acknowledgement');
|
|
await candidate
|
|
.getByRole('button', {
|
|
name: 'Confirmar pela minha parte',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await candidate
|
|
.getByRole('button', {
|
|
name: 'Iniciar acompanhamento',
|
|
exact: true,
|
|
})
|
|
.waitFor();
|
|
await owner.reload();
|
|
await owner
|
|
.getByLabel('Entregável', { exact: true })
|
|
.fill('QA pilot delivery');
|
|
await owner
|
|
.getByRole('button', { name: 'Guardar marco', exact: true })
|
|
.click();
|
|
await owner
|
|
.getByRole('heading', { name: 'Atualizar marco', exact: true })
|
|
.waitFor();
|
|
await owner
|
|
.getByLabel('Motivo da ação', { exact: true })
|
|
.fill('QA start monitoring');
|
|
await owner
|
|
.getByRole('button', {
|
|
name: 'Iniciar acompanhamento',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner
|
|
.getByText('Estado da conexão: Em execução.', { exact: false })
|
|
.waitFor();
|
|
const update = owner
|
|
.getByRole('heading', { name: 'Atualizar marco', exact: true })
|
|
.locator('..');
|
|
await update
|
|
.getByLabel('Estado', { exact: true })
|
|
.selectOption('completed');
|
|
await update
|
|
.getByLabel('Evidência ou referência do resultado', { exact: true })
|
|
.fill('Synthetic QA deliverable evidence');
|
|
await update
|
|
.getByRole('button', { name: 'Guardar marco', exact: true })
|
|
.click();
|
|
await owner
|
|
.getByText('QA pilot delivery · Concluído · Prazo:', {
|
|
exact: false,
|
|
})
|
|
.waitFor();
|
|
assert.equal(
|
|
await update.getByLabel('Estado', { exact: true }).inputValue(),
|
|
'completed',
|
|
);
|
|
for (const width of [1440, 390]) {
|
|
await owner.setViewportSize({ width, height: 1000 });
|
|
assert(
|
|
await owner.evaluate(
|
|
() => document.documentElement.scrollWidth <= innerWidth,
|
|
),
|
|
);
|
|
await owner.screenshot({
|
|
path: `docs/investmoz/partnerships/room-${width}.png`,
|
|
fullPage: true,
|
|
});
|
|
}
|
|
await owner
|
|
.getByLabel('Motivo da ação', { exact: true })
|
|
.fill('QA all milestones completed');
|
|
await owner
|
|
.getByRole('button', {
|
|
name: 'Concluir após os marcos',
|
|
exact: true,
|
|
})
|
|
.click();
|
|
await owner
|
|
.getByText('Estado da conexão: Concluída.', { exact: false })
|
|
.waitFor();
|
|
await owner.goto(base + '/carteira/' + fixture.project_dossier, {
|
|
waitUntil: 'networkidle',
|
|
});
|
|
await owner.getByRole('link', { name: title, exact: true }).waitFor();
|
|
await candidate.goto(
|
|
base + '/parcerias?q=' + encodeURIComponent(title),
|
|
);
|
|
await candidate
|
|
.getByRole('link', { name: title, exact: true })
|
|
.waitFor();
|
|
assert.deepEqual(errors, []);
|
|
fs.writeFileSync(
|
|
'docs/investmoz/partnerships/browser-qa.json',
|
|
JSON.stringify(
|
|
{
|
|
target: 'anchor_restore_20261007_test:55441',
|
|
passed: true,
|
|
partnershipId,
|
|
roomId,
|
|
draftRecovered: true,
|
|
sourceBacklink: true,
|
|
moderation: true,
|
|
interest: true,
|
|
shortlist: true,
|
|
privateMessage: true,
|
|
bilateralAgreement: true,
|
|
milestoneCompleted: true,
|
|
roomClosed: true,
|
|
viewports: [1440, 390],
|
|
errors,
|
|
},
|
|
null,
|
|
2,
|
|
),
|
|
);
|
|
console.log(
|
|
'QA partnership browser passed: real forms, draft recovery, moderation, interest, shortlist, private room, bilateral agreement, milestone and source backlink.',
|
|
);
|
|
} finally {
|
|
await browser.close();
|
|
}
|
|
})().catch((e) => {
|
|
console.error(e);
|
|
process.exitCode = 1;
|
|
});
|