Skip to content

Conversation

@danielway
Copy link
Owner

  • Install @playwright/test for E2E testing
  • Create playwright.config.ts with minimal configuration
    • Uses Vite dev server automatically
    • Chromium-only for simplicity
    • Optimized for CI/CD with retries and proper timeouts
  • Add initial E2E test for task creation workflow
    • Verifies user can create a new task
    • Confirms task appears in UI
    • Validates localStorage persistence
  • Update GitHub Actions CI workflow
    • Add dedicated E2E test job
    • Install Playwright browsers with dependencies
    • Upload test reports on failure
  • Add npm scripts for running E2E tests
    • test:e2e - Run tests headless
    • test:e2e:ui - Run with Playwright UI
    • test:e2e:debug - Run in debug mode
  • Exclude e2e directory from Vitest
  • Add Playwright artifacts to .gitignore

This provides a foundation for comprehensive E2E test coverage
while keeping the initial implementation simple and focused.

- Install @playwright/test for E2E testing
- Create playwright.config.ts with minimal configuration
  - Uses Vite dev server automatically
  - Chromium-only for simplicity
  - Optimized for CI/CD with retries and proper timeouts
- Add initial E2E test for task creation workflow
  - Verifies user can create a new task
  - Confirms task appears in UI
  - Validates localStorage persistence
- Update GitHub Actions CI workflow
  - Add dedicated E2E test job
  - Install Playwright browsers with dependencies
  - Upload test reports on failure
- Add npm scripts for running E2E tests
  - test:e2e - Run tests headless
  - test:e2e:ui - Run with Playwright UI
  - test:e2e:debug - Run in debug mode
- Exclude e2e directory from Vitest
- Add Playwright artifacts to .gitignore

This provides a foundation for comprehensive E2E test coverage
while keeping the initial implementation simple and focused.
- Test clicking time increment to track time
- Test clicking again to stop tracking
- Test tracking multiple time increments
- Verify time summary updates correctly (15min per segment)
- Test editing task description via button
- Test editing task description with Enter key
- Test canceling edit with Escape key
- Test deleting task
- Test deleting task with tracked time
- Test creating task with default type (Task)
- Test creating task with Meeting type
- Test creating task with Review type
- Test changing task type when editing
- Test preserving task type after editing description
- Test creating multiple tasks with different types
- Test tasks persist after page reload
- Test tracked time persists after page reload
- Test multiple tasks persist after page reload
- Test task type persists after page reload

Skipped Phase 4 (date navigation) as DatePicker requires
responsive breakpoints not available in headless testing
- Test creating and tracking multiple tasks
- Test editing multiple tasks
- Test deleting task from list of multiple tasks
- Test tracking time across multiple tasks independently
- Test complex workflow combining create, edit, track, delete
- Test empty description validation
- Test whitespace-only description validation
- Test whitespace trimming
- Test preventing empty updates
- Test long descriptions
- Test special characters in descriptions
- Test unicode and emoji support
- Test rapid task creation
- Test toggling time increments multiple times
- Test edit then delete workflow
- Test data persistence across multiple reloads
Resolved conflicts in package.json by combining:
- E2E test scripts (test:e2e, test:e2e:ui, test:e2e:debug)
- Husky prepare script from master
- Playwright and Husky dependencies
Changed from filter-based selector to getByRole for better reliability:
- Use page.getByRole('button', { name: 'Delete task: ...' })
- Previously used .locator('.taskDelete').filter({ has: ... }) which
  incorrectly looked for child elements instead of the element itself

Fixes 6 failing E2E tests in CI
Previous fix used getByRole globally which could match multiple elements.
Now we:
1. Filter task rows by text to find the specific row
2. Then find the delete button within that row

This ensures we click the correct delete button even with multiple tasks.

Updated files:
- e2e/task-management.spec.ts (2 delete operations)
- e2e/multi-task.spec.ts (2 delete operations)
- e2e/validation.spec.ts (1 delete operation)
Added detailed console.log statements to diagnose why delete button
cannot be found in CI:

- Log task creation steps
- Log all task row content and structure
- Log all buttons with role='button' in each row
- Log their aria-labels and classes
- Log Task B row matching and content
- Log delete button visibility before click

This will help identify the exact issue in CI where we cannot run
Playwright locally due to environment restrictions.
Changed delete button selectors from getByRole('button', { name: '...' })
to locator('.taskDelete') to properly target MuiSvgIcon delete buttons.

The delete buttons are SVG icons with role="button" and correct aria-label,
but Playwright's getByRole doesn't reliably match them. Using the .taskDelete
class selector is more reliable.

Also removed debug logging from multi-task.spec.ts now that the issue is resolved.

Files modified:
- e2e/multi-task.spec.ts (2 delete operations, removed debug logs)
- e2e/task-management.spec.ts (2 delete operations)
- e2e/validation.spec.ts (1 delete operation)
Simplified the time increment selector from:
  .locator('.increment').first().filter({ has: locator('[aria-pressed="false"]') })
to:
  .locator('.increment').first()

The filter was incorrectly looking for a child element with aria-pressed="false",
but the .increment button itself has the aria-pressed attribute. This change makes
it consistent with the other time tracking tests that use the simpler selector.
Added comprehensive test that verifies:
- Tasks and time tracking persist across date changes
- Tasks are date-specific (not visible on other dates)
- Navigation between dates correctly restores tasks
- Page reload preserves tasks and time on the correct date

This test creates a task with logged time, navigates to the next day
to verify the task isn't visible there, navigates back to confirm it's
restored, then reloads the page to ensure persistence works correctly.
Changed from trying to find buttons by name ('Next day', 'Previous day')
to using position-based selectors. The DatePicker component shows three
buttons: [previous date] [current date] [next date], where the dates
are displayed as actual date strings (e.g., "November 15").

Using header button selectors with nth(0) for previous day and nth(2)
for next day to reliably navigate between dates.
@danielway danielway closed this Nov 16, 2025
@danielway danielway reopened this Nov 16, 2025
@danielway danielway merged commit 407303f into master Nov 16, 2025
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants