Executing a task after all test are launch cypress - node.js

I need to execute some code after all tests run. I add this test on after hook. But this task needs the report to be created, but on after hook, the report is not created yet.
I also tried to use
on('run:end', () => {
console.log("gdfgfdsafkañjsdfjñaldfkjsñkasfdñlassfjdskafmjassd");
});
but it does nothing.

You can't, there is an open issue for that.
At the moment you can only leverage a package.json post hook. So, if you have a dedicated command in your package.json file
"scripts": {
"cy:run": "cypress run"
}
you can add a postcy:run script
"scripts": {
"cy:run": "cypress run",
"postcy:run": "<YOUR_COMMAND>"
}
I hope it helps you 😊

You can now listen to after:run events in the plugins file:
on('after:run', (results) => { /* ... */ })
The event fires after the run.
See more info at After Run API

Be aware that the post hook might not run when the tests fail. I'm currently using a global after hook in support/index.ts for running after all tests
I'm currently using a global after hook in support/index.ts
after(() => {
// something here
});

Related

mocha tests not found: "0 passing"

I dont know why the test runner wont detect my tests.
npm test
myproject#1.0.0 test C:\Users\sjsui\Desktop\git_workshop\myproject
mocha ./built/source
0 passing (4ms)
PS C:\Users\sjsui\Desktop\git_workshop\myproject>
I know that test is the default folder that mocha searches for so that is how I structured my project.
built
\--source
\--test
\--test.js
here is my test.js file
describe("consumer tests", function()
{
it("runs bad request tests", (done) => {
let tests = new badrequesttests()
iteratebadtests(tests, done)
})
it("normal consumer tests", (done) => {
let tests = new normaltests()
iteratenormaltests(tests, done)
})
it("abnormal consumer tests", (done) => {
let tests = new unauthorizedtests()
iterateunauthorizedtests(tests, done)
})
})
npm scripts section in package.json
"scripts": {
"test": "mocha ./built/source"
},
as a side note, break points wont hit inside the test (visual studio code debug task -> mocha)
I think your test scripts are not detected y mocha because by default mocha does not scan sub-directories and your tests are inside a subdirectory of path you are passing at the time of invking mocha. There are two ways to resolve this.
Provide the path of test folder to mocha as below
mocha ./built/source/test
Trigger mocha tests with recursive flag. Using this flag mocha will scan the subdirectories of the path you provide
mocha ./built/source --recursive
I think this should solve your problem
You can pass the directory to search for your test files like below:
mocha -- ./built/source/**/*.test.js
This will check for all test files ending with .test.js in their file name in any directory within the source directory.
mocha -- ./built/source/*.test.js
That will check for test files within the source directory.

Mocha --require wait until migration

I have a challenge to run a database migration before start my mocha suite test.
I am using the flag --require to load a bootstrap.js module that I have created and where I run the database migration.
The problem is that migration is an async function and as you know it returns immediately. So, there is any way to wait for the module to be ready until everything it's finished?
I can use some sync lib to convert migration to be synchronous but I would like to hear more strategies.
You could define a global before hook, like so:
import {runMigration} from './bootstrap';
before(done => {
runMigration().then(done);
});
describe('some part of my suite', () => {
/* ... */
If you write this hook in "root suite" - that is, outside any of your own describe blocks - it will run before all tests, regardless of which file you put this block in.
Docs on root level hooks
Note, that your hooks take too long, you might start getting an error like "Timeout of 2000ms exceeded", which can be solved by running mocha with --timeout flag - like mocha --timeout 10000

Console.log statements output nothing at all in Jest

console.log statements output nothing at all in Jest. This was working for me yesterday, and all of sudden, it's not working today. I have made zero changes to my config and haven't installed any updates.
I'm not using the --forceExit option. Still seeing this issue.
Jest suppresses the console log message by default. In order to show the console log message, set silent option to false at the command line
set --silent=false in the command line:
npm run test -- --silent=false
You can run both options together like this --watch --verbose false if you want to also be watching the files and see the output.
for one time runs just do --verbose false
As per comment on https://github.com/facebook/jest/issues/2441,
Try setting verbose: false (or removing it) in the jest options in package.json.
This is a pretty old question and still there's no accepted answer. However, none of the suggested solutions worked for me (settings like --silent --verbose etc.). The main problem is that Jest changes the global console object. So, the easiest solution is to not use the global console object.
Instead import dedicated log functions from the console module and work with those:
import { error } from "console";
error("This is an error");
As easy as that.
Try using console.debug() instead.
Run console.debug('Message here', yourValueHere) inside test function and it should show in the console output when running test script. You can verify if it works using Ctrl+F and find Message here in the standard output.
This does the trick of showing output in the console, while it is not an answer quite on how to use console.log I understand.
I am running #testing-library/jest-dom and jest-junit 12.0.0 as devDependencies.
jest-junit has a minimal configuration of
"jest-junit": {
"usePathForSuiteName": "true"
},
in package.json. This is mainly to configure coverage reporting.
jest is configured like this:
"jest": {
"testMatch": [
"**/__tests__/**/*.[jt]s?(x)",
"**/?(*.)+(spec|test).[jt]s?(x)",
"!**/utilities.ts",
],
Check for your command line flags in package.json to see that you don't have --silent in there.
in addition to --verbose option which can cause this as mentioned, be aware that the --watch may also cause this bug.
One of the potential reason that logging is not printing is due to console.log has been mocked. Something as below
// jest-setup.js
global.console = {
// eslint-disable-next-line no-undef
log: jest.fn(), // console.log are ignored in tests
// log: console.log,
// Keep native behaviour for other methods, use those to print out things in your own tests, not `console.log`
error: console.error,
warn: console.warn,
info: console.info,
debug: console.debug,
};
// package.json
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
"setupFilesAfterEnv": [
"#testing-library/jest-native/extend-expect",
"<rootDir>/src/config/jest-setup.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.test.{ts,tsx}"
]
},
This is commonly used if you wish to disable console.log in jest
Also be sure that your jest config does not have silent: true. In my case, I didn't realize that someone else had added that to our config.
I don't see it in the list of config options, but the command line flag is documented here.
If using Webstorm with Jest configuration, click on the file name instead of the test name.
Having tried a few of the config options in the previous replies, using console.debug() instead of console.log() worked.
In my case, the issue was caused by [only] flag in:
it.only() or test.only('some text',()=>{})
According to the v27 docs silent is what you want here. verbose false (the default) prevents Jest from outputting the result of every test in a hierarchy while silent true (the default) will:
Prevent tests from printing messages through the console.
Use npx jest --silent false if you want to run Jest with that option from the CLI. Tested this just now with console.log and it works as expected.
Tried the advice given regarding jest config settings to no avail. Instead, in my case, the issue seemed related to not awaiting asynchronous code:
test("test", async () => {
console.log("Does output")
new Promise(resolve => {
// some expectation depending on async code
setTimeout(() => resolve(console.log("Does not output")) , 1)
})
})
Rather, awaiting the promise does output the async log:
test("test", async () => {
console.log("Does output")
await new Promise(resolve => {
// some expectation depending on async code
setTimeout(() => resolve(console.log("Does output")) , 1)
})
})
Possibly related background:
https://github.com/facebook/jest/issues/2441
Try using console.info() which is an alias for console.log(). I tried almost all the above answers but still console.log() didn't worked for me by any means. So, used console.info() which did the work.
This is what worked for me: jest --verbose true
In my case the problem was that the logs where made when the module is required, so before the start of an actual test case. Change from a top-level import to using require inside the test case fixed the problem.
In my case the problem was importing the functions from the compiled version (present in dist folder) instead of the src folder. And therefore it was using the old version. So rebuilding the project and/or importing from src fixed my issue.
On MacOS with jest version 26.6.3 I had to append --silent="false"
renaming my file to index.test.js from index.spec.js did the trick for me.

Why can't get the global variable which was set in globalSetup in test code?

I use Jest to do unit test in node.
And I use the new feature globalSetup which come in Jest v22.
I have defined a global variable in globalSetup.
But I can't get it in the test code. Console log is undefined.
Anyone in this question?
Thanks.
Jest version: 22.0.0
node version: 8.9.0
yarn version: 1.3.2
OS: mac High Sierra 10.13.2
The code as follow:
// package.json
{
"jest": {
"globalSetup": "<rootDir>/src/globalSetupTest.js"
}
}
// globalSetupTest.js
module.exports = async function() {
global.foo = 'foo';
console.log(`global setup: ${global.foo}`);
};
// App.test.js
describe('APP test', () => {
it('renders without crashing', () => {
console.log({ foo: global.foo });
});
});
// test result
yarn run v1.3.2
$ node scripts/test.js --env=node --colors
global setup: foo
PASS src/App.test.js
APP test
✓ renders without crashing (5ms)
console.log src/App.test.js:3
{ foo: undefined }
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 0.354s, estimated 1s
Ran all test suites.
There's a solution offered from Jest people themselves: https://jestjs.io/docs/en/puppeteer.html. Note that if you're using CRA, this won't work out of the box (solution below), cause it currently doesn't support testEnvironment option for Jest.
Anyways:
In Jest config file you setup paths to global setup, teardown and test environment scripts
In global setup script, you create a browser and write it's WSEndpoint to a file
In global teardown script, you simply close the browser
In testEnvironment script, you read WSEndpoint from the file you saved before and then use it to connect to the running browser - after this, browser is available in your tests by using a global variable
If you're using CRA, you can use a custom setup for these tests and run them completely separately. And if you're using Puppeteer for e2e tests, this is probably what you want to do anyway.
You just add another script to your package.json: "test:e2e": "jest -c ./jest-e2e.config.js" and set it up as you want. Now you will have npm run test for unit tests and npm run test:e2e for end to end tests.
For what I understood is a design decision of Jest because is considered a bad practice to share state across different tests. Tests run in parallel and they should keep their own state.
See:
https://github.com/facebook/jest/issues/6007#issuecomment-381743011
https://github.com/facebook/jest/issues/4118
Can you try..
global.foo = 'foo';
console.log(`global setup: ${global.foo}`);
(remove the exports)
You can try changing globalSetup to setupFiles. That one, won't expect a function.
https://facebook.github.io/jest/docs/en/configuration.html#setupfiles-array

How to run mocha tests and node in a single npm test command ? (CI)

I want to use Circle CI to integrate a git project.
I'm using mocha for my tests .
What i want to do?
When running npm test I want:
my node server to start
my test file to run
How can I run a single npm test command to run both node and my mocha tests which are already wrapped in a single index.js file.
I have tried this in my package.json:
"scripts": {
"test": "node server/app.js & mocha server/tests/index.js",
"start": "node server/app.js",
"postinstall": "bower install"
}
The problems with the above
My server takes some time to start and the tests fail since they run before the server starts
Is there a standard way to run a server and the tests with a single command but I'm missing something?
If it is possible at all in your case I'd suggest using something like supertest to do the testing. This way, you can avoid having to start a server before starting the test.
I understand that there are scenarios where using supertest is not possible. In such case, you could poll your server in a before hook before all tests to wait until it is ready:
before(function (done) {
// Set a reasonable timeout for this hook.
this.timeout(5000);
function check() {
if (serverIsReady()) {
done();
return;
}
// The server is no ready, check again in 1/10th of a second.
setTimeout(check, 100);
}
check(); // Start checking.
});
I'm not sure what serverIsReady should be precisely in your case. It could be an attempt at getting a trivial path from your server like issuing a GET on the path /.
I think the key is to run your node server in your test, rather than trying to initialise it in another process.
Your mocha test should start with a require to your app, then each
of your tests can interact with it.
For example:
var http = require('http');
var server = http.createServer(function(req, res){
res.end('Hello World\n');
})
server.listen(8888);
describe('http', function(){
it('should provide an example', function(done){
http.get({ path: '/', port: 8888 }, function(res){
expect(res).to.have.property('statusCode', 200);
done();
})
})
})
What I do when running a test that needs certain pre-requisites is use mochas beforeEach() functionality.
From the documentation
You may also pick any file and add “root”-level hooks. For example, add beforeEach() outside of all describe() blocks. This will cause the callback to beforeEach() to run before any test case, regardless of the file it lives in (this is because Mocha has an implied describe() block, called the “root suite”).
beforeEach(function() {
console.log('before every test in every file');
});
In the before each code block you can run your command to start the server
using for example the exec library from npm
https://www.npmjs.com/package/exec
This will ensure your server is running before your tests are run allowing you to simply run npm test.

Resources