-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Description
Description
Issue description
This code snippet is working fine with 4.38.0 and is now not working with 4.39.0
var downloadManager = (HasDownloads) this.getWebDriver();
// confirm that downloads are enabled, else fail fast
Assertions.assertTrue(downloadManager.isDownloadsEnabled(), "Managed downloads are not enabled in this session...");
logger.info("Downloading is enabled for this session `{}`...", this.getWebDriver());
// wait until the list of downloadable files is not empty
// NOTE: this will work for single file download, may face issues later when downloading multiple files
new SynchronizationManager(this).untilCustomTimeout(SynchronizationManager.uiProcessingTimeout,
d -> !downloadManager.getDownloadableFiles().isEmpty());
logger.info("Found `{}` downloadable file(s)...", downloadManager.getDownloadableFiles().size());
// download the files from the grid to the local downloads directory
downloadManager.getDownloadableFiles().forEach(downloadableFile -> {
try {
downloadManager.downloadFile(downloadableFile, Path.of(BrowserFactory.getDownloadPath()));
foundDownloadedFiles[0] = true;
logger.info("Downloaded `{}` from remote grid to `{}` on the local machine...", downloadableFile, Path.of(BrowserFactory.getDownloadPath()).toString());
} catch (IOException e) {
throw new RuntimeException(e);
}
});for your convinence this can be simplified down to these two lines of code
var downloadManager = (HasDownloads) this.getWebDriver();
downloadManager.downloadFile(downloadableFile, Path.of(BrowserFactory.getDownloadPath()));the first line casts a simple Webdriver driver; object that has been initialized to connect to the grid. The grid is configured correctly to enable downloads.
the second line tries to download the file by passing the file name and target location.
Exception Details
As of today (16/12/2025) when I use selenium-java 4.38.0 it works fine, and when I change the version number to 4.39.0 the following exception is thrown.
(Note: nothing else is changed; same machine, same grid instance, same code, same everything, only the selenium-java version number)
unknown command: unknown command: session/a42d018e84d0a3c35c8866528b77e6ec/se/files/titanic.csv
Build info: version: '4.39.0', revision: '126f156aee'
System info: os.name: 'Windows 11', os.arch: 'amd64', os.version: '10.0', java.version: '21.0.9'
Driver info: org.openqa.selenium.remote.RemoteWebDriver$ByteBuddy$Tc7u0OLo$ByteBuddy$dn11cEDn
Command: [a42d018e84d0a3c35c8866528b77e6ec, getDownloadedFile {name=titanic.csv}]
Capabilities {acceptInsecureCerts: false, browserName: chrome, browserVersion: 142.0.7444.59, chrome: {chromedriverVersion: 142.0.7444.59 (4b8153ab58d3..., userDataDir: /tmp/.org.chromium.Chromium...}, fedcm:accounts: true, goog:chromeOptions: {debuggerAddress: localhost:43957}, goog:processID: 222, networkConnectionEnabled: false, pageLoadStrategy: none, platformName: linux, proxy: Proxy(), se:cdp: ws://localhost:4444/session..., se:cdpVersion: 142.0.7444.59, se:containerName: 5ac8e55c5897, se:deleteSessionOnUi: true, se:downloadsEnabled: true, se:gridWebSocketUrl: ws://localhost:20347/sessio..., se:noVncPort: 7900, se:vnc: ws://localhost:4444/session..., se:vncEnabled: true, se:vncLocalAddress: ws://172.18.0.5:7900, setWindowRect: true, strictFileInteractability: false, timeouts: {implicit: 0, pageLoad: 300000, script: 120000}, unhandledPromptBehavior: dismiss and notify, webSocketUrl: ws://localhost:4444/session..., webauthn:extension:credBlob: true, webauthn:extension:largeBlob: true, webauthn:extension:minPinLength: true, webauthn:extension:prf: true, webauthn:virtualAuthenticators: true}
Session ID: a42d018e84d0a3c35c8866528b77e6ec
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.openqa.selenium.remote.ErrorCodec.decode(ErrorCodec.java:167)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:142)
at org.openqa.selenium.remote.codec.w3c.W3CHttpResponseCodec.decode(W3CHttpResponseCodec.java:49)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:215)
at org.openqa.selenium.remote.TracedCommandExecutor.execute(TracedCommandExecutor.java:53)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:561)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:638)
at org.openqa.selenium.remote.RemoteWebDriver.downloadFile(RemoteWebDriver.java:733)
at com.carbon.ise.ui.engine.Bot.lambda$fetchDownloadedFiles$49(Bot.java:931)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at com.carbon.ise.ui.engine.Bot.fetchDownloadedFiles(Bot.java:929)
at com.carbon.ise.ui.engine.debug.steps.DebuggingSteps.iDownloadTheCsvFile(DebuggingSteps.java:52)
at ?.I download the CSV file(classpath:engine/debug.feature:19)in the above snippet titanic.csv is the name of the file I'm downloading.
Initial investigation
The stacktrace points to this line of code in version 4.39.0
as per the below screenshot, comparing with 4.38.0 (the working version) shows that the command being called has changed from downloadFile (below) which was working, to getDownloadedFile (above) in 4.39.0 which is not working.
I traced this change back to this specific PR: #16627
as seen in the changes list here
https://github.com/SeleniumHQ/selenium/pull/16627/changes
Selenium Grid details; the final puzzle piece
I checked my grid version, even though I am setting latest in my grid-compose file, it seems that the grid containers are cashed from Selenium Grid 4.38.0 (revision 6b412e825c)
I upgraded the grid compose file to mention explicitly image: selenium/hub:4.39.0 instead of image: selenium/hub:latest to ensure that I'm on the latest grid
Now, after running my test against this version Selenium Grid 4.39.0 (revision 126f156aee) the exception changes to
java.nio.file.NoSuchFileException: C:\Users\MohabMohie\GitHub\kantar\ise-uiautomation\downloads\titanic.csv
at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:85)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103)
at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108)
at java.base/sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:234)
at java.base/java.nio.file.spi.FileSystemProvider.newOutputStream(FileSystemProvider.java:482)
at java.base/java.nio.file.Files.newOutputStream(Files.java:227)
at java.base/java.nio.file.Files.copy(Files.java:3140)
at org.openqa.selenium.remote.RemoteWebDriver.downloadFile(RemoteWebDriver.java:737)
at com.carbon.ise.ui.engine.Bot.lambda$fetchDownloadedFiles$49(Bot.java:931)
... 4 moretracing that stacktrace shows that the real culprit was not the change in command name (though this is a breaking change and should be highlighted on release notes!) but rather the change that was made to handle moving the downloaded files...
in 4.38.0 it was the below, which was working fine:
String contents = ((Map<String, String>) response.getValue()).get("contents");
Zip.unzip(contents, targetLocation.toFile());now in 4.39.0 it is the following, which is not working:
Contents.Supplier content = (Contents.Supplier) response.getValue();
try (InputStream fileContent = content.get()) {
Files.copy(new BufferedInputStream(fileContent), targetLocation.resolve(fileName));
}I believe this is a minor error, and could easily be resolved by adding this small line of code to create the parent directories before attempting to copy the file into it. Which closely matches the old/expected behavior, without causing any new exceptions if the target parent directory had already existed.
Contents.Supplier content = (Contents.Supplier) response.getValue();
try (InputStream fileContent = content.get()) {
Files.createDirectories(targetLocation);
Files.copy(new BufferedInputStream(fileContent), targetLocation.resolve(fileName));
}I will open a PR to implement this quick fix and will ask @asolntsev and @diemol to review, since they created/merged the original PR.
Highlights
I checked the release notes: https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.39.0
And the details for Java: https://github.com/SeleniumHQ/selenium/blob/trunk/java/CHANGELOG
I didn't see any mention for a breaking change with this update. I think maybe there is an assumption that no one was using this feature since it's new and not yet documented. But please note that a lot of people are eagerly awaiting the latest features and BiDi implementations, myself and my team included.
Kindly be mindful of that in future releases by either explicitly mentioning the breaking changes, or using the @Beta annotation to let us know that something may be changed without warning so that we can jump on it when it does without needing the thorough investigation.
Reproducible Code
mentioned aboveℹ️ Last known working version: 4.38.0