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

[BUG] Text selector doesn't match by combined innerText #2089

Closed
ingvar-nikiforov opened this issue May 4, 2020 · 5 comments
Closed

[BUG] Text selector doesn't match by combined innerText #2089

ingvar-nikiforov opened this issue May 4, 2020 · 5 comments

Comments

@ingvar-nikiforov
Copy link

Context:

  • Playwright Version: 0.16.0
  • Operating System: Mac
  • Node version: v13.11.0
  • Browser: All

Code Snippet

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch()
  const context = await browser.newContext()
  const page = await context.newPage()

  await page.setContent(`
<div class="wrapper">
  <div>
    <span>Should</span>
  </div>
  <div>
    <span>match</span>
  </div>
</div>`)

  const elementByClass = await page.$('.wrapper')
  const innerText = await elementByClass.innerText()
  console.log('Inner Text matches regex:', /Should.*match/is.test(innerText))

  const elementByText = await page.$('text=/Should.*match/is')
  console.log('element not found:', elementByText === null)

  await browser.close()
})()

Output

Inner Text matches regex: true
element not found: true

Describe the bug
Since regex matches innerText of .wrapper element I expect it to be matched by selector.

@dgozman
Copy link
Contributor

dgozman commented May 5, 2020

Matching regexp on the combined text is slow - this will typically turn a linear search into quadratic. I am not sure we want this behavior by default. Perhaps we can do a separate engine text:combined or something.

Note that text selector is based on textContent, not innerText. There is usually a difference based on what's visible or hidden. Comparing with elementHandle.innerText() will not work - use elementHandle.textContent() instead.

@ingvar-nikiforov
Copy link
Author

Changing `innerText` to `textContent` in the provided example will produce the same result.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch()
  const context = await browser.newContext()
  const page = await context.newPage()

  await page.setContent(`
<div class="wrapper">
  <div>
    <span>Should</span>
  </div>
  <div>
    <span>match</span>
  </div>
</div>`)

  const elementByClass = await page.$('.wrapper')
  const textContent = await elementByClass.textContent()
  console.log('Inner Text matches regex:', /Should.*match/is.test(textContent))

  const elementByText = await page.$('text=/Should.*match/is')
  console.log('element not found:', elementByText === null)

  await browser.close()
})()

Correct me if I am wrong that text selector will go from upper nodes to lower nodes and check for a match of its textContent. Which means we are checking every node along the way anyway.

It looks to me that I misused the word combined in the title of this issue.

@pavelfeldman
Copy link
Member

I think we are on the same page. But matching against the text that spans across nodes is expensive, so we aren't doing it by default in text=. Let's keep it open and collect more votes.

@rimiti
Copy link

rimiti commented Jan 26, 2021

Is anyone found a workaround to get a select from "text matching"?

@pavelfeldman
Copy link
Member

This is now fixed since v1.8. Please file a new request if there are outstanding issues. See https://playwright.dev/docs/selectors#text-selector

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants