// Licensed to the Software Freedom Conservancy (SFC) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The SFC licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. 'use strict'; describe('error', function() { let assert = require('assert'); let error = require('../../lib/error'); describe('checkResponse', function() { it('defaults to WebDriverError if type is unrecognized', function() { assert.throws( () => error.checkResponse({error: 'foo', message: 'hi there'}), (e) => { assert.equal(e.constructor, error.WebDriverError); return true; }); }); it('does not throw if error property is not a string', function() { let resp = {error: 123, message: 'abc123'}; let out = error.checkResponse(resp); assert.strictEqual(out, resp); }); test('unknown error', error.WebDriverError); test('element not interactable', error.ElementNotInteractableError); test('element not selectable', error.ElementNotSelectableError); test('element not visible', error.ElementNotVisibleError); test('invalid argument', error.InvalidArgumentError); test('invalid cookie domain', error.InvalidCookieDomainError); test('invalid element coordinates', error.InvalidElementCoordinatesError); test('invalid element state', error.InvalidElementStateError); test('invalid selector', error.InvalidSelectorError); test('invalid session id', error.NoSuchSessionError); test('javascript error', error.JavascriptError); test('move target out of bounds', error.MoveTargetOutOfBoundsError); test('no such alert', error.NoSuchAlertError); test('no such element', error.NoSuchElementError); test('no such frame', error.NoSuchFrameError); test('no such window', error.NoSuchWindowError); test('script timeout', error.ScriptTimeoutError); test('session not created', error.SessionNotCreatedError); test('stale element reference', error.StaleElementReferenceError); test('timeout', error.TimeoutError); test('unable to set cookie', error.UnableToSetCookieError); test('unable to capture screen', error.UnableToCaptureScreenError); test('unexpected alert open', error.UnexpectedAlertOpenError); test('unknown command', error.UnknownCommandError); test('unknown method', error.UnknownMethodError); test('unsupported operation', error.UnsupportedOperationError); function test(status, expectedType) { it(`"${status}" => ${expectedType.name}`, function() { assert.throws( () => error.checkResponse({error: status, message: 'oops'}), (e) => { assert.equal(expectedType, e.constructor); assert.equal(e.message, 'oops'); return true; }); }); } }); describe('encodeError', function() { describe('defaults to an unknown error', function() { it('for a generic error value', function() { runTest('hi', 'unknown error', 'hi'); runTest(1, 'unknown error', '1'); runTest({}, 'unknown error', '[object Object]'); }); it('for a generic Error object', function() { runTest(Error('oops'), 'unknown error', 'oops'); runTest(TypeError('bad value'), 'unknown error', 'bad value'); }); }); test(error.WebDriverError, 'unknown error'); test(error.ElementNotSelectableError, 'element not selectable'); test(error.ElementNotVisibleError, 'element not visible'); test(error.InvalidArgumentError, 'invalid argument'); test(error.InvalidCookieDomainError, 'invalid cookie domain'); test(error.InvalidElementStateError, 'invalid element state'); test(error.InvalidSelectorError, 'invalid selector'); test(error.NoSuchSessionError, 'invalid session id'); test(error.JavascriptError, 'javascript error'); test(error.MoveTargetOutOfBoundsError, 'move target out of bounds'); test(error.NoSuchAlertError, 'no such alert'); test(error.NoSuchElementError, 'no such element'); test(error.NoSuchFrameError, 'no such frame'); test(error.NoSuchWindowError, 'no such window'); test(error.ScriptTimeoutError, 'script timeout'); test(error.SessionNotCreatedError, 'session not created'); test(error.StaleElementReferenceError, 'stale element reference'); test(error.TimeoutError, 'timeout'); test(error.UnableToSetCookieError, 'unable to set cookie'); test(error.UnableToCaptureScreenError, 'unable to capture screen'); test(error.UnexpectedAlertOpenError, 'unexpected alert open'); test(error.UnknownCommandError, 'unknown command'); test(error.UnknownMethodError, 'unknown method'); test(error.UnsupportedOperationError, 'unsupported operation'); function test(ctor, code) { it(`${ctor.name} => "${code}"`, () => { runTest(new ctor('oops'), code, 'oops'); }); } function runTest(err, code, message) { let obj = error.encodeError(err); assert.strictEqual(obj['error'], code); assert.strictEqual(obj['message'], message); } }); describe('throwDecodedError', function() { it('defaults to WebDriverError if type is unrecognized', function() { assert.throws( () => error.throwDecodedError({error: 'foo', message: 'hi there'}), (e) => { assert.equal(e.constructor, error.WebDriverError); return true; }); }); it('throws generic error if encoded data is not valid', function() { assert.throws( () => error.throwDecodedError({error: 123, message: 'abc123'}), (e) => { assert.strictEqual(e.constructor, error.WebDriverError); return true; }); assert.throws( () => error.throwDecodedError('null'), (e) => { assert.strictEqual(e.constructor, error.WebDriverError); return true; }); assert.throws( () => error.throwDecodedError(''), (e) => { assert.strictEqual(e.constructor, error.WebDriverError); return true; }); }); test('unknown error', error.WebDriverError); test('element not selectable', error.ElementNotSelectableError); test('element not visible', error.ElementNotVisibleError); test('invalid argument', error.InvalidArgumentError); test('invalid cookie domain', error.InvalidCookieDomainError); test('invalid element coordinates', error.InvalidElementCoordinatesError); test('invalid element state', error.InvalidElementStateError); test('invalid selector', error.InvalidSelectorError); test('invalid session id', error.NoSuchSessionError); test('javascript error', error.JavascriptError); test('move target out of bounds', error.MoveTargetOutOfBoundsError); test('no such alert', error.NoSuchAlertError); test('no such element', error.NoSuchElementError); test('no such frame', error.NoSuchFrameError); test('no such window', error.NoSuchWindowError); test('script timeout', error.ScriptTimeoutError); test('session not created', error.SessionNotCreatedError); test('stale element reference', error.StaleElementReferenceError); test('timeout', error.TimeoutError); test('unable to set cookie', error.UnableToSetCookieError); test('unable to capture screen', error.UnableToCaptureScreenError); test('unexpected alert open', error.UnexpectedAlertOpenError); test('unknown command', error.UnknownCommandError); test('unknown method', error.UnknownMethodError); test('unsupported operation', error.UnsupportedOperationError); it('leaves remoteStacktrace empty if not in encoding', function() { assert.throws( () => error.throwDecodedError({ error: 'session not created', message: 'oops' }), (e) => { assert.strictEqual(e.constructor, error.SessionNotCreatedError); assert.strictEqual(e.message, 'oops'); assert.strictEqual(e.remoteStacktrace, ''); return true; }); }); function test(status, expectedType) { it(`"${status}" => ${expectedType.name}`, function() { assert.throws( () => error.throwDecodedError({ error: status, message: 'oops', stacktrace: 'some-stacktrace' }), (e) => { assert.strictEqual(e.constructor, expectedType); assert.strictEqual(e.message, 'oops'); assert.strictEqual(e.remoteStacktrace, 'some-stacktrace'); return true; }); }); } }); describe('checkLegacyResponse', function() { it('does not throw for success', function() { let resp = {status: error.ErrorCode.SUCCESS}; assert.strictEqual(resp, error.checkLegacyResponse(resp)); }); test('NO_SUCH_ELEMENT', error.NoSuchElementError); test('NO_SUCH_FRAME', error.NoSuchFrameError); test('UNKNOWN_COMMAND', error.UnsupportedOperationError); test('UNSUPPORTED_OPERATION', error.UnsupportedOperationError); test('STALE_ELEMENT_REFERENCE', error.StaleElementReferenceError); test('ELEMENT_NOT_VISIBLE', error.ElementNotVisibleError); test('INVALID_ELEMENT_STATE', error.InvalidElementStateError); test('UNKNOWN_ERROR', error.WebDriverError); test('ELEMENT_NOT_SELECTABLE', error.ElementNotSelectableError); test('JAVASCRIPT_ERROR', error.JavascriptError); test('XPATH_LOOKUP_ERROR', error.InvalidSelectorError); test('TIMEOUT', error.TimeoutError); test('NO_SUCH_WINDOW', error.NoSuchWindowError); test('INVALID_COOKIE_DOMAIN', error.InvalidCookieDomainError); test('UNABLE_TO_SET_COOKIE', error.UnableToSetCookieError); test('UNEXPECTED_ALERT_OPEN', error.UnexpectedAlertOpenError); test('NO_SUCH_ALERT', error.NoSuchAlertError); test('SCRIPT_TIMEOUT', error.ScriptTimeoutError); test('INVALID_ELEMENT_COORDINATES', error.InvalidElementCoordinatesError); test('INVALID_SELECTOR_ERROR', error.InvalidSelectorError); test('SESSION_NOT_CREATED', error.SessionNotCreatedError); test('MOVE_TARGET_OUT_OF_BOUNDS', error.MoveTargetOutOfBoundsError); test('INVALID_XPATH_SELECTOR', error.InvalidSelectorError); test('INVALID_XPATH_SELECTOR_RETURN_TYPE', error.InvalidSelectorError); test('METHOD_NOT_ALLOWED', error.UnsupportedOperationError); describe('UnexpectedAlertOpenError', function() { it('includes alert text from the response object', function() { let response = { status: error.ErrorCode.UNEXPECTED_ALERT_OPEN, value: { message: 'hi', alert: {text: 'alert text here'} } }; assert.throws( () => error.checkLegacyResponse(response), (e) => { assert.equal(error.UnexpectedAlertOpenError, e.constructor); assert.equal(e.message, 'hi'); assert.equal(e.getAlertText(), 'alert text here'); return true; }); }); it('uses an empty string if alert text omitted', function() { let response = { status: error.ErrorCode.UNEXPECTED_ALERT_OPEN, value: { message: 'hi' } }; assert.throws( () => error.checkLegacyResponse(response), (e) => { assert.equal(error.UnexpectedAlertOpenError, e.constructor); assert.equal(e.message, 'hi'); assert.equal(e.getAlertText(), ''); return true; }); }); }); function test(codeKey, expectedType) { it(`${codeKey} => ${expectedType.name}`, function() { let code = error.ErrorCode[codeKey]; let resp = {status: code, value: {message: 'hi'}}; assert.throws( () => error.checkLegacyResponse(resp), (e) => { assert.equal(expectedType, e.constructor); assert.equal(e.message, 'hi'); return true; }); }); } }); });