301 lines
11 KiB
JavaScript
301 lines
11 KiB
JavaScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('Professor - Dashboard', () => {
|
|
// TODO: Fazer login como professor
|
|
// 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|\/dashboard\/teacher/);
|
|
// });
|
|
|
|
test.describe('Página Inicial do Professor', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/dashboard/teacher');
|
|
});
|
|
|
|
test('deve mostrar turmas atribuídas', async ({ page }) => {
|
|
await expect(page.getByText(/turmas|classes|minhas turmas/i)).toBeVisible();
|
|
});
|
|
|
|
test('deve mostrar cards de turmas', async ({ page }) => {
|
|
const classCard = page.locator('[data-testid="class-card"], .card').first();
|
|
if (await classCard.isVisible()) {
|
|
await expect(classCard.getByText(/turma|class/i)).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('deve mostrar botão de ver detalhes', async ({ page }) => {
|
|
const classCard = page.locator('[data-testid="class-card"], .card').first();
|
|
if (await classCard.isVisible()) {
|
|
const viewButton = classCard.getByRole('link', { name: /ver|detalhes/i });
|
|
if (await viewButton.isVisible()) {
|
|
await expect(viewButton).toBeVisible();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Detalhes da Turma', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
// TODO: Usar ID de turma de teste
|
|
await page.goto('/dashboard/teacher/class/class-id');
|
|
});
|
|
|
|
test('deve mostrar título da turma', async ({ page }) => {
|
|
await expect(page.getByText(/inglês|português|matemática/i, { ignoreCase: true })).toBeVisible();
|
|
});
|
|
|
|
test('deve mostrar informações básicas', async ({ page }) => {
|
|
await expect(page.getByText(/professores|teachers/i)).toBeVisible();
|
|
await expect(page.getByText(/dias|schedule/i)).toBeVisible();
|
|
await expect(page.getByText(/horário|time/i)).toBeVisible();
|
|
});
|
|
|
|
test('deve mostrar label de status', async ({ page }) => {
|
|
const statusLabel = page.locator('[data-testid="status-label"]');
|
|
if (await statusLabel.isVisible()) {
|
|
// Status: Ativa, Arquivada, Inativa
|
|
const classes = await statusLabel.getAttribute('class') || '';
|
|
expect(classes).toMatch(/label-(emerald|gray|red)/);
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Materiais da Turma', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/dashboard/teacher/class/class-id');
|
|
});
|
|
|
|
test('deve mostrar seção de materiais', async ({ page }) => {
|
|
await expect(page.getByText(/materiais|arquivos|materials/i)).toBeVisible();
|
|
});
|
|
|
|
test('deve mostrar materiais agrupados por categoria', async ({ page }) => {
|
|
const materialsSection = page.getByText(/materiais/i).locator('..');
|
|
|
|
const categoryBadges = materialsSection.locator('[data-testid="category-badge"]');
|
|
const count = await categoryBadges.count();
|
|
|
|
if (count > 0) {
|
|
// Cada categoria deve ter cor
|
|
for (let i = 0; i < Math.min(count, 3); i++) {
|
|
const badge = categoryBadges.nth(i);
|
|
const classes = await badge.getAttribute('class') || '';
|
|
expect(classes).toMatch(/bg-/); // Deve ter cor de fundo
|
|
}
|
|
}
|
|
});
|
|
|
|
test('deve ter botão de upload', async ({ page }) => {
|
|
const uploadButton = page.getByRole('link', { name: /upload|adicionar/i });
|
|
if (await uploadButton.isVisible()) {
|
|
await expect(uploadButton).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('deve permitir download de arquivo', async ({ page }) => {
|
|
const downloadLink = page.getByRole('link', { name: /baixar|download|abrir/i }).first();
|
|
if (await downloadLink.isVisible()) {
|
|
const downloadPromise = page.waitForEvent('download');
|
|
|
|
await downloadLink.click();
|
|
|
|
const download = await downloadPromise;
|
|
expect(download.suggestedFilename()).toBeTruthy();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Registrar Aula (Lesson)', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/dashboard/teacher/class/class-id');
|
|
});
|
|
|
|
test('deve abrir modal ao clicar em Registrar Aula', async ({ page }) => {
|
|
const lessonButton = page.getByRole('button', { name: /registrar aula|lesson/i });
|
|
if (await lessonButton.isVisible()) {
|
|
await lessonButton.click();
|
|
|
|
await expect(page.locator('.fixed.inset-0')).toBeVisible();
|
|
await expect(page.getByText(/registrar aula|nova aula/i)).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('deve ter campos de data, tópico e notas', async ({ page }) => {
|
|
await page.getByRole('button', { name: /registrar aula/i }).click();
|
|
|
|
await expect(page.getByLabel(/data|date/i)).toBeVisible();
|
|
await expect(page.getByLabel(/tópico|topic/i)).toBeVisible();
|
|
await expect(page.getByPlaceholder(/notas|observations/i)).toBeVisible();
|
|
});
|
|
|
|
test('deve permitir registrar presença dos alunos', async ({ page }) => {
|
|
await page.getByRole('button', { name: /registrar aula/i }).click();
|
|
|
|
// Deve mostrar lista de alunos
|
|
const studentList = page.locator('[data-testid="student-list"]');
|
|
if (await studentList.isVisible()) {
|
|
// Deve ter opções de presença
|
|
await expect(page.getByRole('combobox', { name: /presença/i })).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('deve salvar aula com sucesso', async ({ page }) => {
|
|
await page.getByRole('button', { name: /registrar aula/i }).click();
|
|
|
|
const timestamp = Date.now();
|
|
await page.getByLabel(/data/i).fill('2025-02-05');
|
|
await page.getByLabel(/tópico/i).fill(`Aula Teste ${timestamp}`);
|
|
await page.getByPlaceholder(/notas/i).fill('Notas da aula');
|
|
|
|
// Registrar presenças
|
|
const attendanceSelects = page.getByRole('combobox', { name: /presença/i });
|
|
const count = await attendanceSelects.count();
|
|
|
|
for (let i = 0; i < Math.min(count, 3); i++) {
|
|
await attendanceSelects.nth(i).selectOption('present');
|
|
}
|
|
|
|
await page.getByRole('button', { name: /salvar|registrar/i }).click();
|
|
|
|
// Deve fechar modal
|
|
await expect(page.locator('.fixed.inset-0')).not.toBeVisible({ timeout: 5000 });
|
|
});
|
|
});
|
|
|
|
test.describe('Histórico de Aulas', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/dashboard/teacher/class/class-id/history');
|
|
});
|
|
|
|
test('deve mostrar lista de aulas registradas', async ({ page }) => {
|
|
await expect(page.getByText(/histórico|lessons|aulas/i)).toBeVisible();
|
|
});
|
|
|
|
test('deve mostrar data e tópico de cada aula', async ({ page }) => {
|
|
const lessonRow = page.locator('[data-testid="lesson-row"], tr').nth(1);
|
|
if (await lessonRow.isVisible()) {
|
|
await expect(lessonRow.getByText(/\d{2}\/\d{2}\/\d{4}/)).toBeVisible();
|
|
await expect(lessonRow.getByText(/tópico|topic/i)).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('deve permitir ver detalhes de uma aula', async ({ page }) => {
|
|
const viewButton = page.getByRole('link', { name: /ver|detalhes/i }).first();
|
|
if (await viewButton.isVisible()) {
|
|
await viewButton.click();
|
|
|
|
await expect(page.getByText(/presença|attendance/i)).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Provas da Turma', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/dashboard/teacher/class/class-id');
|
|
});
|
|
|
|
test('deve mostrar seção de provas', async ({ page }) => {
|
|
await expect(page.getByText(/provas|avaliações|exams/i)).toBeVisible();
|
|
});
|
|
|
|
test('deve ter botão de atribuir prova', async ({ page }) => {
|
|
const assignButton = page.getByRole('button', { name: /atribuir prova/i });
|
|
if (await assignButton.isVisible()) {
|
|
await expect(assignButton).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('deve mostrar lista de provas atribuídas', async ({ page }) => {
|
|
const assignmentList = page.locator('[data-testid="assignment-list"]');
|
|
if (await assignmentList.isVisible()) {
|
|
await expect(assignmentList.getByText(/prova/i)).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Visão Geral da Turma', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/dashboard/teacher/class/class-id');
|
|
});
|
|
|
|
test('deve mostrar número de alunos', async ({ page }) => {
|
|
await expect(page.getByText(/\d+ alunos/i, { exact: false })).toBeVisible();
|
|
});
|
|
|
|
test('deve mostrar cards de visão geral', async ({ page }) => {
|
|
await expect(page.getByText(/visão geral/i)).toBeVisible();
|
|
|
|
const overviewCards = page.locator('[data-testid="overview-card"]');
|
|
const count = await overviewCards.count();
|
|
|
|
if (count > 0) {
|
|
// Deve ter estatísticas
|
|
await expect(page.getByText(/alunos|students/i)).toBeVisible();
|
|
await expect(page.getByText(/presença|attendance/i)).toBeVisible();
|
|
}
|
|
});
|
|
});
|
|
|
|
test.describe('Lista de Alunos da Turma', () => {
|
|
test.beforeEach(async ({ page }) => {
|
|
await page.goto('/dashboard/teacher/class/class-id');
|
|
});
|
|
|
|
test('deve mostrar tabela de alunos', async ({ page }) => {
|
|
const studentTable = page.locator('table');
|
|
if (await studentTable.isVisible()) {
|
|
await expect(studentTable.getByText(/nome|aluno/i)).toBeVisible();
|
|
await expect(studentTable.getByText(/presença/i)).toBeVisible();
|
|
await expect(studentTable.getByText(/média/i)).toBeVisible();
|
|
}
|
|
});
|
|
|
|
test('deve mostrar nome, presença e média', async ({ page }) => {
|
|
const studentTable = page.locator('table').first();
|
|
if (await studentTable.isVisible()) {
|
|
const firstRow = studentTable.locator('tbody tr').first();
|
|
|
|
// Nome (primeiro nome)
|
|
await expect(firstRow.locator('td').nth(0)).not.toBeEmpty();
|
|
|
|
// Presença em %
|
|
const attendanceCell = firstRow.locator('td').nth(1);
|
|
if (await attendanceCell.isVisible()) {
|
|
const text = await attendanceCell.textContent();
|
|
expect(text).match(/\d+%/);
|
|
}
|
|
|
|
// Média
|
|
const avgCell = firstRow.locator('td').nth(2);
|
|
if (await avgCell.isVisible()) {
|
|
const text = await avgCell.textContent();
|
|
expect(text).toMatch(/\d+\.?\d*|-/); // Nota ou traço
|
|
}
|
|
}
|
|
});
|
|
|
|
test('deve mostrar cor baseada no desempenho', async ({ page }) => {
|
|
const studentTable = page.locator('table').first();
|
|
if (await studentTable.isVisible()) {
|
|
// Presença >= 80%: verde, >= 60%: amarelo, < 60%: vermelho
|
|
const attendanceCell = studentTable.locator('tbody tr td').nth(1);
|
|
if (await attendanceCell.isVisible()) {
|
|
const classes = await attendanceCell.getAttribute('class') || '';
|
|
const text = await attendanceCell.textContent();
|
|
|
|
if (text.includes('80') || text.includes('90') || text.includes('100')) {
|
|
expect(classes).toMatch(/text-emerald|green/);
|
|
} else if (text.includes('60') || text.includes('70')) {
|
|
expect(classes).toMatch(/text-amber|yellow/);
|
|
} else {
|
|
expect(classes).toMatch(/text-red/);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
});
|