Skip to content

Commit 957acf0

Browse files
authored
Dockerized integration tests (#5967)
* add docker test setup * change docker image base
1 parent 33e74a8 commit 957acf0

File tree

8 files changed

+182
-1
lines changed

8 files changed

+182
-1
lines changed

docs/general/contributing.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,40 @@ This will fix Prettier and Eslint errors.
9999

100100
To run integrations with [Playwright](https://playwright.dev/), first run `yarn start` to run the examples website, then run `yarn playwright` in a separate session to open the Playwright test suite. Or alternatively, run just `yarn test:integration-local`.
101101

102+
### Running integration tests in Docker
103+
104+
If tests fail on CI but pass locally (often due to OS differences), you can run tests in a Docker container that replicates the same environment as CI.
105+
106+
**Prerequisites:** The project must be built first (same as running tests locally).
107+
108+
```text
109+
yarn test:integration-docker
110+
```
111+
112+
The script will automatically:
113+
114+
1. Start the development server (if not already running)
115+
2. Run tests inside a Docker container
116+
3. Stop the server when tests complete
117+
118+
You can also pass additional arguments to the test runner. For example, to run a specific test file:
119+
120+
```text
121+
yarn test:integration-docker playwright/integration/slate-react/selection.test.ts
122+
```
123+
124+
Or run a specific browser project:
125+
126+
```text
127+
yarn test:integration-docker --project=chromium
128+
```
129+
130+
You can combine arguments as well:
131+
132+
```text
133+
yarn test:integration-docker playwright/integration/examples/check-lists.test.ts --project chromium
134+
```
135+
102136
## Testing Input Methods
103137

104138
[Here's a helpful page](https://github.com/Microsoft/vscode/wiki/IME-Test) detailing how to test various input scenarios on Windows, Mac and Linux.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
"test:inspect": "yarn test --inspect-brk",
3434
"test:integration": "playwright install --with-deps && run-p -r serve playwright",
3535
"test:integration-local": "playwright install && run-p -r serve playwright",
36+
"test:integration-docker": "./playwright/docker/run-tests.sh",
3637
"test:mocha": "mocha --require ./config/babel/register.cjs ./packages/{slate,slate-history,slate-hyperscript}/test/**/*.{js,ts}",
3738
"test:jest": "jest --config jest.config.js",
3839
"tsc:examples": "tsc --project ./site/tsconfig.example.json",

playwright.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ const config: PlaywrightTestConfig = {
8080
/* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
8181
actionTimeout: 0,
8282
/* Base URL to use in actions like `await page.goto('/')`. */
83-
// baseURL: 'http://localhost:3000',
83+
// Can be overridden with PLAYWRIGHT_BASE_URL env var (used by Docker tests)
84+
baseURL: process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3000',
8485

8586
/* Collect trace if the first attempt fails. See https://playwright.dev/docs/trace-viewer */
8687
trace: 'retain-on-first-failure',

playwright/docker/Dockerfile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Use Node.js 22 base (Debian-based, similar to CI ubuntu-22.04)
2+
# Note: Can't use official Playwright image because Yarn PnP uses absolute paths
3+
# that break when the project is mounted at a different location in Docker
4+
FROM node:22-slim
5+
6+
# Install curl (for health checks) and socat (for localhost port forwarding)
7+
RUN apt-get update && \
8+
apt-get install -y curl socat && \
9+
apt-get clean && \
10+
rm -rf /var/lib/apt/lists/*
11+
12+
RUN corepack enable
13+
14+
WORKDIR /app
15+
16+
# Install globally to avoid Yarn PnP path resolution issues in container
17+
RUN npm install -g @playwright/[email protected]
18+
19+
RUN playwright install --with-deps
20+
21+
COPY entrypoint.sh /entrypoint.sh
22+
RUN chmod +x /entrypoint.sh
23+
24+
ENTRYPOINT ["/entrypoint.sh"]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
services:
2+
test-runner:
3+
build:
4+
context: .
5+
dockerfile: Dockerfile
6+
volumes:
7+
- ../..:/app:ro
8+
- ../../test-results:/app/test-results:rw
9+
environment:
10+
- CI=true
11+
- PLAYWRIGHT_BASE_URL=http://host.docker.internal:3000
12+
- NODE_PATH=/usr/local/lib/node_modules
13+
extra_hosts:
14+
- "host.docker.internal:host-gateway"
15+
- "localhost:host-gateway"
16+
stdin_open: false
17+
tty: false

playwright/docker/entrypoint.sh

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "=========================================="
5+
echo "Docker Integration Tests"
6+
echo "=========================================="
7+
8+
# Default to host.docker.internal if not overridden
9+
if [ -z "$PLAYWRIGHT_BASE_URL" ]; then
10+
PLAYWRIGHT_BASE_URL="http://host.docker.internal:3000"
11+
fi
12+
13+
echo "Waiting for development server on host..."
14+
15+
timeout=60
16+
elapsed=0
17+
while ! curl -s "$PLAYWRIGHT_BASE_URL" > /dev/null; do
18+
if [ $elapsed -ge $timeout ]; then
19+
echo "❌ Server did not start within ${timeout}s"
20+
exit 1
21+
fi
22+
sleep 1
23+
elapsed=$((elapsed + 1))
24+
done
25+
26+
echo "✓ Server is ready on host"
27+
28+
# Forward localhost:3000 to host for tests that use hardcoded localhost URLs
29+
echo "Setting up port forwarding from localhost:3000 to host..."
30+
socat TCP-LISTEN:3000,fork,reuseaddr TCP:host.docker.internal:3000 &
31+
SOCAT_PID=$!
32+
33+
sleep 1
34+
35+
cd /app/playwright/docker
36+
playwright test --config=playwright.config.docker.ts "$@"
37+
TEST_EXIT_CODE=$?
38+
39+
kill $SOCAT_PID 2>/dev/null || true
40+
41+
exit $TEST_EXIT_CODE
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import type { PlaywrightTestConfig } from '@playwright/test'
2+
import baseConfig from '../../playwright.config'
3+
4+
const config: PlaywrightTestConfig = {
5+
...baseConfig,
6+
testDir: '..',
7+
outputDir: '../../test-results/docker',
8+
}
9+
10+
export default config

playwright/docker/run-tests.sh

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/bin/bash
2+
3+
# Orchestrates running integration tests: starts dev server if needed, runs Docker tests, cleans up
4+
5+
set -e
6+
7+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8+
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
9+
10+
cd "$PROJECT_ROOT"
11+
12+
echo "=========================================="
13+
echo "Docker Integration Tests"
14+
echo "=========================================="
15+
16+
if curl -s http://localhost:3000 > /dev/null 2>&1; then
17+
echo "✓ Development server already running on port 3000"
18+
SERVER_STARTED_HERE=false
19+
else
20+
echo "Starting development server..."
21+
yarn serve > /dev/null 2>&1 &
22+
SERVER_PID=$!
23+
SERVER_STARTED_HERE=true
24+
25+
trap "echo 'Stopping server...'; kill $SERVER_PID 2>/dev/null || true" EXIT
26+
27+
echo "Waiting for server to be ready..."
28+
timeout=60
29+
elapsed=0
30+
while ! curl -s http://localhost:3000 > /dev/null 2>&1; do
31+
if [ $elapsed -ge $timeout ]; then
32+
echo "❌ Server did not start within ${timeout}s"
33+
exit 1
34+
fi
35+
sleep 1
36+
elapsed=$((elapsed + 1))
37+
done
38+
echo "✓ Server is ready"
39+
fi
40+
41+
echo "Running tests in Docker..."
42+
cd "$SCRIPT_DIR"
43+
44+
docker compose run --rm test-runner "$@"
45+
TEST_EXIT_CODE=$?
46+
47+
# Only stop server if we started it
48+
if [ "$SERVER_STARTED_HERE" = true ]; then
49+
echo "Stopping development server..."
50+
kill $SERVER_PID 2>/dev/null || true
51+
fi
52+
53+
exit $TEST_EXIT_CODE

0 commit comments

Comments
 (0)