3
votes

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:

Flash permissions dialog

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:

  1. 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.

  2. 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.

  3. 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.

  4. 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?

1
--use-fake-ui-for-media-stream argument should do the trick. Can you show how have you passed it to chrome? Thanks.alecxe
Here are the relevant lines from my protractor.conf.js: capabilities: { 'browserName': 'chrome', 'chromeOptions': { 'args': ['use-fake-device-for-media-stream', 'use-fake-ui-for-media-stream'] }, },Isaac Lyman
What if you try this way? capabilities: { 'browserName': 'chrome', 'chromeOptions': { 'args': ['--use-fake-ui-for-media-stream'] }, }alecxe
@alecxe, I've tried it that way too. The chromeOptions array doesn't require the double dashes that you would need on the command line. I tested with 'show-fps-counter', which is very visible, to make sure they were getting through.Isaac Lyman
Okay, thanks, I've always put the -- before, just wanted to check. Good to know.alecxe

1 Answers

2
votes

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.