Selenium download button indicates a zip file download by browser in Java - java

I have a download button without href link in a webpage.
I find it with findExtendedelement and click on it.
After the click a zip file download on the hard drive (i dont know where, and it shouldn't be matter)
I would like to catch this downloaded zip and put it in my project, for example build/reports/tests/temp folder.
Is it possible with selenium?
Update
The HTML looks:
https://i.stack.imgur.com/YnhlH.jpg
I tried this code:
#Test
public void userCanDownloadFile() throws FileNotFoundException, IOException
{
// Folder to store downloads and screenshots to.
reportsFolder = "./src/test/profiles/chrome/downloads/";
open("http://chromedriver.storage.googleapis.com/index.html?path=2.16/");
// Download files
$("a[href='/2.16/chromedriver_win32.zip']").download();
$(By.xpath(".//a[#href='/2.16/chromedriver_mac32.zip']")).download();
// Count files in folder, assert 2
int downloadsCount = new File(reportsFolder+"2.16").listFiles().length;
assertEquals("Should be 2 files but founded " + downloadsCount,
downloadsCount, 2);
// Clean after test
FileUtils.deleteDirectory(new File(reportsFolder+"2.16"));
}
Result:
java.lang.IllegalArgumentException: The element does not have href attribute:
The code is from:
http://selenide-recipes.blogspot.com/2015/08/how-to-download-file-with-selenide.html
I'm looking for something like that, I can handle the downloaded file in my project. (in reportsFolder path)
Unfortunately, this solution doesn't work, because the ExtendedElement (findExtendedElement("span", "class", "download_0") doesn't have an "a href" tag)
Thanks

this xpath: "//span[contains(#class,'download_o')]" should work

Related

How to upload multiple files in selenium for validation?

In a folder 5 CSV files and i need to upload one by one for validation purpose but even single file is not uploading i tried so many methods,can anyone suggest any methods, i'm doing in salesforce.
WebElement uploadElement = driver.findElement(By.xpath("//div[#class='cBatchMaster']//input[1]"));
uploadElement.sendKeys("E:\\Automation\\Error Inventory.csv");
above the code is for single file and directly i'm giving the exact file location but i want to upload the files in one folder
Thanks
Below is the solution in C#. A similar approach can be used in Java
Use AutoITX to upload files. You would need to add AutoItX.Dotnet in your nuget package
using AutoIt;
public static void UploadDocument(IWebElement uploadElement, string path)
{
uploadElement.Click();
AutoItX.WinActivate("Open");
string filepath = Path.Combine(System.IO.Path.GetFullPath(#"..\..\"),path);
Thread.Sleep(1000);
AutoItX.Send(filepath);
AutoItX.Send("{ENTER}");
}
You should be able to upload multiple files from AutoIT once you are able to upload the single file

How can I know the file name after downloading in automation test?

I am using selenium and testng to do Web UI automation test. I download files with Firefox using the same way as Access to file download dialog in Firefox. The file will be downloaded with default name without Open/Save/Cancel dialog successfully.
I repeat the test for different test data. The problems are
When there is a file with 'abc.pdf' in target 'browser.download.dir', if I download a file with same name, the new file will be saved to 'abc (1).pdf'; that's not what I want. In the following test I have problem to decide to open which pdf and check its content.
(Now my solution is, write a retry method: check if the file is downloaded, if yes, move it to another folder; if no, check again. Is there a better way?)
Sometimes when I click link or button to download, the file name is generated dynamically by web system. The file could be .pdf, .eml, .txt, etc. I can know the file suffix from UI. But I can't know the name in advance. Same here, I need open the file and do assertion in following test.
How to overcome? What if I need run the test in multiple threads? Much appreciated!
An easy way is to wait for a new file to be created with a file watcher:
https://docs.oracle.com/javase/tutorial/essential/io/notification.html
This is an example to wait for a .pdf file to be created:
// wait for the PDF to be downloaded
File file = WaitForNewFile(download_folder, ".pdf", 100);
/**
* Waits for a new file to be downloaded with a file watcher
*/
public static File WaitForNewFile(Path folder, String extension, int timeout_sec) throws InterruptedException, IOException {
long end_time = System.currentTimeMillis() + timeout_sec * 1000;
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
folder.register(watcher, StandardWatchEventKinds.ENTRY_MODIFY);
for (WatchKey key; null != (key = watcher.poll(end_time - System.currentTimeMillis(), TimeUnit.MILLISECONDS)); key.reset()) {
for (WatchEvent<?> event : key.pollEvents()) {
File file = folder.resolve(((WatchEvent<Path>)event).context()).toFile();
if (file.toString().toLowerCase().endsWith(extension.toLowerCase()))
return file;
}
}
}
return null;
}

Using selenium webdriver to upload a file

I'm trying to build some automated test for a mailbox application and I'm trying to attach a file. I've read all the documentation from previous post and was able to come up with this:
public void I_attach_a_file_that_exceeds_the_limit() throws Throwable {
WebElement attachFile = driver.findElement(By.id("attachment"));
File f = new File("C:\\coop-provider-swm-specs\\src\\test\\resources\\attachments\\20481kb.txt");
attachFile.sendKeys(f.getCanonicalPath());
}
The problem with this is that the file that it attaches is not the real file. The file that is attached is blank (not sure how that works). The file that I need to attach is a big file and I need to do this in order the authenticate that the user does not exceed the limit for attachments that is allowed.
Change:
attachFile.sendKeys(f.getCanonicalPath());
To:
attachFile.sendKeys(f.getCanonicalPath()).submit();

How to save .pdf file that pops up in a browser window with no url?

I am working with .pdf files that are available on my companies' website only. I am not aware of any way to download them and store in one folder.
The link that I click to get the .pdf file has the following source code:
<a href="javascript:propertiesView('documentName')">
As I click on the link, a .pdf file pops up in a new browser window with no url and no source code. I presume that there is no way to manipulate that .pdf directly, then how can I save it then in order to manipulate the .pdfs from a folder?
Thank You
You may have luck by simply telling your browser to always save PDF files to disk (credits to Dirk):
firefoxProfile.setPreference("browser.helperApps.neverAsk.saveToDisk", "application/pdf");
If that doesn't work, you are probably able to iterate through all open windows/tabs by using the switchTo() methods. Try something like this to get some insight about your opened windows (credits to Prashant Shukla):
public void getWindows() {
Set<String> windows = driver.getWindowHandles();
for (String window : windows) {
driver.switchTo().window(window);
System.out.println(driver.getTitle());
}
}
A non-selenium solution to download the file would be to use the apache-commons library (creadits to Shengyuan Lu):
org.apache.commons.io.FileUtils.copyURLToFile(URL, File)
But this would require that you know the URL of the window, which you probably are able to fetch with the second approach i mentioned (driver.switchTo()) and driver.getCurrentUrl().
I presume that there is no way to manipulate that .pdf directly
That's correct. With Selenium, you cannot.
how can I save it then in order to manipulate the .pdfs from a folder?
I've actually implemented this exact thing in our regression system where I work.
My first step, was to construct a Url based on what the propertiesView(). method did.
in your case, propertiesView() does some sort of window.open is my guess. So your goal is, to extract that Url that it opens, and use concatenation to construct the url.
Once you've found your Url, the rest is a cakewalk. Just download the url to a folder named /pdfs. See this question for how to do that.
It may even require calling that method to figure it out.. Due to my ignorance of your System Under Test, it's difficult for me to give you a code answer, unless you posted it.
A hint that i'll tell you, is if you are using Selenium 1, use
String url =selenium.getEval("var url = something; url;");
to fetch the url and get it into a java object.
(If using selenium 2, use the JavaScriptExecutor#executeScript)
If you want to save a PDF to your hard drive in IE with selenium, you need to use pywinauto with selenium. I just used this code for PDF files that open up in the browser.
//selenium imports
from pywinauto import application //pywinauto import
//write selenium code to open up pdf in the browser
driver = webdriver.Ie("IEDriverServer.exe", capabilities = caps)
//this could be a get or driver.execute_script() to click a link
driver.get("link to pdf")
//save pdf
app = application.Application()
//get the ie window by the title of the application (assuming only one window is open here)
ie = app.window_(title_re = ".*Internet Explorer.*")
//this line focuses on the pdf that is open in the browser
static = ie.Static
//focus on the pdf so we can access the internal controls
static.SetFocus()
//control + h shows the pdf bar, but you don't really need this step
//for it to work. i just used it as a debug
static.TypeKeys("^H")
//open save file dialog
static.TypeKeys("+^S")
//tricky here because the save file dialog opens up as another app instance
//which is how pywinauto sees it
app2 = application.Application()
//bind to the window by title - name of the dialog
save = app2.window_(title_re = ".*Save As.*")
//this is the name of the property where you type in the filename
//way to be undescriptive microsoft
file_name = save[u'FloatNotifySink']
//type in the file name
save.TypeKeys("hello")
//pause for a second - you don't have to do this
time.sleep(4)
//find and bind the save button
button = save[u'&SaveButton']
//click the save button
button.Click()

getAbsolutePath() like method in UploadedFile(org.apache.myfaces.custom.fileupload.UploadedFile;)

I am currently working on an application, where users are given an option to browse and upload excel file, I am badly stuck to get the absolute path of the file being browsed. As location could be anything (Windows/Linux).
import org.apache.myfaces.custom.fileupload.UploadedFile;
-----
-----
private UploadedFile inpFile;
-----
getters and setters
public UploadedFile getInpFile() {
return inpFile;
}
#Override
public void setInpFile(final UploadedFile inpFile) {
this.inpFile = inpFile;
}
we are using jsf 2.0 for UI development and Tomahawk library for browse button.
Sample code for browse button
t:inputFileUpload id="file" value="#{sampleInterface.inpFile}"
valueChangeListener="#{sampleInterface.inpFile}" />
Sample code for upload button
<t:commandButton action="#{sampleInterface.readExcelFile}" id="upload" value="upload"></t:commandButton>
Logic here
Browse button -> user will select the file by browsing the location
Upload button -> on Clicking upload button, it will trigger a method readExcelFile in SampleInterface.
SampleInterface Implementation File
public void readExcelFile() throws IOException {
System.out.println("File name: " + inpFile.getName());
String prefix = FilenameUtils.getBaseName(inpFile.getName());
String suffix = FilenameUtils.getExtension(inpFile.getName());
...rest of the code
......
}
File name : abc.xls
prefix : abc
suffix: xls
Please help me in getting the full path ( as in c:.....) of the file being browsed, this absolute path would then be passed to excelapachepoi class where it will get parsed and contents would be displayed/stored in ArrayList.
Why do you need the absolute file path? What can you do with this information? Creating a File? Sorry no, that is absolutely not possible if the webserver runs at a physically different machine than the webbrowser. Think once again about it. Even more, a proper webbrowser doesn't send information about the absolute file path back.
You just need to create the File based on the uploaded file's content which the client has already sent.
String prefix = FilenameUtils.getBaseName(inpFile.getName());
String suffix = FilenameUtils.getExtension(inpFile.getName());
File file = File.createTempFile(prefix + "-", "." + suffix, "/path/to/uploads");
InputStream input = inpFile.getInputStream();
OutputStream output = new FileOutputStream(file);
try {
IOUtils.copy(input, output);
} finally {
IOUtils.closeQuietly(output);
IOUtils.closeQuietly(input);
}
// Now you can use File.
See also:
How to get the file path from HTML input form in Firefox 3
I remember to have some problem with this in the past too. If I am not mistaken, I think you cannot get the full file path when uploading a file. I think the browser won't tell you it for security purposes.

Categories

Resources