mirror of
https://github.com/BradGroux/veritas-kanban.git
synced 2026-08-28 02:44:59 +00:00
Audit and resolve the open contributor and dependency backlog, stabilize the release candidate, synchronize versioned documentation, and prepare the verified 6.1.1 release.
128 lines
4.5 KiB
TypeScript
128 lines
4.5 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { bypassAuth, seedTestTask, deleteTask, cleanupRoutes } from './helpers/auth';
|
|
|
|
test.describe('Task Status Change', () => {
|
|
let testTaskId: string | null = null;
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
await bypassAuth(page);
|
|
});
|
|
|
|
test.afterEach(async ({ page }) => {
|
|
if (testTaskId) {
|
|
await deleteTask(page, testTaskId).catch(() => {});
|
|
testTaskId = null;
|
|
}
|
|
await cleanupRoutes(page);
|
|
});
|
|
|
|
test('change task status via detail panel dropdown', async ({ page }) => {
|
|
const uniqueTitle = `E2E Status Change ${Date.now()}`;
|
|
|
|
const task = await seedTestTask(page, {
|
|
title: uniqueTitle,
|
|
status: 'todo',
|
|
priority: 'medium',
|
|
});
|
|
testTaskId = (task as { id: string }).id;
|
|
|
|
await page.goto('/');
|
|
|
|
// Verify the task is in the To Do column
|
|
const todoColumn = page.getByRole('region', { name: 'To Do' });
|
|
await expect(todoColumn.locator(`text=${uniqueTitle}`)).toBeVisible({
|
|
timeout: 15_000,
|
|
});
|
|
|
|
// Click the task to open the detail panel
|
|
await todoColumn.locator(`text=${uniqueTitle}`).click();
|
|
|
|
const detailPanel = page.locator('[role="dialog"]');
|
|
await expect(detailPanel).toBeVisible({ timeout: 5_000 });
|
|
|
|
const statusTrigger = detailPanel.getByRole('combobox', { name: 'Status' });
|
|
await expect(statusTrigger).toBeVisible();
|
|
await statusTrigger.click();
|
|
|
|
// Select "In Progress" and wait for the API PATCH response
|
|
const inProgressOption = page.getByRole('option', { name: 'In Progress' });
|
|
await expect(inProgressOption).toBeVisible();
|
|
|
|
const [patchResponse] = await Promise.all([
|
|
page.waitForResponse(
|
|
(resp) => resp.url().includes('/api/tasks/') && resp.request().method() === 'PATCH',
|
|
{ timeout: 10_000 }
|
|
),
|
|
inProgressOption.click(),
|
|
]);
|
|
|
|
// Ensure the PATCH succeeded
|
|
expect(patchResponse.status()).toBeLessThan(400);
|
|
await expect(statusTrigger).toHaveValue('In Progress');
|
|
await expect(detailPanel.getByText('Saving...')).not.toBeVisible({ timeout: 5_000 });
|
|
|
|
// Close the detail panel
|
|
await detailPanel.getByRole('button', { name: 'Close task details' }).click();
|
|
await expect(detailPanel).not.toBeVisible({ timeout: 3_000 });
|
|
|
|
// Wait for the task to move to the In Progress column
|
|
const inProgressColumn = page.getByRole('region', { name: 'In Progress' });
|
|
await expect(inProgressColumn.locator(`text=${uniqueTitle}`)).toBeVisible({
|
|
timeout: 10_000,
|
|
});
|
|
|
|
// Verify it's no longer in the To Do column
|
|
await expect(todoColumn.locator(`text=${uniqueTitle}`)).not.toBeVisible();
|
|
});
|
|
|
|
test('change task status to done via detail panel', async ({ page }) => {
|
|
const uniqueTitle = `E2E Done Task ${Date.now()}`;
|
|
|
|
const task = await seedTestTask(page, {
|
|
title: uniqueTitle,
|
|
status: 'in-progress',
|
|
priority: 'low',
|
|
});
|
|
testTaskId = (task as { id: string }).id;
|
|
|
|
await page.goto('/');
|
|
|
|
// Verify the task starts in In Progress
|
|
const inProgressCol = page.getByRole('region', { name: 'In Progress' });
|
|
await expect(inProgressCol.locator(`text=${uniqueTitle}`)).toBeVisible({ timeout: 15_000 });
|
|
|
|
// Open the detail panel
|
|
await inProgressCol.locator(`text=${uniqueTitle}`).click();
|
|
|
|
const detailPanel = page.locator('[role="dialog"]');
|
|
await expect(detailPanel).toBeVisible({ timeout: 5_000 });
|
|
|
|
const statusTrigger = detailPanel.getByRole('combobox', { name: 'Status' });
|
|
await expect(statusTrigger).toBeVisible();
|
|
await statusTrigger.click();
|
|
|
|
// Select "Done" and wait for the API PATCH
|
|
const doneOption = page.getByRole('option', { name: 'Done' });
|
|
await expect(doneOption).toBeVisible();
|
|
|
|
const [patchResponse] = await Promise.all([
|
|
page.waitForResponse(
|
|
(resp) => resp.url().includes('/api/tasks/') && resp.request().method() === 'PATCH',
|
|
{ timeout: 10_000 }
|
|
),
|
|
doneOption.click(),
|
|
]);
|
|
|
|
expect(patchResponse.status()).toBeLessThan(400);
|
|
await expect(statusTrigger).toHaveValue('Done');
|
|
await expect(detailPanel.getByText('Saving...')).not.toBeVisible({ timeout: 5_000 });
|
|
|
|
// Close panel
|
|
await detailPanel.getByRole('button', { name: 'Close task details' }).click();
|
|
await expect(detailPanel).not.toBeVisible({ timeout: 3_000 });
|
|
|
|
// Verify the task moved to Done
|
|
const doneCol = page.getByRole('region', { name: 'Done' });
|
|
await expect(doneCol.locator(`text=${uniqueTitle}`)).toBeVisible({ timeout: 10_000 });
|
|
});
|
|
});
|