Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom timeouts are ignored on retry attempts. #8336

Closed
GCHQDeveloper911 opened this issue Aug 19, 2020 · 4 comments
Closed

Custom timeouts are ignored on retry attempts. #8336

GCHQDeveloper911 opened this issue Aug 19, 2020 · 4 comments
Labels
type: regression A bug that didn't appear until a specific Cy version release v4.8.0 🐛 Issue present since 4.8.0

Comments

@GCHQDeveloper911
Copy link
Contributor

GCHQDeveloper911 commented Aug 19, 2020

Current behaviour:

Given the following sample spec:

it('does very little', function () {
  cy.get('#notInTheDOM', {timeout: 15000}).should('exist')
})

When you first launch this spec file from the runner, the 15s timeout elapses before the test fails. If you then click retry (or edit the spec file, triggering an automatic retry) the test fails after just 3-4s

Desired behaviour:

The specified custom timeout should be respected on retry.

Test code to reproduce

Please see above.

Versions

Cypress 4.10-4.12, CentOS8, and Chrome 83

@jennifer-shehane
Copy link
Member

I'm not able to recreate this behavior - clicking the retry / editing the specfile maintains the original timeout.

Screen Shot 2020-08-20 at 3 58 38 PM

You may want to make sure that your file changes are being seen - that your app is not using service workers that prevent this. #702

Otherwise, we will need a fully reproducible example to look into this - maybe there's something in your support/plugins/config that is affecting this.

@jennifer-shehane jennifer-shehane added the stage: needs information Not enough info to reproduce the issue label Aug 20, 2020
@GCHQDeveloper911
Copy link
Contributor Author

GCHQDeveloper911 commented Aug 20, 2020

So it turns out that it's the following code that I'm adding as a support module to provide soft assertions that is breaking it!

let isSoftAssertion = false;
let errors = [];

chai.softExpect = function ( ...args ) {
    isSoftAssertion = true;
    return chai.expect(...args);
},
chai.softAssert = function ( ...args ) {
    isSoftAssertion = true;
    return chai.assert(...args);
}      

const origAssert = chai.Assertion.prototype.assert;
chai.Assertion.prototype.assert = function (...args) {
   if ( isSoftAssertion ) {
        try {
            origAssert.call(this, ...args)
        } catch ( error ) {
            errors.push(error);
        }
        isSoftAssertion = false;
    } else {

    origAssert.call(this, ...args)
    }    
};

// monkey-patch `Cypress.log` so that the last `cy.then()` isn't logged to command log
const origLog = Cypress.log;
Cypress.log = function ( data ) {
    if ( data && data.error && /soft assertions/i.test(data.error.message) ) {
        data.error.message = '\n\n\t' + data.error.message + '\n\n';
        throw data.error;
    }
    return origLog.call(Cypress, ...arguments);
};

// monkey-patch `it` callback so we insert `cy.then()` as a last command 
// to each test case where we'll assert if there are any soft assertion errors
function itCallback ( func ) {
    func();
    cy.then(() => {
        if ( errors.length ) {
            const _ = Cypress._;
            let msg = '';

            if ( Cypress.browser.isHeaded ) {

                msg = 'Failed soft assertions... check log above ↑';
            } else {

                _.each( errors, error => {
                    msg += '\n' + error;
                });

                msg = msg.replace(/^/gm, '\t');
            }

            throw new Error(msg);
        }
    });
}

const origIt = window.it;
window.it = (title, func) => {
    origIt(title, func && (() => itCallback(func)));
};
window.it.only = (title, func) => {
    origIt.only(title, func && (() => itCallback(func)));
};
window.it.skip = (title, func) => {
    origIt.skip(title, func);
};

beforeEach(() => {
    errors = [];
});
afterEach(() => {
    errors = [];
    isSoftAssertion = false;
});

Can't say that I understand why this breaks it... but could there be something in how Cypress handles support/index.js? Or can you see anything in this code that would cause it?

@jennifer-shehane
Copy link
Member

I am able to reproduce this in Cypress version 4.8.0-4.12.1 - this was a regression introduced in 4.8.0, however I am unable to reproduce this in 5.0.0.

Closing as resolved. Please update to our latest version to get this bug fix.

@jennifer-shehane jennifer-shehane added v4.8.0 🐛 Issue present since 4.8.0 type: regression A bug that didn't appear until a specific Cy version release and removed stage: needs information Not enough info to reproduce the issue labels Aug 21, 2020
@GCHQDeveloper911
Copy link
Contributor Author

Finally got round to upgrading to 5 and verifying this fixed the issue. Many thanks @jennifer-shehane !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: regression A bug that didn't appear until a specific Cy version release v4.8.0 🐛 Issue present since 4.8.0
Projects
None yet
Development

No branches or pull requests

2 participants