cypress: Allow hiding assertion logs for `.should()` and `.and()` except on failure

Current behavior:

There is no way to hide logs when making assertions, for example, with should.

Desired behavior:

There is a way to hide passing assertions while still reporting failing assertions. Ideally these successful assertions could also be turned back on when running under a different log level.

This came up because I wanted a “safer” version of the get command, which would by default assert that there is only 1 element found (unless an explicit length option was passed) and that the element is visible (unless an explicit noVisibleCheck option was passed), since I’ve seen tests fail or falsely succeed because of overbroad selectors or when an element was present in the DOM but not visible. Cypress tests run fast enough that doing this shouldn’t add significantly to the test run time.

However, when I do this, I end up with a ton of extra logs for each get, which clutters the test output. I’d like a way to disable these logs by default, unless the assertions fail.

Test code to reproduce

https://github.com/ncknuna/cypress-test-tiny/blob/master/cypress/support/commands.js#L45

Versions

Cypress 4.8.0 OSX 10.15.5 Chrome 83.0.4103.61

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Reactions: 51
  • Comments: 36 (2 by maintainers)

Most upvoted comments

I would like this feature as well, to only log assertions that fail.

As a workaround for assertions that are easily checked up front, you can use a somewhat redundant approach like:

            let actual = ctx.maybeGet(key);
            // if we always perform the 'expect', cypress log becomes very busy.
            // detect the failure condition and repeat with chai assertion so it 
            // surfaces in the log and fails the test
            if (!actual) {
                expect(actual, `${this.id}:unreadactBody:${key}`).to.not.be.empty;
            }

+1

I like to check that a cookie exists before each outgoing api request & suppressing this assertion would clean up test logs quite nicely 👍

it sucks that there is still no solution to this issue after more than 3 years. In our case we want to assert on the contents of a file, which results in the whole file being printed out on the log… 😦

Aside from the issue of log clutter, when performing some large validations, I noticed that using expect() takes far longer than a plain JS conditional, which I assume is due to the logging behavior.

Here’s a sample I prepared to reproduce the behavior.

describe('Compare Chai expect() to JS conditional', () => {
    let sampleString = "expect vs conditional"
    
    it('Check equality using expect()', () => {
        for (let i=0; i < 4000; i++){
            expect(sampleString).to.equal(sampleString)
        }
    })

    it('Check equality using JS to trigger expect()', () => {
        for (let i=0; i < 4000; i++){
            if(sampleString !== sampleString)
                expect(sampleString).to.equal(sampleString)
        }
    })
})

Using expect() took ~30 seconds, whereas the conditional took about 0.02 seconds.

For the time being, is there anything lacking in simply using a plain conditional to trigger expect() when the assertion should fail?

As a work around, “native” chai expect() will not generate a Cypress log.

  • add chai package to the project
  • at top of spec import {expect} from 'chai'
  • use .should() with callback, e.g: .should($els => expect($els.length).to.eq(2))

If assertion fails, the error appears in the log in the normal way.

Anybody see any cons for this method?

+1. The use case this would solve for us is for example:

  cy.request(myUrl).then((response) => {
                expect(response.headers['content-type']).to.contain('application/pdf');
                expect(response.body).to.have.length.gt(500);
            });

This is checking that the response is a reasonably sized pdf. This currently prints out the whole pdf in the log. 😦 I’m open to other ideas of how to do this if there’s a better way. 😃

+1 I want to assert that a local storage token exists before I get it to send as an auth header before any cy.request. Cypress will often look for it quicker than it is set, so an assertion seems like the best way, but then it can lead to many weird assertions in the log.