Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cy.contains shouldn't use content from script/style tags in the body #15947

Closed
duaneatat opened this issue Apr 12, 2021 · 6 comments
Closed

cy.contains shouldn't use content from script/style tags in the body #15947

duaneatat opened this issue Apr 12, 2021 · 6 comments
Labels
pkg/driver This is due to an issue in the packages/driver directory type: breaking change Requires a new major release version type: duplicate This issue or pull request already exists type: unexpected behavior User expected result, but got another

Comments

@duaneatat
Copy link

let testText = elem.textContent || elem.innerText || $(elem).text()

Since elem.textContent will include strings that are inside non-visible nodes like <script> and <style> tags, cy.contains can result in false-positives and false negatives. I discovered this while writing tests for a SSR app (using Next.js).

[Click Delete button]
cy.contains(deletedText).should("not.exist");

In this case, the test failed because the value of deletedText was found in body.textContent since that value was present in a <script> tag that was part of the original HTML.

cy.contains("Button that doesn't exist").click();

In this case, an element may get clicked if it contains a script tag that contains the text Button that doesn't exist. This happens pretty easily with our SSR app, where the react component names end up in a script tag, regardless of whether they are visible or not. So the test will pass on that line and proceed after clicking the body.

Is it possible to add an option to allow only visible contents to be matched (and internally use innerText)?
E.g. cy.contains("Visible text", {visibleOnly: true});

@sainthkh sainthkh added the stage: proposal 💡 No work has been done of this issue label Apr 13, 2021
@jennifer-shehane
Copy link
Member

@duaneatat Can you provide a full example of this? Because Cypress does filter out script and style tags when searching for text in contains at this line https://github.com/cypress-io/cypress/blob/develop/packages/driver/src/dom/elements.ts#L1140:L1140

@jennifer-shehane jennifer-shehane added stage: needs information Not enough info to reproduce the issue and removed stage: proposal 💡 No work has been done of this issue labels Apr 30, 2021
@duaneatat
Copy link
Author

duaneatat commented May 1, 2021

Sure! take a look at: https://codepen.io/markduane/pen/YzNojLQ

The line you reference above will indeed prevent matching on script or style tags, but it won't prevent matching an element that contains script or style tags. E.g. body.textContent will still have the script contents, so body will still be matched.

@jennifer-shehane
Copy link
Member

@duaneatat Can you provide an example of a failing test against this codepen? It looks like all of the text inside the script tag in this case is visible on the screen.

@duaneatat
Copy link
Author

My apologies, it only appears that way because the example was outputting textContent to the innerHtml of a div on the page. If you look here: https://codepen.io/markduane/pen/YzNojLQ you'll see the value that is logged into the Console includes the javascript, but that javascript isn't rendered to the page.

@jennifer-shehane
Copy link
Member

Ok, below is a reproducible example.

it('passes even though in script tag', () => {
  cy.visit('index.html')
  // should not pass, but does
  cy.contains('I am in the script tag in body')  
})

it('fails as expected', () => {
  cy.visit('index.html')
  // fails correctly
  cy.contains('I am in the script tag in head')
})
<html>
<script>
  console.log('I am in the script tag in head')
</script>
<body>
  <h1>Look at Console for values</h1>
  <script>
    console.log('I am in the script tag in body')
  </script>
</body>
</html>

Screen Shot 2021-05-04 at 3 10 18 PM

@jennifer-shehane jennifer-shehane changed the title cy.contains can give false positives and false negatives cy.contains shouldn't use content from script/style tags in the body May 4, 2021
@jennifer-shehane jennifer-shehane added stage: ready for work The issue is reproducible and in scope pkg/driver This is due to an issue in the packages/driver directory type: breaking change Requires a new major release version type: unexpected behavior User expected result, but got another and removed stage: needs information Not enough info to reproduce the issue labels May 4, 2021
@sainthkh
Copy link
Contributor

Duplicate of #14861.

@jennifer-shehane jennifer-shehane added type: duplicate This issue or pull request already exists and removed stage: ready for work The issue is reproducible and in scope labels Jul 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pkg/driver This is due to an issue in the packages/driver directory type: breaking change Requires a new major release version type: duplicate This issue or pull request already exists type: unexpected behavior User expected result, but got another
Projects
None yet
Development

No branches or pull requests

3 participants