Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
9b57d81
Added OpenCV service and ActionImage
teo-nikolov Nov 11, 2024
5b8b165
updated pom.xml
teo-nikolov Nov 11, 2024
ba4d7d3
updated getting started
teo-nikolov Nov 11, 2024
2b1c5bc
updated ActionImage click location
teo-nikolov Nov 12, 2024
69d0780
fix null pointer in bdd logging listener
Nov 27, 2024
809c502
add option to covert to grayscale
Nov 27, 2024
be71747
Added new takeScreenshot method
mei-kyoseva Jan 6, 2025
f202c00
Made screenshot plugins register as their superclass ScreenshotPlugin…
mei-kyoseva Jan 6, 2025
d32accf
Moved OpenCvService in a separate module
mei-kyoseva Jan 6, 2025
b15ef94
Removed a comment and extracted logic in method createResultMatrix() …
mei-kyoseva Jan 6, 2025
b389d2a
Refactored OpenCvService
mei-kyoseva Jan 6, 2025
43c7c04
Removed unnecessary dependency on App for Actions object in ActionImage
mei-kyoseva Jan 6, 2025
c2418ff
Moved ByImageBase64 in ImageBase64FindStrategy as a static nested class
mei-kyoseva Jan 6, 2025
e3fbc81
Made 2 setSize overload methods in BrowserService in web
mei-kyoseva Jan 6, 2025
3d7cd48
created byImage and allByImage create methods
mei-kyoseva Jan 6, 2025
b119865
Removed redundant pom dependencies in web module
mei-kyoseva Jan 6, 2025
cfc2735
Added ActionImage for playwright module
mei-kyoseva Jan 6, 2025
34e0d0b
Update OpenCvDemoTests.java
mei-kyoseva Jan 6, 2025
f2fcdbb
extracted change to grayscale logic in a method
mei-kyoseva Jan 6, 2025
1701b2a
Merge branch 'main' into bellatrix-opencv-actionimage-update
mei-kyoseva Jan 6, 2025
241b42f
Made creation of every type of WebComponent via Image possible for we…
mei-kyoseva Jan 6, 2025
e55eabc
add framework tests for OpenCV
Jan 16, 2025
8689f0a
fixed issue with Browser lifecycle, added more tests
Jan 17, 2025
4f04e8e
unbided BrowserService and JavaScriptService from instances of the dr…
mei-kyoseva Jan 17, 2025
033dc64
made different service methods reuse an instance saved in SingletonFa…
mei-kyoseva Jan 17, 2025
70140de
revert change in ImageBase64FindStrategy
mei-kyoseva Jan 17, 2025
662af6c
android module image find strategies
mei-kyoseva Jan 20, 2025
876fc8b
desktop module image find strategies
mei-kyoseva Jan 20, 2025
afa09ef
ios module image find strategies
mei-kyoseva Jan 20, 2025
d4caf48
Merge branch 'main' into bellatrix-opencv-actionimage-update
mei-kyoseva Jan 28, 2025
871853f
added detailed exception message for opencv and vrt in case the scree…
mei-kyoseva Jan 28, 2025
0b9e55b
fix outdated framework tests
Jan 28, 2025
b790b43
Merge remote-tracking branch 'origin/bellatrix-opencv-actionimage-upd…
Jan 28, 2025
dead132
add info about Image Match finder tool
Jan 28, 2025
c2258a9
fixed dependency issue
mei-kyoseva Jan 29, 2025
a062391
playwright-openCV integration for finding components of all kinds by …
mei-kyoseva Jan 31, 2025
0e9feb6
playwright openCV tests
mei-kyoseva Jan 31, 2025
43a6f44
Merge branch 'main' into bellatrix-opencv-actionimage-update
mei-kyoseva Jan 31, 2025
52cbd55
renamed getting started opencv getting started from 25 to 26
mei-kyoseva Jan 31, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,7 @@
import org.openqa.selenium.interactions.Actions;
import solutions.bellatrix.android.components.contracts.Component;
import solutions.bellatrix.android.configuration.AndroidSettings;
import solutions.bellatrix.android.findstrategies.FindStrategy;
import solutions.bellatrix.android.findstrategies.NameFindStrategy;
import solutions.bellatrix.android.findstrategies.TagFindStrategy;
import solutions.bellatrix.android.findstrategies.XPathFindStrategy;
import solutions.bellatrix.android.findstrategies.*;
import solutions.bellatrix.android.infrastructure.DriverService;
import solutions.bellatrix.android.services.AppService;
import solutions.bellatrix.android.services.ComponentCreateService;
Expand All @@ -36,6 +33,7 @@
import solutions.bellatrix.core.utilities.DebugInformation;
import solutions.bellatrix.core.utilities.InstanceFactory;
import solutions.bellatrix.core.utilities.Log;
import solutions.bellatrix.plugins.opencv.Base64Encodable;

import java.awt.Dimension;
import java.util.ArrayList;
Expand Down Expand Up @@ -221,6 +219,10 @@ public <TComponent extends AndroidComponent, TFindStrategy extends FindStrategy>
return createAll(componentClass, findStrategy);
}

public <TComponent extends AndroidComponent> TComponent createByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return create(componentClass, new ImageBase64FindStrategy(encodedImage));
}

public <TComponent extends AndroidComponent> TComponent createByXPath(Class<TComponent> componentClass, String xpath) {
return create(componentClass, new XPathFindStrategy(xpath));
}
Expand All @@ -237,6 +239,11 @@ public <TComponent extends AndroidComponent> List<TComponent> createAllByName(Cl
return createAll(componentClass, new NameFindStrategy(name));
}

public <TComponent extends AndroidComponent> List<TComponent> createAllByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return createAll(componentClass, new ImageBase64FindStrategy(encodedImage));
}


public <TComponent extends AndroidComponent> List<TComponent> createAllByXPath(Class<TComponent> componentClass, String xpath) {
return createAll(componentClass, new XPathFindStrategy(xpath));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,6 @@ public class AndroidSettings {

@Getter @Setter private Boolean videosOnFailEnabled;
@Getter @Setter private String videosSaveLocation;

@Getter @Setter private Boolean allowImageFindStrategies;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2025 Automate The Planet Ltd.
* Author: Miriyam Kyoseva
* Licensed under the Apache License, Version 2.0 (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package solutions.bellatrix.android.findstrategies;

import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import org.openqa.selenium.WebElement;
import solutions.bellatrix.plugins.opencv.Base64Encodable;

import java.util.List;

public class ImageBase64FindStrategy extends FindStrategy {
private final Base64Encodable encodedImage;
public ImageBase64FindStrategy(Base64Encodable encodedImage) {
super(encodedImage.getImageName());
this.encodedImage = encodedImage;
}

@Override
public WebElement findElement(AndroidDriver driver) {
return driver.findElement(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public List<WebElement> findAllElements(AndroidDriver driver) {
return driver.findElements(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public WebElement findElement(WebElement element) {
return element.findElement(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public List<WebElement> findAllElements(WebElement element) {
return element.findElements(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public String toString() {
return String.format("image = %s", getValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ private static AndroidDriver initializeDriverGridMode(GridSettings gridSettings,
options.put("name", testName);
caps.setCapability(gridSettings.getOptionsName(), options);

if (ConfigurationService.get(AndroidSettings.class).getAllowImageFindStrategies())
caps.setCapability("use-plugins", "images");

AndroidDriver driver = null;
try {
driver = new AndroidDriver(new URL(gridSettings.getUrl()), caps);
Expand Down Expand Up @@ -134,6 +137,9 @@ private static AndroidDriver initializeDriverRegularMode(String serviceUrl) {
caps.setAppActivity(getAppConfiguration().getAppActivity());
}

if (ConfigurationService.get(AndroidSettings.class).getAllowImageFindStrategies())
caps.setCapability("use-plugins", "images");

addDriverConfigOptions(caps);
addCustomDriverOptions(caps);
var driver = new AndroidDriver(new URL(serviceUrl), caps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

package solutions.bellatrix.android.infrastructure;

import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import plugins.screenshots.ScreenshotPlugin;
Expand All @@ -35,7 +33,11 @@ public MobileScreenshotPlugin() {
}

@Override
@SneakyThrows
public byte[] takeScreenshot() {
return ((TakesScreenshot)DriverService.getWrappedAndroidDriver()).getScreenshotAs(OutputType.BYTES);
}

@Override
public String takeScreenshot(String name) {
var screenshotSaveDir = getOutputFolder();
var filename = getUniqueFileName(name);
Expand All @@ -57,7 +59,6 @@ public String takeScreenshot(String name) {
}

@Override
@SneakyThrows
public String takeScreenshot(String screenshotSaveDir, String filename) {
var screenshot = ((TakesScreenshot)DriverService.getWrappedAndroidDriver()).getScreenshotAs(OutputType.BASE64);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import solutions.bellatrix.android.findstrategies.*;
import solutions.bellatrix.android.infrastructure.DriverService;
import solutions.bellatrix.core.utilities.InstanceFactory;
import solutions.bellatrix.plugins.opencv.Base64Encodable;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -32,6 +33,10 @@ public <TComponent extends AndroidComponent, TFindStrategy extends FindStrategy>
return allBy(componentClass, findStrategy);
}

public <TComponent extends AndroidComponent> TComponent byImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return by(componentClass, new ImageBase64FindStrategy(encodedImage));
}

public <TComponent extends AndroidComponent> TComponent byId(Class<TComponent> componentClass, String id) {
return by(componentClass, new IdFindStrategy(id));
}
Expand Down Expand Up @@ -76,6 +81,10 @@ public <TComponent extends AndroidComponent> TComponent byIdContaining(Class<TCo
return by(componentClass, new IdContainingFindStrategy(idContaining));
}

public <TComponent extends AndroidComponent> List<TComponent> allByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return allBy(componentClass, new ImageBase64FindStrategy(encodedImage));
}

public <TComponent extends AndroidComponent> List<TComponent> allById(Class<TComponent> componentClass, String automationId) {
return allBy(componentClass, new IdFindStrategy(automationId));
}
Expand Down
6 changes: 6 additions & 0 deletions bellatrix.desktop/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,11 @@
<version>1.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>solutions.bellatrix</groupId>
<artifactId>bellatrix.plugins.opencv</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import solutions.bellatrix.desktop.services.ComponentCreateService;
import solutions.bellatrix.desktop.services.ComponentWaitService;
import solutions.bellatrix.desktop.waitstrategies.*;
import solutions.bellatrix.plugins.opencv.Base64Encodable;

import java.awt.Dimension;
import java.util.ArrayList;
Expand Down Expand Up @@ -247,6 +248,11 @@ public <TComponent extends DesktopComponent> TComponent createByAutomationId(Cla
return create(componentClass, new AutomationIdFindStrategy(automationId));
}

public <TComponent extends DesktopComponent> TComponent createByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return create(componentClass, new ImageBase64FindStrategy(encodedImage));
}


public <TComponent extends DesktopComponent> List<TComponent> createAllByAccessibilityId(Class<TComponent> componentClass, String accessibilityId) {
return createAll(componentClass, new AccessibilityIdFindStrategy(accessibilityId));
}
Expand Down Expand Up @@ -275,6 +281,10 @@ public <TComponent extends DesktopComponent> List<TComponent> createAllByIdConta
return createAll(componentClass, new IdContainingFindStrategy(idContaining));
}

public <TComponent extends DesktopComponent> List<TComponent> createAllByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return createAll(componentClass, new ImageBase64FindStrategy(encodedImage));
}

protected <TComponent extends DesktopComponent, TFindStrategy extends FindStrategy> TComponent create(Class<TComponent> componentClass, TFindStrategy findStrategy) {
CREATING_ELEMENT.broadcast(new ComponentActionEventArgs(this));
findElement();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,6 @@ public class DesktopSettings {

@Getter @Setter private Boolean videosOnFailEnabled;
@Getter @Setter private String videosSaveLocation;

@Getter @Setter private Boolean allowImageFindStrategies;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2025 Automate The Planet Ltd.
* Author: Miriyam Kyoseva
* Licensed under the Apache License, Version 2.0 (the "License");
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package solutions.bellatrix.desktop.findstrategies;

import io.appium.java_client.AppiumBy;
import io.appium.java_client.windows.WindowsDriver;
import org.openqa.selenium.WebElement;
import solutions.bellatrix.plugins.opencv.Base64Encodable;

import java.util.List;

public class ImageBase64FindStrategy extends FindStrategy {
private final Base64Encodable encodedImage;
public ImageBase64FindStrategy(Base64Encodable encodedImage) {
super(encodedImage.getImageName());
this.encodedImage = encodedImage;
}

@Override
public WebElement findElement(WindowsDriver driver) {
return driver.findElement(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public List<WebElement> findAllElements(WindowsDriver driver) {
return driver.findElements(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public WebElement findElement(WebElement element) {
return element.findElement(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public List<WebElement> findAllElements(WebElement element) {
return element.findElements(AppiumBy.image(encodedImage.getBase64Image()));
}

@Override
public String toString() {
return String.format("image = %s", getValue());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

package solutions.bellatrix.desktop.infrastructure;

import lombok.SneakyThrows;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import plugins.screenshots.ScreenshotPlugin;
Expand All @@ -35,7 +33,11 @@ public DesktopScreenshotPlugin() {
}

@Override
@SneakyThrows
public byte[] takeScreenshot() {
return ((TakesScreenshot)DriverService.getWrappedDriver()).getScreenshotAs(OutputType.BYTES);
}

@Override
public String takeScreenshot(String name) {
var screenshotSaveDir = getOutputFolder();
var filename = getUniqueFileName(name);
Expand All @@ -56,7 +58,6 @@ public String takeScreenshot(String name) {
}

@Override
@SneakyThrows
public String takeScreenshot(String screenshotSaveDir, String filename) {
var screenshot = ((TakesScreenshot)DriverService.getWrappedDriver()).getScreenshotAs(OutputType.BASE64);
Path path = Paths.get(screenshotSaveDir, filename);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ private static WindowsDriver initializeDriverGridMode(GridSettings gridSettings)
caps.setApp(getAppConfiguration().getAppPath().replace("\\", "/"));
caps.setAppWorkingDir(new File(getAppConfiguration().getAppPath()).getParent());

if (ConfigurationService.get(DesktopSettings.class).getAllowImageFindStrategies())
caps.setCapability("use-plugins", "images");

WindowsDriver driver = null;
try {
driver = new WindowsDriver(new URL(gridSettings.getUrl()), caps);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import solutions.bellatrix.desktop.components.DesktopComponent;
import solutions.bellatrix.desktop.findstrategies.*;
import solutions.bellatrix.desktop.infrastructure.DriverService;
import solutions.bellatrix.plugins.opencv.Base64Encodable;

import java.util.ArrayList;
import java.util.List;
Expand Down Expand Up @@ -60,6 +61,10 @@ public <TComponent extends DesktopComponent> TComponent byIdContaining(Class<TCo
return by(componentClass, new IdContainingFindStrategy(idContaining));
}

public <TComponent extends DesktopComponent> TComponent byImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return by(componentClass, new ImageBase64FindStrategy(encodedImage));
}

public <TComponent extends DesktopComponent> List<TComponent> allByAutomationId(Class<TComponent> componentClass, String automationId) {
return allBy(componentClass, new AutomationIdFindStrategy(automationId));
}
Expand Down Expand Up @@ -88,6 +93,10 @@ public <TComponent extends DesktopComponent> List<TComponent> allByIdContaining(
return allBy(componentClass, new IdContainingFindStrategy(idContaining));
}

public <TComponent extends DesktopComponent> List<TComponent> allByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return allBy(componentClass, new ImageBase64FindStrategy(encodedImage));
}

public <TComponent extends DesktopComponent, TFindStrategy extends FindStrategy> TComponent by(Class<TComponent> componentClass, TFindStrategy findStrategy) {
var component = InstanceFactory.create(componentClass);
component.setFindStrategy(findStrategy);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import solutions.bellatrix.ios.services.ComponentCreateService;
import solutions.bellatrix.ios.services.ComponentWaitService;
import solutions.bellatrix.ios.waitstrategies.*;
import solutions.bellatrix.plugins.opencv.Base64Encodable;

import java.awt.Dimension;
import java.util.ArrayList;
Expand Down Expand Up @@ -249,6 +250,10 @@ public <TComponent extends IOSComponent> TComponent createByIOSClassChain(Class<
return create(componentClass, new IOSClassChainFindStrategy(iosClassChain));
}

public <TComponent extends IOSComponent> TComponent createByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return create(componentClass, new ImageBase64FindStrategy(encodedImage));
}

public <TComponent extends IOSComponent> List<TComponent> createAllByName(Class<TComponent> componentClass, String name) {
return createAll(componentClass, new NameFindStrategy(name));
}
Expand Down Expand Up @@ -281,6 +286,10 @@ public <TComponent extends IOSComponent> List<TComponent> createAllByIOSClassCha
return createAll(componentClass, new IOSClassChainFindStrategy(iosClassChain));
}

public <TComponent extends IOSComponent> List<TComponent> createAllByImage(Class<TComponent> componentClass, Base64Encodable encodedImage) {
return createAll(componentClass, new ImageBase64FindStrategy(encodedImage));
}

protected <TComponent extends IOSComponent, TFindStrategy extends FindStrategy> TComponent create(Class<TComponent> componentClass, TFindStrategy findStrategy) {
CREATING_ELEMENT.broadcast(new ComponentActionEventArgs(this));
findElement();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,6 @@ public class IOSSettings {

@Getter @Setter private Boolean videosOnFailEnabled;
@Getter @Setter private String videosSaveLocation;

@Getter @Setter private Boolean allowImageFindStrategies;
}
Loading