1

I am trying to download a file using java selenium. The download button is clicked and it takes time to initiate and complete the download from the website (time of download depends on size of file and speed of net).

However, the next code is executed immediately after the code driver.findElement(By.xpath("//*[@id='downloadReport']/div")).click(); without waiting for download to complete.

The file name is dynamic (different file name based on search data extracted from excel sheet SearchData.xls

Any help is highly appreciated.

The code is as under:-

package Basic;

import java.awt.AWTException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.time.Duration;
import java.util.Calendar;

import org.apache.commons.io.FileUtils;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class sftest2 {

public static void main(String[] args) throws IOException, InterruptedException, AWTException {
System.setProperty("webdriver.edge.driver", "D:\\Installer\\msedgedriver.exe");
File file =    new File("D:\\SearchData\\SearchData.xls");
FileInputStream inputStream = new FileInputStream(file);
HSSFWorkbook wb=new HSSFWorkbook(inputStream);
HSSFSheet sheet=wb.getSheet("SF_NSF");
int rowCount=sheet.getLastRowNum()-sheet.getFirstRowNum();
WebDriver driver = new EdgeDriver();
driver.manage().window().maximize();
driver.get("https://******************");
driver.navigate().to("https://******************************");
for(int i=1;i<=rowCount;i++) {
driver.findElement(By.name("cAccount")).sendKeys("Search");
driver.findElement(By.xpath("//*[@id='abcSearchAction']/div[1]/div[3]/div[4]/img")).click();
WebElement bName=driver.findElement(By.id("bName"));
borrowerName.sendKeys(sheet.getRow(i).getCell(0).getStringCellValue());
driver.findElement(By.xpath("//*[@id='search-button']/ul/li[1]/div/input")).click();
Thread.sleep(2000);
driver.navigate().refresh();
WebDriverWait wait = new WebDriverWait(driver,Duration.ofSeconds(20));
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id=\'load_projectTable\']")));
if(driver.getPageSource().contains("View 1 -"))
{
driver.findElement(By.xpath("//*[@id='downloadReport']/div")).click();
Thread.sleep(50000); // Doesnot want to wait for specified time, the next code should execute immediately after complete download of file called through above code
driver.findElement(By.xpath("//*[@id='footer-container']/div[3]/a")).click();
}

else
{
//driver.findElement(By.xpath("//*[@id='three-icons']/ul/li[3]/a/div")).click();
Calendar cal = Calendar.getInstance();
java.util.Date time = cal.getTime();
String timestamp = time.toString().replace(":", "").replace(" ", "");
System.out.println(time);
System.out.println(timestamp);
TakesScreenshot ts = (TakesScreenshot)driver;
File src=ts.getScreenshotAs(OutputType.FILE);
File trg=new File(".\\screenshots\\SF_1Cr_B_Search_"+timestamp+".png");
FileUtils.copyFile(src,trg);
//Thread.sleep(1000);
driver.findElement(By.xpath("//*[@id='footer-container']/div[3]/a")).click();
}
}
//Close the workbook
wb.close();
//Quit the driver
driver.quit();        
}
}
mps
  • 35
  • 5
  • For Chrome you check for the existence of .crdownload extension files which would indicate a partial download. Maybe check this thread: https://stackoverflow.com/questions/48263317/selenium-python-waiting-for-a-download-process-to-complete-using-chrome-web/51575537#51575537 – pcalkins Feb 15 '23 at 20:21
  • Check this one https://stackoverflow.com/questions/61707601/how-to-verify-whether-file-downloading-is-completed-before-closing-the-web-drive/61725884#61725884 – pburgr Feb 16 '23 at 08:21

1 Answers1

0

You can do so using a FluentWait ,just change downloadFolderPath value to your downloads folder and Replace PrefixofFilename value

 String downloadFolderPath = "/Users/user/Downloads/";
        FluentWait<String> wait = new FluentWait<>(downloadFolderPath)
                .withTimeout(Duration.ofSeconds(60))
                .pollingEvery(Duration.ofMillis(500));
        wait.until(path -> {
            File[] listFiles = new File(path).listFiles();

            for (int i = 0; i < Objects.requireNonNull(listFiles).length; i++) {

                if (listFiles[i].isFile()) {
                    String fileName = listFiles[i].getName();
                    if (fileName.startsWith("PrefixofFilename")
                            && fileName.endsWith(".xls")) {
                        return true;
                    }
                }
            }
            return false;
        });
Abhay Chaudhary
  • 1,763
  • 1
  • 8
  • 13
  • File downloaded has dynamic name (random name with each download) hence "PrefixofFilename" cannot be ascertained. – mps Mar 25 '23 at 03:35
  • @mps if you don't know the name then you can delete All the files in download location first and then modify above code to wait until Files count is 1 in the download folder – Abhay Chaudhary Mar 25 '23 at 12:56