How to get last downloaded file using selenium - file

Is there anyway I can get the last downloaded file using selenium. Currently I am downloading an Excel file using selenium, I need to get that file and read it. the reading part is covered, but I need the downloaded file path and file name in order to read it. So far i haven't found anything which can help. I am looking mainly for a google chrome solution, but firefox works too.
Thanks in advance

You can save your download to a fix location by using the profile. Check these discussions:
Downloading file to specified location with Selenium and python
Access to file download dialog in Firefox
As you have mentioned that you have covered the reading part. You can read it from that fixed location.

Below is the code snippet that can help resolve the above query:
**Changes in driver file:**
protected File downloadsDir = new File("");
if (browser.equalsIgnoreCase("firefox"))
{
downloadsDir = new File(System.getProperty("user.dir") + File.separatorChar + "downloads");
if (!downloadsDir.exists())
{
boolean ddCreated = downloadsDir.mkdir();
if (!ddCreated) {
System.exit(1);
}
}
}
/*Firefox browser profile*/
FirefoxProfile firefoxProfile = new FirefoxProfile();
firefoxProfile.setPreference("browser.download.folderList", 2);
firefoxProfile.setPreference("browser.download.manager.showWhenStarting", false);
firefoxProfile.setPreference("browser.download.dir", downloadsDir.getAbsolutePath());
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "text/plain,application/octet-stream");
**Empty the download directory[Can be implemented as #BeforeClass]:**
public void emptyDownloadsDir()
{
// Verify downloads dir is empty, if not remove all files.
File[] downloadDirFiles = downloadsDir.listFiles();
if (downloadDirFiles != null) {
for (File f : downloadDirFiles) {
if (f.exists()) {
boolean deleted = FileUtility.delete(f);
assertTrue(deleted, "Files are not deleted from system local directory" + downloadsDir + ", skipping the download tests.");
}
}
}
}
**Check the Latest downloaded file:**
/*Test file*/
protected static String EXCEL_FILE_NAME= Test_Excel_File.xls;
protected static int WAIT_IN_SECONDS_DOWNLOAD = 60;
// Wait for File download.
int counter = 0;
while (counter++ < WAIT_IN_SECONDS_DOWNLOAD && (downloadsDir.listFiles().length != 1 || downloadsDir.listFiles()[0].getName().matches(EXCEL_FILE_NAME))) {
this.wait(2);
}
// Verify the downloaded File by comparing name.
File[] downloadDirFiles = downloadsDir.listFiles();
String actualName = null;
for (File file : downloadDirFiles) {
actualName = file.getName();
if (actualName.equals(EXCEL_FILE_NAME)) {
break;
}
}
assertEquals(actualName, EXCEL_FILE_NAME, "Last Downloaded File name does not matches.");

import os
import glob
home = os.path.expanduser("~")
downloadspath=os.path.join(home, "Downloads")
list_of_files = glob.glob(downloadspath+"\*.pptx") # * means all if need specific format then *.csv
latest_file = max(list_of_files, key=os.path.getctime)
Simplified solution to get the path to last file in Downloads folder. The above code will get path of the latest .pptx file in Downlodas. Change the extension as required. Or else you can chose not to specify the extension

Note, Shared answer is specific to Chrome Browser and will ONLY return LATEST downloaded file. But we can modify accordingly it for other browsers and for all files as well.
Let say, how we test latest downloaded file in browser.
In existing test browser Open NewTab Window
Go to
downloads (chrome://downloads/)
Check if expected file is there
or not
Now same thing in selenium using java
driver.get("chrome://downloads/");
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement element = (WebElement) js.executeScript("return document.querySelector('downloads-manager').shadowRoot.querySelector('#mainContainer > iron-list > downloads-item').shadowRoot.querySelector('#content')");
String latestFileName= element.getText();

Related

Downloads folder shared file write permissions problem

I am trying to get an offline backup function working on Android 12. It has worked for years on previous versions of Android, 6 & 8. It is required as the size of the backup can often exceed 25mb. I am using a Samsung A7 Lite for this testing to ensure Android 12 compliance. Essentially the function initially creates a backup folder in the downloads folder if it does not exist. It then writes a backup file to that folder. All goes well. I can repeat the function any number of times without there being a problem. It retains father and grandfather versions for security. However, if I try to use the same function where there are existing files the following day, I am presented with a java.io.FileNotFoundException, open failed EACCES (Permission denied). This whole situation appears very illogical, and does not appear to follow the documentation on accessing the downloads folder. If I manually delete the backup file from the previous day, the process succeeds, similarly if I delete the backup directory within the downloads folder, the backup proceeds successfully. The app asks the user for the appropriate permissions which I believe are read and write external storage. Can anybody identify what I am doing wrong in this environment.
The code is below.
String path = "";
// if no external, set to download
if (path.equals("")) {
File systemPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
path = systemPath.getAbsolutePath();
}
// set up backup subdirectory
path = path + "/backup";
// check if path exists
File backupDir = new File(path);
if (!backupDir.exists()) {
try {
backupDir.mkdirs();
MediaScannerConnection.scanFile(this, new String[]{backupDir.getAbsolutePath()}, null, null);
}
catch(Exception e){
e.printStackTrace();
}
}
// first get rid of old backup files leaving at least 2 older versions
File backupFile = new File(path,"backup3.bkp");
if (backupFile.exists())
backupFile.delete();
for (int i = 3;i > 1;i--){
File renameBackupFile = new File(path,"backup" + i + ".bkp");
File existBackupFile = null;
if (i == 2)
existBackupFile = new File(path,"backup.bkp");
else
existBackupFile = new File(path,"backup" + (i - 1) + ".bkp");
if (existBackupFile.exists()) {
try {
existBackupFile.renameTo(renameBackupFile);
} catch (Exception e) {
String message = e.toString();
}
}
}
// create a new backup
String fileName = "backup.bkp";
String backup = path + "/" + fileName;
FileInputStream dataBaseFile = new FileInputStream(DB_PATH);
File newBackupFile = new File(backup);
newBackupFile.createNewFile();
FileOutputStream backupStream = new FileOutputStream(newBackupFile);
//transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = dataBaseFile.read(buffer)) > 0) {
backupStream.write(buffer, 0, length);
}
//Close the streams
backupStream.flush();
backupStream.close();
dataBaseFile.close();
MediaScannerConnection.scanFile(this, new String[]{newBackupFile.getAbsolutePath()}, null, null);

Is there a way in selenium to upload the last downloaded file with dynamic name?

The problem I am facing is I have a file which is having a dynamic number at the last.
For example: Tax_subscription_124.pdf which changes everytime.
Can I upload this particular file as currently I am downloading it in a particular location but not able to upload the same due to dynamic name?
The following code returns the last modified file or folder:
public static File getLastModified(String directoryFilePath)
{
File directory = new File(directoryFilePath);
File[] files = directory.listFiles(File::isFile);
long lastModifiedTime = Long.MIN_VALUE;
File chosenFile = null;
if (files != null)
{
for (File file : files)
{
if (file.lastModified() > lastModifiedTime)
{
chosenFile = file;
lastModifiedTime = file.lastModified();
}
}
}
return chosenFile;
}
Note that it required Java 8 or newer due to the lambda expression.
After that
WebElement fileInput = driver.findElement(By.name("uploadfile"));
fileInput.sendKeys(chosenFile);

Eclipse PDE: Get full path of an external file open in Workbench

I am writing an Eclipse Plugin which requires me to get full path of any kind of file open in the Workspace.
I am able to get full path of any file which is part of any Eclipse project. Code to get open/active editor file from workspace.
public static String getActiveFilename(IWorkbenchWindow window) {
IWorkbenchPage activePage = window.getActivePage();
IEditorInput input = activePage.getActiveEditor().getEditorInput();
String name = activePage.getActiveEditor().getEditorInput().getName();
PluginUtils.log(activePage.getActiveEditor().getClass() +" Editor.");
IPath path = input instanceof FileEditorInput ? ((FileEditorInput) input).getPath() : null;
if (path != null) {
return path.toPortableString();
}
return name;
}
However, if any file is drag-dropped in Workspace or opened using File -> Open File. For instance, I opened a file from /Users/mac/log.txt from File -> Open File. My plugin is not able to find location of this file.
After couple of days search, I found the answer by looking at the source code of Eclipse IDE.
In IDE.class, Eclipse tries to find a suitable editor input depending on the workspace file or an external file. Eclipse handles files in workspace using FileEditorInput and external files using FileStoreEditorInput. Code snippet below:
/**
* Create the Editor Input appropriate for the given <code>IFileStore</code>.
* The result is a normal file editor input if the file exists in the
* workspace and, if not, we create a wrapper capable of managing an
* 'external' file using its <code>IFileStore</code>.
*
* #param fileStore
* The file store to provide the editor input for
* #return The editor input associated with the given file store
* #since 3.3
*/
private static IEditorInput getEditorInput(IFileStore fileStore) {
IFile workspaceFile = getWorkspaceFile(fileStore);
if (workspaceFile != null)
return new FileEditorInput(workspaceFile);
return new FileStoreEditorInput(fileStore);
}
I have modified the code posted in the question to handle both files in Workspace and external file.
public static String getActiveEditorFilepath(IWorkbenchWindow window) {
IWorkbenchPage activePage = window.getActivePage();
IEditorInput input = activePage.getActiveEditor().getEditorInput();
String name = activePage.getActiveEditor().getEditorInput().getName();
//Path of files in the workspace.
IPath path = input instanceof FileEditorInput ? ((FileEditorInput) input).getPath() : null;
if (path != null) {
return path.toPortableString();
}
//Path of the externally opened files in Editor context.
try {
URI urlPath = input instanceof FileStoreEditorInput ? ((FileStoreEditorInput) input).getURI() : null;
if (urlPath != null) {
return new File(urlPath.toURL().getPath()).getAbsolutePath();
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
//Fallback option to get at least name
return name;
}

get email attatchment for POP 3 received as winmail.dat

When I try to get attatchment from POP 3 mail, I am getting them as winmail.dat, not the original attached file name. How can I get the original file name?
for (int i = 0; i < multipart.getCount(); i++)
{
BodyPart bodyPart = multipart.getBodyPart(i);
if(!Part.ATTACHMENT.equalsIgnoreCase(bodyPart.getDisposition()))
{
//do something
}
else
{
bodyPart.getFileName(); // here only get the winmail.dat
}
}
This is part of the Exchange Settings, and sadly you going to need to extract the original contents from the WinMail.dat using JTNEF.
"The Java TNEF package is an open source code implementation of a TNEF message handler, which can be used as a command-line utility or integrated into Java-based mail applications to extract the original message content."
This is found on the JavaMail's third party tools.
As alternative and what looks simpler is POI-HMEF
Sample extraction:
public void extract(String winmailFilename, String directoryName) throws Exception {
HMEFContentsExtractor ext = new HMEFContentsExtractor(new File(winmailFilename));
File dir = new File(directoryName);
File rtf = new File(dir, "message.rtf");
if(! dir.exists()) {
throw new FileNotFoundException("Output directory " + dir.getName() + " not found");
}
System.out.println("Extracting...");
ext.extractMessageBody(rtf);
ext.extractAttachments(dir);
System.out.println("Extraction completed");
}
There is also a sample for printing the contents here.

File exists but program throws a FileNotFoundException

/*
*This program checks type casting from String to int/double from a file
*/
import java.io.*;
import java.lang.String;
public class ConvertingStringsToNums {
public static void main (String[] args){
File dataFile = new File("/files/scores.dat");
FileReader in;
BufferedReader readFile;
String score;
double avgScore, totalScores = 0;
int numScores = 0;
//------------------------------------------------------------
try {
in = new FileReader(dataFile);
readFile = new BufferedReader(in);
while((score = readFile.readLine()) != null) {
numScores += 1;
System.out.println(score);
totalScores += Double.parseDouble(score);
}
avgScore = totalScores / numScores;
readFile.close();
in.close();
} catch(FileNotFoundException e) {
System.err.println("FileNotFoundException: " + e.getMessage());
} catch (IOException e) {
System.err.println("IOException: " + e.getMessage());
} //end try/catch
}
}
1) If you wish to open a file at an absolute file path on your hard drive:
br = new BufferedReader (
new FileReader(
new File ("/files/scores.dat")));
2) If you wish to open a file at an relative path relative to where you started your app:
br = new BufferedReader (
new FileReader(
new File ("files/scores.dat")));
3) If you wish to open a file at an relative path relative to your class files (particularly relevant for packages and/or for executing from a .jar or a .war):
this.getClass().getResourceAsStream ("files/scores.dat");
'Hope that helps
The reason is can be that you wont be having permission to open the file.
try chmod 755 scores.dat from terminal in order to change the permissions and see if the error still exist.
The answer to this problem exists in the javadocs for the File class:
For UNIX platforms, the prefix of an absolute pathname is always "/". Relative pathnames have no prefix. The abstract pathname denoting the root directory has the prefix "/" and an empty name sequence.
In your code, you have the following:
File dataFile = new File("/files/scores.dat");
According to the documentation, this is an absolute path, which means Java is looking for a folder at the root of the filesystem called "files" and then looking for scores.dat in that folder.
If you instead expect to search for a files directory that is relative to the current directory, you'd need to omit the first /:
File dataFile = new File("files/scores.dat");
The other option is to use an absolute path to your data file, but you may run into problems if you change the location of your project or put the class files in a JAR file.
Try turning up your logging level to DEBUG or ALL so that you can see exactly where the program is trying to look. This will help you adjust your code to target the right folder.

Resources