@appium/images-plugin 1.2.4 → 1.3.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 +2 -2
- package/README.md +2 -0
- package/build/lib/compare.d.ts +28 -0
- package/build/lib/compare.d.ts.map +1 -0
- package/build/lib/compare.js +59 -70
- package/build/lib/finder.d.ts +163 -0
- package/build/lib/finder.d.ts.map +1 -0
- package/build/lib/finder.js +323 -358
- package/build/lib/image-element.d.ts +108 -0
- package/build/lib/image-element.d.ts.map +1 -0
- package/build/lib/image-element.js +193 -224
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +15 -5
- package/build/lib/plugin.d.ts +25 -0
- package/build/lib/plugin.d.ts.map +1 -0
- package/build/lib/plugin.js +88 -67
- package/build/tsconfig.tsbuildinfo +1 -1
- package/index.js +1 -3
- package/lib/compare.js +26 -11
- package/lib/finder.js +141 -83
- package/lib/image-element.js +69 -65
- package/lib/logger.js +3 -1
- package/lib/plugin.js +14 -15
- package/package.json +34 -24
- package/build/index.js +0 -27
- package/build/test/e2e/plugin-e2e-specs.js +0 -62
- package/build/test/fixtures/appstore.png +0 -0
- package/build/test/fixtures/img1.png +0 -0
- package/build/test/fixtures/img2.png +0 -0
- package/build/test/fixtures/img2_part.png +0 -0
- package/build/test/fixtures/index.js +0 -24
- package/build/test/unit/finder-specs.js +0 -334
- package/build/test/unit/image-element-specs.js +0 -275
- package/build/test/unit/plugin-specs.js +0 -149
package/lib/image-element.js
CHANGED
|
@@ -1,37 +1,26 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import {
|
|
2
|
+
import {errors} from 'appium/driver';
|
|
3
|
+
import {util} from 'appium/support';
|
|
3
4
|
import log from './logger';
|
|
4
|
-
import {
|
|
5
|
-
import { DEFAULT_SETTINGS } from './finder';
|
|
5
|
+
import {DEFAULT_SETTINGS} from './finder';
|
|
6
6
|
|
|
7
7
|
const IMAGE_ELEMENT_PREFIX = 'appium-image-element-';
|
|
8
8
|
const TAP_DURATION_MS = 125;
|
|
9
9
|
const IMAGE_EL_TAP_STRATEGY_W3C = 'w3cActions';
|
|
10
10
|
const IMAGE_EL_TAP_STRATEGY_MJSONWP = 'touchActions';
|
|
11
|
-
const IMAGE_TAP_STRATEGIES = [
|
|
12
|
-
IMAGE_EL_TAP_STRATEGY_MJSONWP,
|
|
13
|
-
IMAGE_EL_TAP_STRATEGY_W3C
|
|
14
|
-
];
|
|
11
|
+
const IMAGE_TAP_STRATEGIES = [IMAGE_EL_TAP_STRATEGY_MJSONWP, IMAGE_EL_TAP_STRATEGY_W3C];
|
|
15
12
|
const DEFAULT_TEMPLATE_IMAGE_SCALE = 1.0;
|
|
16
13
|
|
|
17
14
|
/**
|
|
18
|
-
* @typedef
|
|
19
|
-
* @property {
|
|
20
|
-
* @property {
|
|
21
|
-
* @property {int} width - width of rect
|
|
22
|
-
* @property {int} height - height of rect
|
|
15
|
+
* @typedef Dimension
|
|
16
|
+
* @property {number} width - width of rect
|
|
17
|
+
* @property {number} height - height of rect
|
|
23
18
|
*/
|
|
24
19
|
|
|
25
20
|
/**
|
|
26
|
-
* @typedef
|
|
27
|
-
* @property {
|
|
28
|
-
* @property {
|
|
29
|
-
*/
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @typedef {Object} Position
|
|
33
|
-
* @property {int} x - x coordinate
|
|
34
|
-
* @property {int} y - y coordinate
|
|
21
|
+
* @typedef Position
|
|
22
|
+
* @property {number} x - x coordinate
|
|
23
|
+
* @property {number} y - y coordinate
|
|
35
24
|
*/
|
|
36
25
|
|
|
37
26
|
/**
|
|
@@ -39,20 +28,17 @@ const DEFAULT_TEMPLATE_IMAGE_SCALE = 1.0;
|
|
|
39
28
|
* and methods that can be used on that set of coordinates via the driver
|
|
40
29
|
*/
|
|
41
30
|
export default class ImageElement {
|
|
42
|
-
|
|
43
31
|
/**
|
|
44
32
|
* @param {string} b64Template - the base64-encoded image which was used to
|
|
45
33
|
* find this ImageElement
|
|
46
34
|
* @param {Rect} rect - bounds of matched image element
|
|
47
35
|
* @param {number} score The similarity score as a float number in range [0.0, 1.0].
|
|
48
36
|
* 1.0 is the highest score (means both images are totally equal).
|
|
49
|
-
* @param {?
|
|
37
|
+
* @param {string?} b64Result - the base64-encoded image which has matched marks.
|
|
50
38
|
* Defaults to null.
|
|
51
|
-
* @param {?
|
|
52
|
-
*
|
|
53
|
-
* @returns {ImageElement}
|
|
39
|
+
* @param {import('./finder').default?} finder - the finder we can use to re-check stale elements
|
|
54
40
|
*/
|
|
55
|
-
constructor
|
|
41
|
+
constructor(b64Template, rect, score, b64Result = null, finder = null) {
|
|
56
42
|
this.template = b64Template;
|
|
57
43
|
this.rect = rect;
|
|
58
44
|
this.id = `${IMAGE_ELEMENT_PREFIX}${util.uuidV4()}`;
|
|
@@ -64,21 +50,21 @@ export default class ImageElement {
|
|
|
64
50
|
/**
|
|
65
51
|
* @returns {Dimension} - dimension of element
|
|
66
52
|
*/
|
|
67
|
-
get size
|
|
53
|
+
get size() {
|
|
68
54
|
return {width: this.rect.width, height: this.rect.height};
|
|
69
55
|
}
|
|
70
56
|
|
|
71
57
|
/**
|
|
72
58
|
* @returns {Position} - coordinates of top-left corner of element
|
|
73
59
|
*/
|
|
74
|
-
get location
|
|
60
|
+
get location() {
|
|
75
61
|
return {x: this.rect.x, y: this.rect.y};
|
|
76
62
|
}
|
|
77
63
|
|
|
78
64
|
/**
|
|
79
65
|
* @returns {Position} - coordinates of center of element
|
|
80
66
|
*/
|
|
81
|
-
get center
|
|
67
|
+
get center() {
|
|
82
68
|
return {
|
|
83
69
|
x: this.rect.x + this.rect.width / 2,
|
|
84
70
|
y: this.rect.y + this.rect.height / 2,
|
|
@@ -88,7 +74,7 @@ export default class ImageElement {
|
|
|
88
74
|
/**
|
|
89
75
|
* @returns {?string} - the base64-encoded image which has matched marks
|
|
90
76
|
*/
|
|
91
|
-
get matchedImage
|
|
77
|
+
get matchedImage() {
|
|
92
78
|
return this.b64MatchedImage;
|
|
93
79
|
}
|
|
94
80
|
|
|
@@ -96,9 +82,9 @@ export default class ImageElement {
|
|
|
96
82
|
* @param {string} protocolKey - the protocol-specific JSON key for
|
|
97
83
|
* a WebElement
|
|
98
84
|
*
|
|
99
|
-
* @returns {
|
|
85
|
+
* @returns {Element} - this image element as a WebElement
|
|
100
86
|
*/
|
|
101
|
-
asElement
|
|
87
|
+
asElement(protocolKey) {
|
|
102
88
|
return {[protocolKey]: this.id};
|
|
103
89
|
}
|
|
104
90
|
|
|
@@ -108,11 +94,13 @@ export default class ImageElement {
|
|
|
108
94
|
* @returns {boolean} - whether the other element and this one have the same
|
|
109
95
|
* properties
|
|
110
96
|
*/
|
|
111
|
-
equals
|
|
112
|
-
return
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
97
|
+
equals(other) {
|
|
98
|
+
return (
|
|
99
|
+
this.rect.x === other.rect.x &&
|
|
100
|
+
this.rect.y === other.rect.y &&
|
|
101
|
+
this.rect.width === other.rect.width &&
|
|
102
|
+
this.rect.height === other.rect.height
|
|
103
|
+
);
|
|
116
104
|
}
|
|
117
105
|
|
|
118
106
|
/**
|
|
@@ -121,7 +109,7 @@ export default class ImageElement {
|
|
|
121
109
|
*
|
|
122
110
|
* @param {BaseDriver} driver - driver for calling actions with
|
|
123
111
|
*/
|
|
124
|
-
async click
|
|
112
|
+
async click(driver) {
|
|
125
113
|
// before we click we need to make sure the element is actually still there
|
|
126
114
|
// where we expect it to be
|
|
127
115
|
let newImgEl;
|
|
@@ -134,9 +122,11 @@ export default class ImageElement {
|
|
|
134
122
|
|
|
135
123
|
// validate tap strategy
|
|
136
124
|
if (!IMAGE_TAP_STRATEGIES.includes(imageElementTapStrategy)) {
|
|
137
|
-
throw new Error(
|
|
138
|
-
|
|
139
|
-
|
|
125
|
+
throw new Error(
|
|
126
|
+
`Incorrect imageElementTapStrategy setting ` +
|
|
127
|
+
`'${imageElementTapStrategy}'. Must be one of ` +
|
|
128
|
+
JSON.stringify(IMAGE_TAP_STRATEGIES)
|
|
129
|
+
);
|
|
140
130
|
}
|
|
141
131
|
|
|
142
132
|
if (checkForImageElementStaleness || updatePos) {
|
|
@@ -146,25 +136,29 @@ export default class ImageElement {
|
|
|
146
136
|
shouldCheckStaleness: true,
|
|
147
137
|
// Set ignoreDefaultImageTemplateScale because this.template is device screenshot based image
|
|
148
138
|
// managed inside Appium after finidng image by template which managed by a user
|
|
149
|
-
ignoreDefaultImageTemplateScale: true
|
|
139
|
+
ignoreDefaultImageTemplateScale: true,
|
|
150
140
|
});
|
|
151
141
|
} catch (err) {
|
|
152
142
|
throw new errors.StaleElementReferenceError();
|
|
153
143
|
}
|
|
154
144
|
|
|
155
145
|
if (!this.equals(newImgEl)) {
|
|
156
|
-
log.warn(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
146
|
+
log.warn(
|
|
147
|
+
`When trying to click on an image element, the image changed ` +
|
|
148
|
+
`position from where it was originally found. It is now at ` +
|
|
149
|
+
`${JSON.stringify(newImgEl.rect)} and was originally at ` +
|
|
150
|
+
`${JSON.stringify(this.rect)}.`
|
|
151
|
+
);
|
|
160
152
|
if (updatePos) {
|
|
161
153
|
log.warn('Click will proceed at new coordinates');
|
|
162
154
|
this.rect = _.clone(newImgEl.rect);
|
|
163
155
|
} else {
|
|
164
|
-
log.warn(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
156
|
+
log.warn(
|
|
157
|
+
'Click will take place at original coordinates. If you ' +
|
|
158
|
+
'would like Appium to automatically click the new ' +
|
|
159
|
+
"coordinates, set the 'autoUpdateImageElementPosition' " +
|
|
160
|
+
'setting to true'
|
|
161
|
+
);
|
|
168
162
|
}
|
|
169
163
|
}
|
|
170
164
|
}
|
|
@@ -184,7 +178,7 @@ export default class ImageElement {
|
|
|
184
178
|
{type: 'pointerDown', button: 0},
|
|
185
179
|
{type: 'pause', duration: TAP_DURATION_MS},
|
|
186
180
|
{type: 'pointerUp', button: 0},
|
|
187
|
-
]
|
|
181
|
+
],
|
|
188
182
|
};
|
|
189
183
|
|
|
190
184
|
// check if the driver has the appropriate performActions method
|
|
@@ -193,8 +187,7 @@ export default class ImageElement {
|
|
|
193
187
|
}
|
|
194
188
|
|
|
195
189
|
// if not, warn and fall back to the other method
|
|
196
|
-
log.warn('Driver does not seem to implement W3C actions, falling back ' +
|
|
197
|
-
'to TouchActions');
|
|
190
|
+
log.warn('Driver does not seem to implement W3C actions, falling back ' + 'to TouchActions');
|
|
198
191
|
}
|
|
199
192
|
|
|
200
193
|
// if the w3c strategy was not requested, do the only other option (mjsonwp
|
|
@@ -202,29 +195,31 @@ export default class ImageElement {
|
|
|
202
195
|
log.info('Will tap using MJSONWP TouchActions');
|
|
203
196
|
const action = {
|
|
204
197
|
action: 'tap',
|
|
205
|
-
options: {x, y}
|
|
198
|
+
options: {x, y},
|
|
206
199
|
};
|
|
207
200
|
|
|
208
201
|
if (driver.performTouch) {
|
|
209
202
|
return await driver.performTouch([action]);
|
|
210
203
|
}
|
|
211
204
|
|
|
212
|
-
throw new Error(
|
|
213
|
-
|
|
214
|
-
|
|
205
|
+
throw new Error(
|
|
206
|
+
"Driver did not implement the 'performTouch' command. " +
|
|
207
|
+
'For drivers to support finding image elements, they ' +
|
|
208
|
+
"should support 'performTouch' and 'performActions'"
|
|
209
|
+
);
|
|
215
210
|
}
|
|
216
211
|
|
|
217
212
|
/**
|
|
218
213
|
* Handle various Appium commands that involve an image element
|
|
219
214
|
*
|
|
220
|
-
* @param {BaseDriver} driver - the driver to use for commands
|
|
215
|
+
* @param {import('appium/driver').BaseDriver} driver - the driver to use for commands
|
|
221
216
|
* @param {string} cmd - the name of the driver command
|
|
222
217
|
* @param {string} imgElId - the id of the ImageElement to work with
|
|
223
|
-
* @param {
|
|
218
|
+
* @param {string[]} args - Rest of arguments for executeScripts
|
|
224
219
|
*
|
|
225
|
-
* @returns {
|
|
220
|
+
* @returns {object} - the result of running a command
|
|
226
221
|
*/
|
|
227
|
-
static async execute
|
|
222
|
+
static async execute(driver, imgEl, cmd, ...args) {
|
|
228
223
|
switch (cmd) {
|
|
229
224
|
case 'click':
|
|
230
225
|
return await imgEl.click(driver);
|
|
@@ -249,12 +244,21 @@ export default class ImageElement {
|
|
|
249
244
|
default:
|
|
250
245
|
throw new errors.NotYetImplementedError();
|
|
251
246
|
}
|
|
252
|
-
default:
|
|
247
|
+
default:
|
|
248
|
+
throw new errors.NotYetImplementedError();
|
|
253
249
|
}
|
|
254
250
|
}
|
|
255
251
|
}
|
|
256
252
|
|
|
257
253
|
export {
|
|
258
|
-
ImageElement,
|
|
259
|
-
|
|
254
|
+
ImageElement,
|
|
255
|
+
IMAGE_EL_TAP_STRATEGY_MJSONWP,
|
|
256
|
+
IMAGE_EL_TAP_STRATEGY_W3C,
|
|
257
|
+
DEFAULT_TEMPLATE_IMAGE_SCALE,
|
|
258
|
+
IMAGE_ELEMENT_PREFIX,
|
|
260
259
|
};
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* @typedef {import('@appium/types').Rect} Rect
|
|
263
|
+
* @typedef {import('@appium/types').Element} Element
|
|
264
|
+
*/
|
package/lib/logger.js
CHANGED
package/lib/plugin.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
/* eslint-disable no-case-declarations */
|
|
2
2
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
|
-
import {
|
|
5
|
-
import BasePlugin from '
|
|
6
|
-
import {
|
|
4
|
+
import {errors} from 'appium/driver';
|
|
5
|
+
import BasePlugin from 'appium/plugin';
|
|
6
|
+
import {compareImages} from './compare';
|
|
7
7
|
import ImageElementFinder from './finder';
|
|
8
|
-
import {
|
|
8
|
+
import {ImageElement, IMAGE_ELEMENT_PREFIX} from './image-element';
|
|
9
9
|
|
|
10
10
|
const IMAGE_STRATEGY = '-image';
|
|
11
11
|
|
|
12
|
-
function getImgElFromArgs
|
|
12
|
+
function getImgElFromArgs(args) {
|
|
13
13
|
for (let arg of args) {
|
|
14
14
|
if (_.isString(arg) && arg.startsWith(IMAGE_ELEMENT_PREFIX)) {
|
|
15
15
|
return arg;
|
|
@@ -18,8 +18,7 @@ function getImgElFromArgs (args) {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
export default class ImageElementPlugin extends BasePlugin {
|
|
21
|
-
|
|
22
|
-
constructor (pluginName) {
|
|
21
|
+
constructor(pluginName) {
|
|
23
22
|
super(pluginName);
|
|
24
23
|
this.finder = new ImageElementFinder();
|
|
25
24
|
}
|
|
@@ -31,26 +30,26 @@ export default class ImageElementPlugin extends BasePlugin {
|
|
|
31
30
|
command: 'compareImages',
|
|
32
31
|
payloadParams: {
|
|
33
32
|
required: ['mode', 'firstImage', 'secondImage'],
|
|
34
|
-
optional: ['options']
|
|
33
|
+
optional: ['options'],
|
|
35
34
|
},
|
|
36
35
|
neverProxy: true,
|
|
37
|
-
}
|
|
36
|
+
},
|
|
38
37
|
},
|
|
39
38
|
};
|
|
40
39
|
|
|
41
|
-
async compareImages
|
|
40
|
+
async compareImages(next, driver, ...args) {
|
|
42
41
|
return await compareImages(...args);
|
|
43
42
|
}
|
|
44
43
|
|
|
45
|
-
async findElement
|
|
44
|
+
async findElement(next, driver, ...args) {
|
|
46
45
|
return await this._find(false, next, driver, ...args);
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
async findElements
|
|
48
|
+
async findElements(next, driver, ...args) {
|
|
50
49
|
return await this._find(true, next, driver, ...args);
|
|
51
50
|
}
|
|
52
51
|
|
|
53
|
-
async _find
|
|
52
|
+
async _find(multiple, next, driver, ...args) {
|
|
54
53
|
const [strategy, selector] = args;
|
|
55
54
|
|
|
56
55
|
// if we're not actually finding by image, just do the normal thing
|
|
@@ -62,7 +61,7 @@ export default class ImageElementPlugin extends BasePlugin {
|
|
|
62
61
|
return await this.finder.findByImage(selector, {multiple});
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
async handle
|
|
64
|
+
async handle(next, driver, cmdName, ...args) {
|
|
66
65
|
// if we have a command that involves an image element id, attempt to find the image element
|
|
67
66
|
// and execute the command on it
|
|
68
67
|
const imgElId = getImgElFromArgs(args);
|
|
@@ -79,4 +78,4 @@ export default class ImageElementPlugin extends BasePlugin {
|
|
|
79
78
|
}
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
export {
|
|
81
|
+
export {ImageElementPlugin, getImgElFromArgs, IMAGE_STRATEGY};
|
package/package.json
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appium/images-plugin",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "Plugin for working with images and image elements in Appium",
|
|
5
|
-
"main": "./build/index.js",
|
|
6
|
-
"repository": {
|
|
7
|
-
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/appium/appium-plugins.git"
|
|
9
|
-
},
|
|
10
|
-
"appium": {
|
|
11
|
-
"pluginName": "images",
|
|
12
|
-
"mainClass": "ImageElementPlugin"
|
|
13
|
-
},
|
|
14
5
|
"keywords": [
|
|
15
6
|
"appium",
|
|
16
7
|
"opencv",
|
|
@@ -18,29 +9,48 @@
|
|
|
18
9
|
"image",
|
|
19
10
|
"webdriver"
|
|
20
11
|
],
|
|
21
|
-
"author": "Appium <maintainers@appium.io>",
|
|
22
|
-
"license": "Apache-2.0",
|
|
23
12
|
"bugs": {
|
|
24
|
-
"url": "https://github.com/appium/appium
|
|
13
|
+
"url": "https://github.com/appium/appium/issues"
|
|
25
14
|
},
|
|
26
|
-
"
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/appium/appium.git",
|
|
18
|
+
"directory": "packages/images-plugin"
|
|
19
|
+
},
|
|
20
|
+
"license": "Apache-2.0",
|
|
21
|
+
"author": "https://github.com/appium",
|
|
27
22
|
"files": [
|
|
28
23
|
"build",
|
|
29
24
|
"docs",
|
|
30
25
|
"lib",
|
|
31
26
|
"index.js"
|
|
32
27
|
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "babel lib --root-mode=upward --out-dir=build/lib",
|
|
30
|
+
"dev": "npm run build -- --watch",
|
|
31
|
+
"fix": "npm run lint -- --fix",
|
|
32
|
+
"lint": "eslint -c ../../.eslintrc --ignore-path ../../.eslintignore .",
|
|
33
|
+
"prepare": "npm run build",
|
|
34
|
+
"test": "npm run test:unit",
|
|
35
|
+
"test:e2e": "mocha --timeout 40s --slow 20s \"./test/e2e/**/*.spec.js\"",
|
|
36
|
+
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
|
37
|
+
},
|
|
33
38
|
"dependencies": {
|
|
34
|
-
"@appium/
|
|
35
|
-
"
|
|
36
|
-
"@appium/opencv": "1.0.1",
|
|
37
|
-
"@appium/support": "2.55.3",
|
|
38
|
-
"lru-cache": "6.0.0"
|
|
39
|
+
"@appium/opencv": "^1.0.9",
|
|
40
|
+
"lru-cache": "7.10.1"
|
|
39
41
|
},
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"appium": "^2.0.0-beta.35"
|
|
44
|
+
},
|
|
45
|
+
"appium": {
|
|
46
|
+
"pluginName": "images",
|
|
47
|
+
"mainClass": "ImageElementPlugin"
|
|
44
48
|
},
|
|
45
|
-
"
|
|
49
|
+
"types": "./build/lib/plugin.d.ts",
|
|
50
|
+
"gitHead": "62b97417fcb7b0c0e2d6bab30bf9406e09bfb2ed",
|
|
51
|
+
"homepage": "https://appium.io",
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">=14",
|
|
54
|
+
"npm": ">=6"
|
|
55
|
+
}
|
|
46
56
|
}
|
package/build/index.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
-
}) : (function(o, m, k, k2) {
|
|
6
|
-
if (k2 === undefined) k2 = k;
|
|
7
|
-
o[k2] = m[k];
|
|
8
|
-
}));
|
|
9
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
-
}) : function(o, v) {
|
|
12
|
-
o["default"] = v;
|
|
13
|
-
});
|
|
14
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
-
if (mod && mod.__esModule) return mod;
|
|
16
|
-
var result = {};
|
|
17
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
-
__setModuleDefault(result, mod);
|
|
19
|
-
return result;
|
|
20
|
-
};
|
|
21
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.ImageElementPlugin = exports.IMAGE_STRATEGY = void 0;
|
|
23
|
-
const plugin_1 = __importStar(require("./lib/plugin"));
|
|
24
|
-
exports.ImageElementPlugin = plugin_1.default;
|
|
25
|
-
Object.defineProperty(exports, "IMAGE_STRATEGY", { enumerable: true, get: function () { return plugin_1.IMAGE_STRATEGY; } });
|
|
26
|
-
exports.default = plugin_1.default;
|
|
27
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdURBQWtFO0FBRXpDLDZCQUZsQixnQkFBa0IsQ0FFa0I7QUFBbEMsK0ZBRm9CLHVCQUFjLE9BRXBCO0FBRHZCLGtCQUFlLGdCQUFrQixDQUFDIn0=
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const path_1 = __importDefault(require("path"));
|
|
7
|
-
const APPIUM_HOME = path_1.default.resolve(__dirname, '..', '..', '..', 'local_appium_home');
|
|
8
|
-
// need to assign this before appium is imported via e2eSetup
|
|
9
|
-
process.env.APPIUM_HOME = APPIUM_HOME;
|
|
10
|
-
const chai_1 = __importDefault(require("chai"));
|
|
11
|
-
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
|
|
12
|
-
const webdriverio_1 = require("webdriverio");
|
|
13
|
-
const compare_1 = require("../../lib/compare");
|
|
14
|
-
const fixtures_1 = require("../fixtures");
|
|
15
|
-
const helpers_1 = require("@appium/base-plugin/build/test/helpers");
|
|
16
|
-
chai_1.default.use(chai_as_promised_1.default);
|
|
17
|
-
chai_1.default.should();
|
|
18
|
-
const THIS_PLUGIN_DIR = path_1.default.resolve(__dirname, '..', '..', '..');
|
|
19
|
-
const TEST_HOST = 'localhost';
|
|
20
|
-
const TEST_FAKE_APP = path_1.default.resolve(APPIUM_HOME, '@appium', 'fake-driver', 'node_modules', '@appium', 'fake-driver', 'test', 'fixtures', 'app.xml');
|
|
21
|
-
const TEST_CAPS = {
|
|
22
|
-
platformName: 'Fake',
|
|
23
|
-
'appium:automationName': 'Fake',
|
|
24
|
-
'appium:deviceName': 'Fake',
|
|
25
|
-
'appium:app': TEST_FAKE_APP
|
|
26
|
-
};
|
|
27
|
-
const WDIO_OPTS = {
|
|
28
|
-
hostname: TEST_HOST,
|
|
29
|
-
connectionRetryCount: 0,
|
|
30
|
-
capabilities: TEST_CAPS
|
|
31
|
-
};
|
|
32
|
-
describe('ImageElementPlugin', function () {
|
|
33
|
-
let server, driver = null;
|
|
34
|
-
after(async function () {
|
|
35
|
-
if (driver) {
|
|
36
|
-
await driver.deleteSession();
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
(0, helpers_1.e2eSetup)({
|
|
40
|
-
before, after, server, host: TEST_HOST, driverName: 'fake', driverSource: 'npm',
|
|
41
|
-
driverSpec: '@appium/fake-driver', pluginName: 'images', pluginSource: 'local',
|
|
42
|
-
pluginSpec: THIS_PLUGIN_DIR,
|
|
43
|
-
});
|
|
44
|
-
it('should add the compareImages route', async function () {
|
|
45
|
-
driver = await (0, webdriverio_1.remote)({ ...WDIO_OPTS, port: this.port });
|
|
46
|
-
let comparison = await driver.compareImages(compare_1.MATCH_FEATURES_MODE, fixtures_1.TEST_IMG_1_B64, fixtures_1.TEST_IMG_2_B64, {});
|
|
47
|
-
comparison.count.should.eql(0);
|
|
48
|
-
comparison = await driver.compareImages(compare_1.GET_SIMILARITY_MODE, fixtures_1.TEST_IMG_1_B64, fixtures_1.TEST_IMG_2_B64, {});
|
|
49
|
-
comparison.score.should.be.above(0.2);
|
|
50
|
-
});
|
|
51
|
-
it('should find and interact with image elements', async function () {
|
|
52
|
-
const imageEl = await driver.$(fixtures_1.APPSTORE_IMG_PATH);
|
|
53
|
-
const { x, y } = await imageEl.getLocation();
|
|
54
|
-
const { width, height } = await imageEl.getSize();
|
|
55
|
-
x.should.eql(28);
|
|
56
|
-
y.should.eql(72);
|
|
57
|
-
width.should.eql(80);
|
|
58
|
-
height.should.eql(91);
|
|
59
|
-
await imageEl.click();
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWUyZS1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvZTJlL3BsdWdpbi1lMmUtc3BlY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsTUFBTSxXQUFXLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztBQUNuRiw2REFBNkQ7QUFDN0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO0FBRXRDLGdEQUF3QjtBQUN4Qix3RUFBOEM7QUFDOUMsNkNBQTZDO0FBQzdDLCtDQUE2RTtBQUM3RSwwQ0FBZ0Y7QUFDaEYsb0VBQWtFO0FBRWxFLGNBQUksQ0FBQyxHQUFHLENBQUMsMEJBQWMsQ0FBQyxDQUFDO0FBQ3pCLGNBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztBQUVkLE1BQU0sZUFBZSxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7QUFDbEUsTUFBTSxTQUFTLEdBQUcsV0FBVyxDQUFDO0FBQzlCLE1BQU0sYUFBYSxHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUN0RixTQUFTLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7QUFDM0QsTUFBTSxTQUFTLEdBQUc7SUFDaEIsWUFBWSxFQUFFLE1BQU07SUFDcEIsdUJBQXVCLEVBQUUsTUFBTTtJQUMvQixtQkFBbUIsRUFBRSxNQUFNO0lBQzNCLFlBQVksRUFBRSxhQUFhO0NBQzVCLENBQUM7QUFDRixNQUFNLFNBQVMsR0FBRztJQUNoQixRQUFRLEVBQUUsU0FBUztJQUNuQixvQkFBb0IsRUFBRSxDQUFDO0lBQ3ZCLFlBQVksRUFBRSxTQUFTO0NBQ3hCLENBQUM7QUFFRixRQUFRLENBQUMsb0JBQW9CLEVBQUU7SUFDN0IsSUFBSSxNQUFNLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQztJQUUxQixLQUFLLENBQUMsS0FBSztRQUNULElBQUksTUFBTSxFQUFFO1lBQ1YsTUFBTSxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDOUI7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUVILElBQUEsa0JBQVEsRUFBQztRQUNQLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsS0FBSztRQUMvRSxVQUFVLEVBQUUscUJBQXFCLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsT0FBTztRQUM5RSxVQUFVLEVBQUUsZUFBZTtLQUM1QixDQUFDLENBQUM7SUFFSCxFQUFFLENBQUMsb0NBQW9DLEVBQUUsS0FBSztRQUM1QyxNQUFNLEdBQUcsTUFBTSxJQUFBLG9CQUFJLEVBQUMsRUFBQyxHQUFHLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBQyxDQUFDLENBQUM7UUFDckQsSUFBSSxVQUFVLEdBQUcsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLDZCQUFtQixFQUFFLHlCQUFjLEVBQUUseUJBQWMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNyRyxVQUFVLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0IsVUFBVSxHQUFHLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyw2QkFBbUIsRUFBRSx5QkFBYyxFQUFFLHlCQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDakcsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN4QyxDQUFDLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRSxLQUFLO1FBQ3RELE1BQU0sT0FBTyxHQUFHLE1BQU0sTUFBTSxDQUFDLENBQUMsQ0FBQyw0QkFBaUIsQ0FBQyxDQUFDO1FBQ2xELE1BQU0sRUFBQyxDQUFDLEVBQUUsQ0FBQyxFQUFDLEdBQUcsTUFBTSxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDM0MsTUFBTSxFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNoRCxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNqQixDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNqQixLQUFLLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyQixNQUFNLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUN0QixNQUFNLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN4QixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIn0=
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.APPSTORE_IMG_PATH = exports.TEST_IMG_2_PART_B64 = exports.TEST_IMG_2_B64 = exports.TEST_IMG_1_B64 = exports.TINY_PNG_DIMS = exports.TINY_PNG = void 0;
|
|
7
|
-
const path_1 = __importDefault(require("path"));
|
|
8
|
-
const fs_1 = __importDefault(require("fs"));
|
|
9
|
-
const TINY_PNG = 'iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyhpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQwIDc5LjE2MDQ1MSwgMjAxNy8wNS8wNi0wMTowODoyMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKE1hY2ludG9zaCkiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6N0NDMDM4MDM4N0U2MTFFOEEzMzhGMTRFNUUwNzIwNUIiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6N0NDMDM4MDQ4N0U2MTFFOEEzMzhGMTRFNUUwNzIwNUIiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo3Q0MwMzgwMTg3RTYxMUU4QTMzOEYxNEU1RTA3MjA1QiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3Q0MwMzgwMjg3RTYxMUU4QTMzOEYxNEU1RTA3MjA1QiIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpdvJjQAAAAlSURBVHjaJInBEQAACIKw/Xe2Ul5wYBtwmJqkk4+zfvUQVoABAEg0EfrZwc0hAAAAAElFTkSuQmCC';
|
|
10
|
-
exports.TINY_PNG = TINY_PNG;
|
|
11
|
-
const TINY_PNG_DIMS = [4, 4];
|
|
12
|
-
exports.TINY_PNG_DIMS = TINY_PNG_DIMS;
|
|
13
|
-
const TEST_IMG_1_PATH = path_1.default.resolve(__dirname, 'img1.png');
|
|
14
|
-
const TEST_IMG_2_PATH = path_1.default.resolve(__dirname, 'img2.png');
|
|
15
|
-
const TEST_IMG_2_PART_PATH = path_1.default.resolve(__dirname, 'img2_part.png');
|
|
16
|
-
const APPSTORE_IMG_PATH = path_1.default.resolve(__dirname, 'appstore.png');
|
|
17
|
-
exports.APPSTORE_IMG_PATH = APPSTORE_IMG_PATH;
|
|
18
|
-
const TEST_IMG_1_B64 = fs_1.default.readFileSync(TEST_IMG_1_PATH).toString('base64');
|
|
19
|
-
exports.TEST_IMG_1_B64 = TEST_IMG_1_B64;
|
|
20
|
-
const TEST_IMG_2_B64 = fs_1.default.readFileSync(TEST_IMG_2_PATH).toString('base64');
|
|
21
|
-
exports.TEST_IMG_2_B64 = TEST_IMG_2_B64;
|
|
22
|
-
const TEST_IMG_2_PART_B64 = fs_1.default.readFileSync(TEST_IMG_2_PART_PATH).toString('base64');
|
|
23
|
-
exports.TEST_IMG_2_PART_B64 = TEST_IMG_2_PART_B64;
|
|
24
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L2ZpeHR1cmVzL2luZGV4LmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLGdEQUF3QjtBQUN4Qiw0Q0FBb0I7QUFFcEIsTUFBTSxRQUFRLEdBQUcsc3ZDQUFzdkMsQ0FBQztBQVkvdkMsNEJBQVE7QUFYakIsTUFBTSxhQUFhLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFXVixzQ0FBYTtBQVRoQyxNQUFNLGVBQWUsR0FBRyxjQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM1RCxNQUFNLGVBQWUsR0FBRyxjQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUM1RCxNQUFNLG9CQUFvQixHQUFHLGNBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGVBQWUsQ0FBQyxDQUFDO0FBQ3RFLE1BQU0saUJBQWlCLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsY0FBYyxDQUFDLENBQUM7QUFPaEUsOENBQWlCO0FBTm5CLE1BQU0sY0FBYyxHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBS3pDLHdDQUFjO0FBSmhELE1BQU0sY0FBYyxHQUFHLFlBQUUsQ0FBQyxZQUFZLENBQUMsZUFBZSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBSXpCLHdDQUFjO0FBSGhFLE1BQU0sbUJBQW1CLEdBQUcsWUFBRSxDQUFDLFlBQVksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUduQixrREFBbUIifQ==
|