Files
course-plat/tests/e2e/admin/statistics.spec.js
T
2026-08-31 14:10:20 -03:00

305 lines
11 KiB
JavaScript

import { test, expect } from '@playwright/test';
test.describe('Admin - Estatísticas de Provas', () => {
// TODO: Fazer login como admin
// test.beforeEach(async ({ page }) => {
// await page.goto('/auth/login');
// await page.getByLabel(/email/i).fill('[email protected]');
// await page.getByLabel(/senha/i).fill('123456');
// await page.getByRole('button', { name: /entrar/i }).click();
// await page.waitForURL(/\/dispatcher/);
// await page.getByRole('button', { name: /admin/i }).click();
// });
test.describe('Página de Estatísticas', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
});
test('deve mostrar header com PageHeader', async ({ page }) => {
await expect(page.getByText(/estatísticas de provas/i)).toBeVisible();
await expect(page.getByText(/visualize estatísticas/i)).toBeVisible();
});
test('deve ter filtro de período', async ({ page }) => {
await expect(page.getByRole('combobox', { name: /período/i })).toBeVisible();
});
test('deve ter botão de atualizar', async ({ page }) => {
const refreshButton = page.getByRole('button', { name: /atualizar|refresh/i });
if (await refreshButton.isVisible()) {
await expect(refreshButton).toBeVisible();
}
});
});
test.describe('Estatísticas Agregadas', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
});
test('deve mostrar total de tentativas', async ({ page }) => {
await expect(page.getByText(/total de tentativas/i)).toBeVisible();
const totalValue = page.locator('text=/deve-total/').first(); // Ajustar seletor
if (await totalValue.isVisible()) {
const text = await totalValue.textContent();
expect(text).toMatch(/\d+/);
}
});
test('deve mostrar média de notas', async ({ page }) => {
await expect(page.getByText(/média de notas/i)).toBeVisible();
});
test('deve mostrar média de aproveitamento', async ({ page }) => {
await expect(page.getByText(/média de aproveitamento/i)).toBeVisible();
const percentageValue = page.locator('text=/deve-percent/').first();
if (await percentageValue.isVisible()) {
const text = await percentageValue.textContent();
expect(text).toMatch(/\d+%/);
}
});
test('deve mostrar taxa de aprovação', async ({ page }) => {
await expect(page.getByText(/taxa de aprovação/i)).toBeVisible();
const passRateValue = page.locator('text=/deve-pass/').first();
if (await passRateValue.isVisible()) {
const text = await passRateValue.textContent();
expect(text).toMatch(/\d+%/);
}
});
});
test.describe('Estatísticas por Turma', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
});
test('deve mostrar cards de turmas', async ({ page }) => {
await expect(page.getByText(/por turma|by class/i)).toBeVisible();
});
test('deve mostrar nome da turma', async ({ page }) => {
const classCard = page.locator('[data-testid="class-stat-card"]').first();
if (await classCard.isVisible()) {
await expect(classCard.getByText(/turma|class/i)).toBeVisible();
}
});
test('deve mostrar número de tentativas por turma', async ({ page }) => {
const classCard = page.locator('[data-testid="class-stat-card"]').first();
if (await classCard.isVisible()) {
await expect(classCard.getByText(/tentativas/i)).toBeVisible();
}
});
test('deve mostrar média da turma com cor baseada no desempenho', async ({ page }) => {
const classCard = page.locator('[data-testid="class-stat-card"]').first();
if (await classCard.isVisible()) {
const avgLabel = classCard.locator('[data-testid="average-label"]').first();
if (await avgLabel.isVisible()) {
// Deve ter cor: emerald (bom), amber (médio), red (ruim)
const classes = await avgLabel.getAttribute('class') || '';
expect(classes).toMatch(/label-emerald|label-amber|label-red|bg-emerald|bg-amber|bg-red/i);
}
}
});
});
test.describe('Estatísticas por Template', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
});
test('deve mostrar cards de templates', async ({ page }) => {
await expect(page.getByText(/por modelo|por template|by template/i)).toBeVisible();
});
test('deve mostrar título do template', async ({ page }) => {
const templateCard = page.locator('[data-testid="template-stat-card"]').first();
if (await templateCard.isVisible()) {
await expect(templateCard.getByText(/prova|template/i)).toBeVisible();
}
});
test('deve mostrar número de tentativas por template', async ({ page }) => {
const templateCard = page.locator('[data-testid="template-stat-card"]').first();
if (await templateCard.isVisible()) {
await expect(templateCard.getByText(/tentativas/i)).toBeVisible();
}
});
});
test.describe('Lista de Tentativas', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
});
test('deve mostrar tabela de tentativas', async ({ page }) => {
await expect(page.getByText(/tentativas de prova/i)).toBeVisible();
await expect(page.locator('table')).toBeVisible();
});
test('deve mostrar colunas principais', async ({ page }) => {
const table = page.locator('table').first();
if (await table.isVisible()) {
await expect(table.getByText(/aluno|student/i)).toBeVisible();
await expect(table.getByText(/turma|class/i)).toBeVisible();
await expect(table.getByText(/modelo|template/i)).toBeVisible();
await expect(table.getByText(/nota|score/i)).toBeVisible();
await expect(table.getByText(/status/i)).toBeVisible();
await expect(table.getByText(/data/i)).toBeVisible();
}
});
test('deve mostrar badge de status correção', async ({ page }) => {
const table = page.locator('table').first();
if (await table.isVisible()) {
const statusCell = table.locator('td').last();
if (await statusCell.isVisible()) {
// Status: fully_graded, partially_graded, auto_graded, pending
await expect(statusCell.locator('[data-testid="label"]')).toBeVisible();
}
}
});
});
test.describe('Paginação', () => {
test('deve ter controles de paginação', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const pagination = page.locator('[data-testid="pagination"]');
if (await pagination.isVisible()) {
await expect(pagination.getByRole('button', { name: /anterior|previous/i })).toBeVisible();
await expect(pagination.getByRole('button', { name: /próxima|next/i })).toBeVisible();
}
});
test('deve mostrar página atual', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const pageInfo = page.getByText(/página \d+ de \d+/i);
if (await pageInfo.isVisible()) {
await expect(pageInfo).toBeVisible();
}
});
test('deve navegar entre páginas', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const nextButton = page.getByRole('button', { name: /próxima|next/i });
if (await nextButton.isEnabled()) {
await nextButton.click();
// Deve mudar a página
const pageInfo = page.getByText(/página \d+ de \d+/i);
if (await pageInfo.isVisible()) {
const text = await pageInfo.textContent();
expect(text).toMatch(/página [2-9]/);
}
}
});
});
test.describe('Filtros', () => {
test('deve filtrar por status', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const statusFilter = page.getByRole('combobox', { name: /status/i });
if (await statusFilter.isVisible()) {
await statusFilter.selectOption('paid');
// Deve recarregar resultados
await page.waitForTimeout(500);
// Verificar se filtrou
}
});
test('deve filtrar por turma', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const classFilter = page.getByRole('combobox', { name: /turma/i });
if (await classFilter.isVisible()) {
const initialCount = await page.locator('table tbody tr').count();
await classFilter.selectOption({ index: 0 });
await page.waitForTimeout(500);
// Pode mostrar menos resultados
}
});
});
test.describe('Labels/Badges de Status', () => {
test('deve usar Label component corretamente', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const label = page.locator('[data-testid="label"]').first();
if (await label.isVisible()) {
// Deve ter as classes de cor
const classes = await label.getAttribute('class') || '';
expect(classes).toMatch(/label-(emerald|amber|red|blue|gray|sky|indigo|purple)/);
}
});
test('deve mostrar cor correta para cada status', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
// Verificar cores dos badges de porcentagem
const percentageLabels = page.locator('[data-testid="average-percent-label"]');
const count = await percentageLabels.count();
for (let i = 0; i < Math.min(count, 3); i++) {
const label = percentageLabels.nth(i);
const classes = await label.getAttribute('class') || '';
// >= 70%: emerald, >= 60%: amber, < 60%: red
expect(classes).toMatch(/label-(emerald|amber|red)/);
}
});
test('deve mostrar cor correta para status de correção', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const gradingLabels = page.locator('[data-testid="grading-status-label"]');
const count = await gradingLabels.count();
for (let i = 0; i < Math.min(count, 3); i++) {
const label = gradingLabels.nth(i);
const classes = await label.getAttribute('class') || '';
// fully_graded: emerald, partially_graded: amber, auto_graded: blue, pending: gray
expect(classes).toMatch(/label-(emerald|amber|blue|gray)/);
}
});
});
test.describe('Exportação de Dados', () => {
test('deve ter botão de exportar CSV', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const exportButton = page.getByRole('button', { name: /exportar|csv/i });
if (await exportButton.isVisible()) {
const downloadPromise = page.waitForEvent('download');
await exportButton.click();
const download = await downloadPromise;
expect(download.suggestedFilename()).toMatch(/\.csv$/);
}
});
test('deve ter botão de exportar PDF', async ({ page }) => {
await page.goto('/admin/dashboard/statistics/exams');
const exportButton = page.getByRole('button', { name: /pdf/i });
if (await exportButton.isVisible()) {
const downloadPromise = page.waitForEvent('download');
await exportButton.click();
const download = await downloadPromise;
expect(download.suggestedFilename()).toMatch(/\.pdf$/);
}
});
});
});