Files
team-planner/tests/e2e/phase1.spec.ts
2026-01-14 01:10:01 +03:00

156 lines
5.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { test, expect } from '@playwright/test';
/**
* E2E тесты для Фазы 1 Team Planner
* - Базовая загрузка страницы
* - Таблица идей
* - Фильтры
* - Создание идей
* - Inline-редактирование
* - Удаление
*/
test.describe('Фаза 1: Базовый функционал', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
// Ждём загрузки таблицы
await page.waitForSelector('table, [role="grid"]', { timeout: 10000 });
});
test('Страница загружается', async ({ page }) => {
await expect(page.locator('body')).toBeVisible();
await expect(page).toHaveTitle(/.*/);
});
test('Таблица идей отображается', async ({ page }) => {
const table = page.locator('table, [role="grid"]');
await expect(table).toBeVisible();
});
test('Таблица имеет заголовки колонок', async ({ page }) => {
const headers = page.locator('th, [role="columnheader"]');
const count = await headers.count();
expect(count).toBeGreaterThan(0);
// Проверяем что есть хотя бы несколько важных колонок
const headerTexts = await headers.allTextContents();
expect(headerTexts.length).toBeGreaterThan(0);
});
test('Фильтры присутствуют на странице', async ({ page }) => {
// Ищем элементы фильтров (inputs, selects, MUI компоненты)
const filterElements = page.locator('input, [role="combobox"], .MuiSelect-select');
const count = await filterElements.count();
expect(count).toBeGreaterThanOrEqual(1);
});
test('Поле поиска работает', async ({ page }) => {
const searchInput = page.locator('input[placeholder*="Поиск"]');
await expect(searchInput).toBeVisible();
await searchInput.fill('test');
await expect(searchInput).toHaveValue('test');
// Очищаем
await searchInput.clear();
});
test('Кнопка создания идеи существует', async ({ page }) => {
const buttons = page.locator('button');
const createButton = buttons.filter({
hasText: /создать|добавить|новая|\+/i,
});
await expect(createButton.first()).toBeVisible();
});
test('Модалка создания открывается', async ({ page }) => {
// Находим и кликаем кнопку создания
const createButton = page
.locator('button')
.filter({ hasText: /создать|добавить|новая/i })
.first();
await createButton.click();
// Проверяем что модалка открылась (используем .first() т.к. MUI создаёт вложенные элементы)
const modal = page.locator('[role="dialog"]').first();
await expect(modal).toBeVisible();
// Закрываем модалку
await page.keyboard.press('Escape');
await expect(modal).toBeHidden();
});
test('Таблица показывает данные или empty state', async ({ page }) => {
const rows = page.locator('tbody tr, [role="row"]');
const rowCount = await rows.count();
if (rowCount > 1) {
// Есть данные
expect(rowCount).toBeGreaterThan(1);
} else {
// Ищем empty state
const emptyState = page.locator('text=/нет|пусто|Нет идей/i');
const hasEmptyState = (await emptyState.count()) > 0;
expect(hasEmptyState || rowCount >= 1).toBeTruthy();
}
});
test('Пагинация присутствует', async ({ page }) => {
const pagination = page.locator(
'.MuiTablePagination-root, [aria-label*="pagination"], nav[aria-label*="pagination"]'
);
await expect(pagination.first()).toBeVisible();
});
test('Inline-редактирование работает (double-click)', async ({ page }) => {
// Находим ячейки таблицы (пропускаем первую - drag handle)
const cells = page.locator('tbody td');
const cellCount = await cells.count();
if (cellCount > 1) {
// Пробуем double-click на ячейках (начиная со второй)
for (let i = 1; i < Math.min(cellCount, 6); i++) {
const cell = cells.nth(i);
const text = await cell.textContent();
if (text && text.trim()) {
await cell.dblclick();
await page.waitForTimeout(500);
// Проверяем появился ли input для редактирования
const input = page.locator(
'.MuiInputBase-input, input.MuiInput-input, tbody input, [role="combobox"]'
);
const inputCount = await input.count();
if (inputCount > 0) {
// Отменяем редактирование
await page.keyboard.press('Escape');
return; // Тест прошёл
}
}
}
}
// Если нет данных для inline-редактирования - это ОК
expect(true).toBeTruthy();
});
test('Кнопка удаления в таблице', async ({ page }) => {
// Ищем иконки/кнопки удаления в строках
const deleteButtons = page.locator(
'tbody button[aria-label*="delete"], tbody button[aria-label*="удалить"], tbody [data-testid="DeleteIcon"], tbody svg'
);
const count = await deleteButtons.count();
// Если есть данные, должны быть кнопки удаления
const rows = await page.locator('tbody tr').count();
if (rows > 0) {
expect(count).toBeGreaterThanOrEqual(0);
}
});
});