Home > Software design >  Cypress is looking for a property in the wrong object
Cypress is looking for a property in the wrong object

Time:09-13

Here are the two tests:

it("It should now show the Send Reset Instructions link", () => {
    fsrloginpage.SendResetInstructions("Send me reset").should('exist');   
});

it("Ihe Send Reset Instructions link should be disabled if the Email is empty", () => {
    fsrloginpage.UsernameEmailField().clear();
    fsrloginpage.SendResetInstructions("Send me reset").should('have.attr','disabled','true');   
});

Here is the .SendResetInstructions object definition:

    SendResetInstructions(linklabel){
        return cy.get('button[class^="mat-focus-indicator mat-button mat-raised-button 
        mat-button-base mat-primary"]').contains(linklabel);
    }

Here are my results:

 It should now show the Send Reset Instructions linkpassed
TEST BODY
1
getbutton[class^="mat-focus-indicator mat-button mat-raised-button mat-button-base mat-primary"]
2
containsSend me reset
3
assertexpected <span.mat-button-wrapper> to exist in the DOM
Ihe Send Reset Instructions link should be disabled if the Email is emptyfailed
TEST BODY
1
getinput[id="mat-input-2"]
2
clear
3
getbutton[class^="mat-focus-indicator mat-button mat-raised-button mat-button-base mat-primary"]
4
containsSend me reset
5
assertexpected <span.mat-button-wrapper> to have attribute disabled
AssertionError
Timed out retrying after 4000ms: expected '<span.mat-button-wrapper>' to have attribute 'disabled'
mcare/integration/FSRLoginBVT.spec.js:68:57
  66 | it("Ihe Send Reset Instructions link should be disabled if the Email is empty", () => {
  67 |     fsrloginpage.UsernameEmailField().clear();
> 68 |     fsrloginpage.SendResetInstructions("Send me reset").should('have.attr','disabled','true');   
     |                                                         ^
  69 | });
  70 | 
  71 | it("Ihe Send Reset Instructions link should be enabled if the Email is filled", () => {

So, it finds the object in the first test, but there is an assert (#1). On the second test, it seems to be ignoring the button, and trying to use the <span.mat-button-wrapper> object it mentioned in the assert (#2). I think it is doing this because the identifier for the button is within a span inside the button. Here is the code I am testing:

<button mat-button="" mat-raised-button="" color="primary"  disabled="true">
<span > Send me reset password instructions </span>
<span matripple="" ></span>
<span ></span>
</button>

Any thoughts on how to get around this? The best solution would be to get the developers to put IDs in their code, but that is not likely to happen in a timely manner.

CodePudding user response:

The issue comes from the fact that your .contains() yields the span element it finds, instead of the button element that wraps the three spans. The yielded span does not have disabled=true, so your assertion fails.

In order to return the parent element, there are a few strategies you could employ, but the easiest one would be to pass in the desired element type that .contains yields.

    SendResetInstructions(linklabel){
        return cy.get('button[class^="mat-focus-indicator mat-button mat-raised-button 
        mat-button-base mat-primary"]').contains('button', linklabel);
    }

CodePudding user response:

You don't really want those classes in your selector, they are for Material Design styling and are likely to be so common they don't differentiate the button.

Just id the button by it's label contents

SendResetInstructions(linklabel) {
  return cy.contains('button', linklabel);
}

I'd say the POM method naming also implies fixed text, for example you would never call this way, it would be confusing

fsrloginpage.SendResetInstructions("Log me in")

so you might as well encapsulate the text

SendResetInstructions() {
  return cy.contains('button', 'Send me reset');
}

Lastly, use the be.disabled assertion not the have.attribute assertion because disabled attribute is (sometimes) present or absent not true or false. be.disabled covers both scenarios.

fsrloginpage.SendResetInstructions().should('be.disabled');
  • Related