meteor-mocha
meteor-mocha copied to clipboard
Client tests in watch mode: Runner does not refresh on client changes
Does anyone else have an issue with client tests not re-running in watch mode?
I'm wondering if anyone can reproduce on their own stack. Steps to reproduce:
- run the test runner:
TEST_WATCH=1 TEST_SERVER=0 TEST_BROWSER_DRIVER=nightmare meteor test --full-app --driver-package dispatch:mocha --port 9000
- Change a client file only Expected: full test suite to re-run. Actual: No change, just the standard print: '=> Client modified -- refreshing'
Any ideas?
@lpgeiger This is expected based on how the watch mode stuff works. There's a note about it in the readme here: https://github.com/meteortesting/meteor-mocha#run-app-tests
There may be some way to detect that client was refreshed and send a message to the server telling it to restart.
@aldeed just curious, what is it that overrides Meteor's default reload mechanism ?
@hexsprite (late response) It isn't overridden. The page does reload, but our Node driver code that is loading the page in headless browser does not know when this happens, so it doesn't know to restart the test reporting sequence.
Couldn't we hook into Meteor's hot reload code to know when the Node driver should restart the test reporting sequence?
@mitar I'm quite new to the meteor internals going this far - but anyone else interested is very welcome to try and find out and share insights.
As a crutch (at least in german we would refer to it as this) you could just add a new-line on a file imported in the server-side code which would make the server reload. Calling it crutch because it helps you getting your way down the road, but it feels too bad for calling it a work-around.
Here is a quick and dirty workaround that will watch your client directory (you probably need to adjust the file extensions list) and then add whitespace on a test file in the server directory. It's not perfect but it works very nicely =)
You can invoke it like so $ TEST_WATCH=1 TEST_SERVER=0 node ./watch-client.js & meteor npm run test
// watch-client.js
const { watch, promises } = require('fs');
const path = require('path');
(async () => {
const options = {
recursive: true,
};
const whitespacefile = './server/changeMe.tests.js';
const fileHandle = await promises.open(whitespacefile, 'a');
const listener = (eventType, filename) => {
if (!['.js', '.jsx', '.tests.js', '.tests.jsx'].includes(path.extname(filename))) {
console.log(`file ${filename} was changed but is ignored`);
return;
}
console.log(`${eventType} event on file ${path.basename(filename)}, changing whitespace in ${whitespacefile}`);
fileHandle.appendFile(' ');
};
watch('./client', options, listener);
})();
Digging a bit into this issue, I found two events used by Meteor internally: https://github.com/meteor/meteor/blob/444f8228b8a46d1035095d606933893e1873b8c3/tools/runners/run-app.js#L822-L830
Here is a sample of usage: https://github.com/meteor/meteor/blob/d9db4f52f2ea6d706a25156768ea42e1fbb8f599/packages/dynamic-import/server.js#L201-L212
Maybe we're able to run the tests on the client again based on that ... Let's give it a try :sunglasses:
I have now pushed a version which contains a working prototype of this. Please leave a comment on what you think about it:
- When reloading, the message
client-refresh
is sent twice, and the messagewebapp-reload-client
once. In order to keep it readable, I added a message on every call, and also added a message when a run is skipped. - If the client-side tests are still running, the browser will not reload and not restart, so you'll have to wait for the client-tests to finish. First then a reload will trigger a rerun of the tests. This is because the events are triggered multiple times and we do not yet have an option to forcefully close the current browser and ignore the test-results if a rerun is triggered.
Created a PR for this - all further details should be shared there: https://github.com/meteortesting/meteor-mocha/pull/106