Webdriver.io enable flash for selenium-standalone - google-chrome

I'm writing acceptance tests on node.js using webdriver.io with selenium standalone server with latest Google Chrome driver.
I need to check that flash elements are clickable, but browser keeps to show me "Restart Chrome to enable Adobe Flash Player".
I've seen article that shows how to make Chrome driver to see custom profile on local machine, but I can't understand how to use this with my standalone server, since it has poor examples for configuration.
Can you explain the correct way to enable Adobe flash player for selenium standalone server in webdriver.io?

I found that the following worked:
browserName: 'chrome',
'goog:chromeOptions' : {
args: ['enable-features=RunAllFlashInAllowMode',
'disable-features=EnableEphemeralFlashPermission'],
prefs: {
"profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player": 1,
'PluginsAllowedForUrls': '/route/to/site.com'
}
}
Using ephemeral mode will create a temp profile which allows the prefs to take effect:
https://developer.chrome.com/extensions/contentSettings
https://support.google.com/chrome/a/answer/3538894?hl=en
'goog:chromeOptions' was introduced as of selenium 3.8 github.com/elgalu/docker-selenium/issues/201 –
You can open up the profile which is a JSON blob and see the site added at profile.content_settings.exceptions.plugins and profile.content_settings.exceptions.flash_data.

It is very easy. you need to create a custom profile that you will always use to load your chrome with. then you configure the browser like you would do manually too. this means make website exclusions for flash. load some extensions or whatever you want to preconfig. with this code you can do it
// setup browser
var options = {
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
args: ['user-data-dir=C:/Users/Administrator/AppData/Local/Google/Chrome/User Data/Profile 21v69',
'--lang=en']
} // chromeOptions: {
} // desiredCapabilities: {
} // options = {
var client = webdriverio.remote(options).init();
Also here are all command line commands for chrome
https://peter.sh/experiments/chromium-command-line-switches/

Another workable method. It's possible to allow flash plugin execution in the chrome config
You need to add in the wdio.conf.js three last preferences from code example
chromeOptions : {
args: chromeArgs,
prefs: {
"download.default_directory": process.env.PWD +'/download',
"profile.default_content_setting_values.plugins": 1,
"profile.content_settings.plugin_whitelist.adobe-flash-player": 1,
"profile.content_settings.exceptions.plugins.*,*.per_resource.adobe-flash-player": 1
}
}
I hope it will helpful

Related

Proxy setting using chrome extension not working with chrome43

I am using chrome extension for switching the chrome proxy setting at runtime.
I have tested my code on chrome 59 and chrome 69 which is working fine.
However, the same code is failing when being tried upon chrome43.
The proxy is not getting switched and the requests are getting directly routed.
Do we have extension issues with chrome43?
Is there any other way to switch the chrome proxy at runtime without the need to restart the chrome browser?
let proxy = xx.xx.xx.xx; //intentionally masked for sharing code
let configPAC = {
mode: "pac_script",
pacScript: {
data : "function FindProxyForURL(url, host) { return 'PROXY "+proxy+"';}",
mandatory:true
}
};
chrome.proxy.settings.set({value: configPAC, scope: "regular"}, function() { console.log("Setting custom proxy here!");});

Permission issue for appium chrome borwser

I am implementing an appium test on remote android driver, with chrome browser for loading urls.
Some of the Urls are pdfs, and chrome asks to store those files. and appears that chrome doesnt have access to filesystem to store those files, which results in a dialog like below.
Please help me pass that dialog without any manual inputs.
Upon clicking continue, it will load actual permissions dialog from Android.
Here is my code initialize appium capabilities
DesiredCapabilities caps = DesiredCapabilities.android();
caps.setCapability("appiumVersion", "1.9.1");
caps.setCapability("deviceName","Samsung Galaxy S9 Plus HD GoogleAPI Emulator");
caps.setCapability("deviceOrientation", "portrait");
caps.setCapability("browserName", "Chrome");
caps.setCapability("platformVersion", "8.1");
caps.setCapability("platformName","Android");
caps.setCapability("autoAcceptAlerts", true);
caps.setCapability("autoGrantPermissions", true);
caps.setCapability("chromedriverArgs", "--allow-file-access-from-files");
caps.setCapability("maxDuration", 10000);
and this is the snippet I use to load a Url
driver.navigate().to("http://kmmc.in/wp-content/uploads/2014/01/lesson2.pdf");
autoGrantPermission also doesnt work in this case because chrome is already installed. Appium team has already rejected this issue -
https://github.com/appium/appium/issues/10008
Please help!
Indeed I had very hard time finding out the solution, but eventually I found a workaround.
The best workaround would have been reinstalling the chrome package. I tried that, but I could not start chrome after reinstalling it, as I had no access to shell, and chromedriver complained. So I left that track.
I tried getting hold of adb command or mobile:changePermissions but for that you need to use server flag --relaxed-security while starting the server, and saucelabs doesnt provide any handy interface to start the server with this flag.
The last resort, I found a solution here - https://stackoverflow.com/a/51241899/4675277 . But just that was not sufficient, because it helped me fix chrome alert, but later on it popped up with another alert with allow and deny, for which another solution in the same question helped me. So this is the code I eventually used -
driver.navigate().to("http://kmmc.in/wp-content/uploads/2014/01/lesson2.pdf");
String webContext = ((AndroidDriver)driver).getContext();
Set<String> contexts = ((AndroidDriver)driver).getContextHandles();
for (String context: contexts){
if (context.contains("NATIVE_APP")){
((AndroidDriver)driver).context(context);
break;
}
}
driver.findElement(By.id("android:id/button1")).click();
contexts = ((AndroidDriver)driver).getContextHandles();
for (String context: contexts){
if (context.contains("NATIVE_APP")){
((AndroidDriver)driver).context(context);
break;
}
}
driver.findElement(By.id("com.android.packageinstaller:id/permission_allow_button")).click();
((AndroidDriver)driver).context(webContext);
This helps allow all permissions required.

Setting sensors (location) in headless Chrome

Is it possible to set custom location coordinates with Chrome Headless? I can't find it in the
Devtools protocol
API. Is there a workaround available?
I googled it and got many methods. I try one by one, almost all of them turn out outdated. Then I find out a solution, use chrome devtools protocol to achieve that.
The small example code below, that it uses the most common tool selenium to execute chrome devtools protocol command.
import time
from selenium.webdriver import Chrome, ChromeOptions
options = ChromeOptions()
options.add_argument("--headless")
driver = Chrome(options=options)
driver.execute_cdp_cmd(
"Browser.grantPermissions",
{
"origin": "https://www.openstreetmap.org/",
"permissions": ["geolocation"]
},
)
driver.execute_cdp_cmd(
"Emulation.setGeolocationOverride",
{
"latitude": 35.689487,
"longitude": 139.691706,
"accuracy": 100,
},
)
driver.get("https://www.openstreetmap.org/")
driver.find_element_by_xpath("//span[#class='icon geolocate']").click()
time.sleep(3) # wait for the page full loaded
driver.get_screenshot_as_file("screenshot.png")
https://chromedevtools.github.io/devtools-protocol/tot/Emulation#method-setGeolocationOverride
and
https://chromedevtools.github.io/devtools-protocol/tot/Emulation#method-clearGeolocationOverride
... then you'll need to contend with ensuring that the correct location sharing setting is set within the user profile (chrome://settings/content/location - which is difficult to access due to being displayed via shadow dom, so using a preconfigured user profile will likely be easier --user-data-dir).
Edit to add: The above does not seem to be effective when using --headless. To resolve this I used https://chromedevtools.github.io/devtools-protocol/tot/Page#method-addScriptToEvaluateOnNewDocument with the following snippet:
navigator.geolocation.getCurrentPosition = function(success, failure) {
success({
coords: {latitude: <your_lat_float>, longitude: <your_lng_float>},
timestamp: Date.now(),
});
}

Create Chrome profiles without launching Chrome?

This has its use in automating creation of new Chrome Profiles. I am using windows and this tends to work except that it launches Chrome.
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe --profile-directory="Profile 1"
I am just wondering if there is a way to do this so that I can create profiles faster as it uses a lot of CPU this way. Firefox creates profiles without launching them.
These profiles will be later used in Selenium
Thanks
You should use NodeJS and chrome headless to automate this. Please look at the below url
https://developers.google.com/web/updates/2017/04/headless-chrome
const chromeLauncher = require('chrome-launcher');
function createChromeProfile(profileName) {
return chromeLauncher.launch({
// port: 9222, // Uncomment to force a specific port of your choice.
chromeFlags: [
'--profile-directory="' + profileName + '"',
'--window-size=412,732',
'--disable-gpu',
'--headless'
]
});
}
createChromeProfile("Profile 1").then(chrome => {
console.log(`Chrome debuggable on port: ${chrome.port}`);
...
chrome.kill();
});

Chrome and Mocha Global Leaks

I have the following extremely simple Mocha / Chai test:
describe('main tests', function () {
var expect = chai.expect, something = null;
before(function () {
something = 0;
});
it('should equal 0', function () {
expect(something).to.equal(0);
});
});
This fails in chrome with the following output:
Error: global leaks detected: css, cssFile, cssRule
In both Firefox and Safari, it passes with no problem.
There was another global variable defined by Google's own Screen Capture extension. Upon disabling that extension Mocha only complained about css, cssFile, and cssRule being global leaks.
I checked and these variables are not defined in Safari or Firefox, so obviously something in Chrome or one of my Chrome extensions is defining these three variables. Is there any way to figure out which extension is defining these variables short of disabling and reenabling all of them in sequence?
The best solution for your problem is not some JavaScript snippet, but the source code of your installed extensions.
Visit the Extensions sub-directory of your Chrome profile (locations below).
Use a tool to recursively search for the term.
For example, using the grep command: grep -r 'cssFile' (available for Linux, Mac and even Windows).
Default locations for your profile's Chrome extensions
Windows XP:
Chrome : %AppData%\..\Local Settings\Application Data\Google\Chrome\User Data\Default\Extensions\
Chromium: %AppData%\..\Local Settings\Application Data\Chromium\User Data\Default\Extensions\
Windows Vista/7/8:
Chrome : %LocalAppData%\Google\Chrome\User Data\Default\Extensions\
Chromium: %LocalAppData%\Chromium\User Data\Default\Extensions\
Linux:
Chrome : ~/.config/google-chrome/Default/Extensions/
Chromium: ~/.config/chromium/Default/Extensions/
Mac OS X:
Chrome : ~/Library/Application Support/Google/Chrome/Default/Extensions/
Chromium: ~/Library/Application Support/Chromium/Default/Extensions/
Well, I just did the disable all extensions thing. Chrome Sniffer appears to be the culprit. Specifically in the following code (detector.js):
for (t in cssClasses) {
// snipped for brevity
for(css in cssClasses[t]) {
// snipped for brevity
for(cssFile in document.styleSheets) {
for(cssRule in document.styleSheets[cssFile].cssRules) {
// snipped for brevity
}
}
}
}
That will leak t, css, cssFile, and cssRule into global scope. Looks like I'm not the first to notice this: https://github.com/nqbao/chromesniffer/pull/51
If anybody wants to answer with how I could have avoided the manual process I will accept your answer.