When one of my Jest tests fails I want to store a screenshot, but only when it fails.
Here is a piece of my test code as an example, the !passed
part in the afterEach is not working.
describe('Page', () => {
it('should contain Text in the header', async () => {
// Arrange
const page = new Page(driver);
// Act
await page.open();
// Assert
expect(await page.getHeaderText()).toBe('Something');
});
afterEach(async () => {
if (!passed) takeScreenshot();
await driver.quit();
});
});
With jasmine I would do something like:
var passed = jasmine.getEnv().currentSpec.results().passed();
But I cannot find something similar for Jest. Maybe there is another solution like taking a screenshot on each failing expect? I tried a try/catch around the expect, but then the test always passes...
How can I check with Jest if my test failed in the afterEach?
afterEach(fn) #Runs a function after each one of the tests in this file completes. If the function returns a promise, Jest waits for that promise to resolve before continuing. This is often useful if you want to clean up some temporary state that is created by each test.
cleanup Unmounts React trees that were mounted with render. Please note that this is done automatically if the testing framework you're using supports the afterEach global and it is injected to your testing environment (like mocha, Jest, and Jasmine). If not, you will need to do manual cleanups after each test.
Order of Execution Once the describe blocks are complete, by default Jest runs all the tests serially in the order they were encountered in the collection phase, waiting for each to finish and be tidied up before moving on.
Each time a test run completes, the global environment is automatically reset for the next. Since tests are standalone and their execution order doesn't matter, Jest runs tests in parallel.
afterEach
.@Niels van Reijmersdal is on the right track. However, the downside of taking a screenshot in specDone
is that it runs after afterEach
, so if there's something in afterEach
that, say, navigates back a few screens, the screenshot you end up taking won't be representative of where the error took place. Here's an answer that allows you to take a screenshot immediately after the error occurs.
Add a custom Jasmine reporter for specStarted
and store the spec results to jasmine.currentTest
.
jasmine.getEnv().addReporter( {
specStarted: result => jasmine.currentTest = result
} );
The unintuitive thing about this is that even though we're storing this in specStarted
before the results are in, jasmine.currentTest
stores a reference to the result
object which will get updated dynamically as the spec runs so when we access it in our afterEach
, it will be holding the results of the spec properly.
Check for failedExpectations
in your afterEach
and take a screenshot if there's been any failures.
afterEach( async () => {
if ( jasmine.currentTest.failedExpectations.length > 0 ) { // There has been a failure.
await driver.takeScreenshot();
}
} );
Here is an example how I solved it in my project: (Assuming that afterEach is used only for taking screenshots and not for cleanup and other navigates)
const testIt = (name, action) => {
test(name, async () => {
try {
await action()}
catch (error) {
await screenshots.createScreenshot(page) //take screenshot
throw error
}
})
}
describe('Test scenario 1', () => {
testIt('test1 will Pass', async () => {
expect(true).toBe(true)
})
testIt('test2 will Fail', async () => {
expect(true).toBe(false)
})
afterEach(async () => {
//ignored
})
})
I use jest-html-reporters, and only failed tests will have attachment there (this solution did not require any other configurations). Result:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With