18
18
/**
19
19
* Locator to search elements by image.
20
20
* Takes screenshot and finds match using openCV.
21
+ * Performs screenshot scaling if devicePixelRatio != 1.
21
22
* Then finds elements by coordinates using javascript.
22
23
*/
23
24
public class ByImage extends By {
24
25
private static boolean wasLibraryLoaded = false ;
25
26
private final Mat template ;
26
- private final boolean doScaling ;
27
27
28
28
private static void loadLibrary () {
29
29
if (!wasLibraryLoaded ) {
@@ -39,19 +39,8 @@ private static void loadLibrary() {
39
39
* @param file image file to locate element by.
40
40
*/
41
41
public ByImage (File file ) {
42
- this (file , false );
43
- }
44
-
45
- /**
46
- * Constructor accepting image file.
47
- *
48
- * @param file image file to locate element by.
49
- * @param doScaling perform screenshot scaling if devicePixelRatio != 1
50
- */
51
- public ByImage (File file , boolean doScaling ) {
52
42
loadLibrary ();
53
43
this .template = Imgcodecs .imread (file .getAbsolutePath (), Imgcodecs .IMREAD_UNCHANGED );
54
- this .doScaling = doScaling ;
55
44
}
56
45
57
46
/**
@@ -60,19 +49,8 @@ public ByImage(File file, boolean doScaling) {
60
49
* @param bytes image bytes to locate element by.
61
50
*/
62
51
public ByImage (byte [] bytes ) {
63
- this (bytes , false );
64
- }
65
-
66
- /**
67
- * Constructor accepting image file.
68
- *
69
- * @param bytes image bytes to locate element by.
70
- * @param doScaling perform screenshot scaling if devicePixelRatio != 1
71
- */
72
- public ByImage (byte [] bytes , boolean doScaling ) {
73
52
loadLibrary ();
74
53
this .template = Imgcodecs .imdecode (new MatOfByte (bytes ), Imgcodecs .IMREAD_UNCHANGED );
75
- this .doScaling = doScaling ;
76
54
}
77
55
78
56
@ Override
@@ -82,21 +60,14 @@ public String toString() {
82
60
83
61
@ Override
84
62
public List <WebElement > findElements (SearchContext context ) {
85
- byte [] screenshotBytes = getScreenshot (context );
86
- Mat source = Imgcodecs .imdecode (new MatOfByte (screenshotBytes ), Imgcodecs .IMREAD_UNCHANGED );
87
- long devicePixelRatio = (long ) AqualityServices .getBrowser ().executeScript (JavaScript .GET_DEVICE_PIXEL_RATIO );
88
- if (devicePixelRatio != 1 && doScaling ) {
89
- int scaledWidth = (int ) (source .width () / devicePixelRatio );
90
- int scaledHeight = (int ) (source .height () / devicePixelRatio );
91
- Imgproc .resize (source , source , new Size (scaledWidth , scaledHeight ), 0 , 0 , Imgproc .INTER_AREA );
92
- }
63
+ Mat source = getScreenshot (context );
93
64
Mat result = new Mat ();
94
65
Imgproc .matchTemplate (source , template , result , Imgproc .TM_CCOEFF_NORMED );
95
66
96
67
float threshold = 1 - AqualityServices .getConfiguration ().getVisualizationConfiguration ().getDefaultThreshold ();
97
68
Core .MinMaxLocResult minMaxLoc = Core .minMaxLoc (result );
98
69
99
- int matchCounter = ( result .width () - template .width () + 1 ) * (result .height () - template .height () + 1 );
70
+ int matchCounter = Math . abs (( result .width () - template .width () + 1 ) * (result .height () - template .height () + 1 ) );
100
71
List <Point > matchLocations = new ArrayList <>();
101
72
while (matchCounter > 0 && minMaxLoc .maxVal >= threshold ) {
102
73
matchCounter --;
@@ -149,11 +120,20 @@ protected static double distanceToPoint(Point matchLocation, WebElement element)
149
120
* Takes screenshot from searchContext if supported, or from browser.
150
121
*
151
122
* @param context search context for element location.
152
- * @return captured screenshot as byte array .
123
+ * @return captured screenshot as Mat object .
153
124
*/
154
- protected byte [] getScreenshot (SearchContext context ) {
155
- return !(context instanceof TakesScreenshot )
156
- ? AqualityServices .getBrowser ().getScreenshot ()
157
- : ((TakesScreenshot ) context ).getScreenshotAs (OutputType .BYTES );
125
+ protected Mat getScreenshot (SearchContext context ) {
126
+ byte [] screenshotBytes = context instanceof TakesScreenshot
127
+ ? ((TakesScreenshot ) context ).getScreenshotAs (OutputType .BYTES )
128
+ : AqualityServices .getBrowser ().getScreenshot ();
129
+ boolean isBrowserScreenshot = context instanceof WebDriver || !(context instanceof TakesScreenshot );
130
+ Mat source = Imgcodecs .imdecode (new MatOfByte (screenshotBytes ), Imgcodecs .IMREAD_UNCHANGED );
131
+ long devicePixelRatio = (long ) AqualityServices .getBrowser ().executeScript (JavaScript .GET_DEVICE_PIXEL_RATIO );
132
+ if (devicePixelRatio != 1 && isBrowserScreenshot ) {
133
+ int scaledWidth = (int ) (source .width () / devicePixelRatio );
134
+ int scaledHeight = (int ) (source .height () / devicePixelRatio );
135
+ Imgproc .resize (source , source , new Size (scaledWidth , scaledHeight ), 0 , 0 , Imgproc .INTER_AREA );
136
+ }
137
+ return source ;
158
138
}
159
139
}
0 commit comments