cypress icon indicating copy to clipboard operation
cypress copied to clipboard

Feature Request: Custom error messages

Open manuelJung opened this issue 5 years ago • 14 comments

if this is not the right place for feature-request, I apologize.

I have an idea for more project-individual error messages:

cy.get('my-element > li.product-widget')
  .pinCustomError('ops! not enough product widgets were rendered')
  .should('have.length', 12)
  .unpinCustomError()

When some error is thrown between a .pinCustomErrro(msg) and .unpinCustomError() the original error message gets replaced with the provided message. That would make the errors way more descriptive

another example:

cy.pinCustomError('product widget did not render')
  .get('.product-widget')

As a developer I write a lot of tests. An error like CypressError: Timed out retrying: Expected to find element: '.product-widget', but never found it. may not really tell me why the test failed. especially if it is a way more complex test than above.

Custom error messages could really help me to identify the problem faster for tests i wrote months ago. This implementation should be flexible enough to hande several use-cases. Another nice side-effect would be, that i can document my tests this way

manuelJung avatar Feb 15 '20 21:02 manuelJung

The error messages of assertions are customizable when using the explicit expect or assert assetions, although this is poorly documented so I understand it not being found.

it('repro', () => {
  cy.get('div').should((div) => {
    expect(div, 'Text should match here').to.contain('foo')
  })
})

Unfortunately, this signature doesn't quite work from within Cypress commands .should() or .and() chainer. I'll double check on this, but I'm not aware of a way.

jennifer-shehane avatar Feb 18 '20 06:02 jennifer-shehane

I would love to have that, I will give it a try to the way you add @jennifer-shehane. Thanks!

estefafdez avatar Feb 25 '20 12:02 estefafdez

You saved my day @jennifer-shehane ! It works perfectly. Thank you so much

terrynguyen255 avatar Sep 11 '20 10:09 terrynguyen255

@jennifer-shehane - it doesn't seem to work, at least in the following case. Any idea? Thanks.

export function assertLoggedIn(): void {
    cy.get('navigation-tree').should((tree) => {
        expect(tree, "Not logged in - can't locate navigation tree").to.be.visible;
    });
}

The log: (note the error message it's not the custom one)

  1) UI tests for Test in CypressPocTestWithCmdLine.java
       uses a bogus user in UI:
     AssertionError: Timed out retrying: Expected to find element: `navigation-tree`, but never found it.
      at Object.assertLoggedIn (http://localhost:49159/__cypress/tests?p=cypress/integration/tests/basicCypressSuiteInvoking.ts:172:31)
      at Context.eval (http://localhost:49159/__cypress/tests?p=cypress/integration/tests/basicCypressSuiteInvoking.ts:209:17)

Using the latest Cypress version.

github-ronk avatar Sep 16 '20 13:09 github-ronk

Allowing .should() and .and() chainers to take an options array that could contain a custom errorMessage option or something of the sort would be wonderful!

mwren-mshanken avatar Sep 29 '20 19:09 mwren-mshanken

I am trying to parse a big file and assert that a string is not included in the file using cypress. I want to replace the assertion message to keep my log clean. I have tried this: I wraped the content as follow:

cy.task('parsePdf', filePath)
  .its('text')
  .then(($txt) => {
    cy.wrap($txt).as('content');
  });

Then I have tried to assert this using Chai expect and insert a custom message in two ways which both result the same:

First:

cy.get('@content').should(($txt) => {
  expect($txt).to.not.include(
    'text that should not be in the content',
    'Custom error message'
  );
});

Second:

cy.get('@content').should(($txt) => {
  expect($txt, 'Custom error message').to.not.include(
    'text that should not be in the content');
});

Result:

Custom error message expected Full report content to not include text that should not be in the content.

What I looking for is only logging Custom error message in a failure.

Expected:

Custom error message

@jennifer-shehane Is there any workaround to not see the Full report content or at least replace it somehow with alias?

aliakhlaghi93 avatar Sep 30 '21 14:09 aliakhlaghi93

Hello! 😊 @jennifer-shehane Is there any update on this? I think it would be a useful feature that I could use at work to give more insight on what that check does.

zolirevesz avatar May 10 '22 13:05 zolirevesz

@jennifer-shehane for some reason expect(element, 'custom message).to.contain('some text') works while expect(element, 'custom message').to.exist doesn't

it('test custom error message', () => {
        cy.visit('https://mywebsite.com/')
        cy.get('button[type="submitfoo"]').should((button) => {
            expect(button, 'submit button should exist').to.exist;
        })
    })

AssertionError: Timed out retrying after 20000ms: Expected to find element: button[type="submitfoo"], but never found it.

it('test custom error message', () => {
        cy.visit('https://mywebsite.com/')
        cy.get('button[type="submit"]').should((button) => {
            expect(button, 'submit button should exist').to.exist;
            expect(button, 'the button should contain NEXT').to.contain('Next');
        })
    })

AssertionError: Timed out retrying after 20000ms: the button should contain NEXT: expected '<button>' to contain 'foo'

orennu avatar Dec 01 '22 11:12 orennu

This is a must have and would make reports like allure more informative and easier to debug. You guys are already awesome for making a cypress, but if you make something like cy.findByTestId('some-test-id').should('be.visible', {error: 'Response was successful but notification is not visible'}) you would be even more awesome.

justasdev avatar Oct 25 '23 17:10 justasdev

It would be great if it were possible to add custom messages to the "get" selector as well.

Sometimes I have a complex "get" expression that is not easy to read. I try compensate this by adding comments:

// Search inside the user grid
cy.get('.x-grid').within(element => {
    // Get the fifth column of the user grid
    cy.get('.x-grid-cell:nth-child(5)').contains('John');
})

If the second "get" selector fails you get a reather cryptic error message: Error: Timed out retrying after 4000ms: Expected to find element: .x-grid-cell:nth-child(5), but never found it..

It would be nice if cypress would support custom messages for selectors as well. Then the following would be possible:

cy.get('.x-grid', { message: 'Get the user grid'}).within(element => {
    cy.get('.x-grid-cell:nth-child(5)', { message: 'Get the fifth column in user grid'}).contains('John');
})

And the error message would be: Error: Timed out retrying after 4000ms: Get the fifth column in user grid..

BillyTom avatar Oct 31 '23 10:10 BillyTom

Just one more "me too" vote.

Virtually every other test runner/assertion library provides a way to supply a custom assertion message. For instance, here's how they do it in Jest, Chai, and Ava.

Cypress should have this essential feature also!

machineghost avatar Nov 19 '23 21:11 machineghost

I vote on this too.

balrajOla avatar Jan 28 '24 17:01 balrajOla

This feature request is 4yo now. Is there any plans to implement it?

justasdev avatar Mar 14 '24 13:03 justasdev

As per @jennifer-shehane comment above:

Unfortunately, this signature doesn't quite work from within Cypress commands .should() or .and() chainer. I'll double check on this, but I'm not aware of a way.

Is there a way to:

  1. have a custom error displayed for an assertion made with .should()?
  2. have a custom error be displayed without the original chai/cypress error?
cy.visit("https://www.google.com/en");

cy.get("input[type=submit]").eq(2).should("have.value", "Google Search"); // error message: expected <input.gNO89b> to have value Google Search

cy.get("input[type=submit]").eq(2).should("have.value", "Google Search", "Custom error"); // error message is the same as the original, does nothing

cy.get("input[type=submit]").eq(2).should(btn => {
    expect(btn, "Custom error").to.have.value("Google Search");
}); // error message: Custom error: expected <input.gNO89b> to have value Google Search
// this displays the custom error but appends the original chai/cypress

SebMoreno avatar May 07 '24 01:05 SebMoreno