How to get nested multi-level div returned in Cypress (Material-UI Dialog)

Viewed 2184

I am trying to get the dialog text from a dialog box written using material-ui. It looks a little like this:

<div class="dialog"><div> 
   <div>
      <div style="">
         <div style="">
            <div style="">Some Text I want to verify</div>
            <div style""></div>
          </div>
      </div>
   </div>
</div>

I have tried solving this from two sides;

  1. trying to add some sort of unique id to the dialogText (i.e. via data-test tag), but these divs appear to be generated from within the material-ui library.
  2. in Jest/Puppeteer I managed to successfully use the following (probably brittle) selector to solve the same problem:

    const dialogText = await page.$eval('[class="dialog"] > div:first-child > div:first-child > div:first-child > div:first-child', e => e.innerHTML);
    expect(dialogText).toBe('Some Text I want to verify');
    

I have tried the same sort of (brittle) approach in Cypress:

cy.get('.dialog > div:first-child > div:first-child > div:first-child > div:first-child').should(($dialog) => {
  const text = $dialog.text()
  cy.log('nested div tex: ', text);
}

But I get null back

I think 1) is generally a more favourable approach as it makes the code more testable (at least in my new-to-cypress state).

However, in the absence of that, 2) should start with the "dialog" class and get whatever text is in that child(x4) div and compare it against an expected value in order to get a decent message if it isn't as expected.

Right now I am struggling to get cy.get and cy.find to return anything.

Thanks

1 Answers

OK, so after much swearing I tried just getting the JS Path from devTools, and that worked...

cy.get('.dialog > div:nth-child(1) > div > div > div:nth-child(1)').should('have.text', 'Some Text I want to verify')

Weirdly, Cypress did not like

cy.get('.dialog > div:nth-child(1) > div > div > div:nth-child(1)').should(($div) => {
  const theText = $div.text();
  cy.log('Log out of dialog Text: ', theText);
}); 

It logged out the text fine but then threw an error "Cannot read property 'text' of null".

This is obviously a brittle selector, but will tide me over untill I work out how to inject data-* attributes in the generated material-ui dialog modal. Probably worth a rephrased question on here from that perspective.

Related