@appium/base-driver
Version:
Base driver class for Appium drivers
133 lines (117 loc) • 4.5 kB
text/typescript
import {waitForCondition} from 'asyncbox';
import _ from 'lodash';
import {util} from '@appium/support';
import {errors} from '../../protocol';
import type {BaseDriver} from '../driver';
import type {Constraints, ITimeoutCommands} from '@appium/types';
import {mixin} from './mixin';
declare module '../driver' {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface BaseDriver<C extends Constraints> extends ITimeoutCommands {}
}
const MIN_TIMEOUT = 0;
const TimeoutCommands: ITimeoutCommands = {
async timeouts<C extends Constraints>(this: BaseDriver<C>, type, ms, script, pageLoad, implicit) {
if (type && _.isString(type) && util.hasValue(ms)) {
// legacy stuff with some Appium-specific additions
this.log.debug(`Timeout arguments: ${JSON.stringify({type, ms})}}`);
switch (type) {
case 'command':
return void (await this.newCommandTimeout(ms));
case 'implicit':
return void (await this.implicitWaitW3C(ms));
case 'page load':
return void (await this.pageLoadTimeoutW3C(ms));
case 'script':
return void (await this.scriptTimeoutW3C(ms));
default:
throw new Error(`'${type}' type is not supported for the timeout API`);
}
}
this.log.debug(`W3C timeout argument: ${JSON.stringify({script, pageLoad, implicit})}}`);
if ([script, pageLoad, implicit].every(_.isNil)) {
throw new errors.InvalidArgumentError('W3C protocol expects any of script, pageLoad or implicit to be set');
}
if (util.hasValue(script)) {
await this.scriptTimeoutW3C(script);
}
if (util.hasValue(pageLoad)) {
await this.pageLoadTimeoutW3C(pageLoad);
}
if (util.hasValue(implicit)) {
await this.implicitWaitW3C(implicit);
}
},
async getTimeouts() {
return {
command: this.newCommandTimeoutMs,
implicit: this.implicitWaitMs,
};
},
// implicit
async implicitWaitW3C<C extends Constraints>(this: BaseDriver<C>, ms: number) {
this.setImplicitWait(this.parseTimeoutArgument(ms));
},
// pageLoad
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async pageLoadTimeoutW3C<C extends Constraints>(this: BaseDriver<C>, ms: number) {
throw new errors.NotImplementedError('Not implemented yet for pageLoad.');
},
// script
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async scriptTimeoutW3C<C extends Constraints>(this: BaseDriver<C>, ms: number) {
throw new errors.NotImplementedError('Not implemented yet for script.');
},
// command
async newCommandTimeout<C extends Constraints>(this: BaseDriver<C>, ms: number) {
this.setNewCommandTimeout(this.parseTimeoutArgument(ms));
},
setImplicitWait<C extends Constraints>(this: BaseDriver<C>, ms: number) {
this.implicitWaitMs = ms;
this.log.debug(`Set implicit wait to ${ms}ms`);
if (this.managedDrivers?.length) {
this.log.debug('Setting implicit wait on managed drivers');
for (const driver of this.managedDrivers) {
if (_.isFunction(driver.setImplicitWait)) {
driver.setImplicitWait(ms);
}
}
}
},
setNewCommandTimeout<C extends Constraints>(this: BaseDriver<C>, ms: number) {
this.newCommandTimeoutMs = ms;
this.log.debug(`Set new command timeout to ${ms}ms`);
if (this.managedDrivers?.length) {
this.log.debug('Setting new command timeout on managed drivers');
for (const driver of this.managedDrivers) {
if (_.isFunction(driver.setNewCommandTimeout)) {
driver.setNewCommandTimeout(ms);
}
}
}
},
async implicitWaitForCondition<C extends Constraints>(
this: BaseDriver<C>,
condFn: (...args: any[]) => Promise<any>
) {
this.log.debug(`Waiting up to ${this.implicitWaitMs} ms for condition`);
const wrappedCondFn = async (...args: any[]) => {
// reset command timeout
await this.clearNewCommandTimeout();
return await condFn(...args);
};
return await waitForCondition(wrappedCondFn, {
waitMs: this.implicitWaitMs,
intervalMs: 500,
logger: this.log,
});
},
parseTimeoutArgument<C extends Constraints>(this: BaseDriver<C>, ms: number | string) {
const duration = parseInt(String(ms), 10);
if (_.isNaN(duration) || duration < MIN_TIMEOUT) {
throw new errors.UnknownError(`Invalid timeout value '${ms}'`);
}
return duration;
},
};
mixin(TimeoutCommands);