Skip to content
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ This repository demonstrates how to run Appium tests in [TestNG](http://testng.o

![BrowserStack Logo](https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780)

## Based on

These code samples are currently based on:

- **Appium-Java-Client:** `8.1.1`
- **Protocol:** `W3C`
## Setup

### Requirements
Expand Down
8 changes: 4 additions & 4 deletions android/testng-examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,22 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
<version>7.6.1</version>
</dependency>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>
<version>7.0.0</version>
<version>8.1.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
<version>2.11.0</version>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
<version>4.4.0</version>
</dependency>
<dependency>
<groupId>com.browserstack</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,64 +2,68 @@

import java.net.URL;
import java.util.Map;
import java.util.HashMap;

import java.util.Iterator;
import java.io.FileReader;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.JSONArray;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;

import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.options.UiAutomator2Options;
import org.openqa.selenium.WebElement;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;


public class BrowserStackTestNGTest {
public AndroidDriver<AndroidElement> driver;
public AndroidDriver driver;

@BeforeMethod(alwaysRun=true)
public void setUp() throws Exception {
JSONParser parser = new JSONParser();
JSONObject config = (JSONObject) parser.parse(new FileReader("src/test/resources/com/browserstack/run_first_test/first.conf.json"));

DesiredCapabilities capabilities = new DesiredCapabilities();
UiAutomator2Options options = new UiAutomator2Options();

JSONArray envs = (JSONArray) config.get("environments");
Map<String, String> envCapabilities = (Map<String, String>) envs.get(0);
Iterator it = envCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
capabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
options.setCapability(pair.getKey().toString(), pair.getValue().toString());
}

Map<String, String> commonCapabilities = (Map<String, String>) config.get("capabilities");
it = commonCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
if(capabilities.getCapability(pair.getKey().toString()) == null){
capabilities.setCapability(pair.getKey().toString(), pair.getValue());
if(options.getCapability(pair.getKey().toString()) == null){
options.setCapability(pair.getKey().toString(), pair.getValue());
}
}

HashMap<String, Object> browserstackOptions = (HashMap<String, Object>) config.get("browserstackOptions");
options.setCapability("bstack:options", browserstackOptions);

String username = System.getenv("BROWSERSTACK_USERNAME");
if(username == null) {
username = (String) config.get("username");
username = (String) browserstackOptions.get("userName");
}

String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");
if(accessKey == null) {
accessKey = (String) config.get("access_key");
accessKey = (String) browserstackOptions.get("accessKey");
}

String app = System.getenv("BROWSERSTACK_APP_ID");
if(app != null && !app.isEmpty()) {
capabilities.setCapability("app", app);
options.setCapability("app", app);
}

driver = new AndroidDriver(new URL("http://"+username+":"+accessKey+"@"+config.get("server")+"/wd/hub"), capabilities);
driver = new AndroidDriver(new URL("http://"+config.get("server")+"/wd/hub"), options);
}

@AfterMethod(alwaysRun=true)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,30 @@
package com.browserstack.run_first_test;

import io.appium.java_client.MobileBy;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.AppiumBy;

import org.openqa.selenium.support.ui.WebDriverWait;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.WebElement;

import org.testng.Assert;
import org.testng.annotations.Test;
import java.util.List;
import java.time.Duration;

public class FirstTest extends BrowserStackTestNGTest {

@Test
public void test() throws Exception {
AndroidElement searchElement = (AndroidElement) new WebDriverWait(driver, 30).until(
ExpectedConditions.elementToBeClickable(MobileBy.AccessibilityId("Search Wikipedia")));
WebElement searchElement = (WebElement) new WebDriverWait(driver, Duration.ofSeconds(30)).until(
ExpectedConditions.elementToBeClickable(AppiumBy.accessibilityId("Search Wikipedia")));

searchElement.click();
AndroidElement insertTextElement = (AndroidElement) new WebDriverWait(driver, 30).until(
ExpectedConditions.elementToBeClickable(MobileBy.id("org.wikipedia.alpha:id/search_src_text")));
WebElement insertTextElement = (WebElement) new WebDriverWait(driver, Duration.ofSeconds(30)).until(
ExpectedConditions.elementToBeClickable(AppiumBy.id("org.wikipedia.alpha:id/search_src_text")));
insertTextElement.sendKeys("BrowserStack");
Thread.sleep(5000);

List<AndroidElement> allProductsName = driver.findElementsByClassName("android.widget.TextView");
List<WebElement> allProductsName = driver.findElements(AppiumBy.className("android.widget.TextView"));
Assert.assertTrue(allProductsName.size() > 0);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package com.browserstack.run_local_test;

import com.browserstack.local.Local;

import java.net.URL;
Expand All @@ -11,72 +12,77 @@
import org.json.simple.JSONArray;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.android.options.UiAutomator2Options;

import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.WebElement;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;


public class BrowserStackTestNGTest {
public AndroidDriver<AndroidElement> driver;
public AndroidDriver driver;
private Local local;

@BeforeMethod(alwaysRun=true)
@BeforeMethod(alwaysRun = true)
public void setUp() throws Exception {
JSONParser parser = new JSONParser();
JSONObject config = (JSONObject) parser.parse(new FileReader("src/test/resources/com/browserstack/run_local_test/local.conf.json"));
JSONObject config = (JSONObject) parser
.parse(new FileReader("src/test/resources/com/browserstack/run_local_test/local.conf.json"));
JSONArray envs = (JSONArray) config.get("environments");

DesiredCapabilities capabilities = new DesiredCapabilities();
UiAutomator2Options options = new UiAutomator2Options();

Map<String, String> envCapabilities = (Map<String, String>) envs.get(0);
Iterator it = envCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
capabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
Map.Entry pair = (Map.Entry) it.next();
options.setCapability(pair.getKey().toString(), pair.getValue().toString());
}

Map<String, String> commonCapabilities = (Map<String, String>) config.get("capabilities");
it = commonCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
if(capabilities.getCapability(pair.getKey().toString()) == null){
capabilities.setCapability(pair.getKey().toString(), pair.getValue());
Map.Entry pair = (Map.Entry) it.next();
if (options.getCapability(pair.getKey().toString()) == null) {
options.setCapability(pair.getKey().toString(), pair.getValue());
}
}

HashMap<String, Object> browserstackOptions = (HashMap<String, Object>) config.get("browserstackOptions");
options.setCapability("bstack:options", browserstackOptions);

String username = System.getenv("BROWSERSTACK_USERNAME");
if(username == null) {
username = (String) config.get("username");
if (username == null) {
username = (String) browserstackOptions.get("userName");
}

String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");
if(accessKey == null) {
accessKey = (String) config.get("access_key");
if (accessKey == null) {
accessKey = (String) browserstackOptions.get("accessKey");
}

String app = System.getenv("BROWSERSTACK_APP_ID");
if(app != null && !app.isEmpty()) {
capabilities.setCapability("app", app);
if (app != null && !app.isEmpty()) {
options.setCapability("app", app);
}

if(capabilities.getCapability("browserstack.local") != null && capabilities.getCapability("browserstack.local") == "true"){
if (browserstackOptions.get("local") != null
&& browserstackOptions.get("local").toString() == "true") {
local = new Local();
Map<String, String> options = new HashMap<String, String>();
options.put("key", accessKey);
local.start(options);
Map<String, String> LocalOptions = new HashMap<String, String>();
LocalOptions.put("key", accessKey);
local.start(LocalOptions);
}

driver = new AndroidDriver(new URL("http://"+username+":"+accessKey+"@"+config.get("server")+"/wd/hub"), capabilities);
driver = new AndroidDriver(new URL("http://"+config.get("server")+"/wd/hub"), options);
}

@AfterMethod(alwaysRun=true)
@AfterMethod(alwaysRun = true)
public void tearDown() throws Exception {
// Invoke driver.quit() to indicate that the test is completed.
// Invoke driver.quit() to indicate that the test is completed.
// Otherwise, it will appear as timed out on BrowserStack.
driver.quit();
if(local != null) local.stop();
if (local != null)
local.stop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

import java.io.File;
import java.util.List;
import java.time.Duration;
import org.apache.commons.io.FileUtils;

import io.appium.java_client.MobileBy;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.AppiumBy;

import org.openqa.selenium.WebElement;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.support.ui.WebDriverWait;
Expand All @@ -19,16 +20,16 @@ public class LocalTest extends BrowserStackTestNGTest {

@Test
public void test() throws Exception {
AndroidElement searchElement = (AndroidElement) new WebDriverWait(driver, 30).until(
ExpectedConditions.elementToBeClickable(MobileBy.id("com.example.android.basicnetworking:id/test_action")));
WebElement searchElement = (WebElement) new WebDriverWait(driver, Duration.ofSeconds(30)).until(
ExpectedConditions.elementToBeClickable(AppiumBy.id("com.example.android.basicnetworking:id/test_action")));
searchElement.click();
AndroidElement insertTextElement = (AndroidElement) new WebDriverWait(driver, 30).until(
ExpectedConditions.elementToBeClickable(MobileBy.className("android.widget.TextView")));
WebElement insertTextElement = (WebElement) new WebDriverWait(driver, Duration.ofSeconds(30)).until(
ExpectedConditions.elementToBeClickable(AppiumBy.className("android.widget.TextView")));

AndroidElement testElement = null;
List<AndroidElement> allTextViewElements = driver.findElementsByClassName("android.widget.TextView");
WebElement testElement = null;
List<WebElement> allTextViewElements = driver.findElements(AppiumBy.className("android.widget.TextView"));
Thread.sleep(10);
for(AndroidElement textElement : allTextViewElements) {
for(WebElement textElement : allTextViewElements) {
if(textElement.getText().contains("The active connection is")) {
testElement = textElement;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,26 @@

import java.net.URL;
import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.io.FileReader;
import java.time.Duration;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.JSONArray;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;

import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.WebElement;
import io.appium.java_client.android.options.UiAutomator2Options;

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Parameters;


public class BrowserStackTestNGTest {
public AndroidDriver<AndroidElement> driver;
public AndroidDriver driver;

@BeforeMethod(alwaysRun=true)
@org.testng.annotations.Parameters(value={"deviceIndex"})
Expand All @@ -28,40 +30,43 @@ public void setUp(String deviceIndex) throws Exception {
JSONObject config = (JSONObject) parser.parse(new FileReader("src/test/resources/com/browserstack/run_parallel_test/parallel.conf.json"));
JSONArray envs = (JSONArray) config.get("environments");

DesiredCapabilities capabilities = new DesiredCapabilities();
UiAutomator2Options options = new UiAutomator2Options();

Map<String, String> envCapabilities = (Map<String, String>) envs.get(Integer.parseInt(deviceIndex));
Iterator it = envCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
capabilities.setCapability(pair.getKey().toString(), pair.getValue().toString());
options.setCapability(pair.getKey().toString(), pair.getValue().toString());
}

Map<String, String> commonCapabilities = (Map<String, String>) config.get("capabilities");
it = commonCapabilities.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
if(capabilities.getCapability(pair.getKey().toString()) == null){
capabilities.setCapability(pair.getKey().toString(), pair.getValue());
if(options.getCapability(pair.getKey().toString()) == null){
options.setCapability(pair.getKey().toString(), pair.getValue());
}
}

HashMap<String, Object> browserstackOptions = (HashMap<String, Object>) config.get("browserstackOptions");
options.setCapability("bstack:options", browserstackOptions);

String username = System.getenv("BROWSERSTACK_USERNAME");
if(username == null) {
username = (String) config.get("username");
username = (String) browserstackOptions.get("userName");
}

String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY");
if(accessKey == null) {
accessKey = (String) config.get("access_key");
accessKey = (String) browserstackOptions.get("accessKey");
}

String app = System.getenv("BROWSERSTACK_APP_ID");
if(app != null && !app.isEmpty()) {
capabilities.setCapability("app", app);
options.setCapability("app", app);
}

driver = new AndroidDriver(new URL("http://"+username+":"+accessKey+"@"+config.get("server")+"/wd/hub"), capabilities);
driver = new AndroidDriver(new URL("http://"+config.get("server")+"/wd/hub"), options);
}

@AfterMethod(alwaysRun=true)
Expand Down
Loading