nightwatch
Version:
Easy to use Node.js based end-to-end testing solution for web applications using the W3C WebDriver API.
277 lines (276 loc) • 10.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const { Capabilities, Browser } = require('selenium-webdriver');
const Utils = require('../../utils');
module.exports = class SeleniumCapabilities {
get initialCapabilities() {
return this.__capabilities;
}
get isChrome() {
return this.initialCapabilities.getBrowserName() === Browser.CHROME;
}
get isSafari() {
return this.initialCapabilities.getBrowserName() === Browser.SAFARI;
}
get isEdge() {
return this.initialCapabilities.getBrowserName() === Browser.EDGE;
}
get isFirefox() {
return this.initialCapabilities.getBrowserName() === Browser.FIREFOX;
}
constructor({ settings, browserName }) {
this.settings = settings;
this.createDesired();
this.__capabilities = this.createInitialCapabilities();
if (browserName) {
this.initialCapabilities.setBrowserName(browserName);
}
}
createDesired() {
this.desiredCapabilities = this.settings.capabilities || this.settings.desiredCapabilities;
if (typeof this.desiredCapabilities == 'function') {
this.desiredCapabilities = this.desiredCapabilities.call(this.settings);
}
return this.desiredCapabilities;
}
/**
* Create an initial capabilities instance based on either the capabilities or desiredCapabilities
* setting from the nightwatch config
*
* @returns {Capabilities}
*/
createInitialCapabilities() {
if (this.desiredCapabilities instanceof Capabilities) {
return this.desiredCapabilities;
}
return new Capabilities(this.desiredCapabilities);
}
alreadyDefinedAs(OptionsClass) {
return this.desiredCapabilities instanceof OptionsClass;
}
create(argv = {}) {
this.argv = argv;
let options;
switch (this.initialCapabilities.getBrowserName()) {
case Browser.CHROME:
options = this.createChromeOptions();
break;
case Browser.FIREFOX:
options = this.createFirefoxOptions();
break;
case Browser.SAFARI:
options = this.createSafariOptions();
break;
case Browser.EDGE:
options = this.createEdgeOptions();
break;
case Browser.OPERA:
// TODO: implement
break;
case Browser.INTERNET_EXPLORER:
options = this.createIeOptions();
break;
}
this
.updateWebdriverPath()
.addHeadlessOption({ options })
.addDevtoolsOption({ options })
.addWindowSizeOption({ options })
.addProxyOption({ options });
return options;
}
/**
* @return {chrome.Options}
*/
createChromeOptions() {
const { Options: ChromeOptions } = require('selenium-webdriver/chrome');
if (this.alreadyDefinedAs(ChromeOptions)) {
return this.desiredCapabilities;
}
// Backward compatibility for 'chromeOptions'
if (Utils.isObject(this.desiredCapabilities.chromeOptions)) {
this.desiredCapabilities['goog:chromeOptions'] = Object.assign(this.desiredCapabilities.chromeOptions, this.desiredCapabilities['goog:chromeOptions']);
}
const { webdriver } = this.settings;
let options = new ChromeOptions(this.desiredCapabilities);
if (webdriver.chrome_binary || this.settings.chrome_binary) {
options.setChromeBinaryPath(webdriver.chrome_binary || this.settings.chrome_binary);
}
if (webdriver.chrome_log_file || this.settings.chrome_log_file) {
options.setChromeLogFile(webdriver.chrome_log_file || this.settings.chrome_log_file);
}
if (webdriver.android_chrome) {
options.androidChrome();
}
return options;
}
createIeOptions() {
const { Options: IeOptions } = require('selenium-webdriver/ie');
if (this.alreadyDefinedAs(IeOptions)) {
return this.desiredCapabilities;
}
const { webdriver } = this.settings;
let options = new IeOptions(this.desiredCapabilities);
if (webdriver.log_path || this.settings.log_path) {
options.setLogFile(webdriver.log_path || this.settings.log_path);
}
if (webdriver.host || this.settings.host) {
options.setHost(webdriver.host || this.settings.host);
}
return options;
}
createEdgeOptions() {
const { Options: EdgeOptions } = require('selenium-webdriver/edge');
if (this.alreadyDefinedAs(EdgeOptions)) {
return this.desiredCapabilities;
}
const { webdriver } = this.settings;
let options = new EdgeOptions(this.desiredCapabilities);
if (webdriver.edge_binary || this.settings.edge_binary) {
options.setEdgeChromiumBinaryPath(webdriver.edge_binary || this.settings.edge_binary);
}
if (webdriver.edge_log_file || this.settings.edge_log_file) {
options.setBrowserLogFile(webdriver.edge_log_file || this.settings.edge_log_file);
}
if (webdriver.android_package) {
options.androidPackage(webdriver.android_package);
}
return options;
}
/**
* @return {firefox.Options}
*/
createFirefoxOptions() {
const { Options: FirefoxOptions } = require('selenium-webdriver/firefox');
if (this.alreadyDefinedAs(FirefoxOptions)) {
return this.desiredCapabilities;
}
const { webdriver } = this.settings;
let options = new FirefoxOptions(this.desiredCapabilities);
if (webdriver.firefox_binary || this.settings.firefox_binary) {
options.setBinary(webdriver.firefox_binary || this.settings.firefox_binary);
}
if (webdriver.firefox_profile || this.settings.firefox_profile) {
options.setProfile(webdriver.firefox_profile || this.settings.firefox_profile);
}
return options;
}
createSafariOptions() {
const { Options: SafariOptions } = require('selenium-webdriver/safari');
if (this.alreadyDefinedAs(SafariOptions)) {
return this.desiredCapabilities;
}
let options = new SafariOptions(this.desiredCapabilities);
return options;
}
usingSeleniumServer() {
return this.settings.selenium && this.settings.selenium.start_process;
}
shouldSetupWebdriver() {
return this.settings.webdriver.start_process && !this.settings.webdriver.server_path;
}
getChromedriverPath() {
try {
return require('chromedriver').path;
}
catch (err) {
return '';
}
}
getGeckodriverPath() {
try {
return require('geckodriver').path;
}
catch (err) {
return '';
}
}
getAppiumPath() {
return require.resolve('appium');
}
updateWebdriverPath() {
if (this.shouldSetupWebdriver()) {
try {
if (this.usingSeleniumServer()) {
if (this.settings.selenium.use_appium) {
this.settings.selenium.server_path = this.settings.webdriver.server_path = this.getAppiumPath();
return this;
}
this.settings.selenium.server_path = this.settings.webdriver.server_path = require('@nightwatch/selenium-server').path;
this.settings.selenium.cli_args = this.settings.selenium.cli_args || {};
const chromeDriver = this.getChromedriverPath();
if (chromeDriver) {
this.settings.selenium.cli_args['webdriver.chrome.driver'] = chromeDriver;
}
const geckoDriver = this.getGeckodriverPath();
if (geckoDriver) {
this.settings.selenium.cli_args['webdriver.gecko.driver'] = geckoDriver;
}
return this;
}
switch (this.initialCapabilities.getBrowserName()) {
case Browser.CHROME:
this.settings.webdriver.server_path = this.getChromedriverPath();
break;
case Browser.FIREFOX:
this.settings.webdriver.server_path = this.getGeckodriverPath();
break;
case Browser.SAFARI:
this.settings.webdriver.server_path = '/usr/bin/safaridriver';
break;
}
}
catch (err) {
this.settings.webdriver.server_path = '';
}
}
return this;
}
hasDevtoolsFlag(options) {
return this.argv.devtools && (options instanceof Capabilities);
}
addDevtoolsOption({ options }) {
if (!this.hasDevtoolsFlag(options)) {
return this;
}
if (this.isChrome) {
const { args = [] } = options.get('goog:chromeOptions');
const newArg = 'auto-open-devtools-for-tabs';
if (!(args.includes(newArg) || args.includes(`--${newArg}`))) {
options.addArguments(newArg);
}
}
else if (this.isSafari) {
options.map_.set('safari:automaticInspection', true);
}
else if (this.isEdge) {
const { args = [] } = options.get('ms:edgeOptions');
const newArg = 'auto-open-devtools-for-tabs';
if (!(args.includes(newArg) || args.includes(`--${newArg}`))) {
options.addArguments(newArg);
}
}
else if (this.isFirefox) {
// TODO: implement when available in Firefox
}
return this;
}
addHeadlessOption({ options }) {
if (this.argv.headless && (options instanceof Capabilities) && (this.isChrome || options.headless)) {
this.isChrome ? options.addArguments('headless=new') : options.headless();
}
return this;
}
addWindowSizeOption({ options }) {
if (this.settings.window_size && (options instanceof Capabilities) && options.windowSize) {
options.windowSize(this.settings.window_size);
}
return this;
}
addProxyOption({ options }) {
if (this.initialCapabilities.getProxy() && (options instanceof Capabilities) && options.setProxy) {
const proxy = require('selenium-webdriver/proxy');
options.setProxy(proxy.manual(this.initialCapabilities.getProxy()));
}
}
};