detecting a file downloaded in selenium java - java

I wrote an automation test in selenium java that detects if the page is redirecting (the automation detects if a new page is opened, the page redirects to other page, a new tab is opened and if an alert window is opened)
Now to the problem.
one of the redirects i can't find any way to detect is an automatic downloaded file (you enter a website and the website automatically downloads a file without any trigger from the user)
p.s.
I know the download process may differ in each browser,
I need it to work mainly on chrome
Thanks

I had the same question and here is what I found somewhere on the Internet (maybe on stackoverflow, I cannot remember). I just added a line to delete the file so that by calling this method at the beginning of my test, I'm making sure the file does not exist anymore when trying to download it again.
public boolean isFileDownloaded(String downloadPath, String fileName) {
File dir = new File(downloadPath);
File[] dirContents = dir.listFiles();
for (int i = 0; i < dirContents.length; i++) {
if (dirContents[i].getName().equals(fileName)) {
// File has been found, it can now be deleted:
dirContents[i].delete();
return true;
}
}
return false;
}
You just have to call with this single line:
isFileDownloaded("C:\Path\To\Your\Folder", "yourPdfFile.abc");
Hope this helps!

My solution in the end was to count the files in the download directory before and after i open the page.
I'll be glad to know if someone knows a way to find the trigger for the download

I am handling a similar condition in my automation.
Step1: set the download path in chrome using chrome preference
ChromeOptions options = new ChromeOptions();
HashMap<String, Object> chromePref = new HashMap<>();
chromePref.put("download.default_directory", <Directory to download file>);
options.setExperimentalOption("prefs", chromePref);
Make sure that there is no file with the expected file name in the folder where you are downloading.
Step 2: navigate to the url in chrome, the file will be automatically downloaded to the specified folder.
Step 3: check the file existence in the downloaded folder.

This method is working for me successfully
/**
* This method will wait until the folder is having any downloads
* #throws InterruptedException
*/
public static void waitUntilFileToDownload(String folderLocation) throws InterruptedException {
File directory = new File(folderLocation);
boolean downloadinFilePresence = false;
File[] filesList =null;
LOOP:
while(true) {
filesList = directory.listFiles();
for (File file : filesList) {
downloadinFilePresence = file.getName().contains(".crdownload");
}
if(downloadinFilePresence) {
for(;downloadinFilePresence;) {
sleep(5);
continue LOOP;
}
}else {
break;
}
}
}

This is working for me perfectly:
public static void waitForTheExcelFileToDownload(String fileName, int timeWait)
throws IOException, InterruptedException {
String downloadPath = getSystemDownloadPath();
File dir = new File(downloadPath);
File[] dirContents = dir.listFiles();
for (int i = 0; i < 3; i++) {
if (dirContents[i].getName().equalsIgnoreCase(fileName)) {
break;
}else {
Thread.sleep(timeWait);
}
}
}

I used "exists" method
public boolean isFileDownloaded() throws Exception {
final int SLEEP_TIME_MILLIS = 1000;
File file = new File(filePath);
final int timeout = 60* SLEEP_TIME_MILLIS;
int timeElapsed = 0;
while (timeElapsed<timeout){
if (file.exists()) {
System.out.println(fileName + " is present");
return true;
} else {
timeElapsed +=SLEEP_TIME_MILLIS;
Thread.sleep(SLEEP_TIME_MILLIS);
}
}
return false;
}

I used a combined variants from different sources:
Override default download folder:
ChromeOptions options = new ChromeOptions();
HashMap<String, Object> chromePref = new HashMap<>();
chromePref.put("download.default_directory", System.getProperty("java.io.tmpdir"));
options.setExperimentalOption("prefs", chromePref);
WebDriver driver = new ChromeDriver(options);
Method body:
WebDriverWait wait = new WebDriverWait(driver, 5);
String tmpFolderPath = System.getProperty("java.io.tmpdir");
String expectedFileName = "Some_file_name.ext";
File file = new File(tmpFolderPath + expectedFileName);
if (file.exists())
file.delete();
// Start downloading here.
wait.until((ExpectedCondition<Boolean>) webDriver -> file.exists());
// Do what you need.

I developed a library which is dealing more clearly in such case.
You can generate a ChromeOptions object with given download folder and use a one line method call to download a file and verify succession:
private SeleniumDownloadKPI seleniumDownloadKPI;
#BeforeEach
void setUpTest() {
seleniumDownloadKPI =
new SeleniumDownloadKPI("/tmp/downloads");
ChromeOptions chromeOptions =
seleniumDownloadKPI.generateDownloadFolderCapability();
driver = new ChromeDriver(chromeOptions);
}
#Test
void downloadAttachTest() throws InterruptedException {
adamInternetPage.navigateToPage(driver);
seleniumDownloadKPI.fileDownloadKPI(
adamInternetPage.getFileDownloadLink(), "SpeedTest_16MB.dat");
waitBeforeClosingBrowser();
}

Hope this will help!
public static Boolean isFileDownloaded(String fileName) {
boolean flag = false;
//paste your directory path below
//eg: C:\\Users\\username\\Downloads
String dirPath = "";
File dir = new File(dirPath);
File[] files = dir.listFiles();
if (files.length == 0 || files == null) {
System.out.println("The directory is empty");
flag = false;
} else {
for (File listFile : files) {
if (listFile.getName().contains(fileName)) {
System.out.println(fileName + " is present");
break;
}
flag = true;
}
}
return flag;
}

during the script execution file download in the download folder of the current user.
Use the Below code to check and download the file
public void delte_file(String filename)
{
String home = System.getProperty("user.home");
String file_name = filename;
String file_with_location = home + "\\Downloads\\" + file_name;
System.out.println("Function Name ===========================" + home + "\\Downloads\\" + file_name);
File file = new File(file_with_location);
if (file.exists()) {
System.out.println(file_with_location + " is present");
if (file.delete()) {
System.out.println("file deleted");
} else {
System.out.println("file not deleted");
}
} else {
System.out.println(file_with_location + " is not present");
}
}
To check file exist or not use the below code:
public static String check_file_exist(String filename)
{
String home = System.getProperty("user.home");
String file_name = filename;
String file_with_location = home + "\\Downloads\\" + file_name;
System.out.println("Function Name ===========================" + home + "\\Downloads\\" + file_name);
File file = new File(file_with_location);
if (file.exists()) {
System.out.println(file_with_location + " is present");
String result = "File Present";
return result;
} else {
System.out.println(file_with_location + " is not present");
String result = "File not Present";
String result1 = result;
return result1;
}
}

String downloadPath = "C:\\Users\\Updoer\\Downloads";
File getLatestFile = getLatestFilefromDir(downloadPath);
String fileName = getLatestFile.getName();
Assert.assertTrue(fileName.equals("Inspections.pdf"), "Downloaded file
name is not matching with expected file name");
----------------every time you need to delete the downloaded file so add
this code also---------
File file = new File("C:\\Users\\Updoer\\Downloads\\Inspections.pdf");
if(file.delete())
System.out.println("file deleted");
System.out.println("file not deleted");
-----Add a method under this code-------
private File getLatestFilefromDir(String dirPath){
File dir = new File(dirPath);
File[] files = dir.listFiles();
if (files == null || files.length == 0) {
return null;
}
File lastModifiedFile = files[0];
for (int i = 1; i < files.length; i++) {
if (lastModifiedFile.lastModified() < files[i].lastModified()) {
lastModifiedFile = files[i];
}
}
return lastModifiedFile;
}

Related

stopped copying large number of files using FileUtils

i am using library apache common io to copy file in my java program. when i tried to copy a lot of files (about 250.000) it just copied 4.454 and then stopped copying.
i saw in the task manager it's still running.
public void copyFiles(File source, File dest) {
Collection<File> all = new ArrayList<File>();
try {
addTree(source, all);
for (File elem : all) {
int p = 1;
File newFile = new File(dest.toString() + "\\" + elem.getName().replace(".", " ("+p+")."));
if (findFile(elem.getName(), dest)) {
for (int x = 1; newFile.exists() == true; x++) {
newFile = new File(dest.toString() + "\\" + elem.getName().replace(".", " ("+x+")."));
}
FileUtils.copyFile(elem.getAbsoluteFile(), newFile);
// jika file TIDAK di hidden maka copy file ke direktori
} else if (!(elem.isHidden())) {
FileUtils.copyFileToDirectory(elem, dest);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

How to speed up File Storage Access?

I am trying to get a list of all Folders that contain MP3 Files on the user's Internal Storage.
Here is the recursive function that I am calling for this purpose -
public void listAllMusicFiles(String pathToDirectory) {
String lastFolderPath = "";
int mp3Count = 0;
File f = new File(pathToDirectory);
File[] files = f.listFiles();
for (File inFile : files) {
if (inFile.isDirectory()) {
//reset last folder path
lastFolderPath = "";
Log.d("Directory ", inFile.getPath());
listAllMusicFiles(inFile.getPath());
} else {
if (inFile.getAbsolutePath().endsWith(".mp3") || inFile.getAbsolutePath().endsWith(".MP3")) {
mp3Count++;
Log.wtf("MP3 Count", mp3Count + " ");
//add each folder only once
String folderName = inFile.getParentFile().getName();
String folderPath = inFile.getParentFile().getPath();
Log.e("FOUND in", folderPath);
//create a new Folder object
Folder currentFolder = new Folder(folderName, folderPath, mp3Count + "");
if (!lastFolderPath.equals(folderPath)) {
Log.d("NEW", folderPath);
lastFolderPath = folderPath;
folderArrayList.add(currentFolder);
} else {
Log.d("OLD", folderPath);
//find a Folder object in folderArrayList where the object's path matches current folderPath
for (Folder folder : folderArrayList) {
String currentPath = folder.getFolder_Path();
if (currentPath.equals(folderPath)) {
//found a match
//update count
folder.setFolder_Song_Count(mp3Count + "");
}
}
}
}
}
}
}
When I run this code on my device, I am able to list the required folders in a RecyclerView, but with a delay of about 6-7 seconds.
I have already moved this task into an AsyncTask, so that my UIThread does not hang because of this intensive operation.
But I am totally at a loss when it comes to improving File System Performance. Kindly help. Thanks !
Instead of storing currentFolder in an ArrayList and in the next step iterating through complete list to find that folder and updating the value, you can simply use HashMap like this
HashMap<String, Folder> folders = new HashMap<>();
public void listAllMusicFiles(String pathToDirectory) {
int mp3Count = 0;
File f = new File(pathToDirectory);
File[] files = f.listFiles();
Folder folder;
String folderName, folderPath;
for (File inFile : files) {
if (inFile.isDirectory()) {
//reset last folder path
Log.d("Directory ", inFile.getPath());
listAllMusicFiles(inFile.getPath());
} else {
if (inFile.getAbsolutePath().endsWith(".mp3") || inFile.getAbsolutePath().endsWith(".MP3")) {
mp3Count++;
Log.wtf("MP3 Count", mp3Count + " ");
//add each folder only once
folderName = inFile.getParentFile().getName();
folderPath = inFile.getParentFile().getPath();
Log.e("FOUND in", folderPath);
if (folders.containsKey(folderPath)) {
folder = folders.get(folderPath);
folder.setFolder_Song_Count(mp3Count + "");
folders.put(folderPath, folder);
} else {
folder = new Folder(folderName, folderPath, mp3Count + "");
folders.put(folderPath, folder);
}
}
}
}
}

How to get the path of a file but without the actual file name

For example C:\Desktop and not C:\Desktop\file.txt.
Here's the code, what can i do to get only the path excluding the actual name of the file or do i have to mechanically remove the name part(String) with the split("\") method.
import java.io.*;
public class FilesInfo {
File file = new File("C:\\Users\\CCKS\\Desktop\\1");
public void viewFiles() throws IOException {
File[] files = file.listFiles();
String path = "";
for(int i = 0; i < files.length; i++){
if(!files[i].isDirectory()){
System.out.println("[DIRECTORY]" + files[i].getPath() + " [NAME] " + files[i].toString() + " [SIZE] " + files[i].length() + "KB");
} else {
path = files[i].getAbsolutePath();
file = new File(path);
}
}
if(path.equals("")){
return;
} else {
viewFiles();
}
}
public static void main(String [] args){
try {
new FilesInfo().viewFiles();
} catch (Exception e){
e.printStackTrace();
}
}
}
Like this,
File file = new File("C:\Desktop\file.txt");
String parentPath= file.getParent();
File file = new File( "C:/testDir/test1.txt" );
String justPath = file.getParent();

Java Path Files.copy rename if exists

just a simple question, with a hard (for me) to find answer :D. Here is my code (im going to try to translate the spanish part):
File carpetanueva = new File("C:"+File.separator+"sistema" + File.separator +
fechasal+File.separator+doc);
carpetanueva.mkdirs();
carpetanueva.setWritable(true);
rutadestino = ("c:"+File.separator+"sistema" +
File.separator + fechasal+File.separator +
doc+File.separator+"imagen.jpg");
//realizo la copia de la imagen desde el jfilechooser a su destino:
Path desde = Paths.get(rutaorigen);
Path hacia = Paths.get(rutadestino);
try {
Files.copy(desde, hacia);
JOptionPane.showMessageDialog(null,
"Se adjunto la planilla de ambulancia correctamente");
} catch (IOException e) {
JOptionPane.showMessageDialog(null, "error: "+e.getLocalizedMessage());
}
I get "rutaorigen" (frompath) from a JFileChooser. And I create "rutadestino" (topath) by using some variables so this way i can give an order. The problem is.. .if directories and the file "imagen.jpg" already exists, it gives an error.. (exception).. How can i make to check if image already exists, and if it does, rename the new image to , for example, imagen2? I cant figure out code, because im a newbie, I did a research and couldnt find something like this! Thanks in advance :)
OK, here is a quick solution if src is a Path to the file you want to copy, dst a Path to the file you want to write, and newName a Path to the file you want to rename to:
if (Files.exists(dst))
Files.move(dst, newName);
Files.copy(src, dst);
Note that you can use the methods in Path to facilitate your path building: .resolve(), .resolveSibling(), .relativize().
Edit: here is a function which will return a suitable name given a directory (dir), a base filename baseName and an "extension" (without the dot) extension:
private static Path findFileName(final Path dir, final String baseName,
final String extension)
{
Path ret = Paths.get(dir, String.format("%s.%s", baseName, extension));
if (!Files.exists(ret))
return ret;
for (int i = 0; i < Integer.MAX_VALUE; i++) {
ret = Paths.get(dir, String.format("%s%d.%s", baseName, i, extension));
if (!Files.exists(ret))
return ret;
}
throw new IllegalStateException("What the...");
}
I think this link will help How do I check if a file exists?
So for your case, probably do something like:
File toFile = new File(rutadestino);
if (toFile.exists()) {
// rename file
toFile.renameTo(new File("newFilePath/newName.jpg"));
} else {
// do something if file does NOT exist
}
Hope that helps! For more info, also check the Java Docs for File
sory late. but my code can help to litle bit.
public void copyFile(File source, File dest) throws IOException,
FileAlreadyExistsException {
File[] children = source.listFiles();
if (children != null) {
for (File child : children) {
if (child.isFile() && !child.isHidden()) {
String lastEks = child.getName().toString();
StringBuilder b = new StringBuilder(lastEks);
File temp = new File(dest.toString() + "\\"
+ child.getName().toString());
if (child.getName().contains(".")) {
if (temp.exists()) {
temp = new File(dest.toString()
+ "\\"
+ b.replace(lastEks.lastIndexOf("."),
lastEks.lastIndexOf("."), " (1)")
.toString());
} else {
temp = new File(dest.toString() + "\\"
+ child.getName().toString());
}
b = new StringBuilder(temp.toString());
} else {
temp = new File(dest.toString() + "\\"
+ child.getName());
}
if (temp.exists()) {
for (int x = 1; temp.exists(); x++) {
if (child.getName().contains(".")) {
temp = new File(b.replace(
temp.toString().lastIndexOf(" "),
temp.toString().lastIndexOf("."),
" (" + x + ")").toString());
} else {
temp = new File(dest.toString() + "\\"
+ child.getName() + " (" + x + ")");
}
}
Files.copy(child.toPath(), temp.toPath());
} else {
Files.copy(child.toPath(), temp.toPath());
}
} else if (child.isDirectory()) {
copyFile(child, dest);
}
}
}
}
features :
1. rename if file exist in the destination. example: document.doc if exist document (1).doc if exist document (2).doc if exist ...
2. copy all file from source (only file) to one folder in destination
The code below checks if the file already exists in destination, if it does, it appends #1 to file name just before the extension. If that file name also exists, it keeps appending #2,#3,#4... till the file name doesn't exist in destination. Since () and spaces create problems in Unix environment, I used # instead.
You can extend this and do a SUMCHECK if the file in destination with the identical name also has the same content and act accordingly.
Credit goes to johan indra Permana
String lastEks = file.getName().toString();
StringBuilder b = new StringBuilder(lastEks);
File temp = new File(backupDir.toString() + File.separator + file.getName().toString());
if (file.getName().contains(".")) {
if(temp.exists()) {
temp = new File(backupDir.toString() + File.separator +
b.replace(lastEks.lastIndexOf("."), lastEks.lastIndexOf("."),"#1").toString());
} else {
temp = new File(backupDir.toString() + File.separator + file.getName().toString());
}
b = new StringBuilder(temp.toString());
} else {
temp = new File(backupDir.toString() + File.separator + file.getName());
}
if (temp.exists()) {
for (int x=1; temp.exists(); x++) {
if(file.getName().contains(".")) {
temp = new File (b.replace(
temp.toString().lastIndexOf("#"),
temp.toString().lastIndexOf("."),
"#" + x ).toString());
} else {
temp = new File(backupDir.toString() + File.separator
+ file.getName() + "#" + x );
}
}
Files.copy(file.toPath(), temp.toPath());
} else {
Files.copy(file.toPath(), temp.toPath());
}

Deleting Multiple Files Java (Android)

I'm new to programming Android, and I want to delete Files on the sd-card. This is my current (working) code...
File appvc = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath(), "ApplifierVideoCache");
if (appvc.isDirectory()) {
String[] children = appvc.list();
for (int i = 0; i < children.length; i++) {
new File(appvc, children[i]).delete();
}
}
Now I want to delete multiple files, but dont want to mention each file with that big block. Am I able to combine all files in one variable? Thanks ;)
Make a recursive method:
/*
* NOTE: coded so as to work around File's misbehaviour with regards to .delete(),
* which does not throw an exception if it fails -- or why you should use Java 7's Files
*/
public void doDelete(final File base)
throws IOException
{
if (base.isDirectory()) {
for (final File entry: base.listFiles())
doDelete(entry);
return;
}
if (!file.delete())
throw new IOException ("Failed to delete " + file + '!');
}
Another possibility would be using the Apache commons-io library and calling
if (file.isDirectory())
FileUtils.deleteDirectory(File directory);
else {
if(!file.delete())
throw new IOException("Failed to delete " + file);
}
You should make a method out of this chunk of code, pass file name and call it whenever you like:
public void DeleteFile(String fileName) {
File appvc = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath(), fileName);
if (appvc.isDirectory()) {
String[] children = appvc.list();
for (int i = 0; i < children.length; i++) {
new File(appvc, children[i]).delete();
}
}
}
File dir = new File(android.os.Environment.getExternalStorageDirectory(),"ApplifierVideoCache");
Then call
deletedir(dir);
public void deletedir(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++) {
listFile[i].delete();
}
}
}
or if your folder as sub folders then
public void walkdir(File dir) {
File listFile[] = dir.listFiles();
if (listFile != null) {
for (int i = 0; i < listFile.length; i++)
{
if (listFile[i].isDirectory())
{
walkdir(listFile[i]);
} else
{
listFile[i].delete();
}
}
}
For kotlin
Create a array of path list
val paths: MutableList<String> = ArrayList()
paths.add("Yor path")
paths.add("Yor path")
.
.
delete file for each path
try{
paths.forEach{
val file = File(it)
if(file.exists(){
file.delete()
}
}
}catch(e:IOException){
}

Categories