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

284 lines
9.8 KiB
JavaScript

import { test, expect } from '@playwright/test';
test.describe('Aluno - Materiais', () => {
// TODO: Fazer login como aluno
// 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\/student/);
// });
test.describe('Dashboard do Aluno', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/dashboard/student');
});
test('deve mostrar turmas matriculadas', async ({ page }) => {
await expect(page.getByText(/turmas|classes|minhas turmas/i)).toBeVisible();
});
test('deve mostrar cards de turmas com informações', async ({ page }) => {
const classCard = page.locator('[data-testid="class-card"], .card').first();
if (await classCard.isVisible()) {
await expect(classCard.getByText(/inglês|português/i, { ignoreCase: true })).toBeVisible();
}
});
});
test.describe('Materiais por Turma', () => {
test.beforeEach(async ({ page }) => {
// TODO: Navegar para página de uma turma específica
await page.goto('/dashboard/student/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) {
// 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-/);
}
}
});
test('deve listar arquivos de cada categoria', async ({ page }) => {
const materialsSection = page.getByText(/materiais/i).locator('..');
const fileLinks = materialsSection.getByRole('link', { name: /abrir|baixar/i });
const count = await fileLinks.count();
if (count > 0) {
await expect(fileLinks.nth(0)).toBeVisible();
}
});
test('deve mostrar tamanho do arquivo', async ({ page }) => {
const materialsSection = page.getByText(/materiais/i).locator('..');
const sizeText = page.getByText(/\d+\.?\d* KB|MB/i).first();
if (await sizeText.isVisible()) {
await expect(sizeText).toBeVisible();
}
});
});
test.describe('Download de Arquivo', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/dashboard/student/class/class-id');
});
test('deve baixar arquivo ao clicar no botão', async ({ page }) => {
const downloadButton = page.getByRole('link', { name: /baixar|download/i }).first();
if (await downloadButton.isVisible()) {
const downloadPromise = page.waitForEvent('download');
await downloadButton.click();
const download = await downloadPromise;
expect(download.suggestedFilename()).toBeTruthy();
}
});
test('deve abrir PDF em nova aba', async ({ page }) => {
const openButton = page.getByRole('link', { name: /abrir/i }).first();
if (await openButton.isVisible()) {
const newPagePromise = page.waitForEvent('popup');
await openButton.click();
const newPage = await newPagePromise;
await expect(newPage).toHaveURL(/\.pdf/i);
}
});
test('deve mostrar preview de imagem', async ({ page }) => {
const imageLink = page.getByRole('link', { name: /abrir/i }).first();
if (await imageLink.isVisible()) {
await imageLink.click();
// Pode abrir modal com preview
const preview = page.locator('img[src*="/uploads/"]').first();
if (await preview.isVisible()) {
await expect(preview).toBeVisible();
}
}
});
});
test.describe('Filtros de Categoria', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/dashboard/student/class/class-id');
});
test('deve ter botões de filtro por categoria', async ({ page }) => {
const categoryBadges = page.locator('[data-testid="category-badge"]');
const count = await categoryBadges.count();
if (count > 0) {
// Ao clicar, deve filtrar materiais
await categoryBadges.nth(0).click();
await page.waitForTimeout(500);
// Verificar se filtrou (pode mostrar apenas materiais da categoria)
}
});
test('deve mostrar todos ao clicar no filtro ativo', async ({ page }) => {
// Primeiro clicar em uma categoria
const categoryBadges = page.locator('[data-testid="category-badge"]');
if ((await categoryBadges.count()) > 0) {
await categoryBadges.nth(0).click();
await page.waitForTimeout(500);
// Clicar novamente para limpar filtro
await categoryBadges.nth(0).click();
await page.waitForTimeout(500);
// Deve mostrar todos novamente
}
});
});
test.describe('Histórico de Aulas', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/dashboard/student/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, tópico e presença', 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}/)).toBeVisible();
const topicCell = lessonRow.locator('td').nth(1);
if (await topicCell.isVisible()) {
await expect(topicCell.getByText(/tópico/i)).toBeVisible();
}
}
});
test('deve mostrar presença do aluno em cada aula', async ({ page }) => {
const attendanceCell = page.locator('tbody tr td').nth(2);
if (await attendanceCell.isVisible()) {
const text = await attendanceCell.textContent();
// Pode ser emoji ou texto
expect(text).toMatch(/presente|ausente|atrasado|✓|✗|◑/i);
}
});
test('deve mostrar link para materiais da aula', async ({ page }) => {
const lessonRow = page.locator('[data-testid="lesson-row"], tr').nth(1);
if (await lessonRow.isVisible()) {
const materialsLink = lessonRow.getByRole('link', { name: /materiais/i });
if (await materialsLink.isVisible()) {
await expect(materialsLink).toBeVisible();
}
}
});
});
test.describe('Presença Global', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/dashboard/student/class/class-id');
});
test('deve mostrar taxa de presença geral', async ({ page }) => {
await expect(page.getByText(/presença|attendance/i)).toBeVisible();
const percentage = page.getByText(/\d+%/i).first();
if (await percentage.isVisible()) {
await expect(percentage).toBeVisible();
}
});
test('deve mostrar presença de forma visual (gráfico ou barra)', async ({ page }) => {
// Pode ter gráfico de barras ou outra visualização
const chart = page.locator('[data-testid="attendance-chart"], canvas, svg');
if (await chart.isVisible()) {
await expect(chart).toBeVisible();
}
});
});
test.describe('Responsividade - Mobile', () => {
test('materiais devem ser usáveis em mobile', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto('/dashboard/student/class/class-id');
// Deve mostrar lista sem scroll horizontal
const hasHorizontalScroll = await page.evaluate(() => {
return document.body.scrollWidth > document.body.clientWidth;
});
expect(hasHorizontalScroll).toBe(false);
});
test('cards de turma devem se ajustar em mobile', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto('/dashboard/student');
const classCards = page.locator('[data-testid="class-card"]');
const count = await classCards.count();
if (count > 0) {
// Em mobile, devem estar em coluna única
const firstCard = classCards.nth(0);
const secondCard = classCards.nth(1);
if (await secondCard.isVisible()) {
const firstBox = await firstCard.boundingBox();
const secondBox = await secondCard.boundingBox();
// Devem estar um abaixo do outro
expect(secondBox.y).toBeGreaterThan(firstBox.y + firstBox.height);
}
}
});
});
test.describe('Busca de Materiais', () => {
test('deve ter campo de busca', async ({ page }) => {
await page.goto('/dashboard/student/class/class-id');
const searchInput = page.getByPlaceholder(/buscar|pesquisar|search/i);
if (await searchInput.isVisible()) {
await expect(searchInput).toBeVisible();
}
});
test('deve filtrar materiais ao buscar', async ({ page }) => {
const searchInput = page.getByPlaceholder(/buscar/i);
if (await searchInput.isVisible()) {
await searchInput.fill('PDF');
await page.waitForTimeout(500);
// Deve mostrar apenas materiais com "PDF"
const fileLinks = page.getByRole('link', { name: /abrir/i });
const count = await fileLinks.count();
if (count > 0) {
for (let i = 0; i < count; i++) {
const text = await fileLinks.nth(i).textContent();
// Pode não filtrar estritamente, mas deve priorizar resultados
}
}
}
});
});
});