Open StanFisher opened 5 years ago
@jennifer-shehane Thanks for looking at this! Why was this labeled as a feature instead of a bug?
I marked it as a feature because once the test finishes, catching any possible errors is NOT something Mocha would do - because by then the test has finished. In Cypress the exception is there because the browser window still stays open after the test. If we closed the browser window immediately, the exception would never happen. So that's why I marked it as a feature
I believed it was Mocha's implementation to not run after
hooks on error of the test suite, but after further investigation, I see that Mocha does run after
hooks on test failure. To quote the Mocha team on their hook execution:
- If
before
hook fails, tests in a suite (where the hook is) and sub-suites are not executed. Ifafter
hook exists, it is called.- If
beforeEach
hook fails, remaining tests in that suite (where the hook is) or sub-suites are not executed. The remainingbefore
hooks are also not executed. IfafterEach
hooks exist in that suite, or parent suites -- they get executed. The suite'safter
hooks are also executed.- If
after
hook fails, no additional hooks are called.- If
afterEach
hook fails, remaining tests in that suite (where the hook is) and sub-suites are not executed. The remainingafter
hooks (from parent suites) are executed.after
hooks are executed 'up' starting from the suite of the last executed test, finishing with a suite where the hook is (inclusively).After any hook error, the next sibling suite (relative to the suite with hook error) is executed.
This allows writing test hooks in a symmetrical manner:
before
(each): allocate all resources for this and child test suites or testsafter
(each): free all resources, allocated bybefore
(each). Make sure, this will work correctly, even if some resource allocation failed -- it will still be called.
Based on this, I would qualify this as a bug in Cypress. We are upgrading Mocha to its latest version here https://github.com/cypress-io/cypress/issues/2528 I will see if the upgrade fixes this issue, if not, then it will require more investigation.
I am unable to check this out in our v4 branch at the moment, but here is the reproducible code for the future. It's strange that the code in the after
hook does run, but the click
is not performed.
describe('page', () => {
beforeEach(() => {
cy.visit('https://www.cypress.io')
})
// ***** NOTE *****
// The presence of this failing tests means that the clicks in the 'after' block don't work.
// If this test is either removed or changed to be passing, then the 'after' block will work.
it('fails', () => {
cy.wrap(false).should('be.true')
})
after(() => {
cy.get('#main-nav>li')
.contains('Support').click()
cy.url().should('contain', '/support/')
})
})
Any workaround for this one? After i run spec file, i want to cleanup few thing in case if anything fails.
I'm having the same issue. In the afterEach i need to perform cleanup after each test, undoing certain UI actions, but if the test failed, any action in afterEach doesn't work properly.
I have to do a weird workaround for now, having my clean up code in beforeEach, but, it won't perform clean up on the last test, so I need to also add a dummy test to the very end.
Is this fixed ?
No this is not fixed. Issues will be closed when they are fixed.
Hi Everyone. I am also experiencing this issue. Is there any update on this issue? Maybe a workaround? @jennifer-shehane
My previous example for this bug no longer exhibits the error properly since the website under test has changed.
I tested this against the upcoming Cypress 4.0 release and verified that this is not fixed in that release.
spec.js
describe('page', () => {
context('after click clicks', () => {
it('passes', () => {
cy.visit('https://example.cypress.io').then(() => {
expect(false).to.be.false
})
})
after(() => {
cy.get('.home-list')
.contains('Querying').click()
cy.url().should('include', '/querying')
})
})
context('after click does not click', () => {
it('fails', () => {
cy.visit('https://example.cypress.io').then(() => {
expect(false).to.be.true
})
})
after(() => {
cy.get('.home-list')
.contains('Querying').click()
cy.url().should('include', '/querying')
})
})
})
I hope this will be solved soon, or at least for someone to offer a workaround. I wrapped a lot of my tests with this, it seems to be super useful, except it doesn't work yet. :)
@Brestachan you can add a dummy test that always passes before the next set of tests run. This will ensure that your after block click action is executed properly. Not the best workaround, but I found this helpful for tests that I know are failing with open bugs that might be a while before they work again.
This is a duplicate of #1477, by the way.
Type also causes this error:
describe('after hook no click', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io')
})
// The presence of this failing tests means that the clicks in the 'after' block don't work.
it('fails', () => {
cy.wrap(false).should('be.true')
})
after(() => {
cy.get('.nav')
.contains('li', 'Utilities').click()
cy.url().should('include', '/utilities')
})
})
describe('afterEach hook no type', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io')
})
// The presence of this failing tests means that the clicks in the 'after' block don't work.
it('fails', () => {
cy.wrap(false).should('be.true')
})
afterEach(() => {
cy.get('.nav')
.contains('Utilities').click()
cy.url().should('include', '/utilities')
})
})
describe('after hook no type', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})
// The presence of this failing tests means that the clicks in the 'after' block don't work.
it('fails', () => {
cy.wrap(false).should('be.true')
})
after(() => {
cy.get('#email1').type('foo').should('have.value', 'foo')
})
})
describe('afterEach hook no click', () => {
beforeEach(() => {
cy.visit('https://example.cypress.io/commands/actions')
})
// The presence of this failing tests means that the clicks in the 'after' block don't work.
it('fails', () => {
cy.wrap(false).should('be.true')
})
afterEach(() => {
cy.get('#email1').type('foo').should('have.value', 'foo')
})
})
Is it possible to get this into a minor or patch release? I cannot use the dummy test idea because then cookies will have already been cleared.
This issue is blocking several tests of us for straight solution. Though we have overridden the mocha on cypress, Is there a deadline for this please?
use force type and force click in after or afterEach Hooks
use force type and force click in after or afterEach Hooks Unfortunately, also variables that are taken form external js file with const are not resolved
Still an issue in version 7.7.0. Is it fixed in 8?
Still an issue in 8.4.1 :(
Is this not fixed yet? Really need an approach to run a few code even if tests fail! Blocking a whole suite of cases for us!
Having the same issue in afterAll() when a testcase fails! I'm using cypress version 8, and have been relying of afterAll() to perform cleanup after test execution.
Still expirience this issue in version 9.7.0 Need the fix so badly, cause it blocks bunch of tests. In fact not only click or type is not working, but also no waiting for element is applied, all should checks are executed once and imediately.
Facing same issue in version 10.3.1 The after hook don't work if one test fails. The after hook doesn't recognize the properties like find element in DOM and also not able to click Hope to see a fix soon. Thank you Cypress community
I'm not sure if I ran into the same issue, but I had a problem with a couple clicks not working in an afterEach
(they seemed to work, cypress didn't say that they failed, but then the action in the UI didn't happen) and I added force: true
and that resulted in them working.
Problem still exists in v10.2.0
As a temp solution I just add another it hook for data cleanup (not nice) Is there any workaround for this ?
The only way for now is to add dummy test which will always be passed.
why has not it fixed since 2018? Its really annoying bug ^( how to catch errors in a running test and delete the created data?
I still have the issue in 12.7 , but there is a workaround you can use .click({ force: true })
it worked for me
Can we please get a fix for this?
Is this a joke, it passed like 4 years and haven't been fixed since ?
Hello! I encountered the same thing. If test fails - some of the components stop reacting to click() in afterEach hook. Even "force click" is not helping... Cypress V12.7. Are there any more suggestions? I have a lot of tests and they are all failing because of this issue...
I do encounter this issue too. After some investigation, here are some workarounds which works for me:
For click() API, Cypress.$(cssSelector).trigger('click') can be used;
For type() API, a custom function setInputValue() can work (for React);
const setInputValue = function (input: any, value: any) {
const lastValue = input.value;
input.value = value;
const event: any = new Event('input', { bubbles: true });
// Hack React 15
event.simulated = true;
// Hack React 16
const tracker = input._valueTracker;
if (tracker) {
tracker.setValue(lastValue);
}
input.dispatchEvent(event);
};
And, cy.wait() works in this situation, so you can use it to wait if you have to.
I understand using the after hook is discouraged ([https://docs.cypress.io/guides/references/best-practices#Using-after-or-afterEach-hooks]()) and we actually clean up right before each test run, but I find it quite frustrating having to launch the tests again and stop it 1 second later only for the app (DDBB) to have the initial state. Furthermore, I dont get why the code fails in the after hook even if discouraged, it's still a bug, right? Thanks!
5 years with no solution is quite a let down as this is causing a major issue in data cleanup for us. Our initial approach was to have it clean up on a blank test to start however if the previous set ran without issue then there would be no data to clean and thus fail the afterEach hook thus failing the rest of the run. So frustrating
I actually cannot use force click as my after hook fails on loading a page and checking that intercepted call has status 200, it just doesn't wait as expected. I spent half a day thinking I must have made a mistake, but same code works if test pass and it actually looks like same rootcause. Considering that conditional actions are not a strength in Cypress I have hard time thinking how to clean up state before not to mention doing revolution to delete things from db (that could be a benefit but I am not sure we have ability to do that currently)
I've been having the same issue for days! Just stumbled across the workaround to add a test to the end of the run that will always pass. This solves the problem for the after all hook. I'm not using after each so can't comment on that. Needs to be fixed though!
This issue is still reproducible on Cypress 13.6.4
Current behavior:
Any click event in the after block fails if one of the tests in an it block fails.
Desired behavior:
Click events in the after block should succeed even if there are tests that fail.
Steps to reproduce:
I forked the cypress-tiny-test repository and set up a reproducible example in the latest commit. https://github.com/StanFisher/cypress-test-tiny
Here's the commit containing the failing after block. https://github.com/StanFisher/cypress-test-tiny/commit/c185242f3fdd30715d16fc44e393e092c30c4d58
Notice that if the failing test is changed to succeed, then the two click events in the after block succeed.
Versions
Cypress 3.1.2 macOS Mojave 10.14.1 Chrome 70.0.3538.102