Skip to content

Commit c25f99e

Browse files
committed
fea: update test cases
1 parent 0e8a5f8 commit c25f99e

2 files changed

Lines changed: 298 additions & 7 deletions

File tree

e2e/donations.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ test.describe('Donations page (/contributing)', () => {
2121

2222
await expect(page.getByRole('heading', { name: /doe via pix/i, level: 3 })).toBeVisible();
2323
await expect(page.getByText('100% do valor vai diretamente para a comunidade')).toBeVisible();
24-
await expect(page.getByText('Sem taxas, sem burocracia é instantâneo')).toBeVisible();
24+
await expect(page.getByText('Sem taxas, sem burocracia - é instantâneo')).toBeVisible();
2525
await expect(page.getByText('Você recebe o comprovante no app do banco')).toBeVisible();
2626
});
2727

@@ -41,7 +41,7 @@ test.describe('Donations page (/contributing)', () => {
4141
const pixInput = page.locator('#pix-copia-cola');
4242
await expect(pixInput).toBeVisible();
4343
await expect(pixInput).toHaveValue(/br\.gov\.bcb\.pix/);
44-
await expect(pixInput).toHaveValue(/doar@podcodar\.org/);
44+
await expect(pixInput).toHaveValue(/podcodar@gmail\.com/);
4545
});
4646

4747
test('switches PIX code when clicking suggested amounts', async ({ page }) => {
@@ -75,7 +75,7 @@ test.describe('Donations page (/contributing)', () => {
7575
// Clear and type a custom amount
7676
await customInput.fill('75');
7777
await expect(pixInput).toHaveValue(/75\.00/);
78-
await expect(pixInput).toHaveValue(/doar@podcodar\.org/);
78+
await expect(pixInput).toHaveValue(/podcodar@gmail\.com/);
7979
});
8080

8181
test('shows validation error for amount below minimum', async ({ page }) => {

e2e/site.spec.ts

Lines changed: 295 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,10 @@ test.describe('Join Us page', () => {
256256
await page.goto('/join-us');
257257

258258
// GitHub section
259-
await expect(page.getByRole('heading', { name: /^github$/i, level: 2 })).toBeVisible();
260-
await expect(page.getByText(/github.com\/podcodar/i)).toBeVisible();
259+
await expect(
260+
page.getByRole('heading', { name: /contribua com código aberto/i, level: 2 })
261+
).toBeVisible();
262+
await expect(page.getByText(/repositórios da organização/i)).toBeVisible();
261263

262264
// GitHub CTA button
263265
await expect(page.getByRole('link', { name: /ver repositórios/i })).toHaveAttribute(
@@ -270,10 +272,12 @@ test.describe('Join Us page', () => {
270272
await page.goto('/join-us');
271273

272274
// Contact section
273-
await expect(page.getByRole('heading', { name: /^contato$/i, level: 2 })).toBeVisible();
275+
await expect(
276+
page.getByRole('heading', { name: /pronto para fazer parte/i, level: 2 })
277+
).toBeVisible();
274278

275279
// Link to contact page
276-
await expect(page.getByRole('link', { name: /envie uma mensagem/i })).toHaveAttribute(
280+
await expect(page.getByRole('link', { name: /entre em contato/i })).toHaveAttribute(
277281
'href',
278282
'/contact'
279283
);
@@ -345,4 +349,291 @@ test.describe('Contact page', () => {
345349
const mailtoLink = page.locator('a[href^="mailto:"]').last();
346350
await expect(mailtoLink).toBeVisible();
347351
});
352+
353+
test('has FAQ section with multiple categories', async ({ page }) => {
354+
await page.goto('/contact');
355+
356+
// FAQ section heading
357+
await expect(page.getByRole('heading', { name: /perguntas frequentes/i })).toBeVisible();
358+
359+
// FAQ categories
360+
await expect(page.getByText('Sobre a PodCodar e Nossa Missão')).toBeVisible();
361+
await expect(page.getByText('Para Novos Membros')).toBeVisible();
362+
await expect(page.getByText('Para Empresas e Parceiros')).toBeVisible();
363+
await expect(page.getByText('Outras Dúvidas')).toBeVisible();
364+
365+
// Sample questions from each category
366+
await expect(page.getByText('O que é a PodCodar?')).toBeVisible();
367+
await expect(page.getByText('Preciso pagar para participar da comunidade?')).toBeVisible();
368+
await expect(page.getByText('Quero participar! Qual é o primeiro passo?')).toBeVisible();
369+
await expect(
370+
page.getByText('Somos uma empresa. Como podemos ser parceiros da PodCodar?')
371+
).toBeVisible();
372+
await expect(page.getByText('Quais ferramentas de comunicação vocês usam?')).toBeVisible();
373+
});
374+
});
375+
376+
// ──────────────────────────────────────────────────────────────────────────────
377+
// Transparency page (/transparency)
378+
// ──────────────────────────────────────────────────────────────────────────────
379+
380+
test.describe('Transparency page', () => {
381+
test('navigates to Transparency page via nav link', async ({ page }) => {
382+
await page.goto('/');
383+
384+
await page
385+
.getByRole('navigation', { name: 'Primary' })
386+
.getByRole('link', { name: /transparência/i })
387+
.click();
388+
389+
await expect(page).toHaveURL(/\/transparency/);
390+
await expect(page.getByRole('heading', { name: /transparência/i, level: 1 })).toBeVisible();
391+
});
392+
393+
test('can navigate directly to /transparency', async ({ page }) => {
394+
await page.goto('/transparency');
395+
396+
await expect(page).toHaveTitle(/PodCodar/i);
397+
await expect(page.getByRole('heading', { name: /transparência/i, level: 1 })).toBeVisible();
398+
});
399+
400+
test('has hero section with stats', async ({ page }) => {
401+
await page.goto('/transparency');
402+
403+
// Eyebrow badge
404+
await expect(page.getByText('Compromisso com a Transparência')).toBeVisible();
405+
406+
// Hero heading
407+
await expect(page.getByRole('heading', { name: /transparência/i, level: 1 })).toBeVisible();
408+
409+
// Stats are visible
410+
await expect(page.locator('text=Documentos').first()).toBeVisible();
411+
await expect(page.locator('text=Membros').first()).toBeVisible();
412+
});
413+
414+
test('has documents section with categories', async ({ page }) => {
415+
await page.goto('/transparency');
416+
417+
// Documents section heading
418+
await expect(page.getByRole('heading', { name: /documentos/i, level: 2 })).toBeVisible();
419+
420+
// CNPJ badge - scoped to main content to avoid footer match
421+
await expect(
422+
page.locator('main, [role="main"]').getByText('53.979.776/0001-61').first()
423+
).toBeVisible();
424+
425+
// Category headings (at least one should exist based on content)
426+
const hasInstitucional = await page
427+
.getByText('Institucional')
428+
.first()
429+
.isVisible()
430+
.catch(() => false);
431+
const hasFinanceiro = await page
432+
.getByText('Financeiro')
433+
.first()
434+
.isVisible()
435+
.catch(() => false);
436+
const hasFiscal = await page
437+
.getByText('Fiscal')
438+
.first()
439+
.isVisible()
440+
.catch(() => false);
441+
expect(hasInstitucional || hasFinanceiro || hasFiscal).toBe(true);
442+
});
443+
444+
test('has board members section', async ({ page }) => {
445+
await page.goto('/transparency');
446+
447+
await expect(
448+
page.getByRole('heading', { name: /conselho administrativo/i, level: 2 })
449+
).toBeVisible();
450+
451+
// Board members from data/transparency.ts
452+
await expect(page.getByText('Marco Antônio de Souza Júnior')).toBeVisible();
453+
await expect(page.getByText('Pedro Henrique Ramos Costa')).toBeVisible();
454+
await expect(page.getByText('Marina Andrade Fonseca')).toBeVisible();
455+
await expect(page.getByText('Pedro Frattezi Silva')).toBeVisible();
456+
});
457+
458+
test('has metrics section with impact numbers', async ({ page }) => {
459+
await page.goto('/transparency');
460+
461+
await expect(
462+
page.getByRole('heading', { name: /impacto e resultados/i, level: 2 })
463+
).toBeVisible();
464+
465+
// Metrics from data/transparency.ts
466+
await expect(page.locator('text=300+').first()).toBeVisible();
467+
await expect(page.locator('text=30+').first()).toBeVisible();
468+
await expect(page.locator('text=16+').first()).toBeVisible();
469+
});
470+
471+
test('has commitment section with CTA links', async ({ page }) => {
472+
await page.goto('/transparency');
473+
474+
await expect(page.getByRole('heading', { name: /nosso compromisso/i, level: 2 })).toBeVisible();
475+
476+
// CTA links
477+
await expect(page.getByRole('link', { name: /fale conosco/i }).first()).toHaveAttribute(
478+
'href',
479+
'/contact'
480+
);
481+
await expect(page.getByRole('link', { name: /como ajudar/i })).toHaveAttribute(
482+
'href',
483+
'/contributing'
484+
);
485+
});
486+
487+
test('has contact CTA with mailto link', async ({ page }) => {
488+
await page.goto('/transparency');
489+
490+
await expect(page.getByRole('heading', { name: /fale conosco/i, level: 2 })).toBeVisible();
491+
492+
const mailtoLink = page.locator('a[href^="mailto:contato@podcodar.org"]');
493+
await expect(mailtoLink).toBeVisible();
494+
});
495+
496+
test('can navigate to a document detail page', async ({ page }) => {
497+
await page.goto('/transparency');
498+
499+
// Click the first document card
500+
const firstDocLink = page.locator('a[href^="/transparency/"]').first();
501+
await expect(firstDocLink).toBeVisible();
502+
await firstDocLink.click();
503+
504+
// Should be on a detail page
505+
await expect(page).toHaveURL(/\/transparency\/.+/);
506+
507+
// Detail page should have a breadcrumb back to transparency
508+
const backLink = page
509+
.getByRole('navigation', { name: 'Breadcrumb' })
510+
.getByRole('link', { name: /transparência/i });
511+
await expect(backLink).toHaveAttribute('href', '/transparency');
512+
});
513+
});
514+
515+
// ──────────────────────────────────────────────────────────────────────────────
516+
// Transparency detail pages (/transparency/:slug)
517+
// ──────────────────────────────────────────────────────────────────────────────
518+
519+
test.describe('Transparency detail pages', () => {
520+
test('estatuto page has title, description and back link', async ({ page }) => {
521+
await page.goto('/transparency/estatuto');
522+
523+
// Page should have a heading (the page title h1, not the markdown content h1)
524+
await expect(
525+
page.locator('h1.text-3xl').filter({ hasText: /ata de assembleia/i })
526+
).toBeVisible();
527+
528+
// Category badge
529+
await expect(page.getByText('Institucional').first()).toBeVisible();
530+
531+
// Back link to transparency - use the breadcrumb nav, not the header nav
532+
const breadcrumbLink = page
533+
.getByRole('navigation', { name: 'Breadcrumb' })
534+
.getByRole('link', { name: /transparência/i });
535+
await expect(breadcrumbLink).toHaveAttribute('href', /\/transparency/);
536+
537+
// Back navigation at bottom
538+
await expect(
539+
page.getByRole('link', { name: /voltar para todos os documentos/i })
540+
).toHaveAttribute('href', '/transparency');
541+
});
542+
543+
test('document page has external file link when available', async ({ page }) => {
544+
await page.goto('/transparency/estatuto');
545+
546+
// Should have a view/download link
547+
const viewLink = page.getByRole('link', { name: /ver documento/i });
548+
await expect(viewLink).toBeVisible();
549+
});
550+
551+
test('renders 404 for non-existent transparency slug', async ({ page }) => {
552+
await page.goto('/transparency/non-existent-doc');
553+
554+
// Should show 404
555+
await expect(page.getByText('404')).toBeVisible();
556+
await expect(page.getByRole('heading', { name: /ops/i })).toBeVisible();
557+
});
558+
});
559+
560+
// ──────────────────────────────────────────────────────────────────────────────
561+
// 404 page
562+
// ──────────────────────────────────────────────────────────────────────────────
563+
564+
test.describe('404 page', () => {
565+
test('shows 404 for non-existent routes', async ({ page }) => {
566+
await page.goto('/this-page-does-not-exist');
567+
568+
await expect(page.getByText('404')).toBeVisible();
569+
await expect(page.getByRole('heading', { name: /ops/i })).toBeVisible();
570+
await expect(page.getByText(/essa página não existe/i)).toBeVisible();
571+
});
572+
573+
test('has navigation links back to main pages', async ({ page }) => {
574+
await page.goto('/non-existent-page');
575+
576+
// Link back to home - scoped to 404 navigation
577+
const nav404 = page.getByRole('navigation', { name: '404 navigation' });
578+
await expect(nav404.getByRole('link', { name: /início/i })).toHaveAttribute('href', '/');
579+
580+
// Link to join-us
581+
await expect(nav404.getByRole('link', { name: /faça parte/i })).toHaveAttribute(
582+
'href',
583+
'/join-us/'
584+
);
585+
});
586+
587+
test('returns 404 status for non-existent page', async ({ page, context }) => {
588+
const response = await page.goto('/definitely-not-real');
589+
expect(response?.status()).toBe(404);
590+
});
591+
});
592+
593+
// ──────────────────────────────────────────────────────────────────────────────
594+
// Cross-page navigation
595+
// ──────────────────────────────────────────────────────────────────────────────
596+
597+
test.describe('Cross-page navigation', () => {
598+
test('all main nav links are present in header', async ({ page }) => {
599+
await page.goto('/');
600+
601+
const nav = page.getByRole('navigation', { name: 'Primary' });
602+
603+
await expect(nav.getByRole('link', { name: /início/i })).toBeVisible();
604+
await expect(nav.getByRole('link', { name: /sobre/i })).toBeVisible();
605+
await expect(nav.getByRole('link', { name: /transparência/i })).toBeVisible();
606+
await expect(nav.getByRole('link', { name: /contato/i })).toBeVisible();
607+
});
608+
609+
test('can navigate from about to join-us via CTA', async ({ page }) => {
610+
await page.goto('/about');
611+
612+
const cta = page.getByRole('link', { name: /faça parte/i }).last();
613+
await cta.click();
614+
615+
await expect(page).toHaveURL(/\/join-us/);
616+
});
617+
618+
test('footer social links are consistent across pages', async ({ page }) => {
619+
const pages = ['/', '/about', '/contact', '/transparency', '/join-us', '/contributing'];
620+
621+
for (const path of pages) {
622+
await page.goto(path);
623+
const socialLinks = page.locator('footer').getByTestId('social-links');
624+
await expect(socialLinks.getByRole('link')).toHaveCount(4);
625+
}
626+
});
627+
628+
test('can navigate to transparency from footer or nav on any page', async ({ page }) => {
629+
await page.goto('/join-us');
630+
631+
await page
632+
.getByRole('navigation', { name: 'Primary' })
633+
.getByRole('link', { name: /transparência/i })
634+
.click();
635+
636+
await expect(page).toHaveURL(/\/transparency/);
637+
await expect(page.getByRole('heading', { name: /transparência/i, level: 1 })).toBeVisible();
638+
});
348639
});

0 commit comments

Comments
 (0)