@appium/images-plugin 1.1.4 → 1.1.9
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 +1 -1
- package/build/lib/compare.d.ts +28 -0
- package/build/lib/compare.d.ts.map +1 -0
- package/build/lib/compare.js +62 -65
- package/build/lib/finder.d.ts +156 -0
- package/build/lib/finder.d.ts.map +1 -0
- package/build/lib/finder.js +321 -363
- package/build/lib/image-element.d.ts +107 -0
- package/build/lib/image-element.d.ts.map +1 -0
- package/build/lib/image-element.js +194 -238
- 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 +26 -0
- package/build/lib/plugin.d.ts.map +1 -0
- package/build/lib/plugin.js +87 -127
- package/build/tsconfig.tsbuildinfo +1 -0
- package/index.js +1 -3
- package/lib/compare.js +35 -11
- package/lib/finder.js +46 -26
- package/lib/image-element.js +17 -23
- package/lib/logger.js +1 -1
- package/lib/plugin.js +4 -37
- package/package.json +28 -22
- package/build/index.js +0 -27
- package/build/test/e2e/plugin-e2e-specs.js +0 -77
- 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/basic-specs.js +0 -16
- package/build/test/unit/finder-specs.js +0 -406
- package/build/test/unit/image-element-specs.js +0 -320
- package/build/test/unit/plugin-specs.js +0 -191
package/lib/finder.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
1
2
|
import LRU from 'lru-cache';
|
|
2
|
-
import { imageUtil, util } from 'appium
|
|
3
|
-
import { errors } from 'appium
|
|
3
|
+
import { imageUtil, util } from '@appium/support';
|
|
4
|
+
import { errors } from '@appium/base-driver';
|
|
4
5
|
import { ImageElement, DEFAULT_TEMPLATE_IMAGE_SCALE,
|
|
5
6
|
IMAGE_EL_TAP_STRATEGY_W3C } from './image-element';
|
|
6
7
|
import { MATCH_TEMPLATE_MODE, compareImages, DEFAULT_MATCH_THRESHOLD } from './compare';
|
|
@@ -19,6 +20,12 @@ const DEFAULT_SETTINGS = {
|
|
|
19
20
|
// element will not be found
|
|
20
21
|
imageMatchThreshold: DEFAULT_MATCH_THRESHOLD,
|
|
21
22
|
|
|
23
|
+
// One of possible image matching methods.
|
|
24
|
+
// Read https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_template_matching/py_template_matching.html
|
|
25
|
+
// for more details.
|
|
26
|
+
// TM_CCOEFF_NORMED by default
|
|
27
|
+
imageMatchMethod: '',
|
|
28
|
+
|
|
22
29
|
// if the image returned by getScreenshot differs in size or aspect ratio
|
|
23
30
|
// from the screen, attempt to fix it automatically
|
|
24
31
|
fixImageFindScreenshotDims: true,
|
|
@@ -81,7 +88,7 @@ export default class ImageElementFinder {
|
|
|
81
88
|
}
|
|
82
89
|
|
|
83
90
|
/**
|
|
84
|
-
* @typedef
|
|
91
|
+
* @typedef FindByImageOptions
|
|
85
92
|
* @property {boolean} [shouldCheckStaleness=false] - whether this call to find an
|
|
86
93
|
* image is merely to check staleness. If so we can bypass a lot of logic
|
|
87
94
|
* @property {boolean} [multiple=false] - Whether we are finding one element or
|
|
@@ -109,13 +116,14 @@ export default class ImageElementFinder {
|
|
|
109
116
|
if (!this.driver) {
|
|
110
117
|
throw new Error(`Can't find without a driver!`);
|
|
111
118
|
}
|
|
112
|
-
const settings =
|
|
119
|
+
const settings = {...DEFAULT_SETTINGS, ...this.driver.settings.getSettings()};
|
|
113
120
|
const {
|
|
114
121
|
imageMatchThreshold: threshold,
|
|
122
|
+
imageMatchMethod,
|
|
115
123
|
fixImageTemplateSize,
|
|
116
124
|
fixImageTemplateScale,
|
|
117
125
|
defaultImageTemplateScale,
|
|
118
|
-
getMatchedImageResult: visualize
|
|
126
|
+
getMatchedImageResult: visualize
|
|
119
127
|
} = settings;
|
|
120
128
|
|
|
121
129
|
log.info(`Finding image element with match threshold ${threshold}`);
|
|
@@ -133,9 +141,7 @@ export default class ImageElementFinder {
|
|
|
133
141
|
screenHeight);
|
|
134
142
|
}
|
|
135
143
|
|
|
136
|
-
|
|
137
|
-
let b64Matched = null;
|
|
138
|
-
let score = 0;
|
|
144
|
+
const results = [];
|
|
139
145
|
const condition = async () => {
|
|
140
146
|
try {
|
|
141
147
|
const {b64Screenshot, scale} = await this.getScreenshotForImageFind(screenWidth, screenHeight);
|
|
@@ -145,12 +151,27 @@ export default class ImageElementFinder {
|
|
|
145
151
|
fixImageTemplateScale, ...scale
|
|
146
152
|
});
|
|
147
153
|
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
154
|
+
const comparisonOpts = {
|
|
155
|
+
threshold,
|
|
156
|
+
visualize,
|
|
157
|
+
multiple,
|
|
158
|
+
};
|
|
159
|
+
if (imageMatchMethod) {
|
|
160
|
+
comparisonOpts.method = imageMatchMethod;
|
|
161
|
+
}
|
|
162
|
+
if (multiple) {
|
|
163
|
+
results.push(...(await compareImages(MATCH_TEMPLATE_MODE,
|
|
164
|
+
b64Screenshot,
|
|
165
|
+
b64Template,
|
|
166
|
+
comparisonOpts)));
|
|
167
|
+
} else {
|
|
168
|
+
results.push(await compareImages(MATCH_TEMPLATE_MODE,
|
|
169
|
+
b64Screenshot,
|
|
170
|
+
b64Template,
|
|
171
|
+
comparisonOpts));
|
|
172
|
+
}
|
|
153
173
|
return true;
|
|
174
|
+
|
|
154
175
|
} catch (err) {
|
|
155
176
|
// if compareImages fails, we'll get a specific error, but we should
|
|
156
177
|
// retry, so trap that and just return false to trigger the next round of
|
|
@@ -177,29 +198,28 @@ export default class ImageElementFinder {
|
|
|
177
198
|
}
|
|
178
199
|
}
|
|
179
200
|
|
|
180
|
-
if (
|
|
201
|
+
if (_.isEmpty(results)) {
|
|
181
202
|
if (multiple) {
|
|
182
203
|
return [];
|
|
183
204
|
}
|
|
184
205
|
throw new errors.NoSuchElementError();
|
|
185
206
|
}
|
|
186
207
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
}
|
|
191
|
-
const imgEl = new ImageElement(b64Template, rect, score, b64Matched, this);
|
|
208
|
+
const elements = results.map(({rect, score, visualization}) => {
|
|
209
|
+
log.info(`Image template matched: ${JSON.stringify(rect)}`);
|
|
210
|
+
return new ImageElement(b64Template, rect, score, visualization, this);
|
|
211
|
+
});
|
|
192
212
|
|
|
193
213
|
// if we're just checking staleness, return straightaway so we don't add
|
|
194
214
|
// a new element to the cache. shouldCheckStaleness does not support multiple
|
|
195
215
|
// elements, since it is a purely internal mechanism
|
|
196
216
|
if (shouldCheckStaleness) {
|
|
197
|
-
return
|
|
217
|
+
return elements[0];
|
|
198
218
|
}
|
|
199
219
|
|
|
200
|
-
const
|
|
220
|
+
const registeredElements = elements.map((imgEl) => this.registerImageElement(imgEl));
|
|
201
221
|
|
|
202
|
-
return multiple ?
|
|
222
|
+
return multiple ? registeredElements : registeredElements[0];
|
|
203
223
|
}
|
|
204
224
|
|
|
205
225
|
/**
|
|
@@ -229,11 +249,11 @@ export default class ImageElementFinder {
|
|
|
229
249
|
}
|
|
230
250
|
|
|
231
251
|
/**
|
|
232
|
-
* @typedef
|
|
252
|
+
* @typedef Screenshot
|
|
233
253
|
* @property {string} b64Screenshot - base64 based screenshot string
|
|
234
254
|
*/
|
|
235
255
|
/**
|
|
236
|
-
* @typedef
|
|
256
|
+
* @typedef ScreenshotScale
|
|
237
257
|
* @property {float} xScale - Scale ratio for width
|
|
238
258
|
* @property {float} yScale - Scale ratio for height
|
|
239
259
|
*/
|
|
@@ -244,7 +264,7 @@ export default class ImageElementFinder {
|
|
|
244
264
|
* @param {int} screenWidth - width of screen
|
|
245
265
|
* @param {int} screenHeight - height of screen
|
|
246
266
|
*
|
|
247
|
-
* @returns {Screenshot, ?
|
|
267
|
+
* @returns { {b64Screenshot: Screenshot, scale: ScreenshotScale? } } base64-encoded screenshot and ScreenshotScale
|
|
248
268
|
*/
|
|
249
269
|
async getScreenshotForImageFind (screenWidth, screenHeight) {
|
|
250
270
|
if (!this.driver.getScreenshot) {
|
|
@@ -352,7 +372,7 @@ export default class ImageElementFinder {
|
|
|
352
372
|
}
|
|
353
373
|
|
|
354
374
|
/**
|
|
355
|
-
* @typedef
|
|
375
|
+
* @typedef ImageTemplateSettings
|
|
356
376
|
* @property {boolean} fixImageTemplateScale - fixImageTemplateScale in device-settings
|
|
357
377
|
* @property {float} defaultImageTemplateScale - defaultImageTemplateScale in device-settings
|
|
358
378
|
* @property {boolean} ignoreDefaultImageTemplateScale - Ignore defaultImageTemplateScale if it has true.
|
package/lib/image-element.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import { errors } from 'appium
|
|
2
|
+
import { errors } from '@appium/base-driver';
|
|
3
3
|
import log from './logger';
|
|
4
|
-
import { util } from 'appium
|
|
4
|
+
import { util } from '@appium/support';
|
|
5
5
|
import { DEFAULT_SETTINGS } from './finder';
|
|
6
6
|
|
|
7
7
|
const IMAGE_ELEMENT_PREFIX = 'appium-image-element-';
|
|
@@ -15,23 +15,15 @@ const IMAGE_TAP_STRATEGIES = [
|
|
|
15
15
|
const DEFAULT_TEMPLATE_IMAGE_SCALE = 1.0;
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* @typedef
|
|
19
|
-
* @property {
|
|
20
|
-
* @property {
|
|
21
|
-
* @property {int} width - width of rect
|
|
22
|
-
* @property {int} height - height of rect
|
|
18
|
+
* @typedef Dimension
|
|
19
|
+
* @property {number} width - width of rect
|
|
20
|
+
* @property {number} height - height of rect
|
|
23
21
|
*/
|
|
24
22
|
|
|
25
23
|
/**
|
|
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
|
|
24
|
+
* @typedef Position
|
|
25
|
+
* @property {number} x - x coordinate
|
|
26
|
+
* @property {number} y - y coordinate
|
|
35
27
|
*/
|
|
36
28
|
|
|
37
29
|
/**
|
|
@@ -46,11 +38,9 @@ export default class ImageElement {
|
|
|
46
38
|
* @param {Rect} rect - bounds of matched image element
|
|
47
39
|
* @param {number} score The similarity score as a float number in range [0.0, 1.0].
|
|
48
40
|
* 1.0 is the highest score (means both images are totally equal).
|
|
49
|
-
* @param {?
|
|
41
|
+
* @param {string?} b64Result - the base64-encoded image which has matched marks.
|
|
50
42
|
* Defaults to null.
|
|
51
|
-
* @param {?
|
|
52
|
-
*
|
|
53
|
-
* @returns {ImageElement}
|
|
43
|
+
* @param {import('./finder').default?} finder - the finder we can use to re-check stale elements
|
|
54
44
|
*/
|
|
55
45
|
constructor (b64Template, rect, score, b64Result = null, finder = null) {
|
|
56
46
|
this.template = b64Template;
|
|
@@ -217,12 +207,12 @@ export default class ImageElement {
|
|
|
217
207
|
/**
|
|
218
208
|
* Handle various Appium commands that involve an image element
|
|
219
209
|
*
|
|
220
|
-
* @param {BaseDriver} driver - the driver to use for commands
|
|
210
|
+
* @param {import('@appium/base-driver').BaseDriver} driver - the driver to use for commands
|
|
221
211
|
* @param {string} cmd - the name of the driver command
|
|
222
212
|
* @param {string} imgElId - the id of the ImageElement to work with
|
|
223
|
-
* @param {
|
|
213
|
+
* @param {string[]} args - Rest of arguments for executeScripts
|
|
224
214
|
*
|
|
225
|
-
* @returns {
|
|
215
|
+
* @returns {object} - the result of running a command
|
|
226
216
|
*/
|
|
227
217
|
static async execute (driver, imgEl, cmd, ...args) {
|
|
228
218
|
switch (cmd) {
|
|
@@ -258,3 +248,7 @@ export {
|
|
|
258
248
|
ImageElement, IMAGE_EL_TAP_STRATEGY_MJSONWP, IMAGE_EL_TAP_STRATEGY_W3C,
|
|
259
249
|
DEFAULT_TEMPLATE_IMAGE_SCALE, IMAGE_ELEMENT_PREFIX
|
|
260
250
|
};
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @typedef {import('@appium/types').Rect} Rect
|
|
254
|
+
*/
|
package/lib/logger.js
CHANGED
package/lib/plugin.js
CHANGED
|
@@ -1,22 +1,12 @@
|
|
|
1
1
|
/* eslint-disable no-case-declarations */
|
|
2
2
|
|
|
3
3
|
import _ from 'lodash';
|
|
4
|
-
import { errors } from 'appium
|
|
4
|
+
import { errors } from '@appium/base-driver';
|
|
5
5
|
import BasePlugin from '@appium/base-plugin';
|
|
6
6
|
import { compareImages } from './compare';
|
|
7
|
-
import ImageElementFinder
|
|
7
|
+
import ImageElementFinder from './finder';
|
|
8
8
|
import { ImageElement, IMAGE_ELEMENT_PREFIX } from './image-element';
|
|
9
9
|
|
|
10
|
-
const IMG_EL_BODY_RE = new RegExp(
|
|
11
|
-
`"(${W3C_ELEMENT_KEY}|${MJSONWP_ELEMENT_KEY})":\s*` + // eslint-disable-line no-useless-escape
|
|
12
|
-
`"${IMAGE_ELEMENT_PREFIX}[^"]+"`
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
const IMG_EL_URL_RE = new RegExp(
|
|
16
|
-
`/(element|screenshot)` +
|
|
17
|
-
`/${IMAGE_ELEMENT_PREFIX}[^/]+`
|
|
18
|
-
);
|
|
19
|
-
|
|
20
10
|
const IMAGE_STRATEGY = '-image';
|
|
21
11
|
|
|
22
12
|
function getImgElFromArgs (args) {
|
|
@@ -35,7 +25,7 @@ export default class ImageElementPlugin extends BasePlugin {
|
|
|
35
25
|
}
|
|
36
26
|
|
|
37
27
|
// this plugin supports a non-standard 'compare images' command
|
|
38
|
-
newMethodMap = {
|
|
28
|
+
static newMethodMap = {
|
|
39
29
|
'/session/:sessionId/appium/compare_images': {
|
|
40
30
|
POST: {
|
|
41
31
|
command: 'compareImages',
|
|
@@ -43,34 +33,11 @@ export default class ImageElementPlugin extends BasePlugin {
|
|
|
43
33
|
required: ['mode', 'firstImage', 'secondImage'],
|
|
44
34
|
optional: ['options']
|
|
45
35
|
},
|
|
36
|
+
neverProxy: true,
|
|
46
37
|
}
|
|
47
38
|
},
|
|
48
39
|
};
|
|
49
40
|
|
|
50
|
-
shouldAvoidProxy (method, route, body) {
|
|
51
|
-
// if it looks like we have an image element in the url (as a route
|
|
52
|
-
// parameter), never proxy. Just look for our image element prefix in allowed
|
|
53
|
-
// positions (either after an 'element' or 'screenshot' path segment), and
|
|
54
|
-
// ensure the prefix is followed by something
|
|
55
|
-
if (IMG_EL_URL_RE.test(route)) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// also if it looks like we have an image element in the request body (as
|
|
61
|
-
// a JSON parameter), never proxy. Basically check against a regexp of the
|
|
62
|
-
// json string of the body, where we know what the form of an image element
|
|
63
|
-
// must be
|
|
64
|
-
if (body) {
|
|
65
|
-
const stringBody = JSON.stringify(body);
|
|
66
|
-
if (stringBody && IMG_EL_BODY_RE.test(stringBody)) {
|
|
67
|
-
return true;
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
41
|
async compareImages (next, driver, ...args) {
|
|
75
42
|
return await compareImages(...args);
|
|
76
43
|
}
|
package/package.json
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appium/images-plugin",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
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,27 +9,42 @@
|
|
|
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"
|
|
14
|
+
},
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/appium/appium.git",
|
|
18
|
+
"directory": "packages/images-plugin"
|
|
25
19
|
},
|
|
26
|
-
"
|
|
20
|
+
"license": "Apache-2.0",
|
|
21
|
+
"author": "Appium <maintainers@appium.io>",
|
|
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
|
+
"test": "npm run test:unit",
|
|
34
|
+
"test:e2e": "mocha --timeout 40s --slow 20s \"./test/e2e/**/*.spec.js\"",
|
|
35
|
+
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
|
36
|
+
},
|
|
33
37
|
"dependencies": {
|
|
34
|
-
"@appium/base-
|
|
35
|
-
"appium
|
|
36
|
-
"
|
|
38
|
+
"@appium/base-driver": "^8.5.2",
|
|
39
|
+
"@appium/base-plugin": "^1.8.4",
|
|
40
|
+
"@appium/opencv": "^1.0.7",
|
|
41
|
+
"@appium/support": "^2.57.4",
|
|
42
|
+
"lru-cache": "6.0.0"
|
|
37
43
|
},
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"copyfiles": "copyfiles ./test/fixtures/*.png ./build"
|
|
44
|
+
"appium": {
|
|
45
|
+
"pluginName": "images",
|
|
46
|
+
"mainClass": "ImageElementPlugin"
|
|
42
47
|
},
|
|
43
|
-
"
|
|
48
|
+
"types": "./build/lib/plugin.d.ts",
|
|
49
|
+
"gitHead": "f15f11bc14d777185ed908a7840657b089cb1049"
|
|
44
50
|
}
|
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,77 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const chai_1 = __importDefault(require("chai"));
|
|
16
|
-
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
|
|
17
|
-
const path_1 = __importDefault(require("path"));
|
|
18
|
-
const webdriverio_1 = require("webdriverio");
|
|
19
|
-
const compare_1 = require("../../lib/compare");
|
|
20
|
-
const fixtures_1 = require("../fixtures");
|
|
21
|
-
const helpers_1 = require("@appium/base-plugin/build/test/helpers");
|
|
22
|
-
chai_1.default.use(chai_as_promised_1.default);
|
|
23
|
-
chai_1.default.should();
|
|
24
|
-
const THIS_PLUGIN_DIR = path_1.default.resolve(__dirname, '..', '..', '..');
|
|
25
|
-
const APPIUM_HOME = path_1.default.resolve(__dirname, '..', '..', '..', 'local_appium_home');
|
|
26
|
-
const TEST_HOST = 'localhost';
|
|
27
|
-
const TEST_PORT = 4723;
|
|
28
|
-
const TEST_FAKE_APP = path_1.default.resolve(APPIUM_HOME, 'appium-fake-driver', 'node_modules', 'appium-fake-driver', 'test', 'fixtures', 'app.xml');
|
|
29
|
-
const TEST_CAPS = {
|
|
30
|
-
platformName: 'Fake',
|
|
31
|
-
'appium:automationName': 'Fake',
|
|
32
|
-
'appium:deviceName': 'Fake',
|
|
33
|
-
'appium:app': TEST_FAKE_APP
|
|
34
|
-
};
|
|
35
|
-
const WDIO_OPTS = {
|
|
36
|
-
hostname: TEST_HOST,
|
|
37
|
-
port: TEST_PORT,
|
|
38
|
-
connectionRetryCount: 0,
|
|
39
|
-
capabilities: TEST_CAPS
|
|
40
|
-
};
|
|
41
|
-
describe('ImageElementPlugin', function () {
|
|
42
|
-
let server, driver = null;
|
|
43
|
-
after(function () {
|
|
44
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
if (driver) {
|
|
46
|
-
yield driver.deleteSession();
|
|
47
|
-
}
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
helpers_1.e2eSetup({
|
|
51
|
-
before, after, server, port: TEST_PORT, host: TEST_HOST, appiumHome: APPIUM_HOME,
|
|
52
|
-
driverName: 'fake', driverSource: 'npm', driverSpec: 'appium-fake-driver',
|
|
53
|
-
pluginName: 'images', pluginSource: 'local', pluginSpec: THIS_PLUGIN_DIR,
|
|
54
|
-
});
|
|
55
|
-
it('should add the compareImages route', function () {
|
|
56
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
-
driver = yield webdriverio_1.remote(WDIO_OPTS);
|
|
58
|
-
let comparison = yield driver.compareImages(compare_1.MATCH_FEATURES_MODE, fixtures_1.TEST_IMG_1_B64, fixtures_1.TEST_IMG_2_B64, {});
|
|
59
|
-
comparison.count.should.eql(0);
|
|
60
|
-
comparison = yield driver.compareImages(compare_1.GET_SIMILARITY_MODE, fixtures_1.TEST_IMG_1_B64, fixtures_1.TEST_IMG_2_B64, {});
|
|
61
|
-
comparison.score.should.be.above(0.2);
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
it('should find and interact with image elements', function () {
|
|
65
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
66
|
-
const imageEl = yield driver.$(fixtures_1.APPSTORE_IMG_PATH);
|
|
67
|
-
const { x, y } = yield imageEl.getLocation();
|
|
68
|
-
const { width, height } = yield imageEl.getSize();
|
|
69
|
-
x.should.eql(28);
|
|
70
|
-
y.should.eql(72);
|
|
71
|
-
width.should.eql(80);
|
|
72
|
-
height.should.eql(91);
|
|
73
|
-
yield imageEl.click();
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWUyZS1zcGVjcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3Rlc3QvZTJlL3BsdWdpbi1lMmUtc3BlY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsd0VBQThDO0FBQzlDLGdEQUF3QjtBQUN4Qiw2Q0FBNkM7QUFDN0MsK0NBQTZFO0FBQzdFLDBDQUFnRjtBQUNoRixvRUFBa0U7QUFFbEUsY0FBSSxDQUFDLEdBQUcsQ0FBQywwQkFBYyxDQUFDLENBQUM7QUFDekIsY0FBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBRWQsTUFBTSxlQUFlLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUNsRSxNQUFNLFdBQVcsR0FBRyxjQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0FBQ25GLE1BQU0sU0FBUyxHQUFHLFdBQVcsQ0FBQztBQUM5QixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUM7QUFDdkIsTUFBTSxhQUFhLEdBQUcsY0FBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsb0JBQW9CLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQzNGLFNBQVMsQ0FBQyxDQUFDO0FBQzlDLE1BQU0sU0FBUyxHQUFHO0lBQ2hCLFlBQVksRUFBRSxNQUFNO0lBQ3BCLHVCQUF1QixFQUFFLE1BQU07SUFDL0IsbUJBQW1CLEVBQUUsTUFBTTtJQUMzQixZQUFZLEVBQUUsYUFBYTtDQUM1QixDQUFDO0FBQ0YsTUFBTSxTQUFTLEdBQUc7SUFDaEIsUUFBUSxFQUFFLFNBQVM7SUFDbkIsSUFBSSxFQUFFLFNBQVM7SUFDZixvQkFBb0IsRUFBRSxDQUFDO0lBQ3ZCLFlBQVksRUFBRSxTQUFTO0NBQ3hCLENBQUM7QUFFRixRQUFRLENBQUMsb0JBQW9CLEVBQUU7SUFDN0IsSUFBSSxNQUFNLEVBQUUsTUFBTSxHQUFHLElBQUksQ0FBQztJQUUxQixLQUFLLENBQUM7O1lBQ0osSUFBSSxNQUFNLEVBQUU7Z0JBQ1YsTUFBTSxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7YUFDOUI7UUFDSCxDQUFDO0tBQUEsQ0FBQyxDQUFDO0lBRUgsa0JBQVEsQ0FBQztRQUNQLE1BQU0sRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsV0FBVztRQUNoRixVQUFVLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsVUFBVSxFQUFFLG9CQUFvQjtRQUN6RSxVQUFVLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLGVBQWU7S0FDekUsQ0FBQyxDQUFDO0lBRUgsRUFBRSxDQUFDLG9DQUFvQyxFQUFFOztZQUN2QyxNQUFNLEdBQUcsTUFBTSxvQkFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9CLElBQUksVUFBVSxHQUFHLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyw2QkFBbUIsRUFBRSx5QkFBYyxFQUFFLHlCQUFjLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDckcsVUFBVSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLFVBQVUsR0FBRyxNQUFNLE1BQU0sQ0FBQyxhQUFhLENBQUMsNkJBQW1CLEVBQUUseUJBQWMsRUFBRSx5QkFBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ2pHLFVBQVUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEMsQ0FBQztLQUFBLENBQUMsQ0FBQztJQUVILEVBQUUsQ0FBQyw4Q0FBOEMsRUFBRTs7WUFDakQsTUFBTSxPQUFPLEdBQUcsTUFBTSxNQUFNLENBQUMsQ0FBQyxDQUFDLDRCQUFpQixDQUFDLENBQUM7WUFDbEQsTUFBTSxFQUFDLENBQUMsRUFBRSxDQUFDLEVBQUMsR0FBRyxNQUFNLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUMzQyxNQUFNLEVBQUMsS0FBSyxFQUFFLE1BQU0sRUFBQyxHQUFHLE1BQU0sT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2hELENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2pCLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2pCLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3JCLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3RCLE1BQU0sT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLENBQUM7S0FBQSxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9
|
|
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==
|
|
@@ -1,16 +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 index_1 = __importDefault(require("../../index"));
|
|
7
|
-
const chai_1 = __importDefault(require("chai"));
|
|
8
|
-
const chai_as_promised_1 = __importDefault(require("chai-as-promised"));
|
|
9
|
-
chai_1.default.use(chai_as_promised_1.default);
|
|
10
|
-
const should = chai_1.default.should();
|
|
11
|
-
describe('ImageElementPlugin', function () {
|
|
12
|
-
it('should exist', function () {
|
|
13
|
-
should.exist(index_1.default);
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzaWMtc3BlY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi90ZXN0L3VuaXQvYmFzaWMtc3BlY3MuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSx3REFBNkM7QUFDN0MsZ0RBQXdCO0FBQ3hCLHdFQUE4QztBQUU5QyxjQUFJLENBQUMsR0FBRyxDQUFDLDBCQUFjLENBQUMsQ0FBQztBQUN6QixNQUFNLE1BQU0sR0FBRyxjQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7QUFHN0IsUUFBUSxDQUFDLG9CQUFvQixFQUFFO0lBQzdCLEVBQUUsQ0FBQyxjQUFjLEVBQUU7UUFDakIsTUFBTSxDQUFDLEtBQUssQ0FBQyxlQUFrQixDQUFDLENBQUM7SUFDbkMsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQyJ9
|