@appium/fake-driver 5.1.5 → 5.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/build/lib/commands/alert.d.ts +12 -77
- package/build/lib/commands/alert.d.ts.map +1 -1
- package/build/lib/commands/alert.js +3 -23
- package/build/lib/commands/alert.js.map +1 -1
- package/build/lib/commands/contexts.d.ts +12 -81
- package/build/lib/commands/contexts.d.ts.map +1 -1
- package/build/lib/commands/contexts.js +8 -28
- package/build/lib/commands/contexts.js.map +1 -1
- package/build/lib/commands/element.d.ts +25 -145
- package/build/lib/commands/element.d.ts.map +1 -1
- package/build/lib/commands/element.js +24 -76
- package/build/lib/commands/element.js.map +1 -1
- package/build/lib/commands/find.d.ts +16 -84
- package/build/lib/commands/find.d.ts.map +1 -1
- package/build/lib/commands/find.js +21 -45
- package/build/lib/commands/find.js.map +1 -1
- package/build/lib/commands/general.d.ts +25 -173
- package/build/lib/commands/general.d.ts.map +1 -1
- package/build/lib/commands/general.js +3 -61
- package/build/lib/commands/general.js.map +1 -1
- package/build/lib/commands/index.d.ts +13 -5
- package/build/lib/commands/index.d.ts.map +1 -1
- package/build/lib/commands/index.js +26 -13
- package/build/lib/commands/index.js.map +1 -1
- package/build/lib/commands/mixin.d.ts +11 -0
- package/build/lib/commands/mixin.d.ts.map +1 -0
- package/build/lib/commands/mixin.js +17 -0
- package/build/lib/commands/mixin.js.map +1 -0
- package/build/lib/driver.d.ts +38 -93
- package/build/lib/driver.d.ts.map +1 -1
- package/build/lib/driver.js +27 -74
- package/build/lib/driver.js.map +1 -1
- package/build/lib/fake-app.d.ts +9 -7
- package/build/lib/fake-app.d.ts.map +1 -1
- package/build/lib/fake-app.js +2 -0
- package/build/lib/fake-app.js.map +1 -1
- package/build/lib/fake-element.d.ts +12 -4
- package/build/lib/fake-element.d.ts.map +1 -1
- package/build/lib/fake-element.js +11 -4
- package/build/lib/fake-element.js.map +1 -1
- package/build/lib/scripts/fake-error.d.ts +1 -0
- package/build/lib/scripts/fake-error.js +11 -1
- package/build/lib/scripts/fake-error.js.map +1 -1
- package/build/lib/scripts/fake-stdin.d.ts +2 -0
- package/build/lib/scripts/fake-stdin.d.ts.map +1 -0
- package/build/lib/scripts/fake-stdin.js +13 -0
- package/build/lib/scripts/fake-stdin.js.map +1 -0
- package/build/lib/types.d.ts +2 -2
- package/build/lib/types.d.ts.map +1 -1
- package/lib/commands/alert.ts +70 -0
- package/lib/commands/{contexts.js → contexts.ts} +26 -34
- package/lib/commands/element.ts +138 -0
- package/lib/commands/find.ts +137 -0
- package/lib/commands/general.ts +115 -0
- package/lib/commands/{index.js → index.ts} +14 -5
- package/lib/commands/mixin.ts +13 -0
- package/lib/driver.js +43 -79
- package/lib/fake-app.js +3 -3
- package/lib/fake-element.js +21 -6
- package/lib/scripts/fake-error.js +8 -1
- package/lib/scripts/fake-stdin.js +9 -0
- package/package.json +4 -3
- package/lib/commands/alert.js +0 -73
- package/lib/commands/element.js +0 -161
- package/lib/commands/find.js +0 -118
- package/lib/commands/general.js +0 -147
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import {Element} from '@appium/types';
|
|
3
|
+
import {errors} from 'appium/driver';
|
|
4
|
+
import {FakeElement} from '../fake-element';
|
|
5
|
+
import {FakeDriver} from '../driver';
|
|
6
|
+
import {util} from '@appium/support';
|
|
7
|
+
import {mixin} from './mixin';
|
|
8
|
+
|
|
9
|
+
const {W3C_WEB_ELEMENT_IDENTIFIER} = util;
|
|
10
|
+
interface FakeDriverFindMixin {
|
|
11
|
+
getExistingElementForNode(node: FakeElement): string | null;
|
|
12
|
+
wrapNewEl(obj: FakeElement): Element;
|
|
13
|
+
|
|
14
|
+
findElOrEls<Many extends boolean, Ctx = any>(
|
|
15
|
+
this: FakeDriver,
|
|
16
|
+
strategy: string,
|
|
17
|
+
selector: string,
|
|
18
|
+
many: Many,
|
|
19
|
+
context?: Ctx
|
|
20
|
+
): Promise<Many extends true ? Element[] : Element>;
|
|
21
|
+
findElement(strategy: string, selector: string): Promise<Element>;
|
|
22
|
+
findElements(strategy: string, selector: string): Promise<Element[]>;
|
|
23
|
+
findElementFromElement(elementId: string, strategy: string, selector: string): Promise<Element>;
|
|
24
|
+
findElementsFromElement(
|
|
25
|
+
elementId: string,
|
|
26
|
+
strategy: string,
|
|
27
|
+
selector: string
|
|
28
|
+
): Promise<Element[]>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare module '../driver' {
|
|
32
|
+
interface FakeDriver extends FakeDriverFindMixin {}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const FindMixin: FakeDriverFindMixin = {
|
|
36
|
+
getExistingElementForNode(this: FakeDriver, node) {
|
|
37
|
+
for (const [id, el] of _.toPairs(this.elMap)) {
|
|
38
|
+
if (el.node === node) {
|
|
39
|
+
return id;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
wrapNewEl(this: FakeDriver, obj: FakeElement): Element {
|
|
46
|
+
// first check and see if we already have a ref to this element
|
|
47
|
+
const existingElId = this.getExistingElementForNode(obj);
|
|
48
|
+
if (existingElId) {
|
|
49
|
+
return {ELEMENT: existingElId, [W3C_WEB_ELEMENT_IDENTIFIER]: existingElId};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// otherwise add the element to the map
|
|
53
|
+
this.maxElId++;
|
|
54
|
+
const maxElId = this.maxElId.toString();
|
|
55
|
+
this.elMap[maxElId] = new FakeElement(obj, this.appModel);
|
|
56
|
+
return {ELEMENT: maxElId, [W3C_WEB_ELEMENT_IDENTIFIER]: maxElId};
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
async findElOrEls<Many extends boolean, Ctx = any>(
|
|
60
|
+
this: FakeDriver,
|
|
61
|
+
strategy: string,
|
|
62
|
+
selector: string,
|
|
63
|
+
many: Many,
|
|
64
|
+
context: Ctx
|
|
65
|
+
): Promise<Many extends true ? Element[] : Element> {
|
|
66
|
+
const qMap = {
|
|
67
|
+
xpath: 'xpathQuery',
|
|
68
|
+
id: 'idQuery',
|
|
69
|
+
'accessibility id': 'idQuery',
|
|
70
|
+
'class name': 'classQuery',
|
|
71
|
+
'tag name': 'classQuery',
|
|
72
|
+
'css selector': 'cssQuery',
|
|
73
|
+
} as Record<string, keyof FakeDriver['appModel']>;
|
|
74
|
+
// TODO this error checking should probably be part of MJSONWP?
|
|
75
|
+
if (!_.includes(_.keys(qMap), strategy)) {
|
|
76
|
+
throw new errors.UnknownCommandError();
|
|
77
|
+
}
|
|
78
|
+
if (selector === 'badsel') {
|
|
79
|
+
throw new errors.InvalidSelectorError();
|
|
80
|
+
}
|
|
81
|
+
const els = this.appModel[qMap[strategy]](selector, context);
|
|
82
|
+
|
|
83
|
+
let retval: Element | Element[];
|
|
84
|
+
if (els.length) {
|
|
85
|
+
if (many) {
|
|
86
|
+
const allEls: Element[] = [];
|
|
87
|
+
for (const el of els) {
|
|
88
|
+
allEls.push(this.wrapNewEl(el));
|
|
89
|
+
}
|
|
90
|
+
retval = allEls;
|
|
91
|
+
} else {
|
|
92
|
+
retval = this.wrapNewEl(els[0]);
|
|
93
|
+
}
|
|
94
|
+
} else if (many) {
|
|
95
|
+
retval = [];
|
|
96
|
+
} else {
|
|
97
|
+
throw new errors.NoSuchElementError();
|
|
98
|
+
}
|
|
99
|
+
return retval as Many extends true ? Element[] : Element;
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* This should override whatever's in ExternalDriver
|
|
104
|
+
* @param {string} strategy Strategy
|
|
105
|
+
* @param {string} selector Selector
|
|
106
|
+
* @this {FakeDriver}
|
|
107
|
+
*/
|
|
108
|
+
async findElement(this: FakeDriver, strategy: string, selector: string) {
|
|
109
|
+
return this.findElOrEls(strategy, selector, false);
|
|
110
|
+
},
|
|
111
|
+
|
|
112
|
+
async findElements(this: FakeDriver, strategy: string, selector: string) {
|
|
113
|
+
return this.findElOrEls(strategy, selector, true);
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
async findElementFromElement(
|
|
117
|
+
this: FakeDriver,
|
|
118
|
+
strategy: string,
|
|
119
|
+
selector: string,
|
|
120
|
+
elementId: string
|
|
121
|
+
) {
|
|
122
|
+
const el = this.getElement(elementId);
|
|
123
|
+
return this.findElOrEls(strategy, selector, false, el.xmlFragment);
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
async findElementsFromElement(
|
|
127
|
+
this: FakeDriver,
|
|
128
|
+
strategy: string,
|
|
129
|
+
selector: string,
|
|
130
|
+
elementId: string
|
|
131
|
+
) {
|
|
132
|
+
const el = this.getElement(elementId);
|
|
133
|
+
return this.findElOrEls(strategy, selector, true, el.xmlFragment);
|
|
134
|
+
},
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
mixin(FindMixin);
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import {ActionSequence, Location, Rect, Size} from '@appium/types';
|
|
2
|
+
import {errors} from 'appium/driver';
|
|
3
|
+
import {FakeDriver, Orientation} from '../driver';
|
|
4
|
+
import {mixin} from './mixin';
|
|
5
|
+
|
|
6
|
+
const ORIENTATIONS = new Set(['LANDSCAPE', 'PORTRAIT']);
|
|
7
|
+
|
|
8
|
+
interface FakeDriverGeneralMixin {
|
|
9
|
+
title(): Promise<string>;
|
|
10
|
+
keys(value: string | string[]): Promise<void>;
|
|
11
|
+
setGeoLocation(location: Location): Promise<void>;
|
|
12
|
+
getGeoLocation(): Promise<Location>;
|
|
13
|
+
getPageSource(): Promise<string>;
|
|
14
|
+
getOrientation(): Promise<string>;
|
|
15
|
+
setOrientation(orientation: Orientation): Promise<void>;
|
|
16
|
+
getScreenshot(): Promise<string>;
|
|
17
|
+
getWindowSize(): Promise<Size>;
|
|
18
|
+
getWindowRect(): Promise<Rect>;
|
|
19
|
+
performActions(actions: ActionSequence[]): Promise<void>;
|
|
20
|
+
releaseActions(): Promise<void>;
|
|
21
|
+
mobileShake(): Promise<void>;
|
|
22
|
+
doubleClick(): Promise<void>;
|
|
23
|
+
execute(script: string, args: any[]): Promise<any>;
|
|
24
|
+
fakeAddition(a: number, b: number, c?: number): Promise<number>;
|
|
25
|
+
getLog(type: string): Promise<any[]>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare module '../driver' {
|
|
29
|
+
interface FakeDriver extends FakeDriverGeneralMixin {}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const GeneralMixin: FakeDriverGeneralMixin = {
|
|
33
|
+
async title(this: FakeDriver) {
|
|
34
|
+
this.assertWebviewContext();
|
|
35
|
+
return this.appModel.title;
|
|
36
|
+
},
|
|
37
|
+
|
|
38
|
+
async keys(this: FakeDriver, value: string | string[]) {
|
|
39
|
+
if (!this.focusedElId) {
|
|
40
|
+
throw new errors.InvalidElementStateError();
|
|
41
|
+
}
|
|
42
|
+
await this.setValue(value, this.focusedElId);
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
async setGeoLocation(this: FakeDriver, location: Location) {
|
|
46
|
+
// TODO test this adequately once WD bug is fixed
|
|
47
|
+
this.appModel.lat = location.latitude;
|
|
48
|
+
this.appModel.long = location.longitude;
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async getGeoLocation(this: FakeDriver) {
|
|
52
|
+
return this.appModel.currentGeoLocation;
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
async getPageSource(this: FakeDriver) {
|
|
56
|
+
return this.appModel.rawXml;
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
async getOrientation(this: FakeDriver) {
|
|
60
|
+
return this.appModel.orientation;
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
async setOrientation(this: FakeDriver, o: Orientation) {
|
|
64
|
+
if (!ORIENTATIONS.has(o)) {
|
|
65
|
+
throw new errors.UnknownError('Orientation must be LANDSCAPE or PORTRAIT');
|
|
66
|
+
}
|
|
67
|
+
this.appModel.orientation = o;
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
async getScreenshot(this: FakeDriver) {
|
|
71
|
+
return this.appModel.getScreenshot();
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
async getWindowSize(this: FakeDriver) {
|
|
75
|
+
return {width: this.appModel.width, height: this.appModel.height};
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
async getWindowRect(this: FakeDriver) {
|
|
79
|
+
return {width: this.appModel.width, height: this.appModel.height, x: 0, y: 0};
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
async performActions(this: FakeDriver, actions: ActionSequence[]) {
|
|
83
|
+
this.appModel.actionLog.push(actions);
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
async releaseActions(this: FakeDriver) {},
|
|
87
|
+
|
|
88
|
+
async getLog(this: FakeDriver, type: string): Promise<ActionSequence[][]> {
|
|
89
|
+
switch (type) {
|
|
90
|
+
case 'actions':
|
|
91
|
+
return this.appModel.actionLog;
|
|
92
|
+
default:
|
|
93
|
+
throw new Error(`Don't understand log type '${type}'`);
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
async mobileShake(this: FakeDriver) {
|
|
98
|
+
this.shook = true;
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
async doubleClick(this: FakeDriver) {},
|
|
102
|
+
|
|
103
|
+
async execute(this: FakeDriver, script: string, args: any[]) {
|
|
104
|
+
return await this.executeMethod(script, args);
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Add two or maybe even three numbers
|
|
109
|
+
*/
|
|
110
|
+
async fakeAddition(this: FakeDriver, num1: number, num2: number, num3 = 0) {
|
|
111
|
+
return num1 + num2 + (num3 ?? 0);
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
mixin(GeneralMixin);
|
|
@@ -1,8 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Export all of the "stuff" from these mixin files. The mixins themselves are not exported,
|
|
3
|
+
* but any types/interfaces that they export (e.g., options objects for some command) are exported.
|
|
4
|
+
*
|
|
5
|
+
* Mixins must not use `Object.assign()` and are expected to use the `mixin` function in the sibling
|
|
6
|
+
* `mixin` module.
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export * from './alert';
|
|
11
|
+
export * from './contexts';
|
|
12
|
+
export * from './element';
|
|
13
|
+
export * from './find';
|
|
14
|
+
export * from './general';
|
|
6
15
|
|
|
7
16
|
/* // TODO:
|
|
8
17
|
//rest.post('/wd/hub/session/:sessionId?/touch/click', controller.doClick);
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {FakeDriver} from '../driver';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This function assigns a mixin `T` to the `FakeDriver` class' prototype.
|
|
5
|
+
* While each mixin has its own interface which is (in isolation) unrelated to `FakeDriver`, the constraint
|
|
6
|
+
* on this generic type `T` is that it must be a partial of `FakeDriver`'s interface. This enforces
|
|
7
|
+
* that it does not conflict with the existing interface of `FakeDriver`. In that way, you can
|
|
8
|
+
* think of it as a type guard.
|
|
9
|
+
* @param mixin Mixin implementation
|
|
10
|
+
*/
|
|
11
|
+
export function mixin<T extends Partial<FakeDriver>>(mixin: T): void {
|
|
12
|
+
Object.assign(FakeDriver.prototype, mixin);
|
|
13
|
+
}
|
package/lib/driver.js
CHANGED
|
@@ -2,7 +2,6 @@ import B from 'bluebird';
|
|
|
2
2
|
import {BaseDriver, errors} from 'appium/driver';
|
|
3
3
|
import {deprecatedCommandsLogged} from '@appium/base-driver/build/lib/protocol/protocol';
|
|
4
4
|
import {FakeApp} from './fake-app';
|
|
5
|
-
import {alert, contexts, element, find, general} from './commands';
|
|
6
5
|
|
|
7
6
|
const FAKE_DRIVER_CONSTRAINTS = /** @type {const} */ ({
|
|
8
7
|
app: {
|
|
@@ -15,22 +14,50 @@ const FAKE_DRIVER_CONSTRAINTS = /** @type {const} */ ({
|
|
|
15
14
|
});
|
|
16
15
|
|
|
17
16
|
/**
|
|
17
|
+
* Constraints for {@linkcode FakeDriver}'s capabilites
|
|
18
18
|
* @typedef {typeof FAKE_DRIVER_CONSTRAINTS} FakeDriverConstraints
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
/**
|
|
22
|
+
* @template [Thing=any]
|
|
22
23
|
* @extends {BaseDriver<FakeDriverConstraints>}
|
|
23
24
|
* @implements {ExternalDriver<FakeDriverConstraints>}
|
|
24
25
|
*/
|
|
25
26
|
export class FakeDriver extends BaseDriver {
|
|
26
|
-
|
|
27
|
+
/**
|
|
28
|
+
* @type {FakeDriverConstraints}
|
|
29
|
+
* @readonly
|
|
30
|
+
*/
|
|
31
|
+
desiredCapConstraints;
|
|
27
32
|
|
|
28
33
|
/** @type {string} */
|
|
29
34
|
curContext;
|
|
30
35
|
|
|
31
|
-
|
|
36
|
+
/** @type {FakeApp} */
|
|
37
|
+
appModel;
|
|
38
|
+
|
|
39
|
+
/** @type {boolean} */
|
|
40
|
+
_proxyActive;
|
|
41
|
+
|
|
42
|
+
/** @type {boolean} */
|
|
43
|
+
shook;
|
|
44
|
+
|
|
45
|
+
/** @type {string?} */
|
|
46
|
+
focusedElId;
|
|
47
|
+
|
|
48
|
+
/** @type {Thing?} */
|
|
49
|
+
fakeThing;
|
|
50
|
+
|
|
51
|
+
/** @type {number} */
|
|
52
|
+
maxElId;
|
|
32
53
|
|
|
33
|
-
|
|
54
|
+
/** @type {Record<string,import('./fake-element').FakeElement>} */
|
|
55
|
+
elMap;
|
|
56
|
+
|
|
57
|
+
constructor(
|
|
58
|
+
opts = /** @type {import('@appium/types').DriverOpts<FakeDriverConstraints>} */ ({}),
|
|
59
|
+
shouldValidateCaps = true
|
|
60
|
+
) {
|
|
34
61
|
super(opts, shouldValidateCaps);
|
|
35
62
|
this.curContext = 'NATIVE_APP';
|
|
36
63
|
this.elMap = {};
|
|
@@ -39,6 +66,8 @@ export class FakeDriver extends BaseDriver {
|
|
|
39
66
|
this.fakeThing = null;
|
|
40
67
|
this._proxyActive = false;
|
|
41
68
|
this.shook = false;
|
|
69
|
+
this.appModel = new FakeApp();
|
|
70
|
+
this.desiredCapConstraints = FAKE_DRIVER_CONSTRAINTS;
|
|
42
71
|
}
|
|
43
72
|
|
|
44
73
|
proxyActive() {
|
|
@@ -73,7 +102,7 @@ export class FakeDriver extends BaseDriver {
|
|
|
73
102
|
* @param {W3CFakeDriverCaps} [w3cCapabilities3] W3C Capabilities
|
|
74
103
|
* @param {import('@appium/types').DriverData[]} [driverData] Other session data
|
|
75
104
|
* @override
|
|
76
|
-
* @returns {Promise<[string,FakeDriverCaps]>}
|
|
105
|
+
* @returns {Promise<[string,FakeDriverCaps]>}
|
|
77
106
|
*/
|
|
78
107
|
async createSession(w3cCapabilities1, w3cCapabilities2, w3cCapabilities3, driverData = []) {
|
|
79
108
|
// TODO add validation on caps.app that we will get for free from
|
|
@@ -112,7 +141,7 @@ export class FakeDriver extends BaseDriver {
|
|
|
112
141
|
/**
|
|
113
142
|
* Set the 'thing' value (so that it can be retrieved later)
|
|
114
143
|
*
|
|
115
|
-
* @param {
|
|
144
|
+
* @param {Thing} thing
|
|
116
145
|
* @returns {Promise<null>}
|
|
117
146
|
*/
|
|
118
147
|
async setFakeThing(thing) {
|
|
@@ -201,86 +230,17 @@ export class FakeDriver extends BaseDriver {
|
|
|
201
230
|
res.send(JSON.stringify(cliArgs));
|
|
202
231
|
});
|
|
203
232
|
}
|
|
204
|
-
|
|
205
|
-
/*********
|
|
206
|
-
* ALERT *
|
|
207
|
-
*********/
|
|
208
|
-
assertNoAlert = alert.assertNoAlert;
|
|
209
|
-
assertAlert = alert.assertAlert;
|
|
210
|
-
getAlertText = alert.getAlertText;
|
|
211
|
-
setAlertText = alert.setAlertText;
|
|
212
|
-
postAcceptAlert = alert.postAcceptAlert;
|
|
213
|
-
postDismissAlert = alert.postDismissAlert;
|
|
214
|
-
|
|
215
|
-
/************
|
|
216
|
-
* CONTEXTS *
|
|
217
|
-
************/
|
|
218
|
-
getRawContexts = contexts.getRawContexts;
|
|
219
|
-
assertWebviewContext = contexts.assertWebviewContext;
|
|
220
|
-
getCurrentContext = contexts.getCurrentContext;
|
|
221
|
-
getContexts = contexts.getContexts;
|
|
222
|
-
setContext = contexts.setContext;
|
|
223
|
-
setFrame = contexts.setFrame;
|
|
224
|
-
|
|
225
|
-
/************
|
|
226
|
-
* ELEMENTS *
|
|
227
|
-
************/
|
|
228
|
-
getElements = element.getElements;
|
|
229
|
-
getElement = element.getElement;
|
|
230
|
-
getName = element.getName;
|
|
231
|
-
elementDisplayed = element.elementDisplayed;
|
|
232
|
-
elementEnabled = element.elementEnabled;
|
|
233
|
-
elementSelected = element.elementSelected;
|
|
234
|
-
setValue = element.setValue;
|
|
235
|
-
getText = element.getText;
|
|
236
|
-
clear = element.clear;
|
|
237
|
-
click = element.click;
|
|
238
|
-
getAttribute = element.getAttribute;
|
|
239
|
-
getElementRect = element.getElementRect;
|
|
240
|
-
getSize = element.getSize;
|
|
241
|
-
equalsElement = element.equalsElement;
|
|
242
|
-
getCssProperty = element.getCssProperty;
|
|
243
|
-
getLocation = element.getLocation;
|
|
244
|
-
getLocationInView = element.getLocationInView;
|
|
245
|
-
|
|
246
|
-
/********
|
|
247
|
-
* FIND *
|
|
248
|
-
********/
|
|
249
|
-
getExistingElementForNode = find.getExistingElementForNode;
|
|
250
|
-
wrapNewEl = find.wrapNewEl;
|
|
251
|
-
findElOrEls = find.findElOrEls;
|
|
252
|
-
findElement = find.findElement;
|
|
253
|
-
findElements = find.findElements;
|
|
254
|
-
findElementFromElement = find.findElementFromElement;
|
|
255
|
-
findElementsFromElement = find.findElementsFromElement;
|
|
256
|
-
|
|
257
|
-
/***********
|
|
258
|
-
* GENERAL *
|
|
259
|
-
***********/
|
|
260
|
-
title = general.title;
|
|
261
|
-
keys = general.keys;
|
|
262
|
-
setGeoLocation = general.setGeoLocation;
|
|
263
|
-
getGeoLocation = general.getGeoLocation;
|
|
264
|
-
getPageSource = general.getPageSource;
|
|
265
|
-
getOrientation = general.getOrientation;
|
|
266
|
-
setOrientation = general.setOrientation;
|
|
267
|
-
getScreenshot = general.getScreenshot;
|
|
268
|
-
getWindowSize = general.getWindowSize;
|
|
269
|
-
getWindowRect = general.getWindowRect;
|
|
270
|
-
performActions = general.performActions;
|
|
271
|
-
getLog = general.getLog;
|
|
272
|
-
mobileShake = general.mobileShake;
|
|
273
|
-
doubleClick = general.doubleClick;
|
|
274
|
-
execute = general.execute;
|
|
275
|
-
fakeAddition = general.fakeAddition;
|
|
276
|
-
releaseActions = general.releaseActions;
|
|
277
233
|
}
|
|
278
234
|
|
|
235
|
+
// eslint-disable-next-line import/no-unresolved
|
|
236
|
+
export * from './commands';
|
|
237
|
+
|
|
279
238
|
export default FakeDriver;
|
|
280
239
|
|
|
281
240
|
/**
|
|
282
241
|
* @typedef {import('./types').FakeDriverCaps} FakeDriverCaps
|
|
283
242
|
* @typedef {import('./types').W3CFakeDriverCaps} W3CFakeDriverCaps
|
|
243
|
+
* @typedef {import('@appium/types').Element} Element
|
|
284
244
|
*/
|
|
285
245
|
|
|
286
246
|
/**
|
|
@@ -292,3 +252,7 @@ export default FakeDriver;
|
|
|
292
252
|
* @template {import('@appium/types').Constraints} C
|
|
293
253
|
* @typedef {import('@appium/types').ExternalDriver<C>} ExternalDriver
|
|
294
254
|
*/
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @typedef {import('@appium/types').Orientation} Orientation
|
|
258
|
+
*/
|
package/lib/fake-app.js
CHANGED
|
@@ -8,7 +8,7 @@ import {FakeElement} from './fake-element';
|
|
|
8
8
|
|
|
9
9
|
const SCREENSHOT = path.join(__dirname, 'screen.png');
|
|
10
10
|
|
|
11
|
-
class FakeApp {
|
|
11
|
+
export class FakeApp {
|
|
12
12
|
constructor() {
|
|
13
13
|
this.dom = null;
|
|
14
14
|
this.activeDom = null;
|
|
@@ -20,7 +20,9 @@ class FakeApp {
|
|
|
20
20
|
this._width = null;
|
|
21
21
|
this._height = null;
|
|
22
22
|
this.rawXml = '';
|
|
23
|
+
/** @type {import('./driver').Orientation} */
|
|
23
24
|
this.currentOrientation = 'PORTRAIT';
|
|
25
|
+
/** @type {import('@appium/types').ActionSequence[][]} */
|
|
24
26
|
this.actionLog = [];
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -176,8 +178,6 @@ class FakeWebView {
|
|
|
176
178
|
}
|
|
177
179
|
}
|
|
178
180
|
|
|
179
|
-
export {FakeApp};
|
|
180
|
-
|
|
181
181
|
/**
|
|
182
182
|
* @typedef {Element & {data: any}} ElementWithData
|
|
183
183
|
*/
|
package/lib/fake-element.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import XMLDom from '@xmldom/xmldom';
|
|
3
3
|
|
|
4
|
-
class FakeElement {
|
|
4
|
+
export class FakeElement {
|
|
5
|
+
/** @type {FakeApp} */
|
|
6
|
+
app;
|
|
7
|
+
|
|
8
|
+
/** @type {string} */
|
|
9
|
+
type;
|
|
10
|
+
|
|
11
|
+
/** @type {Record<string,string>} */
|
|
12
|
+
nodeAttrs;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* @param {any} xmlNode
|
|
16
|
+
* @param {FakeApp} app
|
|
17
|
+
*/
|
|
5
18
|
constructor(xmlNode, app) {
|
|
6
19
|
this.app = app;
|
|
7
20
|
this.node = xmlNode;
|
|
@@ -53,8 +66,8 @@ class FakeElement {
|
|
|
53
66
|
|
|
54
67
|
getLocation() {
|
|
55
68
|
return {
|
|
56
|
-
x: parseFloat(this.nodeAttrs.left || 0),
|
|
57
|
-
y: parseFloat(this.nodeAttrs.top || 0),
|
|
69
|
+
x: parseFloat(this.nodeAttrs.left || '0'),
|
|
70
|
+
y: parseFloat(this.nodeAttrs.top || '0'),
|
|
58
71
|
};
|
|
59
72
|
}
|
|
60
73
|
|
|
@@ -64,8 +77,8 @@ class FakeElement {
|
|
|
64
77
|
|
|
65
78
|
getSize() {
|
|
66
79
|
return {
|
|
67
|
-
width: parseFloat(this.nodeAttrs.width || 0),
|
|
68
|
-
height: parseFloat(this.nodeAttrs.height || 0),
|
|
80
|
+
width: parseFloat(this.nodeAttrs.width || '0'),
|
|
81
|
+
height: parseFloat(this.nodeAttrs.height || '0'),
|
|
69
82
|
};
|
|
70
83
|
}
|
|
71
84
|
|
|
@@ -99,4 +112,6 @@ class FakeElement {
|
|
|
99
112
|
}
|
|
100
113
|
}
|
|
101
114
|
|
|
102
|
-
|
|
115
|
+
/**
|
|
116
|
+
* @typedef {import('./fake-app').FakeApp} FakeApp
|
|
117
|
+
*/
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import readline from 'node:readline';
|
|
2
|
+
|
|
3
|
+
const rl = readline.createInterface({input: process.stdin, output: process.stderr});
|
|
4
|
+
|
|
5
|
+
rl.question('Press ENTER to continue: ', () => {
|
|
6
|
+
rl.close();
|
|
7
|
+
// eslint-disable-next-line no-console
|
|
8
|
+
console.error('You did it!');
|
|
9
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appium/fake-driver",
|
|
3
|
-
"version": "5.1
|
|
3
|
+
"version": "5.2.1",
|
|
4
4
|
"description": "Mock driver used internally by Appium for testing. Ignore",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -75,12 +75,13 @@
|
|
|
75
75
|
"schema": "./build/lib/fake-driver-schema.js",
|
|
76
76
|
"scripts": {
|
|
77
77
|
"fake-error": "./build/lib/scripts/fake-error.js",
|
|
78
|
-
"fake-success": "./build/lib/scripts/fake-success.js"
|
|
78
|
+
"fake-success": "./build/lib/scripts/fake-success.js",
|
|
79
|
+
"fake-stdin": "./build/lib/scripts/fake-stdin.js"
|
|
79
80
|
}
|
|
80
81
|
},
|
|
81
82
|
"typedoc": {
|
|
82
83
|
"entryPoint": "./lib/index.js"
|
|
83
84
|
},
|
|
84
85
|
"types": "./build/lib/index.d.ts",
|
|
85
|
-
"gitHead": "
|
|
86
|
+
"gitHead": "872b924a97c13142bdb8bf4218a4db324f309ce4"
|
|
86
87
|
}
|
package/lib/commands/alert.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import {errors} from 'appium/driver';
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
/**
|
|
5
|
-
* @this {FakeDriver}
|
|
6
|
-
*/
|
|
7
|
-
assertNoAlert() {
|
|
8
|
-
if (this.appModel.hasAlert()) {
|
|
9
|
-
throw new errors.UnexpectedAlertOpenError();
|
|
10
|
-
}
|
|
11
|
-
},
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* @this {FakeDriver}
|
|
15
|
-
*/
|
|
16
|
-
assertAlert() {
|
|
17
|
-
if (!this.appModel.hasAlert()) {
|
|
18
|
-
throw new errors.NoAlertOpenError();
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Get the text of an alert
|
|
24
|
-
*
|
|
25
|
-
* @returns {Promise<string>}
|
|
26
|
-
* @this {FakeDriver}
|
|
27
|
-
*/
|
|
28
|
-
async getAlertText() {
|
|
29
|
-
this.assertAlert();
|
|
30
|
-
return this.appModel.alertText();
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Set the text of an alert
|
|
35
|
-
*
|
|
36
|
-
* @param {string} text
|
|
37
|
-
* @returns {Promise<void>}
|
|
38
|
-
* @this {FakeDriver}
|
|
39
|
-
*/
|
|
40
|
-
async setAlertText(text) {
|
|
41
|
-
this.assertAlert();
|
|
42
|
-
try {
|
|
43
|
-
this.appModel.setAlertText(text);
|
|
44
|
-
} catch (e) {
|
|
45
|
-
throw new errors.InvalidElementStateError();
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Accept an alert
|
|
51
|
-
*
|
|
52
|
-
* @returns {Promise<void>}
|
|
53
|
-
* @this {FakeDriver}
|
|
54
|
-
*/
|
|
55
|
-
async postAcceptAlert() {
|
|
56
|
-
this.assertAlert();
|
|
57
|
-
this.appModel.handleAlert();
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Dismiss an alert
|
|
62
|
-
*
|
|
63
|
-
* @returns {Promise<void>}
|
|
64
|
-
* @this {FakeDriver}
|
|
65
|
-
*/
|
|
66
|
-
async postDismissAlert() {
|
|
67
|
-
return this.postAcceptAlert();
|
|
68
|
-
},
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @typedef {import('../driver').FakeDriver} FakeDriver
|
|
73
|
-
*/
|