-
Notifications
You must be signed in to change notification settings - Fork 0
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/.
npm test # run all e2e tests (headless)
npm run test:ui # run in Playwright's interactive UI mode| 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 |
Before any spec runs, it calls compileMain() to transpile the main process (build.js + tsc). If compilation fails, the whole run aborts.
The custom Playwright fixture set:
-
vitePort(worker-scoped): starts a Vite renderer server and exposes its port. -
electronApp(worker-scoped, auto): launches Electron withelectronArgs(vitePort, ['--test']). The--testflag makes the app hide its window and skip DevTools (IS_TESTinsrc/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/orderedStagesAmongassert only on the test's own items, ignoring any pre-existing/seeded data.
Page objects encapsulate selectors and gestures, keeping specs readable. Selectors rely on data-testid attributes present in the components.
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, plusdragTaskOntoCard,dragTaskToColumnEnd,dragStageBefore. These are carefully written to work withvuedraggable's fallback mode (grabbing near the card's edge, crossing thefallbackTolerancethreshold, then approaching the target in steps).
Wraps the theme toggle and palette picker interactions.
| 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) |
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
})- Prefer
data-testidselectors; 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'sperformDrag-based helpers instead of hand-rolling mouse moves.
NexTask — a modern cross-platform desktop todo app · Electron · Vue 3 · Prisma · TailwindCSS Repository · Licensed under Apache-2.0
Getting Started
Understanding the App
Deep Dives
Workflow