How to use startUnexpectedShutdown method in Appium Base Driver

Best JavaScript code snippet using appium-base-driver

appium.js

Source:appium.js Github

copy

Full Screen

...443 reason,444 } = opts;445 log.debug(`Cleaning up ${util.pluralize('active session', sessionsCount, true)}`);446 const cleanupPromises = force447 ? _.values(this.sessions).map((drv) => drv.startUnexpectedShutdown(reason && new Error(reason)))448 : _.keys(this.sessions).map((id) => this.deleteSession(id));449 for (const cleanupPromise of cleanupPromises) {450 try {451 await cleanupPromise;452 } catch (e) {453 log.debug(e);454 }455 }456 }457 async executeCommand (cmd, ...args) {458 // getStatus command should not be put into queue. If we do it as part of super.executeCommand, it will be added to queue.459 // There will be lot of status commands in queue during createSession command, as createSession can take up to or more than a minute.460 if (cmd === 'getStatus') {461 return await this.getStatus();...

Full Screen

Full Screen

driver-tests.js

Source:driver-tests.js Github

copy

Full Screen

...75 const p = new B((resolve, reject) => {76 setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);77 d.onUnexpectedShutdown(resolve);78 });79 d.startUnexpectedShutdown(new Error('We crashed'));80 await cmdPromise.should.be.rejectedWith(/We crashed/);81 await p;82 });83 it('should not allow commands in middle of unexpected shutdown', async function () {84 // make a command that will wait a bit so we can crash while it's running85 d.oldDeleteSession = d.deleteSession;86 d.deleteSession = async function () {87 await B.delay(100);88 await this.oldDeleteSession();89 }.bind(d);90 let caps = _.clone(defaultCaps);91 await d.createSession(caps);92 const p = new B((resolve, reject) => {93 setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);94 d.onUnexpectedShutdown(resolve);95 });96 d.startUnexpectedShutdown(new Error('We crashed'));97 await p;98 await d.executeCommand('getSession').should.be.rejectedWith(/shut down/);99 });100 it('should allow new commands after done shutting down', async function () {101 // make a command that will wait a bit so we can crash while it's running102 d.oldDeleteSession = d.deleteSession;103 d.deleteSession = async function () {104 await B.delay(100);105 await this.oldDeleteSession();106 }.bind(d);107 let caps = _.clone(defaultCaps);108 await d.createSession(caps);109 const p = new B((resolve, reject) => {110 setTimeout(() => reject(new Error('onUnexpectedShutdown event is expected to be fired within 5 seconds timeout')), 5000);111 d.onUnexpectedShutdown(resolve);112 });113 d.startUnexpectedShutdown(new Error('We crashed'));114 await p;115 await d.executeCommand('getSession').should.be.rejectedWith(/shut down/);116 await B.delay(500);117 await d.executeCommand('createSession', caps);118 await d.deleteSession();119 });120 it('should distinguish between W3C and JSONWP session', async function () {121 // Test JSONWP122 await d.executeCommand('createSession', Object.assign({}, defaultCaps, {123 platformName: 'Fake',124 deviceName: 'Commodore 64',125 }));126 d.protocol.should.equal('MJSONWP');127 await d.executeCommand('deleteSession');...

Full Screen

Full Screen

driver.js

Source:driver.js Github

copy

Full Screen

1import {2 Protocol, errors, determineProtocol3} from '../protocol';4import {5 MJSONWP_ELEMENT_KEY, W3C_ELEMENT_KEY, PROTOCOLS, DEFAULT_BASE_PATH,6} from '../constants';7import os from 'os';8import commands from './commands';9import * as helpers from './helpers';10import log from './logger';11import DeviceSettings from './device-settings';12import { desiredCapabilityConstraints } from './desired-caps';13import { validateCaps } from './capabilities';14import B from 'bluebird';15import _ from 'lodash';16import {17 ImageElement, makeImageElementCache, getImgElFromArgs18} from './image-element';19import AsyncLock from 'async-lock';20import { EventEmitter } from 'events';21B.config({22 cancellation: true,23});24const NEW_COMMAND_TIMEOUT_MS = 60 * 1000;25const EVENT_SESSION_INIT = 'newSessionRequested';26const EVENT_SESSION_START = 'newSessionStarted';27const EVENT_SESSION_QUIT_START = 'quitSessionRequested';28const EVENT_SESSION_QUIT_DONE = 'quitSessionFinished';29const ON_UNEXPECTED_SHUTDOWN_EVENT = 'onUnexpectedShutdown';30class BaseDriver extends Protocol {31 constructor (opts = {}, shouldValidateCaps = true) {32 super();33 // setup state34 this.sessionId = null;35 this.opts = opts;36 this.caps = null;37 this.helpers = helpers;38 // basePath is used for several purposes, for example in setting up39 // proxying to other drivers, since we need to know what the base path40 // of any incoming request might look like. We set it to the default41 // initially but it is automatically updated during any actual program42 // execution by the routeConfiguringFunction, which is necessarily run as43 // the entrypoint for any Appium server44 this.basePath = DEFAULT_BASE_PATH;45 // initialize security modes46 this.relaxedSecurityEnabled = false;47 this.allowInsecure = [];48 this.denyInsecure = [];49 // timeout initialization50 this.newCommandTimeoutMs = NEW_COMMAND_TIMEOUT_MS;51 this.implicitWaitMs = 0;52 this._constraints = _.cloneDeep(desiredCapabilityConstraints);53 this.locatorStrategies = [];54 this.webLocatorStrategies = [];55 // use a custom tmp dir to avoid losing data and app when computer is56 // restarted57 this.opts.tmpDir = this.opts.tmpDir ||58 process.env.APPIUM_TMP_DIR ||59 os.tmpdir();60 // base-driver internals61 this.shutdownUnexpectedly = false;62 this.noCommandTimer = null;63 this.shouldValidateCaps = shouldValidateCaps;64 this.commandsQueueGuard = new AsyncLock();65 // settings should be instantiated by drivers which extend BaseDriver, but66 // we set it to an empty DeviceSettings instance here to make sure that the67 // default settings are applied even if an extending driver doesn't utilize68 // the settings functionality itself69 this.settings = new DeviceSettings({}, _.noop);70 // keeping track of initial opts71 this.initialOpts = _.cloneDeep(this.opts);72 // allow subclasses to have internal drivers73 this.managedDrivers = [];74 // store event timings75 this._eventHistory = {76 commands: [] // commands get a special place77 };78 // cache the image elements79 this._imgElCache = makeImageElementCache();80 // used to handle driver events81 this.eventEmitter = new EventEmitter();82 this.protocol = null;83 }84 /**85 * Set a callback handler if needed to execute a custom piece of code86 * when the driver is shut down unexpectedly. Multiple calls to this method87 * will cause the handler to be executed mutiple times88 *89 * @param {Function} handler The code to be executed on unexpected shutdown.90 * The function may accept one argument, which is the actual error instance, which91 * caused the driver to shut down.92 */93 onUnexpectedShutdown (handler) {94 this.eventEmitter.on(ON_UNEXPECTED_SHUTDOWN_EVENT, handler);95 }96 /**97 * This property is used by AppiumDriver to store the data of the98 * specific driver sessions. This data can be later used to adjust99 * properties for driver instances running in parallel.100 * Override it in inherited driver classes if necessary.101 *102 * @return {object} Driver properties mapping103 */104 get driverData () {105 return {};106 }107 /**108 * This property controls the way {#executeCommand} method109 * handles new driver commands received from the client.110 * Override it for inherited classes only in special cases.111 *112 * @return {boolean} If the returned value is true (default) then all the commands113 * received by the particular driver instance are going to be put into the queue,114 * so each following command will not be executed until the previous command115 * execution is completed. False value disables that queue, so each driver command116 * is executed independently and does not wait for anything.117 */118 get isCommandsQueueEnabled () {119 return true;120 }121 /*122 * make eventHistory a property and return a cloned object so a consumer can't123 * inadvertently change data outside of logEvent124 */125 get eventHistory () {126 return _.cloneDeep(this._eventHistory);127 }128 /*129 * API method for driver developers to log timings for important events130 */131 logEvent (eventName) {132 if (eventName === 'commands') {133 throw new Error('Cannot log commands directly');134 }135 if (typeof eventName !== 'string') {136 throw new Error(`Invalid eventName ${eventName}`);137 }138 if (!this._eventHistory[eventName]) {139 this._eventHistory[eventName] = [];140 }141 const ts = Date.now();142 const logTime = (new Date(ts)).toTimeString();143 this._eventHistory[eventName].push(ts);144 log.debug(`Event '${eventName}' logged at ${ts} (${logTime})`);145 }146 /*147 * Overridden in appium driver, but here so that individual drivers can be148 * tested with clients that poll149 */150 async getStatus () { // eslint-disable-line require-await151 return {};152 }153 // we only want subclasses to ever extend the contraints154 set desiredCapConstraints (constraints) {155 this._constraints = Object.assign(this._constraints, constraints);156 // 'presence' means different things in different versions of the validator,157 // when we say 'true' we mean that it should not be able to be empty158 for (const [, value] of _.toPairs(this._constraints)) {159 if (value && value.presence === true) {160 value.presence = {161 allowEmpty: false,162 };163 }164 }165 }166 get desiredCapConstraints () {167 return this._constraints;168 }169 // method required by MJSONWP in order to determine whether it should170 // respond with an invalid session response171 sessionExists (sessionId) {172 if (!sessionId) return false; // eslint-disable-line curly173 return sessionId === this.sessionId;174 }175 // method required by MJSONWP in order to determine if the command should176 // be proxied directly to the driver177 driverForSession (/*sessionId*/) {178 return this;179 }180 logExtraCaps (caps) {181 let extraCaps = _.difference(_.keys(caps),182 _.keys(this._constraints));183 if (extraCaps.length) {184 log.warn(`The following capabilities were provided, but are not ` +185 `recognized by Appium:`);186 for (const cap of extraCaps) {187 log.warn(` ${cap}`);188 }189 }190 }191 validateDesiredCaps (caps) {192 if (!this.shouldValidateCaps) {193 return true;194 }195 try {196 validateCaps(caps, this._constraints);197 } catch (e) {198 log.errorAndThrow(new errors.SessionNotCreatedError(`The desiredCapabilities object was not valid for the ` +199 `following reason(s): ${e.message}`));200 }201 this.logExtraCaps(caps);202 return true;203 }204 isMjsonwpProtocol () {205 return this.protocol === PROTOCOLS.MJSONWP;206 }207 isW3CProtocol () {208 return this.protocol === PROTOCOLS.W3C;209 }210 setProtocolMJSONWP () {211 this.protocol = PROTOCOLS.MJSONWP;212 }213 setProtocolW3C () {214 this.protocol = PROTOCOLS.W3C;215 }216 /**217 * Check whether a given feature is enabled via its name218 *219 * @param {string} name - name of feature/command220 *221 * @returns {Boolean}222 */223 isFeatureEnabled (name) {224 // if we have explicitly denied this feature, return false immediately225 if (this.denyInsecure && _.includes(this.denyInsecure, name)) {226 return false;227 }228 // if we specifically have allowed the feature, return true229 if (this.allowInsecure && _.includes(this.allowInsecure, name)) {230 return true;231 }232 // otherwise, if we've globally allowed insecure features and not denied233 // this one, return true234 if (this.relaxedSecurityEnabled) {235 return true;236 }237 // if we haven't allowed anything insecure, then reject238 return false;239 }240 /**241 * Assert that a given feature is enabled and throw a helpful error if it's242 * not243 *244 * @param {string} name - name of feature/command245 */246 ensureFeatureEnabled (name) {247 if (!this.isFeatureEnabled(name)) {248 throw new Error(`Potentially insecure feature '${name}' has not been ` +249 `enabled. If you want to enable this feature and accept ` +250 `the security ramifications, please do so by following ` +251 `the documented instructions at https://github.com/appium` +252 `/appium/blob/master/docs/en/writing-running-appium/security.md`);253 }254 }255 // This is the main command handler for the driver. It wraps command256 // execution with timeout logic, checking that we have a valid session,257 // and ensuring that we execute commands one at a time. This method is called258 // by MJSONWP's express router.259 async executeCommand (cmd, ...args) {260 // get start time for this command, and log in special cases261 let startTime = Date.now();262 if (cmd === 'createSession') {263 // If creating a session determine if W3C or MJSONWP protocol was requested and remember the choice264 this.protocol = determineProtocol(...args);265 this.logEvent(EVENT_SESSION_INIT);266 } else if (cmd === 'deleteSession') {267 this.logEvent(EVENT_SESSION_QUIT_START);268 }269 // if we had a command timer running, clear it now that we're starting270 // a new command and so don't want to time out271 this.clearNewCommandTimeout();272 if (this.shutdownUnexpectedly) {273 throw new errors.NoSuchDriverError('The driver was unexpectedly shut down!');274 }275 // If we don't have this command, it must not be implemented276 // If the target element is ImageElement, we must try to call `ImageElement.execute` which exist following lines277 // since ImageElement supports few commands by itself278 const imgElId = getImgElFromArgs(args);279 if (!this[cmd] && !imgElId) {280 throw new errors.NotYetImplementedError();281 }282 let unexpectedShutdownListener;283 const commandExecutor = async () => imgElId284 ? await ImageElement.execute(this, cmd, imgElId, ...args)285 : await B.race([286 this[cmd](...args),287 new B((resolve, reject) => {288 unexpectedShutdownListener = reject;289 this.eventEmitter.on(ON_UNEXPECTED_SHUTDOWN_EVENT, unexpectedShutdownListener);290 })291 ]).finally(() => {292 if (unexpectedShutdownListener) {293 // This is needed to prevent memory leaks294 this.eventEmitter.removeListener(ON_UNEXPECTED_SHUTDOWN_EVENT, unexpectedShutdownListener);295 unexpectedShutdownListener = null;296 }297 });298 const res = this.isCommandsQueueEnabled && cmd !== 'executeDriverScript'299 ? await this.commandsQueueGuard.acquire(BaseDriver.name, commandExecutor)300 : await commandExecutor();301 // if we have set a new command timeout (which is the default), start a302 // timer once we've finished executing this command. If we don't clear303 // the timer (which is done when a new command comes in), we will trigger304 // automatic session deletion in this.onCommandTimeout. Of course we don't305 // want to trigger the timer when the user is shutting down the session306 // intentionally307 if (this.isCommandsQueueEnabled && cmd !== 'deleteSession') {308 // resetting existing timeout309 this.startNewCommandTimeout();310 }311 // log timing information about this command312 const endTime = Date.now();313 this._eventHistory.commands.push({cmd, startTime, endTime});314 if (cmd === 'createSession') {315 this.logEvent(EVENT_SESSION_START);316 } else if (cmd === 'deleteSession') {317 this.logEvent(EVENT_SESSION_QUIT_DONE);318 }319 return res;320 }321 async startUnexpectedShutdown (err = new errors.NoSuchDriverError('The driver was unexpectedly shut down!')) {322 this.eventEmitter.emit(ON_UNEXPECTED_SHUTDOWN_EVENT, err); // allow others to listen for this323 this.shutdownUnexpectedly = true;324 try {325 await this.deleteSession(this.sessionId);326 } finally {327 this.shutdownUnexpectedly = false;328 }329 }330 validateLocatorStrategy (strategy, webContext = false) {331 let validStrategies = this.locatorStrategies;332 log.debug(`Valid locator strategies for this request: ${validStrategies.join(', ')}`);333 if (webContext) {334 validStrategies = validStrategies.concat(this.webLocatorStrategies);335 }336 if (!_.includes(validStrategies, strategy)) {337 throw new errors.InvalidSelectorError(`Locator Strategy '${strategy}' is not supported for this session`);338 }339 }340 /*341 * Restart the session with the original caps,342 * preserving the timeout config.343 */344 async reset () {345 log.debug('Resetting app mid-session');346 log.debug('Running generic full reset');347 // preserving state348 let currentConfig = {};349 for (let property of ['implicitWaitMs', 'newCommandTimeoutMs', 'sessionId', 'resetOnUnexpectedShutdown']) {350 currentConfig[property] = this[property];351 }352 // We also need to preserve the unexpected shutdown, and make sure it is not cancelled during reset.353 this.resetOnUnexpectedShutdown = () => {};354 // Construct the arguments for createSession depending on the protocol type355 const args = this.protocol === PROTOCOLS.W3C ?356 [undefined, undefined, {alwaysMatch: this.caps, firstMatch: [{}]}] :357 [this.caps];358 try {359 await this.deleteSession(this.sessionId);360 log.debug('Restarting app');361 await this.createSession(...args);362 } finally {363 // always restore state.364 for (let [key, value] of _.toPairs(currentConfig)) {365 this[key] = value;366 }367 }368 this.clearNewCommandTimeout();369 }370 proxyActive (/* sessionId */) {371 return false;372 }373 getProxyAvoidList (/* sessionId */) {374 return [];375 }376 canProxy (/* sessionId */) {377 return false;378 }379 /**380 * Whether a given command route (expressed as method and url) should not be381 * proxied according to this driver382 *383 * @param {string} sessionId - the current sessionId (in case the driver runs384 * multiple session ids and requires it). This is not used in this method but385 * should be made available to overridden methods.386 * @param {string} method - HTTP method of the route387 * @param {string} url - url of the route388 *389 * @returns {boolean} - whether the route should be avoided390 */391 proxyRouteIsAvoided (sessionId, method, url) {392 for (let avoidSchema of this.getProxyAvoidList(sessionId)) {393 if (!_.isArray(avoidSchema) || avoidSchema.length !== 2) {394 throw new Error('Proxy avoidance must be a list of pairs');395 }396 let [avoidMethod, avoidPathRegex] = avoidSchema;397 if (!_.includes(['GET', 'POST', 'DELETE'], avoidMethod)) {398 throw new Error(`Unrecognized proxy avoidance method '${avoidMethod}'`);399 }400 if (!_.isRegExp(avoidPathRegex)) {401 throw new Error('Proxy avoidance path must be a regular expression');402 }403 let normalizedUrl = url.replace(new RegExp(`^${_.escapeRegExp(this.basePath)}`), '');404 if (avoidMethod === method && avoidPathRegex.test(normalizedUrl)) {405 return true;406 }407 }408 return false;409 }410 addManagedDriver (driver) {411 this.managedDrivers.push(driver);412 }413 getManagedDrivers () {414 return this.managedDrivers;415 }416 registerImageElement (imgEl) {417 this._imgElCache.set(imgEl.id, imgEl);418 const protoKey = this.isW3CProtocol() ? W3C_ELEMENT_KEY : MJSONWP_ELEMENT_KEY;419 return imgEl.asElement(protoKey);420 }421}422for (let [cmd, fn] of _.toPairs(commands)) {423 BaseDriver.prototype[cmd] = fn;424}425export { BaseDriver };...

Full Screen

Full Screen

context-specs.js

Source:context-specs.js Github

copy

Full Screen

1import chai from 'chai';2import chaiAsPromised from 'chai-as-promised';3import sinon from 'sinon';4import { default as webviewHelpers,5 NATIVE_WIN, WEBVIEW_BASE, WEBVIEW_WIN, CHROMIUM_WIN } from '../../../lib/webview-helpers';6import { setupNewChromedriver } from '../../../lib/commands/context';7import AndroidDriver from '../../..';8import Chromedriver from 'appium-chromedriver';9import PortFinder from 'portfinder';10import { errors } from 'appium-base-driver';11let driver;12let stubbedChromedriver;13let sandbox = sinon.createSandbox();14let expect = chai.expect;15chai.should();16chai.use(chaiAsPromised);17describe('Context', function () {18 beforeEach(function () {19 sandbox.stub(PortFinder, 'getPort').callsFake(function (cb) { // eslint-disable-line promise/prefer-await-to-callbacks20 return cb(null, 4444); // eslint-disable-line promise/prefer-await-to-callbacks21 });22 driver = new AndroidDriver();23 driver.adb = sandbox.stub();24 driver.adb.curDeviceId = 'device_id';25 driver.adb.getAdbServerPort = sandbox.stub().returns(5555);26 sandbox.stub(Chromedriver.prototype, 'restart');27 sandbox.stub(Chromedriver.prototype, 'start');28 sandbox.stub(Chromedriver.prototype.proxyReq, 'bind').returns('proxy');29 stubbedChromedriver = sinon.stub();30 stubbedChromedriver.proxyReq = sinon.stub();31 stubbedChromedriver.proxyReq.bind = sinon.stub();32 stubbedChromedriver.restart = sinon.stub();33 stubbedChromedriver.stop = sandbox.stub().throws();34 stubbedChromedriver.removeAllListeners = sandbox.stub();35 });36 afterEach(function () {37 sandbox.restore();38 });39 describe('getCurrentContext', function () {40 it('should return current context', async function () {41 driver.curContext = 'current_context';42 await driver.getCurrentContext().should.become('current_context');43 });44 it('should return NATIVE_APP if no context is set', async function () {45 driver.curContext = null;46 await driver.getCurrentContext().should.become(NATIVE_WIN);47 });48 });49 describe('getContexts', function () {50 it('should get Chromium context where appropriate', async function () {51 driver = new AndroidDriver({browserName: 'Chrome'});52 expect(await driver.getContexts()).to.include(CHROMIUM_WIN);53 });54 it('should use ADB to figure out which webviews are available', async function () {55 sandbox.stub(webviewHelpers, 'getWebviews');56 expect(await driver.getContexts()).to.not.include(CHROMIUM_WIN);57 webviewHelpers.getWebviews.calledOnce.should.be.true;58 });59 });60 describe('setContext', function () {61 beforeEach(function () {62 sandbox.stub(driver, 'getContexts').returns(['DEFAULT', 'WV', 'ANOTHER']);63 sandbox.stub(driver, 'switchContext');64 });65 it('should switch to default context if name is null', async function () {66 sandbox.stub(driver, 'defaultContextName').returns('DEFAULT');67 await driver.setContext(null);68 driver.switchContext.calledWithExactly('DEFAULT').should.be.true;69 driver.curContext.should.be.equal('DEFAULT');70 });71 it('should switch to default web view if name is WEBVIEW', async function () {72 sandbox.stub(driver, 'defaultWebviewName').returns('WV');73 await driver.setContext(WEBVIEW_WIN);74 driver.switchContext.calledWithExactly('WV').should.be.true;75 driver.curContext.should.be.equal('WV');76 });77 it('should throw error if context does not exist', async function () {78 await driver.setContext('fake')79 .should.be.rejectedWith(errors.NoSuchContextError);80 });81 it('should not switch to context if already in it', async function () {82 driver.curContext = 'ANOTHER';83 await driver.setContext('ANOTHER');84 driver.switchContext.notCalled.should.be.true;85 });86 });87 describe('switchContext', function () {88 beforeEach(function () {89 sandbox.stub(driver, 'stopChromedriverProxies');90 sandbox.stub(driver, 'startChromedriverProxy');91 sandbox.stub(driver, 'suspendChromedriverProxy');92 sandbox.stub(driver, 'isChromedriverContext');93 driver.curContext = 'current_cntx';94 });95 it('should start chrome driver proxy if requested context is webview', async function () {96 driver.isChromedriverContext.returns(true);97 await driver.switchContext('context');98 driver.startChromedriverProxy.calledWithExactly('context').should.be.true;99 });100 it('should stop chromedriver proxy if current context is webview and requested context is not', async function () {101 driver.opts = {recreateChromeDriverSessions: true};102 driver.isChromedriverContext.withArgs('requested_cntx').returns(false);103 driver.isChromedriverContext.withArgs('current_cntx').returns(true);104 await driver.switchContext('requested_cntx');105 driver.stopChromedriverProxies.calledOnce.should.be.true;106 });107 it('should suspend chrome driver proxy if current context is webview and requested context is not', async function () {108 driver.opts = {recreateChromeDriverSessions: false};109 driver.isChromedriverContext.withArgs('requested_cntx').returns(false);110 driver.isChromedriverContext.withArgs('current_cntx').returns(true);111 await driver.switchContext('requested_cntx');112 driver.suspendChromedriverProxy.calledOnce.should.be.true;113 });114 it('should throw error if requested and current context are not webview', async function () {115 driver.isChromedriverContext.withArgs('requested_cntx').returns(false);116 driver.isChromedriverContext.withArgs('current_cntx').returns(false);117 await driver.switchContext('requested_cntx')118 .should.be.rejectedWith(/switching to context/);119 });120 });121 describe('defaultContextName', function () {122 it('should return NATIVE_WIN', async function () {123 await driver.defaultContextName().should.be.equal(NATIVE_WIN);124 });125 });126 describe('defaultWebviewName', function () {127 it('should return WEBVIEW with package', async function () {128 driver.opts = {appPackage: 'pkg'};129 await driver.defaultWebviewName().should.be.equal(WEBVIEW_BASE + 'pkg');130 });131 });132 describe('isWebContext', function () {133 it('should return true if current context is not native', async function () {134 driver.curContext = 'current_context';135 await driver.isWebContext().should.be.true;136 });137 });138 describe('startChromedriverProxy', function () {139 beforeEach(function () {140 sandbox.stub(driver, 'onChromedriverStop');141 });142 it('should start new chromedriver session', async function () {143 await driver.startChromedriverProxy('WEBVIEW_1');144 driver.sessionChromedrivers.WEBVIEW_1.should.be.equal(driver.chromedriver);145 driver.chromedriver.start.getCall(0).args[0]146 .chromeOptions.androidDeviceSerial.should.be.equal('device_id');147 driver.chromedriver.proxyPort.should.be.equal(4444);148 driver.chromedriver.proxyReq.bind.calledWithExactly(driver.chromedriver);149 driver.proxyReqRes.should.be.equal('proxy');150 driver.jwpProxyActive.should.be.true;151 });152 it('should be able to extract package from context name', async function () {153 driver.opts.appPackage = 'pkg';154 driver.opts.extractChromeAndroidPackageFromContextName = true;155 await driver.startChromedriverProxy('WEBVIEW_com.pkg');156 driver.chromedriver.start.getCall(0).args[0]157 .chromeOptions.should.be.deep.include({androidPackage: 'com.pkg'});158 });159 it('should use package from opts if package extracted from context is empty', async function () {160 driver.opts.appPackage = 'pkg';161 driver.opts.extractChromeAndroidPackageFromContextName = true;162 await driver.startChromedriverProxy('WEBVIEW_');163 driver.chromedriver.start.getCall(0).args[0]164 .chromeOptions.should.be.deep.include({androidPackage: 'pkg'});165 });166 it('should handle chromedriver event with STATE_STOPPED state', async function () {167 await driver.startChromedriverProxy('WEBVIEW_1');168 await driver.chromedriver.emit(Chromedriver.EVENT_CHANGED,169 {state: Chromedriver.STATE_STOPPED});170 driver.onChromedriverStop.calledWithExactly('WEBVIEW_1').should.be.true;171 });172 it('should ignore events if status is not STATE_STOPPED', async function () {173 await driver.startChromedriverProxy('WEBVIEW_1');174 await driver.chromedriver.emit(Chromedriver.EVENT_CHANGED,175 {state: 'unhandled_state'});176 driver.onChromedriverStop.notCalled.should.be.true;177 });178 it('should reconnect if session already exists', async function () {179 stubbedChromedriver.hasWorkingWebview = sinon.stub().returns(true);180 driver.sessionChromedrivers = {WEBVIEW_1: stubbedChromedriver};181 await driver.startChromedriverProxy('WEBVIEW_1');182 driver.chromedriver.restart.notCalled.should.be.true;183 driver.chromedriver.should.be.equal(stubbedChromedriver);184 });185 it('should restart if chromedriver has not working web view', async function () {186 stubbedChromedriver.hasWorkingWebview = sinon.stub().returns(false);187 driver.sessionChromedrivers = {WEBVIEW_1: stubbedChromedriver};188 await driver.startChromedriverProxy('WEBVIEW_1');189 driver.chromedriver.restart.calledOnce.should.be.true;190 });191 });192 describe('suspendChromedriverProxy', function () {193 it('should suspend chrome driver proxy', async function () {194 await driver.suspendChromedriverProxy();195 (driver.chromedriver == null).should.be.true;196 (driver.proxyReqRes == null).should.be.true;197 driver.jwpProxyActive.should.be.false;198 });199 });200 describe('onChromedriverStop', function () {201 it('should call startUnexpectedShutdown if chromedriver in active context', async function () {202 sinon.stub(driver, 'startUnexpectedShutdown');203 driver.curContext = 'WEBVIEW_1';204 await driver.onChromedriverStop('WEBVIEW_1');205 let arg0 = driver.startUnexpectedShutdown.getCall(0).args[0];206 arg0.should.be.an('error');207 arg0.message.should.include('Chromedriver quit unexpectedly during session');208 });209 it('should delete session if chromedriver in non-active context', async function () {210 driver.curContext = 'WEBVIEW_1';211 driver.sessionChromedrivers = {WEBVIEW_2: 'CHROMIUM'};212 await driver.onChromedriverStop('WEBVIEW_2');213 driver.sessionChromedrivers.should.be.empty;214 });215 });216 describe('stopChromedriverProxies', function () {217 it('should stop all chromedriver', async function () {218 driver.sessionChromedrivers = {WEBVIEW_1: stubbedChromedriver, WEBVIEW_2: stubbedChromedriver};219 sandbox.stub(driver, 'suspendChromedriverProxy');220 await driver.stopChromedriverProxies();221 driver.suspendChromedriverProxy.calledOnce.should.be.true;222 stubbedChromedriver.removeAllListeners223 .calledWithExactly(Chromedriver.EVENT_CHANGED).should.be.true;224 stubbedChromedriver.removeAllListeners.calledTwice.should.be.true;225 stubbedChromedriver.stop.calledTwice.should.be.true;226 driver.sessionChromedrivers.should.be.empty;227 });228 });229 describe('isChromedriverContext', function () {230 it('should return true if context is webview or chromium', async function () {231 await driver.isChromedriverContext(WEBVIEW_WIN + '_1').should.be.true;232 await driver.isChromedriverContext(CHROMIUM_WIN).should.be.true;233 });234 });235 describe('setupNewChromedriver', function () {236 it('should be able to set app package from chrome options', async function () {237 let chromedriver = await setupNewChromedriver({chromeOptions: {androidPackage: 'apkg'}});238 chromedriver.start.getCall(0).args[0].chromeOptions.androidPackage239 .should.be.equal('apkg');240 });241 it('should use prefixed chromeOptions', async function () {242 let chromedriver = await setupNewChromedriver({243 'goog:chromeOptions': {244 androidPackage: 'apkg',245 },246 });247 chromedriver.start.getCall(0).args[0].chromeOptions.androidPackage248 .should.be.equal('apkg');249 });250 it('should merge chromeOptions', async function () {251 let chromedriver = await setupNewChromedriver({252 chromeOptions: {253 androidPackage: 'apkg',254 },255 'goog:chromeOptions': {256 androidWaitPackage: 'bpkg',257 },258 'appium:chromeOptions': {259 androidActivity: 'aact',260 },261 });262 chromedriver.start.getCall(0).args[0].chromeOptions.androidPackage263 .should.be.equal('apkg');264 chromedriver.start.getCall(0).args[0].chromeOptions.androidActivity265 .should.be.equal('aact');266 chromedriver.start.getCall(0).args[0].chromeOptions.androidWaitPackage267 .should.be.equal('bpkg');268 });269 it('should be able to set androidActivity chrome option', async function () {270 let chromedriver = await setupNewChromedriver({chromeAndroidActivity: 'act'});271 chromedriver.start.getCall(0).args[0].chromeOptions.androidActivity272 .should.be.equal('act');273 });274 it('should be able to set androidProcess chrome option', async function () {275 let chromedriver = await setupNewChromedriver({chromeAndroidProcess: 'proc'});276 chromedriver.start.getCall(0).args[0].chromeOptions.androidProcess277 .should.be.equal('proc');278 });279 it('should be able to set loggingPrefs capability', async function () {280 let chromedriver = await setupNewChromedriver({enablePerformanceLogging: true});281 chromedriver.start.getCall(0).args[0].loggingPrefs282 .should.deep.equal({performance: 'ALL'});283 });284 it('should set androidActivity to appActivity if browser name is chromium-webview', async function () {285 let chromedriver = await setupNewChromedriver({browserName: 'chromium-webview',286 appActivity: 'app_act'});287 chromedriver.start.getCall(0).args[0].chromeOptions.androidActivity288 .should.be.equal('app_act');289 });290 it('should be able to set loggingPrefs capability', async function () {291 let chromedriver = await setupNewChromedriver({pageLoadStrategy: 'strategy'});292 chromedriver.start.getCall(0).args[0].pageLoadStrategy293 .should.be.equal('strategy');294 });295 });...

Full Screen

Full Screen

context.js

Source:context.js Github

copy

Full Screen

...131 if (context === this.curContext) {132 // we exited unexpectedly while automating the current context and so want133 // to shut down the session and respond with an error134 let err = new Error("Chromedriver quit unexpectedly during session");135 await this.startUnexpectedShutdown(err);136 } else {137 // if a Chromedriver in the non-active context barfs, we don't really138 // care, we'll just make a new one next time we need the context.139 logger.warn("Chromedriver quit unexpectedly, but it wasn't the active " +140 "context, ignoring");141 delete this.sessionChromedrivers[context];142 }143};144// Intentionally stop all the chromedrivers currently active, and ignore145// their exit events146helpers.stopChromedriverProxies = async function () {147 this.suspendChromedriverProxy(); // make sure we turn off the proxy flag148 for (let context of _.keys(this.sessionChromedrivers)) {149 let cd = this.sessionChromedrivers[context];...

Full Screen

Full Screen

driver-e2e-tests.js

Source:driver-e2e-tests.js Github

copy

Full Screen

...191 simple: false192 });193 // make sure that the request gets to the server before our shutdown194 await B.delay(100);195 d.startUnexpectedShutdown(new Error('Crashytimes'));196 let res = await p;197 res.status.should.equal(13);198 res.value.message.should.contain('Crashytimes');199 await d.onUnexpectedShutdown.should.be.rejectedWith('Crashytimes');200 });201 });202 describe('event timings', function () {203 it('should not add timings if not using opt-in cap', async function () {204 let session = await startSession(defaultCaps);205 let res = await getSession(session.sessionId);206 should.not.exist(res.events);207 await endSession(session.sessionId);208 });209 it('should add start session timings', async function () {...

Full Screen

Full Screen

proxy-helper.js

Source:proxy-helper.js Github

copy

Full Screen

...32 });33 if (isCommandExpired) {34 proxy.cancelActiveRequests();35 const errMsg = `Appium did not get any response from "${cmdName}" command in ${timeout} ms`;36 await this.startUnexpectedShutdown(new errors.TimeoutError(errMsg));37 log.errorAndThrow(errMsg);38 }39 } else {40 res = await proxy.command(endpoint, method, body);41 }42 // temporarily handle errors that can be returned43 if (res && res.status && parseInt(res.status, 10) !== 0) {44 throw errorFromCode(res.status, res.value);45 }46 return res;47};48Object.assign(extensions, helpers);49export { helpers };50export default extensions;

Full Screen

Full Screen

timeout.js

Source:timeout.js Github

copy

Full Screen

...28 this.noCommandTimer29 .then(async () => { // eslint-disable-line promise/prefer-await-to-then30 log.warn(`Shutting down because we waited ` +31 `${this.newCommandTimeoutMs / 1000} seconds for a command`);32 await this.startUnexpectedShutdown(new Error(`Command ${cmd} timed out!`));33 })34 .catch(B.CancellationError, (/*err*/) => {35 // ignore36 });37};38Object.assign(extensions, commands, helpers);39export { commands, helpers };...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1const BaseDriver = require('appium-base-driver').BaseDriver;2BaseDriver.prototype.startUnexpectedShutdown = function (err) {3 console.log('Unexpected Shutdown');4};5const BaseDriver = require('appium-base-driver').BaseDriver;6BaseDriver.prototype.stopUnexpectedShutdown = function () {7 console.log('Unexpected Shutdown Stopped');8};

Full Screen

Using AI Code Generation

copy

Full Screen

1import { startUnexpectedShutdown } from 'appium-base-driver/lib/mjsonwp/mjsonwp';2startUnexpectedShutdown();3import { startUnexpectedShutdown } from 'appium-base-driver/lib/mjsonwp/mjsonwp';4startUnexpectedShutdown();5function startUnexpectedShutdown() {6 process.emit('SIGTERM');7}8process.on('SIGTERM', () => {9 logger.info('Shutting down due to unexpected shutdown');10 gracefulShutdown();11});12function gracefulShutdown() {13 server.close();14 process.exit(0);15}16process.on('SIGTERM', () => {17 logger.info('Shutting down due to unexpected shutdown');18 gracefulShutdown();19});20function gracefulShutdown() {21 server.close();22 process.exit(0);23}24process.on('SIGTERM', () => {25 logger.info('Shutting down due to unexpected shutdown');26 gracefulShutdown();27});28function gracefulShutdown() {29 server.close();30 process.exit(0);31}32process.on('SIGTERM', () => {33 logger.info('Shutting down due to unexpected shutdown');34 gracefulShutdown();35});36function gracefulShutdown() {37 server.close();38 process.exit(0);39}40process.on('SIGTERM', () => {41 logger.info('Shutting down due to unexpected shutdown');42 gracefulShutdown();43});44function gracefulShutdown() {45 server.close();

Full Screen

Using AI Code Generation

copy

Full Screen

1const { startUnexpectedShutdown } = require('appium-base-driver').BaseDriver;2startUnexpectedShutdown('Unexpected shutdown happened');3const { startUnexpectedShutdown } = require('appium').Driver;4startUnexpectedShutdown('Unexpected shutdown happened');5const { startUnexpectedShutdown } = require('appium-android-driver').AndroidDriver;6startUnexpectedShutdown('Unexpected shutdown happened');7const { startUnexpectedShutdown } = require('appium-ios-driver').IOSDriver;8startUnexpectedShutdown('Unexpected shutdown happened');9const { startUnexpectedShutdown } = require('appium-windows-driver').WindowsDriver;10startUnexpectedShutdown('Unexpected shutdown happened');11const { startUnexpectedShutdown } = require('appium-mac-driver').MacDriver;12startUnexpectedShutdown('Unexpected shutdown happened');13const { startUnexpectedShutdown } = require('appium-fake-driver').FakeDriver;14startUnexpectedShutdown('Unexpected shutdown happened');15const { startUnexpectedShutdown } = require('appium-youiengine-driver').YouiEngineDriver;16startUnexpectedShutdown('Unexpected shutdown happened');17const { startUnexpectedShutdown } = require('appium-espresso-driver').EspressoDriver;18startUnexpectedShutdown('Unexpected shutdown happened');19const { startUnexpectedShutdown } = require('appium-xcuitest-driver').XCUITestDriver;20startUnexpectedShutdown('Unexpected shutdown happened');21const { startUnexpectedShutdown } = require('appium-webdriveragent-driver').WebDriverAgentDriver;22startUnexpectedShutdown('Unexpected shutdown happened');23const { startUnexpectedShutdown } = require('appium-uiautomator2-driver').UiAutomator2Driver;24startUnexpectedShutdown('Unexpected shutdown happened');25const { startUnexpectedShutdown

Full Screen

Using AI Code Generation

copy

Full Screen

1var AppiumBaseDriver = require('appium-base-driver').AppiumBaseDriver;2var appiumBaseDriver = new AppiumBaseDriver();3appiumBaseDriver.startUnexpectedShutdown(new Error('Unexpected error'));4var AppiumBaseDriver = require('appium-base-driver').AppiumBaseDriver;5var appiumBaseDriver = new AppiumBaseDriver();6appiumBaseDriver.restart();7var AppiumBaseDriver = require('appium-base-driver').AppiumBaseDriver;8var appiumBaseDriver = new AppiumBaseDriver();9appiumBaseDriver.getStatus();10var AppiumBaseDriver = require('appium-base-driver').AppiumBaseDriver;11var appiumBaseDriver = new AppiumBaseDriver();12appiumBaseDriver.getSession();13var AppiumBaseDriver = require('appium-base-driver').AppiumBaseDriver;14var appiumBaseDriver = new AppiumBaseDriver();15appiumBaseDriver.getContexts();16var AppiumBaseDriver = require('appium-base-driver').AppiumBaseDriver;17var appiumBaseDriver = new AppiumBaseDriver();18appiumBaseDriver.getCurrentContext();19var AppiumBaseDriver = require('appium-base-driver').AppiumBaseDriver;

Full Screen

Using AI Code Generation

copy

Full Screen

1var AppiumBaseDriver = require('appium-base-driver');2AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {3};4var AppiumBaseDriver = require('appium-base-driver');5AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {6};7var AppiumBaseDriver = require('appium-base-driver');8AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {9};10var AppiumBaseDriver = require('appium-base-driver');11AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {12};13var AppiumBaseDriver = require('appium-base-driver');14AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {15};16var AppiumBaseDriver = require('appium-base-driver');17AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {18};19var AppiumBaseDriver = require('appium-base-driver');20AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {21};22var AppiumBaseDriver = require('appium-base-driver');23AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {24};25var AppiumBaseDriver = require('appium-base-driver');26AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {27};28var AppiumBaseDriver = require('appium-base-driver');29AppiumBaseDriver.prototype.startUnexpectedShutdown = function (err) {30};

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run Appium Base Driver automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful