@appium/images-plugin 1.2.3 → 1.2.4

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.
@@ -1,13 +1,4 @@
1
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
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
4
  };
@@ -110,91 +101,91 @@ class ImageElementFinder {
110
101
  *
111
102
  * @returns {WebElement} - WebDriver element with a special id prefix
112
103
  */
113
- findByImage(b64Template, { shouldCheckStaleness = false, multiple = false, ignoreDefaultImageTemplateScale = false, }) {
114
- return __awaiter(this, void 0, void 0, function* () {
115
- if (!this.driver) {
116
- throw new Error(`Can't find without a driver!`);
117
- }
118
- const settings = Object.assign({}, DEFAULT_SETTINGS, this.driver.settings.getSettings());
119
- const { imageMatchThreshold: threshold, imageMatchMethod, fixImageTemplateSize, fixImageTemplateScale, defaultImageTemplateScale, getMatchedImageResult: visualize } = settings;
120
- logger_1.default.info(`Finding image element with match threshold ${threshold}`);
121
- if (!this.driver.getWindowSize) {
122
- throw new Error("This driver does not support the required 'getWindowSize' command");
123
- }
124
- const { width: screenWidth, height: screenHeight } = yield this.driver.getWindowSize();
125
- // someone might have sent in a template that's larger than the screen
126
- // dimensions. If so let's check and cut it down to size since the algorithm
127
- // will not work unless we do. But because it requires some potentially
128
- // expensive commands, only do this if the user has requested it in settings.
129
- if (fixImageTemplateSize) {
130
- b64Template = yield this.ensureTemplateSize(b64Template, screenWidth, screenHeight);
131
- }
132
- const results = [];
133
- const condition = () => __awaiter(this, void 0, void 0, function* () {
134
- try {
135
- const { b64Screenshot, scale } = yield this.getScreenshotForImageFind(screenWidth, screenHeight);
136
- b64Template = yield this.fixImageTemplateScale(b64Template, Object.assign({ defaultImageTemplateScale, ignoreDefaultImageTemplateScale,
137
- fixImageTemplateScale }, scale));
138
- const comparisonOpts = {
139
- threshold,
140
- visualize,
141
- multiple,
142
- };
143
- if (imageMatchMethod) {
144
- comparisonOpts.method = imageMatchMethod;
145
- }
146
- if (multiple) {
147
- results.push(...(yield (0, compare_1.compareImages)(compare_1.MATCH_TEMPLATE_MODE, b64Screenshot, b64Template, comparisonOpts)));
148
- }
149
- else {
150
- results.push(yield (0, compare_1.compareImages)(compare_1.MATCH_TEMPLATE_MODE, b64Screenshot, b64Template, comparisonOpts));
151
- }
152
- return true;
104
+ async findByImage(b64Template, { shouldCheckStaleness = false, multiple = false, ignoreDefaultImageTemplateScale = false, }) {
105
+ if (!this.driver) {
106
+ throw new Error(`Can't find without a driver!`);
107
+ }
108
+ const settings = Object.assign({}, DEFAULT_SETTINGS, this.driver.settings.getSettings());
109
+ const { imageMatchThreshold: threshold, imageMatchMethod, fixImageTemplateSize, fixImageTemplateScale, defaultImageTemplateScale, getMatchedImageResult: visualize } = settings;
110
+ logger_1.default.info(`Finding image element with match threshold ${threshold}`);
111
+ if (!this.driver.getWindowSize) {
112
+ throw new Error("This driver does not support the required 'getWindowSize' command");
113
+ }
114
+ const { width: screenWidth, height: screenHeight } = await this.driver.getWindowSize();
115
+ // someone might have sent in a template that's larger than the screen
116
+ // dimensions. If so let's check and cut it down to size since the algorithm
117
+ // will not work unless we do. But because it requires some potentially
118
+ // expensive commands, only do this if the user has requested it in settings.
119
+ if (fixImageTemplateSize) {
120
+ b64Template = await this.ensureTemplateSize(b64Template, screenWidth, screenHeight);
121
+ }
122
+ const results = [];
123
+ const condition = async () => {
124
+ try {
125
+ const { b64Screenshot, scale } = await this.getScreenshotForImageFind(screenWidth, screenHeight);
126
+ b64Template = await this.fixImageTemplateScale(b64Template, {
127
+ defaultImageTemplateScale, ignoreDefaultImageTemplateScale,
128
+ fixImageTemplateScale, ...scale
129
+ });
130
+ const comparisonOpts = {
131
+ threshold,
132
+ visualize,
133
+ multiple,
134
+ };
135
+ if (imageMatchMethod) {
136
+ comparisonOpts.method = imageMatchMethod;
137
+ }
138
+ if (multiple) {
139
+ results.push(...(await (0, compare_1.compareImages)(compare_1.MATCH_TEMPLATE_MODE, b64Screenshot, b64Template, comparisonOpts)));
153
140
  }
154
- catch (err) {
155
- // if compareImages fails, we'll get a specific error, but we should
156
- // retry, so trap that and just return false to trigger the next round of
157
- // implicitly waiting. For other errors, throw them to get out of the
158
- // implicit wait loop
159
- if (err.message.match(/Cannot find any occurrences/)) {
160
- return false;
161
- }
162
- throw err;
141
+ else {
142
+ results.push(await (0, compare_1.compareImages)(compare_1.MATCH_TEMPLATE_MODE, b64Screenshot, b64Template, comparisonOpts));
163
143
  }
164
- });
165
- try {
166
- yield this.driver.implicitWaitForCondition(condition);
144
+ return true;
167
145
  }
168
146
  catch (err) {
169
- // this `implicitWaitForCondition` method will throw a 'Condition unmet'
170
- // error if an element is not found eventually. In that case, we will
171
- // handle the element not found response below. In the case where get some
172
- // _other_ kind of error, it means something blew up totally apart from the
173
- // implicit wait timeout. We should not mask that error and instead throw
174
- // it straightaway
175
- if (!err.message.match(/Condition unmet/)) {
176
- throw err;
147
+ // if compareImages fails, we'll get a specific error, but we should
148
+ // retry, so trap that and just return false to trigger the next round of
149
+ // implicitly waiting. For other errors, throw them to get out of the
150
+ // implicit wait loop
151
+ if (err.message.match(/Cannot find any occurrences/)) {
152
+ return false;
177
153
  }
154
+ throw err;
178
155
  }
179
- if (lodash_1.default.isEmpty(results)) {
180
- if (multiple) {
181
- return [];
182
- }
183
- throw new base_driver_1.errors.NoSuchElementError();
156
+ };
157
+ try {
158
+ await this.driver.implicitWaitForCondition(condition);
159
+ }
160
+ catch (err) {
161
+ // this `implicitWaitForCondition` method will throw a 'Condition unmet'
162
+ // error if an element is not found eventually. In that case, we will
163
+ // handle the element not found response below. In the case where get some
164
+ // _other_ kind of error, it means something blew up totally apart from the
165
+ // implicit wait timeout. We should not mask that error and instead throw
166
+ // it straightaway
167
+ if (!err.message.match(/Condition unmet/)) {
168
+ throw err;
184
169
  }
185
- const elements = results.map(({ rect, score, visualization }) => {
186
- logger_1.default.info(`Image template matched: ${JSON.stringify(rect)}`);
187
- return new image_element_1.ImageElement(b64Template, rect, score, visualization, this);
188
- });
189
- // if we're just checking staleness, return straightaway so we don't add
190
- // a new element to the cache. shouldCheckStaleness does not support multiple
191
- // elements, since it is a purely internal mechanism
192
- if (shouldCheckStaleness) {
193
- return elements[0];
170
+ }
171
+ if (lodash_1.default.isEmpty(results)) {
172
+ if (multiple) {
173
+ return [];
194
174
  }
195
- const registeredElements = elements.map((imgEl) => this.registerImageElement(imgEl));
196
- return multiple ? registeredElements : registeredElements[0];
175
+ throw new base_driver_1.errors.NoSuchElementError();
176
+ }
177
+ const elements = results.map(({ rect, score, visualization }) => {
178
+ logger_1.default.info(`Image template matched: ${JSON.stringify(rect)}`);
179
+ return new image_element_1.ImageElement(b64Template, rect, score, visualization, this);
197
180
  });
181
+ // if we're just checking staleness, return straightaway so we don't add
182
+ // a new element to the cache. shouldCheckStaleness does not support multiple
183
+ // elements, since it is a purely internal mechanism
184
+ if (shouldCheckStaleness) {
185
+ return elements[0];
186
+ }
187
+ const registeredElements = elements.map((imgEl) => this.registerImageElement(imgEl));
188
+ return multiple ? registeredElements : registeredElements[0];
198
189
  }
199
190
  /**
200
191
  * Ensure that the image template sent in for a find is of a suitable size
@@ -205,21 +196,19 @@ class ImageElementFinder {
205
196
  *
206
197
  * @returns {string} base64-encoded image, potentially resized
207
198
  */
208
- ensureTemplateSize(b64Template, screenWidth, screenHeight) {
209
- return __awaiter(this, void 0, void 0, function* () {
210
- let imgObj = yield support_1.imageUtil.getJimpImage(b64Template);
211
- let { width: tplWidth, height: tplHeight } = imgObj.bitmap;
212
- logger_1.default.info(`Template image is ${tplWidth}x${tplHeight}. Screen size is ${screenWidth}x${screenHeight}`);
213
- // if the template fits inside the screen dimensions, we're good
214
- if (tplWidth <= screenWidth && tplHeight <= screenHeight) {
215
- return b64Template;
216
- }
217
- logger_1.default.info(`Scaling template image from ${tplWidth}x${tplHeight} to match ` +
218
- `screen at ${screenWidth}x${screenHeight}`);
219
- // otherwise, scale it to fit inside the screen dimensions
220
- imgObj = imgObj.scaleToFit(screenWidth, screenHeight);
221
- return (yield imgObj.getBuffer(support_1.imageUtil.MIME_PNG)).toString('base64');
222
- });
199
+ async ensureTemplateSize(b64Template, screenWidth, screenHeight) {
200
+ let imgObj = await support_1.imageUtil.getJimpImage(b64Template);
201
+ let { width: tplWidth, height: tplHeight } = imgObj.bitmap;
202
+ logger_1.default.info(`Template image is ${tplWidth}x${tplHeight}. Screen size is ${screenWidth}x${screenHeight}`);
203
+ // if the template fits inside the screen dimensions, we're good
204
+ if (tplWidth <= screenWidth && tplHeight <= screenHeight) {
205
+ return b64Template;
206
+ }
207
+ logger_1.default.info(`Scaling template image from ${tplWidth}x${tplHeight} to match ` +
208
+ `screen at ${screenWidth}x${screenHeight}`);
209
+ // otherwise, scale it to fit inside the screen dimensions
210
+ imgObj = imgObj.scaleToFit(screenWidth, screenHeight);
211
+ return (await imgObj.getBuffer(support_1.imageUtil.MIME_PNG)).toString('base64');
223
212
  }
224
213
  /**
225
214
  * @typedef {Object} Screenshot
@@ -239,95 +228,93 @@ class ImageElementFinder {
239
228
  *
240
229
  * @returns {Screenshot, ?ScreenshotScale} base64-encoded screenshot and ScreenshotScale
241
230
  */
242
- getScreenshotForImageFind(screenWidth, screenHeight) {
243
- return __awaiter(this, void 0, void 0, function* () {
244
- if (!this.driver.getScreenshot) {
245
- throw new Error("This driver does not support the required 'getScreenshot' command");
246
- }
247
- const settings = Object.assign({}, DEFAULT_SETTINGS, this.driver.settings.getSettings());
248
- const { fixImageFindScreenshotDims } = settings;
249
- let b64Screenshot = yield this.driver.getScreenshot();
250
- // if the user has requested not to correct for aspect or size differences
251
- // between the screenshot and the screen, just return the screenshot now
252
- if (!fixImageFindScreenshotDims) {
253
- logger_1.default.info(`Not verifying screenshot dimensions match screen`);
254
- return { b64Screenshot };
255
- }
256
- if (screenWidth < 1 || screenHeight < 1) {
257
- logger_1.default.warn(`The retrieved screen size ${screenWidth}x${screenHeight} does ` +
258
- `not seem to be valid. No changes will be applied to the screenshot`);
259
- return { b64Screenshot };
260
- }
261
- // otherwise, do some verification on the screenshot to make sure it matches
262
- // the screen size and aspect ratio
263
- logger_1.default.info('Verifying screenshot size and aspect ratio');
264
- let imgObj = yield support_1.imageUtil.getJimpImage(b64Screenshot);
265
- let { width: shotWidth, height: shotHeight } = imgObj.bitmap;
266
- if (shotWidth < 1 || shotHeight < 1) {
267
- logger_1.default.warn(`The retrieved screenshot size ${shotWidth}x${shotHeight} does ` +
268
- `not seem to be valid. No changes will be applied to the screenshot`);
269
- return { b64Screenshot };
270
- }
271
- if (screenWidth === shotWidth && screenHeight === shotHeight) {
272
- // the height and width of the screenshot and the device screen match, which
273
- // means we should be safe when doing template matches
274
- logger_1.default.info('Screenshot size matched screen size');
275
- return { b64Screenshot };
276
- }
277
- // otherwise, if they don't match, it could spell problems for the accuracy
278
- // of coordinates returned by the image match algorithm, since we match based
279
- // on the screenshot coordinates not the device coordinates themselves. There
280
- // are two potential types of mismatch: aspect ratio mismatch and scale
281
- // mismatch. We need to detect and fix both
282
- const scale = { xScale: 1.0, yScale: 1.0 };
283
- const screenAR = screenWidth / screenHeight;
284
- const shotAR = shotWidth / shotHeight;
285
- if (Math.round(screenAR * FLOAT_PRECISION) === Math.round(shotAR * FLOAT_PRECISION)) {
286
- logger_1.default.info(`Screenshot aspect ratio '${shotAR}' (${shotWidth}x${shotHeight}) matched ` +
287
- `screen aspect ratio '${screenAR}' (${screenWidth}x${screenHeight})`);
288
- }
289
- else {
290
- logger_1.default.warn(`When trying to find an element, determined that the screen ` +
291
- `aspect ratio and screenshot aspect ratio are different. Screen ` +
292
- `is ${screenWidth}x${screenHeight} whereas screenshot is ` +
293
- `${shotWidth}x${shotHeight}.`);
294
- // In the case where the x-scale and y-scale are different, we need to decide
295
- // which one to respect, otherwise the screenshot and template will end up
296
- // being resized in a way that changes its aspect ratio (distorts it). For example, let's say:
297
- // this.getScreenshot(shotWidth, shotHeight) is 540x397,
298
- // this.getDeviceSize(screenWidth, screenHeight) is 1080x1920.
299
- // The ratio would then be {xScale: 0.5, yScale: 0.2}.
300
- // In this case, we must should `yScale: 0.2` as scaleFactor, because
301
- // if we select the xScale, the height will be bigger than real screenshot size
302
- // which is used to image comparison by OpenCV as a base image.
303
- // All of this is primarily useful when the screenshot is a horizontal slice taken out of the
304
- // screen (for example not including top/bottom nav bars)
305
- const xScale = (1.0 * shotWidth) / screenWidth;
306
- const yScale = (1.0 * shotHeight) / screenHeight;
307
- const scaleFactor = xScale >= yScale ? yScale : xScale;
308
- logger_1.default.warn(`Resizing screenshot to ${shotWidth * scaleFactor}x${shotHeight * scaleFactor} to match ` +
309
- `screen aspect ratio so that image element coordinates have a ` +
310
- `greater chance of being correct.`);
311
- imgObj = imgObj.resize(shotWidth * scaleFactor, shotHeight * scaleFactor);
312
- scale.xScale *= scaleFactor;
313
- scale.yScale *= scaleFactor;
314
- shotWidth = imgObj.bitmap.width;
315
- shotHeight = imgObj.bitmap.height;
316
- }
317
- // Resize based on the screen dimensions only if both width and height are mismatched
318
- // since except for that, it might be a situation which is different window rect and
319
- // screenshot size like `@driver.window_rect #=>x=0, y=0, width=1080, height=1794` and
320
- // `"deviceScreenSize"=>"1080x1920"`
321
- if (screenWidth !== shotWidth && screenHeight !== shotHeight) {
322
- logger_1.default.info(`Scaling screenshot from ${shotWidth}x${shotHeight} to match ` +
323
- `screen at ${screenWidth}x${screenHeight}`);
324
- imgObj = imgObj.resize(screenWidth, screenHeight);
325
- scale.xScale *= (1.0 * screenWidth) / shotWidth;
326
- scale.yScale *= (1.0 * screenHeight) / shotHeight;
327
- }
328
- b64Screenshot = (yield imgObj.getBuffer(support_1.imageUtil.MIME_PNG)).toString('base64');
329
- return { b64Screenshot, scale };
330
- });
231
+ async getScreenshotForImageFind(screenWidth, screenHeight) {
232
+ if (!this.driver.getScreenshot) {
233
+ throw new Error("This driver does not support the required 'getScreenshot' command");
234
+ }
235
+ const settings = Object.assign({}, DEFAULT_SETTINGS, this.driver.settings.getSettings());
236
+ const { fixImageFindScreenshotDims } = settings;
237
+ let b64Screenshot = await this.driver.getScreenshot();
238
+ // if the user has requested not to correct for aspect or size differences
239
+ // between the screenshot and the screen, just return the screenshot now
240
+ if (!fixImageFindScreenshotDims) {
241
+ logger_1.default.info(`Not verifying screenshot dimensions match screen`);
242
+ return { b64Screenshot };
243
+ }
244
+ if (screenWidth < 1 || screenHeight < 1) {
245
+ logger_1.default.warn(`The retrieved screen size ${screenWidth}x${screenHeight} does ` +
246
+ `not seem to be valid. No changes will be applied to the screenshot`);
247
+ return { b64Screenshot };
248
+ }
249
+ // otherwise, do some verification on the screenshot to make sure it matches
250
+ // the screen size and aspect ratio
251
+ logger_1.default.info('Verifying screenshot size and aspect ratio');
252
+ let imgObj = await support_1.imageUtil.getJimpImage(b64Screenshot);
253
+ let { width: shotWidth, height: shotHeight } = imgObj.bitmap;
254
+ if (shotWidth < 1 || shotHeight < 1) {
255
+ logger_1.default.warn(`The retrieved screenshot size ${shotWidth}x${shotHeight} does ` +
256
+ `not seem to be valid. No changes will be applied to the screenshot`);
257
+ return { b64Screenshot };
258
+ }
259
+ if (screenWidth === shotWidth && screenHeight === shotHeight) {
260
+ // the height and width of the screenshot and the device screen match, which
261
+ // means we should be safe when doing template matches
262
+ logger_1.default.info('Screenshot size matched screen size');
263
+ return { b64Screenshot };
264
+ }
265
+ // otherwise, if they don't match, it could spell problems for the accuracy
266
+ // of coordinates returned by the image match algorithm, since we match based
267
+ // on the screenshot coordinates not the device coordinates themselves. There
268
+ // are two potential types of mismatch: aspect ratio mismatch and scale
269
+ // mismatch. We need to detect and fix both
270
+ const scale = { xScale: 1.0, yScale: 1.0 };
271
+ const screenAR = screenWidth / screenHeight;
272
+ const shotAR = shotWidth / shotHeight;
273
+ if (Math.round(screenAR * FLOAT_PRECISION) === Math.round(shotAR * FLOAT_PRECISION)) {
274
+ logger_1.default.info(`Screenshot aspect ratio '${shotAR}' (${shotWidth}x${shotHeight}) matched ` +
275
+ `screen aspect ratio '${screenAR}' (${screenWidth}x${screenHeight})`);
276
+ }
277
+ else {
278
+ logger_1.default.warn(`When trying to find an element, determined that the screen ` +
279
+ `aspect ratio and screenshot aspect ratio are different. Screen ` +
280
+ `is ${screenWidth}x${screenHeight} whereas screenshot is ` +
281
+ `${shotWidth}x${shotHeight}.`);
282
+ // In the case where the x-scale and y-scale are different, we need to decide
283
+ // which one to respect, otherwise the screenshot and template will end up
284
+ // being resized in a way that changes its aspect ratio (distorts it). For example, let's say:
285
+ // this.getScreenshot(shotWidth, shotHeight) is 540x397,
286
+ // this.getDeviceSize(screenWidth, screenHeight) is 1080x1920.
287
+ // The ratio would then be {xScale: 0.5, yScale: 0.2}.
288
+ // In this case, we must should `yScale: 0.2` as scaleFactor, because
289
+ // if we select the xScale, the height will be bigger than real screenshot size
290
+ // which is used to image comparison by OpenCV as a base image.
291
+ // All of this is primarily useful when the screenshot is a horizontal slice taken out of the
292
+ // screen (for example not including top/bottom nav bars)
293
+ const xScale = (1.0 * shotWidth) / screenWidth;
294
+ const yScale = (1.0 * shotHeight) / screenHeight;
295
+ const scaleFactor = xScale >= yScale ? yScale : xScale;
296
+ logger_1.default.warn(`Resizing screenshot to ${shotWidth * scaleFactor}x${shotHeight * scaleFactor} to match ` +
297
+ `screen aspect ratio so that image element coordinates have a ` +
298
+ `greater chance of being correct.`);
299
+ imgObj = imgObj.resize(shotWidth * scaleFactor, shotHeight * scaleFactor);
300
+ scale.xScale *= scaleFactor;
301
+ scale.yScale *= scaleFactor;
302
+ shotWidth = imgObj.bitmap.width;
303
+ shotHeight = imgObj.bitmap.height;
304
+ }
305
+ // Resize based on the screen dimensions only if both width and height are mismatched
306
+ // since except for that, it might be a situation which is different window rect and
307
+ // screenshot size like `@driver.window_rect #=>x=0, y=0, width=1080, height=1794` and
308
+ // `"deviceScreenSize"=>"1080x1920"`
309
+ if (screenWidth !== shotWidth && screenHeight !== shotHeight) {
310
+ logger_1.default.info(`Scaling screenshot from ${shotWidth}x${shotHeight} to match ` +
311
+ `screen at ${screenWidth}x${screenHeight}`);
312
+ imgObj = imgObj.resize(screenWidth, screenHeight);
313
+ scale.xScale *= (1.0 * screenWidth) / shotWidth;
314
+ scale.yScale *= (1.0 * screenHeight) / shotHeight;
315
+ }
316
+ b64Screenshot = (await imgObj.getBuffer(support_1.imageUtil.MIME_PNG)).toString('base64');
317
+ return { b64Screenshot, scale };
331
318
  }
332
319
  /**
333
320
  * @typedef {Object} ImageTemplateSettings
@@ -351,47 +338,45 @@ class ImageElementFinder {
351
338
  *
352
339
  * @returns {string} base64-encoded scaled template screenshot
353
340
  */
354
- fixImageTemplateScale(b64Template, opts = {}) {
355
- return __awaiter(this, void 0, void 0, function* () {
356
- if (!opts) {
357
- return b64Template;
358
- }
359
- let { fixImageTemplateScale = false, defaultImageTemplateScale = image_element_1.DEFAULT_TEMPLATE_IMAGE_SCALE, ignoreDefaultImageTemplateScale = false, xScale = DEFAULT_FIX_IMAGE_TEMPLATE_SCALE, yScale = DEFAULT_FIX_IMAGE_TEMPLATE_SCALE } = opts;
360
- if (ignoreDefaultImageTemplateScale) {
361
- defaultImageTemplateScale = image_element_1.DEFAULT_TEMPLATE_IMAGE_SCALE;
362
- }
363
- // Default
364
- if (defaultImageTemplateScale === image_element_1.DEFAULT_TEMPLATE_IMAGE_SCALE && !fixImageTemplateScale) {
365
- return b64Template;
366
- }
367
- // Calculate xScale and yScale Appium should scale
368
- if (fixImageTemplateScale) {
369
- xScale *= defaultImageTemplateScale;
370
- yScale *= defaultImageTemplateScale;
371
- }
372
- else {
373
- xScale = yScale = 1 * defaultImageTemplateScale;
374
- }
375
- // xScale and yScale can be NaN if defaultImageTemplateScale is string, for example
376
- if (!parseFloat(xScale) || !parseFloat(yScale)) {
377
- return b64Template;
378
- }
379
- // Return if the scale is default, 1, value
380
- if (Math.round(xScale * FLOAT_PRECISION) === Math.round(DEFAULT_FIX_IMAGE_TEMPLATE_SCALE * FLOAT_PRECISION)
381
- && Math.round(yScale * FLOAT_PRECISION === Math.round(DEFAULT_FIX_IMAGE_TEMPLATE_SCALE * FLOAT_PRECISION))) {
382
- return b64Template;
383
- }
384
- let imgTempObj = yield support_1.imageUtil.getJimpImage(b64Template);
385
- let { width: baseTempWidth, height: baseTempHeigh } = imgTempObj.bitmap;
386
- const scaledWidth = baseTempWidth * xScale;
387
- const scaledHeight = baseTempHeigh * yScale;
388
- logger_1.default.info(`Scaling template image from ${baseTempWidth}x${baseTempHeigh}` +
389
- ` to ${scaledWidth}x${scaledHeight}`);
390
- logger_1.default.info(`The ratio is ${xScale} and ${yScale}`);
391
- imgTempObj = yield imgTempObj.resize(scaledWidth, scaledHeight);
392
- return (yield imgTempObj.getBuffer(support_1.imageUtil.MIME_PNG)).toString('base64');
393
- });
341
+ async fixImageTemplateScale(b64Template, opts = {}) {
342
+ if (!opts) {
343
+ return b64Template;
344
+ }
345
+ let { fixImageTemplateScale = false, defaultImageTemplateScale = image_element_1.DEFAULT_TEMPLATE_IMAGE_SCALE, ignoreDefaultImageTemplateScale = false, xScale = DEFAULT_FIX_IMAGE_TEMPLATE_SCALE, yScale = DEFAULT_FIX_IMAGE_TEMPLATE_SCALE } = opts;
346
+ if (ignoreDefaultImageTemplateScale) {
347
+ defaultImageTemplateScale = image_element_1.DEFAULT_TEMPLATE_IMAGE_SCALE;
348
+ }
349
+ // Default
350
+ if (defaultImageTemplateScale === image_element_1.DEFAULT_TEMPLATE_IMAGE_SCALE && !fixImageTemplateScale) {
351
+ return b64Template;
352
+ }
353
+ // Calculate xScale and yScale Appium should scale
354
+ if (fixImageTemplateScale) {
355
+ xScale *= defaultImageTemplateScale;
356
+ yScale *= defaultImageTemplateScale;
357
+ }
358
+ else {
359
+ xScale = yScale = 1 * defaultImageTemplateScale;
360
+ }
361
+ // xScale and yScale can be NaN if defaultImageTemplateScale is string, for example
362
+ if (!parseFloat(xScale) || !parseFloat(yScale)) {
363
+ return b64Template;
364
+ }
365
+ // Return if the scale is default, 1, value
366
+ if (Math.round(xScale * FLOAT_PRECISION) === Math.round(DEFAULT_FIX_IMAGE_TEMPLATE_SCALE * FLOAT_PRECISION)
367
+ && Math.round(yScale * FLOAT_PRECISION === Math.round(DEFAULT_FIX_IMAGE_TEMPLATE_SCALE * FLOAT_PRECISION))) {
368
+ return b64Template;
369
+ }
370
+ let imgTempObj = await support_1.imageUtil.getJimpImage(b64Template);
371
+ let { width: baseTempWidth, height: baseTempHeigh } = imgTempObj.bitmap;
372
+ const scaledWidth = baseTempWidth * xScale;
373
+ const scaledHeight = baseTempHeigh * yScale;
374
+ logger_1.default.info(`Scaling template image from ${baseTempWidth}x${baseTempHeigh}` +
375
+ ` to ${scaledWidth}x${scaledHeight}`);
376
+ logger_1.default.info(`The ratio is ${xScale} and ${yScale}`);
377
+ imgTempObj = await imgTempObj.resize(scaledWidth, scaledHeight);
378
+ return (await imgTempObj.getBuffer(support_1.imageUtil.MIME_PNG)).toString('base64');
394
379
  }
395
380
  }
396
381
  exports.default = ImageElementFinder;
397
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vbGliL2ZpbmRlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7QUFBQSxvREFBdUI7QUFDdkIsMERBQTRCO0FBQzVCLDZDQUFrRDtBQUNsRCxxREFBNkM7QUFDN0MsbURBQzREO0FBQzVELHVDQUF3RjtBQUN4RixzREFBMkI7QUFFM0IsTUFBTSxtQkFBbUIsR0FBRyxTQUFTLENBQUM7QUF3Ylosa0RBQW1CO0FBdmI3QyxNQUFNLGVBQWUsR0FBRyxjQUFJLENBQUMsMEJBQTBCLENBQUM7QUF1Yi9DLDBDQUFlO0FBdGJ4QixNQUFNLGdDQUFnQyxHQUFHLENBQUMsQ0FBQztBQXNic0IsNEVBQWdDO0FBcmJqRyx5Q0FBeUM7QUFDekMsaUZBQWlGO0FBQ2pGLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQztBQUMvQixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU87QUFFaEQsTUFBTSxnQkFBZ0IsR0FBRztJQUN2QiwwRUFBMEU7SUFDMUUsNEJBQTRCO0lBQzVCLG1CQUFtQixFQUFFLGlDQUF1QjtJQUU1QywwQ0FBMEM7SUFDMUMsbUhBQW1IO0lBQ25ILG9CQUFvQjtJQUNwQiw4QkFBOEI7SUFDOUIsZ0JBQWdCLEVBQUUsRUFBRTtJQUVwQix5RUFBeUU7SUFDekUsbURBQW1EO0lBQ25ELDBCQUEwQixFQUFFLElBQUk7SUFFaEMsMkVBQTJFO0lBQzNFLDZFQUE2RTtJQUM3RSxXQUFXO0lBQ1gsb0JBQW9CLEVBQUUsS0FBSztJQUUzQiwyRUFBMkU7SUFDM0UsMkVBQTJFO0lBQzNFLCtCQUErQjtJQUMvQiwwRUFBMEU7SUFDMUUsK0VBQStFO0lBQy9FLDZFQUE2RTtJQUM3RSxxQkFBcUIsRUFBRSxLQUFLO0lBRTVCLHVFQUF1RTtJQUN2RSxpRkFBaUY7SUFDakYsNEVBQTRFO0lBQzVFLHlGQUF5RjtJQUN6RixrRkFB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
382
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmluZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vbGliL2ZpbmRlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxvREFBdUI7QUFDdkIsMERBQTRCO0FBQzVCLDZDQUFrRDtBQUNsRCxxREFBNkM7QUFDN0MsbURBQzREO0FBQzVELHVDQUF3RjtBQUN4RixzREFBMkI7QUFFM0IsTUFBTSxtQkFBbUIsR0FBRyxTQUFTLENBQUM7QUF3Ylosa0RBQW1CO0FBdmI3QyxNQUFNLGVBQWUsR0FBRyxjQUFJLENBQUMsMEJBQTBCLENBQUM7QUF1Yi9DLDBDQUFlO0FBdGJ4QixNQUFNLGdDQUFnQyxHQUFHLENBQUMsQ0FBQztBQXNic0IsNEVBQWdDO0FBcmJqRyx5Q0FBeUM7QUFDekMsaUZBQWlGO0FBQ2pGLE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQztBQUMvQixNQUFNLGNBQWMsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDLE9BQU87QUFFaEQsTUFBTSxnQkFBZ0IsR0FBRztJQUN2QiwwRUFBMEU7SUFDMUUsNEJBQTRCO0lBQzVCLG1CQUFtQixFQUFFLGlDQUF1QjtJQUU1QywwQ0FBMEM7SUFDMUMsbUhBQW1IO0lBQ25ILG9CQUFvQjtJQUNwQiw4QkFBOEI7SUFDOUIsZ0JBQWdCLEVBQUUsRUFBRTtJQUVwQix5RUFBeUU7SUFDekUsbURBQW1EO0lBQ25ELDBCQUEwQixFQUFFLElBQUk7SUFFaEMsMkVBQTJFO0lBQzNFLDZFQUE2RTtJQUM3RSxXQUFXO0lBQ1gsb0JBQW9CLEVBQUUsS0FBSztJQUUzQiwyRUFBMkU7SUFDM0UsMkVBQTJFO0lBQzNFLCtCQUErQjtJQUMvQiwwRUFBMEU7SUFDMUUsK0VBQStFO0lBQy9FLDZFQUE2RTtJQUM3RSxxQkFBcUIsRUFBRSxLQUFLO0lBRTVCLHVFQUF1RTtJQUN2RSxpRkFBaUY7SUFDakYsNEVBQTRFO0lBQzVFLHlGQUF5RjtJQUN6RixrRkFBa0Y7SUFDbEYs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