Skip to content

Commit 6b935d7

Browse files
committed
test: add hot module replacement tests for plugin API
1 parent 75801a9 commit 6b935d7

1 file changed

Lines changed: 89 additions & 1 deletion

File tree

test/e2e/api-plugin.test.js

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,30 @@
11
import fs from "node:fs";
22
import os from "node:os";
33
import path from "node:path";
4-
import { describe, it } from "node:test";
4+
import { afterEach, beforeEach, describe, it } from "node:test";
5+
import { fileURLToPath } from "node:url";
56
import { expect } from "expect";
67
import { spyOn } from "jest-mock";
78
import webpack from "webpack";
89
import WebSocket from "ws";
910
import Server from "../../lib/Server.js";
1011
import config from "../fixtures/client-config/webpack.config.js";
1112
import multiCompilerConfig from "../fixtures/multi-compiler-two-configurations/webpack.config.js";
13+
import reloadConfig from "../fixtures/reload-config/webpack.config.js";
1214
import compile from "../helpers/compile.js";
1315
import runBrowser from "../helpers/run-browser.js";
1416
import portsMap from "../ports-map.js";
1517

18+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
19+
1620
const port = portsMap["api-plugin"];
1721
const [portA, portB] = portsMap["api-plugin-multi"];
1822

23+
const cssFilePath = path.resolve(
24+
__dirname,
25+
"../fixtures/reload-config/main.css",
26+
);
27+
1928
describe("API (plugin)", () => {
2029
it("should work with plugin API", async (t) => {
2130
const compiler = webpack(config);
@@ -485,4 +494,83 @@ describe("API (plugin)", () => {
485494
}
486495
});
487496
});
497+
498+
describe("hot module replacement", () => {
499+
beforeEach(() => {
500+
fs.writeFileSync(
501+
cssFilePath,
502+
"body { background-color: rgb(0, 0, 255); }",
503+
);
504+
});
505+
506+
afterEach(() => {
507+
fs.unlinkSync(cssFilePath);
508+
});
509+
510+
it("should apply hot module replacement updates", async () => {
511+
const server = new Server({ port, hot: true });
512+
const compiler = webpack({
513+
...reloadConfig,
514+
plugins: [...reloadConfig.plugins, server],
515+
});
516+
517+
await compile(compiler, port);
518+
519+
const { page, browser } = await runBrowser();
520+
521+
try {
522+
const pageErrors = [];
523+
let doneHotUpdate = false;
524+
525+
page
526+
.on("pageerror", (error) => {
527+
pageErrors.push(error);
528+
})
529+
.on("request", (request) => {
530+
if (/\.hot-update\.json$/.test(request.url())) {
531+
doneHotUpdate = true;
532+
}
533+
});
534+
535+
await page.goto(`http://127.0.0.1:${port}/`, {
536+
waitUntil: "networkidle0",
537+
});
538+
539+
const backgroundColorBefore = await page.evaluate(
540+
() => getComputedStyle(document.body)["background-color"],
541+
);
542+
543+
expect(backgroundColorBefore).toBe("rgb(0, 0, 255)");
544+
545+
fs.writeFileSync(
546+
cssFilePath,
547+
"body { background-color: rgb(255, 0, 0); }",
548+
);
549+
550+
// The change must arrive through HMR (a `.hot-update.json` fetch),
551+
// not a full page reload.
552+
await page.waitForFunction(
553+
() =>
554+
getComputedStyle(document.body)["background-color"] ===
555+
"rgb(255, 0, 0)",
556+
);
557+
558+
expect(doneHotUpdate).toBe(true);
559+
expect(pageErrors).toEqual([]);
560+
561+
// The hot-update delta is served from webpack-dev-middleware's in-memory
562+
// file system, never the real disk.
563+
expect(compiler.outputFileSystem).not.toBe(fs);
564+
const outputFiles = compiler.outputFileSystem.readdirSync("/");
565+
expect(
566+
outputFiles.some((file) => /\.hot-update\.json$/.test(file)),
567+
).toBe(true);
568+
} finally {
569+
await browser.close();
570+
await new Promise((resolve) => {
571+
compiler.close(resolve);
572+
});
573+
}
574+
});
575+
});
488576
});

0 commit comments

Comments
 (0)