Skip to content

Commit bdf8444

Browse files
knagaitsevhiroppy
authored andcommitted
feat(client): 'ws' clientMode (#2090)
* feat(client): ws client mode * test(client): changed client and client mode tests to use arrays
1 parent 6da68ec commit bdf8444

File tree

7 files changed

+224
-209
lines changed

7 files changed

+224
-209
lines changed

lib/utils/getSocketClientPath.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ function getSocketClientPath(options) {
55
let clientImplFound = true;
66
switch (typeof options.clientMode) {
77
case 'string':
8-
// could be 'sockjs', in the future 'ws', or a path that should be required
8+
// could be 'sockjs', 'ws', or a path that should be required
99
if (options.clientMode === 'sockjs') {
1010
// eslint-disable-next-line global-require
1111
ClientImplementation = require('../../client/clients/SockJSClient');
12+
} else if (options.clientMode === 'ws') {
13+
// eslint-disable-next-line global-require
14+
ClientImplementation = require('../../client/clients/WebsocketClient');
1215
} else {
1316
try {
1417
// eslint-disable-next-line global-require, import/no-dynamic-require
@@ -24,7 +27,7 @@ function getSocketClientPath(options) {
2427

2528
if (!clientImplFound) {
2629
throw new Error(
27-
"clientMode must be a string denoting a default implementation (e.g. 'sockjs') or a full path to " +
30+
"clientMode must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to " +
2831
'a JS file which exports a class extending BaseClient (webpack-dev-server/client-src/clients/BaseClient) ' +
2932
'via require.resolve(...)'
3033
);

test/e2e/Client.test.js

Lines changed: 97 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -13,157 +13,112 @@ const port = require('../ports-map').Client;
1313
const cssFilePath = resolve(__dirname, '../fixtures/reload-config/main.css');
1414

1515
describe('reload', () => {
16-
describe('hot', () => {
17-
beforeAll((done) => {
18-
fs.writeFileSync(
19-
cssFilePath,
20-
'body { background-color: rgb(0, 0, 255); }'
21-
);
22-
const options = {
23-
port,
24-
host: '0.0.0.0',
25-
inline: true,
16+
const modes = [
17+
{
18+
title: 'hot with default clientMode (sockjs)',
19+
options: {
2620
hot: true,
27-
watchOptions: {
28-
poll: 500,
29-
},
30-
};
31-
testServer.startAwaitingCompilation(reloadConfig, options, done);
32-
});
33-
34-
afterAll((done) => {
35-
fs.unlinkSync(cssFilePath);
36-
testServer.close(done);
37-
});
38-
39-
describe('on browser client', () => {
40-
it('should hot reload without page refresh', (done) => {
41-
runBrowser().then(({ page, browser }) => {
42-
let refreshed = false;
43-
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
44-
page
45-
.evaluate(() => {
46-
const body = document.body;
47-
const bgColor = getComputedStyle(body)['background-color'];
48-
return bgColor;
49-
})
50-
.then((color) => {
51-
page.setRequestInterception(true).then(() => {
52-
page.on('request', (req) => {
53-
if (
54-
req.isNavigationRequest() &&
55-
req.frame() === page.mainFrame() &&
56-
req.url() === `http://localhost:${port}/main`
57-
) {
58-
refreshed = true;
59-
}
60-
req.continue();
61-
});
62-
fs.writeFileSync(
63-
cssFilePath,
64-
'body { background-color: rgb(255, 0, 0); }'
65-
);
66-
page.waitFor(10000).then(() => {
67-
page
68-
.evaluate(() => {
69-
const body = document.body;
70-
const bgColor = getComputedStyle(body)[
71-
'background-color'
72-
];
73-
return bgColor;
74-
})
75-
.then((color2) => {
76-
browser.close().then(() => {
77-
expect(color).toEqual('rgb(0, 0, 255)');
78-
expect(color2).toEqual('rgb(255, 0, 0)');
79-
expect(refreshed).toBeFalsy();
80-
done();
81-
});
82-
});
83-
});
84-
});
85-
});
86-
});
21+
},
22+
shouldRefresh: false,
23+
},
24+
{
25+
title: 'hot with clientMode ws',
26+
options: {
27+
hot: true,
28+
clientMode: 'ws',
29+
serverMode: require.resolve('../../lib/servers/WebsocketServer'),
30+
},
31+
shouldRefresh: false,
32+
},
33+
{
34+
title: 'inline',
35+
options: {
36+
hot: false,
37+
},
38+
shouldRefresh: true,
39+
},
40+
];
8741

88-
page.goto(`http://localhost:${port}/main`);
89-
});
42+
modes.forEach((mode) => {
43+
describe(mode.title, () => {
44+
beforeAll((done) => {
45+
fs.writeFileSync(
46+
cssFilePath,
47+
'body { background-color: rgb(0, 0, 255); }'
48+
);
49+
const options = Object.assign(
50+
{},
51+
{
52+
port,
53+
host: '0.0.0.0',
54+
inline: true,
55+
watchOptions: {
56+
poll: 500,
57+
},
58+
},
59+
mode.options
60+
);
61+
testServer.startAwaitingCompilation(reloadConfig, options, done);
9062
});
91-
});
92-
});
93-
94-
describe('inline', () => {
95-
beforeAll((done) => {
96-
fs.writeFileSync(
97-
cssFilePath,
98-
'body { background-color: rgb(0, 0, 255); }'
99-
);
100-
const options = {
101-
port,
102-
host: '0.0.0.0',
103-
inline: true,
104-
hot: false,
105-
watchOptions: {
106-
poll: 500,
107-
},
108-
};
109-
testServer.startAwaitingCompilation(reloadConfig, options, done);
110-
});
11163

112-
afterAll((done) => {
113-
fs.unlinkSync(cssFilePath);
114-
testServer.close(done);
115-
});
64+
afterAll((done) => {
65+
fs.unlinkSync(cssFilePath);
66+
testServer.close(done);
67+
});
11668

117-
describe('on browser client', () => {
118-
it('should reload with page refresh', (done) => {
119-
runBrowser().then(({ page, browser }) => {
120-
let refreshed = false;
121-
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
122-
page
123-
.evaluate(() => {
124-
const body = document.body;
125-
const bgColor = getComputedStyle(body)['background-color'];
126-
return bgColor;
127-
})
128-
.then((color) => {
129-
page.setRequestInterception(true).then(() => {
130-
page.on('request', (req) => {
131-
if (
132-
req.isNavigationRequest() &&
133-
req.frame() === page.mainFrame() &&
134-
req.url() === `http://localhost:${port}/main`
135-
) {
136-
refreshed = true;
137-
}
138-
req.continue();
139-
});
140-
fs.writeFileSync(
141-
cssFilePath,
142-
'body { background-color: rgb(255, 0, 0); }'
143-
);
144-
page.waitFor(10000).then(() => {
145-
page
146-
.evaluate(() => {
147-
const body = document.body;
148-
const bgColor = getComputedStyle(body)[
149-
'background-color'
150-
];
151-
return bgColor;
152-
})
153-
.then((color2) => {
154-
browser.close().then(() => {
155-
expect(color).toEqual('rgb(0, 0, 255)');
156-
expect(color2).toEqual('rgb(255, 0, 0)');
157-
expect(refreshed).toBeTruthy();
158-
done();
69+
describe('on browser client', () => {
70+
it(`should reload ${
71+
mode.shouldRefresh ? 'with' : 'without'
72+
} page refresh`, (done) => {
73+
runBrowser().then(({ page, browser }) => {
74+
let refreshed = false;
75+
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
76+
page
77+
.evaluate(() => {
78+
const body = document.body;
79+
const bgColor = getComputedStyle(body)['background-color'];
80+
return bgColor;
81+
})
82+
.then((color) => {
83+
page.setRequestInterception(true).then(() => {
84+
page.on('request', (req) => {
85+
if (
86+
req.isNavigationRequest() &&
87+
req.frame() === page.mainFrame() &&
88+
req.url() === `http://localhost:${port}/main`
89+
) {
90+
refreshed = true;
91+
}
92+
req.continue();
93+
});
94+
fs.writeFileSync(
95+
cssFilePath,
96+
'body { background-color: rgb(255, 0, 0); }'
97+
);
98+
page.waitFor(10000).then(() => {
99+
page
100+
.evaluate(() => {
101+
const body = document.body;
102+
const bgColor = getComputedStyle(body)[
103+
'background-color'
104+
];
105+
return bgColor;
106+
})
107+
.then((color2) => {
108+
browser.close().then(() => {
109+
expect(color).toEqual('rgb(0, 0, 255)');
110+
expect(color2).toEqual('rgb(255, 0, 0)');
111+
expect(refreshed).toEqual(mode.shouldRefresh);
112+
done();
113+
});
159114
});
160-
});
115+
});
161116
});
162117
});
163-
});
164-
});
118+
});
165119

166-
page.goto(`http://localhost:${port}/main`);
120+
page.goto(`http://localhost:${port}/main`);
121+
});
167122
});
168123
});
169124
});

0 commit comments

Comments
 (0)