diff --git a/app-automate/README.md b/app-automate/README.md
new file mode 100644
index 0000000..30a745d
--- /dev/null
+++ b/app-automate/README.md
@@ -0,0 +1,132 @@
+# Cross-Device Automation Agent Demo (BrowserStack App Automate)
+
+[TestNG](http://testng.org) Integration with BrowserStack App Automate for Android and iOS.
+
+
+
+## What Does This Repo Do?
+
+This repository showcases the use of **BrowserStack's Cross-Device Automation Agent** for mobile app automation using TestNG and Appium. The key feature is the ability to write test steps in **Natural Language (Plain English)**, moving away from explicit Appium locators and actions.
+
+It contains demo scripts:
+* **Android - `AppiumTest.java`**: Runs test objectives on the Wikipedia Android app using simple English commands like searching for articles and validating results.
+* **iOS - `AppiumTest.java`**: Runs test objectives on the BBC News iOS app using simple English commands like navigating to Culture tab and validating page headings.
+
+---
+
+## How It Works
+
+1. **Enablement:** The feature is enabled by declaring the capability `aiAuthoring: true` in your `browserstack.yml` configuration file.
+2. **The Command:** Inside the test scripts, the test uses a standard Selenium `JavascriptExecutor` to pass the Natural Language instruction to the BrowserStack environment:
+ ```java
+ // Example for Android: Search for "india" on Wikipedia app
+ jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Tap on the \\\"Search\\\" option from below navigation bar and type \\\" india\\\" on the search bar and tap on the first suggestion\"]}");
+
+ // Example for iOS: Navigate to Culture tab
+ jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Tap on culture tab from the top navigation bar\"]}");
+ ```
+3. **Execution:** The BrowserStack Cross-Device Automation Agent intercepts this command, interprets the natural language, and executes the equivalent low-level Appium actions on the mobile app.
+
+---
+
+## Setup
+
+### Requirements
+
+1. Java 8+
+ - If Java is not installed, follow these instructions:
+ - For Windows, download latest java version from [here](https://java.com/en/download/) and run the installer executable
+ - For Mac and Linux, run `java -version` to see what java version is pre-installed. If you want a different version download from [here](https://java.com/en/download/)
+
+2. Maven (Only required if using Maven as the build tool)
+ - If Maven is not downloaded, download it from [here](https://maven.apache.org/download.cgi)
+ - For installation, follow the instructions [here](https://maven.apache.org/install.html)
+
+3. Gradle (Only required if using Gradle as the build tool)
+ - If Gradle is not downloaded, download it from [here](https://gradle.org/releases/)
+ - For installation, follow the instructions [here](https://gradle.org/install/)
+
+---
+
+## Running the Tests
+
+### For Android
+
+#### Using Maven
+
+- Clone the repository
+- Navigate to the Android directory: `cd app-automate/android`
+- Replace `YOUR_USERNAME` and `YOUR_ACCESS_KEY` with your BrowserStack access credentials in `browserstack.yml`.
+- Declare capability **`aiAuthoring: true`** in `browserstack.yml` file (if not already present).
+- Install dependencies `mvn compile`
+- To run the test suite having cross-platform with parallelization, run `mvn test -P sample-test`.
+- To run local tests, run `mvn test -P sample-local-test`.
+
+#### Using Gradle
+
+- Clone the repository
+- Navigate to the Android directory: `cd app-automate/android`
+- Replace `YOUR_USERNAME` and `YOUR_ACCESS_KEY` with your BrowserStack access credentials in `browserstack.yml`.
+- Declare capability **`aiAuthoring: true`** in `browserstack.yml` file (if not already present).
+- Install dependencies `gradle build`
+- To run the test suite having cross-platform with parallelization, run `gradle sampleTest`.
+- To run local tests, run `gradle sampleLocalTest`.
+
+### For iOS
+
+#### Using Maven
+
+- Clone the repository
+- Navigate to the iOS directory: `cd app-automate/ios`
+- Replace `YOUR_USERNAME` and `YOUR_ACCESS_KEY` with your BrowserStack access credentials in `browserstack.yml`.
+- Declare capability **`aiAuthoring: true`** in `browserstack.yml` file (if not already present).
+- Install dependencies `mvn compile`
+- To run the test suite having cross-platform with parallelization, run `mvn test -P sample-test`.
+- To run local tests, run `mvn test -P sample-local-test`.
+
+#### Using Gradle
+
+- Clone the repository
+- Navigate to the iOS directory: `cd app-automate/ios`
+- Replace `YOUR_USERNAME` and `YOUR_ACCESS_KEY` with your BrowserStack access credentials in `browserstack.yml`.
+- Declare capability **`aiAuthoring: true`** in `browserstack.yml` file (if not already present).
+- Install dependencies `gradle build`
+- To run the test suite having cross-platform with parallelization, run `gradle sampleTest`.
+- To run local tests, run `gradle sampleLocalTest`.
+
+Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github).
+
+---
+
+## Integrate Your Test Suite
+
+### Maven Integration
+
+* Add maven dependency of `browserstack-java-sdk` in your `pom.xml` file:
+ ```xml
+
+ com.browserstack
+ browserstack-java-sdk
+ LATEST
+ compile
+
+ ```
+* Modify your build plugin to run tests by adding `argLine -javaagent:${com.browserstack:browserstack-java-sdk:jar}` in the Surefire plugin configuration.
+* Install dependencies `mvn compile`.
+
+### Gradle Integration
+
+* Add `compileOnly 'com.browserstack:browserstack-java-sdk:latest.release'` in dependencies in your `build.gradle`.
+* Fetch Artifact Information and add `jvmArgs` property in tasks.
+* Install dependencies `gradle build`.
+
+---
+
+## Notes
+
+* You can view your test results on the [BrowserStack App Automate dashboard](https://www.browserstack.com/app-automate).
+* For detailed documentation on Appium and Java setup with BrowserStack App Automate, please refer to the [official documentation](https://www.browserstack.com/docs/app-automate/appium).
+
+## Getting Help
+
+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).
diff --git a/app-automate/android/.gitignore b/app-automate/android/.gitignore
new file mode 100644
index 0000000..66117fc
--- /dev/null
+++ b/app-automate/android/.gitignore
@@ -0,0 +1,12 @@
+*.png
+target/
+local.log
+.idea
+*.iml
+**/logs/*
+.DS_Store
+build
+gradle
+.gradle
+gradlew*
+log
\ No newline at end of file
diff --git a/app-automate/android/README.md b/app-automate/android/README.md
new file mode 100644
index 0000000..7abe9a0
--- /dev/null
+++ b/app-automate/android/README.md
@@ -0,0 +1,91 @@
+# testng-appium-app-browserstack
+
+This repository demonstrates how to run Appium tests in [TestNG](http://testng.org) on BrowserStack App Automate using BrowserStack SDK.
+
+
+
+## Setup
+
+### Requirements
+
+1. Java 8+
+
+ - If Java is not installed, follow these instructions:
+ - For Windows, download latest java version from [here](https://java.com/en/download/) and run the installer executable
+ - For Mac and Linux, run `java -version` to see what java version is pre-installed. If you want a different version download from [here](https://java.com/en/download/)
+
+2. Maven (Only required if using Maven as the build tool)
+ - If Maven is not downloaded, download it from [here](https://maven.apache.org/download.cgi)
+ - For installation, follow the instructions [here](https://maven.apache.org/install.html)
+
+3. Gradle (Only required if using Gradle as the build tool)
+ - If Gradle is not downloaded, download it from [here](https://gradle.org/releases/)
+ - For installation, follow the instructions [here](https://gradle.org/install/)
+
+### Install the dependencies
+
+To install the dependencies for Android tests, run :
+```sh
+cd android/testng-examples
+mvn clean
+```
+
+Or,
+
+To install the dependencies for iOS tests, run :
+
+```sh
+cd ios/testng-examples
+mvn clean
+```
+
+## Getting Started
+
+Getting Started with Appium tests in TestNg on BrowserStack couldn't be easier!
+
+### **Run Sample test :**
+
+- Switch to one of the following directories: [Android examples](android/testng-examples) or [iOS examples](ios/testng-examples)
+- **For Maven:** Run the following command to execute tests in the Maven environment:
+ ```sh
+ mvn test -P sample-test
+ ```
+- **For Gradle:** Run the following command to execute tests in the Gradle environment:
+ ```sh
+ gradle clean sampleTest
+ ```
+
+### **Use Local testing for apps that access resources hosted in development or testing environments :**
+
+- Simply configure the `browserstackLocal` parameter in the `browserstack.yml` file accordingly in [Android examples](android/testng-examples) or [iOS examples](ios/testng-examples).
+ ```
+ browserstackLocal: true
+ ```
+- You can use the `LocalSample` app provided in both folder [Android examples](android/testng-examples) or [iOS examples](ios/testng-examples) to run your test. Change the app parameter in the `browserstack.yml` file.
+
+- **For Maven:** Run the following command to execute tests in the Maven environment:
+ ```sh
+ mvn test -P sample-local-test
+ ```
+- **For Gradle:** Run the following command to execute tests in the Gradle environment:
+ ```sh
+ gradle clean sampleLocalTest
+ ```
+
+-similarly for gradle you can do :- gradle clean sampleLocalTest
+
+
+**Note**: If you are facing any issues, refer [Getting Help section](#Getting-Help)
+
+## Integration with other Java frameworks
+
+For other Java frameworks samples, refer to following repositories :
+
+- [JUnit](https://github.com/browserstack/junit-appium-app-browserstack)
+- [Java](https://github.com/browserstack/java-appium-app-browserstack)
+
+Note: For other test frameworks supported by App-Automate refer our [Developer documentation](https://www.browserstack.com/docs/)
+
+## Getting Help
+
+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).
\ No newline at end of file
diff --git a/app-automate/android/browserstack.yml b/app-automate/android/browserstack.yml
new file mode 100644
index 0000000..9a6388b
--- /dev/null
+++ b/app-automate/android/browserstack.yml
@@ -0,0 +1,81 @@
+# =============================
+# Set BrowserStack Credentials
+# =============================
+# Add your BrowserStack userName and acccessKey here or set BROWSERSTACK_USERNAME and
+# BROWSERSTACK_ACCESS_KEY as env variables
+userName: vishalshivkumar_ECWceV
+accessKey: CHwbbppxpBGZ5ypzTqxC
+
+# ======================
+# BrowserStack Reporting
+# ======================
+# The following capabilities are used to set up reporting on BrowserStack:
+# Set 'projectName' to the name of your project. Example, Marketing Website
+projectName: BrowserStack Sample
+# Set `buildName` as the name of the job / testsuite being run
+buildName: Cross-Device Automation Agent - Android
+# `buildIdentifier` is a unique id to differentiate every execution that gets appended to
+# buildName. Choose your buildIdentifier format from the available expressions:
+# ${BUILD_NUMBER} (Default): Generates an incremental counter with every execution
+# ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30
+# Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests
+buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression}
+# Set `framework` of your test suite. Example, `testng`, `cucumber`, `cucumber-testng`
+# This property is needed to send test context to BrowserStack (test name, status)
+framework: testng
+
+source: testng:appium-sample-sdk:v1.1
+
+app: bs://b78d7940823391d54091b98d7f3b223e321d133e
+#app: ./LocalSample.apk #For running local tests
+
+# =======================================
+# Platforms (Browsers / Devices to test)
+# =======================================
+# Platforms object contains all the browser / device combinations you want to test on.
+# Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate)
+
+platforms:
+ - deviceName: Samsung Galaxy S22 Ultra
+ osVersion: 12.0
+ platformName: android
+ # - deviceName: Samsung Galaxy S21
+ # osVersion: 11.0
+ # platformName: android
+ # - deviceName: Google Pixel 6 Pro
+ # osVersion: 12.0
+ # platformName: android
+aiAuthoring: true
+interactiveDebugging: true
+
+# =======================
+# Parallels per Platform
+# =======================
+# The number of parallel threads to be used for each platform set.
+# BrowserStack's SDK runner will select the best strategy based on the configured value
+#
+# 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
+#
+# 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
+parallelsPerPlatform: 1
+
+# ==========================================
+# BrowserStack Local
+# (For localhost, staging/private websites)
+# ==========================================
+# Set browserStackLocal to true if your website under test is not accessible publicly over the internet
+# Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction
+browserstackLocal: true # (Default false)
+#browserStackLocalOptions:
+#Options to be passed to BrowserStack local in-case of advanced configurations
+# localIdentifier: # (Default: null) Needed if you need to run multiple instances of local.
+# forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel.
+# Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections
+
+# ===================
+# Debugging features
+# ===================
+debug: false # # Set to true if you need screenshots for every selenium command ran
+networkLogs: false # Set to true to enable HAR logs capturing
+consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors)
+# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors)
diff --git a/app-automate/android/build.gradle b/app-automate/android/build.gradle
new file mode 100644
index 0000000..92de6d2
--- /dev/null
+++ b/app-automate/android/build.gradle
@@ -0,0 +1,47 @@
+plugins {
+ id 'java'
+}
+
+repositories { mavenCentral() }
+
+dependencies {
+ testImplementation 'org.testng:testng:7.5'
+ implementation 'org.seleniumhq.selenium:selenium-java:4.13.0'
+ implementation 'io.appium:java-client:8.6.0'
+ implementation 'commons-io:commons-io:2.11.0'
+ implementation 'com.googlecode.json-simple:json-simple:1.1.1'
+ implementation 'com.browserstack:browserstack-java-sdk:latest.release'
+}
+
+group = 'com.browserstack'
+version = '1.0-SNAPSHOT'
+description = 'testng-browserstack'
+sourceCompatibility = '1.8'
+
+def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' }
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+tasks.withType(Test) {
+ systemProperties = System.properties
+}
+
+task sampleTest(type: Test) {
+ useTestNG() {
+ dependsOn cleanTest
+ useDefaultListeners = true
+ suites "src/test/resources/com/browserstack/sample-test.testng.xml"
+ jvmArgs "-javaagent:${browserstackSDKArtifact.file}"
+ }
+}
+
+task sampleLocalTest(type: Test) {
+ useTestNG() {
+ dependsOn cleanTest
+ useDefaultListeners = true
+ suites "src/test/resources/com/browserstack/sample-local-test.testng.xml"
+ jvmArgs "-javaagent:${browserstackSDKArtifact.file}"
+ }
+}
diff --git a/app-automate/android/pom.xml b/app-automate/android/pom.xml
new file mode 100644
index 0000000..a45d8f2
--- /dev/null
+++ b/app-automate/android/pom.xml
@@ -0,0 +1,127 @@
+
+
+ 4.0.0
+
+ com.browserstack
+ testng-browserstack-android
+ 1.0-SNAPSHOT
+ jar
+
+ testng-browserstack
+ https://github.com/browserstack/testng-appium-app-browserstack
+
+
+ UTF-8
+ 1.8
+ 1.8
+ 2.19.1
+ 3.0.0-M5
+ default
+
+
+
+
+ org.testng
+ testng
+ 7.5
+
+
+ org.seleniumhq.selenium
+ selenium-java
+ 4.13.0
+
+
+ io.appium
+ java-client
+ 8.6.0
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1.1
+
+
+ com.browserstack
+ browserstack-java-sdk
+ LATEST
+ compile
+
+
+
+
+
+
+ maven-dependency-plugin
+ 3.3.0
+
+
+ getClasspathFilenames
+
+ properties
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
+
+ src/test/resources/com/browserstack/sample-test.testng.xml
+
+ -javaagent:${com.browserstack:browserstack-java-sdk:jar}
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+ sample-test
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ src/test/resources/com/browserstack/sample-test.testng.xml
+
+
+
+
+
+
+
+ sample-local-test
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ src/test/resources/com/browserstack/sample-local-test.testng.xml
+
+
+
+
+
+
+
+
diff --git a/app-automate/android/settings.gradle b/app-automate/android/settings.gradle
new file mode 100644
index 0000000..55607bd
--- /dev/null
+++ b/app-automate/android/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ mavenCentral()
+ mavenLocal()
+ gradlePluginPortal()
+ }
+
+ resolutionStrategy {
+ eachPlugin {
+ if (requested.id.id == "com.browserstack.gradle-sdk") {
+ useModule("com.browserstack:gradle-sdk:1.1.2")
+ }
+ }
+ }
+}
+rootProject.name = 'testng-browserstack-android'
diff --git a/app-automate/android/src/test/java/com/browserstack/AppiumTest.java b/app-automate/android/src/test/java/com/browserstack/AppiumTest.java
new file mode 100644
index 0000000..dab97e8
--- /dev/null
+++ b/app-automate/android/src/test/java/com/browserstack/AppiumTest.java
@@ -0,0 +1,83 @@
+package com.browserstack;
+
+import java.net.URL;
+import java.util.Map;
+
+import org.openqa.selenium.JavascriptExecutor;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import io.appium.java_client.android.AndroidDriver;
+import io.appium.java_client.android.options.UiAutomator2Options;
+
+
+public class AppiumTest {
+
+ public AndroidDriver driver;
+ private static final String BROWSERSTACK_HUB = "https://hub-cloud.browserstack.com/wd/hub";
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ UiAutomator2Options capabilities = new UiAutomator2Options();
+ driver = new AndroidDriver(new URL(BROWSERSTACK_HUB), capabilities);
+ }
+
+ @Test
+ public void sampleTest() throws Exception {
+ JavascriptExecutor jse = (JavascriptExecutor) driver;
+
+ // AI Action 1: Search for "india" on Wikipedia
+ System.out.println("Action 1: Tap on the \"Search\" option from below navigation bar and type \" india\" on the search bar and tap on the first suggestion");
+ jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Tap on the \\\"Search\\\" option from below navigation bar and type \\\" india\\\" on the search bar and tap on the first suggestion\"]}");
+ Thread.sleep(3000); // Wait for search results
+
+ // AI Action 2: Extract the title of the search result
+ System.out.println("Action 2: Extract the title of the search result...");
+ Object titleResult = jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Extract the title of the search result\"]}");
+ String extractedTitle = titleResult != null ? titleResult.toString() : "";
+ System.out.println("Extracted Title: " + extractedTitle);
+
+ // AI Validation: Check if the title contains "India"
+ System.out.println("Validation: Checking if title of the search result contains India...");
+ Object validationResult = jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Validate if the title of the search result contains India\"]}");
+
+ // Convert AI validation result to boolean and assert
+ boolean isValidationPassed = false;
+
+ if (validationResult instanceof Boolean) {
+ isValidationPassed = (Boolean) validationResult;
+ } else if (validationResult instanceof Map) {
+ // Check if result is an object with a "value" attribute
+ Map, ?> resultMap = (Map, ?>) validationResult;
+ if (resultMap.containsKey("value")) {
+ Object value = resultMap.get("value");
+ if (value instanceof Boolean) {
+ isValidationPassed = (Boolean) value;
+ } else if (value instanceof String) {
+ isValidationPassed = Boolean.parseBoolean((String) value);
+ } else if (value != null) {
+ isValidationPassed = Boolean.parseBoolean(value.toString());
+ }
+ }
+ } else if (validationResult instanceof String) {
+ isValidationPassed = Boolean.parseBoolean((String) validationResult);
+ }
+
+ System.out.println("AI Validation Result: " + isValidationPassed);
+
+ // Standard TestNG assertion using the AI validation output
+ Assert.assertTrue(isValidationPassed,
+ "Article title should contain 'India' but validation failed");
+
+ System.out.println("Test completed successfully!");
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (driver != null) {
+ driver.quit();
+ }
+ }
+}
diff --git a/app-automate/android/src/test/resources/com/browserstack/sample-local-test.testng.xml b/app-automate/android/src/test/resources/com/browserstack/sample-local-test.testng.xml
new file mode 100644
index 0000000..49e888d
--- /dev/null
+++ b/app-automate/android/src/test/resources/com/browserstack/sample-local-test.testng.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/app-automate/android/src/test/resources/com/browserstack/sample-test.testng.xml b/app-automate/android/src/test/resources/com/browserstack/sample-test.testng.xml
new file mode 100644
index 0000000..b348da7
--- /dev/null
+++ b/app-automate/android/src/test/resources/com/browserstack/sample-test.testng.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/app-automate/ios/.gitignore b/app-automate/ios/.gitignore
new file mode 100644
index 0000000..66117fc
--- /dev/null
+++ b/app-automate/ios/.gitignore
@@ -0,0 +1,12 @@
+*.png
+target/
+local.log
+.idea
+*.iml
+**/logs/*
+.DS_Store
+build
+gradle
+.gradle
+gradlew*
+log
\ No newline at end of file
diff --git a/app-automate/ios/LocalSample.ipa b/app-automate/ios/LocalSample.ipa
new file mode 100644
index 0000000..a937349
Binary files /dev/null and b/app-automate/ios/LocalSample.ipa differ
diff --git a/app-automate/ios/browserstack.yml b/app-automate/ios/browserstack.yml
new file mode 100644
index 0000000..5e4463d
--- /dev/null
+++ b/app-automate/ios/browserstack.yml
@@ -0,0 +1,82 @@
+# =============================
+# Set BrowserStack Credentials
+# =============================
+# Add your BrowserStack userName and accessKey here or set BROWSERSTACK_USERNAME and
+# BROWSERSTACK_ACCESS_KEY as env variables
+userName: vishalshivkumar_ECWceV
+accessKey: CHwbbppxpBGZ5ypzTqxC
+
+# ======================
+# BrowserStack Reporting
+# ======================
+# The following capabilities are used to set up reporting on BrowserStack:
+# Set 'projectName' to the name of your project. Example, Marketing Website
+projectName: BrowserStack Sample
+# Set `buildName` as the name of the job / testsuite being run
+buildName: Cross-Device Automation Agent - iOS
+# `buildIdentifier` is a unique id to differentiate every execution that gets appended to
+# buildName. Choose your buildIdentifier format from the available expressions:
+# ${BUILD_NUMBER} (Default): Generates an incremental counter with every execution
+# ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30
+# Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests
+buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression}
+# Set `framework` of your test suite. Example, `testng`, `cucumber`, `cucumber-testng`
+# This property is needed to send test context to BrowserStack (test name, status)
+framework: testng
+
+source: testng:appium-sample-sdk:v1.1
+
+app: bs://ecb6354f5c66a78e20f70eceae8c63c990645248
+aiAuthoring: true
+
+
+#app: ./LocalSample.ipa #For running local tests
+
+# =======================================
+# Platforms (Browsers / Devices to test)
+# =======================================
+# Platforms object contains all the browser / device combinations you want to test on.
+# Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate)
+
+platforms:
+ # - deviceName: iPhone 14 Pro
+ # osVersion: 16
+ # platformName: ios
+ # - deviceName: iPhone 13 Pro
+ # osVersion: 15
+ # platformName: ios
+ - deviceName: iPhone 15
+ osVersion: 17
+ platformName: ios
+
+# =======================
+# Parallels per Platform
+# =======================
+# The number of parallel threads to be used for each platform set.
+# BrowserStack's SDK runner will select the best strategy based on the configured value
+#
+# 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
+#
+# 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
+parallelsPerPlatform: 1
+
+# ==========================================
+# BrowserStack Local
+# (For localhost, staging/private websites)
+# ==========================================
+# Set browserStackLocal to true if your website under test is not accessible publicly over the internet
+# Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction
+browserstackLocal: true # (Default false)
+#browserStackLocalOptions:
+#Options to be passed to BrowserStack local in-case of advanced configurations
+# localIdentifier: # (Default: null) Needed if you need to run multiple instances of local.
+# forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel.
+# Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections
+
+# ===================
+# Debugging features
+# ===================
+debug: false # # Set to true if you need screenshots for every selenium command ran
+networkLogs: false # Set to true to enable HAR logs capturing
+consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors)
+# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors)
diff --git a/app-automate/ios/build.gradle b/app-automate/ios/build.gradle
new file mode 100644
index 0000000..92de6d2
--- /dev/null
+++ b/app-automate/ios/build.gradle
@@ -0,0 +1,47 @@
+plugins {
+ id 'java'
+}
+
+repositories { mavenCentral() }
+
+dependencies {
+ testImplementation 'org.testng:testng:7.5'
+ implementation 'org.seleniumhq.selenium:selenium-java:4.13.0'
+ implementation 'io.appium:java-client:8.6.0'
+ implementation 'commons-io:commons-io:2.11.0'
+ implementation 'com.googlecode.json-simple:json-simple:1.1.1'
+ implementation 'com.browserstack:browserstack-java-sdk:latest.release'
+}
+
+group = 'com.browserstack'
+version = '1.0-SNAPSHOT'
+description = 'testng-browserstack'
+sourceCompatibility = '1.8'
+
+def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' }
+
+tasks.withType(JavaCompile) {
+ options.encoding = 'UTF-8'
+}
+
+tasks.withType(Test) {
+ systemProperties = System.properties
+}
+
+task sampleTest(type: Test) {
+ useTestNG() {
+ dependsOn cleanTest
+ useDefaultListeners = true
+ suites "src/test/resources/com/browserstack/sample-test.testng.xml"
+ jvmArgs "-javaagent:${browserstackSDKArtifact.file}"
+ }
+}
+
+task sampleLocalTest(type: Test) {
+ useTestNG() {
+ dependsOn cleanTest
+ useDefaultListeners = true
+ suites "src/test/resources/com/browserstack/sample-local-test.testng.xml"
+ jvmArgs "-javaagent:${browserstackSDKArtifact.file}"
+ }
+}
diff --git a/app-automate/ios/pom.xml b/app-automate/ios/pom.xml
new file mode 100644
index 0000000..be9d229
--- /dev/null
+++ b/app-automate/ios/pom.xml
@@ -0,0 +1,127 @@
+
+
+ 4.0.0
+
+ com.browserstack
+ testng-browserstack-ios
+ 1.0-SNAPSHOT
+ jar
+
+ testng-browserstack
+ https://github.com/browserstack/testng-appium-app-browserstack
+
+
+ UTF-8
+ 1.8
+ 1.8
+ 2.19.1
+ 3.0.0-M5
+ default
+
+
+
+
+ org.testng
+ testng
+ 7.5
+
+
+ org.seleniumhq.selenium
+ selenium-java
+ 4.13.0
+
+
+ io.appium
+ java-client
+ 8.6.0
+
+
+ commons-io
+ commons-io
+ 2.11.0
+
+
+ com.googlecode.json-simple
+ json-simple
+ 1.1.1
+
+
+ com.browserstack
+ browserstack-java-sdk
+ LATEST
+ compile
+
+
+
+
+
+
+ maven-dependency-plugin
+ 3.3.0
+
+
+ getClasspathFilenames
+
+ properties
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+ 2.22.2
+
+
+ src/test/resources/com/browserstack/sample-test.testng.xml
+
+ -javaagent:${com.browserstack:browserstack-java-sdk:jar}
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.8.1
+
+ 1.8
+ 1.8
+
+
+
+
+
+
+
+ sample-test
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ src/test/resources/com/browserstack/sample-test.testng.xml
+
+
+
+
+
+
+
+ sample-local-test
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+
+ src/test/resources/com/browserstack/sample-local-test.testng.xml
+
+
+
+
+
+
+
+
diff --git a/app-automate/ios/settings.gradle b/app-automate/ios/settings.gradle
new file mode 100644
index 0000000..e77c63f
--- /dev/null
+++ b/app-automate/ios/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ mavenCentral()
+ mavenLocal()
+ gradlePluginPortal()
+ }
+
+ resolutionStrategy {
+ eachPlugin {
+ if (requested.id.id == "com.browserstack.gradle-sdk") {
+ useModule("com.browserstack:gradle-sdk:1.1.2")
+ }
+ }
+ }
+}
+rootProject.name = 'testng-browserstack-ios'
diff --git a/app-automate/ios/src/test/java/com/browserstack/AppiumTest.java b/app-automate/ios/src/test/java/com/browserstack/AppiumTest.java
new file mode 100644
index 0000000..62cc181
--- /dev/null
+++ b/app-automate/ios/src/test/java/com/browserstack/AppiumTest.java
@@ -0,0 +1,85 @@
+package com.browserstack;
+
+import java.net.URL;
+import java.util.Map;
+
+import org.openqa.selenium.JavascriptExecutor;
+import org.openqa.selenium.MutableCapabilities;
+import org.testng.Assert;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import io.appium.java_client.ios.IOSDriver;
+import io.appium.java_client.ios.options.XCUITestOptions;
+
+
+public class AppiumTest {
+
+ public IOSDriver driver;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ MutableCapabilities options = new XCUITestOptions();
+ driver = new IOSDriver(new URL("https://hub-cloud.browserstack.com/wd/hub"),options);
+ System.out.println(driver);
+ }
+
+
+ @Test
+ public void sampleTest() throws Exception {
+ JavascriptExecutor jse = (JavascriptExecutor) driver;
+
+ // AI Action 1: Select culture tab
+ System.out.println("Action 1: Select culture tab");
+ jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Tap on culture tab from the top navigation bar\"]}");
+ Thread.sleep(3000); // Wait for culture tab to load
+
+ // AI Action 2: Extract the page heading
+ System.out.println("Action 2: Extract the page heading...");
+ Object headingResult = jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Extract the main heading text displayed at the top of the page below the BBC logo\"]}");
+ String extractedHeading = headingResult != null ? headingResult.toString() : "";
+ System.out.println("Extracted Heading: " + extractedHeading);
+ Thread.sleep(3000);
+
+ // AI Validation: Check if the page heading is Culture
+ System.out.println("Validation: Checking if the page heading is Culture");
+ Object validationResult = jse.executeScript("browserstack_executor: {\"action\": \"ai\", \"arguments\": [\"Check if the main heading text at the top of the page is Culture\"]}");
+
+ // Convert AI validation result to boolean and assert
+ boolean isValidationPassed = false;
+
+ if (validationResult instanceof Boolean) {
+ isValidationPassed = (Boolean) validationResult;
+ } else if (validationResult instanceof Map) {
+ // Check if result is an object with a "value" attribute
+ Map, ?> resultMap = (Map, ?>) validationResult;
+ if (resultMap.containsKey("value")) {
+ Object value = resultMap.get("value");
+ if (value instanceof Boolean) {
+ isValidationPassed = (Boolean) value;
+ } else if (value instanceof String) {
+ isValidationPassed = Boolean.parseBoolean((String) value);
+ } else if (value != null) {
+ isValidationPassed = Boolean.parseBoolean(value.toString());
+ }
+ }
+ } else if (validationResult instanceof String) {
+ isValidationPassed = Boolean.parseBoolean((String) validationResult);
+ }
+
+ System.out.println("AI Validation Result: " + isValidationPassed);
+
+ // Standard TestNG assertion using the AI validation output
+ Assert.assertTrue(isValidationPassed,
+ "Page heading should be Culture but validation failed");
+
+ System.out.println("Test completed successfully!");
+ }
+
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ driver.quit();
+ }
+}
diff --git a/app-automate/ios/src/test/resources/com/browserstack/sample-local-test.testng.xml b/app-automate/ios/src/test/resources/com/browserstack/sample-local-test.testng.xml
new file mode 100644
index 0000000..49e888d
--- /dev/null
+++ b/app-automate/ios/src/test/resources/com/browserstack/sample-local-test.testng.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/app-automate/ios/src/test/resources/com/browserstack/sample-test.testng.xml b/app-automate/ios/src/test/resources/com/browserstack/sample-test.testng.xml
new file mode 100644
index 0000000..b348da7
--- /dev/null
+++ b/app-automate/ios/src/test/resources/com/browserstack/sample-test.testng.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
diff --git a/automate/.gitignore b/automate/.gitignore
new file mode 100644
index 0000000..6abef23
--- /dev/null
+++ b/automate/.gitignore
@@ -0,0 +1,13 @@
+*.png
+target/
+local.log
+.idea
+*.iml
+.gradle
+build/
+.DS_Store
+gradle
+gradlew
+gradlew.bat
+log
+browserstack.err
diff --git a/README.md b/automate/README.md
similarity index 100%
rename from README.md
rename to automate/README.md
diff --git a/browserstack.yml b/automate/browserstack.yml
similarity index 59%
rename from browserstack.yml
rename to automate/browserstack.yml
index 9ecdb14..33757ad 100644
--- a/browserstack.yml
+++ b/automate/browserstack.yml
@@ -1,16 +1,16 @@
-userName: YOUR_USERNAME
-accessKey: YOUR_ACCESS_KEY
+userName: vishalshivkumar_ECWceV
+accessKey: CHwbbppxpBGZ5ypzTqxC
framework: true
platforms:
- os: Windows
osVersion: 10
browserName: Chrome
- browserVersion: 120.0
+ browserVersion: latest
browserstackLocal: true
buildName: browserstack-AI agent authoring for Automate(Latest)
projectName: BrowserStack Sample
aiAuthoring: true # setting this capability to true will help in running browserstack NL Authoring commands
-
+interactiveDebugging: true # setting this capability to true will help in using BrowserStack Interactive Debugging feature
diff --git a/build.gradle b/automate/build.gradle
similarity index 100%
rename from build.gradle
rename to automate/build.gradle
diff --git a/config/sample-local-test.testng.xml b/automate/config/sample-local-test.testng.xml
similarity index 100%
rename from config/sample-local-test.testng.xml
rename to automate/config/sample-local-test.testng.xml
diff --git a/config/sample-test.testng.xml b/automate/config/sample-test.testng.xml
similarity index 100%
rename from config/sample-test.testng.xml
rename to automate/config/sample-test.testng.xml
diff --git a/pom.xml b/automate/pom.xml
similarity index 100%
rename from pom.xml
rename to automate/pom.xml
diff --git a/src/test/java/com/browserstack/BstackAIAuthoring.java b/automate/src/test/java/com/browserstack/BstackAIAuthoring.java
similarity index 100%
rename from src/test/java/com/browserstack/BstackAIAuthoring.java
rename to automate/src/test/java/com/browserstack/BstackAIAuthoring.java