Files
2026-08-31 14:10:20 -03:00

326 lines
13 KiB
JavaScript

import { test, expect } from '@playwright/test';
test.describe('Professor - Correção de Provas', () => {
// 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('Lista de Provas da Turma', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/dashboard/teacher/class/class-id');
});
test('deve mostrar provas atribuídas à turma', async ({ page }) => {
const assignmentList = page.locator('[data-testid="assignment-list"]');
if (await assignmentList.isVisible()) {
await expect(assignmentList.getByText(/prova/i)).toBeVisible();
}
});
test('deve mostrar status da prova', async ({ page }) => {
const assignmentList = page.locator('[data-testid="assignment-list"]');
if (await assignmentList.isVisible()) {
// Status: pendente, em andamento, concluída
const statusBadge = assignmentList.locator('[data-testid="status-label"]').first();
if (await statusBadge.isVisible()) {
await expect(statusBadge).toBeVisible();
}
}
});
test('deve mostrar número de alunos que fizeram a prova', async ({ page }) => {
const assignmentList = page.locator('[data-testid="assignment-list"]');
if (await assignmentList.isVisible()) {
const progressText = assignmentList.getByText(/\d+\/\d+/i).first();
if (await progressText.isVisible()) {
await expect(progressText).toBeVisible();
}
}
});
test('deve ter botão de ver resultados', async ({ page }) => {
const assignmentCard = page.locator('[data-testid="assignment-card"]').first();
if (await assignmentCard.isVisible()) {
const resultsButton = assignmentCard.getByRole('link', { name: /resultados|correções/i });
if (await resultsButton.isVisible()) {
await expect(resultsButton).toBeVisible();
}
}
});
});
test.describe('Página de Resultados da Turma', () => {
test.beforeEach(async ({ page }) => {
// TODO: Navegar para resultados de uma turma específica
await page.goto('/dashboard/teacher/class/class-id/results');
});
test('deve mostrar lista de tentativas', async ({ page }) => {
await expect(page.getByText(/tentativas|resultados/i)).toBeVisible();
await expect(page.locator('table')).toBeVisible();
});
test('deve mostrar aluno, prova, nota e status', async ({ page }) => {
const table = page.locator('table').first();
if (await table.isVisible()) {
await expect(table.getByText(/aluno|student/i)).toBeVisible();
await expect(table.getByText(/prova|template/i)).toBeVisible();
await expect(table.getByText(/nota|score/i)).toBeVisible();
await expect(table.getByText(/status/i)).toBeVisible();
}
});
test('deve mostrar badge de status de correção', async ({ page }) => {
const table = page.locator('table').first();
if (await table.isVisible()) {
const statusCell = table.locator('tbody tr td').last();
if (await statusCell.isVisible()) {
// Status: pending, partially_graded, fully_graded
const label = statusCell.locator('[data-testid="label"], .label').first();
if (await label.isVisible()) {
const classes = await label.getAttribute('class') || '';
expect(classes).toMatch(/label-(gray|amber|emerald)/);
}
}
}
});
});
test.describe('Corrigir Prova - Modal', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/dashboard/teacher/class/class-id/results');
// Abrir modal de correção
const gradeButton = page.getByRole('button', { name: /corrigir|grade/i }).first();
if (await gradeButton.isVisible()) {
await gradeButton.click();
}
});
test('deve abrir modal com detalhes da tentativa', async ({ page }) => {
await expect(page.locator('.fixed.inset-0')).toBeVisible();
await expect(page.getByText(/correção|grading/i)).toBeVisible();
});
test('deve mostrar informações do aluno', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
await expect(page.getByText(/aluno|student/i)).toBeVisible();
// Deve mostrar data de envio
await expect(page.getByText(/\d{2}\/\d{2}\/\d{4}/)).toBeVisible();
}
});
test('deve mostrar questões da prova', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
const questions = page.locator('[data-testid="question-card"]');
const count = await questions.count();
if (count > 0) {
// Primeira questão deve ter enunciado
await expect(questions.nth(0).getByPlaceholder(/enunciado|questão/i)).toBeVisible();
}
}
});
});
test.describe('Corrigir Questão Textual', () => {
test.beforeEach(async ({ page }) => {
// Abrir modal de correção com questão textual
// await page.goto('/dashboard/teacher/class/class-id/results');
// await page.getByRole('button', { name: /corrigir/i }).click();
});
test('deve mostrar resposta do aluno', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
const textQuestion = page.locator('[data-testid="text-question"]').first();
if (await textQuestion.isVisible()) {
await expect(textQuestion.getByPlaceholder(/resposta/i)).not.toBeEmpty();
}
}
});
test('deve permitir dar pontos parciais', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
const textQuestion = page.locator('[data-testid="text-question"]').first();
if (await textQuestion.isVisible()) {
const pointsInput = textQuestion.getByRole('spinbutton', { name: /pontos/i });
if (await pointsInput.isVisible()) {
await pointsInput.fill('3.5');
const value = await pointsInput.inputValue();
expect(value).toBe('3.5');
}
}
}
});
test('deve ter campo de feedback', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
const textQuestion = page.locator('[data-testid="text-question"]').first();
if (await textQuestion.isVisible()) {
const feedbackInput = textQuestion.getByPlaceholder(/feedback|comentário/i);
if (await feedbackInput.isVisible()) {
await feedbackInput.fill('Bom trabalho, mas pode melhorar a gramática.');
await expect(feedbackInput).toHaveValue(/gramática/i);
}
}
}
});
});
test.describe('Questões de Múltipla Escolha', () => {
test('deve mostrar resposta selecionada pelo aluno', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
const mcQuestion = page.locator('[data-testid="mc-question"]').first();
if (await mcQuestion.isVisible()) {
// Opção correta deve estar marcada
const correctOption = mcQuestion.locator('[data-testid="correct-option"]').first();
if (await correctOption.isVisible()) {
await expect(correctOption).toBeVisible();
}
// Opção errada deve estar marcada se o aluno errou
const wrongOption = mcQuestion.locator('[data-testid="wrong-option"]').first();
if (await wrongOption.isVisible()) {
await expect(wrongOption).toBeVisible();
}
}
}
});
test('deve mostrar opção correta', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
const mcQuestion = page.locator('[data-testid="mc-question"]').first();
if (await mcQuestion.isVisible()) {
const correctOption = mcQuestion.locator('[data-testid="correct-option"]').first();
if (await correctOption.isVisible()) {
await expect(correctOption.getByText(/correta/i)).toBeVisible();
}
}
}
});
test('não deve permitir modificar correção automática', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
const mcQuestion = page.locator('[data-testid="mc-question"]').first();
if (await mcQuestion.isVisible()) {
// Opções devem ser readonly
const options = mcQuestion.locator('input[type="radio"]');
const count = await options.count();
for (let i = 0; i < count; i++) {
await expect(options.nth(i)).toBeDisabled();
}
}
}
});
});
test.describe('Salvar Correção', () => {
test.beforeEach(async ({ page }) => {
// Abrir modal de correção
// await page.goto('/dashboard/teacher/class/class-id/results');
// await page.getByRole('button', { name: /corrigir/i }).first().click();
});
test('deve calcular nota total automaticamente', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
// Deve mostrar nota total calculada
const totalScore = page.getByText(/nota total|total score/i);
if (await totalScore.isVisible()) {
await expect(totalScore).toBeVisible();
}
}
});
test('deve salvar correção com sucesso', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
await page.getByRole('button', { name: /salvar|concluir/i }).click();
// Deve fechar modal
await expect(page.locator('.fixed.inset-0')).not.toBeVisible({ timeout: 5000 });
// Deve mostrar mensagem de sucesso ou atualizar status
// await expect(page.getByText(/correção salva|sucesso/i)).toBeVisible();
}
});
test('deve atualizar status para "corrigido"', async ({ page }) => {
// TODO: Implementar fluxo completo
// 1. Abrir correção
// 2. Salvar
// 3. Verificar se status mudou na lista
});
});
test.describe('Correção Parcial', () => {
test('deve indicar provas parcialmente corrigidas', async ({ page }) => {
await page.goto('/dashboard/teacher/class/class-id/results');
// Deve ter badges para: pending, partially_graded, fully_graded
const partialBadge = page.locator('[data-testid="status-label"]')
.filter({ hasText: /parcial/i });
const count = await partialBadge.count();
expect(count).toBeGreaterThanOrEqual(0);
});
test('deve mostrar ícone de pendência para questões não corrigidas', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
// Questões textuais sem correção devem ter indicador
const ungradedQuestions = page.locator('[data-testid="needs-grading"]');
const count = await ungradedQuestions.count();
if (count > 0) {
await expect(ungradedQuestions.nth(0).getByText(/pendente|corrigir/i)).toBeVisible();
}
}
});
});
test.describe('Cancelar Correção', () => {
test('deve ter botão de cancelar', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
await expect(page.getByRole('button', { name: /cancelar/i })).toBeVisible();
}
});
test('deve fechar modal sem salvar ao cancelar', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
await page.getByRole('button', { name: /cancelar/i }).click();
await expect(page.locator('.fixed.inset-0').not.toBeVisible();
}
});
test('deve perder alterações não salvas', async ({ page }) => {
if (await page.locator('.fixed.inset-0').isVisible()) {
// Fazer alterações
const textQuestion = page.locator('[data-testid="text-question"]').first();
if (await textQuestion.isVisible()) {
const pointsInput = textQuestion.getByRole('spinbutton', { name: /pontos/i });
if (await pointsInput.isVisible()) {
await pointsInput.fill('5');
}
}
// Cancelar
await page.getByRole('button', { name: /cancelar/i }).click();
// Abrir novamente - não deve ter os 5 pontos
// await page.getByRole('button', { name: /corrigir/i }).first().click();
// const newPoints = page.getByRole('spinbutton', { name: /pontos/i }).first();
// const value = await newPoints.inputValue();
// expect(value).not.toBe('5');
}
});
});
});