check_circle Testes Jest
Carregando resultados Jest...
Qualidade sem segredos
Cada push executa a suíte unitária, uma suíte de fluxos em navegador real e um limite de cobertura antes que o build chegue à produção. O que você vê aqui é o resultado real da última execução, além de uma suíte que você pode rodar no seu próprio navegador agora.
Quatorze verificações rodam nesta mesma página: DOM, acessibilidade, i18n, rede e tempos. Nada é simulado e nada vem do cache.
Executa testes de fumaça, estrutura DOM, acessibilidade e desempenho diretamente no seu navegador.
Números direto do GitHub Actions. Os resultados do Jest saem com o build; o resumo do Puppeteer é buscado ao vivo de um Gist que o pipeline atualiza a cada execução.
Carregando resultados Jest...
Carregando resultados E2E...
Carregando cobertura...
Quatro camadas, quatro ferramentas. Cada trecho vem direto deste repositório.
test('closes mobile menu when a nav link is clicked', async () => {
const { container } = render(
<MemoryRouter>
<Navbar />
</MemoryRouter>
);
const toggle = screen.getByLabelText('Toggle navigation');
const menu = container.querySelector('#mobileMenu');
fireEvent.click(toggle);
expect(toggle).toHaveAttribute('aria-expanded', 'true');
expect(menu).toHaveClass('active');
fireEvent.click(screen.getByText(/Personal Projects/i));
await waitFor(() => {
expect(toggle).toHaveAttribute('aria-expanded', 'false');
expect(menu).not.toHaveClass('active');
});
});it('should NOT contain unsafe-inline in script-src', () => {
const headers = fs.readFileSync(headersPath, 'utf-8');
const cspLine = headers.match(/Content-Security-Policy:.*$/m);
expect(cspLine).toBeTruthy();
const scriptSrc = cspLine[0].match(/script-src ([^;]+)/)[1];
expect(scriptSrc).not.toContain("'unsafe-inline'");
});
it('should generate correct SHA-256 hash for JSON-LD script', () => {
const html = fs.readFileSync(htmlPath, 'utf-8');
const [, scriptContent] = html.match(
/<script type="application\/ld\+json">([\s\S]*?)<\/script>/
);
const calculatedHash = crypto
.createHash('sha256')
.update(scriptContent)
.digest('base64');
const hashes = JSON.parse(fs.readFileSync(hashesPath, 'utf-8'));
expect(hashes.jsonLd).toBe(`'sha256-${calculatedHash}'`);
});{
name: 'Cookie consent accept hides banner and stores consent',
run: async (page, step) => {
await step('Navigate to home page', () =>
page.goto(BASE_URL, { waitUntil: 'networkidle2', timeout: NAV_TIMEOUT })
);
await step('Cookie banner is shown', () =>
page.waitForSelector('#cookieConsentBanner', { timeout: NAV_TIMEOUT })
);
await step('Click "Accept all cookies"', () => page.click('#acceptCookies'));
await step('Banner is dismissed', () =>
page.waitForSelector('#cookieConsentBanner', { hidden: true, timeout: NAV_TIMEOUT })
);
await step('Consent cookie is stored', async () => {
const cookie = await page.evaluate(() => document.cookie);
assert(/cookie_consent=accepted/.test(cookie), `Consent cookie not set: "${cookie}"`);
});
},
},{
id: 'dom-safe-links',
nameKey: 'testDashboard.runner.tests.safeLinks.name',
run: async () => {
const externalLinks = Array.from(document.querySelectorAll('a[target="_blank"]'));
const insecureLinks = externalLinks.filter((link) => {
const rel = (link.getAttribute('rel') || '').toLowerCase();
return !rel.includes('noopener') && !rel.includes('noreferrer');
});
if (insecureLinks.length > 0) {
const hrefs = insecureLinks
.slice(0, 3)
.map((l) => l.getAttribute('href'))
.join(', ');
throw new Error(
`Found ${insecureLinks.length} external link(s) without rel="noopener noreferrer": ${hrefs}`
);
}
return {
message: `Verified ${externalLinks.length} external link(s) have secure rel attributes.`,
};
},
},Relatórios HTML estáticos, regenerados a cada deploy.