Closed eNcacz closed 2 months ago
Appears that if anything changes the document (I'm not sure what is triggering that here), it will break iterating xpath results (https://stackoverflow.com/a/27664220). Assuming you're an xpath user, do you usually use the snapshot approach?
I do not understand how the document is changed. I use only simple static document without any javascript inside. The document remains the same from the beginning to the end of the test.
I do not use snapshot approach. This is simplified code to demonstrate, that the XPath does not work even on simple static page. I my real code I need to work with dynamic web page and I use XPath selector in rare cases, when the page structure make impossible to use CSS selectors. I'm not sure if it is OK from performance point of view to create snapshot of the whole page before each element search ...
I'm guessing in your example, it's because you're using showChrome, which will add a mouse tracker by default. You can turn that off, but the underlying document changing problem will be present on a normal website, so it doesn't really matter the root cause here.
The link I sent has a different "result type" of the nodes, which is snapshot. It just means the nodes themselves are snapshotted, not the whole document. I'm wondering if we should change the underlying xpath code to use one of the snapshot options and iterators.
I tried to not use showChrome
but it still crash in the same way.
Then I tried to implement it using snapshot result and it works:
import Hero, {XPathResult} from '@ulixee/hero-playground';
(async () => {
console.log('Running Hero');
const hero = new Hero();
await hero.goto('http://localhost/ulixee/index.html'); // <---- REPLACE THIS URL ACCORDING TO YOUR ENVIRONMENT
await hero.waitForPaintingStable()
console.log('Page loaded');
const document = await hero.document
const xpResult = document.evaluate('//a', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
for (let i = 0; i < await xpResult.snapshotLength; i++) {
const elem = xpResult.snapshotItem(i)
console.log(await elem.outerHTML)
}
console.log('Done')
await hero.close();
})();
So I can use it in this way. But still I wonder if the hero.xpathSelectorAll
can be used somehow or if it is definitely broken and the document.evalueate
is the only way.
Anyway, thanks a lot for your help. This is really appreciated.
Here is the web page source code, which I use for demonstration of this bug:
This is the TypeScript application which demonstrates the bug.
And this is the output of the application:
The result is still the same - it doesn't matter if the XPath selector selects zero, one or many elements.
I have tried to use
hero.document.evaluate()
instead, but it also crashed with very similar exception.Expected behavior
The
hero.xpathSelectorAll
method will return a collection (possibly empty) with elements found.