Skip to content

Commit

Permalink
Disable parallelism when running tests on safari browser (#3565)
Browse files Browse the repository at this point in the history
  • Loading branch information
prudhvi22 committed Mar 1, 2023
1 parent 7174a87 commit 80e30c6
Show file tree
Hide file tree
Showing 7 changed files with 125 additions and 10 deletions.
4 changes: 2 additions & 2 deletions lib/core/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Factory = require('../transport/factory.js');
const {isAndroid, isIos} = require('../utils/mobile');

const {LocateStrategy, Locator} = Element;
const {Logger, isUndefined, isDefined, isObject, isFunction} = Utils;
const {Logger, isUndefined, isDefined, isObject, isFunction, isSafari} = Utils;

class NightwatchAPI {
get WEBDRIVER_ELEMENT_ID() {
Expand Down Expand Up @@ -93,7 +93,7 @@ class NightwatchAPI {
}

isSafari() {
return this.__isBrowserName(Browser.SAFARI);
return isSafari(this.desiredCapabilities);
}

isChrome() {
Expand Down
19 changes: 16 additions & 3 deletions lib/runner/cli/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const Utils = require('../../utils');
const Runner = require('../runner.js');
const ProcessListener = require('../process-listener.js');
const analyticsCollector = require('../../utils/analytics.js');
const {Logger, singleSourceFile} = Utils;
const {Logger, singleSourceFile, isSafari, isLocalhost} = Utils;
const {RealIosDeviceIdError, iosRealDeviceUDID, isRealIos, isMobile, killSimulator} = require('../../utils/mobile.js');

class CliRunner {
Expand Down Expand Up @@ -390,14 +390,27 @@ class CliRunner {
}

for (const env of this.testEnvArray) {
if (isMobile(this.testEnvSettings[env].desiredCapabilities)) {
const {webdriver = {}} = this.testEnvSettings[env];
const desiredCapabilities = this.testEnvSettings[env].capabilities || this.testEnvSettings[env].desiredCapabilities;

if (isMobile(desiredCapabilities)) {

if (Concurrency.isChildProcess()) {
Logger.info('Disabling parallelism while running tests on mobile platform');
}

return false;
}

if (isSafari(desiredCapabilities) && isLocalhost(webdriver)) {
this.isSafariEnvPresent = true;
if (Concurrency.isMasterProcess()) {
// eslint-disable-next-line no-console
console.warn('Running tests in parallel is not supported in Safari. Tests will run in serial mode.');
}

return false;
}
}


Expand Down Expand Up @@ -496,7 +509,7 @@ class CliRunner {

return promise.then(() => {
if (this.isConcurrencyEnabled()) {
return this.testRunner.runConcurrent(this.testEnvArray, modules, this.isTestWorkersEnabled())
return this.testRunner.runConcurrent(this.testEnvArray, modules, this.isTestWorkersEnabled(), this.isSafariEnvPresent)
.then(exitCode => {
if (exitCode > 0) {
this.processListener.setExitCode(exitCode);
Expand Down
9 changes: 7 additions & 2 deletions lib/runner/concurrency/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ const lodashClone = require('lodash.clone');
const {Logger} = Utils;

class Concurrency extends EventEmitter {
constructor(settings = {}, argv = {}, isTestWorkerEnabled) {
constructor(settings = {}, argv = {}, isTestWorkerEnabled, isSafariEnvPresent = false) {
super();

this.argv = argv;
this.settings = lodashClone(settings, true);
this.childProcessOutput = {};
this.globalExitCode = 0;
this.testWorkersEnabled = typeof isTestWorkerEnabled !== undefined ? isTestWorkerEnabled : settings.testWorkersEnabled;
this.isSafariEnvPresent = isSafariEnvPresent;
}

static getChildProcessArgs(envs) {
Expand Down Expand Up @@ -91,7 +92,11 @@ class Concurrency extends EventEmitter {
*/
runTestEnvironments(envs, args, availColors) {
return Promise.all(envs.map((environment, index) => {
let childProcess = this.createChildProcess(environment, args, ['--env', environment], index);
const extraArgs = ['--env', environment];
if (this.isSafariEnvPresent) {
extraArgs.push('--serial');
}
let childProcess = this.createChildProcess(environment, args, extraArgs, index);

return this.runChildProcess(childProcess, environment + ' environment', availColors, 'envs');
}));
Expand Down
4 changes: 2 additions & 2 deletions lib/runner/test-runners/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,8 @@ class DefaultRunner {
* @param {Array} modules
* @return {Promise<number>}
*/
async runConcurrent(testEnvArray, modules, isTestWorkerEnabled) {
this.concurrency = new Concurrency(this.settings, this.argv, isTestWorkerEnabled);
async runConcurrent(testEnvArray, modules, isTestWorkerEnabled, isSafariEnvPresent) {
this.concurrency = new Concurrency(this.settings, this.argv, isTestWorkerEnabled, isSafariEnvPresent);
this.globalReporter.setupChildProcessListener(this.concurrency);

const exitCode = await this.concurrency.runMultiple(testEnvArray, modules);
Expand Down
18 changes: 17 additions & 1 deletion lib/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const fs = require('fs');
const mkpath = require('mkpath');
const glob = require('glob');
const lodashMerge = require('lodash.merge');
const {By} = require('selenium-webdriver');
const {By, Capabilities} = require('selenium-webdriver');

const Logger = require('./logger');
const BrowserName = require('./browsername.js');
Expand Down Expand Up @@ -605,6 +605,22 @@ class Utils {
throw err;
}
}

static isSafari(desiredCapabilities = {}) {
const browserName = desiredCapabilities.browserName || (desiredCapabilities instanceof Capabilities && desiredCapabilities.getBrowserName());

if (browserName && browserName.toLowerCase() === 'safari') {
return true;
}

return false;
}

static isLocalhost(webdriver = {}) {
const {host} = webdriver;

return ['127.0.0.1', 'localhost'].indexOf(host) > -1;
}
}

lodashMerge(Utils, {
Expand Down
41 changes: 41 additions & 0 deletions test/extra/withsafari-concurrent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"src_folders" : ["../sampletests"],
"output_folder" : "./output",
"custom_commands_path" : "",
"custom_assertions_path" : "",
"globals_path" : "./globals.js",
"test_workers" : {
"enabled" : true
},

"output" : false,

"test_settings": {
"default" : {
"desiredCapabilities" : {
"browserName" : "safari"
},
"webdriver": {
"start_process": true
}
},
"chrome" : {
"desiredCapabilities" : {
"browserName" : "chrome"
},
"webdriver": {
"start_process": true
}
},
"firefox" : {
"desiredCapabilities" : {
"browserName" : "firefox"
},
"webdriver": {
"start_process": true
}
}
}
}


40 changes: 40 additions & 0 deletions test/src/runner/cli/testCliRunnerParallel.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,46 @@ describe('Test CLI Runner in Parallel', function () {
assert.strictEqual(runner.parallelMode(), false);
});

it('disable parallelism when running tests on safari', function() {
class RunnerBaseMock extends RunnerBase {
static readTestSource(settings, argv) {
assert.strictEqual(settings.testWorkersEnabled, true);

return [
'test_file_1.js',
'test_file_2.js'
];
}
}
mockery.registerMock('../runner.js', RunnerBaseMock);
const runner = NightwatchClient.CliRunner({
config: path.join(__dirname, '../../../extra/withsafari-concurrent.json'),
env: 'default'
}).setup();
assert.strictEqual(runner.isTestWorkersEnabled(), false);
assert.strictEqual(runner.parallelMode(), false);
});

it('disable parallelism when running tests on safari with --env chrome,safari', function() {
class RunnerBaseMock extends RunnerBase {
static readTestSource(settings, argv) {
assert.strictEqual(settings.testWorkersEnabled, true);

return [
'test_file_1.js',
'test_file_2.js'
];
}
}
mockery.registerMock('../runner.js', RunnerBaseMock);
const runner = NightwatchClient.CliRunner({
config: path.join(__dirname, '../../../extra/withsafari-concurrent.json'),
env: ['default', 'chrome']
}).setup();
assert.strictEqual(runner.isTestWorkersEnabled(), false);
assert.strictEqual(runner.parallelMode(), false);
});

it('mobile config setup on with multiple envs - enable parallelism ', function() {
class RunnerBaseMock extends RunnerBase {
static readTestSource(settings, argv) {
Expand Down

0 comments on commit 80e30c6

Please sign in to comment.