From c8fe5696c87b8166c802945c3f2dec6ee67b5cee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wojciech=20Tyczy=C5=84ski?= Date: Wed, 23 Mar 2022 23:52:11 +0100 Subject: [PATCH] feat: Customize WebDriver config in custom launcher (#35) Example of custom launcher with this PR: module.exports = function(config) { const firefoxOptions = { 'moz:firefoxOptions': { prefs: { 'media.eme.enabled': true, 'media.gmp-manager.updateEnabled': true, }, }, }; config.set({ customLaunchers: { 'FirefoxEME': { base: 'Firefox', config: firefoxOptions, }, 'FirefoxHeadlessEME': { base: 'FirefoxHeadless', config: firefoxOptions, }, }, }); }; --- README.md | 30 ++++++++++++++++++++++++++++-- index.js | 29 +++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 25d282b..195f53a 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ advanced tests to be executed in-browser. If you don't need WebDriver to enable some test scenario in Karma, you can just use typical local browser launchers. -Supports Chrome, Firefox, and Safari. +Supports Chrome, Firefox, Edge, and Safari. ## Installation @@ -36,7 +36,8 @@ already installed. // karma.conf.js module.exports = (config) => { config.set({ - browsers: ['Chrome', 'Firefox', 'Safari'] + plugins: ['karma-local-wd-launcher'], + browsers: ['Chrome', 'Firefox', 'Edge', 'Safari'], }); }; ``` @@ -46,3 +47,28 @@ You can give Karma's command-line interface a list of browsers, too: ```sh karma start --browsers Chrome Firefox Safari ``` + +There is a possibilty to create custom launcher based on existing ones, i.e. to +pass additional configuration options to specific WebDriver. + +```js +// karma.conf.js +module.exports = (config) => { + config.set({ + customLaunchers: { + 'ChromeNoBackgroundSuspend': { + base: 'Chrome', + config: { + 'goog:chromeOptions': { + args: [ + '--disable-background-media-suspend', + '--disable-background-timer-throttling', + '--disable-backgrounding-occluded-windows', + ], + }, + }, + }, + }, + }); +}; +``` diff --git a/index.js b/index.js index abcabf7..547a435 100644 --- a/index.js +++ b/index.js @@ -19,6 +19,7 @@ const fs = require('fs'); const os = require('os'); const path = require('path'); const wd = require('wd'); +const _ = require('lodash'); const {installWebDrivers} = require('webdriver-installer'); @@ -39,7 +40,7 @@ const PLATFORM_MAP = { // - LAUNCHER_NAME: launcher name as presented to Karma // - EXTRA_WEBDRIVER_SPECS: an object containing any extra WebDriver specs // - getDriverArgs(port): take port as string, return driver command arguments -const LocalWebDriverBase = function(baseBrowserDecorator, logger) { +const LocalWebDriverBase = function(baseBrowserDecorator, args, logger) { baseBrowserDecorator(this); this.name = `${this.constructor.LAUNCHER_NAME} via WebDriver`; @@ -61,6 +62,10 @@ const LocalWebDriverBase = function(baseBrowserDecorator, logger) { log.debug('config:', JSON.stringify(config)); + const extraSpecs = + _.merge(this.constructor.EXTRA_WEBDRIVER_SPECS, args.config); + log.debug('extraSpecs:', extraSpecs); + // These names ("browser" and "spec") are needed for compatibility with // karma-webdriver-launcher. this.browser = wd.remote(config); @@ -70,7 +75,7 @@ const LocalWebDriverBase = function(baseBrowserDecorator, logger) { // This is necessary for safaridriver: allowW3C: true, // This allows extra configuration for headless variants: - ...this.constructor.EXTRA_WEBDRIVER_SPECS, + ...extraSpecs, }; this.browser.on('status', (info) => { @@ -192,8 +197,8 @@ function generateSubclass( // Karma will not use "new" to construct our class, so it can't be a true ES6 // class. Use the old function syntax instead. - const subclass = function(baseBrowserDecorator, logger) { - LocalWebDriverBase.call(this, baseBrowserDecorator, logger); + const subclass = function(baseBrowserDecorator, args, logger) { + LocalWebDriverBase.call(this, baseBrowserDecorator, args, logger); }; // These are needed by our base class, LocalWebDriverBase. @@ -215,7 +220,7 @@ function generateSubclass( }; // This configures Karma's dependency injection system: - subclass.$inject = ['baseBrowserDecorator', 'logger']; + subclass.$inject = ['baseBrowserDecorator', 'args', 'logger']; return subclass; } @@ -274,7 +279,15 @@ const LocalWebDriverEdgeHeadless = generateSubclass( const LocalWebDriverFirefox = generateSubclass( 'Firefox', 'Firefox', 'geckodriver', - (port) => ['-p', port]); + (port) => ['-p', port], + { + 'moz:firefoxOptions': { + prefs: { + 'media.eme.enabled': true, + 'media.gmp-manager.updateEnabled': true, + }, + }, + }); const LocalWebDriverFirefoxHeadless = generateSubclass( 'Firefox', 'FirefoxHeadless', @@ -282,6 +295,10 @@ const LocalWebDriverFirefoxHeadless = generateSubclass( (port) => ['-p', port], { 'moz:firefoxOptions': { + prefs: { + 'media.eme.enabled': true, + 'media.gmp-manager.updateEnabled': true, + }, args: [ '-headless', ],