Skip to content
This repository has been archived by the owner on Oct 25, 2023. It is now read-only.

Fix find element wrong coordinate #306

Merged
merged 10 commits into from
Mar 1, 2019

Conversation

KazuCocoa
Copy link
Member

@KazuCocoa KazuCocoa commented Feb 23, 2019

closes appium/appium#12209

@jlipps Can you give me a good example app for if (screenAR === shotAR) lines I can confirm?
I simply commented out for now. If we do not need this, I would like to remove them.


will update https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/image-elements.md later


problem

find by image feature returns wrong coordinate in Android and iOS case.
test cases in below test section fails even it compares same image/element.

For Android

In here, Appium scales screenshot to window size. Then, Appium uses the scaled image as an input for compareImages.

e.g.
The screenshot is 1080x1920. The window size is 1080x1794. OpenCV compares a template image with the screenshot which is scaled from 1080x1920 to 1080x1794. Then Appium returns 1080x1794 based coordinations if it succeeds to find the template image. (But the returns coordinate should be 1080x1920 based one, since find_element :accessibility_id, xxxx returns rect based on 1080x1920 based size.

For iOS

iOS returns 750 × 1334 pixels screenshot evern the window size is width=375, height=667.
compareImages uses scaled screenshot from 750 × 1334 pixels to width=375, height=667. The ratio is 2.
Users should coordinate a template image scale if they would like to use 750 × 1334 pixels screenshot based image as the template image to fixt to width=375, height=667.

It means:
Cannot find proper image

el = @@driver.find_element :accessibility_id, 'Buttons' # find an element labelled 'buttons'
@driver.save_element_screenshot el, 'test_ios_button.png' # Save the element image

image_element = @driver.find_element_by_image 'test_ios_button.png' # Find image with the above element
image_element # raise no element found error because the input image is based on `750 × 1334 pixels` size

Then, users should do:

el = @@driver.find_element :accessibility_id, 'Buttons' # find an element labelled 'buttons'
@driver.save_element_screenshot el, 'test_ios_button.png' # Save the element image

# Need a process to scale `test_ios_button.png` down to fit to `width=375, height=667` size

image_element = @driver.find_element_by_image 'test_ios_button.png'
image_element # can find image

Implementation

  • Get rid of here
    • @jlipps Do you have a good example for this implementation?
  • Introduce fixScaleTemplateImage for iOS case to reduce user actions for an input image

test

https://github.com/appium/ruby_lib_core/pull/193/files is an example to make sure this PR works.
In the test, I ensured the below case for Android and iOS:

  1. Find an element
  2. Get the element screenshot
  3. Find an element by image using step2 's partial image
  4. Assert rect etc between step1 and step3

They worked after this PR.
(This includes landscape and portrait mode.)

helpers.fixScaleTemplateImage = async function (b64Template, scale) {
if (!scale) {
return b64Template;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scale might be destructed here

Copy link
Contributor

@mykola-mokhnach mykola-mokhnach Feb 28, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean const {xScale, yScale} = scale, so you don't have to always add scele. prefix

@@ -201,7 +201,8 @@ helpers.findByImage = async function (b64Template, {
}) {
const {
imageMatchThreshold: threshold,
fixImageTemplateSize
fixImageTemplateSize,
fixTemplateImageScale
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets be consistent fixImageTemplateSize + fixImageTemplateScale %)

*
* @param {string} b64Template - base64-encoded image used as a template to be
* matched in the screenshot
* @param {?ScreenshotScale} scale - scale of screen
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be better for the readability if you provide the default value for the argument if it is optional (scale=null)

@KazuCocoa
Copy link
Member Author

I'm about to merge this in order to publish this via at beta.
I'll re-consider 4fb91b9 again if the beta has ratio issue.
(Perhaps, scaling width or hight base is pretty enough in many cases.)

@KazuCocoa KazuCocoa merged commit 3ec8e56 into appium:master Mar 1, 2019
@KazuCocoa KazuCocoa deleted the fix-find-element-wrong-coordinate branch March 1, 2019 01:23
// screenshot size like `@driver.window_rect #=>x=0, y=0, width=1080, height=1794` and
// `"deviceScreenSize"=>"1080x1920"`
let scale;
if (screenWidth !== shotWidth && screenHeight !== shotHeight) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will consider different ratio case more (and create a PR)

valfirst pushed a commit to vividus-framework/vividus that referenced this pull request Sep 7, 2022
The ratio between the device window size and taken screenshot size is always equal to 1 regardless of the device display density on Android platform.See for details: appium/appium-base-driver#306.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

find by image returns wrong coordinate
2 participants