Initial commit
This commit is contained in:
@@ -0,0 +1,283 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user