UNPKG

webdriverio-automation

Version:

WebdriverIO-Automation android ios project

151 lines (126 loc) 5.27 kB
/* eslint-disable require-await */ import _ from 'lodash'; import log from '../logger'; import { errors } from '../../protocol'; import UUID from 'uuid-js'; import { processCapabilities } from '../capabilities'; let commands = {}; commands.createSession = async function createSession (jsonwpDesiredCapabilities, jsonwpRequiredCaps, w3cCapabilities) { if (this.sessionId !== null) { throw new errors.SessionNotCreatedError('Cannot create a new session ' + 'while one is in progress'); } log.debug(); // Determine weather we should use jsonwpDesiredCapabilities or w3cCapabilities to get caps from let caps; if (w3cCapabilities) { this.setProtocolW3C(); if (jsonwpDesiredCapabilities) { log.debug(`W3C capabilities and MJSONWP desired capabilities were provided`); } if (jsonwpDesiredCapabilities && !_.isPlainObject(w3cCapabilities)) { // If W3C Capabilities and MJSONWP Capabilities were provided and W3C caps aren't a plain object, // log a warning and fall back to MJSONWP if (!_.isEmpty(w3cCapabilities)) { log.warn(`Expected W3C "capabilities" to be a JSON Object but was provided with: ${JSON.stringify(w3cCapabilities)}`); } log.warn(`Falling back to MJSONWP desired capabilities`); this.setProtocolMJSONWP(); caps = jsonwpDesiredCapabilities; } else { log.debug(`Creating session with W3C capabilities: ${JSON.stringify(w3cCapabilities, null, 2)}`); caps = processCapabilities(w3cCapabilities, this.desiredCapConstraints, this.shouldValidateCaps); } } else { this.setProtocolMJSONWP(); log.debug(`Creating session with MJSONWP desired capabilities: ${JSON.stringify(jsonwpDesiredCapabilities, null, 2)}`); caps = jsonwpDesiredCapabilities || {}; } caps = fixCaps(caps, this.desiredCapConstraints); this.validateDesiredCaps(caps); this.sessionId = UUID.create().hex; this.caps = caps; this.opts = _.cloneDeep(this.initialOpts); // merge caps onto opts so we don't need to worry about what's where Object.assign(this.opts, this.caps); // deal with resets // some people like to do weird things by setting noReset and fullReset // both to true, but this is misguided and strange, so error here instead if (this.opts.noReset && this.opts.fullReset) { throw new Error("The 'noReset' and 'fullReset' capabilities are mutually " + 'exclusive and should not both be set to true. You ' + "probably meant to just use 'fullReset' on its own"); } if (this.opts.noReset === true) { this.opts.fullReset = false; } if (this.opts.fullReset === true) { this.opts.noReset = false; } this.opts.fastReset = !this.opts.fullReset && !this.opts.noReset; this.opts.skipUninstall = this.opts.fastReset || this.opts.noReset; // Prevents empty string caps so we don't need to test it everywhere if (typeof this.opts.app === 'string' && this.opts.app.trim() === '') { this.opts.app = null; } if (!_.isUndefined(this.caps.newCommandTimeout)) { this.newCommandTimeoutMs = (this.caps.newCommandTimeout * 1000); } // We need to ininitialize one onUnexpectedShutdow promise per session // to avoid the promise fulfilment being propagated between sessions. this.resetOnUnexpectedShutdown(); log.info(`Session created with session id: ${this.sessionId}`); return [this.sessionId, caps]; }; commands.getSessions = async function getSessions () { let ret = []; if (this.sessionId) { ret.push({ id: this.sessionId, capabilities: this.caps }); } return ret; }; commands.getSession = async function getSession () { if (this.caps.eventTimings) { return Object.assign({}, this.caps, {events: this.eventHistory}); } return this.caps; }; commands.deleteSession = async function deleteSession (/* sessionId */) { this.clearNewCommandTimeout(); this.sessionId = null; }; function fixCaps (originalCaps, desiredCapConstraints = {}) { let caps = _.clone(originalCaps); // boolean capabilities can be passed in as strings 'false' and 'true' // which we want to translate into boolean values let booleanCaps = _.keys(_.pickBy(desiredCapConstraints, (k) => k.isBoolean === true)); for (let cap of booleanCaps) { let value = originalCaps[cap]; if (_.isString(value)) { value = value.toLowerCase(); if (value === 'true' || value === 'false') { log.warn(`Capability '${cap}' changed from string to boolean. This may cause unexpected behavior`); caps[cap] = (value === 'true'); } } } // int capabilities are often sent in as strings by frameworks let intCaps = _.keys(_.pickBy(desiredCapConstraints, (k) => k.isNumber === true)); for (let cap of intCaps) { let value = originalCaps[cap]; if (_.isString(value) && !isNaN(value)) { value = value.trim(); let newValue = parseInt(value, 10); if (value !== `${newValue}`) { newValue = parseFloat(value); } log.warn(`Capability '${cap}' changed from string ('${value}') to integer (${newValue}). This may cause unexpected behavior`); caps[cap] = newValue; } } return caps; } export default commands;