Cypress testing, is there a way to reset the subject after using "have.attr"?

Viewed 241

I'm still new to Cypress but this behavior is driving me batty. Thanks for any help in advance! So, 2 tests on 2 pages. I can run this code on a page in a previous test:

        cy.get('meta[property="article:tag"]')
            .should("have.attr", "content")
            .and("include", subex_subscriberexclusive_only)
            .and("not.include", subex_subscriberexclusiveBeta_only);

Then in a subsequent test, on another page, I run the same code, and it seems by the "not.include" step, this time the subject has changed. At least that is the error I'm getting.

So same code, just swapping variables because the test is to make sure the opposite is true on the 2nd page:

        cy.get('meta[property="article:tag"]')
            .should("have.attr", "content")
            .and("include", subex_subscriberexclusiveBeta_only)
            .and("not.include", subex_subscriberexclusive_only);

The error reads:

The invalid subject you asserted on was:
  > undefined

Another odd thing is that if I comment out the "not.include" test, everything passes. I'm guessing the subject changes after the "include" test, that is where the subject changes.

So is there a way to reset the subject? Or is there another way I should structure this test? I don't want to just comment out the negative test, I want to know we have what we need and not what we don't (And it worked the first time).

Some other things I've tried are using invoke and its but that seems to lead to the same outcome but only for this second page. I can also remove the first test on the first page or swap order and it always hangs up here. Perhaps I made a typo I need second eyes on. In any case, thanks!

Latest try:

        cy.get('meta[property="article:tag"]')
            .should("have.attr", "content")
            .should(($meta) => {
                expect($meta).to.include(subex_subscriberexclusiveBeta_only)
                expect($meta).not.to.include(subex_subscriberexclusive_only)
            })

Same hang up.

Thanks!

1 Answers

Just a guess here, but I'm wondering if you may be running into something similar that I've noticed where the should("not.have.attr", ...) chainer appears to be returning the value of the attribute as the next subject. I haven't found any documentation on this in particular but in some light troubleshooting it seemed to be the case for me.

What I would suggest trying to tease out whether this is also affecting you would be to try one of the following variations of your last code example.

        cy.get('meta[property="article:tag"]')
            .should(($meta) => {
                cy.wrap($meta).should("have.attr", "content")
                expect($meta).to.include(subex_subscriberexclusiveBeta_only)
                expect($meta).not.to.include(subex_subscriberexclusive_only)
            })

Or using expect instead of should on the wrapped element:

        cy.get('meta[property="article:tag"]')
            .should(($meta) => {
                expect($meta).to.have.attr("content");
                expect($meta).to.include(subex_subscriberexclusiveBeta_only)
                expect($meta).not.to.include(subex_subscriberexclusive_only)
            })

I'm not 100% if this will solve your problem but it may and it would be helpful to know whether others have bumped into a similar snag or gap in the otherwise fantastic Cypress documentation.

Update: I was able to confirm that have.attr does in fact change the subject as it is documented at least in the current site. The suggestions above thus, as long as I properly understood the intent, should offer a path forward for resolving your issue.

References:

Related