mirror of
https://github.com/appium/appium.git
synced 2026-02-08 02:30:32 -06:00
* Refactored code from createSession into parseCapsForInnerDriver()
* parseCapsForInnerDriver() takes jsonwp and w3c capabilities and translates them into objects that can be accepted by the "inner driver" that it proxies to
* It adds defaultCapabilities to capabilities.firstMatch and jsonwp caps
* It finds matching caps for W3C and then creates a new W3C capabilities object that only has the valid matching one
* After parseCapsForInnerDriver() parses the JSONWP and W3C it passes the results along to the inner-driver and it's up to the inner driver to create a W3C or JSONWP session
* Add validation to W3C session creation
* Call to 'processCapabilities' does validation now so that it will match an object that passes Appium's validation rules (e.g.: platformName, deviceName required; automation name must be valid, etc...)
* Test that it accepts combo of W3C and JSONWP capabilities
* Test that it rejects invalid W3C capabilities with 400 error
* Also added 'createSession' unit test
* Stripped out unnecessary async/await from driver-specs
* Insert Appium prefixes into W3C caps
* Previously, Appium just took the W3C capabilities, processed them into a caps object and
passed them into the inner driver as
```
{
alwaysMatch: parsedCaps,
firstMatch: [{}],
}
```
* The problem with this is that all of the parsedCaps were unprefixed, and therefore the Inner
Driver complained about it
* Now, it takes the parsedCaps and calls a new method called 'insertAppiumPrefixes' on the
parsed caps like this:
```
{
alwaysMatch: {...insertAppiumPrefixes(parsedCaps)},
firstMatch: [{}],
}
```
* Refactored tests that were affected by this change
* Added tests to test insertAppiumPrefixes function
150 lines
4.5 KiB
JavaScript
150 lines
4.5 KiB
JavaScript
import _ from 'lodash';
|
|
import logger from './logger';
|
|
import { processCapabilities } from 'appium-base-driver';
|
|
|
|
|
|
function inspectObject (args) {
|
|
function getValueArray (obj, indent = ' ') {
|
|
if (!_.isObject(obj)) {
|
|
return [obj];
|
|
}
|
|
|
|
let strArr = ['{'];
|
|
for (let [arg, value] of _.toPairs(obj)) {
|
|
if (!_.isObject(value)) {
|
|
strArr.push(`${indent} ${arg}: ${value}`);
|
|
} else {
|
|
value = getValueArray(value, `${indent} `);
|
|
strArr.push(`${indent} ${arg}: ${value.shift()}`);
|
|
strArr.push(...value);
|
|
}
|
|
}
|
|
strArr.push(`${indent}}`);
|
|
return strArr;
|
|
}
|
|
for (let [arg, value] of _.toPairs(args)) {
|
|
value = getValueArray(value);
|
|
logger.info(` ${arg}: ${value.shift()}`);
|
|
for (let val of value) {
|
|
logger.info(val);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Takes the caps that were provided in the request and translates them
|
|
* into caps that can be used by the inner drivers.
|
|
* @param {Object} jsonwpCaps
|
|
* @param {Object} w3cCapabilities
|
|
* @param {Object} constraints
|
|
* @param {Object} defaultCapabilities
|
|
*/
|
|
function parseCapsForInnerDriver (jsonwpCaps, w3cCapabilities, constraints={}, defaultCapabilities={}) {
|
|
// Check if the caller sent JSONWP caps, W3C caps, or both
|
|
const hasW3CCaps = _.isPlainObject(w3cCapabilities);
|
|
const hasJSONWPCaps = _.isPlainObject(jsonwpCaps);
|
|
|
|
// Make copies of the capabilities that include the default capabilities
|
|
if (hasW3CCaps) {
|
|
w3cCapabilities = {
|
|
...w3cCapabilities,
|
|
alwaysMatch: {
|
|
...defaultCapabilities,
|
|
...w3cCapabilities.alwaysMatch,
|
|
},
|
|
};
|
|
}
|
|
|
|
if (hasJSONWPCaps) {
|
|
jsonwpCaps = {
|
|
...defaultCapabilities,
|
|
...jsonwpCaps,
|
|
};
|
|
}
|
|
|
|
// Get MJSONWP caps
|
|
let desiredCaps = {};
|
|
if (hasJSONWPCaps) {
|
|
desiredCaps = jsonwpCaps;
|
|
}
|
|
|
|
// Get W3C caps
|
|
if (hasW3CCaps) {
|
|
// Call the process capabilities algorithm to find matching caps on the W3C
|
|
// (see: https://github.com/jlipps/simple-wd-spec#processing-capabilities)
|
|
let matchingW3CCaps = processCapabilities(w3cCapabilities, constraints, true);
|
|
|
|
if (hasJSONWPCaps) {
|
|
let jsonwpKeys = _.keys(desiredCaps);
|
|
let matchingW3CCapsKeys = _.keys(matchingW3CCaps);
|
|
|
|
// If JSONWP has keys that W3C doesn't have, log a warning message
|
|
let differingKeys = _.differenceWith(jsonwpKeys, matchingW3CCapsKeys);
|
|
if (!_.isEmpty(differingKeys)) {
|
|
logger.warn(`The following capabilities were provided in the JSONWP desired capabilities but
|
|
not the W3C capabilities: ${JSON.stringify(differingKeys)}`);
|
|
}
|
|
}
|
|
|
|
// If JSONWP caps and W3C caps were provided and there are discrepancies between them
|
|
// we'll be forgiving for now and just merge the two. But in the future, the clients
|
|
// should not be sending discrepant caps and Appium should ignore the extraneous MJSONWP caps
|
|
desiredCaps = {
|
|
...desiredCaps, // TODO: This line should be removed once we decide to not allow discrepent caps
|
|
...matchingW3CCaps,
|
|
};
|
|
}
|
|
|
|
let processedJsonwpCaps = null;
|
|
let processedW3CCapabilities = null;
|
|
|
|
// Create new JSONWP desired capabilities and W3C 'capabilities' objects that have the reconciled attributes
|
|
if (hasJSONWPCaps) {
|
|
processedJsonwpCaps = {...desiredCaps};
|
|
}
|
|
|
|
// Translate the matched W3C caps back into W3C capabilities object so that it
|
|
// can be proxied to the inner driver
|
|
if (hasW3CCaps) {
|
|
processedW3CCapabilities = {
|
|
alwaysMatch: {...insertAppiumPrefixes(desiredCaps)}, // Insert 'appium:' prefix to non-prefixed caps so that the Inner Driver doesn't complain about bad W3C prefixes
|
|
firstMatch: [{}],
|
|
};
|
|
}
|
|
|
|
return {desiredCaps, processedJsonwpCaps, processedW3CCapabilities};
|
|
}
|
|
|
|
|
|
/**
|
|
* Takes a capabilities objects and prefixes capabilities with `appium:`
|
|
* @param {Object} caps Desired capabilities object
|
|
*/
|
|
function insertAppiumPrefixes (caps) {
|
|
|
|
// Standard, non-prefixed capabilities (see https://www.w3.org/TR/webdriver/#dfn-table-of-standard-capabilities)
|
|
const STANDARD_CAPS = [
|
|
'browserName',
|
|
'browserVersion',
|
|
'platformName',
|
|
'acceptInsecureCerts',
|
|
'pageLoadStrategy',
|
|
'proxy',
|
|
'setWindowRect',
|
|
'timeouts',
|
|
'unhandledPromptBehavior'
|
|
];
|
|
|
|
let prefixedCaps = {};
|
|
for (let [name, value] of _.toPairs(caps)) {
|
|
if (STANDARD_CAPS.includes(name) || name.includes(':')) {
|
|
prefixedCaps[name] = value;
|
|
} else {
|
|
prefixedCaps[`appium:${name}`] = value;
|
|
}
|
|
}
|
|
return prefixedCaps;
|
|
}
|
|
|
|
export { inspectObject, parseCapsForInnerDriver, insertAppiumPrefixes };
|