UNPKG

@appium/base-driver

Version:

Base driver class for Appium drivers

852 lines 33.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.errors = exports.ProxyRequestError = exports.BadParametersError = exports.UnableToCaptureScreen = exports.NotImplementedError = exports.NotYetImplementedError = exports.InvalidContextError = exports.NoSuchContextError = exports.MoveTargetOutOfBoundsError = exports.SessionNotCreatedError = exports.InvalidSelectorError = exports.IMEEngineActivationFailedError = exports.IMENotAvailableError = exports.InvalidCoordinatesError = exports.InvalidElementCoordinatesError = exports.ScriptTimeoutError = exports.NoSuchAlertError = exports.NoAlertOpenError = exports.UnexpectedAlertOpenError = exports.UnableToSetCookieError = exports.NoSuchCookieError = exports.InvalidCookieDomainError = exports.InvalidArgumentError = exports.NoSuchWindowError = exports.TimeoutError = exports.XPathLookupError = exports.JavaScriptError = exports.InsecureCertificateError = exports.ElementNotInteractableError = exports.ElementClickInterceptedError = exports.ElementIsNotSelectableError = exports.UnsupportedOperationError = exports.UnknownMethodError = exports.UnknownError = exports.InvalidElementStateError = exports.ElementNotVisibleError = exports.StaleElementReferenceError = exports.UnknownCommandError = exports.NoSuchFrameError = exports.NoSuchShadowRootError = exports.NoSuchElementError = exports.NoSuchDriverError = exports.ProtocolError = void 0; exports.isErrorType = isErrorType; exports.errorFromMJSONWPStatusCode = errorFromMJSONWPStatusCode; exports.errorFromW3CJsonCode = errorFromW3CJsonCode; exports.getResponseForW3CError = getResponseForW3CError; const lodash_1 = __importDefault(require("lodash")); const support_1 = require("@appium/support"); const http_status_codes_1 = require("http-status-codes"); const mjsonwpLog = support_1.logger.getLogger('MJSONWP'); const w3cLog = support_1.logger.getLogger('W3C'); class BaseError extends Error { cause; message; name; stack; constructor(message = '', cause) { super(message); this.cause = cause; this.message = message; this.name = this.constructor.name; this._formatStack(); } _formatStack() { // eslint-disable-next-line no-prototype-builtins if (Error.hasOwnProperty('captureStackTrace') && lodash_1.default.isEmpty(this.stack)) { Error.captureStackTrace(this, this.constructor); } if (!lodash_1.default.isString(this.cause?.stack)) { return; } if (lodash_1.default.isEmpty(this.stack)) { this.stack = this.cause.stack; return; } const stackLines = this.stack?.split('\n') ?? []; stackLines.push('The above error is caused by'); stackLines.push(...this.cause.stack.split('\n')); this.stack = stackLines.join('\n'); } } // base error class for all of our errors class ProtocolError extends BaseError { jsonwpCode; error; w3cStatus; _stacktrace; constructor(msg, jsonwpCode, w3cStatus, w3cErrorSignature, cause) { super(msg, cause); this.jsonwpCode = jsonwpCode ?? UnknownError.code(); this.error = w3cErrorSignature ?? UnknownError.error(); this.w3cStatus = w3cStatus ?? UnknownError.w3cStatus(); this._stacktrace = undefined; } get stacktrace() { return this._stacktrace || this.stack; } set stacktrace(value) { this._stacktrace = value; } /** * Get the Bidi protocol version of an error * @param id - the id used in the request for which this error forms the response * @see https://w3c.github.io/webdriver-bidi/#protocol-definition * @returns The object conforming to the shape of a BiDi error response */ bidiErrObject(id) { // if we don't have an id, the client didn't send one, so we have nothing to send back. // send back zero rather than making something up const intId = (lodash_1.default.isInteger(id) ? id : (parseInt(`${id}`, 10) || 0)); return { id: intId, type: 'error', error: this.error, stacktrace: this.stacktrace, message: this.message, }; } } exports.ProtocolError = ProtocolError; // https://github.com/SeleniumHQ/selenium/blob/176b4a9e3082ac1926f2a436eb346760c37a5998/java/client/src/org/openqa/selenium/remote/ErrorCodes.java#L215 // https://github.com/SeleniumHQ/selenium/issues/5562#issuecomment-370379470 // https://w3c.github.io/webdriver/webdriver-spec.html#dfn-error-code class NoSuchDriverError extends ProtocolError { constructor(message = '', cause) { super(message || 'A session is either terminated or not started', NoSuchDriverError.code(), NoSuchDriverError.w3cStatus(), NoSuchDriverError.error(), cause); } static code() { return 6; } // W3C Error is called InvalidSessionID static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } static error() { return 'invalid session id'; } } exports.NoSuchDriverError = NoSuchDriverError; class NoSuchElementError extends ProtocolError { constructor(message = '', cause) { super(message || 'An element could not be located on the page using the given ' + 'search parameters.', NoSuchElementError.code(), NoSuchElementError.w3cStatus(), NoSuchElementError.error(), cause); } static code() { return 7; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } static error() { return 'no such element'; } } exports.NoSuchElementError = NoSuchElementError; /** * W3C WebDriver "no such shadow root" error. Issued when a command * targets an element's shadow root that does not exist (or has been * detached). Previously this was mis-classified as UnknownError — see * https://github.com/appium/appium/issues/22209. */ class NoSuchShadowRootError extends ProtocolError { constructor(message = '', cause) { super(message || 'The element does not have a shadow root attached.', NoSuchShadowRootError.code(), NoSuchShadowRootError.w3cStatus(), NoSuchShadowRootError.error(), cause); } // W3C-only error. No historical JSONWP code is assigned to // "no such shadow root"; keep a placeholder so the super call // typechecks (other errors in this file follow the same shape). static code() { return 65; } static error() { return 'no such shadow root'; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } } exports.NoSuchShadowRootError = NoSuchShadowRootError; class NoSuchFrameError extends ProtocolError { constructor(message = '', cause) { super(message || 'A request to switch to a frame could not be satisfied because ' + 'the frame could not be found.', NoSuchFrameError.code(), NoSuchFrameError.w3cStatus(), NoSuchFrameError.error(), cause); } static code() { return 8; } static error() { return 'no such frame'; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } } exports.NoSuchFrameError = NoSuchFrameError; class UnknownCommandError extends ProtocolError { constructor(message = '', cause) { super(message || 'The requested resource could not be found, or a request was ' + 'received using an HTTP method that is not supported by the mapped ' + 'resource.', UnknownCommandError.code(), UnknownCommandError.w3cStatus(), UnknownCommandError.error(), cause); } static code() { return 9; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } static error() { return 'unknown command'; } } exports.UnknownCommandError = UnknownCommandError; class StaleElementReferenceError extends ProtocolError { constructor(message = '', cause) { super(message || 'An element command failed because the referenced element is no ' + 'longer attached to the DOM.', StaleElementReferenceError.code(), StaleElementReferenceError.w3cStatus(), StaleElementReferenceError.error(), cause); } static code() { return 10; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } static error() { return 'stale element reference'; } } exports.StaleElementReferenceError = StaleElementReferenceError; class ElementNotVisibleError extends ProtocolError { constructor(message = '', cause) { super(message || 'An element command could not be completed because the element is ' + 'not visible on the page.', ElementNotVisibleError.code(), ElementNotVisibleError.w3cStatus(), ElementNotVisibleError.error(), cause); } static code() { return 11; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } static error() { return 'element not visible'; } } exports.ElementNotVisibleError = ElementNotVisibleError; class InvalidElementStateError extends ProtocolError { constructor(message = '', cause) { super(message || 'An element command could not be completed because the element is ' + 'in an invalid state (e.g. attempting to click a disabled element).', InvalidElementStateError.code(), InvalidElementStateError.w3cStatus(), InvalidElementStateError.error(), cause); } static code() { return 12; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } static error() { return 'invalid element state'; } } exports.InvalidElementStateError = InvalidElementStateError; class UnknownError extends ProtocolError { constructor(message = '', cause) { super(message || 'An unknown server-side error occurred while processing the command.', UnknownError.code(), UnknownError.w3cStatus(), UnknownError.error(), cause); } static code() { return 13; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'unknown error'; } } exports.UnknownError = UnknownError; class UnknownMethodError extends ProtocolError { constructor(message = '', cause) { super(message || 'The requested command matched a known URL but did not match an method for that URL', UnknownMethodError.code(), UnknownMethodError.w3cStatus(), UnknownMethodError.error(), cause); } static code() { return 405; } static w3cStatus() { return http_status_codes_1.StatusCodes.METHOD_NOT_ALLOWED; } static error() { return 'unknown method'; } } exports.UnknownMethodError = UnknownMethodError; class UnsupportedOperationError extends ProtocolError { constructor(message = '', cause) { super(message || 'A server-side error occurred. Command cannot be supported.', UnsupportedOperationError.code(), UnsupportedOperationError.w3cStatus(), UnsupportedOperationError.error(), cause); } static code() { return 405; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'unsupported operation'; } } exports.UnsupportedOperationError = UnsupportedOperationError; class ElementIsNotSelectableError extends ProtocolError { constructor(message = '', cause) { super(message || 'An attempt was made to select an element that cannot be selected.', ElementIsNotSelectableError.code(), ElementIsNotSelectableError.w3cStatus(), ElementIsNotSelectableError.error(), cause); } static code() { return 15; } static error() { return 'element not selectable'; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } } exports.ElementIsNotSelectableError = ElementIsNotSelectableError; class ElementClickInterceptedError extends ProtocolError { constructor(message = '', cause) { super(message || 'The Element Click command could not be completed because the element receiving ' + 'the events is obscuring the element that was requested clicked', ElementClickInterceptedError.code(), ElementClickInterceptedError.w3cStatus(), ElementClickInterceptedError.error(), cause); } static code() { return 64; } static error() { return 'element click intercepted'; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } } exports.ElementClickInterceptedError = ElementClickInterceptedError; class ElementNotInteractableError extends ProtocolError { constructor(message = '', cause) { super(message || 'A command could not be completed because the element is not pointer- or keyboard interactable', ElementNotInteractableError.code(), ElementNotInteractableError.w3cStatus(), ElementNotInteractableError.error(), cause); } static code() { return 60; } static error() { return 'element not interactable'; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } } exports.ElementNotInteractableError = ElementNotInteractableError; class InsecureCertificateError extends ProtocolError { constructor(message = '', cause) { super(message || 'Navigation caused the user agent to hit a certificate warning, which is usually the result of an expired or invalid TLS certificate', UnknownError.code(), InsecureCertificateError.w3cStatus(), InsecureCertificateError.error(), cause); } static error() { return 'insecure certificate'; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } } exports.InsecureCertificateError = InsecureCertificateError; class JavaScriptError extends ProtocolError { constructor(message = '', cause) { super(message || 'An error occurred while executing user supplied JavaScript.', JavaScriptError.code(), JavaScriptError.w3cStatus(), JavaScriptError.error(), cause); } static code() { return 17; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'javascript error'; } } exports.JavaScriptError = JavaScriptError; class XPathLookupError extends ProtocolError { constructor(message = '', cause) { super(message || 'An error occurred while searching for an element by XPath.', XPathLookupError.code(), XPathLookupError.w3cStatus(), XPathLookupError.error(), cause); } static code() { return 19; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } static error() { return 'invalid selector'; } } exports.XPathLookupError = XPathLookupError; class TimeoutError extends ProtocolError { constructor(message = '', cause) { super(message || 'An operation did not complete before its timeout expired.', TimeoutError.code(), TimeoutError.w3cStatus(), TimeoutError.error(), cause); } static code() { return 21; } static w3cStatus() { return http_status_codes_1.StatusCodes.REQUEST_TIMEOUT; } static error() { return 'timeout'; } } exports.TimeoutError = TimeoutError; class NoSuchWindowError extends ProtocolError { constructor(message = '', cause) { super(message || 'A request to switch to a different window could not be satisfied ' + 'because the window could not be found.', NoSuchWindowError.code(), NoSuchWindowError.w3cStatus(), NoSuchWindowError.error(), cause); } static code() { return 23; } static error() { return 'no such window'; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } } exports.NoSuchWindowError = NoSuchWindowError; class InvalidArgumentError extends ProtocolError { constructor(message = '', cause) { super(message || 'The arguments passed to the command are either invalid or malformed', InvalidArgumentError.code(), InvalidArgumentError.w3cStatus(), InvalidArgumentError.error(), cause); } static code() { return 61; } static error() { return 'invalid argument'; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } } exports.InvalidArgumentError = InvalidArgumentError; class InvalidCookieDomainError extends ProtocolError { constructor(message = '', cause) { super(message || 'An illegal attempt was made to set a cookie under a different ' + 'domain than the current page.', InvalidCookieDomainError.code(), InvalidCookieDomainError.w3cStatus(), InvalidCookieDomainError.error(), cause); } static code() { return 24; } static error() { return 'invalid cookie domain'; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } } exports.InvalidCookieDomainError = InvalidCookieDomainError; class NoSuchCookieError extends ProtocolError { constructor(message = '', cause) { super(message || 'No cookie matching the given path name was found amongst the associated cookies of the current browsing context’s active document', NoSuchCookieError.code(), NoSuchCookieError.w3cStatus(), NoSuchCookieError.error(), cause); } static code() { return 62; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } static error() { return 'no such cookie'; } } exports.NoSuchCookieError = NoSuchCookieError; class UnableToSetCookieError extends ProtocolError { constructor(message = '', cause) { super(message || "A request to set a cookie's value could not be satisfied.", UnableToSetCookieError.code(), UnableToSetCookieError.w3cStatus(), UnableToSetCookieError.error(), cause); } static code() { return 25; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'unable to set cookie'; } } exports.UnableToSetCookieError = UnableToSetCookieError; class UnexpectedAlertOpenError extends ProtocolError { constructor(message = '', cause) { super(message || 'A modal dialog was open, blocking this operation', UnexpectedAlertOpenError.code(), UnexpectedAlertOpenError.w3cStatus(), UnexpectedAlertOpenError.error(), cause); } static code() { return 26; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'unexpected alert open'; } } exports.UnexpectedAlertOpenError = UnexpectedAlertOpenError; class NoAlertOpenError extends ProtocolError { constructor(message = '', cause) { super(message || 'An attempt was made to operate on a modal dialog when one was not open.', NoAlertOpenError.code(), NoAlertOpenError.w3cStatus(), NoAlertOpenError.error(), cause); } static code() { return 27; } static w3cStatus() { return http_status_codes_1.StatusCodes.NOT_FOUND; } static error() { return 'no such alert'; } } exports.NoAlertOpenError = NoAlertOpenError; class NoSuchAlertError extends NoAlertOpenError { } exports.NoSuchAlertError = NoSuchAlertError; class ScriptTimeoutError extends ProtocolError { constructor(message = '', cause) { super(message || 'A script did not complete before its timeout expired.', ScriptTimeoutError.code(), ScriptTimeoutError.w3cStatus(), ScriptTimeoutError.error(), cause); } static code() { return 28; } static w3cStatus() { return http_status_codes_1.StatusCodes.REQUEST_TIMEOUT; } static error() { return 'script timeout'; } } exports.ScriptTimeoutError = ScriptTimeoutError; class InvalidElementCoordinatesError extends ProtocolError { constructor(message = '', cause) { super(message || 'The coordinates provided to an interactions operation are invalid.', InvalidElementCoordinatesError.code(), InvalidElementCoordinatesError.w3cStatus(), InvalidElementCoordinatesError.error(), cause); } static code() { return 29; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } static error() { return 'invalid coordinates'; } } exports.InvalidElementCoordinatesError = InvalidElementCoordinatesError; class InvalidCoordinatesError extends InvalidElementCoordinatesError { } exports.InvalidCoordinatesError = InvalidCoordinatesError; class IMENotAvailableError extends ProtocolError { constructor(message = '', cause) { super(message || 'IME was not available.', IMENotAvailableError.code(), IMENotAvailableError.w3cStatus(), IMENotAvailableError.error(), cause); } static code() { return 30; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'unsupported operation'; } } exports.IMENotAvailableError = IMENotAvailableError; class IMEEngineActivationFailedError extends ProtocolError { constructor(message = '', cause) { super(message || 'An IME engine could not be started.', IMEEngineActivationFailedError.code(), IMEEngineActivationFailedError.w3cStatus(), IMEEngineActivationFailedError.error(), cause); } static code() { return 31; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'unsupported operation'; } } exports.IMEEngineActivationFailedError = IMEEngineActivationFailedError; class InvalidSelectorError extends ProtocolError { constructor(message = '', cause) { super(message || 'Argument was an invalid selector (e.g. XPath/CSS).', InvalidSelectorError.code(), InvalidSelectorError.w3cStatus(), InvalidSelectorError.error(), cause); } static code() { return 32; } static w3cStatus() { return http_status_codes_1.StatusCodes.BAD_REQUEST; } static error() { return 'invalid selector'; } } exports.InvalidSelectorError = InvalidSelectorError; class SessionNotCreatedError extends ProtocolError { constructor(message = '', cause) { super(`A new session could not be created.${message ? (' Details: ' + message) : ''}`, SessionNotCreatedError.code(), SessionNotCreatedError.w3cStatus(), SessionNotCreatedError.error(), cause); } static code() { return 33; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'session not created'; } } exports.SessionNotCreatedError = SessionNotCreatedError; class MoveTargetOutOfBoundsError extends ProtocolError { constructor(message = '', cause) { super(message || 'Target provided for a move action is out of bounds.', MoveTargetOutOfBoundsError.code(), MoveTargetOutOfBoundsError.w3cStatus(), MoveTargetOutOfBoundsError.error(), cause); } static code() { return 34; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'move target out of bounds'; } } exports.MoveTargetOutOfBoundsError = MoveTargetOutOfBoundsError; class NoSuchContextError extends ProtocolError { constructor(message = '', cause) { super(message || 'No such context found.', NoSuchContextError.code(), UnknownError.w3cStatus(), UnknownError.error(), cause); } static code() { return 35; } } exports.NoSuchContextError = NoSuchContextError; class InvalidContextError extends ProtocolError { constructor(message = '', cause) { super(message || 'That command could not be executed in the current context.', InvalidContextError.code(), UnknownError.w3cStatus(), UnknownError.error(), cause); } static code() { return 36; } } exports.InvalidContextError = InvalidContextError; // Aliases to UnknownMethodError class NotYetImplementedError extends UnknownMethodError { constructor(message = '', cause) { super(message || 'Method has not yet been implemented', cause); } } exports.NotYetImplementedError = NotYetImplementedError; class NotImplementedError extends UnknownMethodError { constructor(message = '', cause) { super(message || 'Method is not implemented', cause); } } exports.NotImplementedError = NotImplementedError; class UnableToCaptureScreen extends ProtocolError { constructor(message = '', cause) { super(message || 'A screen capture was made impossible', UnableToCaptureScreen.code(), UnableToCaptureScreen.w3cStatus(), UnableToCaptureScreen.error(), cause); } static code() { return 63; } static w3cStatus() { return http_status_codes_1.StatusCodes.INTERNAL_SERVER_ERROR; } static error() { return 'unable to capture screen'; } } exports.UnableToCaptureScreen = UnableToCaptureScreen; // Equivalent to W3C InvalidArgumentError class BadParametersError extends InvalidArgumentError { constructor(paramReqs, paramNames) { super(generateBadParametersMessage(paramReqs, paramNames)); } } exports.BadParametersError = BadParametersError; /** * ProxyRequestError is a custom error and will be thrown up on unsuccessful proxy request and * will contain information about the proxy failure. * In case of ProxyRequestError should fetch the actual error by calling `getActualError()` * for proxy failure to generate the client response. */ class ProxyRequestError extends BaseError { _w3cError; _w3cErrorStatus; _jwpError; constructor(message, httpResponseData, httpStatus, cause) { const [responseErrorObj, originalMessage] = ProxyRequestError._parseHttpResponse(httpResponseData); super(lodash_1.default.isEmpty(message) ? `Proxy request unsuccessful.${originalMessage ? (' ' + originalMessage) : ''}` : message, cause); // If the response error is an object and value is an object, it's a W3C error (for JSONWP value is a string) if (lodash_1.default.isPlainObject(responseErrorObj.value) && lodash_1.default.has(responseErrorObj.value, 'error')) { this._w3cError = responseErrorObj.value; this._w3cErrorStatus = httpStatus; } else if (lodash_1.default.has(responseErrorObj, 'status')) { this._jwpError = responseErrorObj; } } static _parseHttpResponse(data) { let responseErrorObj = support_1.util.safeJsonParse(data); if (!lodash_1.default.isPlainObject(responseErrorObj)) { responseErrorObj = {}; } let errorMessage = lodash_1.default.isString(data) ? data : ''; if (lodash_1.default.isString(responseErrorObj.value)) { errorMessage = responseErrorObj.value; } else if (lodash_1.default.isString(responseErrorObj.value?.message)) { errorMessage = responseErrorObj.value.message; } return [responseErrorObj, errorMessage]; } getActualError() { if (support_1.util.hasValue(this._jwpError?.status) && support_1.util.hasValue(this._jwpError?.value)) { // If it's MJSONWP error, returns actual error cause for request failure based on `jsonwp.status` return errorFromMJSONWPStatusCode(this._jwpError.status, this._jwpError.value); } if (support_1.util.hasValue(this._w3cError) && lodash_1.default.isNumber(this._w3cErrorStatus) && this._w3cErrorStatus >= 300) { return errorFromW3CJsonCode(this._w3cError.error, this._w3cError.message || this.message, this._w3cError.stacktrace || this.stack); } return new UnknownError(this.message, this.cause); } } exports.ProxyRequestError = ProxyRequestError; function generateBadParametersMessage(paramRequirements, paramNames) { const toArray = function (x) { if (lodash_1.default.isUndefined(x)) { return []; } if (lodash_1.default.isArray(x)) { return x; } return [x]; }; const requiredParamNames = toArray(paramRequirements.required); const actualParamNames = toArray(paramNames); const missingRequiredParamNames = lodash_1.default.difference(requiredParamNames, actualParamNames); const resultLines = []; resultLines.push(lodash_1.default.isEmpty(missingRequiredParamNames) ? // This should not happen 'Some of the provided parameters are not known' : `The following required parameter${missingRequiredParamNames.length === 1 ? ' is' : 's are'} missing: ${JSON.stringify(missingRequiredParamNames)}`); if (!lodash_1.default.isEmpty(requiredParamNames)) { resultLines.push(`Known required parameters are: ${JSON.stringify(requiredParamNames)}`); } const optionalParamNames = lodash_1.default.difference(toArray(paramRequirements.optional), ['sessionId', 'id']); if (!lodash_1.default.isEmpty(optionalParamNames)) { resultLines.push(`Known optional parameters are: ${JSON.stringify(optionalParamNames)}`); } resultLines.push(`You have provided${lodash_1.default.isEmpty(actualParamNames) ? ' none' : ': ' + JSON.stringify(paramNames)}`); return resultLines.join('\n'); } // map of error class name to error class exports.errors = { NotYetImplementedError, NotImplementedError, InvalidArgumentError, NoSuchDriverError, NoSuchElementError, UnknownCommandError, StaleElementReferenceError, ElementNotVisibleError, InvalidElementStateError, UnknownError, ElementIsNotSelectableError, ElementClickInterceptedError, ElementNotInteractableError, InsecureCertificateError, JavaScriptError, XPathLookupError, TimeoutError, NoSuchWindowError, NoSuchCookieError, InvalidCookieDomainError, InvalidCoordinatesError, UnableToSetCookieError, UnexpectedAlertOpenError, NoAlertOpenError, ScriptTimeoutError, InvalidElementCoordinatesError, IMENotAvailableError, IMEEngineActivationFailedError, InvalidSelectorError, SessionNotCreatedError, MoveTargetOutOfBoundsError, NoSuchAlertError, NoSuchContextError, InvalidContextError, NoSuchFrameError, NoSuchShadowRootError, UnableToCaptureScreen, UnknownMethodError, UnsupportedOperationError, ProxyRequestError, }; const jsonwpErrorCodeMap = lodash_1.default.values(exports.errors) .reduce((acc, ErrorClass) => { if ('code' in ErrorClass) { acc[ErrorClass.code()] = ErrorClass; } return acc; }, {}); const w3cErrorCodeMap = lodash_1.default.values(exports.errors) .reduce((acc, ErrorClass) => { if ('error' in ErrorClass) { acc[ErrorClass.error()] = ErrorClass; } return acc; }, {}); /** * Type guard to check if an Error is of a specific type */ function isErrorType(err, type) { return err.constructor?.name === type.name; } /** * Retrieve an error derived from MJSONWP status * @param code JSONWP status code * @param value The error message, or an object with a `message` property * @return The error that is associated with provided JSONWP status code */ function errorFromMJSONWPStatusCode(code, value = '') { const ErrorClass = jsonwpErrorCodeMap[code] ?? UnknownError; mjsonwpLog.debug(`Matched JSONWP error code ${code} to ${ErrorClass.name}`); // if `value` is an object, pull message from it, otherwise use the plain // value, or default to an empty string, if null const message = (value || {}).message || value || ''; return new ErrorClass(message); } /** * Retrieve an error derived from W3C JSON Code * @param signature W3C error string (see https://www.w3.org/TR/webdriver/#handling-errors `JSON Error Code` column) * @param message the error message * @param stacktrace an optional error stacktrace * @return The error that is associated with the W3C error string */ function errorFromW3CJsonCode(signature, message, stacktrace) { const ErrorClass = w3cErrorCodeMap[lodash_1.default.toLower(signature)] ?? UnknownError; w3cLog.debug(`Matched W3C error code '${signature}' to ${ErrorClass.name}`); const resultError = new ErrorClass(message); resultError.stacktrace = stacktrace; return resultError; } /** * Convert an Appium error to proper W3C HTTP response * * @param err The error that needs to be translated */ function getResponseForW3CError(err) { const protocolErrorToResponse = (e) => [ e.w3cStatus, { value: { error: e.error, message: e.message, stacktrace: e.stacktrace || e.stack, } } ]; // err is ProtocolError if (['error', 'w3cStatus'].every((prop) => lodash_1.default.has(err, prop))) { return protocolErrorToResponse(err); } // err is ProxyRequestError if (lodash_1.default.has(err, 'getActualError') && lodash_1.default.isFunction(err.getActualError)) { return protocolErrorToResponse(err.getActualError()); } return protocolErrorToResponse(new UnknownError(err.message, err)); } //# sourceMappingURL=errors.js.map