305 lines
11 KiB
JavaScript
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$/);
|
|
}
|
|
});
|
|
});
|
|
});
|