There is an embed element within an iframe element in the page. It contains a pdf viewer and I want to click on the download arrow.
<div id="__pdfviewer0" data-sap-ui="__pdfviewer0" role="document" aria-label="PDF-Viewer" style="width: 100%; height: 100%;">
<iframe id="__pdfviewer0-iframe" src="blob:https://foo#view=FitH" aria-label="PDF-Viewer: Inhalt" class="sapMPDFViewerContent" cd_frame_id_="fooCodeframe"/>
#document (blob:https://foo#view=FitH)
<!DOCTYPE html>
<html>
<head><head/>
<body style="height: 100%; width: 100%; overflow: hidden; margin:0px; background-color: rgb(82, 86, 89);">
<embed name="fooCode" style="position:absolute; left: 0; top: 0;" width="100%" height="100%" src="about:blank" type="application/pdf" internalid="fooCode"/>
</body>
</html>
</iframe>
</div>
The code within the iframe looks like this:
I think that a valid CSSelector for the cr-icon-button would be:
[id=viewer] /deep/ [id=toolbar] /deep/ [id=end] > [id=downloads] /deep/ [id='download']
So I tried this:
var frame = Client.Value.WebDriver.SwitchTo().Frame(FindElement(By.Id("__pdfviewer0-iframe")));
frame.FindElement(By.CssSelector("[id=viewer] /deep/ [id=toolbar] /deep/ [id=end] > [id=downloads] /deep/ [id='download']")).Click();
But it doesn't work. It can't find the button.


The problem is that the element you want is nested in four shadow-roots. They are similar to IFRAMEs in that you need to switch context into them for Selenium to be able to see the DOM inside. In this case, you'll need to switch into the IFRAME and then switch into the nested shadow-roots. Something like the below should work.
For more info on accessing shadow-roots, see this article.