Search code examples
javascriptnode.jsselenium-webdrivershadow-root

How to wait for shadow root child to be located?


I am trying to use selenium to take a screenshot of a website, which has an img tag inside a shadow root, therefore, I want to wait for this img to exist.

Regularly I do something like this:

await driver.wait(until.elementLocated(By.css('img')));

But since it's in a shadow root I can't do it.

Using this :

(await (await element.getShadowRoot()).findElement(By.css('img'))); //I prefer double await than chaining tasks to ShadowRootPromise.

working only sometimes, and sometimes it throws an error that it has not found. I guess it's because the img has not been added to DOM yet.

(Currently, I am talking only about the problem of waiting for the img element to be available, the problem of waiting for the image to actually load and appear is another problem that I already solved.)

How can I wait for it to be available and not only 'get' it?


Solution

  • Eventually I took a look at selenium src and saw how it's done with regular until.elementLocate and came up with:

    const selector = 'img';
    const shadow = await element.getShadowRoot();
    const image = await driver.wait(new WebElementCondition(
        'for element to be located img',
         function () {
            return shadow.findElements(By.css('img')).then(function (elements) {
                return elements[0]
            })
        }
    ))