Files
team-planner/tests/e2e/phase1.spec.ts
2026-01-15 00:18:35 +03:00

199 lines
7.4 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-редактирование
* - Удаление
*
* Используем data-testid для стабильных селекторов
*/
test.describe('Фаза 1: Базовый функционал', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/');
// Ждём загрузки таблицы идей
await page.waitForSelector('[data-testid="ideas-table"]', { timeout: 10000 });
});
test('Страница загружается', async ({ page }) => {
await expect(page.locator('body')).toBeVisible();
await expect(page).toHaveTitle(/.*/);
});
test('Таблица идей отображается', async ({ page }) => {
const table = page.locator('[data-testid="ideas-table"]');
await expect(table).toBeVisible();
});
test('Контейнер таблицы присутствует', async ({ page }) => {
const container = page.locator('[data-testid="ideas-table-container"]');
await expect(container).toBeVisible();
});
test('Фильтры присутствуют на странице', async ({ page }) => {
const filters = page.locator('[data-testid="ideas-filters"]');
await expect(filters).toBeVisible();
});
test('Поле поиска работает', async ({ page }) => {
const searchInput = page.locator('[data-testid="search-input"] input');
await expect(searchInput).toBeVisible();
await searchInput.fill('test');
await expect(searchInput).toHaveValue('test');
// Очищаем
await searchInput.clear();
});
test('Фильтр статуса присутствует', async ({ page }) => {
const statusFilter = page.locator('[data-testid="filter-status"]');
await expect(statusFilter).toBeVisible();
});
test('Фильтр приоритета присутствует', async ({ page }) => {
const priorityFilter = page.locator('[data-testid="filter-priority"]');
await expect(priorityFilter).toBeVisible();
});
test('Фильтр модуля присутствует', async ({ page }) => {
const moduleFilter = page.locator('[data-testid="filter-module"]');
await expect(moduleFilter).toBeVisible();
});
test('Модалка создания открывается', async ({ page }) => {
// Находим и кликаем кнопку создания
const createButton = page
.locator('button')
.filter({ hasText: /создать|добавить|новая/i })
.first();
await createButton.click();
// Проверяем что модалка открылась
const modal = page.locator('[data-testid="create-idea-modal"]');
await expect(modal).toBeVisible();
// Закрываем модалку
await page.keyboard.press('Escape');
await expect(modal).toBeHidden();
});
test('Модалка создания содержит необходимые поля', async ({ page }) => {
const createButton = page
.locator('button')
.filter({ hasText: /создать|добавить|новая/i })
.first();
await createButton.click();
const modal = page.locator('[data-testid="create-idea-modal"]');
await expect(modal).toBeVisible();
// Проверяем наличие формы и поля ввода
const form = page.locator('[data-testid="create-idea-form"]');
await expect(form).toBeVisible();
const titleInput = page.locator('[data-testid="idea-title-input"]');
await expect(titleInput).toBeVisible();
const cancelButton = page.locator('[data-testid="cancel-create-idea"]');
await expect(cancelButton).toBeVisible();
const submitButton = page.locator('[data-testid="submit-create-idea"]');
await expect(submitButton).toBeVisible();
await page.keyboard.press('Escape');
});
test('Таблица показывает данные или empty state', async ({ page }) => {
// Проверяем либо есть строки с данными, либо пустое состояние
const emptyState = page.locator('[data-testid="ideas-empty-state"]');
const ideaRows = page.locator('[data-testid^="idea-row-"]');
const hasEmptyState = await emptyState.isVisible().catch(() => false);
const rowCount = await ideaRows.count();
expect(hasEmptyState || rowCount > 0).toBeTruthy();
});
test('Пагинация присутствует', async ({ page }) => {
const pagination = page.locator('.MuiTablePagination-root');
await expect(pagination.first()).toBeVisible();
});
test('Inline-редактирование работает (double-click)', async ({ page }) => {
// Проверяем есть ли данные
const ideaRows = page.locator('[data-testid^="idea-row-"]');
const rowCount = await ideaRows.count();
if (rowCount > 0) {
// Находим первую строку и кликаем дважды на ячейку
const firstRow = ideaRows.first();
const cells = firstRow.locator('td');
const cellCount = await cells.count();
if (cellCount > 2) {
// Пробуем double-click на ячейках (пропускаем drag handle и color)
const cell = cells.nth(2);
await cell.dblclick();
await page.waitForTimeout(500);
// Проверяем появился ли input для редактирования
const input = page.locator('.MuiInputBase-input, [role="combobox"]');
const inputCount = await input.count();
if (inputCount > 0) {
// Отменяем редактирование
await page.keyboard.press('Escape');
}
}
}
// Тест прошёл без ошибок
expect(true).toBeTruthy();
});
test('Кнопка удаления присутствует в строке', async ({ page }) => {
const ideaRows = page.locator('[data-testid^="idea-row-"]');
const rowCount = await ideaRows.count();
if (rowCount > 0) {
const deleteButtons = page.locator('[data-testid="delete-idea-button"]');
const count = await deleteButtons.count();
expect(count).toBeGreaterThan(0);
}
});
test('Кнопка сброса фильтров появляется при активных фильтрах', async ({ page }) => {
// Изначально кнопка сброса скрыта
const clearButton = page.locator('[data-testid="clear-filters-button"]');
await expect(clearButton).toBeHidden();
// Выбираем статус в фильтре
const statusFilter = page.locator('[data-testid="filter-status"]');
await statusFilter.locator('[role="combobox"]').click();
const listbox = page.locator('[role="listbox"]');
await expect(listbox).toBeVisible();
// Выбираем любой статус кроме "Все"
const options = listbox.locator('[role="option"]');
const optionCount = await options.count();
if (optionCount > 1) {
await options.nth(1).click();
// Теперь кнопка сброса должна быть видна
await expect(clearButton).toBeVisible();
// Сбрасываем фильтры
await clearButton.click();
await expect(clearButton).toBeHidden();
}
});
});