Skip to content

Commit 95b0655

Browse files
committed
initial commit
1 parent d20506d commit 95b0655

File tree

12 files changed

+627
-2
lines changed

12 files changed

+627
-2
lines changed

README.md

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,67 @@
1-
# selfheal-demo-browserstack
2-
Self Heal Demo Scripts
1+
# Self Heal Demo (TestNG)
2+
3+
## Overview
4+
This repository contains demo scripts and configuration for testing the self-healing feature on BrowserStack using Appium and TestNG. It includes two main components:
5+
6+
### 1. Base App (BaseApp.apk)
7+
- The base Android app used for automation and self-healing tests.
8+
- Located at: `android/testng-examples/BaseApp.apk`
9+
- This app serves as the reference for normal (non-self-healing) test runs.
10+
11+
### 2. Self-Heal App (SelfHealApp.apk)
12+
- The self-healing version of the app, built to demonstrate BrowserStack's self-heal capabilities.
13+
- Located at: `android/testng-examples/SelfHealApp.apk`
14+
- Used to validate how the self-heal feature recovers from locator changes or UI modifications.
15+
16+
## Test Scenarios Demonstrated
17+
- This repository includes two different test suites:
18+
- **Base App Test Suite:** Runs against the base app to show standard automation behavior without self-healing.
19+
- **Self-Heal App Test Suite:** Runs against the self-heal app with self-healing enabled to demonstrate how tests recover from locator changes or UI modifications.
20+
- The test names will differ between the two suites to clearly indicate which scenario is being executed (e.g., `BaseAppTest` vs `SelfHealAppTest`).
21+
- By comparing the results of these two test suites, you can clearly observe the benefits of the self-heal feature.
22+
23+
## How to Check Differences
24+
- Run your test suite with both the base app and the self-heal app.
25+
- Compare the results and logs: with self-heal enabled, tests should pass even if some locators have changed, while they may fail without self-heal.
26+
- You can also use diff tools to compare the APKs or source code if needed.
27+
28+
## About the Self-Heal Feature
29+
- The self-heal feature in BrowserStack automatically detects and recovers from locator changes in your app's UI during automated tests.
30+
- If a locator fails (e.g., due to a UI update), self-heal attempts to find the correct element using alternative strategies, allowing your tests to continue without manual intervention.
31+
- This reduces test flakiness and maintenance effort, especially in agile environments with frequent UI changes.
32+
- **To enable self-healing, set `selfHeal: true` in your `browserstack.yml` configuration file.**
33+
34+
#### Example `browserstack.yml` snippet:
35+
```yaml
36+
selfHeal: true
37+
```
38+
39+
## Usage
40+
- Build and upload the APKs to BrowserStack as needed.
41+
- Run your automation scripts using the provided configuration files.
42+
- Make sure `selfHeal: true` is set in your `browserstack.yml` to enable the self-heal feature.
43+
- Review the test results and logs to observe self-healing in action.
44+
45+
### Running Tests with Maven or Gradle
46+
- **For Maven:**
47+
- To run the Base App test suite:
48+
```sh
49+
mvn test -P sampleBaseAppTest
50+
```
51+
- To run the Self-Heal App test suite:
52+
```sh
53+
mvn test -P sampleSelfHealAppTest
54+
```
55+
- **For Gradle:**
56+
- To run the Base App test suite:
57+
```sh
58+
gradle clean sampleBaseAppTest
59+
```
60+
- To run the Self-Heal App test suite:
61+
```sh
62+
gradle clean sampleSelfHealAppTest
63+
```
64+
65+
## Getting Help
66+
67+
If you are running into any issues or have any queries, please check [Browserstack Support page](https://www.browserstack.com/support/app-automate) or [get in touch with us](https://www.browserstack.com/contact?ref=help).
7.07 MB
Binary file not shown.
7.07 MB
Binary file not shown.
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# =============================
2+
# Set BrowserStack Credentials
3+
# =============================
4+
# Add your BrowserStack userName and acccessKey here or set BROWSERSTACK_USERNAME and
5+
# BROWSERSTACK_ACCESS_KEY as env variables
6+
userName: BROWSERSTACK_USERNAME
7+
accessKey: BROWSERSTACK_ACCESS_KEY
8+
9+
# ======================
10+
# BrowserStack Reporting
11+
# ======================
12+
# The following capabilities are used to set up reporting on BrowserStack:
13+
# Set 'projectName' to the name of your project. Example, Marketing Website
14+
projectName: BrowserStack Samples
15+
# Set `buildName` as the name of the job / testsuite being run
16+
buildName: browserstack build
17+
# `buildIdentifier` is a unique id to differentiate every execution that gets appended to
18+
# buildName. Choose your buildIdentifier format from the available expressions:
19+
# ${BUILD_NUMBER} (Default): Generates an incremental counter with every execution
20+
# ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30
21+
# Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests
22+
buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression}
23+
# Set `framework` of your test suite. Example, `testng`, `cucumber`, `cucumber-testng`
24+
# This property is needed to send test context to BrowserStack (test name, status)
25+
framework: testng
26+
27+
source: testng:appium-sample-sdk:v1.1
28+
29+
app: ./BaseApp.apk
30+
# app: ./SelfHealApp.apk # For testing with the Self Heal App
31+
32+
# =======================================
33+
# Platforms (Browsers / Devices to test)
34+
# =======================================
35+
# Platforms object contains all the browser / device combinations you want to test on.
36+
# Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate)
37+
38+
platforms:
39+
- deviceName: Samsung Galaxy S22 Ultra
40+
osVersion: 12.0
41+
platformName: android
42+
- deviceName: Samsung Galaxy S21
43+
osVersion: 11.0
44+
platformName: android
45+
- deviceName: Google Pixel 6 Pro
46+
osVersion: 12.0
47+
platformName: android
48+
49+
# =======================
50+
# Parallels per Platform
51+
# =======================
52+
# The number of parallel threads to be used for each platform set.
53+
# BrowserStack's SDK runner will select the best strategy based on the configured value
54+
#
55+
# Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack
56+
#
57+
# Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack
58+
parallelsPerPlatform: 1
59+
60+
# ==========================================
61+
# BrowserStack Local
62+
# (For localhost, staging/private websites)
63+
# ==========================================
64+
# Set browserStackLocal to true if your website under test is not accessible publicly over the internet
65+
# Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction
66+
browserstackLocal: true # <boolean> (Default false)
67+
#browserStackLocalOptions:
68+
#Options to be passed to BrowserStack local in-case of advanced configurations
69+
# localIdentifier: # <string> (Default: null) Needed if you need to run multiple instances of local.
70+
# forceLocal: true # <boolean> (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel.
71+
# Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections
72+
73+
# ===================
74+
# Debugging features
75+
# ===================
76+
debug: false # <boolean> # Set to true if you need screenshots for every selenium command ran
77+
networkLogs: false # <boolean> Set to true to enable HAR logs capturing
78+
consoleLogs: errors # <string> Remote browser's console debug levels to be printed (Default: errors)
79+
# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors)
80+
81+
selfHeal: false # Set to true if you want to enable self-healing capabilities in your tests
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
plugins {
2+
id 'java'
3+
}
4+
5+
repositories { mavenCentral() }
6+
7+
dependencies {
8+
testImplementation 'org.testng:testng:7.5'
9+
implementation 'org.seleniumhq.selenium:selenium-java:4.13.0'
10+
implementation 'io.appium:java-client:8.6.0'
11+
implementation 'commons-io:commons-io:2.11.0'
12+
implementation 'com.googlecode.json-simple:json-simple:1.1.1'
13+
implementation 'com.browserstack:browserstack-java-sdk:latest.release'
14+
}
15+
16+
group = 'com.browserstack'
17+
version = '1.0-SNAPSHOT'
18+
description = 'testng-browserstack'
19+
sourceCompatibility = '1.8'
20+
21+
def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' }
22+
23+
tasks.withType(JavaCompile) {
24+
options.encoding = 'UTF-8'
25+
}
26+
27+
tasks.withType(Test) {
28+
systemProperties = System.properties
29+
}
30+
31+
task sampleBaseAppTest(type: Test) {
32+
useTestNG() {
33+
dependsOn cleanTest
34+
useDefaultListeners = true
35+
suites "src/test/resources/com/browserstack/sample-base-app-test.testng.xml"
36+
jvmArgs "-javaagent:${browserstackSDKArtifact.file}"
37+
}
38+
}
39+
40+
task sampleSelfHealAppTest(type: Test) {
41+
useTestNG() {
42+
dependsOn cleanTest
43+
useDefaultListeners = true
44+
suites "src/test/resources/com/browserstack/sample-self-heal-app-test.testng.xml"
45+
jvmArgs "-javaagent:${browserstackSDKArtifact.file}"
46+
}
47+
}

android/testng-examples/pom.xml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3+
<modelVersion>4.0.0</modelVersion>
4+
5+
<groupId>com.browserstack</groupId>
6+
<artifactId>testng-browserstack-android</artifactId>
7+
<version>1.0-SNAPSHOT</version>
8+
<packaging>jar</packaging>
9+
10+
<name>testng-appium-app</name>
11+
<url>https://github.com/browserstack/selfheal-demo-browserstack</url>
12+
13+
<properties>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
<maven.compiler.target>1.8</maven.compiler.target>
16+
<maven.compiler.source>1.8</maven.compiler.source>
17+
<surefire.version>2.19.1</surefire.version>
18+
<surefire.plugin.version>3.0.0-M5</surefire.plugin.version>
19+
<config.file>default</config.file>
20+
</properties>
21+
22+
<dependencies>
23+
<dependency>
24+
<groupId>org.testng</groupId>
25+
<artifactId>testng</artifactId>
26+
<version>7.5</version>
27+
</dependency>
28+
<dependency>
29+
<groupId>org.seleniumhq.selenium</groupId>
30+
<artifactId>selenium-java</artifactId>
31+
<version>4.13.0</version>
32+
</dependency>
33+
<dependency>
34+
<groupId>io.appium</groupId>
35+
<artifactId>java-client</artifactId>
36+
<version>8.6.0</version>
37+
</dependency>
38+
<dependency>
39+
<groupId>commons-io</groupId>
40+
<artifactId>commons-io</artifactId>
41+
<version>2.11.0</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>com.googlecode.json-simple</groupId>
45+
<artifactId>json-simple</artifactId>
46+
<version>1.1.1</version>
47+
</dependency>
48+
<dependency>
49+
<groupId>com.browserstack</groupId>
50+
<artifactId>browserstack-java-sdk</artifactId>
51+
<version>LATEST</version>
52+
<scope>compile</scope>
53+
</dependency>
54+
</dependencies>
55+
56+
<build>
57+
<plugins>
58+
<plugin>
59+
<artifactId>maven-dependency-plugin</artifactId>
60+
<version>3.3.0</version>
61+
<executions>
62+
<execution>
63+
<id>getClasspathFilenames</id>
64+
<goals>
65+
<goal>properties</goal>
66+
</goals>
67+
</execution>
68+
</executions>
69+
</plugin>
70+
<plugin>
71+
<groupId>org.apache.maven.plugins</groupId>
72+
<artifactId>maven-surefire-plugin</artifactId>
73+
<version>2.22.2</version>
74+
<configuration>
75+
<suiteXmlFiles>
76+
<suiteXmlFile>src/test/resources/com/browserstack/sample-base-app-test.testng.xml</suiteXmlFile>
77+
</suiteXmlFiles>
78+
<argLine>-javaagent:${com.browserstack:browserstack-java-sdk:jar}</argLine>
79+
</configuration>
80+
</plugin>
81+
<plugin>
82+
<groupId>org.apache.maven.plugins</groupId>
83+
<artifactId>maven-compiler-plugin</artifactId>
84+
<version>3.8.1</version>
85+
<configuration>
86+
<source>1.8</source>
87+
<target>1.8</target>
88+
</configuration>
89+
</plugin>
90+
</plugins>
91+
</build>
92+
93+
<profiles>
94+
<profile>
95+
<id>sampleBaseAppTest</id>
96+
<build>
97+
<plugins>
98+
<plugin>
99+
<groupId>org.apache.maven.plugins</groupId>
100+
<artifactId>maven-surefire-plugin</artifactId>
101+
<configuration>
102+
<suiteXmlFiles>
103+
<suiteXmlFile>src/test/resources/com/browserstack/sample-base-app-test.testng.xml</suiteXmlFile>
104+
</suiteXmlFiles>
105+
</configuration>
106+
</plugin>
107+
</plugins>
108+
</build>
109+
</profile>
110+
<profile>
111+
<id>sampleSelfHealAppTest</id>
112+
<build>
113+
<plugins>
114+
<plugin>
115+
<groupId>org.apache.maven.plugins</groupId>
116+
<artifactId>maven-surefire-plugin</artifactId>
117+
<configuration>
118+
<suiteXmlFiles>
119+
<suiteXmlFile>src/test/resources/com/browserstack/sample-self-heal-app-test.testng.xml</suiteXmlFile>
120+
</suiteXmlFiles>
121+
</configuration>
122+
</plugin>
123+
</plugins>
124+
</build>
125+
</profile>
126+
</profiles>
127+
</project>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pluginManagement {
2+
repositories {
3+
mavenCentral()
4+
mavenLocal()
5+
gradlePluginPortal()
6+
}
7+
8+
resolutionStrategy {
9+
eachPlugin {
10+
if (requested.id.id == "com.browserstack.gradle-sdk") {
11+
useModule("com.browserstack:gradle-sdk:1.1.2")
12+
}
13+
}
14+
}
15+
}
16+
rootProject.name = 'testng-browserstack-android'
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.browserstack;
2+
3+
import java.net.URL;
4+
5+
import org.openqa.selenium.MutableCapabilities;
6+
import org.testng.annotations.AfterMethod;
7+
import org.testng.annotations.BeforeMethod;
8+
9+
import io.appium.java_client.android.AndroidDriver;
10+
import io.appium.java_client.android.options.UiAutomator2Options;
11+
12+
13+
public class AppiumTest {
14+
15+
public AndroidDriver driver;
16+
17+
@BeforeMethod(alwaysRun=true)
18+
public void setUp() throws Exception {
19+
MutableCapabilities capabilities = new UiAutomator2Options();
20+
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
21+
}
22+
23+
@AfterMethod(alwaysRun=true)
24+
public void tearDown() throws Exception {
25+
driver.quit();
26+
}
27+
}

0 commit comments

Comments
 (0)