tududi/e2e/tests/task-project-assignment.spec.ts
2025-11-06 23:43:20 +02:00

125 lines
4.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, Page } from '@playwright/test';
import {
login,
navigateAndWait,
waitForElement,
hoverAndWaitForVisible,
createUniqueEntity,
waitForNetworkIdle
} from '../helpers/testHelpers';
// Helper to create a task
async function createTask(page: Page, taskName: string) {
const taskInput = page.locator('[data-testid="new-task-input"]');
await taskInput.fill(taskName);
await taskInput.press('Enter');
await waitForNetworkIdle(page);
}
// Helper to open task edit modal
async function openTaskEditModal(page: Page, taskName: string) {
const taskContainer = page.locator('[data-testid*="task-item"]').filter({ hasText: taskName });
await expect(taskContainer).toBeVisible({ timeout: 15000 });
const editButton = taskContainer.locator('[data-testid*="task-edit"]');
await hoverAndWaitForVisible(taskContainer, editButton);
await editButton.click();
const taskNameInput = page.locator('[data-testid="task-name-input"]');
await waitForElement(taskNameInput, { timeout: 15000 });
return taskNameInput;
}
// Helper to create a project
async function createProject(page: Page, projectName: string) {
const addProjectButton = page.locator('button[aria-label="Add Project"]');
await expect(addProjectButton).toBeVisible();
await addProjectButton.click();
await expect(page.locator('input[name="name"]')).toBeVisible({ timeout: 10000 });
const nameInput = page.locator('[data-testid="project-name-input"]');
await nameInput.click();
await nameInput.clear();
await nameInput.fill(projectName);
await expect(nameInput).toHaveValue(projectName, { timeout: 2000 });
const saveButton = page.locator('[data-testid="project-save-button"]');
await expect(saveButton).toBeEnabled();
await saveButton.click();
await expect(page.locator('[data-testid="project-modal"]')).not.toBeVisible({ timeout: 15000 });
}
test('comprehensive project assignment functionality in task modal', async ({ page, baseURL }) => {
const appUrl = await login(page, baseURL);
// === SETUP: Create two projects ===
await navigateAndWait(page, appUrl + '/projects');
const project1Name = createUniqueEntity('First Project');
await createProject(page, project1Name);
const project2Name = createUniqueEntity('Second Project');
await createProject(page, project2Name);
// Navigate to tasks page
await navigateAndWait(page, appUrl + '/tasks');
// Create a task
const taskName = createUniqueEntity('Task with Project');
await createTask(page, taskName);
// === TEST 1: Assign project using keyboard navigation ===
await openTaskEditModal(page, taskName);
await expect(page.locator('[data-testid="task-modal"][data-state="idle"]')).toBeVisible();
let taskModal = page.locator('[data-testid="task-modal"]');
let projectSectionButton = taskModal.locator('button[title="Project"]').filter({ has: page.locator('svg') });
await projectSectionButton.click();
let projectSearchInput = page.locator('input[placeholder*="Search or create"]');
await expect(projectSearchInput).toBeVisible({ timeout: 5000 });
await projectSearchInput.fill(project1Name);
await page.waitForTimeout(500);
// Use arrow down + Enter
await projectSearchInput.press('ArrowDown');
await projectSearchInput.press('Enter');
// Verify badge appears and input is hidden
let projectBadge = taskModal.locator('span').filter({ hasText: project1Name });
await expect(projectBadge).toBeVisible();
await expect(projectSearchInput).not.toBeVisible();
// === TEST 2: Cannot add a second project (single project restriction) ===
// Badge should be visible, no input available
const inputStillGone = page.locator('input[placeholder*="Search or create"]');
await expect(inputStillGone).not.toBeVisible();
// === TEST 3: Remove project by clicking × button ===
const removeButton = projectBadge.locator('button');
await expect(removeButton).toBeVisible();
await removeButton.click();
// Badge should disappear, input should reappear
await expect(projectBadge).not.toBeVisible();
projectSearchInput = page.locator('input[placeholder*="Search or create"]');
await expect(projectSearchInput).toBeVisible();
// === TEST 4: Exact match auto-selection with Enter ===
// Type exact project name and press Enter (no arrow keys needed)
await projectSearchInput.fill(project2Name);
await page.waitForTimeout(500);
await projectSearchInput.press('Enter');
// Verify project is selected immediately
projectBadge = taskModal.locator('span').filter({ hasText: project2Name });
await expect(projectBadge).toBeVisible();
await expect(projectSearchInput).not.toBeVisible();
// Test complete - all project assignment functionality verified
// No need to close modal as test is finished
});