fix: Tune status presence verification for generic protocol
MODIFY
lib/jsonwp-proxy/protocol-converter.js
lib/jsonwp-proxy/protocol-converter.js
@@ -2,7 +2,7 @@ import _ from 'lodash';
import { logger, util } from 'appium-support';
import { duplicateKeys } from '../basedriver/helpers';
import { PROTOCOLS, MJSONWP_ELEMENT_KEY, W3C_ELEMENT_KEY } from '../protocol/protocol';
-import { errors } from '../protocol/errors';
+import { formatStatus } from '../protocol/helpers';
const log = logger.getLogger('Protocol Converter');
@@ -188,18 +188,6 @@ class ProtocolConverter {
: await this.proxyFunc(url, method, body);
}
- async proxyGetStatus (url, method, body) {
- const [res, resBodyObj] = await this.proxyFunc(url, method, body);
- if (!_.isPlainObject(resBodyObj)) {
- return [res, resBodyObj];
- }
- const patchedBody = _.clone(resBodyObj);
- if (!_.has(resBodyObj, 'status')) {
- resBodyObj.status = res.statusCode === 200 ? 0 : errors.UnknownError.code();
- }
- return [res, patchedBody];
- }
-
/**
* Handle "crossing" endpoints for the case
* when upstream and downstream drivers operate different protocols
@@ -212,14 +200,10 @@ class ProtocolConverter {
*/
async convertAndProxy (commandName, url, method, body) {
if (!this.downstreamProtocol) {
- if (commandName === 'getStatus') {
- // Patch getStatus call for GENERIC protocol
+ // Patch calls with GENERIC protocol
// to preserve the backward compatibility
- return await this.proxyGetStatus(url, method, body);
- }
- // There is no point to convert anything if we do not know
- // for which protocol the conversion should be done
- return await this.proxyFunc(url, method, body);
+ const [res, resBodyObj] = await this.proxyFunc(url, method, body);
+ return [res, formatStatus(resBodyObj, res.statusCode)];
}
// Same url, but different arguments

MODIFY
lib/jsonwp-proxy/proxy.js
lib/jsonwp-proxy/proxy.js
@@ -314,7 +314,7 @@ class JWProxy {
}
}
resBodyObj.value = formatResponseValue(resBodyObj.value);
- formatStatus(resBodyObj, SESSIONS_CACHE.getProtocol(reqSessionId));
+ formatStatus(resBodyObj, res.statusCode, SESSIONS_CACHE.getProtocol(reqSessionId));
res.status(response.statusCode).send(JSON.stringify(resBodyObj));
}
}

MODIFY
lib/protocol/helpers.js
lib/protocol/helpers.js
@@ -6,6 +6,7 @@ import { PROTOCOLS } from '.';
const MJSONWP_ELEMENT_KEY = 'ELEMENT';
const W3C_ELEMENT_KEY = 'element-6066-11e4-a52e-4f735466cecf';
const JSONWP_SUCCESS_STATUS_CODE = 0;
+const JSONWP_UNKNOWN_ERROR_STATUS_CODE = 13;
/**
* Preprocesses the resulting value for API responses,
@@ -32,19 +33,22 @@ function formatResponseValue (resValue) {
* This method DOES mutate the `responseBody` argument if needed
*
* @param {Object} responseBody
+ * @param {number} responseCode the HTTP response code
* @param {?string} protocol The name of the protocol, either
* `PROTOCOLS.W3C` or `PROTOCOLS.MJSONWP`
* @returns {Object} The fixed response body
*/
-function formatStatus (responseBody, protocol = null) {
- if (!_.isPlainObject(responseBody) || !protocol) {
+function formatStatus (responseBody, responseCode = 200, protocol = null) {
+ if (!_.isPlainObject(responseBody)) {
return responseBody;
}
- if (protocol === PROTOCOLS.MJSONWP && !_.isInteger(responseBody.status)) {
- // Response status should be the status set by the driver response.
- responseBody.status = JSONWP_SUCCESS_STATUS_CODE;
- }
- if (protocol === PROTOCOLS.W3C && !_.isUndefined(responseBody.status)) {
+ const isError = _.has(responseBody.value, 'error') || responseCode >= 400;
+ if ((protocol === PROTOCOLS.MJSONWP && !_.isInteger(responseBody.status))
+ || (!protocol && !_.has(responseBody, 'status'))) {
+ responseBody.status = isError
+ ? JSONWP_UNKNOWN_ERROR_STATUS_CODE
+ : JSONWP_SUCCESS_STATUS_CODE;
+ } else if (protocol === PROTOCOLS.W3C && _.has(responseBody, 'status')) {
delete responseBody.status;
}
return responseBody;

MODIFY
lib/protocol/protocol.js
lib/protocol/protocol.js
@@ -355,7 +355,6 @@ function buildHandler (app, method, path, spec, driver, isSessCmd) {
}
}
- httpResBody = formatStatus(httpResBody, currentProtocol);
httpResBody.value = driverRes;
SESSIONS_CACHE.getLogger(req.params.sessionId || newSessionId, currentProtocol).debug(`Responding ` +
`to client with driver.${spec.command}() result: ${_.truncate(JSON.stringify(driverRes), {length: LOG_OBJ_LENGTH})}`);
@@ -418,11 +417,13 @@ function buildHandler (app, method, path, spec, driver, isSessCmd) {
} else {
httpResBody.sessionId = req.params.sessionId || null;
}
-
// Don't include sessionId in W3C responses
if (currentProtocol === PROTOCOLS.W3C) {
delete httpResBody.sessionId;
}
+
+ httpResBody = formatStatus(httpResBody, httpStatus, currentProtocol);
+
res.status(httpStatus).json(httpResBody);
}
};

fix: Tune status presence verification for generic protocol (#355)