How to best handle file upload failures in selenium webdriver - selenium-webdriver

I am looking for any ideas on how best to handle file upload failures in selenium webdriver.
Recently I have been seeing a higher number of failures in my webdriver test suite, the error I am trying to fix is a failure in the Internet Explorer tests caused by a file upload failing.
In webdriver the only way I know to upload a file to an input element is to use the SendKeys() method and pass the file path to SendKeys() this works like a charm in chrome and firefox but periodically have had issues with it in Internet Explorer. What appears to happen is the file upload window gets opened but the path is not typed nor is the file uploaded. This leaves the node with a file upload window open, being this is a native window's window and not a webpage selenium cannot interact with the pop up.
The result is the HttpWebRequest does not get a response back triggering a WebdriverTimoutException. This results in the session getting cleaned up. This causes a cascade of failures for all other tests in the suite as the session has been terminated.
Environment Info:
Selenium.Webdriver & Seleneium.Support version 3.7.0
IEDriver 3.7.0
Testing in IE 11

I may be late to answer this question, but someone will benefit.
The file(s) in question should be available on the machine (be it local or remote server) that your program is running on, for example, in your /resources directory
On your local machine, this should work.
chooseFileElement.waitForVisible().type("/file/path/filename.jpg");
clickButton("Attach File");
On Remote Server however, you need to associate a new instance of LocalFileDetector to the <input type=file> element.
LocalFileDetector detector = new LocalFileDetector();
File localFile = detector.getLocalFile("/file/path/filename.jpg");
RemoteWebElement input = (RemoteWebElement) myDriver().findElement(By.id("fileUpload"));
input.setFileDetector(detector);
input.sendKeys(localFile.getAbsolutePath());
clickButton("Attach File");

It really depends on how you've written your code. What I would do is when you get down to the end and detect that you've gotten into a bad state, e.g. the File | Open dialog has been left open, close the dialog and start that part of the script over. I'm not sure what start over in your case would mean... maybe it means reload the page and start from there... maybe it means just .sendKeys() to the INPUT again.
You should be able to dismiss the dialog by sending an ESC to the page. You should be able to use .sendKeys() on the BODY tag or whatever.
You should be able to detect the bad state by catching certain exceptions.

Related

WebExtensions: is it possible to intercept/register a handler with the "file open" dialogs?

I have a Web Extension that occasionally deals in files -- usually by sending off a URL to the file to a remote server or by downloading the file at the user's request and shipping off the bytes to the same server.
This works fine for most use-cases, but sometimes you'll come across a site that automatically triggers a download of a file and pops open the file-open dialog for the user to handle. I wasn't able to find any documentation or filed bugs to this effect, but is there a way to register an extension to appear as a handler in that dialog?
Its currently not possible to add an icon to the file chooser dialog with WebExtensions. Feel free to open a feature request here: http://bugzilla.mozilla.org/
If you want to handle an action whenever a download occurs, you can use
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/API/downloads/onCreated

Multiple BackgroundWorker throws timeout exception

If I keep two FileDownload (find code in below link) in Pause mode and if I start 3rd third instance of Filedownload, I am getting timeout error.
I am working on a WPF application where I need to download multiple .zip files from a CDN server. I am using following code to download file.
https://www.codeproject.com/Articles/35954/C-NET-Background-File-Downloader?msg=5402177#xx5402177xx
In my case I have to download multiple files simultaneously and to show progress for each file downloading. I am creating an instance of FileDownloader (find code in below link) class each time when user downloads a file.
I am facing operation timeout error, when I am keeping two instances of FileDownloader on Puase mode and when I start 3rd instance. The 3rd instance continuously waiting at webResp = (HttpWebResponse)webReq.GetResponse(); and after sometime it throws operation timeout error.
If I try to download same zip files through chrome browser, and if keep first to on pause still the 3rd file getting downloaded.
Any suggestions, how to resolve the issue?
Resolved the issue, by default the number of connection an application can open are 2 but with below line of code you can set it to higher number. It can also be done in app.config
https://msdn.microsoft.com/en-us/library/fb6y0fyc(v=vs.110).aspx
ServicePointManager.DefaultConnectionLimit = 65000;

C# Selenium Webdriver Interacting with native image upload dialog using SendKeys.SendWait does not work on TeamCity

I am using Windows.Forms.SendKeys.SendWait to interact with the native windows dialog when uploading an image.
I click the upload button using webdriver, then go:
SendKeys.SendWait("^A"); //Highlight content so it can be overwritten
SendKeys.SendWait(path);
SendKeys.SendWait(#"{Enter}");
Works great when I run it locally on my PC, however, the test won't run on the TeamCity agent (I have many other tests that run OK). It fails as it seems that native dialog never appears or if it does, it can't interact with it.
Not sure what's happening as this whole test agent process runs in the background and I can't see what it's doing - I can take screenshots using webdriver but it won't capture native dialogs anyway.
I tried to configure the team city test agent windows service (change Log On settings to allow interacting with desktop) but this did not work. Seems it just isn't able to interact with it... any ideas on how to make this work?
In order to upload a file with Selenium, you should use Webdriver's SendKeys directly to the input element that requires the path (Not Forms.SendKeys). See this example.
Note: You'll need to avoid clicking the button that opens the dialog.

How to get file download complete status using selenium web driver c#

I am writing a automation script using selenium web driver for downloading multiple files one by one from a web site in Mozilla fire fox. I have downloaded first file successfully and next time I need to wait for download to complete. Can anybody help how to identify an ongoing download is completed using c# selenium web driver.? Since I am not getting the download complete status, I am unable to continue downloading next file.
Assuming you are testing file downloading in Firefox as you mentioned. Here is an approach to achieve what you want.
Open new window/tab in Firefox and navigate to 'about:downloads' directly.
i.e. driver.Navigate().GoToUrl("about:downloads");
You will get the list of downloads (i.e. already downloaded files and the file which is being downloaded currently.)
You will have to switch between your site tab and downloads tab.
Now on downloads tab, looking at HTML, you can easily find out in progress download using state or status attributes.
For example, for the first file in the list, if state="0" and/or status
contains the text 'remaining', it means downloading is in progress
So you can wait till state becomes state = 1 and/or status does not contain >the text 'remaining'
Refer the attached screen shot.
The explanation I gave here looks very high level, but I am sure this approach will work. It is simple too.
Let me know if you have any queries on this.

Can Protractor click Flash's "Adobe Flash Player Settings" prompt?

My Protractor suite is running on a webapp that uses Flash to capture camera and microphone. Of course, the first time anyone uses the app, Flash pops up a dialog box to ask for permission to use the webcam and mic.
The HTML for this dialog looks like this:
<div id="flash-container" class="">
<object width="247" height="159" id="flashRecorder" type="application/x-shockwave-flash" data="EIRecorderProcess.swf" style="visibility: visible;">
<param name="allowScriptAccess" value="always">
<param name="wmode" value="transparent">
</object>
</div>
And the dialog box itself looks like this:
Protractor gets hung here, because it doesn't seem to know how to click the "Allow" button and the app won't let it continue until it does. Here's what I've tried:
I visited my site-specific Flash security settings to allow access
for the webapp. But every time WebDriver runs, it creates a
temporary profile on Chrome, which doesn't know about those security
settings, so the Settings box pops up anyway.
I set up the Protractor config file to run Chrome with the options
'use-fake-device-for-media-stream', 'use-fake-ui-for-media-stream',
and 'disable-bundled-ppapi-flash'. The first two don't make a difference.
The last one breaks everything for real.
I tried using this:
browser.actions()
.mouseMove(element(by.css('object#flashRecorder')), x, y)
.click()
.perform();
And even though I'm a crack-shot and I'm pretty sure I nailed the button's
coordinates (used some javascript coordinate tracing to be sure), nothing happened.
I used the Chrome flag "user-data-dir=/a/random/path" so that after the first
time hitting the dialog and clicking "Allow" and "Remember", the security settings are
stored and it doesn't pop up
any more. This is the current workaround, but creates some extra overhead for any
devs who want to run the tests, and the programmer in me says it isn't kosher for
an automated test to require human interaction.
Has anyone found another way to do this?
This is not Chrome prompting for permission; it is Flash. So the standard Chrome hacks (e.g., --use-fake-ui-for-media-stream) will not work here.
I solved this problem by generating the required Flash permissions file, and uploading it to the appropriate directory, so that Flash is satisfied.
The Flash permissions you need are stored in a file called 'settings.sol', in a directory specific to the host you are accessing. That file is in AMF format, and I use the Python PyAMF library to generate it. It works something like this:
from pyamf import sol
object = sol.SOL ('www.hostname.com/settings')
object[u'allow'] = True
object[u'always'] = True
object[u'klimit'] = 100
sol.save (object, 'settings.sol')
Not the 'www.hostname.com' specified in the name; that must be the host name that is requesting permission.
Then you have to upload this file to the correct directory, which you may have to create, and that directory is specific to the host name.
There are actually two directories in Chrome; one for NPAPI Flash (the old technology that is going away in Chrome 45) and one for Pepper Flash (the new technology).
The old (NPAPI) Flash permissions are stored in a fixed location, and the directory path includes the host name ('www.hostname.com' in the example above):
C:\Users\UserName\AppData\Roaming\Macromedia\Flash Player\macromedia.com\support\flashplayer\sys\#www.hostname.com\settings.sol
The new (Pepper) Flash permissions are stored in the user's Chrome directory, which as you point out, is created by WebDriver for each browser instance. WebDriver returns that directory to you in the 'userDataDir' key of the 'chrome' capabilities. Again in Python:
user_dir = my_driver.capabilities.get ('chrome').get ('userDataDir')
Then the settings.sol file needs to be put in the following directory, which you must create:
[user_dir]\Default\Pepper Data\Shockwave Flash\WritableRoot\#SharedObjects\12345678\macromedia.com\support\flashplayer\sys\#www.hostname.com\settings.sol
Note the '12345678' here. If you let Flash create the permissions file, it will use a semi-random number here. But since this is a freshly-created user directory, and since we are creating almost the entire path, we can just make one up.
Once you have created the appropriate settings.sol file, and created the appropriate directory structure, and uploaded the settings.sol file to the correct place in that directory structure, then Flash will find this file that grants permission, and it will no longer prompt you.

Resources