In test automation, handling file downloads can be a bit tricky, especially when you want to dynamically handle different file names. Instead of hardcoding the file name, it's much more flexible to detect the latest downloaded file, ensuring your script works regardless of the file name.
Here's an approach to achieve this using Selenium WebDriver in Java.
How to Approach it with Logic?
1. Set Up Chrome Preferences:
- We first configure Chrome using ChromeOptions to ensure that downloads go to a specific directory, without any browser popups or interruptions.
- The safebrowsing.enabled option is set to true to handle potentially insecure downloads.
2. Use FluentWait:
- To detect when the file download completes, we use a FluentWait on the download folder. This wait continuously checks if the file has been downloaded by monitoring changes in the folder.
3. Sort Files by Modification Time:
- Once the download starts, the files in the download directory are sorted based on their last modified timestamp. The latest modified file is assumed to be the newly downloaded one.
4. Ensure File Completeness:
- The script ensures that the file is fully downloaded by checking if the file is readable.
Automation Script Code:
package LambdaTest_PlagroundSolution; import Selenium_Utilities.PageLocatorActions; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.support.ui.FluentWait; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import java.io.File; import java.time.Duration; import java.util.Arrays; import java.util.Comparator; import java.util.HashMap; public class DownloadFileDemo_Test extends PageLocatorActions { private static String URL = "https://www.lambdatest.com/selenium-playground/download-file-demo"; // To get the current working directory -System.getProperty("user.dir") private static String downloadFilePath = System.getProperty("user.dir") + "\\src\\main\\resources\\downloads"; @BeforeTest public void setup() { HashMap<String, Object> chromePrefs = new HashMap<>(); chromePrefs.put("profile.default_content_settings.popups", 0); chromePrefs.put("download.default_directory",downloadFilePath); // For changing defualt download folder path //Enable safe download - if you have issue while downloading like - "download blocked" or "unverified downlaod b" chromePrefs.put("safebrowsing.enabled", "true"); ChromeOptions options = new ChromeOptions(); options.setExperimentalOption("prefs", chromePrefs); //Disable notifications options.addArguments("--disable-notifications"); //Downloading the file // To handle insecure file download warning - pop-up in Selenium // Use chrome options - "--unsafely-treat-insecure-origin-as-secure= <Your Domain Name>" // options.addArguments("--unsafely-treat-insecure-origin-as-secure=https://www.lambdatest.com/selenium-playground/download-file-demo"); options.addArguments("--start-maximized"); driver=new ChromeDriver(options); driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(15)); driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(25)); driver.manage().deleteAllCookies(); } @AfterTest public void teardown() { if (driver!=null) { driver.quit(); } } @Test public void verifyDownloadFileDemo() { driver.get(URL); // Wait until the download link is clickable waitAndClickOnElementByXpath("//button[normalize-space()='Download File']"); File file = new File(downloadFilePath); FluentWait<File> wait = new FluentWait<>(file) .withTimeout(Duration.ofMinutes(5)) .pollingEvery(Duration.ofSeconds(5)) .ignoring(Exception.class) .withMessage("File is not downloaded completely..."); File downloadedFile = null; try { // Wait until the newest file is detected downloadedFile = wait.until(dir -> { File[] files = dir.listFiles(); if (files != null && files.length > 0) { // Sort the files by last modified date to get the latest one return Arrays.stream(files) .filter(File::canRead) // Ensure the file can be read .max(Comparator.comparingLong(File::lastModified)) // Get the latest file .orElse(null); } return null; }); } catch (Exception e) { System.out.println("File is not downloaded successfully..."); } // If the file is downloaded, print the name of the file if (downloadedFile != null) { System.out.println("File " + downloadedFile.getName() + " is downloaded successfully.."); } else { System.out.println("No file was downloaded."); } } }
Key Points:
- Dynamic File Detection: No need to hardcode the file name. The script dynamically detects the most recently downloaded file in the specified directory.
- Handling Downloads with ChromeOptions: By modifying the default Chrome preferences, we ensure files are downloaded automatically to the desired location.
- Polling with FluentWait: FluentWait helps to check continuously until the file download is completed, ensuring a more robust test case.