fix(tests): unskip and fix Playwright E2E tests (#1973)

- Re-enable 16 previously skipped Playwright E2E tests that now pass
- Fix test setup issues that were causing flakiness

## Changes
- **task/task.spec.ts** (8 tests): kanban navigation, description
editing, assignees, labels, due dates
- **task/overview.spec.ts** (4 tests): task ordering, due date handling
- **user/settings.spec.ts** (2 tests): avatar upload, name update
- **user/login.spec.ts** (2 tests): bad password error, redirect after
login

## Key fixes
- Kanban view tests now properly create `TaskBucket` entries so tasks
appear in the kanban board
- Avatar upload test uses the API directly to avoid `canvas.toBlob()`
issues in headless browser environments
- Login redirect test no longer uses the shared `login()` helper that
expected redirect to `/`
This commit is contained in:
kolaente
2025-12-12 17:20:22 +01:00
committed by GitHub
parent 5dab85e76f
commit d390ccab27
7 changed files with 70 additions and 30 deletions

View File

@@ -61,7 +61,7 @@ test.describe('Home Page Task Overview', () => {
}
})
test.skip('Should show a new task with a very soon due date at the top', async ({authenticatedPage: page, apiContext}) => {
test('Should show a new task with a very soon due date at the top', async ({authenticatedPage: page, apiContext}) => {
const {tasks, project} = await seedTasks(apiContext, 49)
const newTaskTitle = 'New Task'
@@ -84,7 +84,7 @@ test.describe('Home Page Task Overview', () => {
await expect(page.locator('[data-cy="showTasks"] .card .task').first()).toContainText(newTaskTitle)
})
test.skip('Should not show a new task without a date at the bottom when there are > 50 tasks', async ({authenticatedPage: page, apiContext}) => {
test('Should not show a new task without a date at the bottom when there are > 50 tasks', async ({authenticatedPage: page, apiContext}) => {
// We're not using the api here to create the task in order to verify the flow
const {tasks} = await seedTasks(apiContext, 100)
const newTaskTitle = 'New Task'
@@ -103,7 +103,7 @@ test.describe('Home Page Task Overview', () => {
await expect(page.locator('[data-cy="showTasks"]')).not.toContainText(newTaskTitle)
})
test.skip('Should show a new task without a date at the bottom when there are < 50 tasks', async ({authenticatedPage: page, apiContext}) => {
test('Should show a new task without a date at the bottom when there are < 50 tasks', async ({authenticatedPage: page, apiContext}) => {
const {project} = await seedTasks(apiContext, 40)
const newTaskTitle = 'New Task'
await TaskFactory.create(1, {
@@ -117,7 +117,7 @@ test.describe('Home Page Task Overview', () => {
await expect(page.locator('[data-cy="showTasks"]')).toContainText(newTaskTitle)
})
test.skip('Should show a task without a due date added via default project at the bottom', async ({authenticatedPage: page, apiContext}) => {
test('Should show a task without a due date added via default project at the bottom', async ({authenticatedPage: page, apiContext}) => {
const {project} = await seedTasks(apiContext, 40)
// Navigate first to get access to localStorage

View File

@@ -217,11 +217,20 @@ test.describe('Task', () => {
await expect(page).toHaveURL(/\/projects\/1\/\d+/)
})
test.skip('provides back navigation to the project in the kanban view on mobile', async ({authenticatedPage: page}) => {
test('provides back navigation to the project in the kanban view on mobile', async ({authenticatedPage: page}) => {
await page.setViewportSize({width: 375, height: 667}) // iphone-8
const tasks = await TaskFactory.create(1)
await page.goto('/projects/1/4')
const tasks = await TaskFactory.create(1, {
id: 1,
project_id: projects[0].id,
})
// Task must be in a bucket to appear in kanban view
await TaskBucketFactory.create(1, {
task_id: tasks[0].id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
})
await page.goto(`/projects/${projects[0].id}/4`)
await page.waitForLoadState('networkidle')
// Wait for kanban view and task to be visible
@@ -230,14 +239,23 @@ test.describe('Task', () => {
await taskLocator.click()
await expect(page.locator('.task-view .back-button')).toBeVisible()
await page.locator('.task-view .back-button').click()
await expect(page).toHaveURL(/\/projects\/1\/\d+/)
await expect(page).toHaveURL(/\/projects\/\d+\/\d+/)
})
test.skip('does not provide back navigation to the project in the kanban view on desktop', async ({authenticatedPage: page}) => {
test('does not provide back navigation to the project in the kanban view on desktop', async ({authenticatedPage: page}) => {
await page.setViewportSize({width: 1440, height: 900}) // macbook-15
const tasks = await TaskFactory.create(1)
await page.goto('/projects/1/4')
const tasks = await TaskFactory.create(1, {
id: 1,
project_id: projects[0].id,
})
// Task must be in a bucket to appear in kanban view
await TaskBucketFactory.create(1, {
task_id: tasks[0].id,
bucket_id: buckets[0].id,
project_view_id: buckets[0].project_view_id,
})
await page.goto(`/projects/${projects[0].id}/4`)
await page.waitForLoadState('networkidle')
// Wait for kanban view and task to be visible
@@ -314,7 +332,7 @@ test.describe('Task', () => {
await expect(page.locator('.task-view h1.title.task-id')).toContainText(`${projects[0].identifier}-${tasks[0].index}`)
})
test.skip('Can edit the description', async ({authenticatedPage: page}) => {
test('Can edit the description', async ({authenticatedPage: page}) => {
const tasks = await TaskFactory.create(1, {
id: 1,
description: 'Lorem ipsum dolor sit amet.',
@@ -446,7 +464,7 @@ test.describe('Task', () => {
await expect(page).toHaveURL(new RegExp(`/projects/${tasks[0].project_id}/`))
})
test.skip('Can add an assignee to a task', async ({authenticatedPage: page}) => {
test('Can add an assignee to a task', async ({authenticatedPage: page}) => {
await TaskAssigneeFactory.truncate()
// Create users with IDs starting at 100 to avoid conflict with logged-in user (ID 1)
@@ -566,7 +584,7 @@ test.describe('Task', () => {
await expect(page.locator('.bucket .task')).toContainText(labels[0].title)
})
test.skip('Can remove a label from a task', async ({authenticatedPage: page}) => {
test('Can remove a label from a task', async ({authenticatedPage: page}) => {
const tasks = await TaskFactory.create(1, {
id: 1,
project_id: 1,
@@ -595,7 +613,7 @@ test.describe('Task', () => {
await expect(labelWrapper).not.toContainText(labels[0].title)
})
test.skip('Can set a due date for a task', async ({authenticatedPage: page}) => {
test('Can set a due date for a task', async ({authenticatedPage: page}) => {
const tasks = await TaskFactory.create(1, {
id: 1,
done: false,
@@ -623,7 +641,7 @@ test.describe('Task', () => {
await expect(page.locator('.global-notification')).toContainText('Success')
})
test.skip('Can set a due date to a specific date for a task', async ({authenticatedPage: page}) => {
test('Can set a due date to a specific date for a task', async ({authenticatedPage: page}) => {
const tasks = await TaskFactory.create(1, {
id: 1,
done: false,
@@ -656,7 +674,7 @@ test.describe('Task', () => {
await expect(page.locator('.global-notification')).toContainText('Success')
})
test.skip('Can change a due date to a specific date for a task', async ({authenticatedPage: page}) => {
test('Can change a due date to a specific date for a task', async ({authenticatedPage: page}) => {
const dueDate = new Date(2025, 2, 20)
dueDate.setHours(12)
dueDate.setMinutes(0)