Do you want to request a _feature_ or report a _bug_?
feature request.
What is the current behavior?
Cannot find a way to get test status in afterEach()
What is the expected behavior?
Need a way to get test status, like mocha can do this with this.currentTest.state
.
Please provide your exact Jest configuration and mention your Jest, node,
yarn/npm version and operating system.
Jest 22.0.6
+1
In combination with Puppeteer it would be perfect to get the test status in afterEach().
e.g. we could create a screenshot in afterEach() if status is failed
As a data point, my company's test suite uses the mocha currentTest.state
to rollback the current database transaction in a particular way if there was a failure. Seems to be a blocker for switching to Jest though I confess I'm not very experienced with the ins and outs of either our test suite or Jest :)
I use Browserstack to run my integration test, and I need to flag the browserstack build as complete or fail.
I must be in afterEach and / or afterAll because I need the driver instance currently used (see https://github.com/jeromemacias/nodium/blob/master/src/hook/browserstack.js)
Same as the others, we are using Jest with the TestObject/SauceLabs device farm and we need a way to get the current test status to update the test status on the TestObject website. It would be very useful to have something like this.currentTest
in Mocha!
I was able to find a workaround to get the current test status using jasmine custom reports.
const reporter = {
specDone: async result => {
console.log(result.status);
await driver.quit();
}
};
jasmine.getEnv().addReporter(reporter);
Is there any progress on that?
Will this feature be implemented in the near future
Need to decide whether to use Jest or not for testing based on this feature availability
I believe the category of "passing state into tests/hooks" suggestions is currently not a top priority unfortunately.
Note that we recommend not using any jasmine
-specific APIs like one of the comments suggests because jest-jasmine2
will be replaced as a default by jest-circus
(likely in the next major).
This seems like something that could be implemented in user land? And made into reusable helpers with something like
test('a', saveTestState(() => {/* ... */}));
afterEach(ifTestFailed(() => {/* ... */}));
Hi @jeysal , thanks for the suggestion!
Can you please elaborate more about how to implement the saveTestState
and ifTestFailed
?
I was thinking about something like:
let lastTestFailed;
export const saveTestState = async (testFn) => {
try {
await testFn()
lastTestFailed = false;
} catch (err) {
lastTestFailed = true;
throw err
}
}
export const ifTestFailed = async (hookFn) => {
if(lastTestFailed) await hookFn()
}
Not tested and not complete e.g. because it doesn't take the possible done
callback into account, but that's the general idea.
I found a solution using jest-circus
to implement a new testEnvironment
, here is my code:
Create a file in the same directory as jest.config.js
, named seleniumEnvironment.js
const JSDOMEnvironment = require('jest-environment-jsdom-fifteen')
class SeleniumEnvironment extends JSDOMEnvironment {
constructor(config, context) {
super(config, context)
this.global.hasTestFailures = false
}
handleTestEvent(event, state) {
if (event.name === 'test_fn_failure') {
this.global.hasTestFailures = true
}
}
}
module.exports = SeleniumEnvironment
In jest.config.js
I added: testEnvironment: './seleniumEnvironment',
Now in your afterEach
/afterAll
/ you can detect test failures via this.global.hasTestFailures
.
I am also looking for a way to do this.
@pplante this didn't work for me. I have also never used jest-circus
though. Are there any additional steps needed?
@rgomezp You need to define the jest-circus
as test runner:
https://github.com/facebook/jest/tree/master/packages/jest-circus
Hack the global.jasmine.currentEnv_.fail works for me.
describe('Name of the group', () => {
beforeAll(() => {
global.__CASE_FAILED__= false
global.jasmine.currentEnv_.fail = new Proxy(global.jasmine.currentEnv_.fail,{
apply(target, that, args) {
global.__CASE__FAILED__ = true
// you also can record the failed info...
target.apply(that, args)
}
}
)
})
afterAll(async () => {
if(global.__CASE_FAILED__) {
console.log("there are some case failed");
// TODO ...
}
})
it("should xxxx", async () => {
// TODO ...
expect(false).toBe(true)
})
});
I recently had to get access to the test name during the test, so I followed this comment https://github.com/facebook/jest/issues/7774#issuecomment-520780088.
My plan is to use jasmine.currentTest.failedExpectations.length > 0
to identify if there are errors in afterEach()
EDIT: FWIW, it works with playwright, failedExpectations
includes TimeoutError
from playwright.
afterEach(() => {
console.log(jasmine.currentTest)
console.table(jasmine.currentTest)
})
it("asdf", async () => {
await page.waitForSelector("does-not-exist", {
timeout: 1000
})
// expect(true).toBe(false)
})
Leaving our solution here in case it's useful to anybody else.
You can store current spec results in Jasmine and access it in afterEach
.
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's a link to my StackOverflow answer as well: https://stackoverflow.com/a/62557472/293280
How can I access jasmine in the .test.js files? I'm getting 'jasmine' is not defined.
when I try to add a reporter.
How can I access jasmine in the .test.js files? I'm getting
'jasmine' is not defined.
when I try to add a reporter.
I added the reporter in our Appium's driver.js
file. There, jasmine
is automatically setup (by Jest?) as a global. ESLint even complains about it not being defined but it's available at runtime.
as @joshuapinter explained here:
https://stackoverflow.com/a/62557472/293280
you can add an custom reporter to get access.
I created a little helper function:
let currentSpecResult: jasmine.CustomReporterResult;
jasmine.getEnv().addReporter({
specStarted: (result) => currentSpecResult = result,
});
export function getCurrentSpecResult() {
return currentSpecResult;
}
so I can import it in any spec and as a side effect, the reporter gets registered (but only if I use it and only once):
import { getCurrentSpecResult } from './get-current-spec-result.ts';
describe('get spec result', () => {
it('should fail', () => {
fail('!');
});
afterEach(() => {
const result = getCurrentSpecResult();
const failed = result.failedExpectations?.pop();
expect(failed).toBeTruthy();
});
});
wicked? ;-D
Most helpful comment
+1
In combination with Puppeteer it would be perfect to get the test status in afterEach().
e.g. we could create a screenshot in afterEach() if status is failed