package com.codeborne.selenide.impl; import com.codeborne.selenide.Configuration; import com.codeborne.selenide.proxy.FileDownloadFilter; import com.codeborne.selenide.proxy.SelenideProxyServer; import com.google.common.base.Predicate; import org.openqa.selenium.NoSuchWindowException; import org.openqa.selenium.WebElement; import java.io.File; import java.io.FileNotFoundException; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.logging.Logger; import static com.codeborne.selenide.WebDriverRunner.getWebDriver; public class DownloadFileWithProxyServer { private static final Logger log = Logger.getLogger(DownloadFileWithProxyServer.class.getName()); Waiter waiter = new Waiter(); public File download(WebElementSource anyClickableElement, WebElement clickable, SelenideProxyServer proxyServer) throws FileNotFoundException { return clickAndInterceptFileByProxyServer(anyClickableElement, clickable, proxyServer); } private File clickAndInterceptFileByProxyServer(WebElementSource anyClickableElement, WebElement clickable, SelenideProxyServer proxyServer) throws FileNotFoundException { String currentWindowHandle = getWebDriver().getWindowHandle(); Set<String> currentWindows = getWebDriver().getWindowHandles(); FileDownloadFilter filter = proxyServer.responseFilter("download"); filter.activate(); try { clickable.click(); waiter.wait(filter, new HasDownloads()); return firstDownloadedFile(anyClickableElement, filter); } finally { filter.deactivate(); closeNewWindows(currentWindowHandle, currentWindows); } } private void closeNewWindows(String currentWindowHandle, Set<String> currentWindows) { Set<String> windowHandles = getWebDriver().getWindowHandles(); if (windowHandles.size() != currentWindows.size()) { Set<String> newWindows = new HashSet<>(windowHandles); newWindows.removeAll(currentWindows); log.info("File has been opened in a new window, let's close " + newWindows.size() + " new windows"); for (String newWindow : newWindows) { log.info(" Let's close " + newWindow); try { getWebDriver().switchTo().window(newWindow); getWebDriver().close(); } catch (NoSuchWindowException windowHasBeenClosedMeanwhile) { log.info(" Failed to close " + newWindow + ": " + Cleanup.of.webdriverExceptionMessage(windowHasBeenClosedMeanwhile)); } catch (Exception e) { log.warning(" Failed to close " + newWindow + ": " + e); } } getWebDriver().switchTo().window(currentWindowHandle); } } private static class HasDownloads implements Predicate<FileDownloadFilter> { @Override public boolean apply(FileDownloadFilter filter) { return !filter.getDownloadedFiles().isEmpty(); } } private File firstDownloadedFile(WebElementSource anyClickableElement, FileDownloadFilter filter) throws FileNotFoundException { List<File> files = filter.getDownloadedFiles(); if (files.isEmpty()) { throw new FileNotFoundException("Failed to download file " + anyClickableElement + " in " + Configuration.timeout + " ms." + filter.getResponses()); } log.info("Downloaded file: " + files.get(0).getAbsolutePath()); log.info("Just in case, all intercepted responses: " + filter.getResponses()); return files.get(0); } }