I am using Selenium and the ChromeDriver to automatically download certain files. Inspired by this append and this append I am trying to get hold of the name of a downloaded file (I have to do that since the site I am trying to download from generates random filenames when clicking "Download").
The below code tries to obtain the downloaded file's name from the browser's download history:
...
driver.get("chrome://downloads");
JavascriptExecutor js = (JavascriptExecutor)driver;
String filename = (String) js.executeScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item'.shadowRoot.querySelector('div#content #file-link').text");
...
This always yields me the error message:
Exception javascript error: Cannot read properties of null (reading 'shadowRoot')
(Session info: chrome=131.0.6778.109)
Build info: version: '4.27.0', revision: 'd6e718d134'
System info: os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '21.0.5'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Command: [fa5d918ed3ad42856f819e801d6e17f8, executeScript {args=[], script=document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item').shadowRoot.querySelector('#progress').getAttribute('value')}]
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 131.0.6778.109, chrome: {chromedriverVersion: 131.0.6778.87 (ce31cae94873..., userDataDir: C:\Users\xxx\AppData\Local\...}, fedcm:accounts: true, goog:chromeOptions: {debuggerAddress: localhost:52301}, networkConnectionEnabled: false, pageLoadStrategy: normal, platformName: windows, proxy: Proxy(), se:cdp: ws://localhost:52301/devtoo..., se:cdpVersion: 131.0.6778.109, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 30000}, unhandledPromptBehavior: dismiss and notify, webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true}
Session ID: fa5d918ed3ad42856f819e801d6e17f8
However, if I open the Chrome browser's Developer Tools Console and enter (i.e. copy&paste) that very same command string [return] document.querySelector('downloads-manager').shadowRoot.querySelector('#downloadsList downloads-item'.shadowRoot.querySelector('div#content #file-link').text
on the command line it returns me the downloaded file's name, so the expression seems correct.
Note that one has to omit the leading "return" when pasting the command on the browser console. In the Java application I tried with a return
(i.e. js.executeScript("return document.querySelector...");
as well as without (i.e. js.executeScript("document.querySelector...");
) but that didn't make any difference and the error message is the exactly the same.
Any idea anyone, why the js.executeScript(...)
doesn't yield me same result as entering the same command on the browser console?
This is using the currently latest Chrome version "131.0.6778.109 (Official Build) (64-bit)" and Selenium as well as ChromeDriver v4.27.0 (on Java v21).
Duuuh! :-( Turned out the simple reason why my JavaScript snippet didn't yield a result was that my code ran too quick after triggering the download. The file wasn't fully downloaded, yet, and hence my selector for the download history tab never yielded a result. Adding a loop in which I wait for a limited number of seconds for its appearance (i.e. until the executeScript(...)
returns a non-null result) got me going.
Why didn't I think about that reason, earlier? ||-(
My appologies for the wasted bandwidth and time...