Skip to content

Testing

daarunia edited this page Jul 11, 2026 · 1 revision

Testing

NexTask uses Playwright to run true end-to-end tests: they launch the real Electron application, drive the UI, and assert on what the user sees. Tests live under tests/.

Running the tests

npm test          # run all e2e tests (headless)
npm run test:ui   # run in Playwright's interactive UI mode

How it's wired

Configuration — playwright.config.ts

Option Value Why
testDir ./tests/e2e Where the specs live
globalSetup ./tests/global-setup.ts Compiles the Electron main process once before the run
timeout 100000 ms E2E flows (launching Electron, DnD) are slow
retries 1 One retry on failure
workers 1 A single worker — all specs share one Electron instance and one SQLite DB
headless true No visible window in CI
Artifacts trace on first retry, screenshot on failure, video retained on failure Debugging aid

Global setup — tests/global-setup.ts

Before any spec runs, it calls compileMain() to transpile the main process (build.js + tsc). If compilation fails, the whole run aborts.

Fixtures — tests/fixtures/test.ts

The custom Playwright fixture set:

  • vitePort (worker-scoped): starts a Vite renderer server and exposes its port.
  • electronApp (worker-scoped, auto): launches Electron with electronArgs(vitePort, ['--test']). The --test flag makes the app hide its window and skip DevTools (IS_TEST in src/main/constants.ts).
  • page: the app's first window.
  • header / taskBoard: page objects (see below).

Because the Electron app and DB are shared across specs (single worker, no reset between runs), tests are written to be resilient:

  • they generate unique task titles (e.g. Tâche créée ${Date.now()}) to avoid collisions,
  • they clean up after themselves (archiving the tasks they created),
  • helpers like orderedTitlesAmong / orderedStagesAmong assert only on the test's own items, ignoring any pre-existing/seeded data.

Page objects — tests/components

Page objects encapsulate selectors and gestures, keeping specs readable. Selectors rely on data-testid attributes present in the components.

TaskBoard.ts

The richest page object. Covers the Kanban board and task dialog:

  • Task dialog: openCreateDialog, openEditDialog, fillAndSave, createTask, selectVersion.
  • Cards: taskCard, archiveTask, columnTaskTitles, orderedTitlesAmong.
  • Stages: addStage, renameStage, deleteStage, openStageMenu, stageTitles, orderedStagesAmong.
  • Drag-and-drop: low-level performDrag, plus dragTaskOntoCard, dragTaskToColumnEnd, dragStageBefore. These are carefully written to work with vuedraggable's fallback mode (grabbing near the card's edge, crossing the fallbackTolerance threshold, then approaching the target in steps).

Header.ts

Wraps the theme toggle and palette picker interactions.

Test suites — tests/e2e

Spec Covers
header/theme.spec.ts Light/dark mode toggle
header/palette.spec.ts Primary-color palette selection
stage/stage.spec.ts Creating, renaming, reordering and deleting columns
task/task.spec.ts Task dialog: create, defaults, cancel, edit, archive
task/task-dnd.spec.ts Drag-and-drop of tasks (within and across columns)
task/task-persistence.spec.ts Changes survive (persistence through the API/DB)

Example (from task/task.spec.ts)

test('crée une nouvelle tâche qui apparaît dans la colonne', async ({ taskBoard }) => {
  const title = uniqueTitle('Tâche créée')

  await taskBoard.createTask('A faire', {
    title,
    description: 'Description de test',
    version: '1.4.5',
  })

  const card = taskBoard.taskCard(title)
  await expect(card).toBeVisible()

  await taskBoard.archiveTask(title) // cleanup
})

Writing new tests — tips

  • Prefer data-testid selectors; add one to the component if it's missing.
  • Generate unique identifiers for any data you create, and clean up afterwards — the DB is shared.
  • Reuse the page objects rather than sprinkling raw locators in specs.
  • For drag-and-drop, reuse TaskBoard's performDrag-based helpers instead of hand-rolling mouse moves.

Related pages

Clone this wiki locally