0

I'm trying to get access to some shadow dom elements using selenium in Javascript/Typescript, but can't quite seem to get it to work as expected. I haven't been able to find any javascript specific documentation but have addapted other examples to this:

let shadowHost = await this.driver.findElement(elementLocator("xpath", "//custom-element"));
let testShadow: WebElement = await this.driver.executeScript("return arguments[0].shadowRoot", shadowHost);
debugLog(await testShadow.findElements(By.xpath("//div")))

the testShadow seems to have a findElements function but it gives me a bad locator error:

InvalidArgumentError: invalid argument: invalid locator
         (Session info: chrome=101.0.4951.54)
           at Object.throwDecodedError (/home/bwarner/git/BDD/symbolik-selenium-bdd/node_modules/selenium-webdriver/lib/error.js:522:15)
           at parseHttpResponse (/home/bwarner/git/BDD/symbolik-selenium-bdd/node_modules/selenium-webdriver/lib/http.js:549:13)
           at Executor.execute (/home/bwarner/git/BDD/symbolik-selenium-bdd/node_modules/selenium-webdriver/lib/http.js:475:28)
           at processTicksAndRejections (internal/process/task_queues.js:95:5)
           at async thenableWebDriverProxy.execute (/home/bwarner/git/BDD/symbolik-selenium-bdd/node_modules/selenium-webdriver/lib/webdriver.js:735:17)
           at async ShadowRoot.findElements (/home/bwarner/git/BDD/symbolik-selenium-bdd/node_modules/selenium-webdriver/lib/webdriver.js:2979:20)
           at async World.<anonymous> (/home/bwarner/git/BDD/symbolik-selenium-bdd/features/step_definitions/shadowroot_steps.ts:15:14)

I'm wondering if this is just something that isn't supported at all or if I'm doing something wrong, or if there's another hack that I can do to write some tests.

Logging out testShadow returns:

ShadowRoot {
  driver_: thenableWebDriverProxy {
    session_: Promise { [Session] },
    executor_: Executor { customCommands_: [Map], log_: [Logger], w3c: true },
    fileDetector_: null,
    onQuit_: undefined,
    then: [Function: bound then],
    catch: [Function: bound catch]
  },
  id_: '5bf8d739-abc4-4091-bb72-8bf285dfe363'
}
Bill Warner
  • 639
  • 6
  • 18
  • 1
    Does the first line work without the two other lines? – Remirror May 06 '22 at 20:46
  • yes, the shadowHost gets a webelement and the testShadow does become an object although the executeScript can return different things. I have a feeling it's returning an object of type ShadowRoot that may not be defined in the selenium types definition and I can't find any javascript documentation for it. Added the return value of testShadow to the question. – Bill Warner May 06 '22 at 21:12
  • 1
    You're facing a runtime error, that cannot have anything to do with typings. For simplification, try a CSS selector instead of a XPath one, say `debugLog(await testShadow.findElements(By.css("div")))` and see if that works. The error message says it's a locator problem - that is the "`By`" part. – Remirror May 07 '22 at 07:52
  • I have tried different forms, even the return format of By which looks like {css: "div"} or {xpath: "//div"} but all say the same thing. My only reason for saying type Error is that I'm passing the shape that the type system thinks I need to but it obviously isn't the right one. – Bill Warner May 09 '22 at 13:22
  • @Remirror I have to appologize. I responded above while out of town and going by memory. Now that I'm back into the testing I thought I'd give the `By.css` one more go and it seems to be what I needed. I could have sworn I had tested that and a million other things. I am now able to navigate a tree of shadow roots. – Bill Warner May 10 '22 at 16:01

0 Answers0