Skip to content

feat(client): 'ws' clientMode #2090

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

Merged
merged 3 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions lib/utils/getSocketClientPath.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@ function getSocketClientPath(options) {
let clientImplFound = true;
switch (typeof options.clientMode) {
case 'string':
// could be 'sockjs', in the future 'ws', or a path that should be required
// could be 'sockjs', 'ws', or a path that should be required
if (options.clientMode === 'sockjs') {
// eslint-disable-next-line global-require
ClientImplementation = require('../../client/clients/SockJSClient');
} else if (options.clientMode === 'ws') {
// eslint-disable-next-line global-require
ClientImplementation = require('../../client/clients/WebsocketClient');
} else {
try {
// eslint-disable-next-line global-require, import/no-dynamic-require
Expand All @@ -24,7 +27,7 @@ function getSocketClientPath(options) {

if (!clientImplFound) {
throw new Error(
"clientMode must be a string denoting a default implementation (e.g. 'sockjs') or a full path to " +
"clientMode must be a string denoting a default implementation (e.g. 'sockjs', 'ws') or a full path to " +
'a JS file which exports a class extending BaseClient (webpack-dev-server/client-src/clients/BaseClient) ' +
'via require.resolve(...)'
);
Expand Down
239 changes: 97 additions & 142 deletions test/e2e/Client.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,157 +13,112 @@ const port = require('../ports-map').Client;
const cssFilePath = resolve(__dirname, '../fixtures/reload-config/main.css');

describe('reload', () => {
describe('hot', () => {
beforeAll((done) => {
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(0, 0, 255); }'
);
const options = {
port,
host: '0.0.0.0',
inline: true,
const modes = [
{
title: 'hot with default clientMode (sockjs)',
options: {
hot: true,
watchOptions: {
poll: 500,
},
};
testServer.startAwaitingCompilation(reloadConfig, options, done);
});

afterAll((done) => {
fs.unlinkSync(cssFilePath);
testServer.close(done);
});

describe('on browser client', () => {
it('should hot reload without page refresh', (done) => {
runBrowser().then(({ page, browser }) => {
let refreshed = false;
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
page
.evaluate(() => {
const body = document.body;
const bgColor = getComputedStyle(body)['background-color'];
return bgColor;
})
.then((color) => {
page.setRequestInterception(true).then(() => {
page.on('request', (req) => {
if (
req.isNavigationRequest() &&
req.frame() === page.mainFrame() &&
req.url() === `http://localhost:${port}/main`
) {
refreshed = true;
}
req.continue();
});
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(255, 0, 0); }'
);
page.waitFor(10000).then(() => {
page
.evaluate(() => {
const body = document.body;
const bgColor = getComputedStyle(body)[
'background-color'
];
return bgColor;
})
.then((color2) => {
browser.close().then(() => {
expect(color).toEqual('rgb(0, 0, 255)');
expect(color2).toEqual('rgb(255, 0, 0)');
expect(refreshed).toBeFalsy();
done();
});
});
});
});
});
});
},
shouldRefresh: false,
},
{
title: 'hot with clientMode ws',
options: {
hot: true,
clientMode: 'ws',
serverMode: require.resolve('../../lib/servers/WebsocketServer'),
},
shouldRefresh: false,
},
{
title: 'inline',
options: {
hot: false,
},
shouldRefresh: true,
},
];

page.goto(`http://localhost:${port}/main`);
});
modes.forEach((mode) => {
describe(mode.title, () => {
beforeAll((done) => {
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(0, 0, 255); }'
);
const options = Object.assign(
{},
{
port,
host: '0.0.0.0',
inline: true,
watchOptions: {
poll: 500,
},
},
mode.options
);
testServer.startAwaitingCompilation(reloadConfig, options, done);
});
});
});

describe('inline', () => {
beforeAll((done) => {
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(0, 0, 255); }'
);
const options = {
port,
host: '0.0.0.0',
inline: true,
hot: false,
watchOptions: {
poll: 500,
},
};
testServer.startAwaitingCompilation(reloadConfig, options, done);
});

afterAll((done) => {
fs.unlinkSync(cssFilePath);
testServer.close(done);
});
afterAll((done) => {
fs.unlinkSync(cssFilePath);
testServer.close(done);
});

describe('on browser client', () => {
it('should reload with page refresh', (done) => {
runBrowser().then(({ page, browser }) => {
let refreshed = false;
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
page
.evaluate(() => {
const body = document.body;
const bgColor = getComputedStyle(body)['background-color'];
return bgColor;
})
.then((color) => {
page.setRequestInterception(true).then(() => {
page.on('request', (req) => {
if (
req.isNavigationRequest() &&
req.frame() === page.mainFrame() &&
req.url() === `http://localhost:${port}/main`
) {
refreshed = true;
}
req.continue();
});
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(255, 0, 0); }'
);
page.waitFor(10000).then(() => {
page
.evaluate(() => {
const body = document.body;
const bgColor = getComputedStyle(body)[
'background-color'
];
return bgColor;
})
.then((color2) => {
browser.close().then(() => {
expect(color).toEqual('rgb(0, 0, 255)');
expect(color2).toEqual('rgb(255, 0, 0)');
expect(refreshed).toBeTruthy();
done();
describe('on browser client', () => {
it(`should reload ${
mode.shouldRefresh ? 'with' : 'without'
} page refresh`, (done) => {
runBrowser().then(({ page, browser }) => {
let refreshed = false;
page.waitForNavigation({ waitUntil: 'load' }).then(() => {
page
.evaluate(() => {
const body = document.body;
const bgColor = getComputedStyle(body)['background-color'];
return bgColor;
})
.then((color) => {
page.setRequestInterception(true).then(() => {
page.on('request', (req) => {
if (
req.isNavigationRequest() &&
req.frame() === page.mainFrame() &&
req.url() === `http://localhost:${port}/main`
) {
refreshed = true;
}
req.continue();
});
fs.writeFileSync(
cssFilePath,
'body { background-color: rgb(255, 0, 0); }'
);
page.waitFor(10000).then(() => {
page
.evaluate(() => {
const body = document.body;
const bgColor = getComputedStyle(body)[
'background-color'
];
return bgColor;
})
.then((color2) => {
browser.close().then(() => {
expect(color).toEqual('rgb(0, 0, 255)');
expect(color2).toEqual('rgb(255, 0, 0)');
expect(refreshed).toEqual(mode.shouldRefresh);
done();
});
});
});
});
});
});
});
});
});

page.goto(`http://localhost:${port}/main`);
page.goto(`http://localhost:${port}/main`);
});
});
});
});
Expand Down
Loading