How do I get selenium to open my electron app? - selenium

I'm attempting to setup Selenium to test my electron app. So far I have the code from the Electron documentation, however, this only opens the HTML file, not my actual app. Here is my code:
import * as path from "path";
const webdriver = require('selenium-webdriver');
const driver = new webdriver.Builder()
// The "9515" is the port opened by ChromeDriver.
.usingServer('http://localhost:9515')
.withCapabilities({
'chromeOptions': {
// Here is the path to your Electron binary.
binary: '../../node_modules/electron/dist/electron.exe'
}
})
.forBrowser('chrome')
.build();
const current_path = path.join(__dirname, "../../dist/public/index.html");
driver.get('file://' + current_path);
How can I get it to open my app?
I've been trying to figure this out for several days, and all the other articles and stackoverflow posts either point to Spectron (which is now deprecated) or don't explain how to open my own app and not a different website.
EDIT: I figured out that adding "args": ['--app=PATH_TO_PROJECT_DIR')] in the chromeOptions object , and changing the name to "goog:chromeOptions", makes it open to the correct file path, however, now I get the following error:
WebDriverError: unknown error: no chrome binary at ../../node_modules/electron/dist/electron.exe
Changing back to "chromeOptions" stops it from opening the app directory, but does open a blank chrome window.

The solution was to:
Replace '../../node_modules/electron/dist/electron.exe' with path.join(__dirname, '../../node_modules/electron/dist/electron.exe')
To change chromeOptions to goog:chromeOptions
To add "args": [path.join(__dirname, '../../')] to the goog:chromeOptions object.
Working Code:
import * as path from "path";
const webdriver = require('selenium-webdriver');
const driver = new webdriver.Builder()
// The "9515" is the port opened by ChromeDriver.
.usingServer('http://localhost:9515')
.withCapabilities({
'goog:chromeOptions': {
// Here is the path to your Electron binary.
"binary": path.join(__dirname, '../../node_modules/electron/dist/electron.exe'),
"args": ['--app=' + path.join(__dirname, "../../")]
}
})
.forBrowser('chrome')
.build();

Related

Error: The specified executable path does not exist: /tmp/.mount_JobAppuO0ICL/resources/app.asar/dist/main/chromedriver/chromedriver

I am trying to use Selenium and Chrome WebDriver in Electron, which works fine in development. However, once I package the application and run it, I get the following error:
Error: The specified executable path does not exist: /tmp/.mount_JobAppuO0ICL/resources/app.asar/dist/main/chromedriver/chromedriver
Here's the code that starts the driver:
const service = new chrome.ServiceBuilder(path).build();
chrome.setDefaultService(service);
const options = new chrome.Options();
options.options_.debuggerAddress = "localhost:9222";
this.driver = await new Builder()
.withCapabilities({ unexpectedAlertBehaviour: "accept" })
.forBrowser("chrome")
.setChromeOptions(options)
.build();
Where path is from require("chromedriver").path.
I'm not using selenium and chrome driver to test Electron app. I'm using selenium and chrome driver for functionality inside Electron app.
Thank you

How to pack chromedriver.exe on Mac

I'm trying to use Selenium on Electron app and am using the following modules:
"chromedriver": "^78.0.1",
"selenium-webdriver": "^4.0.0-alpha.4",
"electron-builder": "^21.2.0",
I built my app on a Mac and Selenium is working fine. However, when I run Electron Selenium app on Widows it can't find chromedriver.
react-electron/node_modules/chromedriver is below.
Of course it doesn't have chromedriver.exe, so I put chromedriver.exe into chromedriver/bin. Then I built it again but the built app doesn't include chromedriver.exe. How can I pack chromedriver.exe into the built app?
I applicate your help.
I found the solution. I put chromedriver.exe into node_modules/chromedriver/lib/chromedriver.
I can check it was copied in
win-unpacked/resources/app.asar.unpacked/node_modules/chromedriver/lib/chromedriver/chromedriver.exe
When the app run, chromedriver can fined in C:\Users\user\AppData\Local\Programs\MyApp\resources\app.asar.unpacked\node_modules\chromedriver\lib\chromedriver\chromedriver.exe
I can get the driver path like this.
const chromedriver = require('chromedriver');
async getDriverPath() {
let driverPath:string = this.chromedriver.path;
driverPath = await driverPath.replace('app.asar','app.asar.unpacked');
log.info("this.driverPath " + driverPath);
return driverPath;
}
And also, I set driver path like this.
const webdriver = require('selenium-webdriver');
const {Builder} = webdriver;
let my_driver;
async startChrome() {
const driverPath = await this.getDriverPath();
const service = new chrome.ServiceBuilder(driverPath).build();
chrome.setDefaultService(service);
my_driver = new Builder().forBrowser('chrome').build();
}
I hope this will help someone.

Unable to install WebExtension with Selenium

I'm trying to test my firefox webextension but firefox refuses to install it because it doesn't have the install.rdf file. But that file is not used anymore by webextensions.
const firefox = require('selenium-webdriver/firefox');
const webdriver = require('selenium-webdriver');
require('geckodriver');
let profile = new firefox.Profile();
profile.addExtension(process.cwd() + '/build/firefox/');
profile.setPreference('extensions.firebug.showChromeErrors', true);
let options = new firefox.Options().setProfile(profile);
let _driver = new webdriver.Builder()
.forBrowser('firefox')
.setFirefoxOptions(options)
.build();
Error: ENOENT: no such file or directory, open '/dev/webext/build/firefox/install.rdf'
Is there a setting that I need to enable to tell it it's a webextension?
The WebExtension API is not yet supported by Selenium v3.4.0 . The method Profile::addExtension only works for a legacy addon where install.rdf is present at the root.
To test a web extension, you can either use a profile where the extension is already installed, or you can implement the custom command available with GeckoDriver since v0.17.0:
var webdriver = require('selenium-webdriver');
var Command = require('selenium-webdriver/lib/command').Command;
function installWebExt(driver, extension) {
let cmd = new Command('moz-install-web-ext')
.setParameter('path', path.resolve(extension))
.setParameter('temporary', true);
driver.getExecutor()
.defineCommand(cmd.getName(), 'POST', '/session/:sessionId/moz/addon/install');
return driver.schedule(cmd, 'installWebExt(' + extension + ')');
}
var driver = new webdriver.Builder()
.forBrowser('firefox')
.build();
installWebExt(driver, "C:\\temp\\extension.zip");
This is an issue with FirefoxDriver. This issue is already logged in both SeleniumHQ/selenium#4184 and
mozilla/geckodriver#759
GeckoDriver says that
A workaround for the time being would be to use the add-on endpoints
geckodriver 0.17.0 provides to get an extension installed from the
local disk.
https://github.com/mozilla/geckodriver/blob/release/src/marionette.rs#L66
So you have to use the geckodriver endpoints to do that. I have already mentioned on how to use the endpoints here

How to set the firefox profile at the node end in remote webdriver/grid configuration

It is always suggested to set the firefox profile in DesiredCapabilities and pass that through the wire ,where the hub is running . Like below
DesiredCapabilities caps = DesiredCapabilities.firefox();
FirefoxProfile profile=new FirefoxProfile(new File("Local Path to firefox profile folder"));
caps.setCapability(FirefoxDriver.PROFILE, profile);
URL url = new URL("http://localhost:4444/wd/hub");
WebDriver driver= new RemoteWebDriver(url,caps );
But sending the huge 87-90 mb profile info to hub over http ,for each selenium test case slowing down the test case execution .
I have tried configuring the grid node with "Dwebdriver.firefox.profile=E:\\Firefox_Profile_Location":"", property in json node config file like below.
{
"configuration":
{
.//Other Settings
.//Other Settings
.//Other Settings
"Dwebdriver.firefox.profile=E:\\Firefox_Profile_Location":"",
"maxSession":7,
"registerCycle":5000,
"register":true
},
"capabilities":
[
{"browserName":"firefox",
"seleniumProtocol":"WebDriver",
"maxInstances":5,
"platform":"VISTA"
}
]
}
But running with the above configuration is throwing below error .
WebDriverException: Firefox profile 'E:\Firefox_Profile_Location'
named in system property 'webdriver.firefox.profile' not found
Advanced thanks for any help on how to configure the firefox profile from the node side .
You need to provide the profile in the capabilities object as a base64 encoded zip:
var fs = require('fs');
capabilities: [
{
browserName: 'firefox',
seleniumProtocol: 'WebDriver',
maxInstances: 5,
platform: 'VISTA',
firefox_profile: new Buffer(fs.readFileSync("./profile.zip")).toString('base64')
}
]
Moreover Firefox creates the missing files for a given profile. So you should keep just the necessary files in the profile depending on your needs:
Preferences: user.js
Passwords: key3.db
logins.json
Cookies: cookies.sqlite
Certificate: cert8.sqlite
Extensions: extensions/
I think you'll have to use firefox profile name and not the location.
"webdriver.firefox.profile":"default"
Have a look at this and this and this
If you want know how to create a profile follow this and this

How to disable 'This type of file can harm your computer' pop up

I'm using selenium chromedriver for automating web application.
In my application, I need to download xml files. But when I download xml file, I get 'This type of file can harm your computer' pop up. I want to disable this pop up using selenium chromedriver and I want these type of files to be downloaded always. How can this be done?
Selenium version : 2.47.1
Chromedriver version : 2.19
UPDATE it's long standing Chrome bug from 2012.
The problem with XML files started to happen to me as of Chrome 47.0.2526.80 m.
After spending maybe 6 hours trying to turn off every possible security option I tried a different approach.
Ironically, it seems that turning on the Chrome option "Protect you and your device from dangerous sites" removes the message "This type of file can harm your computer. Do you want to keep file.xml anyway?"
I am using 'Ruby' with 'Watir-Webdriver' where the code looks like this:
prefs = {
'safebrowsing' => {
'enabled' => true,
}
}
b = Watir::Browser.new :chrome, :prefs => prefs
Starting the browser like this, with safebrowsing option enabled, downloads the xml files without the message warning. The principle should be the same for Selenium with any programming language.
#####
Edited: 13-04-2017
In latest version of Google Chrome the above solution is not enough. Additionally, it is necessary to start the browser with the following switch:
--safebrowsing-disable-download-protection
Now, the code for starting the browser would look something like this:
b = Watir::Browser.new :chrome, :prefs => prefs, :switches => %w[--safebrowsing-disable-download-protection]))
I am posting below the complete code that got file download working for me:
Hope it helps :-) I am using Java-Selenium
System.setProperty("webdriver.chrome.driver", "C:/chromedriver/chromedriver.exe");
String downloadFilepath = "D:/MyDeskDownload";
HashMap<String, Object> chromePrefs = new HashMap<String, Object>();
chromePrefs.put("profile.default_content_settings.popups", 0);
chromePrefs.put("download.default_directory", downloadFilepath);
chromePrefs.put("safebrowsing.enabled", "true");
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("prefs", chromePrefs);
DesiredCapabilities cap = DesiredCapabilities.chrome();
cap.setCapability(CapabilityType.ACCEPT_SSL_CERTS, true);
cap.setCapability(ChromeOptions.CAPABILITY, options);
WebDriver driver = new ChromeDriver(cap);
Following Python code works for me
chromeOptions = webdriver.ChromeOptions()
prefs = {'safebrowsing.enabled': 'false'}
chromeOptions.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(chrome_options=chromeOptions)
The accepted answer stopped working after a recent update of Chrome. Now you need to use the --safebrowsing-disable-extension-blacklist and --safebrowsing-disable-download-protection command-line switches. This is the WebdriverIO config that works for me:
var driver = require('webdriverio');
var client = driver.remote({
desiredCapabilities: {
browserName: 'chrome',
chromeOptions: {
args: [
'disable-extensions',
'safebrowsing-disable-extension-blacklist',
'safebrowsing-disable-download-protection'
],
prefs: {
'safebrowsing.enabled': true
}
}
}
});
Note that I am also disabling extensions, because they generally interfere with automated testing, but this is not strictly needed to fix the problem with downloading XML and JavaScript files.
I found these switches by reading through this list. You can also see them in the Chromium source.
I came across this recently, using Katalon Studio, Chrome version 88.
Thankfully just the enabling safebrowsing did the trick. You access the settings via "Project Settings" and you navigate to "Desired Capabilities" -> "Web UI" -> "Chrome".
If you don't have a "prefs" setting add it and set the type to Dictionary. Then in the Value add a boolean named "safebrowsing.enabled" and set the value to "true".
Result might look like:
(And you can the default directory setting has nothing to do with this example).
I used all of suggested chrome options in C# and only when my internet connected worked for me but when internet disconnected none of them work for me.
(I'm not sure.may be chrome safebrowsing need to internet connection)
By using older version of chrome(version71) and chromedriver(version 2.46) and after downloading,i saw downloaded XML file name constains 'Unconfirmed' with 'crdownload' extension
and parsing XML file wouldn't work properly.
Finally, creating wait with Thread.Sleep(1000) solved my problem.
IWebDriver Driver;
//chromedriver.exe version2.46 path
string path = #"C:\cd71";
ChromeDriverService driverService = ChromeDriverService.CreateDefaultService(path, "chromedriver.exe");
ChromeOptions options = new ChromeOptions();
// options.AddArgument("headless");
options.AddArgument("--window-position=-32000,-32000");
options.AddUserProfilePreference("download.default_directory", #"c:\xmlFiles");
options.AddUserProfilePreference("download.prompt_for_download", false);
options.AddUserProfilePreference("disable-popup-blocking", "true");
options.AddUserProfilePreference("safebrowsing.enabled", "true");
Driver = new ChromeDriver(driverService, options);
try
{
Driver.Navigate().GoToUrl(url);
Thread.Sleep(1000);
//other works like: XML parse
}
catch
{
}
For context, I had a .csv with a list of .swf flash documents and their respective urls. Since the files could only be accessed after a valid login, I couldn't use a simple requests based solution.
Just like .xml, downloading a .swf triggers a similar prompt.
None of the answers worked for me.
So I stripped away all the extra arguments and settings the above answers proposed and just made the chrome instance headless.
options.add_argument("--headless")
prefs = {
"download.default_directory": "C:\LOL\Flash",
"download.prompt_for_download": False,
"download.directory_upgrade": True,
}
options.add_experimental_option("prefs",prefs)
The only workaround that works for me:
Use argument with path to chrome profile
chromeOptions.add_argument(chrome_profile_path)
Search for file download_file_types.pb in chrome profile folder.
In my case ..chromedriver\my_profile\FileTypePolicies\36\download_file_types.pb
Backup this file and then open with any hexeditor (you can use oline).
Search for the filetype you want to download, i.e. xml and change it to anything i.e. xxx
Im using Google Version 80.0.3987.122 (Official Build) (32-bit) and ChromeDriver 80.0.3987.106. Getting the same error even after adding the below while downloading a .xml file.
$ChromeOptions = New-Object OpenQA.Selenium.Chrome.ChromeOptions
$ChromeOptions.AddArguments(#(
"--disable-extensions",
"--ignore-certificate-errors"))
$download = "C:\temp\download"
$ChromeOptions.AddUserProfilePreference("safebrowsing.enabled", "true");
$ChromeOptions.AddUserProfilePreference("download.default_directory", $download);
$ChromeOptions.AddUserProfilePreference("download.prompt_for_download", "false");
$ChromeOptions.AddUserProfilePreference("download.directory_upgrade", "true");
$ChromeDriver = New-Object OpenQA.Selenium.Chrome.ChromeDriver($chromeOptions)