Files
appium/lib/basedriver/device-settings.js
T
Kazuaki Matsuo b38ef751f4 Fix template scale in find element by image (#307)
* add imageTemplateDefaultScale to scale arbitrary scale every time by default

* put all of template scaling into one method

* increase test cases to cover all situations

* define gnoreDefaultImageTemplateScale for click

* add a comment

* tweak comments

* fix typo, default value, docstring

* fix review

* fix ratio potential issue

* use const instead of let

* tweak a comment about scale factor

* remove _, tweak NaN comparison

* use math.round to compare two float

* rename float round constant

* fix typo

* update imgObj

* fix comments
2019-03-20 09:00:02 +09:00

98 lines
3.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import _ from 'lodash';
import log from './logger';
import { DEFAULT_MATCH_THRESHOLD } from './commands/images';
import { IMAGE_EL_TAP_STRATEGY_W3C, DEFAULT_TEMPLATE_IMAGE_SCALE } from './image-element';
const GLOBAL_DEFAULT_SETTINGS = {
// value between 0 and 1 representing match strength, below which an image
// element will not be found
imageMatchThreshold: DEFAULT_MATCH_THRESHOLD,
// if the image returned by getScreenshot differs in size or aspect ratio
// from the screen, attempt to fix it automatically
fixImageFindScreenshotDims: true,
// whether Appium should ensure that an image template sent in during image
// element find should have its size adjusted so the match algorithm will not
// complain
fixImageTemplateSize: false,
// whether Appium should ensure that an image template sent in during image
// element find should have its scale adjusted to display size so the match
// algorithm will not complain.
// e.g. iOS has `width=375, height=667` window rect, but its screenshot is
// `width=750 × height=1334` pixels. This setting help to adjust the scale
// if a user use `width=750 × height=1334` pixels's base template image.
fixImageTemplateScale: false,
// Users might have scaled template image to reduce their storage size.
// This setting allows users to scale a template image they send to Appium server
// so that the Appium server compares the actual scale users originally had.
// e.g. If a user has an image of 270 x 32 pixels which was originally 1080 x 126 pixels,
// the user can set {defaultImageTemplateScale: 4.0} to scale the small image
// to the original one so that Appium can compare it as the original one.
defaultImageTemplateScale: DEFAULT_TEMPLATE_IMAGE_SCALE,
// whether Appium should re-check that an image element can be matched
// against the current screenshot before clicking it
checkForImageElementStaleness: true,
// whether before clicking on an image element Appium should re-determine the
// position of the element on screen
autoUpdateImageElementPosition: false,
// which method to use for tapping by coordinate for image elements. the
// options are 'w3c' or 'mjsonwp'
imageElementTapStrategy: IMAGE_EL_TAP_STRATEGY_W3C,
};
// declare settings that are really handled only by basedriver, so downstream
// drivers can choose to ignore them for their own settings validation, etc...
const BASEDRIVER_HANDLED_SETTINGS = [
'imageMatchThreshold',
'fixImageFindScreenshotDims',
'fixImageTemplateSize',
'fixImageTemplateScale',
'defaultImageTemplateScale',
'checkForImageElementStaleness',
'autoUpdateImageElementPosition',
'imageElementTapStrategy',
];
class DeviceSettings {
constructor (defaultSettings = {}, onSettingsUpdate = null) {
this._settings = Object.assign({}, GLOBAL_DEFAULT_SETTINGS, defaultSettings);
this.onSettingsUpdate = onSettingsUpdate;
}
// calls updateSettings from implementing driver every time a setting is changed.
async update (newSettings) {
if (!_.isObject(newSettings)) {
throw new Error('Settings update should be called with valid JSON');
}
for (let prop of _.keys(newSettings)) {
if (_.isUndefined(this._settings[prop])) {
log.warn(`Didn't know about setting '${prop}'. Are you sure you ` +
`spelled it correctly? Proceeding anyway. Valid settings: ${_.keys(this._settings)}`);
}
if (this._settings[prop] !== newSettings[prop]) {
// update setting only when there is updateSettings defined.
if (this.onSettingsUpdate) {
await this.onSettingsUpdate(prop, newSettings[prop], this._settings[prop]);
this._settings[prop] = newSettings[prop];
} else {
log.errorAndThrow('Unable to update settings; onSettingsUpdate method not found');
}
}
}
}
getSettings () {
return this._settings;
}
}
export default DeviceSettings;
export { DeviceSettings, BASEDRIVER_HANDLED_SETTINGS };