问题
It seems protractor doesn't provide any out of the box solution for starting a server before it runs. Having to run multiple commands before functional tests will run is a bad user experience and bad for automated testing.
Angular-cli has its own solution that is rather complicated, which this plugin claims to duplicate, although it doesn't work for me and may be unmaintained. https://www.npmjs.com/package/protractor-webpack
EDIT: BETTER SOLUTION ACCEPTED BELOW
I came up with a solution using child_process.exec that seems to work well, although I don't like it very much. I'd like to share it in case anyone needs it and to see if anyone can come up with a better solution.
Launch the process in the beforeLaunch hook of protractor:
beforeLaunch: () => {
webpackServerProcess = exec(`webpack-dev-server --port=3003 --open=false`, null, () => {
console.log(`Webpack Server process reports that it exited. Its possible a server was already running on port ${port}`)
});
},
Then above the configuration block we set up the exit handlers to make positively sure that server gets killed when we are done.
let webpackServerProcess; // Set below in beforeLaunch hook
function cleanUpServer(eventType) {
console.log(`Server Cleanup caught ${eventType}, killing server`);
if (webpackServerProcess) {
webpackServerProcess.kill();
console.log(`SERVER KILLED`);
}
}
[`exit`, `SIGINT`, `SIGUSR1`, `SIGUSR2`, `uncaughtException`].forEach((eventType) => {
process.on(eventType, cleanUpServer.bind(null, eventType));
})
The various event listeners are needed to handle cntrl+c events and situations where the process is killed by ID. Strange that node does not provide an event to encompass all of these.
回答1:
Protractor also has onCleanUp
that will run after all the specs in the file have finished.
And you are doing the right thing by keeping a reference to your process so that you can kill it later.
let webpackServerProcess;
beforeLaunch: () {
webpackServerProcess = exec('blah'); // you could use spawn instead of exec
},
onCleanUp: () {
process.kill(webpackServerProcess.pid);
// or webpackServerProcess.exit();
}
Since you are launching the serverProcess with child_process.exec, and not in a detached state, it should go away if the main process is killed with SIGINT or anything else. So you might not even have to kill it or cleanup.
回答2:
I found a much more reliable way to do it using the webpack-dev-server node api. That way no separate process is spawned and we don't have to clean anything. Also, it blocks protractor until webpack is ready.
beforeLaunch: () => {
return new Promise((resolve, reject) => {
new WebpackDevServer(webpack(require('./webpack.config.js')()), {
// Do stuff
}).listen(APP_PORT, '0.0.0.0', function(err) {
console.log('webpack dev server error is ', err)
resolve()
}).on('error', (error) => {
console.log('dev server error ', error)
reject(error)
})
})
},
来源:https://stackoverflow.com/questions/49365602/how-to-start-a-server-before-protractor-runs-and-clean-up-afterwards