How to Run End-to-End Tests for OpenWork: Complete Setup Guide
Run pnpm test:e2e after starting the local Den server with pnpm dev:den and launching the UI with pnpm dev or pnpm dev:headless-web to execute the full desktop-first test suite against the OpenWork codebase.
OpenWork by different-ai is an open-source desktop application that validates user workflows through comprehensive end-to-end (E2E) testing across its Electron interface and local control plane. When you run end-to-end tests for OpenWork, you are verifying the integration between the desktop UI, the Den API server, and supporting infrastructure like MySQL and Redis. The test suite lives in evals/specs/**/*.e2e.test.ts and leverages the custom @openwork/testkit framework built on Vitest.
Understanding the E2E Architecture
OpenWork’s testing strategy validates the complete user journey from UI interaction through backend persistence. The architecture consists of three coordinated components:
- Den (Local Server): The API gateway and authentication layer running on port 8790, defined in the
dev:denscript inpackage.json(lines 71-76). This process automatically spawns Docker containers for MySQL and Redis. - User Interface: Either the full Electron desktop app (
apps/@openwork/desktop) or the headless web version (scripts/dev-headless-web.ts) running on port 3005. The testkit uses Chrome DevTools Protocol (CDP) to drive clicks, navigation, and authentication flows. - Test Runner: Vitest executing the
@openwork/testkitrunner, invoked via thetest:e2escript inpackage.json(lines 108-110), which discovers all*.e2e.test.tsfiles underevals/specs/.
A typical spec file like evals/specs/desktop-server-credential-coherence.test.ts declaratively sequences steps: launch UI → sign in → create workspace → assert UI state, while automatically tearing down processes after completion.
Prerequisites
Before executing tests, ensure your environment meets these requirements:
- Node.js and pnpm installed globally
- Docker Desktop running (required for MySQL and Redis containers spawned by
pnpm dev:den) - Environment variables configured (the
pnpm dev:denscript automatically setsDATABASE_URLandDEN_DB_ENCRYPTION_KEY)
Step-by-Step Test Execution
Step 1: Install Dependencies
Install all monorepo dependencies from the project root:
pnpm install
Step 2: Start the Den Server
Launch the local Den control plane, which initializes the database and cache layers:
pnpm dev:den
This command spins up MySQL and Redis via Docker Compose and starts the Den API gateway on port 8790 and the web UI on port 3005.
Step 3: Launch the User Interface
Choose your test target environment. For realistic desktop behavior:
pnpm dev
For faster execution without Electron overhead, use the headless web launcher (which writes connection details to tmp/dev-headless-web.json):
pnpm dev:headless-web
Step 4: Execute the Test Suite
With Den and the UI running, trigger the Vitest runner:
pnpm test:e2e
The @openwork/testkit framework automatically discovers all evals/specs/**/*.e2e.test.ts files, orchestrates the browser via CDP, and reports results in the console.
Running Individual Test Files
To debug a specific scenario without executing the entire suite, pass the file path directly:
pnpm test:e2e evals/specs/desktop-server-credential-coherence.test.ts
This approach loads only the specified spec against the running Den and UI instances, producing targeted output and screenshots in tmp/ on failure.
Troubleshooting Common Issues
| Issue | Root Cause | Solution |
|---|---|---|
| Port conflicts | Another process occupies the CDP or Vite ports. | Export OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=0 PORT=0 before running pnpm dev to enable dynamic port allocation. |
| Missing Docker containers | MySQL or Redis failed to start. | Verify Docker Desktop is running, then execute pnpm dev:den:mysql to manually trigger the Docker Compose stack. |
| Stale profile locks | Previous dev sessions left lock files. | Delete the lock file referenced in the startup banner ([openwork] dev profile=…) or restart with the --replace flag. |
Summary
- OpenWork E2E tests verify the full stack from Electron UI through the Den backend using Vitest and
@openwork/testkit. - Test specifications reside in
evals/specs/**/*.e2e.test.tsand follow a declarative step-based format. - Execution requires three terminals: one for
pnpm dev:den(backend), one forpnpm devorpnpm dev:headless-web(frontend), and one forpnpm test:e2e(runner). - Configuration details for all scripts are defined in
package.json, specifically lines 71-76 for the Den server and lines 108-110 for the test command. - Debugging artifacts including screenshots and connection logs are written to the
tmp/directory.
Frequently Asked Questions
What test framework does OpenWork use for E2E testing?
OpenWork uses a custom framework called @openwork/testkit built on top of Vitest. This framework manages process orchestration, CDP-based browser control, and automatic teardown of the Electron and Den processes between test runs.
Can I run a single E2E test file instead of the entire suite?
Yes. Append the specific file path to the pnpm test:e2e command, such as pnpm test:e2e evals/specs/desktop-server-credential-coherence.test.ts. This executes only that spec against the currently running Den server and UI instance.
Why do OpenWork E2E tests require Docker to be running?
The Den control plane (started via pnpm dev:den) orchestrates MySQL and Redis services using Docker Compose. These databases persist organization data, authentication states, and workspace configurations that the E2E tests validate through the UI layer.
How do I resolve port conflicts when running OpenWork E2E tests?
Export the environment variables OPENWORK_ELECTRON_REMOTE_DEBUG_PORT=0 and PORT=0 before launching the dev servers. This instructs the Electron and Vite processes to select available random ports instead of defaulting to fixed ports that may be occupied.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →