@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.
Files changed (67) hide show
  1. package/LICENSE +1 -1
  2. package/build/lib/commands/alert.d.ts +12 -77
  3. package/build/lib/commands/alert.d.ts.map +1 -1
  4. package/build/lib/commands/alert.js +3 -23
  5. package/build/lib/commands/alert.js.map +1 -1
  6. package/build/lib/commands/contexts.d.ts +12 -81
  7. package/build/lib/commands/contexts.d.ts.map +1 -1
  8. package/build/lib/commands/contexts.js +8 -28
  9. package/build/lib/commands/contexts.js.map +1 -1
  10. package/build/lib/commands/element.d.ts +25 -145
  11. package/build/lib/commands/element.d.ts.map +1 -1
  12. package/build/lib/commands/element.js +24 -76
  13. package/build/lib/commands/element.js.map +1 -1
  14. package/build/lib/commands/find.d.ts +16 -84
  15. package/build/lib/commands/find.d.ts.map +1 -1
  16. package/build/lib/commands/find.js +21 -45
  17. package/build/lib/commands/find.js.map +1 -1
  18. package/build/lib/commands/general.d.ts +25 -173
  19. package/build/lib/commands/general.d.ts.map +1 -1
  20. package/build/lib/commands/general.js +3 -61
  21. package/build/lib/commands/general.js.map +1 -1
  22. package/build/lib/commands/index.d.ts +13 -5
  23. package/build/lib/commands/index.d.ts.map +1 -1
  24. package/build/lib/commands/index.js +26 -13
  25. package/build/lib/commands/index.js.map +1 -1
  26. package/build/lib/commands/mixin.d.ts +11 -0
  27. package/build/lib/commands/mixin.d.ts.map +1 -0
  28. package/build/lib/commands/mixin.js +17 -0
  29. package/build/lib/commands/mixin.js.map +1 -0
  30. package/build/lib/driver.d.ts +38 -93
  31. package/build/lib/driver.d.ts.map +1 -1
  32. package/build/lib/driver.js +27 -74
  33. package/build/lib/driver.js.map +1 -1
  34. package/build/lib/fake-app.d.ts +9 -7
  35. package/build/lib/fake-app.d.ts.map +1 -1
  36. package/build/lib/fake-app.js +2 -0
  37. package/build/lib/fake-app.js.map +1 -1
  38. package/build/lib/fake-element.d.ts +12 -4
  39. package/build/lib/fake-element.d.ts.map +1 -1
  40. package/build/lib/fake-element.js +11 -4
  41. package/build/lib/fake-element.js.map +1 -1
  42. package/build/lib/scripts/fake-error.d.ts +1 -0
  43. package/build/lib/scripts/fake-error.js +11 -1
  44. package/build/lib/scripts/fake-error.js.map +1 -1
  45. package/build/lib/scripts/fake-stdin.d.ts +2 -0
  46. package/build/lib/scripts/fake-stdin.d.ts.map +1 -0
  47. package/build/lib/scripts/fake-stdin.js +13 -0
  48. package/build/lib/scripts/fake-stdin.js.map +1 -0
  49. package/build/lib/types.d.ts +2 -2
  50. package/build/lib/types.d.ts.map +1 -1
  51. package/lib/commands/alert.ts +70 -0
  52. package/lib/commands/{contexts.js → contexts.ts} +26 -34
  53. package/lib/commands/element.ts +138 -0
  54. package/lib/commands/find.ts +137 -0
  55. package/lib/commands/general.ts +115 -0
  56. package/lib/commands/{index.js → index.ts} +14 -5
  57. package/lib/commands/mixin.ts +13 -0
  58. package/lib/driver.js +43 -79
  59. package/lib/fake-app.js +3 -3
  60. package/lib/fake-element.js +21 -6
  61. package/lib/scripts/fake-error.js +8 -1
  62. package/lib/scripts/fake-stdin.js +9 -0
  63. package/package.json +4 -3
  64. package/lib/commands/alert.js +0 -73
  65. package/lib/commands/element.js +0 -161
  66. package/lib/commands/find.js +0 -118
  67. 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
- export {default as alert} from './alert';
2
- export {default as contexts} from './contexts';
3
- export {default as element} from './element';
4
- export {default as find} from './find';
5
- export {default as general} from './general';
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
- desiredCapConstraints = FAKE_DRIVER_CONSTRAINTS;
27
+ /**
28
+ * @type {FakeDriverConstraints}
29
+ * @readonly
30
+ */
31
+ desiredCapConstraints;
27
32
 
28
33
  /** @type {string} */
29
34
  curContext;
30
35
 
31
- appModel = new FakeApp();
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
- constructor(opts = {}, shouldValidateCaps = true) {
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]>} Session ID and normalized capabilities
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 {any} thing
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
  */
@@ -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
- export {FakeElement};
115
+ /**
116
+ * @typedef {import('./fake-app').FakeApp} FakeApp
117
+ */
@@ -1 +1,8 @@
1
- throw Error('Unsuccessfully ran the script');
1
+ import ora from 'ora';
2
+
3
+ const spinner = ora('Running fake-error...').start();
4
+
5
+ setTimeout(() => {
6
+ spinner.fail('Oh nooooooo!');
7
+ throw Error('Unsuccessfully ran the script');
8
+ }, 1000);
@@ -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.5",
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": "322363b8876a7ea7b630d538e22965f7bab0ea06"
86
+ "gitHead": "872b924a97c13142bdb8bf4218a4db324f309ce4"
86
87
  }
@@ -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
- */