From 5ad892a1a56c74d5676d782506564b2270e3b065 Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Tue, 3 Sep 2024 19:46:29 +0300 Subject: [PATCH] test: refactor --- .cspell.json | 3 +- examples/app/connect/README.md | 23 ++ examples/app/connect/app.js | 6 + examples/app/connect/webpack.config.js | 14 ++ examples/app/hono/README.md | 23 ++ examples/app/hono/app.js | 6 + examples/app/hono/ssl/localhost-cert.pem | 19 ++ examples/app/hono/ssl/localhost-privkey.pem | 28 +++ examples/app/hono/webpack.config.js | 55 +++++ examples/server/http2/README.md | 22 ++ examples/server/http2/app.js | 6 + examples/server/http2/webpack.config.js | 16 ++ examples/util.js | 16 +- .../__snapshots__/app.test.js.snap.webpack5 | 110 ++++----- test/e2e/app.test.js | 225 +++++++++++------- test/fixtures/ssl/localhost-cert.pem | 19 ++ test/fixtures/ssl/localhost-privkey.pem | 28 +++ 17 files changed, 474 insertions(+), 145 deletions(-) create mode 100644 examples/app/connect/README.md create mode 100644 examples/app/connect/app.js create mode 100644 examples/app/connect/webpack.config.js create mode 100644 examples/app/hono/README.md create mode 100644 examples/app/hono/app.js create mode 100644 examples/app/hono/ssl/localhost-cert.pem create mode 100644 examples/app/hono/ssl/localhost-privkey.pem create mode 100644 examples/app/hono/webpack.config.js create mode 100644 examples/server/http2/README.md create mode 100644 examples/server/http2/app.js create mode 100644 examples/server/http2/webpack.config.js create mode 100644 test/fixtures/ssl/localhost-cert.pem create mode 100644 test/fixtures/ssl/localhost-privkey.pem diff --git a/.cspell.json b/.cspell.json index 1ad85836e5..75ccb46d8d 100644 --- a/.cspell.json +++ b/.cspell.json @@ -68,7 +68,8 @@ "noselect", "commitlint", "eslintcache", - "hono" + "hono", + "privkey" ], "ignorePaths": [ "CHANGELOG.md", diff --git a/examples/app/connect/README.md b/examples/app/connect/README.md new file mode 100644 index 0000000000..b2074b1718 --- /dev/null +++ b/examples/app/connect/README.md @@ -0,0 +1,23 @@ +# `app` Option + +Serve using [`connect`](https://github.com/senchalabs/connect) as an application. + +**webpack.config.js** + +```js +const connect = require("connect"); + +module.exports = { + // ... + devServer: { + server: { + app: () => connect(), + }, + }, +}; +``` + +## What Should Happen + +1. The script should open `https://localhost:8080/` in your default browser. +2. You should see the text on the page itself change to read `Success!`. diff --git a/examples/app/connect/app.js b/examples/app/connect/app.js new file mode 100644 index 0000000000..51cf4a396b --- /dev/null +++ b/examples/app/connect/app.js @@ -0,0 +1,6 @@ +"use strict"; + +const target = document.querySelector("#target"); + +target.classList.add("pass"); +target.innerHTML = "Success!"; diff --git a/examples/app/connect/webpack.config.js b/examples/app/connect/webpack.config.js new file mode 100644 index 0000000000..0b7dd7bc23 --- /dev/null +++ b/examples/app/connect/webpack.config.js @@ -0,0 +1,14 @@ +"use strict"; + +// our setup function adds behind-the-scenes bits to the config that all of our +// examples need +const connect = require("connect"); +const { setup } = require("../../util"); + +module.exports = setup({ + context: __dirname, + entry: "./app.js", + devServer: { + app: () => connect(), + }, +}); diff --git a/examples/app/hono/README.md b/examples/app/hono/README.md new file mode 100644 index 0000000000..54b9cbe199 --- /dev/null +++ b/examples/app/hono/README.md @@ -0,0 +1,23 @@ +# `app` Option + +Serve using [`hono`](https://github.com/honojs/hono) as an application. + +**webpack.config.js** + +```js +const connect = require("connect"); + +module.exports = { + // ... + devServer: { + server: { + app: () => connect(), + }, + }, +}; +``` + +## What Should Happen + +1. The script should open `https://localhost:8080/` in your default browser. +2. You should see the text on the page itself change to read `Success!`. diff --git a/examples/app/hono/app.js b/examples/app/hono/app.js new file mode 100644 index 0000000000..51cf4a396b --- /dev/null +++ b/examples/app/hono/app.js @@ -0,0 +1,6 @@ +"use strict"; + +const target = document.querySelector("#target"); + +target.classList.add("pass"); +target.innerHTML = "Success!"; diff --git a/examples/app/hono/ssl/localhost-cert.pem b/examples/app/hono/ssl/localhost-cert.pem new file mode 100644 index 0000000000..c8453042dc --- /dev/null +++ b/examples/app/hono/ssl/localhost-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIUevWiuCfenWuq9KyC8aQ/tc1Io14wDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDQyNDE2MDYyMloXDTI0MDUy +NDE2MDYyMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA1v/lb9u9WkqkF7zjIKe2R+b4S0sQnWIfBFZ0ggtaOL0a +ntud/EuaGQgLtJgSwO2M2xIqKx+yoLhoM+273EJe0KmfJMxYNAkhwP9h6vrKnaQJ +mpAhoalfEGyCrnHHMKISAAn4Rlc8NXnULoFhHzNm8bdqvP33rCmsJ+tNYC5kwzyt +HvRNFyg9BOUfACiPW17opFH0rao3IfZrQ6yRbknef1pX1x2pbDAH14rCT/vXaTs6 +VGuqLE/wRsSt+7nMHy/PmXxMyb4G4/UflYtnKfmXpDRw+TDEGzvTZedtoOz+rrJC +e989R9qYGrlPfyfZbI+O348FV66I+jcD+/EUQs+HkwIDAQABo1MwUTAdBgNVHQ4E +FgQU6bk4LSwtVQEt7V/ev+Zj270zdAkwHwYDVR0jBBgwFoAU6bk4LSwtVQEt7V/e +v+Zj270zdAkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAUBgo +E3CZrrc/MaadFg1meNk+eKACmTsIa5cT6zi7MsvoKakXEd4bGd+iLifUzlAa1ygj +dQppfprb5t68I7oO9/lkh2DfKrXxW/RpdhB05KslUd8q/3XY5kyao5quzeiVoMHR +u+XYjoy2mTwdUC2uzFy6rkHsAkJy2vJJoDdlNsrKn6AZmh+voHHKrAtOL4gnanQV +wR1u8eBVfk2MKIl2pNSCA4bD16uZyp3+oqq097BEoVa1pR+l8nwbsh/YfALifq/d +P3yiN5+EqgiOIF9b8PZORe+Ry1O7uvPnU2ZRkVWPJ1S17Ms0lnr7IY3qjSBTuK66 +5uYi7ojrb5Vf0UL5oQ== +-----END CERTIFICATE----- diff --git a/examples/app/hono/ssl/localhost-privkey.pem b/examples/app/hono/ssl/localhost-privkey.pem new file mode 100644 index 0000000000..c260882984 --- /dev/null +++ b/examples/app/hono/ssl/localhost-privkey.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQDW/+Vv271aSqQX +vOMgp7ZH5vhLSxCdYh8EVnSCC1o4vRqe2538S5oZCAu0mBLA7YzbEiorH7KguGgz +7bvcQl7QqZ8kzFg0CSHA/2Hq+sqdpAmakCGhqV8QbIKucccwohIACfhGVzw1edQu +gWEfM2bxt2q8/fesKawn601gLmTDPK0e9E0XKD0E5R8AKI9bXuikUfStqjch9mtD +rJFuSd5/WlfXHalsMAfXisJP+9dpOzpUa6osT/BGxK37ucwfL8+ZfEzJvgbj9R+V +i2cp+ZekNHD5MMQbO9Nl522g7P6uskJ73z1H2pgauU9/J9lsj47fjwVXroj6NwP7 +8RRCz4eTAgMBAAECggEAA+zbFv43iEj5kvdfXC7DrK9iVBmUPZNXhqA/c0paxNNr +A4B182+76f4UHKF0IjKUEkHUJEJpY/bJ7DzIY76QdZXLMoRKjfSmuZvQAVa/0T33 +8Or1ujpZ4nZgsmegX9ptorOL5VjdYAqP3aN+DvBEzl/vYnDujyWZn4bzvDBMpaXS +39qW1MkcZ8UiP1fRad76+S57WnieBV+NRHYEAiDdMFKXLuw/igX/xOSZgq5Jh3I2 +hLS49S41dN1P9l9H2bPMw0CthNvMPPaemwKHz+84hSS+P4VJOWJzlGnXEdIFuqBR +GFBESQzcemfS9DDB22Yt06YujBCbwTVVAxj73lnKkQKBgQDvYXK36J9y/NphDAWi +Cwti5oE3eSfV0YazQwm+rRwC64wbpBFAm9ujwjUmaYBg75lBLF5nOOe8s1n95g5I +tLfFb+zuZh8NNLjhfNE9/SNmRnnMvbcaDHeIE2RMAz+PuLN/gFLmsVIwK2X1LRC2 +0vHjw9Yzh6JLiOajAchzhZiCEQKBgQDl7R6Wfggo8myETA8Uv5tWot3IcquRkEl/ +TRCyao2/79rAGexS7piwD7FPdSDOk1zfZFYUOMzyMjj60sGcPRPqRX6D0usEODLQ +TwsTJSCNgPnIOkqKkccwtqlTimbRIrPUSQfFPj56RzKKWdrJ/P3LPRjzkK7i3vLV +EGlAENaLYwKBgHKSOnzpWr+HY+IFBgErthRs7LWnSDifYxATauuXIQwIvvNP0G4S +6snzHss2vZonszstSDWxV8DKOq052eZUkIxv6H+l4wDIFiDeQ6uep73Ax3UF7EgM +ZX18gombGGXqagcBXSxK/GJPsynomtJWHi38Ql5BcZ0jdffY157q9zZxAoGAPZtD +Tt+GIDKUkP4wLEcKwDPzaPoQrngSuWFUz/ls8bi6zC4l/DKiBsqtn7Sqja8+ezzP +M6vkfiCm084UwmA7LdJhC8E/52mHc/k55m9UQZYFV3kG8AoPbSYESLYUxoSd2ouW +4WrEIs9g42EgFm8LMaG1Rc3GjlNejWhQSzI3yjECf3v7VoAcUwVfuVkwbm9W24vR +neFTF8QBl//fxIdxZwoj5SrSgMOjmZ3pXA/ZbFJ0pB4Rh5dmKTYqdpfXsOTiBuwB +XlqPVpN8UZEl3edpufLDyPldNej/9kEAkK5FS3YVyIQEg75739bCTlfzzCX1HdMx +q98XYm/n5LWYFezsAt0= +-----END PRIVATE KEY----- diff --git a/examples/app/hono/webpack.config.js b/examples/app/hono/webpack.config.js new file mode 100644 index 0000000000..cc11a8ce46 --- /dev/null +++ b/examples/app/hono/webpack.config.js @@ -0,0 +1,55 @@ +"use strict"; + +const wdm = require("webpack-dev-middleware"); +const { Hono } = require("hono"); +const { serve } = require("@hono/node-server"); +// eslint-disable-next-line import/extensions, import/no-unresolved +const { serveStatic } = require("@hono/node-server/serve-static"); +const { setup } = require("../../util"); + +// our setup function adds behind-the-scenes bits to the config that all of our +// examples need +module.exports = setup({ + context: __dirname, + entry: "./app.js", + devServer: { + // WARNING: + // + // You always need to set up middlewares which you required for your app, + // built-in middlewares (like `history-api-fallback`/etc) doesn't work by default with `hono` + setupMiddlewares: (_, devServer) => [ + { + name: "webpack-dev-middleware", + middleware: wdm.honoWrapper(devServer.compiler), + }, + { + name: "static", + path: "/.assets/*", + middleware: serveStatic({ + root: "../../.assets", + rewriteRequestPath: (item) => item.replace(/^\/\.assets\//, "/"), + }), + }, + ], + app: () => new Hono(), + server: (_, app) => + serve({ + fetch: app.fetch, + // + // Uncomment for `https` + // createServer: require('node:https').createServer, + // serverOptions: { + // key: fs.readFileSync("./ssl/localhost-privkey.pem"), + // cert: fs.readFileSync("./ssl/localhost-cert.pem"), + // }, + // + // Uncomment for `http2` + // createServer: require("node:http2").createSecureServer, + // serverOptions: { + // allowHTTP1: true, + // key: require("fs").readFileSync("./ssl/localhost-privkey.pem"), + // cert: require("fs").readFileSync("./ssl/localhost-cert.pem"), + // }, + }), + }, +}); diff --git a/examples/server/http2/README.md b/examples/server/http2/README.md new file mode 100644 index 0000000000..fd2ae94430 --- /dev/null +++ b/examples/server/http2/README.md @@ -0,0 +1,22 @@ +# HTTP2 server + +**webpack.config.js** + +```js +const connect = require("connect"); + +module.exports = { + // ... + devServer: { + server: { + server: "http2", + app: () => connect(), + }, + }, +}; +``` + +## What Should Happen + +1. The script should open `https://localhost:8080/` in your default browser. +2. You should see the text on the page itself change to read `Success!`. diff --git a/examples/server/http2/app.js b/examples/server/http2/app.js new file mode 100644 index 0000000000..51cf4a396b --- /dev/null +++ b/examples/server/http2/app.js @@ -0,0 +1,6 @@ +"use strict"; + +const target = document.querySelector("#target"); + +target.classList.add("pass"); +target.innerHTML = "Success!"; diff --git a/examples/server/http2/webpack.config.js b/examples/server/http2/webpack.config.js new file mode 100644 index 0000000000..4c29be511c --- /dev/null +++ b/examples/server/http2/webpack.config.js @@ -0,0 +1,16 @@ +"use strict"; + +// our setup function adds behind-the-scenes bits to the config that all of our +// examples need +const connect = require("connect"); +const { setup } = require("../../util"); + +module.exports = setup({ + context: __dirname, + entry: "./app.js", + devServer: { + server: "http2", + // Only `connect` supports `http2` + app: () => connect(), + }, +}); diff --git a/examples/util.js b/examples/util.js index d6f139e270..633939d890 100644 --- a/examples/util.js +++ b/examples/util.js @@ -4,6 +4,7 @@ const path = require("path"); const fs = require("graceful-fs"); +const mime = require("mime"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const { marked } = require("marked"); @@ -25,9 +26,18 @@ module.exports = { const result = { ...defaults, ...config }; const onBeforeSetupMiddleware = ({ app }) => { - app.get("/.assets/*", (req, res) => { - const filename = path.join(__dirname, "/", req.path); - res.sendFile(filename); + app.use("/.assets/", (req, res, next) => { + if (req.method !== "GET" && req.method !== "HEAD") { + next(); + return; + } + + res.setHeader("Content-Type", mime.lookup(req.url)); + + const filename = path.join(__dirname, "/.assets/", req.url); + const stream = fs.createReadStream(filename); + + stream.pipe(res); }); }; const renderer = new marked.Renderer(); diff --git a/test/e2e/__snapshots__/app.test.js.snap.webpack5 b/test/e2e/__snapshots__/app.test.js.snap.webpack5 index cc58d46e1c..182d9ce3f3 100644 --- a/test/e2e/__snapshots__/app.test.js.snap.webpack5 +++ b/test/e2e/__snapshots__/app.test.js.snap.webpack5 @@ -28,7 +28,7 @@ exports[`app option should work using "connect (async)" application and "http" s " `; -exports[`app option should work using "connect (async)" application and "http2" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -36,11 +36,11 @@ exports[`app option should work using "connect (async)" application and "http2" ] `; -exports[`app option should work using "connect (async)" application and "http2" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "connect (async)" application and "http2" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "connect (async)" application and "http2" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response text 1`] = ` " @@ -56,7 +56,7 @@ exports[`app option should work using "connect (async)" application and "http2" " `; -exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -64,11 +64,11 @@ exports[`app option should work using "connect (async)" application and "https" ] `; -exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "connect (async)" application and "https" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): response text 1`] = ` " @@ -84,7 +84,7 @@ exports[`app option should work using "connect (async)" application and "https" " `; -exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -92,11 +92,11 @@ exports[`app option should work using "connect (async)" application and "spdy" s ] `; -exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "connect (async)" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response text 1`] = ` " @@ -112,7 +112,7 @@ exports[`app option should work using "connect (async)" application and "spdy" s " `; -exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -120,11 +120,11 @@ exports[`app option should work using "connect" application and "http" server sh ] `; -exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "connect" application and "http" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` " @@ -140,7 +140,7 @@ exports[`app option should work using "connect" application and "http" server sh " `; -exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -148,11 +148,11 @@ exports[`app option should work using "connect" application and "http2" server s ] `; -exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "connect" application and "http2" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response text 1`] = ` " @@ -168,7 +168,7 @@ exports[`app option should work using "connect" application and "http2" server s " `; -exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -176,11 +176,11 @@ exports[`app option should work using "connect" application and "https" server s ] `; -exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "connect" application and "https" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response text 1`] = ` " @@ -196,7 +196,7 @@ exports[`app option should work using "connect" application and "https" server s " `; -exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -204,11 +204,11 @@ exports[`app option should work using "connect" application and "spdy" server sh ] `; -exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "connect" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` " @@ -224,7 +224,7 @@ exports[`app option should work using "connect" application and "spdy" server sh " `; -exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "hono" application and "[object Object]" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -232,11 +232,11 @@ exports[`app option should work using "express" application and "http" server sh ] `; -exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "hono" application and "[object Object]" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "hono" application and "[object Object]" server should handle GET request to index route (/): response status 1`] = `200`; -exports[`app option should work using "express" application and "http" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "hono" application and "[object Object]" server should handle GET request to index route (/): response text 1`] = ` " @@ -252,7 +252,7 @@ exports[`app option should work using "express" application and "http" server sh " `; -exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): console messages 1`] = ` +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): console messages 1`] = ` [ "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", "[HMR] Waiting for update signal from WDS...", @@ -260,11 +260,23 @@ exports[`app option should work using "express" application and "https" server s ] `; -exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): page errors 1`] = `[]`; +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): console messages 2`] = ` +[ + "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", + "[HMR] Waiting for update signal from WDS...", + "Hey.", +] +`; -exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response status 1`] = `200`; +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): page errors 1`] = `[]`; -exports[`app option should work using "express" application and "https" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): page errors 2`] = `[]`; + +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): response status 1`] = `200`; + +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): response status 2`] = `200`; + +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): response text 1`] = ` " @@ -280,19 +292,7 @@ exports[`app option should work using "express" application and "https" server s " `; -exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): console messages 1`] = ` -[ - "[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.", - "[HMR] Waiting for update signal from WDS...", - "Hey.", -] -`; - -exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): page errors 1`] = `[]`; - -exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response status 1`] = `200`; - -exports[`app option should work using "express" application and "spdy" server should handle GET request to index route (/): response text 1`] = ` +exports[`app option should work using "hono" application and "custom server" server should handle GET request to index route (/): response text 2`] = ` " @@ -307,15 +307,3 @@ exports[`app option should work using "express" application and "spdy" server sh " `; - -exports[`app option should work using "hono" application and "(options, app) => require("@hono/node-server").serve(app)" server should handle GET request to index route (/): console messages 1`] = ` -[ - "Failed to load resource: the server responded with a status of 500 (Internal Server Error)", -] -`; - -exports[`app option should work using "hono" application and "(options, app) => require("@hono/node-server").serve(app)" server should handle GET request to index route (/): page errors 1`] = `[]`; - -exports[`app option should work using "hono" application and "(options, app) => require("@hono/node-server").serve(app)" server should handle GET request to index route (/): response status 1`] = `500`; - -exports[`app option should work using "hono" application and "(options, app) => require("@hono/node-server").serve(app)" server should handle GET request to index route (/): response text 1`] = `"Internal Server Error"`; diff --git a/test/e2e/app.test.js b/test/e2e/app.test.js index f6ed79640f..8210b2b76e 100644 --- a/test/e2e/app.test.js +++ b/test/e2e/app.test.js @@ -1,7 +1,9 @@ "use strict"; +const fs = require("fs"); const path = require("path"); const webpack = require("webpack"); +const wdm = require("webpack-dev-middleware"); const Server = require("../../lib/Server"); const config = require("../fixtures/client-config/webpack.config"); const runBrowser = require("../helpers/run-browser"); @@ -13,96 +15,159 @@ const staticDirectory = path.resolve( ); const apps = [ - ["express", () => require("express")()], - ["connect", () => require("connect")()], - ["connect (async)", () => require("connect")()], - // ["hono", () => new (require("hono").Hono)()], + ["express", () => require("express")(), "http"], + ["express", () => require("express")(), "https"], + ["express", () => require("express")(), "spdy"], + ["connect", () => require("connect")(), "http"], + ["connect", () => require("connect")(), "https"], + ["connect", () => require("connect")(), "spdy"], + ["connect", () => require("connect")(), "http2"], + ["connect (async)", () => require("connect")(), "http"], + [ + "hono", + () => new (require("hono").Hono)(), + (_, app) => require("@hono/node-server").serve({ fetch: app.fetch }), + (_, devServer) => [ + { + name: "webpack-dev-middleware", + middleware: wdm.honoWrapper(devServer.compiler), + }, + ], + ], + [ + "hono", + () => new (require("hono").Hono)(), + (_, app) => + require("@hono/node-server").serve({ + fetch: app.fetch, + createServer: require("node:https").createServer, + serverOptions: { + key: fs.readFileSync( + path.resolve(__dirname, "../fixtures/ssl/localhost-privkey.pem"), + ), + cert: fs.readFileSync( + path.resolve(__dirname, "../fixtures/ssl/localhost-cert.pem"), + ), + }, + }), + (_, devServer) => [ + { + name: "webpack-dev-middleware", + middleware: wdm.honoWrapper(devServer.compiler), + }, + ], + ], + [ + "hono", + () => new (require("hono").Hono)(), + { + type: (options, app) => + require("@hono/node-server").serve({ + fetch: app.fetch, + createServer: require("node:http2").createSecureServer, + serverOptions: options, + }), + options: { + allowHTTP1: true, + key: fs.readFileSync( + path.resolve(__dirname, "../fixtures/ssl/localhost-privkey.pem"), + ), + cert: fs.readFileSync( + path.resolve(__dirname, "../fixtures/ssl/localhost-cert.pem"), + ), + }, + }, + (_, devServer) => [ + { + name: "webpack-dev-middleware", + middleware: wdm.honoWrapper(devServer.compiler), + }, + ], + ], ]; -const servers = ["http", "https", "spdy", "http2"]; - describe("app option", () => { - for (const [appName, app] of apps) { - for (const server of servers) { - if (appName === "express" && server === "http2") { - // eslint-disable-next-line no-continue - continue; - } - - let compiler; - let devServer; - let page; - let browser; - let pageErrors; - let consoleMessages; - - describe(`should work using "${appName}" application and "${server}" server`, () => { - beforeEach(async () => { - compiler = webpack(config); - - devServer = new Server( - { - static: { - directory: staticDirectory, - watch: false, - }, - app, - server, - port, - setupMiddlewares: () => [], + for (const [appName, app, server, setupMiddlewares] of apps) { + let compiler; + let devServer; + let page; + let browser; + let pageErrors; + let consoleMessages; + + describe(`should work using "${appName}" application and "${typeof server === "function" ? "custom server" : server}" server`, () => { + beforeEach(async () => { + compiler = webpack(config); + + devServer = new Server( + { + static: { + directory: staticDirectory, + watch: false, }, - compiler, - ); + app, + server, + port, + setupMiddlewares: + typeof setupMiddlewares !== "undefined" + ? setupMiddlewares + : // eslint-disable-next-line no-undefined + undefined, + }, + compiler, + ); + + await devServer.start(); + + ({ page, browser } = await runBrowser()); + + pageErrors = []; + consoleMessages = []; + }); - await devServer.start(); + afterEach(async () => { + await browser.close(); + await devServer.stop(); + }); - ({ page, browser } = await runBrowser()); + it("should handle GET request to index route (/)", async () => { + page + .on("console", (message) => { + consoleMessages.push(message); + }) + .on("pageerror", (error) => { + pageErrors.push(error); + }); - pageErrors = []; - consoleMessages = []; - }); + const pageUrl = devServer.isTlsServer + ? `https://127.0.0.1:${port}/` + : `http://127.0.0.1:${port}/`; - afterEach(async () => { - await browser.close(); - await devServer.stop(); + const response = await page.goto(pageUrl, { + waitUntil: "networkidle0", }); - it("should handle GET request to index route (/)", async () => { - page - .on("console", (message) => { - consoleMessages.push(message); - }) - .on("pageerror", (error) => { - pageErrors.push(error); - }); - - const pageUrl = - server === "https" || server === "spdy" || server === "http2" - ? `https://127.0.0.1:${port}/` - : `http://127.0.0.1:${port}/`; - - const response = await page.goto(pageUrl, { - waitUntil: "networkidle0", - }); - - const HTTPVersion = await page.evaluate( - () => performance.getEntries()[0].nextHopProtocol, - ); - - if (server === "spdy" || server === "http2") { - expect(HTTPVersion).toEqual("h2"); - } else { - expect(HTTPVersion).toEqual("http/1.1"); - } - - expect(response.status()).toMatchSnapshot("response status"); - expect(await response.text()).toMatchSnapshot("response text"); - expect( - consoleMessages.map((message) => message.text()), - ).toMatchSnapshot("console messages"); - expect(pageErrors).toMatchSnapshot("page errors"); - }); + const HTTPVersion = await page.evaluate( + () => performance.getEntries()[0].nextHopProtocol, + ); + + if ( + server === "spdy" || + server === "http2" || + (server.options && server.options.allowHTTP1) + ) { + expect(HTTPVersion).toEqual("h2"); + } else { + expect(HTTPVersion).toEqual("http/1.1"); + } + + expect(response.status()).toMatchSnapshot("response status"); + expect(await response.text()).toMatchSnapshot("response text"); + expect( + consoleMessages.map((message) => message.text()), + ).toMatchSnapshot("console messages"); + expect(pageErrors).toMatchSnapshot("page errors"); }); - } + }); } }); diff --git a/test/fixtures/ssl/localhost-cert.pem b/test/fixtures/ssl/localhost-cert.pem new file mode 100644 index 0000000000..c8453042dc --- /dev/null +++ b/test/fixtures/ssl/localhost-cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCTCCAfGgAwIBAgIUevWiuCfenWuq9KyC8aQ/tc1Io14wDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MB4XDTI0MDQyNDE2MDYyMloXDTI0MDUy +NDE2MDYyMlowFDESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA1v/lb9u9WkqkF7zjIKe2R+b4S0sQnWIfBFZ0ggtaOL0a +ntud/EuaGQgLtJgSwO2M2xIqKx+yoLhoM+273EJe0KmfJMxYNAkhwP9h6vrKnaQJ +mpAhoalfEGyCrnHHMKISAAn4Rlc8NXnULoFhHzNm8bdqvP33rCmsJ+tNYC5kwzyt +HvRNFyg9BOUfACiPW17opFH0rao3IfZrQ6yRbknef1pX1x2pbDAH14rCT/vXaTs6 +VGuqLE/wRsSt+7nMHy/PmXxMyb4G4/UflYtnKfmXpDRw+TDEGzvTZedtoOz+rrJC +e989R9qYGrlPfyfZbI+O348FV66I+jcD+/EUQs+HkwIDAQABo1MwUTAdBgNVHQ4E +FgQU6bk4LSwtVQEt7V/ev+Zj270zdAkwHwYDVR0jBBgwFoAU6bk4LSwtVQEt7V/e +v+Zj270zdAkwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAUBgo +E3CZrrc/MaadFg1meNk+eKACmTsIa5cT6zi7MsvoKakXEd4bGd+iLifUzlAa1ygj +dQppfprb5t68I7oO9/lkh2DfKrXxW/RpdhB05KslUd8q/3XY5kyao5quzeiVoMHR +u+XYjoy2mTwdUC2uzFy6rkHsAkJy2vJJoDdlNsrKn6AZmh+voHHKrAtOL4gnanQV +wR1u8eBVfk2MKIl2pNSCA4bD16uZyp3+oqq097BEoVa1pR+l8nwbsh/YfALifq/d +P3yiN5+EqgiOIF9b8PZORe+Ry1O7uvPnU2ZRkVWPJ1S17Ms0lnr7IY3qjSBTuK66 +5uYi7ojrb5Vf0UL5oQ== +-----END CERTIFICATE----- diff --git a/test/fixtures/ssl/localhost-privkey.pem b/test/fixtures/ssl/localhost-privkey.pem new file mode 100644 index 0000000000..c260882984 --- /dev/null +++ b/test/fixtures/ssl/localhost-privkey.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEugIBADANBgkqhkiG9w0BAQEFAASCBKQwggSgAgEAAoIBAQDW/+Vv271aSqQX +vOMgp7ZH5vhLSxCdYh8EVnSCC1o4vRqe2538S5oZCAu0mBLA7YzbEiorH7KguGgz +7bvcQl7QqZ8kzFg0CSHA/2Hq+sqdpAmakCGhqV8QbIKucccwohIACfhGVzw1edQu +gWEfM2bxt2q8/fesKawn601gLmTDPK0e9E0XKD0E5R8AKI9bXuikUfStqjch9mtD +rJFuSd5/WlfXHalsMAfXisJP+9dpOzpUa6osT/BGxK37ucwfL8+ZfEzJvgbj9R+V +i2cp+ZekNHD5MMQbO9Nl522g7P6uskJ73z1H2pgauU9/J9lsj47fjwVXroj6NwP7 +8RRCz4eTAgMBAAECggEAA+zbFv43iEj5kvdfXC7DrK9iVBmUPZNXhqA/c0paxNNr +A4B182+76f4UHKF0IjKUEkHUJEJpY/bJ7DzIY76QdZXLMoRKjfSmuZvQAVa/0T33 +8Or1ujpZ4nZgsmegX9ptorOL5VjdYAqP3aN+DvBEzl/vYnDujyWZn4bzvDBMpaXS +39qW1MkcZ8UiP1fRad76+S57WnieBV+NRHYEAiDdMFKXLuw/igX/xOSZgq5Jh3I2 +hLS49S41dN1P9l9H2bPMw0CthNvMPPaemwKHz+84hSS+P4VJOWJzlGnXEdIFuqBR +GFBESQzcemfS9DDB22Yt06YujBCbwTVVAxj73lnKkQKBgQDvYXK36J9y/NphDAWi +Cwti5oE3eSfV0YazQwm+rRwC64wbpBFAm9ujwjUmaYBg75lBLF5nOOe8s1n95g5I +tLfFb+zuZh8NNLjhfNE9/SNmRnnMvbcaDHeIE2RMAz+PuLN/gFLmsVIwK2X1LRC2 +0vHjw9Yzh6JLiOajAchzhZiCEQKBgQDl7R6Wfggo8myETA8Uv5tWot3IcquRkEl/ +TRCyao2/79rAGexS7piwD7FPdSDOk1zfZFYUOMzyMjj60sGcPRPqRX6D0usEODLQ +TwsTJSCNgPnIOkqKkccwtqlTimbRIrPUSQfFPj56RzKKWdrJ/P3LPRjzkK7i3vLV +EGlAENaLYwKBgHKSOnzpWr+HY+IFBgErthRs7LWnSDifYxATauuXIQwIvvNP0G4S +6snzHss2vZonszstSDWxV8DKOq052eZUkIxv6H+l4wDIFiDeQ6uep73Ax3UF7EgM +ZX18gombGGXqagcBXSxK/GJPsynomtJWHi38Ql5BcZ0jdffY157q9zZxAoGAPZtD +Tt+GIDKUkP4wLEcKwDPzaPoQrngSuWFUz/ls8bi6zC4l/DKiBsqtn7Sqja8+ezzP +M6vkfiCm084UwmA7LdJhC8E/52mHc/k55m9UQZYFV3kG8AoPbSYESLYUxoSd2ouW +4WrEIs9g42EgFm8LMaG1Rc3GjlNejWhQSzI3yjECf3v7VoAcUwVfuVkwbm9W24vR +neFTF8QBl//fxIdxZwoj5SrSgMOjmZ3pXA/ZbFJ0pB4Rh5dmKTYqdpfXsOTiBuwB +XlqPVpN8UZEl3edpufLDyPldNej/9kEAkK5FS3YVyIQEg75739bCTlfzzCX1HdMx +q98XYm/n5LWYFezsAt0= +-----END PRIVATE KEY-----