I'm trying to search inner text case insensitive using puppeteer.
I've read this: case insensitive xpath contains() possible?
For example I have this elements:
<div>
<span>Test One</span>
<span>Test Two</span>
<span>Test Three</span>
</div>
I've tried this unsuccessfully:
const element = await page.$x("//span//text()[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]");
Your XPath expression is valid, but you are returning text()
instead of the node itself. page.$x
expects the XPath to return an element, therefore your code does not work. To return the node you need to query for the span element.
const element = await page.$x("//span[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]");
Please note, that text()
only works for text-only nodes. If you have mixed content (containing elements and text), you should use the string value (.
instead of text()
):
const element = await page.$x("//span[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]");
To compare the expressions I put them below each other:
//span//text()[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]
//span[contains(translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')
//span[contains(translate(., 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), 'two')]
The first one is the expression (given by you) for the text of the span node. The second one queries the node itself by using text()
. The last one uses the string value to query the node.
Not as pretty, but you can use page.evaluateHandle
along with a regex to find the element:
const element = await page.evaluateHandle(() =>
Array.from(document.querySelectorAll("div > span")).find(a => /test two/i.test(a.innerText))
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With