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

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.

Related

How to best handle file upload failures in 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.

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.

IE file download box get location

i am currently working on a issue where i need to get location of the file downloaded.First let me explain the scenario.
I placed a link in my page and when user clicks the link it shows file download dialog with open/save/cancel options in IE.Now when the user clicks on the save button and choose a location to save the file i need to get that file saved location using whatever options possible.
Thanks!
I do not think you can... at least not easy. This runs on the client, and for security reasons you can not acces the client's filesystem with javascript.
Maybe it is however possible using a flash or silverlight plugin, as the user can allow access from within these applications to the local filesystem. It might be very difficult tho...
The browser will not allow you to access information about the clients filesystem.

Open a file in the browser from Silverlight

I have a Button (or a hyperlinkbutton) in Silverlight. I want to open a file on a server share when this butto in clicked. With other words I want a new Browser Tab or Window to open showing the requested file, just like I enter the URL in the browsers addressbar:
file://C:\myfile.txt
I tried in the OnClick Method the following:
System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(#"file://C:\myfile.txt"),"_blank");
it throws an Exception (Access denied).
When I do the same with an http: page it works:
System.Windows.Browser.HtmlPage.Window.Navigate(new Uri(#"http://www.somedomain.com"),"_blank");
How can I achive the same with a file. Security can not be an issue, I have full access to that file. And please don't tell me that this is not possible... would mean we have to go back to PHP.
Silverlight runs on the client side and in by default in LOW trusted mode which dont allow application to access local file system.
For the purpose, u can try giving full trust to the silverlight application.
Firefox does not allow external URLs to link to a local resource anymore :(

How to make .exe file programmatically set to run as admin always in vista?

I have written a winform application in C#. When I run the program for some functionality it required admin permission. After Installation If I set the .exe file to run as admin manually (by clicking right mouse button on .exe file) then my program run perfectly.
Now I need user not to set the run as admin property after installation by clicking right mouse button. I need to set this programaticaly somewhere in the code that user no need to bother about this. This specific problem is only arise for Windows Vista. Can anyone help me out?
You need to add a manifest to the app that specifies it require admin privileges. Read more on MSDN.
Update: You can add a manifest to your project by right-clicking on the project and selecting Add / New Item / Application Manifest File. This will add a new file called app.manifest to your project and will reference it from the project properties, in the Manifest dropdown on the Application tab. The default manifest template even has a nice comments on how exactly to change the required UAC execution level.
You need to specify the requestedExecutionLevel in the manifest.
See here for a detailed explanation:
http://petesbloggerama.blogspot.com/2007/04/making-your-assembly-run-as.html

Resources