'Retrieve text from elements in Cypress

The html structure is shown below:

<app-screen _ngcontent-put-c111>
    #shadow-root (open)
        <style>...</style>
        <style>...</style>
        <style>...</style>
        <style>...</style>
        <style>...</style>
        <div class="app-toolbar">
            <app-toolbar-root class="ng-star-inserted">
                #shadow-root (open)
                    <style>...</style>
                    <style>...</style>
                    <style>...</style>
                    <style>...</style>
                    <style>...</style>
                    <div class="app-container">
                        <div class="top-level-bar">
                            <div id="csrContent">
                                <app-csr-content _ngcontent-put-c121>
                                    <div class="csr-content">
                                        <app-csr-toolbar class="csr-content_toolbar">
                        <csr-toolbar class="csr-toolbar">
                            <h3 class="csr-h3">
                                " Student "
                                <span _ngcontent-put-c121> - Details </span>
                            </h3>
                        </csr-toolbar>
                    </app-csr-toolbar>
                                    </div> 
                                <app-csr-content>
                            </div>
                        </div>          
                    </div>      
            </app-stud-container>
        </div>
</app-screen>

I am trying to retrieve the text like this:

cy.get(app-screen).find(.csr-content_toolbar .csr-toolbar h3).should('contain', 'Student - Details');

But the below error is displaying:

Timed out retrying after 4000ms: expected '<h3.csr-h3>' to contain 'Student - Details'

When I send the expected text to contain 'Student' alone, then it passes. Does it not suppose to get the text from the child elements as well as 'Student - Details'?



Solution 1:[1]

The " Student " part of the text is a Text node, which does not behave exactly as you might expect in Cypress.

You can test for all the text including whitespace,

cy.get('csr-toolbar h3')
  .should('contain', '\n      " Student "\n       - Details \n  ')

or you can trim beginning and end, but you still have the newline and spaces in between

cy.get('csr-toolbar h3')
  .invoke('text')
  .then(text => text.trim())
  .should('eq', '" Student "\n       - Details')
})

or you can extract the text nodes and trim them

cy.get('csr-toolbar h3')
  .then($el => $el.contents())   // text nodes and span
  .then($nodes => [...$nodes].map(node => node.textContent.trim()) ) // extract text
  .should('deep.eq', ['" Student "', '- Details', ''])   // check against an array

or you can add a step to join then up

cy.get('csr-toolbar h3')
  .then($el => $el.contents())   // text nodes and span
  .then($nodes => [...$nodes].map(node => node.textContent.trim()) ) // extract text
  .then(texts => texts.join('')
  .should('eq', '" Student "- Details')

It's probably better to test the two elements separately

cy.get('csr-toolbar')
  .find('h3').should('contain', 'Student')
  .find('span').should('contain', '- Details')

Solution 2:[2]

As the asserted string includes leading and trailing whitespaces you need to use:

cy.get('app-screen').find('.csr-content_toolbar .csr-toolbar h3').should('include.text', ' Student - Details ')

If you want those leading and trailing whitespaces to be ignored out-of-box without workarounds, then consider using cy.contains(). Otherwise you will probably need to make use of a solution like the one mentioned here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2