Skip to content

Commit

Permalink
fix: cy.contains() ignores <style> and <script> without removin…
Browse files Browse the repository at this point in the history
…g them. (#19424)

* fix

* Merge tests.

* fix

* Apply suggestions from code review

Co-authored-by: Emily Rohrbough  <[email protected]>

* kick off build again

Co-authored-by: Emily Rohrbough <[email protected]>
Co-authored-by: Matt Henkes <[email protected]>
  • Loading branch information
3 people committed Dec 20, 2021
1 parent 593d4b8 commit 3250945
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 20 deletions.
20 changes: 20 additions & 0 deletions packages/driver/cypress/fixtures/content-in-body.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,25 @@ <h1>Script and Style in the body</h1>
h1 { font-size: 32px }
</style>
</div>

<!--
// https://github.com/cypress-io/cypress/issues/19377
Below is added to ensure `style`, `script` tags are not removed by `cy.contains()` command.
-->
<p>Hello</p>
<button id="my_button_1" style="display: none;">I'm a button</button>
<button id="my_button_2">Click me</button>
<div id="result"></div>
<style>
button#my_button_1 {
background-color: red;
display: inline !important;
}
</style>
<script id="my_script">
document.getElementById('my_button_2').addEventListener('click', function() {
document.getElementById('result').innerHTML = 'This is the result';
});
</script>
</body>
</html>
30 changes: 30 additions & 0 deletions packages/driver/cypress/integration/commands/querying_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1955,6 +1955,7 @@ space
})
})

// https://github.com/cypress-io/cypress/issues/14861
describe('ignores style and script tag in body', () => {
it('style', (done) => {
cy.on('fail', (err) => {
Expand All @@ -1977,6 +1978,35 @@ space
cy.visit('fixtures/content-in-body.html')
cy.contains('I am in the script tag in body', { timeout: 500 })
})

// https://github.com/cypress-io/cypress/issues/19377
describe('cy.contains() does not remove <style> and <script> tags', () => {
it('cy.contains() does not remove style tags from the DOM', () => {
cy.visit('fixtures/content-in-body.html')

cy.get('button#my_button_1').should('be.visible')
cy.contains('Hello').should('be.visible')
cy.get('button#my_button_1').should('be.visible')
})

it('cy.contains() does not remove script tags from the DOM', () => {
cy.visit('fixtures/content-in-body.html')

cy.window().then((win) => {
const scriptElement = win.document.getElementById('my_script')

expect(scriptElement?.id).to.equal('my_script')
})

cy.get('button#my_button_2').click()
cy.contains('This is the result').should('be.visible')
cy.window().then((win) => {
const scriptElement = win.document.getElementById('my_script')

expect(scriptElement?.id).to.equal('my_script')
})
})
})
})

describe('subject contains text nodes', () => {
Expand Down
30 changes: 10 additions & 20 deletions packages/driver/src/dom/elements/find.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import $document from '../document'
import $jquery from '../jquery'
import { getTagName } from './elementHelpers'
import { isWithinShadowRoot, getShadowElementFromPoint } from './shadow'
import { normalizeWhitespaces, escapeQuotes, isSelector } from './utils'
import { normalizeWhitespaces, escapeQuotes } from './utils'

/**
* Find Parents relative to an initial element
Expand Down Expand Up @@ -125,10 +125,16 @@ export const getFirstDeepestElement = ($el: JQuery, index = 0) => {
const $current = $el.slice(index, index + 1)
const $next = $el.slice(index + 1, index + 2)

if (!$next) {
if (!$next || $current.length === 0) {
return $current
}

// https://github.com/cypress-io/cypress/issues/14861
// filter out the <script> and <style> tags
if ($current && ['SCRIPT', 'STYLE'].includes($current.prop('tagName'))) {
return getFirstDeepestElement($el, index + 1)
}

// does current contain next?
if ($.contains($current.get(0), $next.get(0))) {
return getFirstDeepestElement($el, index + 1)
Expand Down Expand Up @@ -217,20 +223,6 @@ export const getElements = ($el) => {
return els
}

// Remove <style> and <script> elements inside <body>. Even though the contains
// selector avoids selecting them with :not(script,style), it will find the
// text anyway and attribute it to the <body>
// https://github.com/cypress-io/cypress/issues/14861
const removeScriptAndStyleElements = (elem) => {
const $elem = $(elem)

if (!isSelector($elem, 'body')) return elem

$elem.find('script,style').remove()

return $elem[0]
}

export const getContainsSelector = (text, filter = '', options: {
matchCase?: boolean
} = {}) => {
Expand All @@ -252,14 +244,12 @@ export const getContainsSelector = (text, filter = '', options: {

// taken from jquery's normal contains method
cyContainsSelector = function (elem) {
elem = removeScriptAndStyleElements(elem)
let testText = normalizeWhitespaces(elem)
const testText = normalizeWhitespaces(elem)

return text.test(testText)
}
} else if (_.isString(text)) {
cyContainsSelector = function (elem) {
elem = removeScriptAndStyleElements(elem)
let testText = normalizeWhitespaces(elem)

if (!options.matchCase) {
Expand All @@ -284,7 +274,7 @@ export const getContainsSelector = (text, filter = '', options: {
const textToFind = escapedText.includes(`\'`) ? `"${escapedText}"` : `'${escapedText}'`

// use custom cy-contains selector that is registered above
return `${filter}:not(script,style):cy-contains(${textToFind}), ${filter}[type='submit'][value~=${textToFind}]`
return `${filter}:cy-contains(${textToFind}), ${filter}[type='submit'][value~=${textToFind}]`
})

return selectors.join()
Expand Down

3 comments on commit 3250945

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 3250945 Dec 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/9.1.2/circle-develop-325094556d6a6fee0e8404c1e90ed31958e6e43d/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 3250945 Dec 20, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/9.1.2/circle-develop-325094556d6a6fee0e8404c1e90ed31958e6e43d/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 3250945 Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/9.1.2/circle-develop-325094556d6a6fee0e8404c1e90ed31958e6e43d/cypress.tgz

Please sign in to comment.