UNPKG

codeceptjs

Version:

Modern Era Acceptance Testing Framework for NodeJS

234 lines (209 loc) 6.74 kB
const container = require('../container'); const mainConfig = require('../config'); const recorder = require('../recorder'); const event = require('../event'); const output = require('../output'); const debug = require('debug')('codeceptjs:plugin:wdio'); const defaultConfig = { services: [], capabilities: {}, }; let restartsSession; /** * Webdriverio services runner. * * This plugin allows to run webdriverio services like: * * * selenium-standalone * * sauce * * testingbot * * browserstack * * appium * * A complete list of all available services can be found on [webdriverio website](https://webdriver.io). * * ###### Setup * * 1. Install a webdriverio service * 2. Enable `wdio` plugin in config * 3. Add service name to `services` array inside wdio plugin config. * * See examples below: * * ###### Selenium Standalone Service * * Install ` @wdio/selenium-standalone-service` package, as [described here](https://webdriver.io/docs/selenium-standalone-service.html). * It is important to make sure it is compatible with current webdriverio version. * * Enable `wdio` plugin in plugins list and add `selenium-standalone` service: * * ```js * plugins: { * wdio: { * enabled: true, * services: ['selenium-standalone'] * // additional config for service can be passed here * } * } * ``` * * Please note, this service can be used with Protractor helper as well! * * ##### Sauce Service * * Install `@wdio/sauce-service` package, as [described here](https://webdriver.io/docs/sauce-service.html). * It is important to make sure it is compatible with current webdriverio version. * * Enable `wdio` plugin in plugins list and add `sauce` service: * * ```js * plugins: { * wdio: { * enabled: true, * services: ['sauce'], * user: ... ,// saucelabs username * key: ... // saucelabs api key * // additional config, from sauce service * } * } * ``` * * --- * * In the same manner additional services from webdriverio can be installed, enabled, and configured. * * #### Configuration * * * `services` - list of enabled services * * ... - additional configuration passed into services. * */ module.exports = (config) => { const webDriver = container.helpers('WebDriver'); if (webDriver) { config = Object.assign(webDriver.options, config); restartsSession = !!config.restart; } config = Object.assign(defaultConfig, config); const services = []; const launchers = []; for (const name of config.services) { // webdriverio v5 style const Service = safeRequire(`@wdio/${name.toLowerCase()}-service`); if (Service) { if (Service.launcher && typeof Service.launcher === 'function') { const Launcher = Service.launcher; launchers.push(new Launcher(config)); } if (typeof Service === 'function') { services.push(new Service(config, config.capabilities)); } continue; } throw new Error(`Couldn't initialize service ${name} from wdio plugin config.\nIt should be available either in '@wdio/${name.toLowerCase()}-service' package`); } debug(`services ${services}, launchers ${launchers}`); recorder.startUnlessRunning(); for (const launcher of launchers) { registerLauncher(launcher); } for (const service of services) { registerService(service); } function registerService(service) { const name = service.constructor.name; if (service.beforeSession) { event.dispatcher.on(event.all.before, () => { recorder.add(`service ${name} all.before`, async () => { await service.beforeSession(config, config.capabilities); }); }); } if (service.afterSession) { event.dispatcher.on(event.all.result, (result) => { recorder.add(`service ${name} all.after`, async () => { await service.afterSession(result); }); }); } if (service.beforeSuite) { event.dispatcher.on(event.suite.before, (suite) => { debug(`suite started: ${suite.title}`); recorder.add(`service ${name} suite.before`, () => service.beforeSuite(suite)); }); } if (service.afterSuite) { event.dispatcher.on(event.suite.after, (suite) => { debug(`suite finished: ${suite.title}`); recorder.add(`service ${name} suite.after`, () => service.afterSuite(suite)); }); } if (service.beforeTest) { event.dispatcher.on(event.test.started, async (test) => { if (test.parent) { test.parent.toString = () => test.parent.title; } // test.parent = test.parent ? test.parent.title : null; debug(`test started: ${test.title}`); if (webDriver) { global.browser = webDriver.browser; global.browser.config = Object.assign(mainConfig.get(), global.browser.config); } await service.beforeTest(test); }); } if (service.afterTest) { event.dispatcher.on(event.test.finished, async (test) => { debug(`test finished: ${test.title}`); await service.afterTest(test); }); } if (restartsSession && service.before) { event.dispatcher.on(event.test.started, test => service.before()); } if (restartsSession && service.after) { event.dispatcher.on(event.test.finished, test => service.after()); } if (!restartsSession && service.before) { let initializedBrowser = false; event.dispatcher.on(event.test.started, async (test) => { if (!initializedBrowser) { await service.before(); initializedBrowser = true; } }); } if (!restartsSession && service.after) { event.dispatcher.on(event.all.result, result => service.after(result)); } } function registerLauncher(launcher) { const name = launcher.constructor.name; if (launcher.onPrepare) { event.dispatcher.on(event.all.before, () => { recorder.add(`launcher ${name} start`, async () => { await launcher.onPrepare(config, config.capabilities); output.debug(`Started ${name}`); }); }); } if (launcher.onComplete) { event.dispatcher.on(event.all.after, () => { recorder.add(`launcher ${name} start`, async () => { await launcher.onComplete(process.exitCode, config, config.capabilities); output.debug(`Stopped ${name}`); }); }); } } }; function safeRequire(name) { try { return require(name); } catch (e) { if (!e.message.match(`Cannot find module '${name}'`)) { throw new Error(`Couldn't initialise "${name}".\n${e.stack}`); } return null; } }