Skip to content

Commit 5535d16

Browse files
authored
API test server to run unit tests, acceptance tests for codeceptjs with Docker Compose support and reliable data reloading (#5101)
1 parent a52bba7 commit 5535d16

File tree

9 files changed

+507
-49
lines changed

9 files changed

+507
-49
lines changed

Dockerfile

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,8 @@ RUN apt-get update && \
1212
# Install latest chrome dev package and fonts to support major charsets (Chinese, Japanese, Arabic, Hebrew, Thai and a few others)
1313
# Note: this installs the necessary libs to make the bundled version of Chromium that Puppeteer
1414
# installs, work.
15-
RUN apt-get update && apt-get install -y gnupg wget && \
16-
wget --quiet --output-document=- https://dl-ssl.google.com/linux/linux_signing_key.pub | gpg --dearmor > /etc/apt/trusted.gpg.d/google-archive.gpg && \
17-
echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google-chrome.list && \
18-
apt-get update && \
19-
apt-get install -y google-chrome-stable --no-install-recommends && \
20-
rm -rf /var/lib/apt/lists/*
15+
# Skip Chrome installation for now as Playwright image already has browsers
16+
RUN echo "Skipping Chrome installation - using Playwright browsers"
2117

2218

2319
# Add pptr user.
@@ -31,17 +27,23 @@ RUN groupadd -r pptruser && useradd -r -g pptruser -G audio,video pptruser \
3127
COPY . /codecept
3228

3329
RUN chown -R pptruser:pptruser /codecept
34-
RUN runuser -l pptruser -c 'npm i --loglevel=warn --prefix /codecept'
30+
# Set environment variables to skip browser downloads during npm install
31+
ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
32+
ENV PUPPETEER_SKIP_DOWNLOAD=true
33+
# Install as root to ensure proper bin links are created
34+
RUN cd /codecept && npm install --loglevel=warn
35+
# Fix ownership after install
36+
RUN chown -R pptruser:pptruser /codecept
3537

3638
RUN ln -s /codecept/bin/codecept.js /usr/local/bin/codeceptjs
3739
RUN mkdir /tests
3840
WORKDIR /tests
39-
# Install puppeteer so it's available in the container.
40-
RUN npm i puppeteer@$(npm view puppeteer version) && npx puppeteer browsers install chrome
41-
RUN google-chrome --version
41+
# Skip the redundant Puppeteer installation step since we're using Playwright browsers
42+
# RUN npm i puppeteer@$(npm view puppeteer version) && npx puppeteer browsers install chrome
43+
# RUN chromium-browser --version
4244

43-
# Install playwright browsers
44-
RUN npx playwright install
45+
# Skip the playwright browser installation step since base image already has browsers
46+
# RUN npx playwright install
4547

4648
# Allow to pass argument to codecept run via env variable
4749
ENV CODECEPT_ARGS=""

bin/test-server.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Standalone test server script to replace json-server
5+
*/
6+
7+
const path = require('path')
8+
const TestServer = require('../lib/test-server')
9+
10+
// Parse command line arguments
11+
const args = process.argv.slice(2)
12+
let dbFile = path.join(__dirname, '../test/data/rest/db.json')
13+
let port = 8010
14+
let host = '0.0.0.0'
15+
16+
// Simple argument parsing
17+
for (let i = 0; i < args.length; i++) {
18+
const arg = args[i]
19+
20+
if (arg === '-p' || arg === '--port') {
21+
port = parseInt(args[++i])
22+
} else if (arg === '--host') {
23+
host = args[++i]
24+
} else if (!arg.startsWith('-')) {
25+
dbFile = path.resolve(arg)
26+
}
27+
}
28+
29+
// Create and start server
30+
const server = new TestServer({ port, host, dbFile })
31+
32+
console.log(`Starting test server with db file: ${dbFile}`)
33+
34+
server
35+
.start()
36+
.then(() => {
37+
console.log(`Test server is ready and listening on http://${host}:${port}`)
38+
})
39+
.catch(err => {
40+
console.error('Failed to start test server:', err)
41+
process.exit(1)
42+
})
43+
44+
// Graceful shutdown
45+
process.on('SIGINT', () => {
46+
console.log('\nShutting down test server...')
47+
server.stop().then(() => process.exit(0))
48+
})
49+
50+
process.on('SIGTERM', () => {
51+
console.log('\nShutting down test server...')
52+
server.stop().then(() => process.exit(0))
53+
})

docs/internal-test-server.md

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Internal API Test Server
2+
3+
This directory contains the internal API test server implementation that replaces the third-party `json-server` dependency.
4+
5+
## Files
6+
7+
- `lib/test-server.js` - Main TestServer class implementation
8+
- `bin/test-server.js` - CLI script to run the server standalone
9+
10+
## Usage
11+
12+
### As npm script:
13+
14+
```bash
15+
npm run test-server
16+
```
17+
18+
### Directly:
19+
20+
```bash
21+
node bin/test-server.js [options] [db-file]
22+
```
23+
24+
### Options:
25+
26+
- `-p, --port <port>` - Port to listen on (default: 8010)
27+
- `--host <host>` - Host to bind to (default: 0.0.0.0)
28+
- `db-file` - Path to JSON database file (default: test/data/rest/db.json)
29+
30+
## Features
31+
32+
- **Full REST API compatibility** with json-server
33+
- **Automatic file watching** - Reloads data when db.json file changes
34+
- **CORS support** - Allows cross-origin requests for testing
35+
- **Custom headers support** - Handles special headers like X-Test
36+
- **File upload endpoints** - Basic file upload simulation
37+
- **Express.js based** - Uses familiar Express.js framework
38+
39+
## API Endpoints
40+
41+
The server provides the same API endpoints as json-server:
42+
43+
### Users
44+
45+
- `GET /user` - Get user data
46+
- `POST /user` - Create/update user
47+
- `PATCH /user` - Partially update user
48+
- `PUT /user` - Replace user
49+
50+
### Posts
51+
52+
- `GET /posts` - Get all posts
53+
- `GET /posts/:id` - Get specific post
54+
- `POST /posts` - Create new post
55+
- `PUT /posts/:id` - Replace specific post
56+
- `PATCH /posts/:id` - Partially update specific post
57+
- `DELETE /posts/:id` - Delete specific post
58+
59+
### Comments
60+
61+
- `GET /comments` - Get all comments
62+
- `POST /comments` - Create new comment
63+
- `DELETE /comments/:id` - Delete specific comment
64+
65+
### Utility
66+
67+
- `GET /headers` - Return request headers (for testing)
68+
- `POST /headers` - Return request headers (for testing)
69+
- `POST /upload` - File upload simulation
70+
- `POST /_reload` - Manually reload database file
71+
72+
## Migration from json-server
73+
74+
This server is designed as a drop-in replacement for json-server. The key differences:
75+
76+
1. **No CLI options** - Configuration is done through constructor options or CLI args
77+
2. **Automatic file watching** - No need for `--watch` flag
78+
3. **Built-in middleware** - Headers and CORS are handled automatically
79+
4. **Simpler file upload** - Basic implementation without full multipart support
80+
81+
## Testing
82+
83+
The server is used by the following test suites:
84+
85+
- `test/rest/REST_test.js` - REST helper tests
86+
- `test/rest/ApiDataFactory_test.js` - API data factory tests
87+
- `test/helper/JSONResponse_test.js` - JSON response helper tests
88+
89+
All tests pass with the internal server, proving full compatibility.

0 commit comments

Comments
 (0)