2

I am trying to write to test toggle action of accordion using cypress testing library. Below is the Markup for accordion, it is being toggled using checkbox hack :

 <div class='accordion'>
                <div class='accordion__item'>
                    <input style="display:none" type="checkbox"  id="item1"/>
                    <label class="accordion__itemLabel"for="item1">FAQ's</label>
                    <div style="display:none" class="accordion__itemContent"> FAQ Content Here </div>
                </div>
                <div class='accordion__item'>
                    <input style="display:none" type="checkbox"  id="item2"/>
                    <label class="accordion__itemLabel"for="item2">Contact us details</label>
                    <div style="display:none" class="accordion__itemContent"> Contact us details here </div>
                </div>
 </div>

and Tests is below :

    it("should toggle accordion ", () => {
            const checkbox = cy.findByRole({ role: "checkbox" });
            expect(checkbox.checked).equal(false);
            cy.get(".accordion__itemContent").invoke("display").equal("none")
            fireEvent.click(checkbox)
            expect(checkbox.checked).equal(true);
            cy.get(".accordion__itemContent").invoke("display").equal("block")
        })

The problem is cy.findByRole({ role: "checkbox" }); always returns undefined , how can I fix this or write above test in a right way .

Thanks

juliomalves
  • 42,130
  • 20
  • 150
  • 146
Bhupendra
  • 1,196
  • 16
  • 39

2 Answers2

4

Based on the Cypress Testing Library examples, instead of passing the role in an object (cy.findByRole({ role: "checkbox" })), you should be passing it as the first argument:

cy.findByRole("checkbox");

Beyond that, as Jonah pointed out, I think your test may be failing because you are trying to assign the return value of cy.findByRole to a variable. In Cypress, everything is asynchronous, so you need to chain your assertions. This is explained in more depth in the Cypress documentation.

Here is your test case rewritten with all of the above in mind:

cy.findByRole("checkbox").should("not.be.checked");
cy.get(".accordion__itemContent").invoke("display").equal("none")
cy.findByRole("checkbox")
  .check()
  .should("be.checked");
cy.get(".accordion__itemContent").invoke("display").equal("block")
Adam Vigneaux
  • 163
  • 3
  • 11
1

Why are you using cy.findByRole({ role: "checkbox" }); if the checkbox has nice id ( id="item1")? I would simply use cy.get('#item1') in order to get the required checkbox.

In addition, if you want to check the checkbox, the Cypress has method for that .check() and .uncheck() for deselecting.

In summary your code could be:

it("should toggle accordion ", () => {
        cy.get('#item1').should('not.be.checked')
        cy.get(".accordion__itemContent").invoke("display").equal("none")
        cy.get('#item1').check().should('be.checked')
        cy.get(".accordion__itemContent").invoke("display").equal("block")
    })
Jonah
  • 614
  • 7
  • 18
  • 1
    Thanks Jonah for reply , I am not using id selector to make the tests implementation free and rely only on findByRole / text etc.. from cypress-testing-library to ensure that tests don't break when we change the class names or id etc – Bhupendra Sep 12 '20 at 00:00