Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(dev-sever): add e2e test cases part 2 #7829

Merged
merged 11 commits into from
Sep 11, 2024
65 changes: 51 additions & 14 deletions packages/rspack-dev-server/client/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,28 @@ var status = {
currentHash: typeof __webpack_hash__ !== "undefined" ? __webpack_hash__ : ""
};

var decodeOverlayOptions = function decodeOverlayOptions(overlayOptions) {
if (typeof overlayOptions === "object") {
["warnings", "errors", "runtimeErrors"].forEach(function (property) {
if (typeof overlayOptions[property] === "string") {
var overlayFilterFunctionString = decodeURIComponent(
overlayOptions[property]
);

// eslint-disable-next-line no-new-func
var overlayFilterFunction = new Function(
"message",
"var callback = ".concat(
overlayFilterFunctionString,
"\n return callback(message)"
)
);
overlayOptions[property] = overlayFilterFunction;
}
});
}
};

/** @type {Options} */
var options = {
hot: false,
Expand All @@ -132,6 +154,7 @@ if (parsedResourceQuery.progress === "true") {
options.progress = true;
enabledFeatures.Progress = true;
}

if (parsedResourceQuery.overlay) {
try {
options.overlay = JSON.parse(parsedResourceQuery.overlay);
Expand All @@ -149,6 +172,7 @@ if (parsedResourceQuery.overlay) {
},
options.overlay
);
decodeOverlayOptions(options.overlay);
}
enabledFeatures.Overlay = true;
}
Expand Down Expand Up @@ -232,6 +256,7 @@ var onSocketMessage = {
return;
}
options.overlay = value;
decodeOverlayOptions(options.overlay);
},
/**
* @param {number} value
Expand Down Expand Up @@ -321,16 +346,22 @@ var onSocketMessage = {
for (var i = 0; i < printableWarnings.length; i++) {
log.warn(printableWarnings[i]);
}
var needShowOverlayForWarnings =
var overlayWarningsSetting =
typeof options.overlay === "boolean"
? options.overlay
: options.overlay && options.overlay.warnings;
if (needShowOverlayForWarnings) {
overlay.send({
type: "BUILD_ERROR",
level: "warning",
messages: _warnings
});
if (overlayWarningsSetting) {
var warningsToDisplay =
typeof overlayWarningsSetting === "function"
? _warnings.filter(overlayWarningsSetting)
: _warnings;
if (warningsToDisplay.length) {
overlay.send({
type: "BUILD_ERROR",
level: "warning",
messages: _warnings
});
}
}
if (params && params.preventReloading) {
return;
Expand All @@ -352,16 +383,22 @@ var onSocketMessage = {
for (var i = 0; i < printableErrors.length; i++) {
log.error(printableErrors[i]);
}
var needShowOverlayForErrors =
var overlayErrorsSettings =
typeof options.overlay === "boolean"
? options.overlay
: options.overlay && options.overlay.errors;
if (needShowOverlayForErrors) {
overlay.send({
type: "BUILD_ERROR",
level: "error",
messages: _errors
});
if (overlayErrorsSettings) {
var errorsToDisplay =
typeof overlayErrorsSettings === "function"
? _errors.filter(overlayErrorsSettings)
: _errors;
if (errorsToDisplay.length) {
overlay.send({
type: "BUILD_ERROR",
level: "error",
messages: _errors
});
}
}
},
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/rspack-dev-server/etc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class RspackDevServer extends WebpackDevServer {
constructor(options: Configuration, compiler: Compiler | MultiCompiler);
compiler: Compiler | MultiCompiler;
// (undocumented)
static getFreePort(port: string, host: string): Promise<any>;
static getFreePort: (port: string, host: string) => Promise<any>;
// (undocumented)
initialize(): Promise<void>;
options: ResolvedDevServer;
Expand Down
20 changes: 10 additions & 10 deletions packages/rspack-dev-server/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const config = {
testPathIgnorePatterns: isWin
? []
: [
// TODO: check why http proxy server throw error with websocket server
"<rootDir>/tests/e2e/allowed-hosts.test.js",
// TODO: check why this test timeout
"<rootDir>/tests/e2e/host.test.js",
// TODO: not support progress plugin event yet
"<rootDir>/tests/e2e/progress.test.js",
// TODO: check why this test throw error when run with other tests
"<rootDir>/tests/e2e/watch-files.test.js"
],
// TODO: check why http proxy server throw error with websocket server
"<rootDir>/tests/e2e/allowed-hosts.test.js",
// TODO: check why this test timeout
"<rootDir>/tests/e2e/host.test.js",
// TODO: not support progress plugin event yet
"<rootDir>/tests/e2e/progress.test.js",
// TODO: check why this test throw error when run with other tests
"<rootDir>/tests/e2e/watch-files.test.js"
],
cache: false,
testTimeout: process.env.CI ? 120000 : 30000,
transform: {
Expand All @@ -33,7 +33,7 @@ const config = {
]
},
// Add this to find out which test timeouts
testSequencer: "<rootDir>/tests/helpers/sequencer.js",
// testSequencer: "<rootDir>/tests/helpers/sequencer.js",
snapshotResolver: "<rootDir>/tests/helpers/snapshot-resolver.js",
setupFilesAfterEnv: ["<rootDir>/tests/helpers/setup-test.js"],
globalSetup: "<rootDir>/tests/helpers/global-setup-test.js",
Expand Down
8 changes: 7 additions & 1 deletion packages/rspack-dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@
"sockjs-client": "^1.6.1",
"supertest": "^6.1.3",
"tcp-port-used": "^1.0.2",
"typescript": "5.0.2"
"typescript": "5.0.2",
"style-loader": "^3.3.3",
"css-loader": "^6.11.0",
"require-from-string": "^2.0.2",
"wait-for-expect": "^3.0.2",
"prettier": "3.2.5",
"@jest/test-sequencer": "^29.7.0"
},
"dependencies": {
"chokidar": "^3.6.0",
Expand Down
71 changes: 44 additions & 27 deletions packages/rspack-dev-server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ import type { Socket } from "node:net";
import { type Compiler, MultiCompiler } from "@rspack/core";
import type { FSWatcher } from "chokidar";
import rdm from "webpack-dev-middleware";
import WebpackDevServer from "webpack-dev-server";
import WebpackDevServer, {
type OverlayMessageOptions
} from "webpack-dev-server";
// @ts-ignore 'package.json' is not under 'rootDir'
import { version } from "../package.json";

Expand All @@ -23,31 +25,39 @@ import { applyDevServerPatch } from "./patch";

applyDevServerPatch();

export class RspackDevServer extends WebpackDevServer {
static async getFreePort(port: string, host: string) {
if (typeof port !== "undefined" && port !== null && port !== "auto") {
return port;
}
const encodeOverlaySettings = (setting: OverlayMessageOptions | undefined) =>
typeof setting === "function"
? encodeURIComponent(setting.toString())
: setting;

const pRetry = require("p-retry");
const getPort = require("webpack-dev-server/lib/getPort");
const basePort =
typeof process.env.WEBPACK_DEV_SERVER_BASE_PORT !== "undefined"
? Number.parseInt(process.env.WEBPACK_DEV_SERVER_BASE_PORT, 10)
: 8080;

// Try to find unused port and listen on it for 3 times,
// if port is not specified in options.
const defaultPortRetry =
typeof process.env.WEBPACK_DEV_SERVER_PORT_RETRY !== "undefined"
? Number.parseInt(process.env.WEBPACK_DEV_SERVER_PORT_RETRY, 10)
: 3;

return pRetry(() => getPort(basePort, host), {
retries: defaultPortRetry
});
const getFreePort = async function getFreePort(port: string, host: string) {
if (typeof port !== "undefined" && port !== null && port !== "auto") {
return port;
}

const pRetry = require("p-retry");
const getPort = require("webpack-dev-server/lib/getPort");
const basePort =
typeof process.env.WEBPACK_DEV_SERVER_BASE_PORT !== "undefined"
? Number.parseInt(process.env.WEBPACK_DEV_SERVER_BASE_PORT, 10)
: 8080;

// Try to find unused port and listen on it for 3 times,
// if port is not specified in options.
const defaultPortRetry =
typeof process.env.WEBPACK_DEV_SERVER_PORT_RETRY !== "undefined"
? Number.parseInt(process.env.WEBPACK_DEV_SERVER_PORT_RETRY, 10)
: 3;

return pRetry(() => getPort(basePort, host), {
retries: defaultPortRetry
});
};

WebpackDevServer.getFreePort = getFreePort;

export class RspackDevServer extends WebpackDevServer {
static getFreePort = getFreePort;
/**
* resolved after `normalizedOptions`
*/
Expand Down Expand Up @@ -385,12 +395,19 @@ export class RspackDevServer extends WebpackDevServer {
}

if (typeof client.overlay !== "undefined") {
searchParams.set(
"overlay",
const overlayString =
typeof client.overlay === "boolean"
? String(client.overlay)
: JSON.stringify(client.overlay)
);
: JSON.stringify({
...client.overlay,
errors: encodeOverlaySettings(client.overlay.errors),
warnings: encodeOverlaySettings(client.overlay.warnings),
runtimeErrors: encodeOverlaySettings(
client.overlay.runtimeErrors
)
});

searchParams.set("overlay", overlayString);
}

if (typeof client.reconnect !== "undefined") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,24 @@ exports[`API Invalidate callback should use the provided \`callback\` function:

exports[`API Invalidate callback should use the provided \`callback\` function: response status 1`] = `200`;

exports[`API Server.checkHostHeader should allow URLs with scheme for checking origin when the "option.client.webSocketURL" is object: 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.",
"WebSocket connection to 'ws://test.host:8158/ws' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED",
"[webpack-dev-server] JSHandle@object",
"[webpack-dev-server] Disconnected!",
"[webpack-dev-server] Trying to reconnect...",
]
`;

exports[`API Server.checkHostHeader should allow URLs with scheme for checking origin when the "option.client.webSocketURL" is object: page errors 1`] = `[]`;

exports[`API Server.checkHostHeader should allow URLs with scheme for checking origin when the "option.client.webSocketURL" is object: response status 1`] = `200`;

exports[`API Server.checkHostHeader should allow URLs with scheme for checking origin when the "option.client.webSocketURL" is object: web socket URL 1`] = `"ws://test.host:8158/ws"`;

exports[`API Server.getFreePort should retry finding the port for up to defaultPortRetry times (number): console messages 1`] = `
[
"[webpack-dev-server] Server started: Hot Module Replacement enabled, Live Reloading enabled, Progress disabled, Overlay enabled.",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`host should work using "127.0.0.1" host and "auto" port: 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[`host should work using "127.0.0.1" host and "auto" port: page errors 1`] = `[]`;

exports[`host should work using "127.0.0.1" host and port as number: 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[`host should work using "127.0.0.1" host and port as number: page errors 1`] = `[]`;

exports[`host should work using "127.0.0.1" host and port as string: 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[`host should work using "127.0.0.1" host and port as string: page errors 1`] = `[]`;

exports[`host should work using "localhost" host and "auto" port: 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[`host should work using "localhost" host and "auto" port: page errors 1`] = `[]`;

exports[`host should work using "localhost" host and port as number: 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[`host should work using "localhost" host and port as number: page errors 1`] = `[]`;

exports[`host should work using "localhost" host and port as string: 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[`host should work using "localhost" host and port as string: page errors 1`] = `[]`;
Loading
Loading