Skip to content

Commit 2f160a5

Browse files
committed
playwright: auto-start a web server for the special URL localhost:5000
To make it easier to run the tests locally (or in the near future, in every PullRequest), let's add a minimal node.js script that serves the static webpages in as similar a manner to GitHub Pages as is needed for the tests to validate the site. This server will be started automatically when running with the environment variable PLAYWRIGHT_TEST_URL set to http://localhost:5000/. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 63fc16b commit 2f160a5

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

playwright.config.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,14 @@ module.exports = defineConfig({
7474
// },
7575
],
7676

77-
/* Run your local dev server before starting the tests */
78-
// webServer: {
79-
// command: 'npm run start',
80-
// url: 'http://127.0.0.1:3000',
81-
// reuseExistingServer: !process.env.CI,
82-
// },
77+
/* Run a local web server before starting the tests as needed */
78+
webServer:
79+
process.env.PLAYWRIGHT_TEST_URL !== 'http://localhost:5000/'
80+
? undefined
81+
: {
82+
command: 'node script/serve-public.js',
83+
url: process.env.PLAYWRIGHT_TEST_URL,
84+
reuseExistingServer: true,
85+
},
8386
});
8487

script/serve-public.js

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/usr/bin/env node
2+
3+
const http = require('http');
4+
const url = require('url');
5+
const fs = require('fs');
6+
const path = require('path');
7+
8+
const basePath = path.join(__dirname, '..', 'public');
9+
10+
const mimeTypes = {
11+
"html": "text/html",
12+
"jpeg": "image/jpeg",
13+
"jpg": "image/jpeg",
14+
"png": "image/png",
15+
"ico": "image/x-icon",
16+
"js": "text/javascript",
17+
"css": "text/css",
18+
"json": "application/json",
19+
'pf_filter': 'application/gzip',
20+
'pf_fragment': 'application/gzip',
21+
'pf_index': 'application/gzip',
22+
'pf_meta': 'application/gzip',
23+
'pagefind': 'application/gzip',
24+
};
25+
26+
const handler = (request, response) => {
27+
const pathname = url.parse(request.url).pathname;
28+
let filename = path.join(basePath, pathname === "/" ? "index.html" : pathname);
29+
30+
let stats = fs.statSync(filename, { throwIfNoEntry: false });
31+
if (!stats?.isFile() && !filename.match(/\.[A-Za-z0-9]{1,11}$/)) {
32+
filename += ".html";
33+
stats = fs.statSync(filename, { throwIfNoEntry: false });
34+
}
35+
try{
36+
if (!stats?.isFile()) throw new Error(`Not a file: ${filename}`);
37+
const fileStream = fs.createReadStream(filename);
38+
let mimeType = mimeTypes[path.extname(filename).split(".")[1]];
39+
if (!mimeType) throw new Error(`Could not get mime type for '${filename}'`)
40+
response.writeHead(200, {'Content-Type':mimeType});
41+
fileStream.pipe(response);
42+
} catch(e) {
43+
console.log(`Could not read ${filename}`);
44+
response.writeHead(404, {'Content-Type': 'text/plain'});
45+
response.write('404 Not Found\n');
46+
response.end();
47+
return;
48+
}
49+
};
50+
51+
const server = http.createServer(handler);
52+
53+
server.on("listening", () => {
54+
console.log(`Now listening on: http://localhost:${server.address().port}/`);
55+
});
56+
server.listen(5000);

0 commit comments

Comments
 (0)