This repository has been archived by the owner on Oct 25, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 130
/
timeout.js
168 lines (143 loc) · 5.44 KB
/
timeout.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import log from '../logger';
import { waitForCondition } from 'asyncbox';
import _ from 'lodash';
import { util } from 'appium-support';
import { errors } from '../../protocol';
let commands = {}, helpers = {}, extensions = {};
const MIN_TIMEOUT = 0;
commands.timeouts = async function timeouts (type, ms, script, pageLoad, implicit) {
if (util.hasValue(type) && util.hasValue(ms)) {
log.debug(`MJSONWP timeout arguments: ${JSON.stringify({type, ms})}}`);
switch (type) {
case 'command':
await this.newCommandTimeout(ms);
return;
case 'implicit':
await this.implicitWaitMJSONWP(ms);
return;
case 'page load':
await this.pageLoadTimeoutMJSONWP(ms);
return;
case 'script':
await this.scriptTimeoutMJSONWP(ms);
return;
default:
throw new Error(`'${type}' type is not supported for MJSONWP timeout`);
}
}
// Otherwise assume it is W3C protocol
log.debug(`W3C timeout argument: ${JSON.stringify({script, pageLoad, implicit})}}`);
if (util.hasValue(script)) {
await this.scriptTimeoutW3C(script);
}
if (util.hasValue(pageLoad)) {
await this.pageLoadTimeoutW3C(pageLoad);
}
if (util.hasValue(implicit)) {
await this.implicitWaitW3C(implicit);
}
};
commands.getTimeouts = async function getTimeouts () { // eslint-disable-line require-await
return {
command: this.newCommandTimeoutMs,
implicit: this.implicitWaitMs,
};
};
// implicit
commands.implicitWaitW3C = async function implicitWaitW3C (ms) {
await this.implicitWait(ms);
};
commands.implicitWaitMJSONWP = async function implicitWaitMJSONWP (ms) {
await this.implicitWait(ms);
};
commands.implicitWait = async function implicitWait (ms) {
await this.setImplicitWait(this.parseTimeoutArgument(ms));
};
helpers.setImplicitWait = function setImplicitWait (ms) { // eslint-disable-line require-await
this.implicitWaitMs = ms;
log.debug(`Set implicit wait to ${ms}ms`);
if (this.managedDrivers && this.managedDrivers.length) {
log.debug('Setting implicit wait on managed drivers');
for (let driver of this.managedDrivers) {
if (_.isFunction(driver.setImplicitWait)) {
driver.setImplicitWait(ms);
}
}
}
};
// pageLoad
// eslint-disable-next-line no-unused-vars
commands.pageLoadTimeoutW3C = async function pageLoadTimeoutW3C (ms) { // eslint-disable-line require-await
throw new errors.NotImplementedError('Not implemented yet for pageLoad.');
};
// eslint-disable-next-line no-unused-vars
commands.pageLoadTimeoutMJSONWP = async function pageLoadTimeoutMJSONWP (ms) { // eslint-disable-line require-await
throw new errors.NotImplementedError('Not implemented yet for pageLoad.');
};
// script
// eslint-disable-next-line no-unused-vars
commands.scriptTimeoutW3C = async function scriptTimeoutW3C (ms) { // eslint-disable-line require-await
throw new errors.NotImplementedError('Not implemented yet for script.');
};
// eslint-disable-next-line no-unused-vars
commands.scriptTimeoutMJSONWP = async function scriptTimeoutMJSONWP (ms) { // eslint-disable-line require-await
throw new errors.NotImplementedError('Not implemented yet for script.');
};
// command
commands.newCommandTimeout = async function newCommandTimeout (ms) { // eslint-disable-line require-await
this.setNewCommandTimeout(this.parseTimeoutArgument(ms));
};
helpers.setNewCommandTimeout = function setNewCommandTimeout (ms) {
this.newCommandTimeoutMs = ms;
log.debug(`Set new command timeout to ${ms}ms`);
if (this.managedDrivers && this.managedDrivers.length) {
log.debug('Setting new command timeout on managed drivers');
for (let driver of this.managedDrivers) {
if (_.isFunction(driver.setNewCommandTimeout)) {
driver.setNewCommandTimeout(ms);
}
}
}
};
helpers.clearNewCommandTimeout = function clearNewCommandTimeout () {
if (this.noCommandTimer) {
clearTimeout(this.noCommandTimer);
this.noCommandTimer = null;
}
};
helpers.startNewCommandTimeout = function startNewCommandTimeout () {
// make sure there are no rogue timeouts
this.clearNewCommandTimeout();
// if command timeout is 0, it is disabled
if (!this.newCommandTimeoutMs) return; // eslint-disable-line curly
this.noCommandTimer = setTimeout(async () => {
log.warn(`Shutting down because we waited ` +
`${this.newCommandTimeoutMs / 1000.0} seconds for a command`);
const errorMessage = `New Command Timeout of ` +
`${this.newCommandTimeoutMs / 1000.0} seconds ` +
`expired. Try customizing the timeout using the ` +
`'newCommandTimeout' desired capability`;
await this.startUnexpectedShutdown(new Error(errorMessage));
}, this.newCommandTimeoutMs);
};
helpers.implicitWaitForCondition = async function implicitWaitForCondition (condFn) {
log.debug(`Waiting up to ${this.implicitWaitMs} ms for condition`);
let wrappedCondFn = async (...args) => {
// reset command timeout
this.clearNewCommandTimeout();
return await condFn(...args);
};
return await waitForCondition(wrappedCondFn, {
waitMs: this.implicitWaitMs, intervalMs: 500, logger: log
});
};
helpers.parseTimeoutArgument = function parseTimeoutArgument (ms) {
let duration = parseInt(ms, 10);
if (_.isNaN(duration) || duration < MIN_TIMEOUT) {
throw new errors.UnknownError(`Invalid timeout value '${ms}'`);
}
return duration;
};
Object.assign(extensions, commands, helpers);
export { commands, helpers };
export default extensions;