puppeteer-sharp icon indicating copy to clipboard operation
puppeteer-sharp copied to clipboard

querying-elements-in-shadow-dom

Open aas72 opened this issue 8 months ago • 2 comments

The following code:
var browserFetcher = new BrowserFetcher();
await browserFetcher.DownloadAsync();
await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = false });
await using var page = await browser.NewPageAsync();
await page.GoToAsync("https://www.brusselsairlines.com/nl/nl/contact/feedback/general/delays-and-cancellation");
var elementHandle = await page.QuerySelectorAsync("maui-checkbox[name='isRepresentative'] >>> input[name='isRepresentative']");

Throws the following exception from the QuerySelectorAsync function: PuppeteerSharp.EvaluationFailedException: 'Evaluation failed: SyntaxError: Failed to execute 'querySelector' on 'Document': 'maui-checkbox[name='isRepresentative'] >>> input[name='isRepresentative']' is not a valid selector.

In puppeteer(non-sharp) this works correctly: https://pptr.dev/guides/page-interactions#querying-elements-in-shadow-dom

Example puppeteer(non-sharp) code:

const puppeteer = require('puppeteer');

function sleep(ms) {
    return new Promise((resolve) => {
        setTimeout(resolve, ms);
    });
}

(async () => {
    const browser = await puppeteer.launch({headless: false});
    const page = await browser.newPage();
    await page.goto('https://www.brusselsairlines.com/nl/nl/contact/feedback/general/delays-and-cancellation');
    // https://pptr.dev/guides/page-interactions#querying-elements-in-shadow-dom
    var elementHandle = await page.waitForSelector('maui-checkbox[name="isRepresentative"] >>> input[name="isRepresentative"]');

    while (true)
    {
        await sleep(1000);
        await elementHandle.click();
    }

    console.log(`elementHandle:${elementHandle}`);
})();

aas72 avatar Mar 10 '25 11:03 aas72

Yeah. We don't have that feature yet.

kblok avatar Mar 10 '25 11:03 kblok

Is there an other way to access elements within a shadow DOM (open).

I tried:

await page.GoToAsync("https://www.brusselsairlines.com/nl/nl/contact/feedback/general/delays-and-cancellation");
var elementHandle = await page.QuerySelectorAsync("xpath///maui-checkbox[@name='isRepresentative']");
await elementHandle.ClickAsync();
var shadowRootElementHandle = await elementHandle.GetPropertyAsync("shadowRoot");
var firstChildElementHandle = (ElementHandle)await shadowRootElementHandle.GetPropertyAsync("firstElementChild");
await firstChildElementHandle.ClickAsync();

This seems to do something. I don't know if it is a valid way of doing it. I wonder if there is a way to do a QuerySelectorAsync from the shadowRoot location.

aas72 avatar Mar 10 '25 12:03 aas72