0% found this document useful (0 votes)
49 views755 pages

Test Execution 11-25-2023

The document provides information about test execution using Continuous Testing and the SeeTest platform. It discusses migrating test suites created with Selenium, Appium, Espresso, or XCUITest to the Continuous Testing platform. It also covers parallel test execution on web and mobile devices, viewing test results, and using Appium for mobile test automation on Android and iOS.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
49 views755 pages

Test Execution 11-25-2023

The document provides information about test execution using Continuous Testing and the SeeTest platform. It discusses migrating test suites created with Selenium, Appium, Espresso, or XCUITest to the Continuous Testing platform. It also covers parallel test execution on web and mobile devices, viewing test results, and using Appium for mobile test automation on Android and iOS.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 755

Test Execution

Test Execution

©2023 Digital.ai Inc. All rights reserved Page 1


Test Execution

Test Execution Home


Explore these topics to learn more about Test Execution with Continuous Testing and the SeeTest platform.

This space is dedicated to those of you who already have created test suites, driven by Selenium, Appium,
Espresso or XCUITest.

Here you can find detailed information on different facets of the product, including:

• Migrating your test suites to Continuous Testing platform.


• Parallel test execution on Web and Mobile devices.
• Viewing and analyzing test results.

Mobile - Android and iOS


Continuous Testing platform provides a wide set of solutions for mobile test automation, from migrating
Appium \ Espresso \ XCUITest scripts to advanced operations such as parallel execution, reporting and
dashboards.

Appium

Appium is an open-source automation tool for testing mobile applications. It allows you to perform, simulate
and test actions that a user might perform while using the applications. Such actions include clicking on
elements, sending input data, swiping, scrolling, raising the volume, clicking the home button, you name it.
The list is endless. Consider Appium as that user who tries to do everything with the app (even things that
the app was not designed for) and finds all the little annoying bugs and inconsistencies. You use Appium so
that your user will eventually have the best and smoothest experience using your app. Appium is so robust
that it lets you test native applications, web applications (actual websites) and hybrid applications (those that
combine native and web).

Continuous Testing goes hand in hand with Appium. You can write your tests using Appium or grab your
existing tests and run them against our cloud devices. Included in this documentation is sample code to help
you get started.

©2023 Digital.ai Inc. All rights reserved Page 1


Test Execution

Before you proceed with fetching the sample tests:

1. If you plan to test a native or hybrid app, upload your app to your project.
2. Obtain an Access Key

Appium Server (Open Source) Execution

Continuous Testing Cloud supports Appium open-source execution when any Appium Tests are run.

To use Appium Open Source, use the capability appiumVersion.

Appium Version Capability


The appiumVersion capability specifies the version of Appium.

The currently supported versions are:

• 1.22.3
• 2.1.3

Appium Version Desired Capability


dcIOS.setCapability("appiumVersion", "<version tag>");
dcIOS.setCapability("automationName", "XCUITest");
dcIOS.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.2.6");

Application Capability

MobileCapabilityType.APP is an existing capability that specifies the Cloud Application. It is extended


to specify the application version.

It needs to follow the pattern provided below.

Cloud Application Desired Capability


dcIOS.setCapability(MobileCapabilityType.APP, "cloud:<Bundle ID>:<App version>
");

For example:

Cloud Application Desired Capability Example


dcIOS.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank
:2435");

©2023 Digital.ai Inc. All rights reserved Page 2


Test Execution

Complete Examples
Application Test Example
String MyDeviceUDID="1234567890ABCDEF";

dcIOS.setCapability("appiumVersion", "1.22.3");
dcIOS.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank
:2435");
dcIOS.setCapability("bundleId", "com.experitest.ExperiBank");
dcIOS.setCapability(MobileCapabilityType.PLATFORM_VERSION, "11.2.6");
dcIOS.setCapability("automationName", "XCUITest");
dcIOS.setCapability("deviceName", "auto");
dcIOS.setCapability("udid", MyDeviceUDID);
dc.setCapability("user", <user name>);
dc.setCapability("password", <password>);
dc.setCapability("testName", "My First Appium OSS Test");
Web Test Example
String MyDeviceUDID="1234567890ABCDEF";

dcIOS.setCapability("appiumVersion", "1.22.3");

dcIOS.setCapability(MobileCapabilityType.BROWSER_NAME, "Safari");

dcIOS.setCapability("automationName", "XCUITest");
dcIOS.setCapability("deviceName", "auto");
dcIOS.setCapability("udid", MyDeviceUDID);
dc.setCapability("user", getUsername());
dc.setCapability("password", getPassword());
dc.setCapability("testName", "My First Appium OSS Test");

Long-Running Commands Limitation


There are some long-running commands in Appium, like runAppInBackground.

In Appium versions below 1.20, the maximum command execution time is 10 minutes (Appium limitation).
After Appium 1.20, the maximum command execution time is 20 minutes.

In order to use long-running commands, increase the values in these capabilities.

dc.setCapability("newCommandTimeout", 900); // 15 Minutes


dc.setCapability("wdaConnectionTimeout", 900_000); // 15 Minutes (Relevant for
iOS only)

©2023 Digital.ai Inc. All rights reserved Page 3


Test Execution

Appium OSS Supported Capabilities


Capabilities
Capability Documentation Supported Comments
OS
uniqueName Application Setup iOS/Android You can install and launch an App with a
unique name.

reportDisable (report.disable) Automated Test Reports iOS/Android Use this capability to choose if a report is
generated.

installOnlyForUpdate Application Setup iOS/Android Re-installs an application only if an older


version already installed on the device.

buildVersion / releaseVersion / Application Setup iOS/Android Installs and launches the app by build version/
appVersion release version.

instrumentApp Application Setup iOS/Android Instrument the application. This is needed for
extra capabilities (simulateCapture for
example).

DeviceQuery Device Setup iOS/Android Instead of using "udid" capability you can run
queries for cloud devices.

appiumVersion iOS/Android Choose the Appium Server version to be used


for the execution.To see which versions are
supported, see Appium Version Capability.

releaseDevice Device Setup iOS/Android Gives the capability to not release a device
after performing driver.quit();
Default: trueIn case the device is already
reserved or uses future reservations when the
test starts then the releaseDevice capability
does not have any effect and the device is not
be released.

dontGoHomeOnQuit iOS/Android The device remains in the last left state even
after ending the test.Default: falseFor iOS: In
the case of starting a new session, launch the
app with noReset=true (from appium version
1.22.0 and above) to continue from the same
state.

commandScreenshot iOS/Android In Video Report, takes a screenshot also


before and after every action.Default: false

AudioReport Attaching Audio to iOS/Android Attaches a device audio to the video report.
Video Report

selfHealing Appium Self-Healing iOS/Android Enable or disable self-healing during


session.Default: false

©2023 Digital.ai Inc. All rights reserved Page 4


Test Execution

Code Examples

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

iOS Native Test


protected AppiumDriver<MobileElement> driver = null;//driver
DesiredCapabilities dc = new DesiredCapabilities();

@Before
public void setUp() throws MalformedURLException {
//Appium Open Source Have to capabilities
dc.setCapability("testName",<Your Test Name>);//set the test name
dc.setCapability("platformName", "iOS");//set platform(iOS/Android)
dc.setCapability("deviceName", "auto");//set the device name
dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");//a
utomation name(XCUITest for iOS)
dc.setCapability(MobileCapabilityType.APP, <Your APP>);//for install

//Experitest capabilities
dc.setCapability("accessKey", <your accessKey>);// cloud Authorization
dc.setCapability("appiumVersion", <Appium Version>);//Desired Appium v
ersion for example 1.16.0-p1
driver = new IOSDriver<IOSElement>(new URL("<server>), dc);//init driv
er
}

@Test
public void Test(){
//Your Test Goes Here
}

@After
public void tearDown() {
driver.quit();

}
iOS Web Test

©2023 Digital.ai Inc. All rights reserved Page 5


Test Execution

protected AppiumDriver<MobileElement> driver = null;//driver


DesiredCapabilities dc = new DesiredCapabilities();

@Before
public void setUp() throws MalformedURLException {
//Appium Open Source Have to capabilities
dc.setCapability("testName",<Your Test Name>);//set the test name
dc.setCapability("platformName", "iOS");//set platform(iOS/Android)
dc.setCapability("deviceName", "auto");//set the device name
dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");//a
utomation name(XCUITest for iOS)
dc.setCapability(MobileCapabilityType.BROWSER_NAME, BrowserType.SAFARI
);//for mobile web

//Experitest capabilities
dc.setCapability("accessKey", <your accessKey>);// cloud Authorization
dc.setCapability("appiumVersion", <Appium Version>);//Desired Appium v
ersion for example 1.16.0-p1
driver = new IOSDriver<IOSElement>(new URL("<server>), dc);//init driv
er
}

@Test
public void test()
{
driver.get("http://www.google.com");
//your test goes here
}

@After
public void tearDown(){

driver.quit();

}
Android Native Test
protected AppiumDriver<MobileElement> driver = null;//driver
protected DesiredCapabilities dc = new DesiredCapabilities();
private String deviceSN = <device serial number>;//device to run on
private String appiumVersion = "1.16.0-p2";//appium version to run

@Before
public void before() throws MalformedURLException {
//Appium capabilities
dc.setCapability("udid", deviceSN);

©2023 Digital.ai Inc. All rights reserved Page 6


Test Execution

dc.setCapability("testName", <your test name>);


dc.setCapability("app","cloud:" + <app-package>);
dc.setCapability("automationName", "UiAutomator2");
dc.setCapability("platformName", "Android");

//Experitest capabilities
dc.setCapability("accessKey", <your accessKey>);// cloud Authorization
dc.setCapability("appiumVersion", appiumVersion);//Appium server versi
on
driver = new AndroidDriver<>(new URL("<server>), dc);
}

@Test
public void test() {
//your test goes here
}

@After
public void tearDownAfterAll() {
if (driver != null) {
driver.quit();
}
}
Android Web Test
protected AppiumDriver<MobileElement> driver = null;//driver
protected DesiredCapabilities dc = new DesiredCapabilities();
private String deviceSN = <device serial number>;//device to run on
private String appiumVersion = "1.16.0-p2";//appium version to run

@Before
public void before() throws MalformedURLException {
//Appium capabilities
dc.setCapability("udid", deviceSN);
dc.setCapability("testName", <your test name>);
dc.setCapability(MobileCapabilityType.BROWSER_NAME, "Chrome");
dc.setCapability("automationName", "UiAutomator2");
dc.setCapability("platformName", "Android");

//Experitest capabilities
dc.setCapability("accessKey", <your accessKey>);// cloud Authorization
dc.setCapability("appiumVersion", appiumVersion);
driver = new AndroidDriver<>(new URL("<server>"), dc);
}

@Test
public void test() {
driver.get("https://www.experitest.com");

©2023 Digital.ai Inc. All rights reserved Page 7


Test Execution

driver.findElement(By.id("to-about-section")).click();
driver.findElement(By.id("firstname")).sendKeys("user1");
driver.findElement(By.id("lastname")).sendKeys("last1");
driver.findElement(By.id("email")).sendKeys("[email protected]");
driver.findElement(By.id("password")).sendKeys("pass");
}

@After
public void tearDownAfterAll() {
if (driver != null) {
driver.quit();
}
}

Flutter Driver Support in Appium OSS


Flutter driver is used to run automation tests for Flutter applications.

Limitations

• Flutter driver is supported only for Appium version 2 (and Appium Java client 8).
• Flutter driver is supported only for Automation and not in Mobile Studio.

To test a Flutter application:

1. Add support for flutterDriverExtension before the runApp command, in main.dart.

main.dart
import 'package:flutter_driver/driver_extension.dart';

void main() {
enableFlutterDriverExtension();
runApp(const MyApp());
}

2. Add dev_dependencies to pubspec.yml.

©2023 Digital.ai Inc. All rights reserved Page 8


Test Execution

pubspec.yaml
dev_dependencies:
test: any
flutter_driver:
sdk: flutter
flutter_test:
sdk: flutter

3. Build the application.

• Android: flutter build apk --debug


• iOS 13.0 and lower: flutter build ios --debug
• iOS 14.0+: flutter build ios --profile
4. Upload the application to the Cloud.

To run an automation test on a Flutter application:

1. Pull the appium 2.0.0-beta.55 image from AWS.

Docker Pull Command


docker pull public.ecr.aws/dai-ct/appium-opensource:2.0.0.beta.55-6

2. Set the automation name in the capabilities to be "Flutter".

capabilities.setCapability("platformName", "Android");
capabilities.setCapability("automationName", "Flutter");

Espresso Driver Support in Appium OSS


For more information about Appium Espresso driver, see the Appium Espresso Driver documentation.

The Espresso driver is supported only for Appium versions 2.x (and Appium Java client 8)

Espresso Server is an application installed on device which enables Espresso test execution.

Before the first test execution Espresso server must be build for specific application under test.

For each application under test, there is a special Espresso Server matching this application.

As per the Appium documentation, the Espresso server should be built by developers.

To prepare for the first Espresso test run in the Cloud:

©2023 Digital.ai Inc. All rights reserved Page 9


Test Execution

1. Build Espresso Server using a local Appium Server (should be done only once for application under
test).
2. Upload Espresso Server to the Cloud with a unique name (should be done only once for application
under test).
3. Run the test with the espressoServerUniqueName capability.

Install and Run Appium Server


To install the Appium Server with the Espresso driver, run these commands:

• npm install -g appium@next


• appium driver install espresso

To make sure you are running Appium Server 2.x, run: appium -v

To run the Appium Server, run: appium

For more details see the Appium Documentation.

Build the Espresso Server


To build the Espresso server:

1. Set the Espresso driver type.

capabilities.setCapability("platformName", "Android");
capabilities.setCapability("automationName", "Espresso");

2. Set the application under test.

capabilities.setCapability("app", "/Users/OEpstein/Downloads/JetSurvey.apk
");
Example of Espresso Server Build Configuration:
capabilities.setCapability("appium:forceEspressoRebuild", true); // Defaul
t is false
capabilities.setCapability("appium:showGradleLog", true); // Defaul
t is false
capabilities.setCapability("espressoBuildConfig", "{\"toolsVersions\": " +
"{\"compileSdk\":31} ," +
"\"additionalAndroidTestDependencies\": " +
"[\"androidx.compose.runtime:runtime:1.1.1\" , " +

©2023 Digital.ai Inc. All rights reserved Page 10


Test Execution

"\"androidx.compose.ui:ui-tooling:1.1.1\" , " +
"\"androidx.compose.foundation:foundation:1.1.1\" , "
+
"\"androidx.compose.material:material:1.1.1\" ] }");

3. Set compose mode in order to test JetPack application.

driver = new AndroidDriver(new URL(APPIUM_SERVER_URL), capabilities);


driver.setSetting("driver", "compose");
// Test code...
driver.quit();

4. Uninstall Espresso Server from Android device, so that Appium Server installs it.

adb uninstall io.appium.espressoserver.test

5. Run the test. It generates the Espresso server.

To see where the Espressor server is located, check the in Appium server log.

Appium Server Log Example


[EspressoDriver@39f7 (d53ddc1e)] Installing Espresso Test Server apk from the
target device (path: '/var/folders/03/n6jdys956n1d_7wyznsmzpd00000gp/T/io.appi
um.espressoserver.test_2.2.2_com.example.compose.jetsurvey_899X07061.apk')

This APK file should be uploaded to the Cloud server.

Upload the Espresso Server to the Cloud Server


1. Navigate to Applications in the Cloud.

©2023 Digital.ai Inc. All rights reserved Page 11


Test Execution

2. Provide unique name.

Run the Test With the espressoServerUniqueName


Capability
Provide the capability in each test.

capabilities.setCapability("espressoServerUniqueName", "espresso_jetsurvey");

©2023 Digital.ai Inc. All rights reserved Page 12


Test Execution

Now the test can be executed on cloud devices.

Example Code for Building an Espresso Server


package jetpack;

import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.MalformedURLException;
import java.net.URL;

public class JetpackBuildServerTest {

/**
* Appium Server must have version 2.x
* Appium Client must have version 8.x (Gradle dependency: implementation
'io.appium:java-client:8.0.0')
*/
public static final String APPIUM_SERVER_URL = "http://localhost:4723"; //
Local Appium server
private static AndroidDriver driver;
private static final DesiredCapabilities capabilities = new DesiredCapabili
ties();

@BeforeAll
public static void setUp() throws MalformedURLException {
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("automationName", "Espresso");
capabilities.setCapability("app", "/Users/OEpstein/Downloads/JetSurvey
.apk");

/**
* Capabilities for Espresso Server build
* Test dependencies should be provided by JetPack application develop
ers.
* Dependencies versions must match the versions in application under
test.
*/
capabilities.setCapability("appium:forceEspressoRebuild", true); // De
fault is false
capabilities.setCapability("appium:showGradleLog", true); // Default i
s false

©2023 Digital.ai Inc. All rights reserved Page 13


Test Execution

capabilities.setCapability("espressoBuildConfig", "{\"toolsVersions\":
" +
"{\"compileSdk\":31} ," +
"\"additionalAndroidTestDependencies\": " +
"[\"androidx.compose.runtime:runtime:1.2.0-alpha08\" , " +
"\"androidx.compose.ui:ui-tooling:1.2.0-alpha08\" , " +
"\"androidx.compose.foundation:foundation:1.2.0-alpha08\" , "
+
"\"androidx.compose.material:material:1.2.0-alpha08\" ] }");

driver = new AndroidDriver(new URL(APPIUM_SERVER_URL), capabilities);


driver.setSetting("driver", "compose");
}

@Test
public void jetSurvey() {
// Espresso server is created during Appium driver creation.
}

@AfterAll
public static void tearDown() {
if (driver != null)
driver.quit();
}
}

Example Test Code


import io.appium.java_client.AppiumBy;
import io.appium.java_client.android.AndroidDriver;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.MalformedURLException;
import java.net.URL;

public class JetpackDemoTest {


public static final String APPIUM_SERVER_URL = "http://<host:port>/wd/hub";
public static final String CLOUD_ACCESS_KEY = "<access key>";
private static AndroidDriver driver;
private static final DesiredCapabilities capabilities = new DesiredCapabili
ties();

©2023 Digital.ai Inc. All rights reserved Page 14


Test Execution

@BeforeAll
public static void setUp() throws MalformedURLException {
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("automationName", "Espresso");

capabilities.setCapability("accessKey", CLOUD_ACCESS_KEY);
capabilities.setCapability("deviceQuery", "@os='android'");
capabilities.setCapability("appium:appiumVersion", "2.0.0.beta.23");
capabilities.setCapability("app", "cloud:com.example.compose.jetsurvey
/.MainActivity");
capabilities.setCapability("testName", "Appium 2.x Espresso driver in
compose mode");

/**
* Espresso server with this unique name must exist in cloud project
*/
capabilities.setCapability("espressoServerUniqueName", "espresso_jetsu
rvey");

driver = new AndroidDriver(new URL(APPIUM_SERVER_URL), capabilities);


driver.setSetting("driver", "compose");
}

@Test
public void jetSurvey() {
WebElement email = driver.findElement(AppiumBy.tagName("emailTag"));
email.click();
email.sendKeys("[email protected]");
WebElement continueButton = driver.findElement(AppiumBy.tagName("contin
ueTag"));
continueButton.click();
}

@AfterAll
public static void tearDown() {
if (driver != null)
driver.quit();
}
}

Limitations
It is not possible to open Mobile Studio during Espresso test execution.

©2023 Digital.ai Inc. All rights reserved Page 15


Test Execution

Troubleshooting

Problem Possible Solution


The following message appears in console: espressoServerUniqueName Provide the required capability.
capability must be provided for Appium Espresso tests

The following error appears in Appium Server log: Cannot launch activity Uninstall the previous application under test on
Android device.

The following error appears in Appium Server Incorrect Espresso server was used for the
log: INSTRUMENTATION_STATUS: Error=Unable to find instrumentation target application under test. Verify that Espresso
package: Server matches the application under test.

The following error appears in Appium Server


log:java.lang.NoSuchMethodError: No static method isTraceInProgress()Z in
class Landroidx/compose/runtime/ComposerKt
1. Incorrect Espresso server was used for
the application under test.

2. Espresso server was built with incorrect


dependencies (or incorrect versions of
dependencies).

The following error appears in Appium Server log:Got response with status 500: Espresso server was built without the required
{"id":"5ae1278b-b8b0-4986-972a- dependencies.Provide additional dependencies
ed2a92d6e258","sessionId":"b2bc2c1e-4370-4e44-80b2- in the espressoBuildConfig capability when
dcca88ae11cb","value":{"error":"unknown building the Espresso server.
error","message":"java.lang.NoSuchMethodError: No virtual method
replace(ILjava/lang/Object;)Ljava/lang/Object; in class Landroidx/collection/
SparseArrayCompat

Appium OSS Supported Commands


SeeTest Client Commands
Command Documentation Supported Comments
OS
installApp Install iOSAndroid

Installs the application with the


given package name or bundle
ID.

©2023 Digital.ai Inc. All rights reserved Page 16


Test Execution

Command Documentation Supported Comments


OS
driver.installApp("cloud
:com.experitest.ExperiBa
nk/.LoginActivity")

Installs the application with given


unique name:

driver.installApp("cloud
:unqiueName=app_unique_n
ame")

Installs the application with given


release version or build version or
both:

driver.installApp("cloud
:com.experitest.ExperiBa
nk/.LoginActivity:releas
eVersion=1.0")
driver.installApp("cloud
:com.experitest.ExperiBa
nk/.LoginActivity:buildV
ersion=1234")
driver.installApp("cloud
:com.experitest.ExperiBa
nk/.LoginActivity:releas
eVersion=1.0:buildVersio
n=1234")

• If several matching applications


are found, the latest uploaded
application is installed.

• The application is installed in


non-instrumented mode
(instrument=false).

Android

keepData: If true, this upgrades


the existing application installed
without losing its data.
By default this false.

©2023 Digital.ai Inc. All rights reserved Page 17


Test Execution

Command Documentation Supported Comments


OS

driver.installApp("cloud
:com.experitest.ExperiBa
nk/.LoginActivity:keepDa
ta=true")

report SeeTest Client - Report iOSAndroid

Adds a step to the generated


report.

//adds a passed step wit


h message step should be
passed
driver.executeScript("s
eetest:client.report", "
step should be passed",
"true");

//adds a failed step wit


h the message step shoul
d be failed
driver.executeScript("se
etest:client.report", "s
tep should be failed","f
alse");

launchWithOptions Launch with Options iOS

@Test
public void test(){
Map<String, Obje
ct> launchOptionsMap = n
ew HashMap();

launchOptionsMap
.put("relaunch", true);

// Create ENV vars map t


o pass to the applicatio
n so it will run in DEBU
G with a secret key
Map envVars = ne

©2023 Digital.ai Inc. All rights reserved Page 18


Test Execution

Command Documentation Supported Comments


OS
w HashMap();

envVars.put("sec
ret_key", "DFSF5343543CA
A");
envVars.put("DEB
UG", true);
launchOptionsMap
.put("launch_env",envVar
s);

String bundleId
= "com.apple.AppStore";

//Converting Map to vali


d JSON for execute scrip
t

Gson gsonObj = n
ew Gson();

String jsonStr =
gsonObj.toJson(launchOp
tionsMap).replace("\"",
"\\\"");
driver.executeSc
ript("seetest:client.lau
nch", bundleId, jsonStr)
;
}

setAuthenticationReply SeeTest Client - iOSAndroid


SetAuthenticationReply(Reply, Delay) -
TouchID

driver.executeScript("s
eetest:client.setAuthent
icationReply", "AUTHENTI
CATION_SUCCEEDED", "1000
0");

simulateCapture SeeTest Client - SimulateCapture iOSAndroid

// Simulates a capture.
It works only with a URL
, not local files
driver.executeScript("se
etest:client.simulateCap
ture", "<FILE_URL>");

©2023 Digital.ai Inc. All rights reserved Page 19


Test Execution

Command Documentation Supported Comments


OS

// or files uploaded to t
he cloud through file rep
ository
driver.executeScript("se
etest:client.simulateCap
ture", "cloud:<FILE_UNIQ
UE_NAME>");

startPerformanceTransaction StartPerformanceTransaction iOSAndroid

Starts a performance transaction.

driver.executeScript("se
etest:client.startPerfor
manceTransaction", "Moni
tor");

Youn need to
use endPerformanceTransaction
at the end.

startPerformanceTransactionForApplication StartPerformanceTransactionForApplication iOS Android

Starts a performance transaction.

driver.executeScript("se
etest:client.startPerfor
manceTransactionForAppli
cation", "com.experitest
.ExperiBank", "Monitor")
;

You need to
use endPerformanceTransaction
at the end.

endPerformanceTransaction EndPerformanceTransaction iOSAndroid

driver.executeScript("se
etest:client.endPerforma
nceTransaction", "<Repor
t Name>");

©2023 Digital.ai Inc. All rights reserved Page 20


Test Execution

Command Documentation Supported Comments


OS

sendKeysWithBT SendKeysWithBT iOSAndroid

driver.executeScript("se
etest:client.sendKeysWit
hBT", "" + Keys.CONTROL+
Keys.ALT + "I");

HybridClearCache SeeTest Client - HybridClearCache iOSAndroid

Clears the browser's cache.


To continue with the test in the
browser, use driver.context to set
the context back to the web.

driver.executeScript("se
etest:client.hybridClear
Cache()");

startStepGroup SeeTest Client - StartStepsGroup iOSAndroid

driver.executeScript("se
etest:client.startStepsG
roup", "<Group Name">);

stopStepGroup SeeTest Client - StopStepsGroup iOSAndroid

driver.executeScript("se
etest:client.stopStepsGr
oup");

setNetworkConnection SeeTest Client - setNetworkConnection Android

driver.executeScript("se
etest:client.setNetworkC

©2023 Digital.ai Inc. All rights reserved Page 21


Test Execution

Command Documentation Supported Comments


OS
onnection", "<MODE>", tr
ue);

getNetworkConnection SeeTest Client - getNetworkConnection Android

Gets the network connection for a


device.
It executes any of these modes:

• airplane_mode

• wifi

• mobile_data

• bluetooth

Returns true if the chosen mode


is set to On in the device.

driver.executeScript("se
etest:client.getNetworkC
onnection", "<MODE>");

addTestProperty SeeTest Client - addTestProperty iOSAndroid

driver.executeScript("se
etest:client.addTestProp
erty", "<propertyName>",
"<propertyValue>");

setLocationPlaybackFile SeeTest Client - setLocation iOSAndroid

Changes the device location


according to a series of location
points provided by the Csv file in
order to mimic the behavior of a
location movement.

©2023 Digital.ai Inc. All rights reserved Page 22


Test Execution

Command Documentation Supported Comments


OS
• LocationProvider argument is
optional, Default value is GPS.

• When using this command, you


need to set
newCommandTimeout (Timeout
Capabilities) capability with a
bigger value than the command
waiting time (that is set by the
WaitForSetLocationEnd
command).

driver.executeScript("se
etest:client.setLocation
PlaybackFile", "cloud:Lo
cationCsvFile", delay, "
LocationProvider");

waitForSetLocationEnd SeeTest Client - setLocation iOSAndroid

Specifies the waiting time


for setLocationPlaybackFile.

driver.executeScript("se
etest:client.waitForSetL
ocationEnd", 5000);

setPasscode SeeTest Client - setPasscode iOS

Set a default passcode to the


device. If it fails, it throws an
exception.

driver.executeScript("se
etest:client.setPasscode
");

clearPasscode SeeTest Client - clearPasscode iOS

Clear the passcode from the

©2023 Digital.ai Inc. All rights reserved Page 23


Test Execution

Command Documentation Supported Comments


OS
device. If it fails, it throws an
exception.

driver.executeScript("se
etest:client.clearPassco
de");

setNetworkConditions SeeTest Client - setNetworkConditions iOSAndroid

Select the profile configured on


the Network Virtualization server
to test the device under the
different network conditions.

driver.executeScript("se
etest:client.setNetworkC
onditions", "Monitor", 6
0000);

clearLocation SeeTest Client - ClearLocation iOSAndroid

Clear the device’s location


services.

driver.executeScript("se
etest:client.clearLocati
on");

stopLocationPlayback SeeTest Client - stopLocationPlayback iOSAndroid

Use this command to search


for any active setLocation task on
the device and stop it.

driver.executeScript("se
etest:client.stopLocatio
nPlayback");

activateVoiceAssistance SeeTest Client - ActivateVoiceAssistance iOSAndroid

Use this command to activate the


voice assistant service on the
device (for example, Siri or

©2023 Digital.ai Inc. All rights reserved Page 24


Test Execution

Command Documentation Supported Comments


OS
Google Assistant). It sends the
text parameter as if it is a spoken
directive.

driver.executeScript("se
etest:client.activateVoi
ceAssistance", "open goo
gle");

This is supported as of version


23.10.

For more supported Continuous Testing Cloud commands for Appium OSS, see Using The File Repository.

Authentication with Appium

Obtain Your Access Key

Authentication as a user is performed using an accessKey.

The Access Key can either be passed as part of the capabilities or as part of the URL.

Capabilities authentication
For accessKey, use the following convention:

DesiredCapabilities dc = new DesiredCapabilities();


dc.setCapability("accessKey", "<accessKey>");

AppiumDriver driver = new AndroidDriver(new URL(cloudurl + "/wd/hub/"), dc);

URL authentication
For accessKey, use the following convention:

©2023 Digital.ai Inc. All rights reserved Page 25


Test Execution

AppiumDriver driver = new AndroidDriver(new URL("http://:" + accessKey + "@" +


host+":" + port + "/wd/hub/"), dc);

Debug an Appium Session

This article explains how to run automated tests on a device that you have already opened from a web
desktop browser.

To debug a test that is actively running, see Debug A Test Request

If you already have some experience, and understand how to open a device for automation mode, you can
skip the first items and continue from here.

1. Click Open. A new page opens a browser tab. It has two sections, the left side of the page has the
device and operations which can be performed on it. The section on the right side displays useful utility
operations such as viewing logs and automation.

©2023 Digital.ai Inc. All rights reserved Page 26


Test Execution

2. On right side of the screen, click Automation > LET'S START AUTOMATING.

You get a screen that looks like the screen below.

3. Copy the Device ID. The device is reserved and ready to run Automation.

Run the Automation Tests


Add the desired capability requesting to run your test on this specific device.

Testbase Modification

©2023 Digital.ai Inc. All rights reserved Page 27


Test Execution

/**
* Initialize default properties.
*/
protected void initDefaultDesiredCapabilities() {
dc.setCapability(MobileCapabilityType.UDID, "FA69TBN03839");
}

Once your tests execute, you can follow the console log on the device screen. It prints out all the commands
executed by the Appium Grid Node.

During the execution of the test from the code environment, you can place breakpoints in order to pause the
execution and better investigate the application state, fetch dump, and interact with the device.

If the test is paused for more time than defined in newCommandTimeout capability, the Appium server
session resets.

The default value of newCommandTimeout is 60 seconds.

While debugging a test it is better to provide a greater value for this capability. If driver.quit is not called,
you can only execute the next test when the timeout is reached.

After the test is completed, the device web session stays open and subsequent tests can use it. You can find
more info on running a test on a reserved device here.

©2023 Digital.ai Inc. All rights reserved Page 28


Test Execution

View Your Automated Appium Tests


You can view your automated Appium tests live in the cloud.

To view your automated Appium tests:

1. Click the test notifications bar in the upper right hand corner. You see there how many tests are
currently running (middle button).
2. Click it to open the list of currently running tests (up to 5 tests can be listed, even if more than 5 are
running).
3. Click View All to view all tests.

If any tests are running for you, you see them populated in the grid nodes which gets visible in right hand
side of page when you click Execution in the Continuous Testing cloud landing page.

©2023 Digital.ai Inc. All rights reserved Page 29


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 30


Test Execution

To get a better view of the test, click View Device.

SeeTest - Appium Extension

Continuous Testing Cloud provides the SeeTest Client API which can be used to develop automation tests
alongside Appium native methods. Using SeeTest Client together with the Appium driver, you can enhance

©2023 Digital.ai Inc. All rights reserved Page 31


Test Execution

and enrich your test with capabilities and actions that are not included in and cannot be achieved using
Appium.

Some of the advantages of using SeeTest Client with Appium are:

• Allows you to install, launch and uninstall an application in runtime, regardless of the app that you
specified in the capabilities.
• Better control of the device, because Continuous Testing Cloud allows you to execute native device
action (such as home, recent apps, notifications) without having to specify the key code that
corresponds to these actions.

SeeTest Client doesn't replace Appium Driver but rather accompanies Appium and improves automation
tests in those cases where Appium doesn't support.

To work with SeeTest client, initialize it and pass the driver instance as the parameter as shown in code
snippet below:

Using Seetest Client


driver = new IOSDriver(new URL("https://cloud.seetest.io:443/wd/hub"), dc);
seetest = new SeeTestClient(driver);

Currently the SeeTest Client API is only available for Java.

Seetest Dependency Configuration in a Gradle


Project:
Modify build.gradle:

repositories {
maven{
url "https://cloud.experitest.com/repo/"
}
mavenCentral()
}
dependencies {
compile 'com.experitest:appium-seetest-extension:+'
}

©2023 Digital.ai Inc. All rights reserved Page 32


Test Execution

Seetest Dependency Configuration in a Maven


Project:
Modify POM.xml:

Maven Dependency
<repositories>
<repository>
<id>seeetest</id>
<name>seetest client</name>
<url>https://cloud.experitest.com/repo/</url>
</repository>
</repositories>
<dependency>
<groupId>com.experitest</groupId>
<artifactId>appium-seetest-extension</artifactId>
<version>LATEST</version>
</dependency>

Device Commands
SeeTest Client provides several device-related commands for better control over the device while testing.

Such commands allow you to control the device to support your testing needs, while making sure that your
test scenario is as flexible and accurate as possible.

DeviceAction
Description
This command allows you to execute device commands without having to specify key codes. You can use
the deviceAction command to perform various actions on the device, actions that either require you to
specify key code or require physical access to the device.

©2023 Digital.ai Inc. All rights reserved Page 33


Test Execution

Parameters
Name Value Description
Action string Action to execute

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

DeviceAction Command Usage


DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//show the list of recent apps


seetest.deviceAction("Recent Apps");

List of Supported Actions


◦ Home - Click the Home button

◦ Back - Click the Back button

◦ Power - Click the Power key

◦ Landscape - Change orientation to landscape mode

◦ Portrait - Change orientation to portrait mode

©2023 Digital.ai Inc. All rights reserved Page 34


Test Execution

◦ Change Orientation - Toggle orientation

◦ Menu - Click the Menu button

◦ Unlock - Unlock the device

◦ Wake - Wake the device

◦ Paste - Paste text from clipboard

◦ Volume Up - Click the Volume Up button

◦ Volume Down - Click the Volume Down button

◦ Recent Apps - Show recent apps

DeviceAction - Landscape And Portrait


Description
You can toggle the orientation of the device reflection by using the key events for Landscape and Portrait.

This command is supported in Android only. Android version must be 4.1 or above when using non-
instrumented applications.

Usage
Using command to toggle orientation on an Android device to landscape mode by sending the text
'Landscape' or to portrait by sending 'Portrait'

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

©2023 Digital.ai Inc. All rights reserved Page 35


Test Execution

Example

Landscape and Portrait


DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//This command sets the orientation to Portrait or Landscape.
seetest.deviceAction("Portrait");
seetest.deviceAction("Landscape");

Advanced configuration:

Some devices will require advanced configuration in order to toggle orientation properly. For those, you can
use the following with SendTextCommand:

• For landscape orientation use: {LANDSCAPE_0}, {LANDSCAPE_90}, {LANDSCAPE_180},


{LANDSCAPE_270} to control the orientation and its direction.
• For portrait orientation use: {PORTRAIT_0}, {PORTRAIT_90}, {PORTRAIT_180}, {PORTRAIT_270}.

For example:

• {LANDSCAPE_90} is the equivalent of {PORTRAIT_0}.


• {PORTRAIT_180} is equivalent of the being device upside down.

Reboot
Description
This command allows you to reboot the device, while specifying the timeout waiting for the device to
reload. You can use the reboot command to reboot the device if you are required to do so as part of the test.

Parameters
Name Value Description
Timeout int Timeout in milliseconds. The default is 40000.

©2023 Digital.ai Inc. All rights reserved Page 36


Test Execution

On some devices, an additional action is needed after reboot of unlocking the device. This can be done
using DeviceAction of "Unlock".

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Reboot Command Usage


DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// reboot and wait 2 minutes for the device to reload
// unlock the device after reboot

if(seetest.reboot(120000)){
seetest.deviceAction("Unlock")
}

Run Command - adb


Description
This command allows you to run adb commands or other device shell commands.

You can use the run command to execute adb and shell commands in runtime while executing your test. You
can open the settings or wifi settings menu, push a file to SD card, and even call a number.

Parameters
Name Value Description
Command string Command to run

©2023 Digital.ai Inc. All rights reserved Page 37


Test Execution

This is supported on Android only.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example
Using Run Command
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

// open android settings


seetest.run("adb shell am start -a android.settings._SETTINGS");

// open wifi settings


seetest.run("adb shell am start -a android.settings.WIFI_SETTINGS");

// push a file to SD storage


seetest.run("adb push C:\\Users\\myuser\\Pictures\\myPicture.png /sdcard/Pictu
res/myPicture.png");

// call a number
seetest.run("adb shell am start -a android.intent.action.CALL -d tel:+65123456
78");

©2023 Digital.ai Inc. All rights reserved Page 38


Test Execution

SetLocation
Description
The command lets you set the location of the device. This lets you test geolocation-based applications. It is
assumed that you have preconfigured the device for location testing. This command will fail the current test
in case the location couldn't be set.

Name Value Description


Latitude -90 to 90 Latitude value in decimal degrees, ranging from -90 to 90.
Positive values represent latitudes north of the equator while negative values represent latitudes south
of the equator.

Longitude -180 to 180 Longitude value in decimal degrees, ranging from -180 to 180.
Positive values represent longitudes east of the prime meridian while negative values represent
longitudes west of the prime meridian.

The location set using SetLocation command can be cleared using ClearLocation.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

SetLocation of Device
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
// This command sets location.
seetest.setLocation("20.593684", "78.962880");

©2023 Digital.ai Inc. All rights reserved Page 39


Test Execution

ClearLocation
Description
Use this command to reset the device’s location services after you execute SetLocation.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

ClearLocation
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//this command will clear the location
seetest.clearLocation

CloseKeyboard
Description
Use this command to close the soft keypad if open on the device.

©2023 Digital.ai Inc. All rights reserved Page 40


Test Execution

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

Close Keyboard
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// this command reset set location.
seetest.closeKeyboard();

Drag Coordinates
Description
Use this command to perform the drag action based on start coordinates (X,Y) and end coordinates (X,Y)
on the device reflection.

Parameters
Name Type Description
X1 Coordinate Integer X coordinate starting point to start the drag

Y1 Coordinate Integer Y coordinate starting point to start the drag

X2 Coordinate Integer X coordinate starting point to end the drag

Y2 Coordinate Integer Y coordinate starting point to end the drag

Time Integer Time in milliseconds for the command to be executed

©2023 Digital.ai Inc. All rights reserved Page 41


Test Execution

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

Drag Action
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Command to Drag Action
client.dragCoordinates(636, 826, 572, 1166, 2000);

GetText
Description
Use this command to get all text located in a specific contextual zone from the entire screen of the device
reflection.

Name Type Possible Values


Zone String NATIVE: All text properties of the Native dump on the screen.
WEB: All text properties of the Web dump on the screen.TEXT: All the text that appears on the screen.Default:
All names of elements which are on the Object repository that appear on the screen in the chosen zone.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 42


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetText
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//this command will get Native zone screen reflection.
seetest.getText("NATIVE")

Pinch
Description
Use this command to pinch in and out at specific location using a specific pinch radius.

Parameters
Name Type Description
Inside Boolean Pinch direction.

• True - In

• False - Out:

X Coordinate Integer X coordinate of the center point from top left

Y Coordinate Integer X coordinate of the center point from top left.

Radius Integer The pinch radius in screen pixels.

Horizontal Boolean Pinch direction

©2023 Digital.ai Inc. All rights reserved Page 43


Test Execution

Name Type Description


• True - Horizontal

• False - Vertical

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

Example for Pinch Operation


DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Command performs and pinch action
seetest.pinch(true, 600, 1000, 700, false)

©2023 Digital.ai Inc. All rights reserved Page 44


Test Execution

SetProperty
Description
Use this command to change the configuration on the device during runtime. It sets the given property to the
given value.

Parameters
Name Value
Property Property

Value Value to be set

Supported Properties

Property Values Description

hybridClick Enable/disable or true/false (Default = disable/false) When hybrid Click is enabled, the click method
javascript.

report.image.width Size in pixels (default value: 500) Defines the size, in pixels, of the generated ima

screen.latency Unit in milliseconds The value of screen.latency is used in the calcu


the latter screenshot is taken.

screen.quality 1-100 (percentages) To change the quality of the image received fro

screen.refresh Greater than 0 in milliseconds To control the refresh rate time gap to get a new
device.

ignore.ocr.recommendation true/false To enable/disable OCR recognition.

Android .instrumentation.security none, smart, hard (default value: smart) Disable the Android LayoutParams FLAG_SEC

• none - Do not disable the security flag.

• smart - Disable the security flag when activity

• hard - Disable the security flag on the activity


repeated sequence (every few secs).

on.device.xpath true/false If it is set to true, it causes any web command t


be calculated on the device itself. This enables
part of the properties shown in the object spy a
work on the device. So, if the XPath contains o
tags, it will not be executed on the device (even
true):

©2023 Digital.ai Inc. All rights reserved Page 45


Test Execution

Property Values Description

@onScreen, @top, @css, @width, @height, @


@text or @nodeName

assert.element.idle true/ false. (default: false)

This property is used to control SeeTest verifica


regarding busy elements. When the property is
will fail a command if the element in question is
a busy state. Otherwise, the verification will ign
Usage examples:

• To identify a toast which generally is a


assert.element.idle=false.

• To click on an element, use: assert.elem


clicks do not work on busy elements).

Note
This property is available also as an 'app-prope
be declared and set on/off in the app.properties

full/center/none/legacy_mode This is an app property used to define the desir


element.visibility.level default value: legacy_mode. elements on the device's screen for the testing
levels are supported:

• full: Fully contained. This mode defines the e


on whether the element rectangle is fully con
screen rectangle.

• center: Center contained. This mode defines


based on whether the center of the element (
the screen.

• none: No visibility constraints. This mode doe


visibility on the screen once the element is fo

• legacy_mode: Maintains old legacy, meaning


mode.

For example:Running isElementFound() on an


completely hidden by the devices navigation ba
following based on each mode:

©2023 Digital.ai Inc. All rights reserved Page 46


Test Execution

Property Values Description

• Full: false

• center: false

• none: true

chrome.load.timeout integer>=0 (time in milliseconds). This is a device property used to control the tim
Default value: 10,000 ms for local devices and on chrome.
15000 ms for cloud devices. For example:

• When executing ' launch(chrome:...)', the req


load on the current tab. This process require
website opened on this tab and if the loading
Chrome will load the new URL in a new tab.

• Under bad network conditions, chrome might


deterioration. This property allows you to adj
timeout under different network conditions.

adbPortForward selected port number/ -1 To enable specifying which adb port number to
Android device from. If set to -1, it will forward t

Android .native .nonInstrumented true/false Enable the user to switch between working und
instrumented mode during test execution.

WPDevice .nonInstrumented.objects enable/disable, true/false (default value is enable/ If set false/disable, it will not take the non-instru
true) or short/thin If set short/thin, it will take a non-instrumented
application bar.

ios.native.nonInstrumented true/false For Native dump only. If set to true, it will take t
dump.

iosDevice.nonInstrumented To switch between instrumented/non-instrumen


enable/disable (default value: enable) working with an iOS device.

ios.elementsendtext.action.fire true/ false (default value: false) When the user uses the ElementSendText com
the ios.elementsendtext.action.fire property is e
the event that should have been triggered by th

ios.non- true/false (default value: false)


instrumented.dump.escape.attributes
When set to true, it will escape properties (hidd
from the non-instrumented dump. Uses for big
elements.

©2023 Digital.ai Inc. All rights reserved Page 47


Test Execution

Property Values Description

Note:
This property is available also as an 'app-prope
be declared and set on/off in the app.properties

js.max.string.size integer values > 0 (default value: 255) Set the maximum text attribute length in the ob

clicks.time.gap Integer values > 0 (default value: 0) iOS: Milliseconds between clicks in case simula
above) is desired. Set this property and make s
clicks is 3 or above. This will simulate a fast rep
same spot (recommended values are 50 ms an
Default: 0.

Android.instrumentation.camera true/ false or enable/disable. (default value: false) This property enables you to support camera in
fly. When set to true, the next time you use the
instrument=true, your application will be instrum
support.
This ability is intended especially for test autom
with the camera. For further information,
see SimulateCapture.Note: This property is ava
property', which can be declared and set on/off
file.

Android.instrumentation.camera2 true/ false or enable/disable. (default value: false) This property enables you to support camera A
the-fly. When set to true, the next time you use
with instrument=true, your application will be in
camera support.
This ability is intended especially for test autom
with the camera. For further information, please
see SimulateCapture.Notes:

• This property is available also as an 'app-pro


be declared and set on/off in the app.propert

• To use camera2 Api, should both property


Android.instrumentation.camera and
Android.instrumentation.camera2 set to true

• This property is supported in devices with An


than 6.1.

ios.auto.accept.alerts true/false If set to true, system alerts aree accepted auto


appear on the screen. The click will happen du
that will use XPath queries.

true/false If set to true, system alerts will be dismissed au


appear on the screen. The click will happen du
ios.auto.dismiss.alerts that will use XPath queries.

• Dismiss
It only works with iOS 9 and above.

©2023 Digital.ai Inc. All rights reserved Page 48


Test Execution

Property Values Description

• Don't allow

• Close

• Cancel

• Not now

• "...Later"

android.install.grant.permissions true/false Grants the permissions your app requires on in


to false

attach.crash.log.to.report true/false Saves crash logs that were created on the dev
the report folder

ios.dump.focus.process process_name:<name> orbundle_id: <bundleId> Getting dump from a specific process, identified
orprocess_id:<pid> bundle_id or process_id.For example, getting a
assistiveTouch:
ios.dump.focus.process=process_nam

ios.dump.non.instrumented.include.attributes attribute name(currently, only the 'visible' attribute is Used only on iOS for getting dump non-instrum
supported). attributes.For example:
ios.dump.non.instrumented.include.attributes=v

battery.report.percentage true/false Change the presented data units for battery mo


default unit which is mAh to a percentage

ios.keyboard.close.by.dump true/false Close keyboard with simulated user action bas


use

location.service.gpslocation.service.network true/false Toggle GPS off by setting both properties to fal


using one of these properties to true:

• for GPS with 'device only' mode: use 'location


'location.service.network=false'

• for GPS with 'battery saving' mode: use 'loca


'location.service.network=true'

• for GPS with 'High accuracy' mode: use 'loca


'location.service.network=true'

ios.element-send-text.use.xcautomation Use XCAutomation for elementSendText, by de


true/false false, then elementSendText operation rather th
executing on the device will be executing in mu

ios.dump.fetch.top true / false(default) Instead of calculating the "top" property with th


property makes the "top" property being querie
only if you have problems with the existing prop
operation.

©2023 Digital.ai Inc. All rights reserved Page 49


Test Execution

Property Values Description

disable.reporter true When running a grid test on the cloud with a co


this to true to save the test results locally.

ios.instrumentation.log.level none,fatal,error,warn,info,debug,all Sets the desired log level to the iOS instrumen

safari.webview.include true / false(default) When fetching a native dump, this property will
elements of the safari WebView will be seen in

ios.element.top.bounds.contained.in.parent true / false(default) Sets top=false for elements that their rectangle
their parent's bounds.

ios.waiting.element.polling.interval Integer values >= 0 (default value:0) Used for stabilizing click operations.Sets the in
the element location in milliseconds, waiting for
the same location.

ios.11.use.old.monitoring.service true / false(default) Used only for iOS 11 to choose the service whi
CPU / Memory (the old service monitors only d

ios.request.location.permission true / false (default) Request location permission. Required for getL
iOS.Supported on iOS 11 and above

controller.idle.timeout Integer values >= 10000 milliseconds (default: Set the idle controller timeout, how long will the
10000) after stopping the test execution.

split.view.dump.ios true / false (default) Enforces getting instrumented dump first.

ios.dump.grid.sampling.params <SamplesX>,<SamplesY>,<Depth>,<Hybrid(optional Create dump by sampling grid of points, Samp


default=true)>,<FrontMostAppFocused(optional many samples on X-Axis when the device is in
default=false)> ordefault when in Landscape the samples on each axis w
recommend first trying the default value which
not create the expected dump only then try oth
property with empty parameters will remove it,
dump.

ios.dump.active.applications true / false (default) Get dumps from all active applications.
This is useful in iOS 13, whose dump doesn't in
elements by default when another application i

ios.allow.orientation.correction true / false (default value: true) Allow iOS non-instrumented dump orientation t
property is useful for backward compatibility in
oriented in Landscape Left, a set up that has n
12.10. If your code depends on the wrong elem
"false" to get the old behavior back.

listener.max.recovery.attempts Integer values >= 1 When using mobile listeners, this property sets
row recovery would be attempted. If not set, the
attempts would be equal to the number of mob

ios.dump.uielements.only.params true/false Create a dump by collecting native UI elements


avoid crashes in case of a large web dump and
performance.

android.upgrade.uninstall true/false (default value: true) By default, when installing an application and a
installed on the device, the old application is un
installing the new version. When keeping the a
the application data will be lost, for example, ap
were placed on the Home Screen. Set this prop
override this behavior.

©2023 Digital.ai Inc. All rights reserved Page 50


Test Execution

Property Values Description

true/false (default value: false) Get dumps from webview for instrumented and
applications.WebView debugging must be enab
android.noninstrumented.webview application: https://developer.chrome.com/docs
debugging/webviews/
This feature should work if only one debuggabl
parallel. Supported for Android 6 devices and a

enable.appium.grid.cache true/false (default value: true) Default behavior: Appium Grid caches element
asked again it just retrieves from the cache. in
that element changes after it's cached, then wh
element, the cached element with old attribute
returned. In case we need the elements after th
set the property to false.

android.chrome.avoid.first.launch.experience true/false (default value: false) By default, when restarting Chrome, e.g., by a
the parameter stopIfRunning=true, then a UI sc
handling Chrome's Welcome page if it appears
property to true, a different mechanism will be u
Welcome page from appearing.Note if you are
command-line file:when set to "true", Chrome w
application and any existing chrome command
overridden.

ios.instrumentation.fix.scale true/false (default value: false) Should fix the scaling of applications in instrum
used when application has hosted frames or in
(the application isn't in full screen and need to b

ios.safari.launch.timeout 0 (default value: 40) When set to 0, the tests will not wait for the tim
instead it will move to the next command imme
situations where the URL will present a pop-up
safari and not the actual page itself.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

©2023 Digital.ai Inc. All rights reserved Page 51


Test Execution

...
...
// this command can be used to set the screen refresh rate.
seetest.setProperty("screen.refresh", "10");

SimulateCapture
Description
The command allows users to test applications that use the camera on a mobile device.

The command injects an image file into the camera preview screen.

Parameters
Name Value Description
Picture Path in String The image file full path, this image will switch the original camera preview screen.
Path format In Appium Server (Appium Open Source) file unique name can be provided in the following
format:cloud:file_unique_nameUsing The File Repository

Usage
The command can be used to Simulate Camera capture action, this command needs the Simulate Capture
libraries when an application is uploaded.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 52


Test Execution

Simulate Capture - Using file from file repository


// File with unique name my_image must exist in file repository
driver.executeScript("seetest:client.simulateCapture", "cloud:my_image")
Simulate Capture - using local file
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// this command simulates


seetest.simulateCapture("C:\\images\\image.jpg");

Prerequisite

To work with this feature, the app must require and acquire the
permission"android.permission.WRITE_EXTERNAL_STORAGE" before attempting to simulate capture

For Android 9+

For SeeTest local, android 9+, a user should make sure that the following shell commands are run before
running the application:

adb shell settings put global hidden_api_policy_pre_p_apps 1


adb shell settings put global hidden_api_policy_p_apps 1

GetDeviceProperty
Description
This command can be used retrieve device properties.

Parameters
Name Value Description
Property Name Property Set of name of the properties whose values can be queried

Supported Properties

©2023 Digital.ai Inc. All rights reserved Page 53


Test Execution

Property String Comments


Name device.name Name of the device

Serial Number device.sn Serial number of the device

OS device.os iOS or Android

Version os.version full os version

Manufacture device.manufacture Device Manufacture

Model device.model Device Model

Model Name device.modelname Device Model Name

Time device.time Device Time

Remote device.remote Is the device on a remote machine? (True/False)

Device screen size device.screensize Screen Size of Device

Host device.host The IP and port of the host machine (127.0.0.1 or USB
for local devices)

Category device.category Phone or Tablet

Application Bundle Version app.CFBundleVersion Only for iOS devices, for instrumented applications -
released and unreleased versions

Application Bundle Short app.CFBundleShortVersionString Only for iOS devices, for instrumented applications
Version

Application version app.version In iOS - only for instrumented applications

Instrumentation version instrumentation.version Only for iOS devices, for instrumented applications

Orientation orientation Landscape or Portrait

Instrumentation log level ios.instrumentation.log.level Only for iOS devices, for instrumented applications

Usage
Command can be used to get the property of the device using the property name.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

©2023 Digital.ai Inc. All rights reserved Page 54


Test Execution

...
...
// this command gets the given property
seetest.getDeviceProperty("device.name");

Swipe
Description
Swipe the screen in a given direction.

Parameters
Name Type Description
Direction String Direction of the swipe motion.

• Right

• Left

Offset Integer Swipe offset

Time Integer Swipe overall time

Usage
Command can be used to swipe in a given direction from an offset.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

swipe
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

©2023 Digital.ai Inc. All rights reserved Page 55


Test Execution

dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Swipes right from an offset
seetest.swipe("Right", 10, 500);

iOS 15 and Above


In some cases the swipe operation might require you to use SetDragStartDelay first.

For example:

• Opening control-center on devices with home button via swipe down.


• Opening app-switcher on devices without home button via swipe down.

swipe
//Command to delay in drag.
seetest.setDragStartDelay(50);
// Swipes down from an offset
seetest.swipe("Down", 0, 2000);

GetNetworkConnection
Description
The command gives the ability to getting the network connection for a device.

Note : This command only works in Android Device.

Parameters
Name Value Description
Network type Checks if a device is in given network type.

• airplane_mode

• wifi

• mobile_data

©2023 Digital.ai Inc. All rights reserved Page 56


Test Execution

Name Value Description


• Bluetooth

Usage
Command can be used to check if a device is in a given network mode.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetNetworkConnection
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...// Checks if network is given network type and corresponding action can be
taken.
if(seetest.getNetworkConnection("airplane_mode")){
// If statement
}

HybridClearCache
Description
Use this command to clear the device browser's cache.

• Chrome: On non-iOS only. Chrome's cache, cookies, and user history data are cleared.
• Safari: On iOS only. For this browser both the cookies and the cache are cleared.

©2023 Digital.ai Inc. All rights reserved Page 57


Test Execution

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

HybridClearCache
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Clear the browser cache


seetest.hybridClearCache();

SetNetworkConditions
Description
Use this command to select the profile configured on the Network Virtualization server to test the device
under the different network conditions.

This command only works for the users having Project Administrator role.

Parameters
Name Type Description
Profile String Network conditions profile created in the Network Virtualization Tool

Duration Int Time in milliseconds for the selected profile (0 = permanent)

If Profile is not set (empty), the default profile (no network limitations) is selected.

©2023 Digital.ai Inc. All rights reserved Page 58


Test Execution

Usage
Network Profile Virtualization is enabled for the Project Administrators. Subsequent to this the profile name
can be used to set the network condition.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

SetNetworkConditions
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
seetest.setNetworkConditions("LTE Network", 30000);

©2023 Digital.ai Inc. All rights reserved Page 59


Test Execution

// Do Test

SetAuthenticationReply
Description
Use this command to simulate different authentication responses on applications that request a user
fingerprint authentication.

It is recommended to execute the command before an authentication request dialog is displayed.

Limitations

• This is supported only on devices that allow TouchID.


• The Launched Application needs to be Instrumented Only.

• In Android, mocking authentication is supported for applications which use the native
implementation. Mock authentication is not supported for third party libraries.

Parameters
Name Type Possible Values Description
Reply String iOS - Reply type to mock.

• MockFullGUI

• Success

• StopMock

• AuthenticationFailedError

• UserCancelError

• UserFallbackError

©2023 Digital.ai Inc. All rights reserved Page 60


Test Execution

Name Type Possible Values Description

• SystemCancelError

• PasscodeNotSetError

Android -

• CLEAR_MOCK

• AUTHENTICATION_SUCCEEDED

• AUTHENTICATION_FAILED

• ERROR_CANCELED

• ERROR_HW_UNAVAILABLE

• ERROR_LOCKOUT

• ERROR_NO_SPACE

• ERROR_UNABLE_TO_PROCESS

• ERROR_VENDOR_BASE

• FP_ACQUIRED_GOOD

• FP_ACQUIRED_PARTIAL

Delay Int Delay in milliseconds after authentication request dialog is open.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

SetAuthenticationReply
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);

©2023 Digital.ai Inc. All rights reserved Page 61


Test Execution

seetest = new SeeTestClient(driver);

// deviceid here should be if of an iOS device.


dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Sets Auth Reply as Success.


seetest.SetAuthenticationReply("Success", 0);

Flick
Description
Use this command to flick the screen in a given direction. As a visible aid, an arrow is drawn on the reflection
showing the flick motion. It starts according to the swipe value and points in the opposite of the swipe
direction. For example, when flicking right, the swipe arrow points to the left.

Parameters
Name Type Description
Direction String DirectionPossible values:

• Right

• Left

Offset Int Pixels

Time Int

Usage
In order to flick the screen you can add the command 'flick', provide the direction and offset.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/

©2023 Digital.ai Inc. All rights reserved Page 62


Test Execution

• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

flick
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Command will swipe right but the arrow point to left.
seetest.flick("Right", 100, 1000);

SyncElements
Description
Use this command to wait for all UI elements on a page to be ready. This works on the dump level. It returns
true when there are no changes to the elements dump for the specified period of time.

Parameters
Name Type Description
Integer Time in milliseconds for the UI elements to be static (no changes to the dump).

SilentTime

Timeout Integer Waiting timeout in milliseconds.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 63


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SyncElements
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Synch elements.
seetest.syncElements(3000, 10000)

ReceiveIncomingCall
Description
Use this command to simulate receiving an incoming phone call.

Parameters
Name Value Description
FromNumber String Phone number that the message will appear to arrive from (5+ characters).

HangupInSeconds Integer Seconds to wait while the phone is ringing before hanging up on the caller side.

Notes:

To use telephony features (receiving calls and SMS), the Cloud Administrator must configure and activate a
telephony account. This is done in Settings → Device Policies -> Telephony.

Usage
Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 64


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

ReceiveIncomingCall
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

// Simulate receiving an incoming call


seetest.receiveIncomingCall("123456", 10);

ReceiveIncomingSMS
Description
Use this command to simulate a received SMS.

Parameters
Name Value Description
FromNumber String Phone number that the message appears to arrive from (5+ characters).

HangupInSeconds Integer How many seconds to wait while the phone is ringing before hanging up on the caller side.

To use telephony features (receiving calls and SMS), the Cloud Administrator must have configured and
activated a telephony account. This is done in the Settings → Device Policies → Telephony.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 65


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example
ReceiveIncomingSMS
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

// Simulate receiving an SMS


seetest.receiveIncomingSMS("123456", 10);

GetRunningApplications
Description
This command returns all the running applications on the device as a String array.

For iOS, this returns a list of bundle IDs.

For Android, this returns a list of packages.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 66


Test Execution

GetRunningApplications
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Gets the RunningApplications
seetest.getRunningApplications();

GetConnectedDevices
Description
This command returns a string of all devices currently available in the device list (on ready mode).

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example:

GetConnectedDevice
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Get the current foreground activity


seetest.getConnectedDevices();

©2023 Digital.ai Inc. All rights reserved Page 67


Test Execution

CloseAllApplications
Description
Use this command to kill all the background processes. This closes all applications that are currently running
on the device.

The foreground application closes and you are returned to the home screen.

Note

• This command is supported for Android 5.0+ and all iOS versions.
• This command does not clear the Recent Apps view.

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

CloseAllApplications
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

seetest.closeAllApplications();

©2023 Digital.ai Inc. All rights reserved Page 68


Test Execution

ActivateVoiceAssistance
Description
Use this command to activate the voice assistant service on the device (for example, Siri or Google
Assistant). It sends the text parameter as if it is a spoken directive.

Parameters
Name Value Description
Text String Text to send to the assistant service

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

ActivateVoiceAssistance
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
seetest.activateVoiceAssistance("open google");

SetNetworkConnection
Description
Use this command to set the network connection for a device.

©2023 Digital.ai Inc. All rights reserved Page 69


Test Execution

Parameters
Name Type Possible Values Description
Connection String Connection type.

• airplane_mode

• wifi

• mobile_data

• Bluetooth

Enable Boolean Enable and disable a connection type.

• True - Enable the network connection type.

• False - Disable the network connection type.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetNetworkConnection
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Set the Network connection as airplane_mode
seetest.setNetworkConnection("airplane_mode", true);

©2023 Digital.ai Inc. All rights reserved Page 70


Test Execution

Note: Some Xiaomi devices with Android 6 and MIUI 9 Xiaomi have their own permission manager. It needs
to be disabled in order to use this command.

In order to do disable Permission Manager:

1. Under Developer Options turn off MIUI optimization.


2. Reboot the device.
3. Under Settings go to Permissions.
4. Click the gear icon.
5. Turn off the Permission Manager.

GetApplicationInfo
Description
Use this command to get specific application info, given a key parameter for the requested information.

These types of information are supported for both platforms:

• Application version number.


• Application build number.

Parameters
Name Type Description
BundleId String Application package name.

Key String The requested info key name.These are valid for iOS and Android:

• releaseVersion - The application version.

• versionName - The application release build number.

In iOS , CFBundleShortVersionString can also be used instead of versionName. CFBundleVersion can also
be used instead of releaseVersionIn Android. versionCode can also be used instead of releaseVersion.

©2023 Digital.ai Inc. All rights reserved Page 71


Test Execution

iOS Additional Application Information


In addition to the application version number and the application build number, in iOS you can get additional
application information.

This feature is only supported for primitive types, for example, objects whose value type is NSString,
NSNumber, or NSDate.

Some commonly used properties are MinimumOSVersion, DTSDKName, and


CFBundleDevelopmentVersion.

You can find more properties by inspecting the info.plist file in the application IPA.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GetApplicationInfo
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
client = new SeeTestClient(driver);

...
...
//Get Version name of the application name ... For Android
client.getApplicationInfo("com.experitest.Eribank","versionName");

GetClipboardText
Description
Use this command to get text that is currently stored in the device clipboard.

©2023 Digital.ai Inc. All rights reserved Page 72


Test Execution

This command works on Android 5+.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GetClipBoardText
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
seetest.getClipboardText();

SetClipboardText
Description
Use this command to set the content of the system clipboard.

Command works only for Android 5+.

Parameters
Name Type Description
Text String Clipboard Text

©2023 Digital.ai Inc. All rights reserved Page 73


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetClipboardText
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Checked if MakePaymentButton is above Mortgage Request.
seetest.setClipboardText("text");

StartLoggingDevice
Description
Use this command to start the device log. It is written to path specified. Use StopLoggingDevice to stop the
log.

Parameters

Name Type Description


Filepath String Path to file or directory to which the log will be written.Directory is mandatory. If file is not provided,
default.log is created.

Usage
Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 74


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

StartLoggingDevice
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Start Logging Command


seetest.startLoggingDevice("c:\\logs");

P2CX
Description
According to the given percentage, this command will return the active device's width pixel count (X
Coordinate) as an Integer.

With this command and the matching P2CY command, you can avoid relying on coordinates and to give
relative size not based on resolution of device.

Parameters
Name Value Description
Percentage Integer Given screen percentage Value will be between 0 to 100

©2023 Digital.ai Inc. All rights reserved Page 75


Test Execution

Usage
Example

In the following example we will get the width pixels value of 80% of the screen (where the EriBank logo
ends (X coordinates of 80% of the screen)

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

©2023 Digital.ai Inc. All rights reserved Page 76


Test Execution

P2CX
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
seetest.p2cx(80);

P2CY
Description
According to the given percentage, this command will return the active device's height pixel count (Y
Coordinate) as an Integer.

With this command and the matching P2CX command, you can avoid relying on coordinates and to give
relative size not based on resolution of device

Parameters
Name Value Description
Percentage Integer Given screen percentage Value will be between 0 to 100

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 77


Test Execution

In the following example I wish to verify that the application logo is located in the top 20% of the screen. I will
have to get the width of 20% of the screen's height in coordinates.

P2CY
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
seetest.p2cy(20);

©2023 Digital.ai Inc. All rights reserved Page 78


Test Execution

SendKeysWithBT
Description
This command sends keyboard events to the Bluetooth keyboard on the device.

The device should be paired with a Bluetooth adapter in order to use this command: How to pair the device

The command is available only for users in the accessibility project.

For more details on accessibility testing, refer the following link:

Keyboard shortcuts for VoiceOver and Talkback

Parameters
Name Value Description
Keys String The value should contain both modifiers and keysModifiers must be always specified before keys.Example:""
+ Keys.CONTROL + Keys.SHIFT + "C"

Supported modifiers:
Keys.SHIFT
Keys.LEFT_SHIFT
Keys.CONTROL
Keys.LEFT_CONTROL
Keys.ALT
Keys.LEFT_ALT
Keys.META
Keys.COMMAND

Supported special keys:


Keys.BACK_SPACE
Keys.TAB
Keys.RETURN
Keys.ENTER
Keys.PAUSE
Keys.ESCAPE
Keys.SPACE
Keys.PAGE_UP
Keys.PAGE_DOWN
Keys.END
Keys.HOME
Keys.LEFT

©2023 Digital.ai Inc. All rights reserved Page 79


Test Execution

Keys.ARROW_LEFT
Keys.UP
Keys.ARROW_UP
Keys.RIGHT
Keys.ARROW_RIGHT
Keys.DOWN
Keys.ARROW_DOWN
Keys.INSERT
Keys.DELETE
Keys.SEMICOLON
Keys.EQUALS
Keys.MULTIPLY
Keys.ADD
Keys.SEPARATOR
Keys.SUBTRACT
Keys.DECIMAL
Keys.DIVIDE
Keys.F1
Keys.F2
Keys.F3
Keys.F4
Keys.F5
Keys.F6
Keys.F7
Keys.F8
Keys.F9
Keys.F10
Keys.F11
Keys.F12

Usage
Example

GetApplicationInfo
driver.executeScript("seetest:client.sendKeysWithBT", "" + Keys.CONTROL+ Keys.
ALT + "I");
driver.executeScript("seetest:client.sendKeysWithBT", "" + Keys.ESC);

In case of using a programming language other than Java where the "Keys" class is not available, we can
mimic the same behavior by sending the equivalent Unicode characters. Here's an example in WebDriverIO:

browser.execute("seetest:client.sendKeysWithBT", "\uE014");

In above example, we are sending the "Right Arrow" command. A full list of available Keys operations in
Unicode can be found here.

©2023 Digital.ai Inc. All rights reserved Page 80


Test Execution

SetPasscode
Description
Use this command to set a default passcode to the device. If it fails, it throws an exception.

This command is supported in iOS only.

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

SetPasscode
DesiredCapabilities dc = new DesiredCapabilities();
driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
seetest.setPasscode();

ClearPasscode
Description
Use this command to clears the passcode from the device. It returns true only if it was cleared successfully.

• It is recommended to use this on a supervised device.


• This command is supported in iOS only.

©2023 Digital.ai Inc. All rights reserved Page 81


Test Execution

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

ClearPasscode
DesiredCapabilities dc = new DesiredCapabilities();
driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
if(seetest.clearPasscode()) {
System.out.println("Passcode cleared successfully");
} else {
System.out.println("Failed to clear passcode");
}

StopLoggingDevice
Description
Use this command to stop the device log. This is called after calling StartLoggingDevice.

Usage

©2023 Digital.ai Inc. All rights reserved Page 82


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

StartLoggingDevice
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
//Start Logging Command
seetest.startLoggingDevice("c:\\logs");
...

//Stop Logging Command


seetest.stopLoggingDevice();

setLocationPlaybackFile
This is an asynchronous operation. It walks through the values in the given file and sets the location after the
delay in the delay parameter. This is used to simulate the movement of a device.

Use waitForSetLocationToEnd(timeout) to verify the task is complete. This command fails the
current test in case the location cannot be set.

Use StopLocationPlayback to stop the task early.

This returns true if started successfully.

Name Value Description


csvPath String Path to a CSV file with the values (Latitude, Longitude, Altitude). Altitude is supported only for Android
devices.

delay int Delay in milliseconds between every mock location.

mockReciever String Receiver to use for mocking: gps / network/ gps,network. Supported only for Android.

©2023 Digital.ai Inc. All rights reserved Page 83


Test Execution

CSV File Example


Latitude, Longitude, Altitude
28.70406,77.102493,256.5
28.984463,77.706413,230.2
30.37818,76.776695,282.6
32.259541,75.632072,334
32.726601,74.857025,302.5
34.083672,74.797279,1595.7
34.560131,76.126137,2687.2
34.152588,77.577057,3501
32.239632,77.188713,2050
31.104815,77.173403,2276
30.73827,76.765144,321
26.8465108,80.9466832,123
25.611,85.144,59.46
23.259933,77.412613,500
17.38714,78.491684,536
12.972442,77.580643,923
13.067439,80.237617,6.7
8.524139,76.936638,21.352

CSV file upload must be enabled in the settings. For more information, see File Repository.

When using multiple csv files, each task must finish before starting a new one with a different csv file. If a
new command is called before the present task finished, the new task is ignored.

You can use waitForSetLocationToEnd(timeout) command with a large enough timeout for the task
to finish before calling the next one.

The final location set using setLocationPlaybackFile command can be cleared using ClearLocation.

waitForSetLocationToEnd
This is a synchronized command that waits until setLocationPlaybackFile ends or times out. It is only valid
when using setLocationPlaybackFile with a CSV file.

It returns false if it times out.

Name Value Description


timeout int >= 0 Timeout for the command in milliseconds

SetLocation of Device
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

String csvPath = "/Users/Experitest/Documents/locations.csv";

©2023 Digital.ai Inc. All rights reserved Page 84


Test Execution

...
...
// This command sets a series of locations.
seetest.setLocationPlaybackFile(csvPath, 1000, "gps");
seetest.waitForSetLocationToEnd(10000);

StopLocationPlayback
Description
Use this command to search for any active setLocation task on the device and stop it. This is needed
because setLocationPlaybackFile is an asynchronous operation.

This operation is only relevant for setLocationPlaybackFile.

This operation does nothing if no setLocation task is active.

If it fails, it throws an exception.

Application Preparation
Before you can start working with applications, you need to install them and prepare them for testing.

The Continuous Testing Cloud client lets you execute preliminary application preparation actions in order to
make sure that your application is ready for testing.

ApplicationClearData
Description
Use this command to clear the entire application data and cache from the device it is installed on during
runtime.

Parameters
Name Type Description
BundleId (iOS) / Application Activity (Android) string Application whose data you want to clear

©2023 Digital.ai Inc. All rights reserved Page 85


Test Execution

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of ApplicationClearData Command


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

seetest.applicationClearData("com.experitest.ExperiBank/.LoginActivity");

ApplicationClose
Description
Use this command to close and kill an application in the foreground of the device during runtime.

Parameters
Name Type Description
BundleID (iOS) / Application Activity (Android) string Application to close

Use Case
You can use this to close and then launch the application in order to test stability and data persistence.

Example

©2023 Digital.ai Inc. All rights reserved Page 86


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of ApplicationClose Command


driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

seetest.applicationClose("com.experitest.ExperiBank");

Install
Description
Use this command to install an application in run time.

Parameters
Name Type Description
Path string Path of the application to be installed. Can be either a URL or the application path in the cloud.

Instrument boolean

• True - Instrumented

• False - Non-instrumented

KeepData boolean

• True - Upgrades the existing application installed without losing its data.

• False - Reinstalls the application and deletes the old data.

©2023 Digital.ai Inc. All rights reserved Page 87


Test Execution

Name Type Description

In iOS, KeepData does not have effect. Data is kept when using same provision profile. Otherwise the data
is lost.

Installing applications on grid clients from a local path has been deprecated. Instead, use cloud applications.

Use Case
Because the report is the sum of all steps (closely linked with the commands that you issued during the test),
you may want to inject custom steps and messages into the report in order to enrich the report and provide
additional information that is not found in the report, or is printed to the console instead. The command also
lets you decide whether the step has failed or passed.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of Install Command


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

....
....

//installing from a url


seetest.install("http://d242m5chux1g9j.cloudfront.net/eribank.apk", true, true
);
//installing from a cloud path
seetest.install("cloud:com.experitest.ExperiBank/.LoginActivity", true, true);

Normally when using this command, you use the launch command with it.

©2023 Digital.ai Inc. All rights reserved Page 88


Test Execution

Launch
Description
Use this command to launch applications in run time.

Parameters
Name Type Description
BundleId (iOS) / Application Activity (Android) string Application to be launched

Instrument boolean

• True - Instrumented

• False - Non-instrumented

stopIfRunning boolean

• True - Stops the app if it is running

• False - Do not stop the app but simply bring it forward

In Appium Grid, if you want to launch with with Instrument set to True, make sure that the context is set to
instrumented first. To do this, do one of the following:

• Add driver.context("NATIVE_APP_INSTRUMENTED") before launch.

• Use driver.setCapability("appInstrumented", "true").

Otherwise, Appium grid throws an error and launch fails.

Use Case
After using the install command, you would want to launch the app anytime during the test. Note that the
launch command complements the install command but does not rely on it. The launch command lets you
launch any application given that you know the BundleID (iOS), or App Package and App Main Activity
(Android).

©2023 Digital.ai Inc. All rights reserved Page 89


Test Execution

Example

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of Launch Command


driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

//your app sends a verification code to the user's phone.


//You can launch the Native iOS SMS app to retrieve the code.
seetest.launch("com.apple.mobilesms", false, false);

iOS

iOS Native Bundle IDs


App Name | Bundle ID
---------------------------------
App Store | com.apple.AppStore
Calculator | com.apple.calculator
Calendar | com.apple.mobilecal
Camera | com.apple.camera
Clock | com.apple.mobiletimer
Compass | com.apple.compass
Contacts | com.apple.MobileAddressBook
FaceTime | com.apple.facetime
Files | com.apple.DocumentsApp
Find Friends| com.apple.mobileme.fmf1
Find iPhone | com.apple.mobileme.fmip1
Health | com.apple.health
Home | com.apple.Home

©2023 Digital.ai Inc. All rights reserved Page 90


Test Execution

iBooks | com.apple.iBooks
iCloud Drive| com.apple.iclouddriveapp
iTunes Store| com.apple.MobileStore
Mail | com.apple.mobilemail
Maps | com.apple.Maps
Messages | com.apple.mobilesms
Music | com.apple.Music
News | com.apple.news
Notes | com.apple.mobilenotes
Phone | com.apple.mobilephone
Photos | com.apple.mobileslideshow
Photo Booth | com.apple.Photo-Booth
Podcasts | com.apple.podcasts
Reminders | com.apple.reminders
Safari | com.apple.mobilesafari
Settings | com.apple.Preferences
Stocks | com.apple.stocks
Tips | com.apple.tips
TV | com.apple.tv
Videos | com.apple.videos
Voice Memos | com.apple.voicememos
Wallet | com.apple.passbook
Watch | com.apple.bridge
Weather | com.apple.weather

Android

For Android it is a bit harder to get the full list and launching the app also requires the app activity. You can
use APK Info app for that purpose.

Launch with Options

SeeTest allows you to pass Environment variables and command-line arguments to the application during
the launch process.

Users are required to pass the environment variables or command-line arguments as a JSON of the key-
value set which is passed to the application

There is 2 launch with options command that exists in SeeTest.


1.) launch(String applicationIdentifier, Map launchOptions) :- This command takes application Identifier and
launchOptions as MAP
2.) launchWithOptions(String applicationIdentifier, String launchOptionsJSON) :- This command takes
application identifier and launchOptions as JSON String.

©2023 Digital.ai Inc. All rights reserved Page 91


Test Execution

While SeeTest Client support both the commands, SeeTest Appium Extension does not support the First
command. If you want to use launch with options with SeeTest Appium extension, you have to use the
second command with JSON Parameter.

Supported Keys
Key Type Description OS
relaunch boolean Whether or not to kill the application in case it is running Android &
iOS

instrument boolean Launch the application in an instrumented mode Android

launch_args JSON Array An ordered array of command line args iOS

launch_env JSON Object Set of key = value pairs that will be passed as Environment variables to the iOS
application

verify boolean Whether or not to verify that the application is still in the foreground when the iOS
launch ends.If not specified, defaults to true.Set this option to false if the
application is not expected to stay in the foreground after it is launched.

initial_wait boolean Whether or not to wait for the application to launch and idle.If not specified, iOS
defaults to true.Set this option to false in order to speed up the launch process,
and not wait for the application to idle.If set to false, it is client responsibility to
handle synchronisation issues and verify launch succeeded.

<adb-option- <adb-option- key-value pairs of adb extra options Android


key> value>

• Instrumentation in iOS is determined during installation.

The examples below show a couple of use cases for this feature for users who are using JAVA and Ruby
Clients.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example - Java launch iOS App with options and pass JSON as environment variables
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<Device_ID>");
driver = new AndroidDriver(new URL("<server>"), dc);

©2023 Digital.ai Inc. All rights reserved Page 92


Test Execution

client = new SeeTestClient(driver);

JsonObject launchOptions = new JsonObject();


launchOptions.addProperty("relaunch", true);
// Create ENV vars JSON Object to pass to the application so it will run in DE
BUG with a secret key
JsonObject envVars = new JsonObject();
envVars.addProperty("secret_key", "DFSF5343543CAA");
envVars.addProperty("DEBUG", true);

launchOptions.add("launch_env",envVars);
client.launchWithOptions("com.experitest.ExperiBank", launchOptions.toString()
);

Example - Java launch Android App with adb options


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<Device_ID>");
driver = new AndroidDriver(new URL("<server>"), dc);
client = new SeeTestClient(driver);

// Launch app as non-instrumented, use relaunch


JsonObject launchOptions = new JsonObject();
launchOptions.addProperty("instrumented", false);
launchOptions.addProperty("relaunch", true);
// Add adb params
launchOptions.addProperty("-D", "");
launchOptions.addProperty("--es", "android.intent.extra.TEXT Hello");

client.launchWithOptions("com.experitest.ExperiBank/.LoginActivity",launchOpti
ons.toString());

• In iOS:

When passing to the application ENV vars or CMD line ARGS Make sure that you also pass the key
"relaunch" with value `true` so that the application will be able to parse these arguments

• In Android:

Options are:

◦ -D: Enable debugging.


◦ -W: Wait for launch to complete.
◦ --start-profiler file: Start profiler and send results to file.
◦ -P file: Like --start-profiler, but profiling stops when the app goes idle.

©2023 Digital.ai Inc. All rights reserved Page 93


Test Execution

◦ -R count: Repeat the activity launch count times. Prior to each repeat, the top activity
will be finished.
◦ -S: Force stop the target app before starting the activity.
◦ --opengl-trace: Enable tracing of OpenGL functions.
◦ --user user_id | current: Specify which user to run as; if not specified, then run as
the current user.
◦ --es: extra custom options

Uninstall
Description
The command allows you to uninstall applications in run time.

Parameters
Name Value Description
BundleId (iOS) / Application Activity (Android) string The app to uninstall

Usage
For good measure and for leaving behind you a clean environment, you can uninstall application that you
used during the test.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of Uninstall Command


driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

©2023 Digital.ai Inc. All rights reserved Page 94


Test Execution

...
...

seetest.uninstall("com.experitest.ExperiBank");

Element Commands
SeeTest Client element commands allow you to interact with elements in your application or website.

These commands make it easier to interact with elements and execute actions that are hard to configure
using native Appium commands.

Click
Description
This command will click an element. Although Appium provides a native click method, the SeeTest Client
extends the click command by allowing you to specify how many clicks to perform. In addition, this command
has the ability to click on elements based on OCR (optical character recognition).

Parameters
Name Value Description
zone string Zone - Native, Web, Text (OCR)

elemen string xpath of the element to find. In case of Text (OCR), the element's text

index int index of the element to find, if more than one element answers to the xpath query

clickCount int Number of clicks to perform

Usage
If your app includes a feature where an element or button need to be clicked more than once, you can use
this command. You can also use this command to click on element that does not have a defined XPath and
can only be recognized based text that appears in their image.

©2023 Digital.ai Inc. All rights reserved Page 95


Test Execution

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of Click Command


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

// to click an native element in an app


seetest.click("NATIVE", "xpath=//*[@text='click me']", 0, 5);

// to click an element by OCR


seetest.click("TEXT", "click me", 0, 5);

ClickCoordinate
Description
This command will click an element according to the coordinates specified in the command.

Parameters
Name Value Description
x coordinate int X: Horizontal Offset from the Element in screen pixels

y coordinate int Y: Vertical Offset from the Element in screen pixels

©2023 Digital.ai Inc. All rights reserved Page 96


Test Execution

Name Value Description


clickCount int Number of clicks to perform

Usage
This command allows you to click an element according to its location on the screen, using x and y
coordinates.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of ClickCoordinate Command


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

// locate the element at coordinates x: 250, y: 100 and clicks on it three tim
es
seetest.clickCoordinate(250, 100, 3);

DragDrop
Description
This command allows you to drag an element or text from a specified zone and drop it on another element.

©2023 Digital.ai Inc. All rights reserved Page 97


Test Execution

Parameters
Name Value Description
Zone string Select Zone - Native or Web

DragElement string The xpath identifier of the element to be dragged

DragIndex int Specify index if the element appears more than once

DropElement string The xpath identifier of the element onto which the previous element will be dropped

DropIndex Specify index if the element appears more than once

Usage
You can use this command to test drag drop scenarios if your app allows that (i.e. your app is a game that
incorporates the dragging and dropping of elements).

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of DragDrop Command


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

// specify how much time should pass before the drag action starts
// this ensures that the dragged elements is caught
seetest.setDragStartDelay(1000);
// locate the element at coordinates x: 250, y: 100 and clicks on it three tim

©2023 Digital.ai Inc. All rights reserved Page 98


Test Execution

es
seetest.dragDrop("NATIVE", "xpath=//*[@text='DemoUI']", 0, "xpath=//*[@text='E
riBank']", 0);

In this example, dragging the DemoUi element on top of the EriBank element will create a folder that
contains them both.

©2023 Digital.ai Inc. All rights reserved Page 99


Test Execution

SwipeWhileNotFound
Description
This command will swipe the screen in search of element. If found, the command will return true, allowing
you to use it in an if-else construct.

Parameters
Name Value Description
direction string Direction to swipe:Up, down, left, right

offset int Swipe offset, the distance from the bottom of the screen in pixels

swipeTime int Swipe Time, swipe round duration in milliseconds.

zone string Zone - Native, Web

elementToFind string xpath of the element to find

elementToFindInex int index of the element to find, if more than one element answers to the xpath query

delay int Time to wait before sending a command (in milliseconds), delay time between swipes

rounds int Maxium swipe rounds

click boolean True - click the element once it's foundFalse - don't click the element

Usage
If your app requires scrolling up or down in search of an element to click on, you can test this activity using
the swipeWhileNotFound command.

Example
Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 100


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of SwipeWhileNotFound Command


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

...
...

if(seetest.swipeWhileNotFound("Down", 0, 2000, "NATIVE", "xpath=//*[@text='ord


er']", 0, 1000, 5, true))
{
// if statement
}

ElementGetProperty
Description
Command to get a property of an element. It can retrieve all properties of the elements that are showing on
the object spy as also controllers.

Parameters
Name Value Description
Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

©2023 Digital.ai Inc. All rights reserved Page 101


Test Execution

Name Value Description


Element String which identifies the Element Identification of Element in the device screen.Example: Button, Text
Box.

Element index Integer representing index of the Element

Property String value of the Element Property Property of Element.Example : Text

Usage:
This command can be used get any property element.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

ElementGetProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Command will fetch the "enabled" property of Element "Contacts" if the Andr
oid Contacts App is opened and
// displayed in the Device screen
System.out.println(seetest.elementGetProperty("NATIVE", "//*[@text='Contacts']
", 0, "enabled"));

©2023 Digital.ai Inc. All rights reserved Page 102


Test Execution

GetAllValues
Description
Get all the values of a certain property from all the existing elements. Possible properties are all the methods
available on the Object spy for the page.

Parameters
Name Value Description
Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Element Identifier as String Identification of Element in the device screen.Identification can be XPATH or any other
Appium Element Identifier.

Property Property name as String The property or method to be extracted from the elements that meet the query

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GetAllValues
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...

©2023 Digital.ai Inc. All rights reserved Page 103


Test Execution

...
// Gets all the values of the property "text" for all elements which are ident
ified by given xpath.
seetest.getAllValues("NATIVE", "//*[@id='usernameTextField']", "text");

ElementSetProperty
Description
Designed command to set values of controllers such as date pickers, sliders, switches etc.

Parameters
Name Value Description
Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Element Identifier as String Identification of Element in the device screen.Identification can be XPATH or
any other Appium Element Identifier.

Index Element index Index of Element

Property Property name as String Property Name

Value Value of the property name as String Property Value

Usage
Command is used to set value for a property of an Element in the device screen.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

©2023 Digital.ai Inc. All rights reserved Page 104


Test Execution

Example

ElementSetProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Sets the property "text" of the element identified by XPATH "//*[@class='UIA
PickerWheel']" to 19.
seetest.elementSetProperty("NATIVE", "//*[@class='UIAPickerWheel']", 1, "text"
, "19");

The above code will work if you have the iOS native date and time running in foreground as shown in image
below.

TouchCoordinate Commands
Note

©2023 Digital.ai Inc. All rights reserved Page 105


Test Execution

Touch commands supported in iOS only in instrumented Native zone, Android supports all zones

TouchDownCoordinate
Description

Touch down at X,Y coordinates

Parameters

Name Value
Horizontal Coordinate Integer Horizontal coordinate

Vertical coordinate Integer Vertical coordinate

TouchMoveCoordinate
Description

Touch move to to X, Y coordinates, this command should come after touchDownCoordinate or touchDown
commands.

Parameters

Name Value
Horizontal Coordinate Integer Horizontal coordinate

Vertical coordinate Integer Vertical coordinate

TouchUp
Description

Touch Up from last element/coordinate touched down or moved to.

Usage
Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 106


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

TouchDown Commands
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

seetest.touchDownCoordinate(236, 737);
seetest.touchMoveCoordinate(1200, 1700);
seetest.touchMoveCoordinate(700, 1700);
seetest.touchUp();

Touch Commands
Note

Touch commands supported in iOS only in instrumented Native zone, Android supports all zones

TouchDown
Description

Touch down on element.

©2023 Digital.ai Inc. All rights reserved Page 107


Test Execution

Parameters

Name Value Description


Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Element Identifier as String Identification of Element in the device screen.Identification can be XPATH or any other
Appium Element Identifier

Index Element index as Integer Index of Element

TouchMove
Description

Touch move to element, this command should come after touchDown or touchDownCoordinate commands.

Parameters

Name Value Description


Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Element Identifier as String Identification of Element in the device screen.Identification can be XPATH or any other
Appium Element Identifier

Index Element index Index of Elemen

©2023 Digital.ai Inc. All rights reserved Page 108


Test Execution

TouchUp
Description

Touch Up from last element/coordinate touched down or moved to.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Touch Commands
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

client.touchDown("NATIVE", "//*[@text=Username']", 0);


client.touchMove("NATIVE", "//*[@text='Login']", 0);
client.touchUp();

ElementSendText
Description
Send text to an element

©2023 Digital.ai Inc. All rights reserved Page 109


Test Execution

Parameters
Name Value Description
Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Element Identifier as String Identification of Element in the device screen.Identification can be XPATH or any other
Appium Element Identifier

Index Element index as Integer Index of Element

Text String Text to Send

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

ElementSendText
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//show the list of recent apps


seetest.elementSendText("NATIVE", "//*[@accessibilityLabel='Username']" , 0 ,
"company");

©2023 Digital.ai Inc. All rights reserved Page 110


Test Execution

ElementListSelect
Description
Select an element within a list (first making the element visible)

Note: This command will work only on instrumented applications

Parameters
Name Value Description
List locator String A String identifier of List locator

Element locator String A String identifier of Element locator

Index Integer Element Index

Click Boolean True to select the element.

Usage
The command can be used to select an element in a List.

Example

Consider the EriBank Application,

Step 1: Login to the EriBank application.

Step 2: Click the Make Payment button.

Step 3: Click Select button.

In Automation mode open Open the Object Spy.

Now we need to find the list locator identifier.

©2023 Digital.ai Inc. All rights reserved Page 111


Test Execution

Click the parent of the list element and note down the list locator identifier which is in this case
"accessibility=conutryView".

Now we need to find the element identifier,

©2023 Digital.ai Inc. All rights reserved Page 112


Test Execution

Click any element in the list and note down the Element identifier which is text=Greece.

Once this is done the following code cane be used to select the Element in the list locator.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

ElementListSelect
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...

©2023 Digital.ai Inc. All rights reserved Page 113


Test Execution

...

seetest.elementListSelect("accessibilityLabel=conutryView","text=Greece", 0, t
rue);

VerifyElementFound
Description
Verification command to check if an element exists.

Parameters
Name Value Description
zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String Identification of Element in the device screen.

Index Integer Element to find index

Usage
Command to check of element is found in screen. If not found throws and exception.

Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 114


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

VerifyElementFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Check if the element representing "text" = "login" is found in NATIVE zone
.
seetest.verifyElementFound("NATIVE", "text=Login", 0);

VerifyElementNotFound
Description
Verify that an element is NOT found in a specified zone

Parameters
Name Value Description
zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

©2023 Digital.ai Inc. All rights reserved Page 115


Test Execution

Name Value Description


Element String Identification of Element in the device screen.

Index Integer Element to find index

Usage
Command can be used to check if the specified element is not found in the device screen, if it is found it will
lead to an Exception.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 116


Test Execution

VerifyElementNotFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Check if the element representing "text" = "login" is found in NATIVE zone
.
seetest.verifyElementNotFound("TEXT", "Login", 0);

SendWhileNotFound
Description
Send given text while an element is not found.

There are a few KEY EVENTS(listed below) that can be used (such as the one in the following example)

Parameters
Name Value Description
ToSend String These are typically KEY EVENTS

Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

ElementToFind String Identification of Element in the device screen.

©2023 Digital.ai Inc. All rights reserved Page 117


Test Execution

Name Value Description


Element to find index Integer Element to find index

Timeout Integer Waiting Timeout in millisecondsExample : 7000 for 7 seconds

Delay Integer Delay in milliseconds

Key Events
• For the Home key use {Home}
• For deleting text: {BKSP}
• For unlocking and waking the device : {UNLOCK}
• Closing the keyboard on the device: {CLOSEKEYBOARD}
• Toggle orientation:
◦ For landscape: {LANDSCAPE}
◦ For Portrait: {PORTRAIT}

Usage
This command can be used in the navigation function, which will know how to identify the current location in
the application and navigate to any other required page. This behaves as a recovery mechanism when a test
fails.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

In following {BKSP} i.e. back will be sent to the device till the text 123 is found. As you can see the we do
have 12345 as initial text and then 2 backspaces will be sent, since 123 will found this command will be
successful.

©2023 Digital.ai Inc. All rights reserved Page 118


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 119


Test Execution

SendWhileNotFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Backspaces till the screen as text 123
seetest.sendWhileNotFound("{BKSP}", "NATIVE", "text=123", 0, 10000, 1000);

LongClick
Description
Long click on or near an element or text (the proximity to the element/text is specified by an X-Y offset)

Parameters

Name Value Description


Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String Identification of Element in the device screen.

©2023 Digital.ai Inc. All rights reserved Page 120


Test Execution

Name Value Description


Element to find index Integer Element to find index

Click Count Integer Number of clicks

Horizontal Offset Integer Horizontal Offset from the Element in screen pixels

Horizontal Offset Integer Vertical Offset from the Element in screen pixels

Usage
Designed command for longer click operations (click duration is 2000 milliseconds)

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

LongClick
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// This command will look for the EriBank application in device screen at the
moment and long click once.
seetest.longClick("NATIVE", "//*[@text='EriBank']", 0, 1, 0, 0);

ElementListPick
Description
Select an element from the Object Repository in a list (first make the element visible) Equivalent command
to elementListSelect command.

©2023 Digital.ai Inc. All rights reserved Page 121


Test Execution

Note: This command will work only on instrumented applications

Parameters
Name Value Description
List Zone Name String with available zones Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

List locator String A String identifier of List locator

List Zone Name String with available zones Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element locator String A String identifier of Element locator

Index Integer Element Index

Click Boolean If true then click

Usage
Uses zones to identify the list Locator and the element Locator

Example

Image and code below displays how this command can be used.

©2023 Digital.ai Inc. All rights reserved Page 122


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

ElementListPick
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//

©2023 Digital.ai Inc. All rights reserved Page 123


Test Execution

seetest.elementListPick("NATIVE", "id=countryList", "NATIVE", "text=United Kin


gdom", 0, true);

ElementListVisible
Description
Matching command to ElementListSelect. Will make an element on a list visible.

Note: This command will work only on instrumented applications

Parameters
Name Value Description
List locator String A String identifier of List locator

Element locator String A String identifier of Element locator

Index Integer Element Index

Usage
This is actually elementListSelect command with click parameter of false.

Example

Consider the EriBank Application,

Step 1: Login to the EriBank application.

Step 2: Click the Make Payment button.

Step 3: Click Select button.

In Automation mode open Open the Object Spy.

Now we need to find the list locator identifier.

©2023 Digital.ai Inc. All rights reserved Page 124


Test Execution

Click the parent of the list element and note down the list locator identifier which is in this case
"accessibility=conutryView".

Now we need to find the element identifier,

©2023 Digital.ai Inc. All rights reserved Page 125


Test Execution

Click any element in the list and note down the Element identifier which is text=Greece.

Once this is done the following code cane be used to select the Element in the list locator.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

ElementListVisible
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

seetest.elementListVisible("accessibilityLabel=conutryView","text=Greece", 0);

©2023 Digital.ai Inc. All rights reserved Page 126


Test Execution

ElementSwipe
Description
Swipe the screen in a given direction. The command will only perform the swipe within a given container.

Parameters
Name Value Description
Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Element Identifier as String Identification of Element in the device screen.Identification can be XPath or any other
Appium Element Identifier.

Index Integer Index of Element

Direction String Direction to swipe

Offset Integer Swipe offset

Time Integer Swipe overall time (milliseconds)

Usage
Equivalent command to the swipe command. This command will swipe inside a container and not the entire
screen.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

©2023 Digital.ai Inc. All rights reserved Page 127


Test Execution

Example

In this example swipe down is attempted in element "id=brown_menu"

ElementSwipe
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
// Swipes down
seetest.elementSwipe("NATIVE", "id=browse_menu", 0, "Down", 500, 1000);

ElementSwipeWhileNotFound
Description
Swipe inside a component to search for an element or text.

Parameters
Name Value Description
Zone String as valid zones Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

SearchElement String The container element identifier

Direction String Direction to swipe

Offset Integer Swipe Offset

©2023 Digital.ai Inc. All rights reserved Page 128


Test Execution

Name Value Description


Swipe Time Integer Time for the swipe action

Element to find Zone String as valid zones Zone of the sought element

• NATIVE

• WEB

• TEXT

Element to find String The sought element identifier

Element to Find Index Integer The sought element’s index (i.e., the number of times the element appears after
the first appearance minus two).

Delay Integer Time to wait before sending a command (in milliseconds)

Rounds Integer Maximum swipe rounds

Click Boolean Click the found element if TRUE

Usage
Command could be used to scroll down till element is not found

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 129


Test Execution

ElementSwipeWhileNotFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

if(seetest .elementSwipeWhileNotFound("NATIVE", "id=nav_drawer", "Down", 0, 20


00, "NATIVE", "text=History", 0, 1000, 5, true)){
// If statement
}

©2023 Digital.ai Inc. All rights reserved Page 130


Test Execution

FlickCoordinate
Description
Flick the screen from X, Y in a given direction

Parameters
Name Value Description
X Integer Horizontal Coordinate in screen pixels

Y Integer Vertical Coordinate in screen pixels

Direction String Direction of the Flicking motion

Usage
In order to flick the screen you can add the command 'flick', provide the starting point and the direction.

As a visible aid, an arrow will be drawn on the reflection showing the flick motion.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

FlickCoordinate
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Flick up to given coordinates
seetest.flickCoordinate(78, 286, "Up");

©2023 Digital.ai Inc. All rights reserved Page 131


Test Execution

FlickElement
Description
Flick the chosen element in the chosen direction

Parameters
Name Value Description
Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String which identifies the Element Identification of Element in the device screen.Example: Button, Text
Box.

Element index Integer representing index of the Element

Direction String Direction of the Flicking motion

Usage
Command can be used to flick an element from its center, in the chosen direction.

As a visible aid, an arrow will be drawn on the reflection showing the flick motion.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

FlickElement

©2023 Digital.ai Inc. All rights reserved Page 132


Test Execution

DesiredCapabilities dc = new DesiredCapabilities();


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
seetest.flickElement("NATIVE", "xpath=//*[@text='Phone']", 0, "Up");

GetElementCount
Description
Count the number of times an element or text is found.

Parameters
Name Value Description
Zone Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String which identifies the Element Common identifier to all the elements to count.

Usage
Command can be used to get the count of element found in a screen.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

©2023 Digital.ai Inc. All rights reserved Page 133


Test Execution

Example

GetElementCount
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Counts the number of times element corresponding to //*[@class='android.wid
get.TextView'
int int0 = client.getElementCount("NATIVE", "//*[@class='android.widget.TextVi
ew']");

GetElementCountIn
Description
Count the number of elements appearances in a container.

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Search String Search Element

Index Integer Element index

Direction String Direction to analyze. The options


are UP, Down, Left, Right or Inside

Element Count String with one of the following values The zone to extract the text from
Zone

©2023 Digital.ai Inc. All rights reserved Page 134


Test Execution

Name Value Description


• NATIVE

• WEB

• TEXT

Element Count Integer Select Element to count

Width Integer Width of the search

Height Integer Height of the search

Usage
Similar command to getElementCount command which will count elements based on a container.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

Following example we count number of buttons in the application below.

©2023 Digital.ai Inc. All rights reserved Page 135


Test Execution

GetElementCountIn
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
int int0 = seetest.getElementCountIn("NATIVE", "//*[@id='scrollView1']", 0, "I
nside", "NATIVE", "class=android.widget.Button", 0, 0);

©2023 Digital.ai Inc. All rights reserved Page 136


Test Execution

GetTextIn
Description
Get text in a certain area relative to an element . The direction can be UP, DOWN, LEFT or RIGHT.

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String Select an Element

Index Integer Element index

Text Zone String with one of the following values The zone to extract the text from. See getText command for the options.

• NATIVE

• WEB

• TEXT

Direction String Direction to analyze - can be UP, Down, Left, Right or Inside

Width Integer Width of the search

Height Integer Height of the search

Usage
Command can be used to get text for certain area.

Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 137


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

In this example we will try to get all the text of the Web part from the EriBank Application.

Login to Eribank Application to get following screen

©2023 Digital.ai Inc. All rights reserved Page 138


Test Execution

Using Object Spy find the Xpath corresponding to the "MakePayment". Use the code snippet below to use
this command to get the text.

GetTextln
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
String str0 = client.getTextIn("NATIVE", "accessibilityLabel=makePaymentButton
", 0, "WEB", "Up", 0, 0);

IsElementFound
Description
Check if a given element or text is found in the specified zone; if found returns TRUE if not found returns
FALSE.

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

SearchElement String Element to search.

Index Integer Element or text index

©2023 Digital.ai Inc. All rights reserved Page 139


Test Execution

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

IsElementFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Checks if the device screen/application has the elemenent corresponding to /
/*[text='register']
if(seetest.isElementFound("NATIVE", "//*[text='register']", 0)){
// If statement
}

IsFoundIn
Description
Search for an element and check if an element related to it exists. The direction can be UP, DOWN, LEFT or
RIGHT.

©2023 Digital.ai Inc. All rights reserved Page 140


Test Execution

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Search String Search Element

Index Integer Element index

Direction String Direction to analyze. The options


are UP, Down, Left, Right or Inside

Element Find Zone String with one of the following values Find Element Zone

• NATIVE

• WEB

• TEXT

ElementToFind Integer Element to Find

Width Integer Width of the search

Height Integer Height of the search

Usage
Command can be used to find and Element using an other element.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 141


Test Execution

In the following example, we will try to find the ‘Make Payment’ button using the ‘Mortgage Request’ button.

We need to find the XPATH of Make Payment and Mortgage Request.

IsFoundIn
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

©2023 Digital.ai Inc. All rights reserved Page 142


Test Execution

//Checked if MakePaymentButton is above Mortgage Request.


seetest.isFoundIn("NATIVE", "accessibilityLabel=Mortgage Request", 0, "Up", "N
ATIVE", "accessibilityLabel=makePaymentButton", 0, 0);

VerifyIn
Description
Search for an element and verify that an element related to it exists. The direction can be UP, DOWN, LEFT
or RIGHT.

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Search String Search Element

Index Integer Element index

Direction String Direction to analyze. The options are UP, Down, Left, Right or Inside

Element FindZone String with one of the following values Find Element Zone

• NATIVE

• WEB

• TEXT

ElementToFind Integer Element to Find

Width Integer Width of the search

Height Integer Height of the search

©2023 Digital.ai Inc. All rights reserved Page 143


Test Execution

Usage
Command can be used to verify an element is present in relation with another element.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

We will use the EriBank application to identify the Make Payment button using the Mortgage Request
button.

Login and navigate to the Make Payment page. Once login is successful we get following screen.

©2023 Digital.ai Inc. All rights reserved Page 144


Test Execution

We need to find the XPATH of Make Payment and Mortgage Request. Once done command can be used.
See below.

VerifyIn
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Checked if MakePaymentButton is above Mortgage Request.

©2023 Digital.ai Inc. All rights reserved Page 145


Test Execution

seetest.verifyIn("NATIVE", "accessibilityLabel=Mortgage Request", 0, "Up", "NA


TIVE", "accessibilityLabel=makePaymentButton", 0, 0);

WaitForElement
Description
Sets sleep until element is identified.

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String Query to identify the objects/Name of the element.

Index Integer Element index

Timeout Integer Waiting Timeout in milliseconds.

Usage
Command can be used to find element till a timeout. This can be useful in Web application in which element
is loads after a delay.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

©2023 Digital.ai Inc. All rights reserved Page 146


Test Execution

Example

WaitForElement
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Waits for the Element with "id=FirstName" until 10000 milliseconds
seetest.waitForElement("WEB", "id=FirstName", 0, 10000)

WaitForElementToVanish
Description
Wait for Element to disappear from the screen.

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String Select Element to wait for.

Index Integer Element index

Timeout Integer Waiting Timeout in milliseconds.

Usage
Command can be used to wait for an element to disappear until a given time.

Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 147


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

WaitforElementToVanish
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Waits for the Element identified by XPATH //*[@accessibilityLabel='Network co
nnection in progress'] to disappear until 10000 milliseconds
if(seetest.waitForElementToVanish("NATIVE", "//*[@accessibilityLabel='Network
connection in progress']", 0, 10000)){
// If statement
}

ForceTouch
Description
Simulates force touch on an element.

Supported only in iOS Device

Parameters
Name Value Description
Zone String with one of the following Zones which define the way the element will be identified.
values

• NATIVE

• WEB

©2023 Digital.ai Inc. All rights reserved Page 148


Test Execution

Name Value Description


• TEXT

Element String Select Element

Index Integer Element index

Duration Integer Duration of the peek (click) action in milliseconds.

Force Integer Force level - percent (100% - Max force) - relevant for instrumented
applications.

DragDistanceX Integer Horizontal distance of drag, starting from the Element Coordinates.

DragDistanceY Integer Vertical distance of drag, starting from the Element Coordinates.

DragDuration Integer Duration of the pop (drag) action in milliseconds.

Usage
Command can be used to force touch an element.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

This example demonstrates how to perform the peek and pop event on the medium button, we will use
100% force level for the peek and then drag up the element to expose the actions dialog.

To drag up we will set 'DragDistanceY' to '-250'.

©2023 Digital.ai Inc. All rights reserved Page 149


Test Execution

ForceTouch
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
//Force touch on Element accessibilityLabel=ExperiTest
seetest.forceTouch("NATIVE", "accessibilityLabel=ExperiTest", 0, 100, 100, 0,
-250, 1500);

SetPickerValues
Description
Designed command to set values for pickers.

©2023 Digital.ai Inc. All rights reserved Page 150


Test Execution

Parameters
Name Value Description
ZoneName String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String Select Element (XPath is supported for the picker identifier)

Index Integer Picker Index

WheelIndex Index Wheel index at the selected picker

Value String The value to be set

Note: Wheelindex is only relevant for iOS, because a picker in iOS might have multiple wheels.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

In this example, UICatalog's the picker value is reduced by 4 in Non-Instrumented mode.

©2023 Digital.ai Inc. All rights reserved Page 151


Test Execution

SetPickerValues
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

seetest.setPickerValues("NATIVE", "xpath=//*[@class='UIAPicker']", 0, 1, "down


:4");

Gesture Commands
A gesture is a sequence of touch events, done with one or more fingers. To simulate a single or multi-
touch gesture, a set of gesture commands are provided by SeeTest Extension.

©2023 Digital.ai Inc. All rights reserved Page 152


Test Execution

A gesture consists of one or more event sequences (paths), where each path is executed with a different
finger.

Supported by iOS devices only

The general structure for gesture is as follows (in pseudo-code):

General Stycture of Commands


// tells the client we want to perform a gesture
gestureStartBuilding(...);

// path 1 - add commands for the first simulated finger


gestureTouchDown...;
gestureTouchMove...;
gestureWait...;
gestureTouchUp...;

// path 2 - add commands for the second simulated finger


gestureTouchDown...;
gestureTouchUp...;

// identify elements and perform the gesture on the device


gesturePerform...;

A few points to note:

1. To start a set of gesture commands, we need to execute gestureStartBuilding() first.


2. All gesture steps will be performed when executing gesturePerform().
3. Each gesture command is given a finger index. Index is any integer.
4. Events can be performed on elements, given by any identification method, or by coordinates.
5. Paths start executing at the same time. i.e., path 1 and path 2 from the above example will start
executing at the same time.

StartMultiGesture
Description

Indicate to SeeTest that the following commands sent from the client are grouped under the multi gesture
step.

©2023 Digital.ai Inc. All rights reserved Page 153


Test Execution

PerfomMultiGestureStep
Description

Takes the steps added since the last StartMultiGesture command till this command and sends them to the
device.

At this step, the elements used in different commands will be identified, for example an element identified
with xpath in native zone.

MultiTouchDown
Description

Adds a touch down event on the given element, with the given finger index.

Parameters

Name Value Description


Zone String Select Zone

• NATIVE

• WEB

• TEXT

Element Integer Select Element

Index Integer Element index

FingerIndex Integer finger index - distinguishes between paths.

MultiTouchDownCoordinate
Description

Adds a touch down event on the given coordinate, with the given finger index.

©2023 Digital.ai Inc. All rights reserved Page 154


Test Execution

Parameters

Name Value Description


X-Coordinate Integer the x coordinate for the touch point

Y-Coordinate Integer the y coordinate for the touch point

FingerIndex Integer finger index - distinguishes between paths.

MultiTouchMove

Description
Adds a move event to the given element, with the given finger index.

The move will start from the last point touched down or moved to.

Parameters
Name Value Description
Zone String Select Zone

• NATIVE

• WEB

• TEXT

Element Integer Select Element

Index Integer Element index

FingerIndex Integer finger index - distinguishes between paths.

MultiTouchMoveCoordinate

Description
Adds a move event to the given coordinate, with the given finger index.

©2023 Digital.ai Inc. All rights reserved Page 155


Test Execution

The move will start from the last point touched down or moved to.

Parameters
Name Value Description
X-Coordinate Integer the x coordinate for the touch point

Y-Coordinate Integer the y coordinate for the touch point

FingerIndex Integer finger index - distinguishes between paths.

MultiTouchUp
Description

Touch up from the last point touched down or moved to.

Parameters

Name Value Description


FingerIndex Integer finger index - distinguishes between paths.

MultiClick
Description

Adds a click on the given element, with the given finger index.

Parameters

Name Value Description


Zone String Select Zone

• NATIVE

• WEB

• TEXT

©2023 Digital.ai Inc. All rights reserved Page 156


Test Execution

Name Value Description


Element Integer Select Element

Index Integer Element index

FingerIndex Integer finger index - distinguishes between paths.

MultiClickCoordinate
Description

Adds a click one the given coordinate, with the given finger index

Parameters

Name Value Description


X-Coordinate Integer the x coordinate for the touch point

Y-Coordinate Integer the y coordinate for the touch point

FingerIndex Integer finger index - distinguishes between paths.

MultiSwipe

Description
Performs a swipe across the screen in the given direction, with the given finger.

Parameters
Name Value Description
Direction String Direction of the swipe motion.

Offset Integer Swipe offset (in pixels).

Time Integer Overall swipe time

FingerIndex Integer finger index - distinguishes between paths.

©2023 Digital.ai Inc. All rights reserved Page 157


Test Execution

MultiWait
Description

Adds a wait, with the given finger.

Parameters
Name Value Description
Direction String Direction of the swipe motion.

Offset Integer Swipe offset (in pixels).

Time Integer Overall swipe time

FingerIndex Integer finger index - distinguishes between paths.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Gesture Commands
DesiredCapabilities dc = new DesiredCapabilities();
driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
seetest.launch("com.apple.Maps", false, false);
// finger 0
seetest.startMultiGesture("test");
seetest.multiTouchDownCoordinate(200,600, 0);
seetest.multiTouchMoveCoordinate(250, 600, 0);
seetest.multiTouchUp(0);

// finger 1
seetest.multiTouchDownCoordinate(170,600, 1);
seetest.multiTouchMoveCoordinate(140, 600, 1);
seetest.multiTouchUp(1);

©2023 Digital.ai Inc. All rights reserved Page 158


Test Execution

seetest.performMultiGesture();

RunNativeAPICall
Description
Gives the ability to create and run scripts that are based on the Native API methods available for the class of
the element.

Note: This command will work only on instrumented applications.

Parameters
Name Value Description
Zone String with valid values as Select Zone

• NATIVE

• WEB

• TEXT

Element Integer Select Element (should use xPath)

Index Integer Element index

Script String The Native API script that will run on the identified element

©2023 Digital.ai Inc. All rights reserved Page 159


Test Execution

Usage
Command be used to run scripts based on Native API call. See the example below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

Consider a video element identified by id named 'video_view'.

If there is script to,

• view.pause - will pause the video.


• view.getDuration - will return the total length of the video in milliseconds.
• view.seekTo - will move the video to a specific time position.

then this command can be used to execute the script such that all actions above can be performed.

DesiredCapabilities dc = new DesiredCapabilities();


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Run the script on the element identified by "xpath=//*[@id='video_view']"
seetest.runNativeAPICall("NATIVE", "xpath=//*[@id='video_view']", 0, "view.pau
se(); var length = view.getDuration(); length = length*0.9; view.seekTo(length
);");

©2023 Digital.ai Inc. All rights reserved Page 160


Test Execution

Drag
Description
Drag an element or text into a specified zone (you can drag the second, third, etc appearance of the element
by setting Index to 1, 2, etc)

Parameters
Name Value Description
Zone String with following valid values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element Element Identifier as String Select Element from drop-down list OR (for OCR text identification) insert text into
the empty box in the drop down list

Index Integer Element Order

XOffset Integer Horizontal Offset from the Element in screen pixels (negative values are possible,
can use P2cx to convert screen percentage to pixels)

YOffset Integer Vertical Offset from the Element in screen pixels (negative values are possible, can
use P2cy to convert screen percentage to pixels)

Usage
Command can be used with SetDragStartDelay command in order to move and element such as icon to one
location to other.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 161


Test Execution

In the following example, we will use the drag command together with the SetDragStartDelay command in
order to move the Play Store icon across the device's springboard.

Drag
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//Command to delay in drag.


seetest.setDragStartDelay(5000);
seetest.drag("NATIVE", "xpath=//*[@text='Play Store']", 0, 0, -300);

©2023 Digital.ai Inc. All rights reserved Page 162


Test Execution

GetPickerValues
Description
Get all values from picker element.

Supported only in iOS

Parameters
Name Value Description
Zone String with one of the following values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

PickerElement String Select the picker Element

Index Integer Element index.

Value String The value to be set

WheelIndex Index Wheel index at the selected picker

Usage
Command can be used to get all the values of a picker element.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 163


Test Execution

In the example below, An App UICatalog's picker values are retrieved by executing the command.

GetPickerValues
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Getting the picker values for the XPATH, //*[@class='UIAPicker']
String vals = seetest.getPickerValues("NATIVE", "xpath=//*[@class='UIAPicker']
", 0, 0);

©2023 Digital.ai Inc. All rights reserved Page 164


Test Execution

ElementGetTableRowsCount
Description
This command allows you to extract the numbers of one or more rows of a given table, whether the table is
entirely visible on the screen or not.

Note: This command will work only on instrumented applications.

Parameters
Name Value Description
Zone String with one of the following values Select the Zone in which the table is stored

• NATIVE

• WEB

• TEXT

TableLocator String Locator of the table class element

TableIndex Integer Index in case of multiple tables on the screen

Visbile Boolean Boolean parameter. Set true to return the number of visible rows only,
or false to return the total number of rows including ones that are not
visible.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

©2023 Digital.ai Inc. All rights reserved Page 165


Test Execution

In the following example, number of rows of UICatalog application is extracted.

ElementGetTableRowsCount
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Gets the number of rows.
int int3 = client.elementGetTableRowsCount("NATIVE", "xpath=//*[@class='UITabl
eView']", 0, true);

Utilities Commands

SeeTest Appium Extension provides several commands which acts as helper commands in automation
testing.

©2023 Digital.ai Inc. All rights reserved Page 166


Test Execution

AddTestProperty
Description
Use this command to add a property to a test. The property appears in the reporter's report.

Properties are restricted to 1000 per project. Trying to add a new property may return false if 1000 properties
are already defined in the project.

Parameters
Name Type Description
Property String Property name

Value String Property value

Return Value
• True - Property and value were added.
• False - Addition of the property failed.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

AddTestProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...

©2023 Digital.ai Inc. All rights reserved Page 167


Test Execution

...
seetest.addTestProperty("testlogin" , "true")

Audio Support
Continuous Testing Cloud supports audio interaction with the device.

As of version 23.3, audio features are no longer be supported by the old hardware and are only supported
through the new Bluetooth hardware.

This interaction is done by playing an audio file to the device or recording the device's output through
Bluetooth, and storing it in an audio file.

This feature requires dedicated hardware installed in cloud device and needs to be set up in the cloud by
administrators.

Audio Recording
Description
To record audio, use startAudioRecording. To stop recording, use stopAudioRecording.

Audio recording automatically stops if the test run completes even if stopAudioRecording is not called.

startAudioRecording Parameter

Name Value Description


Audio File String Required. Full path to local Audio file (Appium Grid only)
In Appium Server (Appium Open Source) the unique file name can be provided in this
format:cloud:file_unique_nameFor more information, see Using the File Repository.

stopAudioRecording does not need a parameter.

©2023 Digital.ai Inc. All rights reserved Page 168


Test Execution

Usage
The audio is recorded inline from the device to a file. The recorded files are saved in *.wav or *.flac formats,
according to your preference.

Use sleep if needed to wait until performing the next command. For more information, see sleep.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Audio Recording - Using file repository


// File with unique name my_audio_recording must NOT exist in file repository
driver.executeScript("seetest:client.startAudioRecording", "cloud:my_audio_rec
ording");
// Commands that play audio on device
driver.executeScript("seetest:client.stopAudioRecording");
// Download file with unique name my_audio_recording from file repository using
Rest API
startAudioRecording
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
// Records the Audio file
seetest.startAudioRecording("C:\\AudioFilesToPlay\\OpeningWaze.wav");
seetest.stopAudioRecording();

©2023 Digital.ai Inc. All rights reserved Page 169


Test Execution

StartAudioPlay
Description
This starts playing an audio file to the device. The file is played until it ends. The test proceeds while the file
is played unless WaitForAudioPlayEnd is used. For more information, see WaitForAudioPlayEnd.

Only Wave files are supported.

Parameters
Name Value Description
Audio File String Full path to audio file
In Appium Server (Appium Open Source) file unique name can be provided in the following
format:cloud:file_unique_nameFor more information, see Using File Repository.

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Audio Play - Using file repository


// File with unique name my_music must exist in file repository
driver.executeScript("seetest:client.startAudioPlay", "cloud:my_music");
// ...
driver.executeScript("seetest:client.stopAudioPlay");
StartAudioPlay
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

©2023 Digital.ai Inc. All rights reserved Page 170


Test Execution

...
...
seetest.startAudioPlay("C:\\AudioFilesToPlay\\OpenWaze.wav");

WaitForAudioPlayEnd
Description
Use this command to wait until the audio play is completed. Once the audio play is completed the normal
execution continues.

Audio play begins and the next step won't be performed until one of the following happens:

• The file ends.


• The waiting timeout ends.

Parameters
Name Value Description
Timeout Integer Time in milliseconds until execution ends.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Wait for audio play end - using file repository

©2023 Digital.ai Inc. All rights reserved Page 171


Test Execution

// File with unique name my_music must exist in file repository


driver.executeScript("seetest:client.startAudioPlay", "cloud:my_music");
driver.executeScript("seetest:client.waitForAudioPlayEnd", 10_000);
WaitForAudioPlayEnd
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
// Plays the Audio file
seetest.startAudioPlay("C:\\AudioFilesToPlay\\OpenWaze.wav");
//Waits till the previous audio file play is completed (10000 milliseconds).
seetest.waitForAudioPlayEnd(10000);

CaptureElement
Description

Use this command to capture a screenshot of a part of the device’s screen in a given time and create a new
element in the zone runtime that you can use in later steps of your scripts. This can be highly useful when
the elements on the screen change often or for image comparisons. Once the image is captured, it can be
then clicked using click.

Parameters
Name Value Description
name String Name that will be given to the captured Element

X Integer First point X

Y Integer First point Y

Width Integer Width of the captured area

Height Integer Height of the captured area

Similarity Integer Integer number between 80-100. Enables to define the tolerance of changes when searching for the image.

©2023 Digital.ai Inc. All rights reserved Page 172


Test Execution

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

In the following example we capture the Calendar Element.

©2023 Digital.ai Inc. All rights reserved Page 173


Test Execution

CaptureElement
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//Get the current foreground activity

©2023 Digital.ai Inc. All rights reserved Page 174


Test Execution

seetest.captureElement("Calendar", 275, 255, 264, 299, 100)


seetest.click("runtime", "Calendar", 0, 1)

CaptureNetworkDump
Description
Use this command to start and stop device network traffic capture for a cloud device. The capture starts
when startCaptureNetworkDump is executed. The capture stops at end of the test run or when
stopCaptureNetworkDump is executed.

Parameters
Name Value Description
localFilePath String Full path of the requested file download destination.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

CaptureNetworkDump
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
seetest.startCaptureNetworkDump("C:\\tmp\\device.pcap");

©2023 Digital.ai Inc. All rights reserved Page 175


Test Execution

seetest.stopCaptureNetworkDump();

ElementGetText
Description
Use this command to get text from an element. The text is returned as a string.

Parameters
Name Value Description
Zone String with following possible values Zones which define the way the element will be identified.

• NATIVE

• WEB

• TEXT

Element String which identifies the Element Identification of Element in the device screen.Example: Button, Text Box.

index Integer Integer representing index of the element.

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

©2023 Digital.ai Inc. All rights reserved Page 176


Test Execution

ElementGetText
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
// Command will fetch the "enabled" property of Element "Contacts" if the Andr
oid Contacts App is opened and
// displayed in the Device screen
String text = seetest.elementGetText("NATIVE", "//*[@text='Hint:company']", 0)
;

GenerateReport
Description
Use this command to generates a report of the tests which have been running by the client.

This command also releases the connection between the client and the controller (connection with the
device)

This command requires setReporter to be executed first. For more information see

Parameters
Name Value Description
Release Client boolean If set to true, the command eventually calls releasClient.If set to false, a report is generated, but
the client will not be released.

Note: The older overloaded version of this command (without parameters) is equivalent to
generateReport(true).

Return Value
Returns the path of the report.

©2023 Digital.ai Inc. All rights reserved Page 177


Test Execution

Usage
This should be a part of teardown function of the test.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GenerateReport
{
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
}

public void teardown() {


Boolean reportReleaseClient = true;
if (reportReleaseClient)
// Generates and Releases the client.
seetest.generateReport(true);
} else {
// Generates and does not Release the client.
seetest.generateReport(false);
// Releasing specifically.
driver.quit();
}
}

©2023 Digital.ai Inc. All rights reserved Page 178


Test Execution

GetContextList
Description
Use this command to obtain a list of current contexts including all web views.

Returns
This command returns a string array with the contexts such as NATIVE_APP.

Usage
Command is useful to get the context list of the launched application.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GetContextList
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//Auto Scr
seetest.getContextList();

©2023 Digital.ai Inc. All rights reserved Page 179


Test Execution

GetCurrentActivity
Description
Use this command to retrieve the foreground activity name.

Only Android devices are supported.

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetCurrentActivity
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//Get the current foreground activity


seetest.getCurrentActivity();

GetCurrentApplicationName
Description
Use this command to retrieve the name, bundle, and package name of the application that's currently run in
the active device foreground.

©2023 Digital.ai Inc. All rights reserved Page 180


Test Execution

This command throws an exception for devices which do not support the command.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetCurrentApplication
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//show the list of recent apps


seetest.getCurrentApplicationName();

GetDevicesInformation
Description
Use this command to retrieve all information for a device. This returns an XML string.

XML Attributes

Attribute name Type Description


added string True if device was added to device manager

agent int Agent port number or -1 if not available

audio string Audio support (false\true values)

buildnumber double OS build number

©2023 Digital.ai Inc. All rights reserved Page 181


Test Execution

Attribute name Type Description


category string Device type (phone, tablet, etc.)

host string Device host

location string Agent location

manufacture string Manufacturer name

model string Model identifier

modelname string Model name

name string Device name

os string Device OS

remote string Remote or local device

reservedtoyou string Is device currently reserved to user

screensize string Screen size

serialnumber string Device's Serialnumber

status string Current status of device(unreserved offline, unreserved online, reserved online, etc.)

used string True if device is currently taken

version string Device full operating system version (build number inclusive)

versionnumber double Device full operating system version (build number exclusive)

emulator string True if device is emulator

dhmexteranlhost string Device Host Machine's external host

dhmexternalport string Device Host Machine's external port

dhminternalhost string Device Host Machine's internal host

dhminternalport string Device Host Machine's internal port

dhmlocation string Location of host machine (for example, local)

dhmname string Device Host Machine's name

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetDevicesInformation

©2023 Digital.ai Inc. All rights reserved Page 182


Test Execution

DesiredCapabilities dc = new DesiredCapabilities();


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//Command displays Device information


seetest.getDevicesInformation();

GetInstalledApplications
Description
Use this command to get a list of applications installed on the device.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetInstalledApplications
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
seetest.getInstalledApplications();

©2023 Digital.ai Inc. All rights reserved Page 183


Test Execution

GetLastCommandResultMap
Description
Use this command to retrieve information on the last command executed.

Key Type Description


package String Package name of last installed app

position Element position (upper left corner of the element)

WinTitle Active device the action was made on

status Boolean If the command succeeded

dtime Time of a command execution

width Element width

height Element height

click Click coordinates on click elements

img.height Report image height

img.width Report image width

screen.height Screen height

screen.width Screen width

logLine String Command summary

outFile String Report image path

time Time from command to operation

bcolor.name Background color name (TEXT Zone only)

bcolor Background color value (TEXT Zone only)

color Text color value (TEXT Zone only)

color.name Text color name (TEXT Zone only)

font.size Font size (TEXT Zone only)

step Index of command step in the test

found Boolean Whether the element was found

keys When command fails to execute

errorMessage String Error indication

exception String Exception stack trace (optional)

©2023 Digital.ai Inc. All rights reserved Page 184


Test Execution

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GetLastCommandResultMap
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
seetest .getDeviceProperty("device.sn");
// Gets the map of last command i.e deviceProperty of device.sn
System.out.println(seetest.getLastCommandResultMap());

GetSimCard
Description
Use this command to get the assigned sim card name of the client's device after connecting to a device on
the Continuous Testing Cloud using the SeeTest client.

This command is only applicable to Continuous Testing Cloud, Enterprise edition.

Usage

©2023 Digital.ai Inc. All rights reserved Page 185


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GetSimCard
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
String str0 = seetest.getSimCard();

GetVisualDump
Description
Use this command get the properties of the screen. It returns an XML string with the entire dump (object
spy).

Parameters
Name Value
type String

• Non-instrumented.

• Native (of native instrumented applications).

• Web (of hybrid applications or web sites).

• Web:[custom root for dump]

If the dump type is not supported on the current page, and empty XML is returned.

©2023 Digital.ai Inc. All rights reserved Page 186


Test Execution

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

getVisualDump
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Gets the Non Instrumented Visual Dump


seetest.getVisualDump("Non Instrumented");

PressWhileNotFound
Description
Use this command to press on an element while another element is not found.

Parameters
Name Type Description
Zone String Zones which define the way the element will be identified.Possible values:

• NATIVE

©2023 Digital.ai Inc. All rights reserved Page 187


Test Execution

Name Type Description

• WEB

• TEXT

ElementToClick String Element to click on when ElementToFind is not found

ElementToClickIndex Integer Index of ElementToClick

ElementToFind String Element to look for

Timeout Integer Waiting Timeout in milliseconds

Delay Integer Time to wait between rounds

Usage
Example

In this example, while element "Expense : 4" is not found, Add is clicked.

©2023 Digital.ai Inc. All rights reserved Page 188


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

PressWhileNotFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);

©2023 Digital.ai Inc. All rights reserved Page 189


Test Execution

seetest = new SeeTestClient(driver);


dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Press until we find element with text "Expense :4"


seetest.pressWhileNotFound("NATIVE", "text=Add", 0, "text=Expense :4", 0, 1000
0, 100);

SetProjectBaseDirectory
Description
Use this command to specify the project location.

All commands which call objects from the Object repository need the location of the project (where elements
on the Object repository are stored) to operate on them.

Parameter
Name Value Description
projectbaseDirectory String Project base directory on the local disk.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetProjectBaseDirectory

©2023 Digital.ai Inc. All rights reserved Page 190


Test Execution

DesiredCapabilities dc = new DesiredCapabilities();


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
//Set the Project Base directory.
seetest.setProjectBaseDirectory("<project base directory>");
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

SetReporter
Description
Use this command to set the reporter for a test case. This is generally called at the beginning of each test
case, and its configuration will define the report that will be generated at the end of the test.

Use this command with GenerateReport to generate the report.

Parameters

Report Type String Format of the generated report. Optional formats are "XML" or "pdf".

Report Path String Path where the report and all its content will be stored. The default path in Windows is C:\Users\<User
name>\seetest-reports\ folder.Note: This parameter is ignored currently and the report is notgenerated in
the local path.The generated path of the report is returned by GenerateReport.

Report Name String Name of the report in the Report summary page.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 191


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

SetReporter
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
seetest.setReporter("pdf", "" , "<ReportName>");
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...
seetest.setReporter("pdf", "C://NEWPRJ//SeetestExtenstion//reports" , "Untitle
d");

SetSimCard
Description
This command assigns a SIM card to a device.

This command is only applicable to Continuous Testing Cloud, Enterprise edition.

Usage
After connecting to a device on cloud using the SeeTest client , you can use the SetSimCard command to
assign a SIM card by it's name to this device.

©2023 Digital.ai Inc. All rights reserved Page 192


Test Execution

If an empty String or Null are sent as the SIM card name, any sim card already assigned is unassigned from
the device.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

SetSimCard
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

seetest.setSimCard(simCardName);

Sleep
Description
Use this command to pause the script for a specified time in milliseconds. You can use this to wait for an
application to fully load.

Parameters
Name Value Description
Time Integer Time to sleep in milliseconds.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/

©2023 Digital.ai Inc. All rights reserved Page 193


Test Execution

• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Sleep
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

// Wait for 5000 milliseconds.


seetest.sleep(5000)

Accessibility Inspection
Appium Automation provides an API to interact with the accessibility inspector service directly.

You can use the Accessibility Inspector in these ways:

• SeeTest Extension
• Script Execution

Commands
• AccessibilityStart - Starts the Accessibility Inspector service on the device.
• AccessibilityMoveNext - Moves the Accessibility Inspector to the next element.
• AccessibilityMovePrevious - Moves the Accessibility Inspector to the previous element.
• AccessibilityActivate - Activates the current element highlighted by the Accessibility Inspector. This
enables actions on the element.
• AccessibilityFocusedElement - Gets current element and its information highlighted by the Accessibility
Inspector.
• AccessibilityStop - Stops the Accessibility Inspector service on the device.

Usage
In order to utilize Accessibility Inspector, use AccessibilityStart. Otherwise none of the other accessibility
commands work.

©2023 Digital.ai Inc. All rights reserved Page 194


Test Execution

For Android devices, the target package needs to be specified using accessibilityStart(targetPackage).

Once Accessibility Inspector is activated, Continuous Testing Cloud performs the Home command and the
device returns to springboard.

Use AccessibilityStop to stop the service.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Basic iOS test flow


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new IOSDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);
try{
seetest.accessibilityStart();
seetest.launch("com.experitest.ExperiBank", true, false);
seetest.accessibilityMoveNext();
seetest.accessibilityMoveNext();
seetest.accessibilityActivate();
String str = seetest.accessibilityFocusedElement();
JSONObject jsonObject = new JSONObject(str);
assertEquals(jsonObject.getString("label").equals(<Expected value>));
}finally{
seetest.accessibilityStop();
}
Basic Android test flow
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);
try{
seetest.accessibilityStart("com.experitest.ExperiBank");
seetest.launch("com.experitest.ExperiBank", true, false);
seetest.accessibilityMoveNext();
seetest.accessibilityMoveNext();

©2023 Digital.ai Inc. All rights reserved Page 195


Test Execution

seetest.accessibilityActivate();
String str = seetest.accessibilityFocusedElement();
JSONObject jsonObject = new JSONObject(str);
assertEquals(jsonObject.getString("label").equals(<Expected value>));
}finally{
seetest.accessibilityStop();
}

AccessibilityActivate
Description
Use this command to activate the current element highlighted by the Accessibility Inspector. This command
will perform an activate action on the current element highlighted by the Accessibility Inspector.

Parameters
None.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java Example

Java example
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);

...
...

©2023 Digital.ai Inc. All rights reserved Page 196


Test Execution

seetest.accessibilityActivate();

AccessibilityFocusedElement
Description
Use this command to get the currently highlighted element by Accessibility Inspector.

Parameters
None.

Return Value
JSON representing element properties. Example return value:

{"ElementHash":"WAMAAABy7oICAAAAEQAAAAAAAAA","Value":"0","Class":"UIAccessibilityPickerComponent","Traits":"A

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java Example

Java example
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);

...
...

String str = seetest.accessibilityFocusedElement();

©2023 Digital.ai Inc. All rights reserved Page 197


Test Execution

AccessibilityMovePrevious
Description
This command moves the Accessibility Inspector focus to the previous element.

Parameters
None.

Return value
JSON representing element properties. Example return value:

{"ElementHash":"WAMAAABy7oICAAAAEQAAAAAAAAA","Value":"0","Class":"UIAccessibilityPickerComponent","Traits":"A

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java Example

Java example
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);

...
...

String str = seetest.accessibilityMovePrevious();

©2023 Digital.ai Inc. All rights reserved Page 198


Test Execution

AccessibilityMoveNext
Description
Use this command to move the Accessibility Inspector focus to the next element.

Parameters
None.

Return value
JSON representing element properties. Example return value:

{"ElementHash":"WAMAAABy7oICAAAAEQAAAAAAAAA","Value":"0","Class":"UIAccessibilityPickerComponent","Traits":"A

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java Example

Java example
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);

...
...

String str = seetest.accessibilityMoveNext();

©2023 Digital.ai Inc. All rights reserved Page 199


Test Execution

AccessibilityStop
Description
Use this command to stop the Accessibility Inspector service on the device.

Parameters
None.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java Example

AccessibilityStop
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);

...
...

seetest.accessibilityStop();

©2023 Digital.ai Inc. All rights reserved Page 200


Test Execution

AccessibilityStart
Description
Use this command to run the Accessibility Inspector service on the device.

The service continues until AccessibilityStop is called, or the driver is released.

This command performs a home action. Therefore, you need to relaunch the application afterward.

Parameters
Android - TargetPackage of the application

iOS - None.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java Example

iOS AccessibilityStart
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new IOSDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);

...
...

seetest.accessibilityStart();
Android AccessibilityStart
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
driver = new AndroidDriver(new URL("<server>"), dc);
SeeTestClient seetest = new SeeTestClient(driver);

©2023 Digital.ai Inc. All rights reserved Page 201


Test Execution

...
...

seetest.accessibilityStart("com.experitest.ExperiBank");

Har Recording
Description
Start and stop capturing of HAR data during specific transactions for a cloud device. The capture starts
when startHarRecording is executed. The capture stops when stopHarRecording is executed or the
device is released.

Har recording cannot work in parallel with tunneling.

Parameters
Name Value Description
har file String The full path of the requested file download destination.
In Appium Server (Appium Open Source) file unique name can be provided in the following
format:cloud:file_unique_nameFor more information see Using the File Repository

filter String Optional parameter. Filter for the content type.


If the filter is not given, the value will be according to cloud server configuration.
(See configuration for Cloud Admins on PCAP and HAR Support )
You can learn more about the filter here and here.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

Har file recording - using file repository

©2023 Digital.ai Inc. All rights reserved Page 202


Test Execution

// File with unique name my_har_file must NOT exist in file repository
driver.executeScript("seetest:client.startHarRecording", "cloud:my_har_recordi
ng");
// Commands that perform web requests on device
driver.executeScript("seetest:client.stopHarRecording");
// Download file with unique name my_har_recording from file repository using Re
st API
CaptureNetworkDump
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...
seetest.startHarRecording("C:\\tmp\\device.zip", "~t text/html");

seetest.stopHarRecording();

Report and Utilities


When you execute tests, Continuous Testing generates detailed HTML based reports that you can use in
order to track down issues, gather data, and share with your team.

The power of these reports is not just in their detailed format, but also in that they can be reformatted and
designed to your needs.

With SeeTest Client reporting capabilities you can:

• Add custom step report


• Group steps for readability
• Show images only for unsuccessful steps (to reduce report size)
• Exclude certain steps from the report

Such capabilities allow you to customize the report and tailor it to your specific test needs.

©2023 Digital.ai Inc. All rights reserved Page 203


Test Execution

Report
Description
This command you to specify a custom step with data of your choice. It also allows you to specify whether
the steps has passed or failed.

Parameters
Name Value Description
Message string The message that you want the step to show. Can be any string that you specify.

status boolean true - step has passed, false - step has failed

Usage
Since the report is the sum of all steps (closely linked with the commands that you issued during the test),
you would often want to inject custom steps and messages into the report in order to enrich the report and
provide additional information that is not found in the report, or is printed to the console instead. The
command also lets you decide whether the step has failed or passed.

Be cautious when setting a step as failed! Doing so will mark the whole test as failed, even if the Appium test
itself made it all the way to the end without any errors or exceptions.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Code snippet for Reports


DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...

©2023 Digital.ai Inc. All rights reserved Page 204


Test Execution

...
seetest.report("THIS STEP HAS SUCCEEDED", true);
...
seetest.report("THIS STEP HAS FAILED", false);

Report Grouping Commands


Description
These command allow you to group steps together in order to make the report easier to read and work with.

One command initiates step grouping and the other resets it.

Parameters
Name Value Description
caption string The name of the group you want it to appear in the report. You can specify whatever name you like.

©2023 Digital.ai Inc. All rights reserved Page 205


Test Execution

Name Value Description

• startStepsGroup - to initiate grouping

• stopStepsGroup - to stop grouping

Usage
Let's say you run a test that includes both logging in and performing some actions post login. You can group
the login flow and the subsequent flow in two different groups.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of Report Grouping Command


DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

seetest.startStepsGroup("Login Flow"); //start the login flow group


driver.findElement(By.xpath("//*[@id='usernameTextField']")).sendKeys("company"
);
driver.findElement(By.xpath("//*[@id='passwordTextField']")).sendKeys("company"
);
driver.findElement(By.xpath("//*[@id='loginButton']")).click();
driver.findElement(By.xpath("//*[@text='Login']")).click();
seetest.stopStepsGroup(); //stop the login flow group

seetest.startStepsGroup("Payment Flow"); //start the payment flow group


driver.findElement(By.xpath("//*[@text='Make Payment']")).click();
driver.findElement(By.xpath("//*[@id='phoneTextField']")).sendKeys("123456");
driver.findElement(By.xpath("//*[@id='nameTextField']")).sendKeys("Test");

©2023 Digital.ai Inc. All rights reserved Page 206


Test Execution

driver.findElement(By.xpath("//*[@id='amount']")).click();
driver.findElement(By.xpath("//*[@id='countryTextField']")).sendKeys("US");
driver.findElement(By.xpath("//*[@text='Send Payment']")).click();
driver.findElement(By.xpath("//*[@text='Yes']")).click();
seetest.stopStepsGroup(); //stop the payment flow group

SetShowPassImageInReport
Description
For each step in the test, a screenshot of the device is taken and added to that step in the report. If the test is
long and complicated it has many steps and many images that need to be included in the report. The more
images in the report the longer it takes the test to execute. If you want to download this report it occupies a
lot of space and you might have difficulties sending it to other team members. This command lets remove the
images off of steps that have passed leaving only those images of failed steps.

The main use case of this command is to reduce the time it takes a test to execute, reduce overall size of the
report, and make it more readable.

©2023 Digital.ai Inc. All rights reserved Page 207


Test Execution

Parameters
Name Value Description
showPassImageInReport boolean true - show images only for failed steps

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of SetShowPassImageInReport
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

seetest.setShowPassImageInReport(false);
driver.findElement(By.xpath("//*[@text='Username']")).sendKeys("company");
driver.findElement(By.xpath("//*[@text='Password']")).sendKeys("company");
driver.findElement(By.xpath("//*[@text='loginButton']")).click();
// the next step will fail - the report will show an image only for this step
driver.findElement(By.xpath("//*[@text='logouButton']")).click();

©2023 Digital.ai Inc. All rights reserved Page 208


Test Execution

Example Report

SetShowReport
Description
This command allows you to choose which steps appear in the report and which steps are excluded.

If there are steps whose presence in the report is not crucial, call the command before they occur and then
call the command again to include subsequent steps. For example, if you issue a driver navigate command
or if you issue a command that is not directly related to the test such getting device logs, these commands
are not so valuable for your test.

In the Video Report, skipped steps are skipped from the video itself. That means step images are not
collected when this is set to false.

Parameters
Name Value Description
showReport boolean true (default) - show steps

©2023 Digital.ai Inc. All rights reserved Page 209


Test Execution

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage od ShowReport Command


DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

seetest.setShowReport(false); //exclude the step from the test


driver.get("https://seetest.io");
seetest.setShowReport(true); //include subsequent steps in the test

SetReportStatus
Description
Overrides final report status. Used in order to match a local test result with the report result.

The status will appear as a step in the generated report.

Parameters
Name Value Description
status String status with below valid values. Test status to set

• Failed

• Skipped

• Passed

©2023 Digital.ai Inc. All rights reserved Page 210


Test Execution

Name Value Description

message String error message Error message. Cause of failure.

stacktrace A string representation of exception stacktrace Exception stacktrace set

Usage

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

SetReportStatus
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

//show the list of recent apps


seetest.setReportStatus("skipped", "Failed to assert result");

SetShowReport Command
Description
This command allows you to choose which steps will appear in the report and which steps will be excluded.

Parameters
Name Value Description
showReport boolean true (default) - show steps, false - steps will not be shown

©2023 Digital.ai Inc. All rights reserved Page 211


Test Execution

Usage
If there are steps whose presence in the report is not crucial, you can call the command before they occur
and then call the command again to include subsequent steps. For example, if you issue a driver navigate
command or if you issue a command that is not directly related to the test such getting device logs, these
commands are not so valuable for your test. You can exclude them with the use of setShowReport.

Example

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage od ShowReport Command


driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

.....
.....

seetest.setShowReport(false); //exclude the step from the test


driver.get("https://seetest.io");
seetest.setShowReport(true); //include subsequent steps in the test

SetShowPassImageInReport Command
Description
For each step in the test, an screenshot of the device is taken and added to that step in the report. If the test
is long and complicated it will have many steps and many images that will need to be included in the report.
The more images in the report the longer it will take the test to execute. If you wanted to download this report
it would occupy a lot of space and you might have difficulties sending it to other team members. This
command lets remove the images off of steps that have passed leaving only those images of failed steps.

©2023 Digital.ai Inc. All rights reserved Page 212


Test Execution

Parameters
Name Value Description
showPassImageInReport boolean true - show images only for failed steps, false - show images for all steps

Usage
The main usage of this command is to, reduce the time it takes a test to execute, reduce overall size of the
report and make it more readable.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Usage of SetShowPassImageInReport
driver = new IOSDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

....
....

seetest.setShowPassImageInReport(false);
driver.findElement(By.xpath("//*[@text='Username']")).sendKeys("company");
driver.findElement(By.xpath("//*[@text='Password']")).sendKeys("company");
driver.findElement(By.xpath("//*[@text='loginButton']")).click();
// the next step will fail - the report will show an image only for this step
driver.findElement(By.xpath("//*[@text='logouButton']")).click();

©2023 Digital.ai Inc. All rights reserved Page 213


Test Execution

Example Report

Report Command
Description
This command you to specify a custom step with data of your choice. It also allows you to specify whether
the steps has passed or failed.

Parameters
Name Value Description
Message string The message that you want the step to show. Can be any string that you specify.

status boolean true - step has passed, false - step has failed

Usage
Since the report is the sum of all steps (closely linked with the commands that you issued during the test),
you would often want to inject custom steps and messages into the report in order to enrich the report and
provide additional information that is not found in the report, or is printed to the console instead. The
command also lets you decide whether the step has failed or passed.

©2023 Digital.ai Inc. All rights reserved Page 214


Test Execution

Be cautious when setting a step as failed! Doing so will mark the whole test as failed, even if the Appium test
itself made it all the way to the end without any errors or exceptions.

Example
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Code snippet for Reports


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

....
....

seetest.report("THIS STEP HAS SUCCEEDED", true);


...
seetest.report("THIS STEP HAS FAILED", false);

©2023 Digital.ai Inc. All rights reserved Page 215


Test Execution

Controlling Element Identification Rules


When running a test step on a Native element, a set of rules are enforced in the found element's properties
before the actual command operation is performed.

Busy Element Rule


A Busy Element is an element that is still being drawn by the Operation System on the device, or is busy
showing some animation.
In case the element is found in such state, SeeTest waits for it to get idle for a short time, and then gives up
waiting and performs the step on the busy element.

Default behavior can be configured by setting app.properties file as per properties described below.

Property Value Description


element.idle.timeout timeout in milliseconds Timeout wait for busy element (1500 by default)

assert.element.idle If element is not found till timeout - should the test step fail ("true") instead of
continuing to perform it on the busy element ("false" - the default value).

©2023 Digital.ai Inc. All rights reserved Page 216


Test Execution

Property Value Description

true or false

Elements with zero size


Elements with zero size (i.e. width or height) are often deflated elements that the application intend to inflate
when they are required.

This default behavior might be configured by setting the following properties:

Property Value Description


assert.element.dimension true or false should elements with 0 width or height fail the test ("true" by default).

Monitoring Commands
SeeTest Client provides monitoring commands to monitor device parameters like battery, cpu etc. Such
commands allow you check how device behaves in terms of crucial parameters like power and battery
usage.

The monitors are collected during your test execution.

Notes:

1. The current supported monitors are:


• Memory: MB
• CPU: percentage
• Battery: percentage (only when a an instrumented application is running in the foreground)
2. Every launch command will automatically add the launched application to the list of monitored
applications.
3. This feature is supported on Android and iOS devices

Android System Resources Monitoring


Continuous Testing provides an API for monitoring device CPU, Memory, and Battery Usage.

• Our System Resources data is based on Google's Android Debug Bridge (adb) tool.
• For each type of resource, Continuous Testing can provide values both for the entire system and for a
specific process.
• Continuous Testing provides both real-time monitoring graphs and API for automation tests that allow
capturing the data during the test.

©2023 Digital.ai Inc. All rights reserved Page 217


Test Execution

• All System Resources Monitoring are available for both non-instrumented and instrumented
applications.

The following is a short explanation for each type of System Resources.

Memory
Continous Testing provides CPU metrics data based on 'adb shell dumpsys meminfo'.

The result is the total Proportional Set Size (PSS) value

CPU
Continuous Testing provides CPU metrics data based on 'adb shell dumpsys cpuinfo'

The result is the value divided by the number device CPU cores, the returned value is a percentage
between 0 to 100.

Battery Usage
Continous Testing provides Battery Usage metrics data based on 'adb dumpsys batterystats',

We provide data on the following parameters:

• cpu_power_use - Energy consumed by CPU's operations related to the application


• wifi_power_use - Energy consumed by the WiFi component
• gpu_power_use - Energy consumed by the GPU (screen consumption).
• rest_power_use - Energy consumed by all other components: sensors, bluetooth, cellular, etc...
• total_usage the total of: cpu_power_use, wifi_power_use , gpu_power_use, and rest_power_use
• screen_power_use - Power consumed by the screen while the application was running in the
foreground

The data is presented in unit mAh by default, but it can be also presented in percents (relatively to the full
battery capacity)

• In some cases, adb does not provide battery usage information for one or more component (e.g WiFi)
this could happens due to a specific Mobile Vendor or to the OS version. In that case, we return the
value - N/A.
• All battery usage information that we collecting from adb tool are approximate power usage, there are
some cases that older values are higher the new value. In that cases the differences are minor.

©2023 Digital.ai Inc. All rights reserved Page 218


Test Execution

GetCounter
Description
Returns the monitor (CPU/Memory/Battery) value on the given time

Parameters
Name Value Description
CounterName String

• CPU

• Memory

• Battery(only when a Instrumented application is running in the foreground)

PackageName String Optional parameter. When given, monitor value will be returned for the application whose package
name is given, otherwise the monitor value will be returned for the system level.

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

GetCounter
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);

©2023 Digital.ai Inc. All rights reserved Page 219


Test Execution

dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// Start Monitor and erases and previous monitor data and store current monito
r in a given file.
seetest.startMonitor("com.experitest.ExperiBank");
seetest.setMonitorPollingInterval(1000);
seetest.sleep(5000);
// get Count for cpu
client.GetCounter("cpu");

Values will be retuned in the report

GetMonitorsData
Description
Return the content of the monitor values as a string in CSV format.

©2023 Digital.ai Inc. All rights reserved Page 220


Test Execution

Parameters
Name Value
Full Path The absolute path for the file. The path must include the file name with *.csv.

Usage
Command retrieves all Counter values which were collected during the test run so far.

Command needs to be used after monitoring has been started using startMonitor command

Example

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

GetMonitorsData
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// Start Monitor and erases and previous monitor data and store current monito
r in a given file.
seetest.startMonitor("com.experitest.ExperiBank");
seetest.setMonitorPollingInterval(1000);
seetest.sleep(5000);
// Gets then monitior data in local file
seetest.getMonitorsData("C:\\experitest\\monitor.csv");

iOS System Resources Monitoring


SeeTest provides API for monitoring device CPU, Memory and Battery Usage, this document applies to
SeeTest version 12.0 and above

©2023 Digital.ai Inc. All rights reserved Page 221


Test Execution

• Our System Resources data is based on Apple tools: Xcode and Activity Monitor Instrument
• Currently, Apple does not provide any API for monitoring these kinds of resources, only graphical user
interface tools are available
• For each type of resource, SeeTest can provide values both for the entire system and for a
specific process.
• SeeTest provides both real-time monitoring graphs and API for automation tests that allow capturing
the data during the test
• Since SeeTest 12.0 SeeTest also supports monitoring for system apps such as Safari, Email and more
• All System Resources Monitoring are available for both non-instrumented and instrumented
applications

The following is a short explanation for each type of System Resources:

Memory
SeeTest memory metrics data correlates to the Activity Monitor Instrument - 'Memory' column introduced in
Xcode 10

This data is a value calculated by Apple and gives a relative indication of the monitored process memory
usage.

©2023 Digital.ai Inc. All rights reserved Page 222


Test Execution

Working with older versions of Seetest

Until version 11.9, SeeTest memory metrics data have been derived from a different Activity Monitor
Instrument column - 'Real Mem' column

This column does not exist in the new Xcode versions and has a value different than the new 'Memory'
column used in Xcode 10.

Please note that your performance test results might be affected by this change.

You may revert back to the old behavior by using the property 'ios.11.use.old.monitoring.service' but this will
remove the support for non-development applications

The following screenshot shows the different values between Xcode 10 to Xcode 9 for the same processes:

CPU
SeeTest CPU metrics data correlates to the Activity Monitor Instrument - '% CPU' column

Total CPU is calculated as the sum of all processes CPU usage, the result might be higher than 100%,
depending on the number of CPU Cores for the specific device.

Working with older versions of Seetest

Until version 11.9, SeeTest normalized the CPU results to be similar to Android Results (values are between
0 to 100 percent). Since SeeTest 12.0 we do not normalize the CPU results in order to comply with Apple's
tools

©2023 Digital.ai Inc. All rights reserved Page 223


Test Execution

You may revert back to the old behavior by using the property 'ios.11.use.old.monitoring.service' but this will
remove the support for non-development applications

Battery Usage
SeeTest Battery Usage metrics data correlates to the Xcode Energy Gauge.

We provide data on the following parameters: CPU, GPU, Location, Network, and Overhead.

SetMonitorPollingInterval
Description
This command sets the intervals between each polling of the monitor counter values

©2023 Digital.ai Inc. All rights reserved Page 224


Test Execution

Parameters
Name Value
Time Time intervals in milliseconds (ms).

Usage
Default polling intervals is 1000ms. User can use this command to change the intervals.

Note: The minimum monitoring polling interval is 500ms for Android devices and 1000-2000ms for iOS
devices (depends on the device).

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetMonitorPollingInterval
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// Start Monitor and erases and previous monitor data and store current monito
r in a given file.
seetest.startMonitor("com.experitest.ExperiBank");
// Polling interval
seetest.setMonitorPollingInterval(1000);
seetest.sleep(5000);
seetest.getMonitorsData("C:\\experitest\\monitor.csv");

©2023 Digital.ai Inc. All rights reserved Page 225


Test Execution

StartMonitor
Description
Erase monitoring information collected so far and start monitoring a given application on a regular basis.

Parameters
Name Value
PackageName

• Name of application to be monitored or an empty string if you just want to erase monitoring information.

Usage
This will erase the monitoring information collected so far and will start monitoring the given application
name.

If no application name will be given, only the monitoring information will be erased.

Note:

• Supported version: Android 6.0+ and all iOS versions.


• Monitoring must be started after the application was launched.
• If an application is closed, energy monitoring must be started again by executing startMonitor
command.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

StartMonitor

©2023 Digital.ai Inc. All rights reserved Page 226


Test Execution

DesiredCapabilities dc = new DesiredCapabilities();


driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// Start Monitor and erases and previous monitor data and store current monito
r in a given file.
seetest.startMonitor("com.experitest.ExperiBank");
seetest.setMonitorPollingInterval(1000);
seetest.sleep(5000);
seetest.getMonitorsData("C:\\experitest\\monitor.csv");

Note : The collected data can be retrieved and exported in CSV format with command getMonitorsData.

StartPerformanceTransaction
Description
Start Performance Transaction collects data on Duration, CPU, Battery, Memory, and Network traffic of the
device.

The command must be used with the following EndPerformanceTransaction

Network traffic (HAR) will not be recorded in the transaction if tunneling is turned on

Parameters
Name Value
NVProfile Name of the Virtualization profile (Network Virtualization). Note: If the empty value is passed, then the '3G-average'
profile is selected and if the 'NONE' value is passed, no profile will be selected.

This will start a performance transaction. An exception is thrown if trying to start a transaction while an
existing transaction is already run.

You can view the transaction, once ended, in SeeTest Reporter under the "Transactions" tab.

Note:

©2023 Digital.ai Inc. All rights reserved Page 227


Test Execution

• Supported version Android 5.0+ and all iOS versions.


• A transaction maximum time is 5 min. After 5 minutes transaction will be canceled
• The transaction will be canceled if you release client\quit driver. No data will be saved
• Make sure the NV server is configured correctly and connected to Host Machine. The device should be
connected to the NV network. Advise Network Visualization documentations

Replace <ACCESS_KEY> with the appropriate access key.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

StartPerformanceTransaction
String accessKey = "<ACCESS_KEY>"
String url = "<server>";
DesiredCapabilities dc = new DesiredCapabilities();
//...your capabilities
dc.setCapability("testName", "Transaction example Demo");
dc.setCapability("accessKey", accessKey);
dc.setCapability("deviceQuery", "@os='android' and @category='TABLET'");
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank/.L
oginActivity");
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.experitest.Expe
riBank");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".LoginActivity");

driver = new AndroidDriver(new URL(url), dc);


seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// Starts performance transaction


seetest.startPerformanceTransaction("4G-average");

//do some work. For example - Login transaction:

©2023 Digital.ai Inc. All rights reserved Page 228


Test Execution

driver.findElement(By.xpath("//*[@id='loginButton']")).click();

// end performance transaction, returns a performance data in JSON format.


String loginPerfData = seetest.endPerformanceTransaction("Login");

EndPerformanceTransaction
Description

End Performance Transaction must be performed after StartPerformanceTransaction. It takes the collected
data on Duration CPU, Battery and Memory of the current device, and upload it to SeeTest Reporter.

The collected data can be viewed under the transaction tab in SeeTest Reporter.

Parameters
Name Value
Name Name of the transaction to save

Usage
This will end a performance transaction. An exception is thrown if trying to end a transaction without starting.

You can view the transaction, once ended, in SeeTest Reporter under "Transactions" tab.

Note:

• Supported version Android 5.0+ and all iOS versions.


• A transaction maximum time is 5 min. After 5 minutes transaction will be canceled
• The transaction will be canceled if you release client/quit driver. No data will be saved

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 229


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

EndPerformanceTransaction
String accessKey = "<accessKey>"
String url = "<server>";
DesiredCapabilities dc = new DesiredCapabilities();
//...your capabilities
dc.setCapability("testName", "Transaction example Demo");
dc.setCapability("accessKey", accessKey);
dc.setCapability("deviceQuery", "@os='android' and @category='TABLET'");
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank/.L
oginActivity");
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.experitest.Expe
riBank");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".LoginActivity");

driver = new AndroidDriver(new URL(url), dc);


seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// Starts performance transaction


seetest.startPerformanceTransaction("4G-average");

//do some work. For example - Login transaction:


driver.findElement(By.xpath("//*[@id='loginButton']")).click();

// end performance transaction, returns a performance data in JSON format.


String loginPerfData = seetest.endPerformanceTransaction("Login");

Result Example

{
"transactionName": "transaction test",
"transactionId": 10,
"appName": "com.experitest.ExperiBank",
"appVersion": "1.2890",
"deviceInfo": {
"uid": "RGF8MM81FK8SV",
"model": "SM-G973F",

©2023 Digital.ai Inc. All rights reserved Page 230


Test Execution

"name": "samsung SM-G973F",


"deviceType": "ANDROID",
"category": "PHONE",
"manufacturer": "samsung",
"osVersion": "9.0",
"emulator": false,
"mssbSupported": false
},
"deviceScreenDimension": {
"width": 1080,
"height": 2042
},
"metrics": {
"startTimestamp": 1683028885746,
"endTimestamp": 1683028901275,
"cpuAvg": 0.440625,
"cpuMax": 0.95,
"memoryAvg": 40.923583984375,
"memoryMax": 71.8056640625,
"batteryAvg": 0.046218749999999996,
"batteryMax": 0.174,
"nvProfileName": "",
"networkDownload": 0,
"networkUpload": 0
},
"link": "https://mycloud.experitest.com/test-trans/index.html?trans_id=1234"
}

StartPerformanceTransactionForApplication
Description
Start Performance Transaction collects data on Duration, CPU, Battery, Memory of the specified application
on the device. The Network traffic will be measured for the device, and not per application.

The command must be used with the following EndPerformanceTransaction

©2023 Digital.ai Inc. All rights reserved Page 231


Test Execution

Parameters
Name Value
applicationName Application to be monitored (bundle id for iOS and package name for Android)

NVProfile Name of the Virtualization profile (Network Virtualization). Note: If the empty value is passed, then the '3G-
average' profile is selected and if 'NONE' value is passed, no profile will be selected.

This will start a performance transaction. An exception is thrown if trying to start a transaction while an
existing transaction is already run.

You can view the transaction, once ended, in SeeTest Reporter under the "Transactions" tab.

Note:

• Supported version Android 5.0+ and all iOS versions.


• A transaction maximum time is 5 min. After 5 minutes transaction will be canceled.
• The transaction will be canceled if you release the client/quit driver. No data will be saved.
• Make sure the NV server is configured correctly and connected to Host Machine. The device should be
connected to the NV network. Advise Network Visualization documentations

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

StartPerformanceTransaction
String accessKey = "<ACCESS_KEY>"
String url = "<server>";
DesiredCapabilities dc = new DesiredCapabilities();
//...your capabilities
dc.setCapability("testName", "Transaction example Demo");
dc.setCapability("accessKey", accessKey);
dc.setCapability("deviceQuery", "@os='android' and @category='TABLET'");
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank/.L
oginActivity");
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.experitest.Expe
riBank");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".LoginActivity");

©2023 Digital.ai Inc. All rights reserved Page 232


Test Execution

driver = new AndroidDriver(new URL(url), dc);


seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");

...
...

// Starts performance transaction


seetest.startPerformanceTransactionForApplication("com.experitest.ExperiBank",
"4G-average");

//do some work. For example - Login transaction:


driver.findElement(By.xpath("//*[@id='loginButton']")).click();

// end performance transaction, returns a performance data in JSON format.


String loginPerfData = seetest.endPerformanceTransaction("Login");

Configuration Commands
Use the configuration commands to define how other commands behave.

SetDefaultClickDownTime
Description
Use this command to set the default click down time (default is 100 milliseconds). A typical use case is to
simulate a longer than usual click.

Parameters
Name Type Description
Downtime Integer Time in milliseconds

Usage
Replace <server> with the appropriate URL.

©2023 Digital.ai Inc. All rights reserved Page 233


Test Execution

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetDefaultClickDownTime
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Clicks for 5000 milliseconds


seetest.setDefaultClickDownTime(5000);

SetDefaultTimeOut
Description
Use this command to set the default timeout for other commands.

Parameters
Name Type Description
Timeout Integer Timeout in milliseconds

Typical Use Case


This command can be used to postpone a test so it does not fail because of timeout issues. For example,
you can use this to make sure there is no failure until the set timeout expires if a Click command is not
successful.

©2023 Digital.ai Inc. All rights reserved Page 234


Test Execution

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetDefautTimeOut
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Default Time out set 10 seconds, no error till 10 seconds even if click comm
and is not successful till 10 seconds.
seetest.setDefaultTimeout(10000);
seetest.click("NATIVE", "//*[@text=EriBank]", 0, 2);

SetDragStartDelay
Description
Use this command to set the drag start delay.

Parameters
Name Type Description
Delay Integer Time in Milliseconds

©2023 Digital.ai Inc. All rights reserved Page 235


Test Execution

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

setDragStartDelay
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Command to delay in drag.


seetest.setDragStartDelay(5000);

SetInKeyDelay
Description
Use this command to set the time between key down and key up.

Parameters
Name Type Description
Delay Integer Time in millisecond's

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 236


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetInKeyDelay
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

seetest.setInKeyDelay(10000)

SetKeyToKeyDelay
Description
Use this command to set the time between two key presses.

Parameters
Name Type Description
Key delay Integer Time in Milliseconds

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 237


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetKeyToKeyDelay
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

seetest.setKeyToKeyDelay(1000);

SetSpeed
Description
Use this command to set the speed of the test.

Parameters
Name Type Possible Values Description
Speed String Test speed

• Slow

• Normal

• Fast

©2023 Digital.ai Inc. All rights reserved Page 238


Test Execution

Usage
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

Speed
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

// Runs the test with Slow speed


seetest.setSpeed("Slow")

SetWebAutoScroll
Description
Use this command to determine behavior of scrolling to invisible elements on a webView.

webAutoScroll is not supported for elements with at least one ancestor containing the transform property.
This is because that property can change the coordinates of elements on the web page. To
enable webAutoScroll, remove the transform property from the elements and its parents.

©2023 Digital.ai Inc. All rights reserved Page 239


Test Execution

Parameters
Name Type Description
AutoScroll Boolean

• True - Scroll the webView when searching for invisible objects.

• False - Scroll the webView when searching for invisible objects.

Usage
When setting SetWebAutoScroll to False, the result will be When setting SetWebAutoScroll to True, the result will be True,
False, because the Golf tab is not visible on the screen. because the test automatically scrolls down the web page until it
finds the Golf tab.

©2023 Digital.ai Inc. All rights reserved Page 240


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Example

SetWebAutoScroll
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");

...
...

//Auto Scroll set to true


seetest.setWebAutoScroll(true);

Capabilties in Appium Based Tests

This section describes the available capabilities and examples for their usage.

Continuous Testing expands Appium's capabilities and allows better control over the device and test.

You can start developing a new framework, or migrate your existing Appium tests and execute them with
higher performance and stability rates.

Device Queries
Introduction
In general, Capabilities are series of key and value pairs that can customize or configure a device or browser
session for testing to Selenium or Appium WebDriver.

Continuous Testing Cloud extends these capabilities with the Device Query capability. It is a special type of
capability which describes one or more capabilities in a single query like input.

The code snippet below is used to set Device Query using Selenium\Appium Java client bindings.

©2023 Digital.ai Inc. All rights reserved Page 241


Test Execution

Device Query settings


/**
* Creates an Android Driver with Desired Capabilities.
*
*/
protected void createDriverWithCapabilities() {
LOGGER.info("Setting up Desired Capabilities");
String accessKey = System.getenv(ENV_VAR_ACCESS_KEY);

dc.setCapability(SeeTestCapabilityType.ACCESS_KEY, accessKey);
dc.setCapability(MobileCapabilityType.PLATFORM_NAME,"iOS");
String deviceQuery = String.format("@os=android and @dhmlocation='us-1'",
"android");
dc.setCapability(SeeTestCapabilityType.DEVICE_QUERY, deviceQuery);
AppiumDriver driver = new AndroidDriver(SeeTestProperties.SEETEST_IO_APPIU
M_URL, dc) :
}

A few important observations can be made from the code sample.

• The Device Query is set using the key SeeTestCapabilityType.DEVICE_QUERY.


• Multiple capabilities can be set in one single query input, for example, device
query="@os=android and @location='US', as opposed to the Appium capability which needs
to be set one by one.
• Property os overrides MobileCapabilityType.PLATFORM_NAME as they have the same
meaning.

Supported Properties

Property Name Property Value Example or Possible Values


os Operating system.

• iOS

• android

serialnumber Serial Number of the device. Unique identifier of the device in the SeeTest cloud.

version device's operating system version (for example Any Device versionExample: 4.1.2
4.1.2).

©2023 Digital.ai Inc. All rights reserved Page 242


Test Execution

Property Name Property Value Example or Possible Values


versionnumber device's operating system version number (for Any Device version numberExample: 4.1
example 4.1).

category device category. Currently supported in android


devices.

• WATCH

• PHONE

• TABLET

modelName Device marketing name Example: Galaxy S7 Edge

model Device model Example: SM-G935F

dhmlocation Location of the host machine as set in the Example: us-1


SeeTestCloud configuration.

manufacture Manufacturer of the device. Example: apple

name Kind of the device Example: iPhone 7

tag Device tag (that was added by Cloud / Project Example: new_device
administrator)

region Region of the device's DHM Example: Argentina

Syntax and Examples


Device Query is written in XPATH syntax, that is, @<propertyname>='<propertyvalue>' [ and
@<propertyname>='<propertyvalue>' .....].

Device tags are added to query without @ character: tag='new_device'.

Example Description
"contains(@dhmlocation,'us') and @manufacture='Samsung' and
@os='android' and @version='4.2.2'

• US location

• Samsung Manufacturer

• Android OS

• version 4.2.2

©2023 Digital.ai Inc. All rights reserved Page 243


Test Execution

Example Description

"@model='iphone' and @os='ios' and contains(@name, 'iPhone')"

• iPhone model

• iOS

• Name contains 'iPhone'

"@model='iphone' and @os='ios' and starts-with(@name, 'iPhone')"

• iPhone model

• iOS

• Name starts with 'iPhone'

@os='ios' and tag='new_device' and tag='released_2019'

• iOS

• device has these tags: 'new_device' and 'released_2019'

Device Setup
Use Device Setup to select the desired device(s).

Device Setup Properties

Name Description Example (Java)


udid Unique device identifier dc.setCapability(MobileCapabilityType.UDID, "ABCDE12345");

©2023 Digital.ai Inc. All rights reserved Page 244


Test Execution

Name Description Example (Java)


platformVersion Mobile device version number dc.setCapability(MobileCapabilityType.PLATFORM_VERSION,
"5.0")

deviceManufacture Device manufacturer dc.setCapability("deviceManufacturer", "samsung");

deviceModel Device model dc.setCapability("deviceModel", "iphone 6");

deviceCategory Device category dc.setCapability("deviceCategory", "PHONE");

deviceWithAudio Device has audio injection \ dc.setCapability("deviceWithAudio", true);


extraction support (default: false)

deviceQuery Query device for list of available dc.setCapability("deviceQuery", "@os='android' and


properties. This capability @manufacture='samsung");
overrides any other capabilities
set by the user and it determines
the device to test.
(See WaitForDevice).

orientation Start the test when the device in a dc.setCapability(MobileCapabilityType.ORIENTATION,


certain orientation.Values: "landscape");
"landscape" / "portrait"

releaseDevice Give the capability to not release dc.setCapability("releaseDevice", false);


a device after performing
driver.quit().

• true (default) - Releases the


device reservation at the end of
the session.

• false - Cloud does not release


the device reservation at the
end of the session.

The ability to use the command


depends on the permissions on
the project for the connecting
user.If the user doesn't have the
permission not to release the
device on driver.quit(), the setting
is ignored and default value is
applied.This flag is ignored and
devices are not released in
following cases:

• Device was previously reserved


(future reservation)

• Device was opened in web


studio

• Device was opened in remote


debug mode during the test

©2023 Digital.ai Inc. All rights reserved Page 245


Test Execution

Name Description Example (Java)

When running multiple tests on a


shared device, it is recommended
to use this capability as false, to
keep the device.

deviceCleanup Performs a device cleanup after dc.setCapability("deviceCleanup", "false")


the session ends.The option will
only be operational if the project
settings allows it (in project
settings - Settings --> Project -->
Manage --> Device
Policies, Enable release without
cleanup is checked).If Enable
release without cleanup is
unchecked, the settings
deviceCleanup are ignored and a
cleanup is performed
unconditionally.Values: true/
falseDefault value: trueProject
cleanup is ignored with a shared
device. After releasing the device
it goes through a backup and
restore process.

onlyAvailable Use only available devices. dc.setCapability("onlyAvailable", true);

configurationProfile Installs an iOS configuration dc.setCapability("configurationProfile", "ABCD-123-EDF");


profile on the device.This is
supported only for iOS devices.

removeConfigurationProfile On driver.quit(), removes the iOS dc.setCapability("RemoveConfigurationProfile", true);


config profile from the device that
was installed using
configurationProfile capability.
Values: true/falseDefault value:
falseThis is supported only for
iOS devices.

setPasscode Sets the passcode 123456 for an dc.setCapability("setPasscode", true);


iOS device at session creation
time.

Other than UDID, all of the capabilities are just extensions of the deviceQuery capability (for example Audio \
Manufacture). The query constructed is based on the other capabilities provided.

Code Examples
Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/

©2023 Digital.ai Inc. All rights reserved Page 246


Test Execution

• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Setup Device by UDID

These examples demonstrate how to set a capability which will initialize the driver to connect to a device
using the device UDID.

Java
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.UDID, "1162000958")
driver = new AndroidDriver<>(new URL("<server>"), dc);
Python
dc = {}
self.dc['udid'] = '1162000958'
self.driver = webdriver.Remote('<server>', self.dc)
C Sharp
DesiredCapabilities dc = new DesiredCapabilities();
dc.SetCapability(MobileCapabilityType.Udid, "1162000958")
driver = new AndroidDriver<>(new URL("<server>"), dc);
Ruby
desired_caps = {
caps: {
udid: '1162000958',
},
appium_lib: {
server_url: '<server>',
}
}
@driver = Appium::Driver.new(desired_caps, true).start_driver

Setup Device by Device Query

These examples demonstrate how to set a capability which initializes the driver to connect to a device using
a dynamic query, based on the device characteristics (model and OS).

Java
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("deviceQuery", "@os='ios' and contains(@model, 'iphone')");
driver = new IOSDriver<>(new URL("<server>"), dc);
Python

©2023 Digital.ai Inc. All rights reserved Page 247


Test Execution

dc = {}
self.dc['deviceQuery'] = "@os='ios' and contains(@model, 'iphone')"
self.driver = webdriver.Remote('<server>', self.dc)
C Sharp
DesiredCapabilities dc = new DesiredCapabilities();
dc.SetCapability("deviceQuery", "@os='ios' and contains(@model, 'iphone')");
driver = new IOSDriver<>(new URL("<server>"), dc);
Ruby
desired_caps = {
caps: {
deviceQuery: "@os='ios' and contains(@model, 'iphone')",
},
appium_lib: {
server_url: '<server>',
}
}
@driver = Appium::Driver.new(desired_caps, true).start_driver

Browser Setup

In order to start testing on a browser you need to specify the type of browser you want to test on.

Name Possible Values


browserName For iOS: Safari
For Android: Browser / Chromium / Chrome

Following are the code samples in difference languages to use the capability.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java
DesiredCapabilities dc = new DesiredCapabilities();
dc.setBrowserName(MobileBrowserType.CHROME);
driver = new AndroidDriver('<server>', dc);
driver.get("seetest.io");

©2023 Digital.ai Inc. All rights reserved Page 248


Test Execution

Additional way to set the browser (Java)

dc.setCapability(MobileCapabilityType.BROWSER_NAME, MobileBrowserType.CHROME);
Python
dc = {}
self.dc['browserName'] = 'safari'
self.driver = webdriver.Remote('<server>', self.dc)
self.driver.get('seetest.io')
C Sharp
DesiredCapabilities dc = new DesiredCapabilities();
dc.SetCapability(MobileCapabilityType.BrowserName, MobileBrowserType.Chrome);
driver = new AndroidDriver('<server>', dc);
driver.Navigate().GoToUrl("seetest.io");
Ruby
desired_caps = {
caps: {
browserName: 'safari',
},
appium_lib: {
server_url: '<server>',
}
}
@driver = Appium::Driver.new(desired_caps, true).start_driver

@driver.get('seetest.io')

Application Setup
Continuous Testing cloud platform provides additional application capabilities for your Appium based
tests.

These capabilities give you better control over the state of the application before a tests is run.

Name Description
app

The path to the application files, which would be installed and launched

• Optional - To install cloud apps with unique name use this syntax:

//app capability:
cloud:uniqueName=<value>

// To support iOS app you should also add the capability 'bundleId'

©2023 Digital.ai Inc. All rights reserved Page 249


Test Execution

Name Description
// To support Android app you should add the'appPackage' and the 'appActivi
ty' capabilities

(Upload app to cloud with a unique name)

instrumentApp Instrument the application.Default: false

noReset

1. Launch the application without killing it before (when the capabilities bundleID (iOS) or
packageName+activityName (Android) are provided

2. Not kill/close the application on driver quit (when the capabilities bundleID (iOS) or
packageName+activityName (Android) are provided

3. Stay on the application and not go to Home screen on driver.quit

4. Not clear application data (android only)

5. The application is not reinstalled no matter the versioning (it overrides the parameter
installOnlyForUpdate)

fullReset Uninstall the application completely before installing it again.Relevant only when the app capability
specified.Upon test completion, the application will be uninstalled (driver.quit()).When appears with
noReset = true the application will stay on the device at the end of the test (when app capability is
provided)When appears with noReset = false the application will not be uninstalled at the beginning, only
at the end of the test (when app capability is not provided)Default: false

applicationClearData Clears the application data. See application clear data for more informationWhen one of noReset or
fullReset or both is set true, then applicationClearData will have no effect.Default: false

autoWebview Moves application into web view context.

appBuildVersion Used only when installing a cloud application. Specifies the application build version for installation.
(formerly appVersion)

appReleaseVersion Used only when installing a cloud application. Specifies the application release version for installation.

installOnlyForUpdate
(formerly
install.only.for.update) Install the application only if the desired version is different from the application version on the device (or if
the app does not exist on the device). Otherwise, keep the application on the device.
That will greatly improve session creation time for testings on the same application version
The following desired capability must also be specified if using this feature:

• At least one of 2 new capabilities have to be provided "appReleaseVersion" or "appBuildVersion" (formally


appVersion), then

©2023 Digital.ai Inc. All rights reserved Page 250


Test Execution

Name Description
• If only "appReleaseVersion" is provided
- application will not be installed if there is an application with same release version is installed on
device

• If only "appBuildVersion" (formally appVersion) is provided


- application will not be installed if there is an application with same build version is installed on
device

• If both "appReleaseVersion" and "appBuildVersion" (formally appVersion) are provided


- application will not be installed if there is an application with same release version AND with
same build version is installed on device.

• When no "appReleaseVersion" nor "appBuildVersion" (formally appVersion) is provided for


application
- application should not be installed and an exception is thrown.

• 'bundleId' for iOS only

• 'appPackage' and 'appActivity' for Android only

The installation of the package on the device will happen in the following cases:

1. if the application is already installed on the device and the version different than the one specified
by appBuildVersion and/or appReleaseVersion. the desired version will be installed

2. noReset is true - overrides the version check and follow the behavior of noReset

3. fullReset is true - overrides the version check and follow the behavior of fullReset

iOS Example

dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank"
);
dc.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.experitest.ExperiBa
nk");
dc.setCapability("appBuildVersion", "2.23");
dc.setCapability("installOnlyForUpdate", true);

Android Example

©2023 Digital.ai Inc. All rights reserved Page 251


Test Execution

Name Description

dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank/
.LoginActivity");
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.experitest.Ex
periBank");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".LoginActivity")
;
dc.setCapability("appBuildVersion", "4352");
dc.setCapability("appReleaseVersion", "1.01");
dc.setCapability("installOnlyForUpdate", true);

dontGoHomeOnQuit The device will remain in last left state even after ending the testDefault: false

iOS Only
Name Description
bundleId iOS application identifier

Java
// iOS - launch pre-installed application and switch context automatically int
o webview
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank");
dc.setCapability(MobileCapabilityType.AUTO_WEBVIEW, true);
driver = new IOSDriver<>('<server>', dc);
Python
dc = {}

....
....

self.dc['platformName'] = 'ios'
self.dc['app'] = 'cloud:com.experitest.ExperiBank'
self.dc['autoWebview'] = True

self.driver = webdriver.Remote('<server>', self.dc)

C Sharp
// iOS - launch pre-installed application and switch context automatically int
o webview
DesiredCapabilities dc = new DesiredCapabilities();

©2023 Digital.ai Inc. All rights reserved Page 252


Test Execution

dc.setCapability(MobileCapabilityType.App, "cloud:com.experitest.ExperiBank");
dc.SetCapability(MobileCapabilityType.AutoWebView, true);
driver = new IOSDriver<>('<server>', dc);

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Android Only
Name Description
noReset Don't reset app state before this session.Default false.

appPackage package name of the activity for launch

appActivity activity name to launch

autoGrantPermissions Grants permissions required by the application on install

Java
// Install Android application from path and launch it on the device
// You'll need to upload the application to the cloud as a prerequisite

DesiredCapabilities dc = new DesiredCapabilities();


dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.eribank/com.e
xperitest.ExperiBank.LoginActivity");
dc.setCapability("instrumentApp", true);
dc.setCapability(MobileCapabilityType.FULL_RESET, true);
dc.setCapability("dontGoHomeOnQuit", true);
driver = new AndroidDriver<>('<server>', dc);
Python
dc = {}

....
....

self.dc['platformName'] = 'android'
self.dc['app'] = 'cloud:com.experitest.eribank/com.experitest.ExperiBank.Login
Activity'
self.dc['instrumentApp'] = True
self.dc['fullReset'] = True

©2023 Digital.ai Inc. All rights reserved Page 253


Test Execution

self.dc['dontGoHomeOnQuit'] = True
self.driver = webdriver.Remote('<server>', self.dc)

C Sharp
// Install Android application from path and launch it on the device
DesiredCapabilities dc = new DesiredCapabilities();
dc.SetCapability(MobileCapabilityType.App, "cloud:com.experitest.eribank/com.e
xperitest.ExperiBank.LoginActivity");
dc.SetCapability("instrumentApp", true);
dc.SetCapability(MobileCapabilityType.FullReset, true);
dc.SetCapability("dontGoHomeOnQuit", true);
driver = new AndroidDriver<>('<server>', dc);

Start Test without Launching An Application


In order to start the test, you should omit the app capability and the application ID capabilities (bundleId/
appPackage + appActivity).

Java
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver<>('<server>', dc);
Python
dc = {}
self.dc['platformName'] = 'android'
self.driver = webdriver.Remote('<server>', self.dc)
C Sharp
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver<>('<server>', dc);

ChromeDriver on Android
• Information for Cloud Administrators since version 23.2

If you wish to test web applications using Chrome on Android, you can initialize the driver as ChromeDriver.
What this means is that commands and actions will be carried out by ChromeDriver, allows for more
accurate and error-free web application tests. The implementation of ChromeDriver takes into account
testing outside the web application. In case you change the context from Web to Native App, commands will
be delegated through Appium Driver; if you switch back to Web context, commands will once more be
delegated to ChromeDriver.

©2023 Digital.ai Inc. All rights reserved Page 254


Test Execution

To initialize ChromeDriver, you need to set it in the test capabilities:

Java
dc.setBrowserName(MobileBrowserType.CHROME);
Python
self.dc['browserName'] = 'chrome'
C Sharp
dc.SetCapability(MobileCapabilityType.BrowserName, MobileBrowserType.Chrome);

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Ruby
desired_caps = {
caps: {
...
browserName: 'chrome',
...
},
appium_lib: {
server_url: '<server>',
}
}

Setting this capability will cause Chrome browser to launch immediately once the test starts. It is not possible
to set this capability alongside app related capabilities (AndroidMobileCapabilityType.APP_PACKAGE,
AndroidMobileCapabilityType.APP_ACTIVITY) because the MobileBrowserType capability takes
precedence.

The corresponding context is "CHROMIUM". If you want to switch to Native app context and back, you need
to set the context to "CHROMIUM":

©2023 Digital.ai Inc. All rights reserved Page 255


Test Execution

Java
driver.context("CHROMIUM");

Python
self.driver.switch_to.context("CHROMIUM")

C Sharp
driver.Context = "CHROMIUM";
Ruby
@driver.switch_to.context("CHROMIUM")

iOS Alerts

Alert capabilities allow you to configure an auto accept/dismiss of iOS popup alerts. This comes in handy
when you wish to avoid having tests fail because alerts and popups prevented the driver from recognizing
and interacting with elements in the app.

Supported for iOS 9 and above.

Name Possible Values Notes


autoAcceptAlerts true / falseDefault: OK/Allow/AcceptThe alert popup will be accepted and disappear immediately on
false any element related consecutive operation which is executed after the popup
appeared

autoDismissAlerts true / falseDefault: Dismiss/Don't allow/Close/Cancel/Not now/...LaterThe alert popup will be dismissed
false and disappeared immediately on any element related consecutive operation which
is executed after the popup appearing

Dismissing Alerts

Replace "autoAcceptAlerts" with "autoDismissAlerts" to dismiss alerts

Java
public void test() throws MalformedURLException {
IOSDriver<IOSElement> driver = null;

DesiredCapabilities dc = new DesiredCapabilities();

©2023 Digital.ai Inc. All rights reserved Page 256


Test Execution

dc.setCapability("app", app);
dc.setCapability("autoAcceptAlerts", true);
driver = new IOSDriver<>(new URL(<server>), dc);

// clicking on this button will cause a popup alert with "Don't allow"
and "OK" buttons to appear
driver.findElement(By.xpath("//*[@XCElementType='XCUIElementTypeButton']"))
.click();

// clicking on a button behind the popup alert will cause the popup to
disappear
driver.findElement(By.xpath("//*[@XCElementType='XCUIElementTypeButton'][3]
")).click();
}
Python
def test():
dc = {}
self.dc['platformName'] = 'ios'
self.dc['app'] = app
self.dc['autoAcceptAlerts'] = True
self.driver = webdriver.Remote(<server>, self.dc)

# // clicking on this button will cause a popup alert with "Don't allow
" and "OK" buttons to appear
self.driver.find_element_by_xpath("xpath=//*[@XCElementType='XCUIElemen
tTypeButton']")

# // clicking on a button behind the popup alert will cause the popup
to disappear
self.driver.find_element_by_xpath("xpath=//*[@XCElementType='XCUIElemen
tTypeButton[3]']")
C Sharp
public void test() throws MalformedURLException {
IOSDriver<IOSElement> driver = null;

DesiredCapabilities dc = new DesiredCapabilities();


dc.SetCapability("app", app);
dc.SetCapability("autoAcceptAlerts", true);
driver = new IOSDriver<>(new URL(<server>), dc);

// clicking on this button will cause a popup alert with "Don't allow"
and "OK" buttons to appear
driver.FindElement(By.xpath("//*[@XCElementType='XCUIElementTypeButton']")
).Click();

// clicking on a button behind the popup alert will cause the popup to
disappear

©2023 Digital.ai Inc. All rights reserved Page 257


Test Execution

driver.FindElement(By.xpath("//*[@XCElementType='XCUIElementTypeButton'][3
]")).Click();
}
Ruby
def test_ios_app
desired_caps = {
caps: {
app: 'app',
autoAcceptAlerts: true,
},
appium_lib: {
server_url: '<server>',
}
}
@driver = Appium::Driver.new(desired_caps, true).start_driver

# clicking on this button will cause a popup alert with "Don't allow" a
nd "OK" buttons to appear
@driver.find_element(:xpath, "//*[@XCElementType='XCUIElementTypeButton']")
.click

# clicking on a button behind the popup alert will cause the popup to
disappear
@driver.find_element(:xpath, "//*[@XCElementType='XCUIElementTypeButton'][3
]").click

end

Timeout Capabilities
Name Description Units Default Value
newSessionWaitTimeout Timeout for new Session creation How long should we wait before Seconds 10 Minutes
failing the driver initialization

newCommandTimeout The timeout of a command, before the server, closes the session Seconds 30 Seconds
(seconds)

endSessionWaitTimeout The timeout of ending appium session (driver.quit())Reports are Seconds 5 Minutes
uploaded to reporter during ending appium session.

©2023 Digital.ai Inc. All rights reserved Page 258


Test Execution

Examples

Java
dc.setCapability("newSessionWaitTimeout", 300);
dc.setCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 15);
Python
self.dc["newSessionWaitTimeout"] = 300
self.dc["newCommandTimeout"] = 15
C Sharp
dc.SetCapability("newSessionWaitTimeout", 300);
dc.SetCapability(MobileCapabilityType.NEW_COMMAND_TIMEOUT, 15);
Ruby
desired_caps = {
caps: {
newSessionWaitTimeout: 300,
newCommandTimeout: 15,
browserName: 'safari'
},

Override Appium Driver Log Method to


Print Log Values to Console
In order to have the IDE console print Appium Studio logs, you should create a new driver class by
extending the existing AndroidDriver or IOSDriver classes and override the log method.

Currently, this is only possible to achieve with Java, C# and Python.

Visit our Git Repo for a working demo:

Java

C#

Python

In your test script, initialize the driver using the newly created driver classes.

©2023 Digital.ai Inc. All rights reserved Page 259


Test Execution

Network Virtualization Capabilities


If you are running an automated tests on your mobile application or website and you want to know how
they behave under certain network conditions, you can set the network conditions before the test starts.

Setting network profile is done in Appium's capabilities settings.

This capability allows setting a predefined network virtualization profile on the device of the test.

The chosen profile will be used during the entire test run.

Name Description
nvProfile Defines a network virtualization profile on the device which is set for the test

Java
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("nvProfile", "profile1");
driver = new IOSDriver<>(new URL("<server>", dc);
Python
self.dc['nvProfile'] = 'profile1'
C Sharp
DesiredCapabilities dc = new DesiredCapabilities();
dc.SetCapability("nvProfile", "profile1");
driver = new IOSDriver<>(new URL("<server>"), dc);
Ruby
desired_caps = {
caps: {
...
...
nvProfile: 'profile1'
...
...
},
appium_lib: {
server_url: '<server>',
}
}

©2023 Digital.ai Inc. All rights reserved Page 260


Test Execution

Attaching Audio to Video Report


With audioReport, to can add synchronized audio to your video reports, adding a layer of analysis to your
application testing.

1. Set up the device for audio recording support (see Audio and Screen Readers Support Using a
Bluetooth Adapter).

2. Set the AudioReport capability to true in your test capabilities.

dc.setCapability("audioReport", true);
3. Run your test on a device with audio report.

Limitations:

• It is not possible to record additional recordings for the same device when this capability is true. In
general, it is possible to use only one audio recording feature at the same time.
• If the device does not have Bluetooth properly configured and enabled, the test fails.

Code Examples

Use these examples to get started with Appium based testing.

If you don't find the programming language or framework that you were looking for, contact us using chat or
email.

©2023 Digital.ai Inc. All rights reserved Page 261


Test Execution

Java
Continuous Testing Cloud lets you to execute Appium tests developed in Java, on local and remotely located
devices.

You can use the sample tests in our git repository by cloning them, or the sample tests below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Android App Testing using Java


package apptest;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public class AndroidAppTest {

AndroidDriver driver = null;


DesiredCapabilities dc = new DesiredCapabilities();
String testName = "Testing Android App with Java";
String accessKey = System.getenv("SEETEST_IO_ACCESS_KEY");

@Before
public void setUp() throws IOException {
dc.setCapability("testName", testName);
dc.setCapability("accessKey", accessKey);
//install the app on the device
dc.setCapability(MobileCapabilityType.APP, "http://d242m5chux1g9j.clou
dfront.net/eribank.apk");

©2023 Digital.ai Inc. All rights reserved Page 262


Test Execution

//get an Android device


dc.setCapability("platformName", "Android");
//launch the app
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.experit
est.ExperiBank");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".LoginActi
vity");
driver = new AndroidDriver(new URL("<server>"), dc);
}

@Test
public void testYourAndroidApp() {
driver.findElement(By.xpath("//*[@id='usernameTextField']")).sendKeys("
company");
driver.findElement(By.xpath("//*[@id='passwordTextField']")).sendKeys("
company");
driver.findElement(By.xpath("//*[@id='loginButton']")).click();
driver.findElement(By.xpath("//*[@id='makePaymentButton']")).click();
driver.findElement(By.xpath("//*[@id='phoneTextField']")).sendKeys("123
456");
driver.findElement(By.xpath("//*[@id='nameTextField']")).sendKeys("Test
");
driver.findElement(By.xpath("//*[@id='amountTextField']")).sendKeys("10
");
driver.findElement(By.xpath("//*[@id='countryTextField']")).sendKeys("U
S");
driver.hideKeyboard();
driver.findElement(By.xpath("//*[@id='sendPaymentButton']")).click();
driver.findElement(By.xpath("//*[@id='button1']")).click();

@After
public void tearDown() {
if (driver != null)
{
driver.quit();
System.out.println("Report URL : " + driver.getCapabilities().getC
apability("reportUrl"));

}
}

}
IOS App Testing for java
package apptest;

import io.appium.java_client.remote.IOSMobileCapabilityType;

©2023 Digital.ai Inc. All rights reserved Page 263


Test Execution

import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.MalformedURLException;
import java.net.URL;

public class iOSAppTest {

IOSDriver driver = null;


DesiredCapabilities dc = new DesiredCapabilities();
String testName = "Testing iOS App with Java";
String accessKey = System.getenv("SEETEST_IO_ACCESS_KEY");

@Before
public void setUp() throws MalformedURLException {
dc.setCapability("testName", testName);
dc.setCapability("accessKey", accessKey);
//install the app on the device
dc.setCapability(MobileCapabilityType.APP, "http://d242m5chux1g9j.clou
dfront.net/EriBank.ipa");
//get an iOS device
dc.setCapability("platformName", "iOS");
dc.setCapability("autoDismissAlerts", true);
//launch the app
dc.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.experitest.Ex
periBank");

driver = new IOSDriver(new URL("<server>"), dc);


}

@Test
public void testYouriOSApp() {

driver.findElement(By.xpath("//*[@text='Username']")).sendKeys("company
");
driver.findElement(By.xpath("//*[@text='Password']")).sendKeys("company
");
driver.findElement(By.xpath("//*[@text='loginButton']")).click();
driver.findElement(By.xpath("//*[@text='makePaymentButton']")).click();
driver.findElement(By.xpath("//*[@text='Phone']")).sendKeys("123456");
driver.findElement(By.xpath("//*[@text='Name']")).sendKeys("Test");
driver.findElement(By.xpath("//*[@text='Amount']")).sendKeys("10");
driver.findElement(By.xpath("//*[@text='Country']")).sendKeys("US");
driver.findElement(By.xpath("//*[@text='sendPaymentButton']")).click();
driver.findElement(By.xpath("//*[@text='Yes']")).click();

©2023 Digital.ai Inc. All rights reserved Page 264


Test Execution

@After
public void tearDown() {
if (driver != null)
{
driver.quit();
System.out.println("Report URL : " + driver.getCapabilities().getC
apability("reportUrl"));

}
}

}
Chrome on Android Test using Java
package webtest;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileBrowserType;
import io.appium.java_client.remote.MobileCapabilityType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

public class AndroidWebTest {


ChromeOptions chromeOptions;
AndroidDriver driver = null;
DesiredCapabilities dc = new DesiredCapabilities();
String testName = "Testing Website on Android Chrome with Java";
String accessKey = System.getenv("SEETEST_IO_ACCESS_KEY");

@Before
public void setUp() throws MalformedURLException {
dc.setCapability("testName", testName);
dc.setCapability("accessKey",accessKey);
dc.setBrowserName(MobileBrowserType.CHROME);
driver = new AndroidDriver(new URL("<server>"),dc);
}

@Test

©2023 Digital.ai Inc. All rights reserved Page 265


Test Execution

public void testYourAndroidApp() throws InterruptedException {


driver.get("https://amazon.com");
System.out.println(driver.getTitle());
if( driver.getCapabilities().getCapability("device.category").equals("
TABLET")){

driver.findElement(By.xpath("//*[@name='field-keywords']")).sendKey
s("iPhone");
driver.findElement(By.xpath("//*[@text='Go']")).click();
}
else{
driver.findElement(By.xpath("//*[@name='k']")).sendKeys("iPhone");
driver.findElement(By.xpath("//*[@value='Go']")).click();
}
}

@After
public void tearDown() {
if (driver != null)
{
driver.quit();
System.out.println("Report URL : " + driver.getCapabilities().getC
apability("reportUrl"));

}
}

}
Safari on IOS Test using Java
package apptest;

import io.appium.java_client.remote.IOSMobileCapabilityType;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.MobileCapabilityType;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.remote.DesiredCapabilities;
import java.net.MalformedURLException;
import java.net.URL;

public class iOSAppTest {

IOSDriver driver = null;


DesiredCapabilities dc = new DesiredCapabilities();
String testName = "Testing iOS App with Java";
String accessKey = System.getenv("SEETEST_IO_ACCESS_KEY");

©2023 Digital.ai Inc. All rights reserved Page 266


Test Execution

@Before
public void setUp() throws MalformedURLException {
dc.setCapability("testName", testName);
dc.setCapability("accessKey", accessKey);
//install the app on the device
dc.setCapability(MobileCapabilityType.APP, "http://d242m5chux1g9j.clou
dfront.net/EriBank.ipa");
//get an iOS device
dc.setCapability("platformName", "iOS");
dc.setCapability("autoDismissAlerts", true);
//launch the app
dc.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.experitest.Ex
periBank");

driver = new IOSDriver(new URL("<server>"), dc);


}

@Test
public void testYouriOSApp() {

driver.findElement(By.xpath("//*[@text='Username']")).sendKeys("company
");
driver.findElement(By.xpath("//*[@text='Password']")).sendKeys("company
");
driver.findElement(By.xpath("//*[@text='loginButton']")).click();
driver.findElement(By.xpath("//*[@text='makePaymentButton']")).click();
driver.findElement(By.xpath("//*[@text='Phone']")).sendKeys("123456");
driver.findElement(By.xpath("//*[@text='Name']")).sendKeys("Test");
driver.findElement(By.xpath("//*[@text='Amount']")).sendKeys("10");
driver.findElement(By.xpath("//*[@text='Country']")).sendKeys("US");
driver.findElement(By.xpath("//*[@text='sendPaymentButton']")).click();
driver.findElement(By.xpath("//*[@text='Yes']")).click();

@After
public void tearDown() {
if (driver != null)
{
driver.quit();
System.out.println("Report URL : " + driver.getCapabilities().getC
apability("reportUrl"));

}
}

©2023 Digital.ai Inc. All rights reserved Page 267


Test Execution

Set Appium Java Client

To make use of the Appium Java Client, add a dependency to your Maven and Gradle projects.

Make sure you replace <VERSION> with 7.6.0.

It is recommended to use the public maven repository before the code export.

pom.xml
<dependency>
<groupId>com.experitest</groupId>
<artifactId>appium</artifactId>
<version>VERSION</version>
</dependency>
build.gradle
dependencies {
compile group: 'io.appium', name: 'java-client', version: 'VERSION'
}

Prerequisites
• Latest JDK.
• Java IDE like Eclipse or IntelliJ

Before you proceed with fetching the sample tests:

1. Upload your app to your project.


2. Fetch your access key.

Appium requires you to fetch and integrate Appium Dependencies, also known as Appium Java Client
Libraries. The process requires you to download the .jar files and add them to your project. It takes time and
there could be some setbacks on the way. We want it to be as easy as possible for you to start your testing
so we created a git project for you that will help you set up your project with a few clicks. The project includes
one iOS test class and one Android test class.

Included in the git project is a Gradle file that takes care of adding the Appium Java Client libraries and JUnit
(Unit Testing).

To use the repository:

1. Close the repository using either Intellij or Eclipse.

©2023 Digital.ai Inc. All rights reserved Page 268


Test Execution

2. Edit the test and run it.

You can also use the TestNG testing framework.

C#

Continuous Testing Cloud lets you execute Appium tests written in C# on remotely located devices. This
page has everything you need on order to run Appium tests using C#. It lists requirements, prerequisites and
two sample tests hosted in a git repository - one for iOS and one for Android.

You can use the sample tests in the git repository by cloning them, or use the sample tests.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Android App Test with C Sharp


using System;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Appium.Android;
using NUnit;
using NUnit.Framework;
using System.Collections.Generic;
using OpenQA.Selenium.Appium.Enums;
using OpenQA.Selenium.Appium.Service;
using OpenQA.Selenium.Appium.Service.Options;

namespace AppiumCsharpFirstTest
{
[TestFixture]
public class AndroidAppTest
{
// you have configured an access key as environment variable,
// use the line below. Otherwise, specify the key directly.
private string accessKey = Environment.GetEnvironmentVariable("SEETEST
_IO_ACCESS_KEY");
private string testName = "Android App Test with C#";

©2023 Digital.ai Inc. All rights reserved Page 269


Test Execution

protected AndroidDriver<AndroidElement> driver = null;

protected AppiumOptions caps = new AppiumOptions();

[SetUp()]
public void SetupTest()
{
caps.AddAdditionalCapability("testName", testName);
caps.AddAdditionalCapability("accessKey", accessKey);
caps.AddAdditionalCapability("deviceQuery", "@os='android'");
caps.AddAdditionalCapability("platformName", "Android")
;
caps.AddAdditionalCapability("app", "cloud:com.experitest.ExperiBa
nk/.LoginActivity");
caps.AddAdditionalCapability("appPackage", "com.experitest.ExperiB
ank");
caps.AddAdditionalCapability("appActivity", ".LoginActi
vity");

driver = new AndroidDriver<AndroidElement>(new Uri("<server>"), ca


ps);
}

[Test()]
public void TestAndroidApp()
{
driver.FindElement(By.XPath("xpath=//*[@id='usernameTextField']"))
.SendKeys("company");
driver.FindElement(By.XPath("xpath=//*[@id='passwordTextField']"))
.SendKeys("company");
driver.FindElement(By.XPath("xpath=//*[@id='loginButton']")).Clic
k();
driver.FindElement(By.XPath("xpath=//*[@id='makePaymentButton']"))
.Click();
driver.FindElement(By.XPath("xpath=//*[@id='phoneTextField']")).Se
ndKeys("123456");
driver.FindElement(By.XPath("xpath=//*[@id='nameTextField']")).Sen
dKeys("Test");
driver.FindElement(By.XPath("xpath=//*[@id='amountTextField']")).S
endKeys("10");
driver.FindElement(By.XPath("xpath=//*[@id='countryTextField']")).
SendKeys("US");
driver.FindElement(By.XPath("xpath=//*[@id='sendPaymentButton']"))
.Click();
driver.FindElement(By.XPath("xpath=//*[@id='button1']")).Click();
}

[TearDown()]

©2023 Digital.ai Inc. All rights reserved Page 270


Test Execution

public void TearDown()


{
if (driver != null)
{
Console.WriteLine(driver.Capabilities.GetCapability("reportUrl
"));
driver.Quit();
}
}
}
}
IOS App Test with C Sharp
using System;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium;
using OpenQA.Selenium.Appium.iOS;
using NUnit.Framework;

namespace AppiumCsharpFirstTest
{
public class iOSAppTest
{

// you have configured an access key as environment variable,


// use the line below. Otherwise, specify the key directly.
private string accessKey = Environment.GetEnvironmentVariable("SEETEST
_IO_ACCESS_KEY");
private string testName = "iOS App Test with C#";

protected IOSDriver<IOSElement> driver = null;

protected AppiumOptions caps = new AppiumOptions();

[SetUp()]
public void SetupTest()
{
caps.AddAdditionalCapability("testName", testName);
caps.AddAdditionalCapability("accessKey", accessKey);
caps.AddAdditionalCapability("deviceQuery", "@os='ios'");
caps.AddAdditionalCapability("platformName", "iOS");
caps.AddAdditionalCapability("app", "cloud:com.experitest.ExperiBa
nk");
caps.AddAdditionalCapability("bundleId", "com.experitest.ExperiBan
k");

driver = new IOSDriver<IOSElement>(new Uri("<server>"), caps);


}

[Test()]

©2023 Digital.ai Inc. All rights reserved Page 271


Test Execution

public void TestiOSApp()


{
driver.FindElement(By.XPath("xpath=//*[@id='usernameTextField']"))
.SendKeys("company");
driver.FindElement(By.XPath("xpath=//*[@id='passwordTextField']"))
.SendKeys("company");
driver.FindElement(By.XPath("xpath=//*[@id='loginButton']")).Clic
k();
}

[TearDown()]
public void TearDown()
{
if (driver != null)
{
Console.WriteLine(driver.Capabilities.GetCapability("reportUrl
"));
driver.Quit();
}
}

}
}
Chrome on Android Test with C Sharp
using System;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Appium.Android;
using NUnit;
using NUnit.Framework;
using System.Collections.Generic;
using OpenQA.Selenium.Appium.Enums;
using OpenQA.Selenium.Appium.Service;
using OpenQA.Selenium.Appium.Service.Options;

namespace AppiumCsharpFirstTest
{
[TestFixture]
public class AndroidWebTest
{
// you have configured an access key as environment variable,
// use the line below. Otherwise, specify the key directly.
private string accessKey = Environment.GetEnvironmentVariable("SEETEST
_IO_ACCESS_KEY");
private string testName = "Android Web Test with C#";

protected AndroidDriver<AndroidElement> driver = null;

©2023 Digital.ai Inc. All rights reserved Page 272


Test Execution

protected AppiumOptions caps = new AppiumOptions();

[SetUp()]
public void SetupTest()
{
caps.AddAdditionalCapability("testName", testName);
caps.AddAdditionalCapability("accessKey", accessKey);
caps.AddAdditionalCapability("deviceQuery", "@os='android'");
caps.AddAdditionalCapability("platformName", "Android")
;
caps.AddAdditionalCapability("browserName", "chrome");

driver = new AndroidDriver<AndroidElement>(new Uri("<server>"),


caps);
}

[Test()]
public void TestAndroidApp()
{
driver.Navigate().GoToUrl("https://amazon.com");
if (driver.Capabilities.GetCapability("device.category").Equals("T
ABLET"))
{
driver.FindElement(By.XPath("//*[@name='field-keywords']")).Sen
dKeys("iPhone");
driver.FindElement(By.XPath("//*[@text='Go']")).Click();
}
else
{
driver.FindElement(By.XPath("//*[@name='k']")).SendKeys("iPhon
e");
driver.FindElement(By.XPath("//*[@value='Go']")).Click();
}
}

[TearDown()]
public void TearDown()
{
if(driver != null)
{
Console.WriteLine(driver.Capabilities.GetCapability("reportUrl
"));
driver.Quit();
}

}
}
}
Safari on IOS Test with C Sharp

©2023 Digital.ai Inc. All rights reserved Page 273


Test Execution

using System;
using OpenQA.Selenium.Appium;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Appium.iOS;
using NUnit.Framework;
using OpenQA.Selenium.Appium.Enums;

namespace AppiumCsharpFirstTest
{
[TestFixture]
public class IOSWebTest
{
// you have configured an access key as environment variable,
// use the line below. Otherwise, specify the key directly.
private string accessKey = Environment.GetEnvironmentVariable("SEETEST
_IO_ACCESS_KEY");
private string testName = "iOS Safari Web Test";

protected IOSDriver<IOSElement> driver = null;

protected AppiumOptions caps = new AppiumOptions();

[SetUp()]
public void SetupTest()
{
caps.AddAdditionalCapability("testName", testName);
caps.AddAdditionalCapability("accessKey", accessKey);
caps.AddAdditionalCapability("deviceQuery", "@os='ios'");
caps.AddAdditionalCapability("platformName", "iOS");
caps.AddAdditionalCapability("browserName", "safari");
caps.AddAdditionalCapability("autoDismissAlerts", true)
;

driver = new IOSDriver<IOSElement>(new Uri("<server>"), caps);

[Test()]
public void TestiOSApp()
{
driver.Navigate().GoToUrl("https://amazon.com");
if (driver.Capabilities.GetCapability("device.category").Equals("T
ABLET"))
{
driver.FindElement(By.XPath("//*[@name='field-keywords']")).Sen
dKeys("iPhone");
driver.FindElement(By.XPath("//*[@text='Go']")).Click();
}

©2023 Digital.ai Inc. All rights reserved Page 274


Test Execution

else
{
driver.FindElement(By.XPath("//*[@name='k']")).SendKeys("iPhon
e");
driver.FindElement(By.XPath("//*[@value='Go']")).Click();
}
}

[TearDown()]
public void TearDown()
{
if (driver != null)
{
Console.WriteLine(driver.Capabilities.GetCapability("reportUrl
"));
driver.Quit();
}
}
}
}

Prerequisites

These samples require using the Visual Studio Community Edition.

Before you proceed with fetching the sample tests:

1. If you plan to test a native or hybrid app, upload your app to your project.

2. Fetch your access key.

Getting Started

Appium requires you to fetch and integrate Appium Dependencies, also known as the Appium C# Client
Libraries. The git project is a packages.config file that takes care of adding Appium C# Client libraries and
NUnit (unit testing for C#).

Now you can clone the repository to your Visual Studio project.

If you are having issues with obtaining the requires packages, run the following commands in Visual Studio
Package Manager Console:

To get Selenium:

Install-Package Selenium.Support

To get Appium:

©2023 Digital.ai Inc. All rights reserved Page 275


Test Execution

Install-Package Appium.WebDriver

To get NUnit:

Install-Package NUnit
Install-Package NUnit3TestAdapter
Install-Package NUnit.Console

NUnit

NUnit is a testing unit framework designed to support test execution for .NET. It allows you to run tests that
were written in C# without the need to initialize the test classes that you have written.

What does this mean?

The default unit testing template defines one method for setting up the test, one method for executing the
test, and one test for cleaning up once the test has been executed (whether the test succeeded or not).
Consider the code template below:

Example : C# NUnit Test


[TestFixture]
public class IOSWebTest
{
// you have configured an access key as environment variable,
// use the line below. Otherwise, specify the key directly.
private string accessKey = Environment.GetEnvironmentVariable("SEETEST
_IO_ACCESS_KEY");
private string testName = "iOS Safari Web Test";
protected IOSDriver<IOSElement> driver = null;

DesiredCapabilities dc = new DesiredCapabilities();

[SetUp()]
public void SetupTest()
{
dc.SetCapability("testName", testName);
dc.SetCapability("accessKey", accessKey);
dc.SetCapability(MobileCapabilityType.PlatformName, "iOS");
dc.SetCapability("autoDismissAlerts", true);

©2023 Digital.ai Inc. All rights reserved Page 276


Test Execution

dc.SetCapability(MobileCapabilityType.BrowserName, "safari");
driver = new IOSDriver<IOSElement>(new Uri("https://cloud.seetest.
io:443/wd/hub"), dc);
}

[Test()]
public void TestiOSApp()
{
driver.Navigate().GoToUrl("https://amazon.com");
}

[TearDown()]
public void TearDown()
{
driver.Quit();
}
}

As you can see, each method is marked with an annotation that defines its role in the test workflow:

• [SetUp()] - the method that prepares all the parameters needed for the test
• [Test()] - the method where the test steps are defined
• [TearDown()] - the method that cleans up after the test has finished running

Without NUnit, you would have to create an instance of the test class and run inside a static main method.
With NUnit, you do not need to write create a class test instance and run it in a main method.

Getting Started with NUnit

To use NUnit, install the required NUnit packages using Visual Studio Package Manager Console by running
these commands:

Install-Package NUnit
Install-Package NUnit3TestAdapter

These packages are added to your project. They are also added to the packages.config file in your project.
This makes the project importable, allowing it to be transferred to other team members and even checked
into a git repository.

To learn more about NUnit, see the NUnit Documentation.

Python

©2023 Digital.ai Inc. All rights reserved Page 277


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Continuous Testing Cloud lets you execute Appium tests on remotely located devices. This page is the
starting line for your Appium tests with Python. It lists requirements, prerequisites and two sample tests
hosted in a git repository - one for iOS and one for Android.

Use of our sample tests in our git repository by cloning them, or use the sample tests below.

Android App Testing with Python


import unittest
from appium import webdriver
import os

class AndroidAppTest(unittest.TestCase):
test_name = "Android App Test with Python"
dc = {}
# if you have configured an access key as environment variable,
# use the line below. Otherwise, specify the key directly.
accessKey = os.environ['SEETEST_IO_ACCESS_KEY']
driver = None

def setUp(self):
self.dc['testName'] = self.test_name
self.dc['accessKey'] = self.accessKey
self.dc['platformName'] = 'Android'
self.dc['app'] = 'http://d242m5chux1g9j.cloudfront.net/eribank.apk'
self.dc['appPackage'] = 'com.experitest.ExperiBank'
self.dc['appActivity'] = '.LoginActivity'
self.driver = webdriver.Remote('<server>', self.dc)

def testYourAndroidApp(self):
self.driver.find_element_by_xpath("xpath=//*[@id='usernameTextField']")
.send_keys('company')
self.driver.find_element_by_xpath("xpath=//*[@id='passwordTextField']")
.send_keys('company')
self.driver.find_element_by_xpath("xpath=//*[@id='loginButton']").clic
k()
self.driver.find_element_by_xpath("xpath=//*[@text='Make Payment']").cl
ick()

©2023 Digital.ai Inc. All rights reserved Page 278


Test Execution

self.driver.find_element_by_xpath("xpath=//*[@id='phoneTextField']").se
nd_keys('123456')
self.driver.find_element_by_xpath("xpath=//*[@id='nameTextField']").sen
d_keys('Test')
self.driver.find_element_by_xpath("xpath=//*[@id='amountTextField']").s
end_keys('10')
self.driver.find_element_by_xpath("xpath=//*[@id='countryTextField']").
send_keys('US')
self.driver.find_element_by_xpath("xpath=//*[@text='Send Payment']").cl
ick()
self.driver.find_element_by_xpath("xpath=//*[@id='button1']").click()

def tearDown(self):
if self.driver is not None:
print(self.driver.capabilities.get("reportUrl"))
self.driver.quit()

if __name__ == '__main__':
unittest.main()
IOS App Testing using Python
import unittest
from appium import webdriver
import os

class IosAppTest(unittest.TestCase):
test_name = "iOS App Test with Python"
dc = {}
# if you have configured an access key as environment variable,
# use the line below. Otherwise, specify the key directly.
accessKey = os.environ['SEETEST_IO_ACCESS_KEY']
driver = None

def setUp(self):
self.dc['testName'] = self.test_name
self.dc['accessKey'] = self.accessKey
self.dc['app'] = 'http://d242m5chux1g9j.cloudfront.net/EriBank.ipa'
self.dc['bundleId'] = 'com.experitest.ExperiBank'
self.dc['platformName'] = 'ios'
self.dc['autoDismissAlerts'] = True
self.driver = webdriver.Remote('<server>', self.dc)

def testUntitled(self):
self.driver.find_element_by_xpath("xpath=//*[@text='Username']").send_k
eys('company')
self.driver.find_element_by_xpath("xpath=//*[@text='Password']").send_k
eys('company')
self.driver.find_element_by_xpath("xpath=//*[@text='loginButton']").cli
ck()

©2023 Digital.ai Inc. All rights reserved Page 279


Test Execution

self.driver.find_element_by_xpath("xpath=//*[@text='makePaymentButton']
").click()
self.driver.find_element_by_xpath("xpath=//*[@text='Phone']").send_key
s('123456')
self.driver.find_element_by_xpath("xpath=//*[@text='Name']").send_keys(
'Test')
self.driver.find_element_by_xpath("xpath=//*[@text='Amount']").send_key
s('10')
self.driver.find_element_by_xpath("xpath=//*[@text='Country']").send_ke
ys('US')
self.driver.find_element_by_xpath("xpath=//*[@text='sendPaymentButton']
").click()
self.driver.find_element_by_xpath("xpath=//*[@text='Yes']").click()

def tearDown(self):
if self.driver is not None:
print(self.driver.capabilities.get("reportUrl"))
self.driver.quit()

if __name__ == '__main__':
unittest.main()
Chrome on Android Test with Python
import unittest
from appium import webdriver
import os

class TestWebsiteAndroidChrome(unittest.TestCase):
dc = {}
test_name = 'Test Mobile Website on Android Chrome'
# if you have configured an access key as environment variable,
# use the line below. Otherwise, specify the key directly.
accessKey = os.environ['SEETEST_IO_ACCESS_KEY']
driver = None

def setUp(self):
self.dc['testName'] = self.test_name
self.dc['accessKey'] = self.accessKey
self.dc['platformName'] = 'android'
self.dc['browserName'] = 'chrome'
self.driver = webdriver.Remote('<server>', self.dc)

def testUntitled(self):
self.driver.get('https://amazon.com')
if self.driver.capabilities['device.category'] == 'TABLET':
self.driver.find_element_by_xpath("//*[@name='field-keywords']").sen
d_keys('iPhone')
self.driver.find_element_by_xpath("//*[@text='Go']").click()
else:

©2023 Digital.ai Inc. All rights reserved Page 280


Test Execution

self.driver.find_element_by_xpath("//*[@name='k']").send_keys('iPho
ne')
self.driver.find_element_by_xpath("//*[@value='Go']").click()

def tearDown(self):
if self.driver is not None:
print(self.driver.capabilities.get("reportUrl"))
self.driver.quit()

if __name__ == '__main__':
unittest.main()
Safari on IOS Test with Python
import unittest
import os
from appium import webdriver

class TestWebsiteiOSSafari(unittest.TestCase):
dc = {}
test_name = 'Test Mobile Website on iOS Safari'
# if you have configured an access key as environment variable,
# use the line below. Otherwise, specify the key directly.
accessKey = os.environ['SEETEST_IO_ACCESS_KEY']
driver = None

def setUp(self):
self.dc['testName'] = self.test_name
self.dc['accessKey'] = self.accessKey
self.dc['platformName'] = 'ios'
self.dc['browserName'] = 'safari'
self.dc['autoDismissAlerts'] = True
self.driver = webdriver.Remote('<server>', self.dc)

def testUntitled(self):
self.driver.get('https://amazon.com')
if self.driver.capabilities['device.category'] == 'TABLET':
self.driver.find_element_by_xpath("//*[@name='field-keywords']").sen
d_keys('iPhone')
self.driver.find_element_by_xpath("//*[@text='Go']").click()
else:
self.driver.find_element_by_xpath("//*[@name='k']").send_keys('iPho
ne')
self.driver.find_element_by_xpath("//*[@value='Go']").click()

def tearDown(self):
if self.driver is not None:
print(self.driver.capabilities.get("reportUrl"))
self.driver.quit()

©2023 Digital.ai Inc. All rights reserved Page 281


Test Execution

if __name__ == '__main__':
unittest.main()

Prerequisites

• Latest Python.
• Python IDE like PyCharm.

• Appium Python Client on your machine. To install the client, run this command:

pip install Appium-Python-Client

• Projected uploaded and access key obtained

To proceed with fetching the sample tests:

• Upload your app to your project


• Fetch your access key

Get Started
• Find the sample test in the git repository.
• Clone the repository.
• Edit the test, then run it.

Javascript
Continuous Testing Cloud lets you execute Appium tests on remotely located devices. This page discusses
how to prepare and execute Appium tests using JavaScript and Node.js, as well as use your existing Appium
tests written in JavaScript.

Use of our sample tests in our git repository by cloning them, or use the sample tests.

©2023 Digital.ai Inc. All rights reserved Page 282


Test Execution

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Android App Testing using Javascript


"use strict";
var webdriverio = require('webdriverio');

function main() {

let options = {
host: '<server>',
protocol: 'https',
port: 443,
path: '',
desiredCapabilities: {
accessKey: "<ACCESS_KEY>",
platformName: 'android',
//udid: "<deviceid>", optional
app: "http://d242m5chux1g9j.cloudfront.net/eribank.apk", // if you hav
e the app in your project you can do cloud:com.pacakge.name
appPackage: "com.experitest.ExperiBank",
appActivity: ".LoginActivity",
testName: "Javascript Android App Test"
}
};

webdriverio
.remote(options)
.init()
.setValue("//*[@id='usernameTextField']", "company")
.setValue("//*[@id='passwordTextField']", "company")
.click("//*[@id='loginButton']")
.click("//*[@id='makePaymentButton']")
.setValue("//*[@id='phoneTextField']", "123456")
.setValue("//*[@id='nameTextField']", "Test")
.setValue("//*[@id='amountTextField']", "10")
.setValue("//*[@id='countryTextField']", "US")
.click("//*[@id='sendPaymentButton']")
.click("//*[@id='button1']")

©2023 Digital.ai Inc. All rights reserved Page 283


Test Execution

.click("//*[@id='logoutButton']")
.end()
.catch(function (err) {
console.log(err);
});
}

main();
IOS App Testing using Javascript
"use strict";
var webdriverio = require('webdriverio');

function main() {

let options = {
host: 'server',
protocol: 'https',
port: 443,
path: '',
desiredCapabilities: {
accessKey: "<ACCESS_KEY>",
platformName: 'ios',
//udid: "<deviceid>", optional
app: "http://d242m5chux1g9j.cloudfront.net/EriBank.ipa", // if you hav
e the app in your project you can do cloud:com.pacakge.name
bundleId: "com.experitest.ExperiBank", // would be appPackage and appA
ctivity for Android
testName: "Javascript iOS App Test"
}
};

webdriverio
.remote(options)
.init()
.setValue("//*[@id='usernameTextField']", "company")
.setValue("//*[@id='passwordTextField']", "company")
.click("//*[@id='loginButton']")
.click("//*[@id='makePaymentButton']")
.setValue("//*[@id='phoneTextField']", "123456")
.setValue("//*[@id='nameTextField']", "Test")
.setValue("//*[@id='amountTextField']", "10")
.setValue("//*[@id='countryTextField']", "US")
.click("//*[@id='sendPaymentButton']")
.click("//*[@id='Yes']")
.click("//*[@id='logoutButton']")
.end()
.catch(function (err) {
console.log(err);
});

©2023 Digital.ai Inc. All rights reserved Page 284


Test Execution

main();
Chrome on Android Test using Javascript
"use strict";
var webdriverio = require('webdriverio');

function main() {

let options = {
host: '<server>',
protocol: 'https',
port: 443,
path: '',
desiredCapabilities: {
accessKey: "<ACCESS_KEY>",
platformName: 'android',
browserName: 'chrome',
//udid: "<deviceid>", optional
testName: "Javascript Android Web Test"
}
};

webdriverio
.remote(options)
.init()
.url("https://ebay.com")
.setValue("//*[@id='kw']", "iPhone")
.click("//*[@id='ghs-submit']")
.pause(2000)
.getTitle().then(function(title){
console.log("The title of the page is: ", title);
})
.end()
.catch(function (err) {
console.log(err);
});
}

main();
Safari on IOS Test using Javascript
"use strict";
var webdriverio = require('webdriverio');

function main() {

let options = {
host: '<server>',
protocol: 'https',

©2023 Digital.ai Inc. All rights reserved Page 285


Test Execution

port: 443,
path: '',
desiredCapabilities: {
accessKey: "<ACCESS_KEY>",
platformName: 'ios',
//udid: "<deviceid>", optional
app: "http://d242m5chux1g9j.cloudfront.net/EriBank.ipa", // if you hav
e the app in your project you can do cloud:com.pacakge.name
bundleId: "com.experitest.ExperiBank", // would be appPackage and appA
ctivity for Android
testName: "Javascript iOS App Test"
}
};

webdriverio
.remote(options)
.init()
.setValue("//*[@id='usernameTextField']", "company")
.setValue("//*[@id='passwordTextField']", "company")
.click("//*[@id='loginButton']")
.click("//*[@id='makePaymentButton']")
.setValue("//*[@id='phoneTextField']", "123456")
.setValue("//*[@id='nameTextField']", "Test")
.setValue("//*[@id='amountTextField']", "10")
.setValue("//*[@id='countryTextField']", "US")
.click("//*[@id='sendPaymentButton']")
.click("//*[@id='Yes']")
.click("//*[@id='logoutButton']")
.end()
.catch(function (err) {
console.log(err);
});
}

main();

Prerequisites

• Latest Node.js.

• webdriver node bindings:

npm install --save webdriverio

©2023 Digital.ai Inc. All rights reserved Page 286


Test Execution

• Applicaiton uploaded and cloud access key obtained.

To proceed with fetching the sample tests:

• Upload your app to your project


• Fetch your access key

Getting Started
• Find the sample test in the git repository.

• Clone the repository.

• Edit the test, then run it.

Ruby
Continuous Testing Cloud lets you execute Appium tests written in Ruby on remotely located devices. These
include existing Appium tests written in Ruby that you have been running locally.

Use our sample tests in our git repository by cloning them, or use the sample tests below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Android App Test with Ruby


require 'test/unit'
require 'appium_lib'

class TestYourAndroidApp < Test::Unit::TestCase


def setup
desired_caps = {
caps: {
accessKey: ENV['SEETEST_IO_ACCESS_KEY'],
platformName: 'android',

©2023 Digital.ai Inc. All rights reserved Page 287


Test Execution

testName: 'Android App test with Ruby',


app: 'http://d242m5chux1g9j.cloudfront.net/eribank.apk',
appPackage: 'com.experitest.ExperiBank',
appActivity: '.LoginActivity'
},
appium_lib: {
server_url: '<server>',
}
}
@driver = Appium::Driver.new(desired_caps).start_driver
end

def test_android_app
@driver.find_element(:xpath, "//*[@id='usernameTextField']").send_keys 'comp
any'
@driver.find_element(:xpath, "//*[@id='passwordTextField']").send_keys 'comp
any'
@driver.find_element(:xpath, "//*[@id='loginButton']").click
@driver.find_element(:xpath, "//*[@id='makePaymentButton']").click
@driver.find_element(:xpath, "//*[@id='phoneTextField']").send_keys '123456'
@driver.find_element(:xpath, "//*[@id='nameTextField']").send_keys 'Test'
@driver.find_element(:xpath, "//*[@id='amountTextField']").send_keys '5'
@driver.find_element(:xpath, "//*[@id='countryTextField']").send_keys 'US'
@driver.find_element(:xpath, "//*[@id='sendPaymentButton']").click
@driver.find_element(:xpath, "//*[@id='button1']").click
end

def teardown
puts @driver.capabilities['reportUrl']
@driver.quit
end
end
IOS App Test with Ruby
require 'test/unit'
require 'appium_lib'

class TestYouriOSApp < Test::Unit::TestCase


def setup
desired_caps = {
caps: {
accessKey: ENV['SEETEST_IO_ACCESS_KEY'],
platformName: 'ios',
testName: 'iOS App Test with Ruby',
app: 'http://d242m5chux1g9j.cloudfront.net/EriBank.ipa',
autoDismissAlerts: true,
bundleId: 'com.experitest.ExperiBank',
},
appium_lib: {
server_url: '<server>',

©2023 Digital.ai Inc. All rights reserved Page 288


Test Execution

}
}
@driver = Appium::Driver.new(desired_caps, true).start_driver

end

def test_ios_app
@driver.find_element(:xpath, "//*[@text='Username']").send_keys 'company'
@driver.find_element(:xpath, "//*[@text='Password']").send_keys 'company'
@driver.find_element(:xpath, "//*[@text='loginButton']").click
@driver.find_element(:xpath, "//*[@text='makePaymentButton']").click
@driver.find_element(:xpath, "//*[@text='Phone']").send_keys '123456'
@driver.find_element(:xpath, "//*[@text='Name']").send_keys 'Test'
@driver.find_element(:xpath, "//*[@text='Amount']").send_keys '5'
@driver.find_element(:xpath, "//*[@text='Country']").send_keys 'US'
@driver.find_element(:xpath, "//*[@text='sendPaymentButton']").click
@driver.find_element(:xpath, "//*[@text='Yes']").click
end

def teardown
puts @driver.capabilities['reportUrl']
@driver.quit
end
end
Chrome on Android Test with Ruby
require 'test/unit'
require 'appium_lib'

class TestYourWebAppAndroid < Test::Unit::TestCase


def setup
desired_caps = {
caps: {
accessKey: ENV['SEETEST_IO_ACCESS_KEY'],
platformName: 'android',
testName: 'Android Web Test with Ruby',
browserName: 'chrome',

},
appium_lib: {
server_url: '<server>',
}
}
@driver = Appium::Driver.new(desired_caps, true).start_driver
end

def test_android_web
@driver.get('https://amazon.com')
if @driver.capabilities['device.category'].eql? 'TABLET'
@driver.find_element(:xpath, "//*[@name='field-keywords']").send_keys 'mob

©2023 Digital.ai Inc. All rights reserved Page 289


Test Execution

ile autoamtion testing'


search_btn = @driver.find_element(:xpath, "//*[@text='Go']")
else
@driver.find_element(:xpath, "//*[@name='k']").send_keys 'mobile autoamti
on testing'
search_btn = @driver.find_element(:xpath, "//*[@value='Go']")
end

search_btn.click
end

def teardown
puts @driver.capabilities['reportUrl']
@driver.quit
end
end
Safari on IOS Test with Ruby
ios_web_test.rb (source from Ruby Sample)require 'test/unit'
require 'appium_lib'

class TestYourWebAppiOS < Test::Unit::TestCase


def setup
desired_caps = {
caps: {
accessKey: ENV['SEETEST_IO_ACCESS_KEY'],
platformName: 'ios',
testName: 'iOS Web Test with Ruby',
autoDismissAlerts: true,
browserName: 'safari',

},
appium_lib: {
server_url: '<server>',
}
}
@driver = Appium::Driver.new(desired_caps, true).start_driver
end

def test_ios_web
@driver.get('https://amazon.com')
if @driver.capabilities['device.category'].eql? 'TABLET'
@driver.find_element(:xpath, "//*[@name='field-keywords']").send_keys 'mob
ile autoamtion testing'
search_btn = @driver.find_element(:xpath, "//*[@text='Go']")
else
@driver.find_element(:xpath, "//*[@name='k']").send_keys 'mobile autoamti
on testing'
search_btn = @driver.find_element(:xpath, "//*[@value='Go']")
end

©2023 Digital.ai Inc. All rights reserved Page 290


Test Execution

end

def teardown
puts @driver.capabilities['reportUrl']
@driver.quit
end
end

Prerequisites

• Ruby

• Appium for Ruby

gem install appium_lib

• Ruby IDE, or other code editor (atom is recommended) and then run your tests from the command
line.

Getting Started

To get started, clone the sample tests from thegit repository and start testing.

If you use a general purpose code editor, then to run the tests:

1. Open a command prompt or shell.


2. Navigate to the folder where the project is located.
3. Run this command:

ruby testfile.rb

©2023 Digital.ai Inc. All rights reserved Page 291


Test Execution

Appium Selenium Proxy


Connect Selenium / Appium java tests to the remote grid through a corporate proxy.

Java Client
Appium Client 8 / Selenium 4

The code was tested with Appium java client version 8.0.0

Appium client 8.x should be used to run tests on Appium server 2.x

Copy the following code to your client-side:

It is important to keep the package name

Proxy Netty Client


package org.openqa.selenium.remote.http.netty;

import io.netty.util.HashedWheelTimer;
import io.netty.util.Timer;
import io.netty.util.concurrent.DefaultThreadFactory;
import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.DefaultAsyncHttpClientConfig;
import org.asynchttpclient.Dsl;
import org.asynchttpclient.config.AsyncHttpClientConfigDefaults;
import org.openqa.selenium.internal.Require;
import org.openqa.selenium.remote.http.*;

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;

/**
* Based on this code with disabled proxySelector: .setUseProxySelector(false)
* https://github.com/SeleniumHQ/selenium/blob/selenium-4.3.0/java/src/org/ope
nqa/selenium/remote/http/netty/NettyClient.java
*/
public class ProxyNettyClient implements HttpClient {

private static final Timer TIMER;


private static final AsyncHttpClient client = createHttpClient(ClientConfig.
defaultConfig());

static {
ThreadFactory threadFactory = new DefaultThreadFactory("netty-client-t
imer", true);

©2023 Digital.ai Inc. All rights reserved Page 292


Test Execution

TIMER = new HashedWheelTimer(


threadFactory,
AsyncHttpClientConfigDefaults.defaultHashedWheelTimerTickDurati
on(),
TimeUnit.MILLISECONDS,
AsyncHttpClientConfigDefaults.defaultHashedWheelTimerSize());
}

private final ClientConfig config;


private final HttpHandler handler;
private final BiFunction<HttpRequest, WebSocket.Listener, WebSocket> toWebS
ocket;

private ProxyNettyClient(ClientConfig config) {


this.config = Require.nonNull("HTTP client config", config);
this.handler = new NettyHttpHandler(config, client).with(config.filter())
;
this.toWebSocket = NettyWebSocket.create(config, client);
}

/**
* Converts a long to an int, clamping the maximum and minimum values to
* fit in an integer without overflowing.
*/
static int toClampedInt(long value) {
return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, v
alue));
}

private static AsyncHttpClient createHttpClient(ClientConfig config) {


DefaultAsyncHttpClientConfig.Builder builder =
new DefaultAsyncHttpClientConfig.Builder()
.setThreadFactory(new DefaultThreadFactory("AsyncHttpC
lient", true))
.setUseInsecureTrustManager(true)
.setAggregateWebSocketFrameFragments(true)
.setWebSocketMaxBufferSize(Integer.MAX_VALUE)
.setWebSocketMaxFrameSize(Integer.MAX_VALUE)
.setNettyTimer(TIMER)
.setRequestTimeout(toClampedInt(config.readTimeout().to
Millis()))
.setConnectTimeout(toClampedInt(config.connectionTimeou
t().toMillis()))
.setReadTimeout(toClampedInt(config.readTimeout().toMil
lis()))
.setFollowRedirect(true)
.setUseProxyProperties(true)
.setUseProxySelector(false)
.setMaxRequestRetry(0);

©2023 Digital.ai Inc. All rights reserved Page 293


Test Execution

return Dsl.asyncHttpClient(builder);
}

@Override
public HttpResponse execute(HttpRequest request) {
return handler.execute(request);
}

@Override
public WebSocket openSocket(HttpRequest request, WebSocket.Listener listen
er) {
Require.nonNull("Request to send", request);
Require.nonNull("WebSocket listener", listener);

return toWebSocket.apply(request, listener);


}

@Override
public HttpClient with(Filter filter) {
Require.nonNull("Filter", filter);
return new ProxyNettyClient(config.withFilter(filter));
}

@Override
public void close() {
// no-op -- closing the client when the JVM shuts down
}

@HttpClientName("netty")
public static class Factory implements HttpClient.Factory {

@Override
public HttpClient createClient(ClientConfig config) {
Require.nonNull("Client config", config);

if (config.baseUri() != null && "unix".equals(config.baseUri().getSc


heme())) {
return new NettyDomainSocketClient(config);
}

return new ProxyNettyClient(config);


}
}
}

Running Appium test using proxy:

©2023 Digital.ai Inc. All rights reserved Page 294


Test Execution

Example
package example;

import io.appium.java_client.MobileCommand;
import io.appium.java_client.ios.IOSDriver;
import io.appium.java_client.remote.AppiumCommandExecutor;
import io.appium.java_client.remote.MobileCapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.HttpCommandExecutor;
import org.openqa.selenium.remote.http.netty.ProxyNettyClient;

import java.net.URL;

public class AppiumViaProxy {


static String cloudUrl = "https://myorg.experitest.com/wd/hub";
static String accessKey = "<access_key>";
IOSDriver driver = null;
protected DesiredCapabilities dc = new DesiredCapabilities();

static {
System.setProperty("http.proxyHost", "localhost");
System.setProperty("http.proxyPort", "3128");
System.setProperty("org.asynchttpclient.AsyncHttpClientConfig.proxy.use
r", "username");
System.setProperty("org.asynchttpclient.AsyncHttpClientConfig.proxy.pas
sword", "password");
}

public void start() throws Exception {


dc.setCapability(MobileCapabilityType.PLATFORM_NAME, "ios");
dc.setCapability(MobileCapabilityType.AUTOMATION_NAME, "XCUITest");
dc.setCapability("deviceQuery", "@os='ios'");
dc.setCapability("accessKey", accessKey);
dc.setCapability("appiumVersion", "2.0.0.beta.23");

HttpCommandExecutor commandExecutor = new AppiumCommandExecutor(


MobileCommand.commandRepository, new URL(cloudUrl), new ProxyN
ettyClient.Factory());
driver = new IOSDriver(commandExecutor, dc);

System.out.println("Page source len: " + driver.getPageSource());


driver.quit();
}
public static void main(String[] args) throws Exception {
new AppiumViaProxy().start();
}
}

©2023 Digital.ai Inc. All rights reserved Page 295


Test Execution

Appium Client 7 or below

The provided code was tested with Appium java client version 7.1.0.

Appium client 7 or below should be used to run tests on Appium server 1.x

Copy the following code to your client-side :

Web-Driver Proxy Client Factory


import io.appium.java_client.MobileCommand;
import io.appium.java_client.remote.AppiumCommandExecutor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import okhttp3.*;
import org.openqa.selenium.remote.http.HttpClient;

public class WebDriverProxyClientFactory implements HttpClient.Factory {

public static AppiumCommandExecutor createAppiumExecutor(URL url, String p


roxyHost, int proxyPort, String proxyUsername,
String proxyPassword) {
return new AppiumCommandExecutor(MobileCommand.commandRepository, url,
new WebDriverProxyClientFactory(proxyHost, proxyPort, proxyUse
rname, proxyPassword));
}

private String proxyHost;


private int proxyPort;
private String proxyUsername;
private String proxyPassword;

public WebDriverProxyClientFactory(String proxyHost, int proxyPort, String


proxyUsername, String proxyPassword) {
this.proxyHost = proxyHost;
this.proxyPort = proxyPort;
this.proxyUsername = proxyUsername;
this.proxyPassword = proxyPassword;
}

private final ConnectionPool pool = new ConnectionPool();

©2023 Digital.ai Inc. All rights reserved Page 296


Test Execution

@Override
public HttpClient.Builder builder() {
return new org.openqa.selenium.remote.http.HttpClient.Builder() {
public HttpClient createClient(URL url) {
// configure the proxy
proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxy
Host, proxyPort));

// configure the credentials and register in the builder


Authenticator authenticator = null;
if (proxyUsername != null && proxyPassword != null) {
String credential = Credentials.basic(proxyUsername, proxy
Password);
authenticator = new Authenticator() {
public Request authenticate(Route route, Response resp
onse) throws IOException {
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
}
};
}
OkHttpClient.Builder client = (new OkHttpClient.Builder())
.connectionPool(WebDriverProxyClientFactory.this.pool)
.followRedirects(true)
.followSslRedirects(true)
.proxy(this.proxy)
.readTimeout(this.readTimeout.toMillis(), TimeUnit.MIL
LISECONDS)
.connectTimeout(this.connectionTimeout.toMillis(), Tim
eUnit.MILLISECONDS)
.proxyAuthenticator(authenticator);

return new org.openqa.selenium.remote.internal.OkHttpClient(cl


ient.build(), url);
}
};
}

@Override
public void cleanupIdleClients() {
this.pool.evictAll();
}
}

Running Appium test using proxy:

Example

©2023 Digital.ai Inc. All rights reserved Page 297


Test Execution

static String host = "<env>.experitest.com";


static String accessKey = "<access key>";
static String proxyHost = "<proxy host>";
static int proxyPort = 8080;
static String proxyUser = "user";
static String proxyPassword = "password";

IOSDriver driver = null;


protected DesiredCapabilities dc = new DesiredCapabilities();
@Before
public void setUp() throws Exception{
dc.setCapability("deviceQuery", "@os='ios'");
dc.setCapability("accessKey", accessKey);

dc.setCapability("platformName", "ios");

URL url = new URL("https://" + host + "/wd/hub");

driver = new IOSDriver<IOSElement>(


WebDriverProxyClientFactory.createAppiumExecutor(url, proxyHos
t, proxyPort , proxyUser, proxyPassword), dc);
}

Python client
The code was tested with Appium-Python-Client versions 2.8.1 and 1.3.0

Appium-Python-Client 1.x should be used to run tests on Appium grid and Appium server 1.x

Appium-Python-Client 2.x should be used to run tests on Appium server 1.x ans 2.x

Proxy URL is provided via environment variable.

import os
import unittest
from appium import webdriver

class AppiumTest(unittest.TestCase):
proxyUrl = 'http://10.100.102.6:9090'
cloudUrl = 'https://mycloud.experitest.com/wd/hub'
accessKey = "<access_key>"
dc = {}
driver = None

def setUp(self):
self.dc['accessKey'] = self.accessKey

©2023 Digital.ai Inc. All rights reserved Page 298


Test Execution

self.dc['testName'] = 'Appium Python Proxy test'


self.dc['app'] = 'cloud:com.experitest.ExperiBank/.LoginActivity'
self.dc['appPackage'] = 'com.experitest.ExperiBank'
self.dc['appActivity'] = '.LoginActivity'
self.dc['platformName'] = 'android'
self.dc['appiumVersion'] = '1.22.3'
self.dc['deviceQuery'] = "@os='android'"

os.environ["HTTPS_PROXY"] = self.proxyUrl
self.driver = webdriver.Remote(self.cloudUrl, self.dc)

def testEribank(self):
self.driver.find_element("xpath", "//*[@text='Username']").send_keys('c
ompany')

def tearDown(self):
self.driver.quit()

if __name__ == '__main__':
unittest.main()

Using The File Repository

The File Repository is supported only for Appium Server (Appium Open Source) commands.

To learn how to store and download files from file repository see File Repository Rest API.

Permissions
There are several configurations that define the access to the file repository.

• File repository can be globally enabled or disabled for the cloud (see File Repository).
• File repository can be enabled or disabled for each project (see Project Resources).
• The administrator can prevent users with the "User" role to upload/modify files in the file repository
(see Project Resources).

©2023 Digital.ai Inc. All rights reserved Page 299


Test Execution

Commands
A unique file name must be provided using the "cloud:" prefix.

Commands that Can Use Files From The File Repository

• simulateCapture
• startAudioPlay / stopAudioPlay

The file must exist in file repository before command execution. (You can upload files to file repository using
the File Repository Rest API.)

Use a file unique name in the repository in order to execute a command. For example:

driver.executeScript("seetest:client.simulateCapture", "cloud:my_image");

In this case, my_image is a file unique name in the file repository.

File URL

When a file is provided without the "cloud:" prefix, it is treated as a URL.

driver.executeScript("seetest:client.simulateCapture", "https://myserver.com/m
y_image");

Commands That Produce Files and Store Them in The File Repository

• startAudioRecording / stopAudioRecording
• startHarRecording / stopHarRecording

The file must not exist in file repository before command execution. Otherwise the command fails.

driver.executeScript("seetest:client.startAudioRecording", "cloud:my_audio");
// Commands that play audio on device
driver.executeScript("seetest:client.stopAudioRecording");

Now the file with the unique name my_audio can be downloaded from the file repository using File
Repository Rest API

©2023 Digital.ai Inc. All rights reserved Page 300


Test Execution

Examples
Simulate Capture
// File with unique name my_image must exist in file repository
driver.executeScript("seetest:client.simulateCapture", "cloud:my_image");

Audio Play Commands


// File with unique name my_music must exist in file repository
driver.executeScript("seetest:client.startAudioPlay", "cloud:my_music");
driver.executeScript("seetest:client.stopAudioPlay");

driver.executeScript("seetest:client.startAudioPlay", "cloud:my_music");
driver.executeScript("seetest:client.waitForAudioPlayEnd", "10000");

Audio Recording Commands


// File with unique name my_audio_recording must NOT exist in file repository
driver.executeScript("seetest:client.startAudioRecording", "cloud:my_audio_rec
ording");
// Commands that play audio on device
driver.executeScript("seetest:client.stopAudioRecording");
// Download file with unique name my_audio_recording from file repository using
Rest API

HAR File Recording Commands


// File with unique name my_har_file must NOT exist in file repository
driver.executeScript("seetest:client.startHarRecording", "cloud:my_har_recordi
ng");
// Commands that perform web requests on device
driver.executeScript("seetest:client.stopHarRecording");
// Download file with unique name my_har_recording from file repository using Re
st API

ADB Push File to Device Command


// File with unique name must exist in file repository
// File from repository will be uploaded to provided path on device.
driver.executeScript("seetest:client.pushFile", "path_on_device", "cloud:file_i
n_repo");

©2023 Digital.ai Inc. All rights reserved Page 301


Test Execution

ADB Pull File from Device Command


// File with unique name must NOT exist in file repository
// File downloaded from device will be stored in file repository with given uni
que name.
driver.executeScript("seetest:client.pullFile", "path_on_device", "cloud:file_i
n_repo");

Start/Stop Logging device Command


// File with unique name must not exist in file repository
// Device log file will be uploaded to the provided "log_file_name" on file repos
itory in the 'Stop Logging device command'.
driver.executeScript("seetest:client.startLoggingDevice", "cloud:log_file_name"
);
.
.
.
// Device log file will be uploaded to path on file repository that was provided
on 'Start Logging device command'.
driver.executeScript("seetest:client.stopLoggingDevice");

Appium Multi Region (Mobile)

There is an option to start Appium session using region address.

AndroidDriver driver = new AndroidDriver(new URL("https://ukregion.experitest.


com/wd/hub"), dc);
IOSDriver driver = new IOSDriver(new URL("https://ukregion.experitest.com/wd/h
ub"), dc);

When starting session using region address:

1. Only devices located in provided region can be used.


2. Test execution will be faster since command are executed on region components.

It is still possible to start Appium session using cloud address (same as before 21.10)

AndroidDriver driver = new AndroidDriver(new URL("https://uscloud.experitest.c


om/wd/hub"), dc);
IOSDriver driver = new IOSDriver(new URL("https://uscloud.experitest.com/wd/hu
b"), dc);

When starting session using cloud address:

©2023 Digital.ai Inc. All rights reserved Page 302


Test Execution

1. Devices in all regions can be used.


2. Test execution will be faster for devices located in master region.
3. Test execution will be slower for devices located in remote (other) regions.

Recommendation
For better performance users should choose the cloud region with the lowest latency from client machines
where Appium tests are running.

Regions addresses can be provided by cloud administrator

Architecture
The new architecture has 2 goals:

1. Reduce the load on cloud server.


2. Improve test execution performance on devices in remote regions (when client is located in the same
region).

Appium commands flow (except for starting and ending Appium session)

Address used to Used device Result Appium command flow


create Appium
Driver
Cloud address Device from master Recommended. Better Appium Client → Master region proxy →
region performance. Device Host Machine

Cloud address Device from remote Not recommended. Slower. Appium Client → Master region proxy →
region Cloud server → Remote Region Proxy →
Device Host Machine

Region address Device from the same Recommended. Better Appium Client → Remote region proxy →
region performance. Device Host Machine

©2023 Digital.ai Inc. All rights reserved Page 303


Test Execution

Address used to Used device Result Appium command flow


create Appium
Driver
Region address Device from different Not supported. Device will not
region be found.

Appium Desktop

Appium Desktop is an open-source application for Mac, Windows and Linux. This gives the users the ability
to automate mobile scripts with a flexible UI.
Digital.ai's Continuous Testing integration with Appium Desktop allows you to inspect on real Android and
IOS Devices. The latest Appium Desktop can be downloaded from Appium Desktop Github Page.

This guide will go through how to use Appium Desktop with SeeTest Cloud.

Start the Server


Start up the Appium Desktop Application to bring up the new session window, and start the server
in "Simple" mode.

©2023 Digital.ai Inc. All rights reserved Page 304


Test Execution

Connect to your SeeTest Cloud instance


1) Click on "Start Inspector Session"

©2023 Digital.ai Inc. All rights reserved Page 305


Test Execution

2) From the Cloud Providers, choose "Experitest"

©2023 Digital.ai Inc. All rights reserved Page 306


Test Execution

3) Populate the URL of your Cloud, and Access Key

©2023 Digital.ai Inc. All rights reserved Page 307


Test Execution

Populate the Desired Capabilities


We need to populate the capabilities in order to point the Appium instance to a device we want to work with

Basic iOS Capabilities

automationName - XCUITest
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - iOS
udid - Device Serial Number

©2023 Digital.ai Inc. All rights reserved Page 308


Test Execution

iOS Application Capabilities

To Install & Launch an Application, the following capabilities are required:

app - cloud:<Name of Bundle Identifier>


bundleId - Bundle Identifier of the Application

To simply Launch an Application, the following capabilities are required:

bundleId - Bundle Identifier of the Application

iOS Browser Capabilities

browserName - Safari

Android Basic Capabilities

automationName - UIAutomator2
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - Android
udid - Device Serial Number

©2023 Digital.ai Inc. All rights reserved Page 309


Test Execution

Android Application Capabilities

To Install & Launch an Application, the following capabilities are required:

app - cloud:<Name of AppPackage/appActivity>


appPackage - Package Name of the Application
appActivity - Activity Name of the Application

To simply Launch an Application, the following capabilities are required:

appPackage - Package Name of the Application


appActivity - Activity Name of the Application

©2023 Digital.ai Inc. All rights reserved Page 310


Test Execution

Android Browser Capabilities

browserName - Chrome

Start Session

Once all the necessary Capabilities are populated, we can "Start Session"

That's it, happy testing!

©2023 Digital.ai Inc. All rights reserved Page 311


Test Execution

Appium Inspector

Appium Inspector is a GUI inspector for mobile apps and more, powered by a (separately installed) Appium
server, This gives the users the ability to automate mobile scripts with a flexible UI.

You can connect to a local server or to a cloud.

You have two ways of connecting to SeeTest cloud:

Connect to your Seetest Cloud (Appium server tab)


1. Open the Appium Inspector
2. Click on Appium server tab
3. Add the remote host and the port (no need to add the protocol with the host)
4. Add "/wd/hub" to the remote path
5. Check the SSL check box for secure cloud
6. The accessKey needs to be added as part of the capabilities "experitest:accessKey"

©2023 Digital.ai Inc. All rights reserved Page 312


Test Execution

• You can specify which appium version to use by changing the project version from the cloud or by
adding "appium:appiumVersion" capability with a version that exists in the cloud.

Connect to your SeeTest Cloud instance


1. Open the Appium Inspector
2. Click on Select cloud providers
3. Select Experitest
4. Populate the cloud URL and the AccessKey

©2023 Digital.ai Inc. All rights reserved Page 313


Test Execution

Populate the Desired Capabilities


We need to populate the capabilities in order to point the Appium instance to a device we want to work with.

Appium inspector is expected to work by default with Appium 2.0 which is based on the W3C client, and its
capabilities (W3C capabilities)

so for it to work we need to add the "appium:" prefix to all of appium capabilities we want to use
(appium capabilities)

iOS Basic Capabilities:

automationName - XCUITest
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - iOS
udid - Device Serial Number

©2023 Digital.ai Inc. All rights reserved Page 314


Test Execution

iOS Browser Capabilities:

You need to add to the basic capabilities:

browserName - safari

©2023 Digital.ai Inc. All rights reserved Page 315


Test Execution

iOS Application Capabilities:

You need to add to the basic capabilities:

to Install & Launch an Application, the following capabilities are required:

app - cloud:<Name of Bundle Identifier>


bundleId - Bundle Identifier of the Application

To simply Launch an Application, the following capabilities are required:

bundleId - Bundle Identifier of the Application

Android Basic Capabilities

automationName - UIAutomator2
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - Android
udid - Device Serial Number

©2023 Digital.ai Inc. All rights reserved Page 316


Test Execution

Android Browser Capabilities:

You need to add to the basic capabilities:

browserName - Chrome

Android Application Capabilities:

You need to add to the basic capabilities:

to Install & Launch an Application, the following capabilities are required:

©2023 Digital.ai Inc. All rights reserved Page 317


Test Execution

app - cloud:<Name of AppPackage/appActivity>


appPackage - Package Name of the Application
appActivity - Activity Name of the Application

To simply Launch an Application, the following capabilities are required:

appPackage - Package Name of the Application


appActivity - Activity Name of the Application

You can use this checkbox to add the Appim prefix automatically.

Appium Image Recognition

Appium supports Image Locator Strategy, which relies on the OpenCV library.

©2023 Digital.ai Inc. All rights reserved Page 318


Test Execution

We created a special Appium OSS image (1.22.2.cv) that is based on Appium 1.22.2 version with the
support of the opencv4nodejs library.

With this plugin, you can find elements Native or Web by the image locator, as well as compare and find
similarity between images.

For more information see Image Elements and Image Comparison.

Usage Examples
Gradle Dependency
implementation 'io.appium:java-client:8.3.0'

Example Code for io.appium.java_client:8.3.0


File img = new File(filePath);

String base64EncodedImageFile = Base64.getEncoder().encodeToString(Files.readA


llBytes(img.toPath()));

By imageLocator = AppiumBy.image(base64EncodedImageFile);

WebElement element = driver.findElement(imageLocator);

element.click();

Install the Appium Image


1. From the machine of docker swarm open a terminal and run: docker pull public.ecr.aws/
dai-ct/appium-opensource:1.22.2.cv-6
2. Open the Docker's Portainer and make sure the image is there (instructions are here).

Additional Appium Capabilities Using DigitalAI:Options (Appium 2)

With the release of Appium 2, there have been improvements and additions to test capabilities.

©2023 Digital.ai Inc. All rights reserved Page 319


Test Execution

Protocol Changes
Appium's API is based on the W3C WebDriver Protocol, and it has supported this protocol for years. Before
the W3C WebDriver Protocol was designed as a web standard, several other protocols were used for both
Selenium and Appium. These protocols were JSONWP (JSON Wire Protocol) and MJSONWP (Mobile JSON
Wire Protocol). The W3C Protocol differs from the (M)JSONWP protocols in a few minor ways.

Until Appium 2.0, Appium supported both protocols, so that older Selenium and Appium clients could still
communicate with newer Appium servers. Moving forward, support for older protocols will be removed.

You have these kinds of capabilities:

• Standard W3C capabilities


• Appium vendor capabilities
• Digital.ai vendor capabilities

For more information on migrating from Appium 1.x to 2x see Migrating from Appium 1.x to Appium 2.x.

Standard W3c Capabilites


The Standard W3C capabilities in Appium refer to the set of common capabilities that are recognized and
supported by most WebDriver implementations, including Appium. These capabilities provide a consistent
way to configure and control the WebDriver sessions for different automation frameworks and tools. For a
list of standard capabilities, see WebDriver (w3c.github.io).

Appium Capabilities
One sinificant difference between the old and new protocols is the format of capabilities. Previously called
"desired capabilities", and now called simply "capabilities", there is now a requirement for a "vendor prefix"
on any non-standard capabilities. The list of standard capabilities is given in the WebDriver Protocol spec,
and includes a few commonly used capabilities such as browserName and platformName.

These standard capabilities continue to be used as-is. All other capabilities must include a vendor prefix in
their name. A vendor prefix is a string followed by a colon, such as appium:. Most of Appium's capabilities
go beyond the standard W3C capabilities and must therefore include vendor prefixes. We recommend you
use appium: unless directed otherwise instructed.

For example:

• appium:app
• appium:noReset
• appium:deviceName

©2023 Digital.ai Inc. All rights reserved Page 320


Test Execution

Digital.Ai Vendor Capabilities


All Digital.ai capabilities which supported by Appium OSS are provided by one object which is
called digital.ai:options. The digital.ai capabilities are documented in Appium OSS Supported
Capabilities and Device Setup.

For example, to use Appium 2 you need to set the appiumVersion capability as an option in the object.

Java Capabilities Sample


DesiredCapabilities dc = new DesiredCapabilities();

Map<String, Object> options = new HashMap<>();


options.put("appiumVersion", "2.0.0");
dc.setCapability("digital.ai:options",options);

Code Examples
Java
DesiredCapabilities dc = new DesiredCapabilities();

dc.setCapability("platformName","iOS");
Map<String, Object> digitalaiOptions = new HashMap<>();
digitalaiOptions.put("appiumVersion", "2.0.0");

digitalaiOptions.put("deviceQuery", "@os='ios' and @category='PHONE'");

dc.setCapability("digitalai:options", digitalaiOptions);

Map<String, Object> appiumOptions = new HashMap<>();

appiumOptions.put(MobileCapabilityType.APP, "cloud:com.experitest.ExperiBank")
;

appiumOptions.put(IOSMobileCapabilityType.BUNDLE_ID, "com.experitest.ExperiBan
k");

dc.setCapability("appium:options", appiumOptions);
Python
desired_caps = {

'platformName': 'iOS',

digitalai_options = {

©2023 Digital.ai Inc. All rights reserved Page 321


Test Execution

'appiumVersion': '2.0.0',

'deviceQuery': "@os='ios' and @category='PHONE'",

desired_caps['digitalai:options'] = digitalai_options

appium_options = { 'app': 'cloud:com.experitest.ExperiBank',

'bundleId': 'com.experitest.ExperiBank',

desired_caps['appium:options'] = appium_options
Node.js
capabilities: [{
"platformName" : "android",
'appium:options': {
"appPackage":"com.experitest.ExperiBank"},
'digitalai:options' : {
"appiumVersion" : "2.0.0",
'deviceQuery': "@os='ios' and @category='PHONE'",
},
}

Appium Self-Healing

Digital.ai AI-Powered Self-Healing uses classification AI techniques to understand and repair the element
mismatches autonomously without human intervention. This greatly reduces the time need for automation
maintenance, helping teams focus on increasing coverage. Automated end-to-end tests are affected by
minor UI changes. This reduces the time needed for test maintenance between test runs and enables faster
feedback while increasing test resilience.

Self-Healing is enabled for Native and Web tests in Android, and Web tests in iOS.

To enable Self-Healing:

1. Make sure the feature is enabled by your Cloud Administrator (see Appium Self-Healing Configuration).

2. Use the capability selfHealing and set it to true.

dc.setCapability("selfHealing", true);

©2023 Digital.ai Inc. All rights reserved Page 322


Test Execution

Healed Locators
You can see information about Healed Locators once the test execution finishes in the test Report Page
under Test Data:

• Original Locator

• Healed Locator

• Confidence score: How common are the Healed Locator and the Original Locator. This is a real number
between 0 and 1 (0 and 1 not included). The higher the number is, the more the Healed Locator and
the Original Locator similar.

Grid Clients
• Appium Client
• Java Grid Client
• VBScript Grid Client
• C VUGen Grid Client
• Ruby Grid Client
• Python Grid Client
• Webdriver.io Starter Code
• Getting Started with Grid Clients

Appium Client

You can use any Appium Client test in any language to run tests using SeeTest Cloud Grid.

SeeTest Cloud supports version 4.1 and upwards of JAVA Appium Client.

Note:

©2023 Digital.ai Inc. All rights reserved Page 323


Test Execution

Appium Grid doesn't work with JAVA Appium client 8+ (or similar clients that uses only W3C). If you need to
run Appium Grid use a previous version of the Appium client.
W3C is supported only with Appium Open Source Execution.

Example
Appium Client Test example in JAVA
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("deviceQuery", "@os='android');
dc.setCapability("username", "cloudUsername");
dc.setCapability("password", "cloudPassword");
dc.setCapability("projectName", "cloudProject");

AndroidDriver driver = new AndroidDriver<>(new URL("http://"+cloudHost+":"+clo


udPort), dc);

Capabilties
Capability Name Meaning Mandatory Default
Value
username Name of cloud user with which to execute the test. Yes

password Password of cloud user with which to execute the test. Yes

projectName Name of the project to use. Only if the cloud


user isassociated
with morethan one
project

experitest:accesskey The accessKey of cloud user with which to execute the No


test.This can be used instead of
username&password&projectName.

newSessionWaitTimeout Timeout in seconds to wait when trying to create a new No 300


session.

newCommandTimeout Timeout in seconds to wait between commands. No 60

generateReport Whether to generate a report. No TRUE

experitest:testName Name of the test to be shown in Cloud UI and Report. No Auto-


generated

reservationDuration Time in minutes for which to reserve the device.For a shared No 240 (4 hours)
device this capability is ignored.(Reservation duration is
determined by the share manager.)

takeScreenshots Enable or disable taking screenshots for a No TRUE


report.false improves running performance.

©2023 Digital.ai Inc. All rights reserved Page 324


Test Execution

Authentication
Authentication can be done either via user and password or an accessKey.

The user and password or accessKey can either be passed as part of the capabilities as shown above or
part of the URL.

User and Password


AndroidDriver driver = new AndroidDriver<>(new URL("http://"+user+":"+password
+"@"+host+":"+port+"/wd/hub"), dc);

accessKey
AndroidDriver driver = new AndroidDriver<>(new URL("http://:"+accessKey+"@"+ho
st+":"+port+"/wd/hub"), dc);

Java Grid Client

Examples - Java Grid Execution


SeeTest Client - Using Grid Execution
SeeTest Client - Using Grid Execution
GridClient gridClient = new GridClient("cloudUsername","cloudPassword","cloudP
roject","https://cloud.experitest.com");
Client client = gridClient.lockDeviceForExecution("testname", "@os='android'",
60, TimeUnit.MINUTES.toMillis(2));

Create a new GridClient. Fill in the user credentials, details about the cloud server and the project to log into:

GridClient(String username, String password, String Project, String hostname, int port, boolean
isSecured)

GridClient(String username, String password, String Project, String URL)

Cloud Project

Cloud Admin will always run the test in the "Default" project. Cloud project provided to grid client is not
used.

©2023 Digital.ai Inc. All rights reserved Page 325


Test Execution

User / Project Admin which is assigned to the single project will always run the test in their single project.
Cloud project provided to grid client is not used.

User / Project Admin which is assigned to several projects - must provide cloud project for login. The test
will run in the selected project.

Then use the grid client created to request a device to run your test on with the following command:

Client lockDeviceForExecution(String testName, String deviceXpathQuery, int reservetionTime, long


timeout)

The method can be used with additional parameter releaseDevice

Client lockDeviceForExecution(String testName, String deviceXpathQuery, boolean releaseDevice,


int reservetionTime, long timeout, boolean onlyAvailable)

When releseDevice = true:

• The device is released at the end of the test


• The default value is 'true'

When releseDevice = false:

• keeps the reservation

In case the device is already reserved or uses future reservations when the test starts then releaseDevice
capability will not have any effect and the device will not be released.

When onlyAvailable=true:

• Use only available devices.


• If the method without onlyAvailable parameter is used, the default used is: onlyAvailable=false

When onlyAvailable=false:

• Use devices in the following priority: STAW, manual, reserved, available.

VBScript Grid Client

Examples - VBScript Grid Execution For SeeTest

©2023 Digital.ai Inc. All rights reserved Page 326


Test Execution

SeeTest VBScript Client - Using Grid Execution


Dim gridClient, client

Set gridClient = CreateObject("Experitest.GridVBClient")


gridClient.SetConnectionInfo "cloudUsername", "cloudPassword", "cloudProject",
"cloud.experitest.com", 80, true
Set client = gridClient.LockDeviceForExecution("testname", "@os='android'", 60
, 20000)
'Set a reporter
client.SetReporter "xml", "reports"
.
.
.
'Generate the test report
client.GenerateReport
client.ReleaseClient

Create a new GridClient:

1. Create new object instance of 'Experitest.GridVBClient'.


2. Use the SetConnectionInfo function to configure your running environment. Provide the following
details: user name, user password, project, cloud server URL.

SetConnectionInfo String username, String password, String Project, String hostname, int port,
boolean isSecured

SetURLConnectionInfo String username, String password, String Project, String URL

Then use the grid client created to request a device to run your test on. Do so with the following command:

Client LockDeviceForExecution(String testName, String deviceXpathQuery, int reservetionTime, long


timeout)

If you want to generate a report when the test is finished, you need to set a reporter

SetReporter String report type, String report path

and at the end of the test use GenerateReport

©2023 Digital.ai Inc. All rights reserved Page 327


Test Execution

Registering imageClient.dll
You will need to register imageClient.dll file to be able to run a Grid Test

To register imageClient.dll , run from Command Line these commands :

Make sure to adjust commands if SeeTest Installation Folder is different from the default

In Command Line
"c:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" "C:\Program Files
(x86)\Experitest\SeeTest\clients\C#\imageClient.dll" /codebase
"c:\Windows\Microsoft.NET\Framework64\v4.0.30319\RegAsm.exe" "C:\Program Files
(x86)\Experitest\SeeTest\clients\C#\imageClient.dll"

Or in 32-bit machines :

In Command Line
"c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "C:\Program Files (
x86)\Experitest\SeeTest\clients\C#\imageClient.dll" /codebase
"c:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" "C:\Program Files (
x86)\Experitest\SeeTest\clients\C#\imageClient.dll"

C VUGen Grid Client

Examples - C VUGen Grid Execution For SeeTest

SeeTest C VUGen Client - Using Grid Execution


#include "grid_api.h"

/* Callback which is invoked whenever an ic_... command fails: */


static void exceptionCB(image_client* client)
{
if (client->latest_result.status == IC_INTERNAL_EXCEPTION) {
lr_error_message ("Internal exception of type %s was raised: %s",
client->latest_result.details.internal_exception.caus
e_id,
client->latest_result.details.internal_exception.mess
age);
}

©2023 Digital.ai Inc. All rights reserved Page 328


Test Execution

/* Generates a report of this test case and releases the client so that ot
her clients can approach the agent in the near future: */
/* For more information - https://docs.digital.ai/bundle/TC/page/as-_repor
t_of_executed_test.html */
ic_generate_report(client, IC_TRUE);
lr_abort();
}

/* Callback which is invoked whenever an grid_... command fails: */


static void exceptionGCB(grid_client *grid_client)
{
if (grid_client->latest_result.status == IC_INTERNAL_EXCEPTION) {
lr_error_message ("Internal exception of type %s was raised: %s",
grid_client->latest_result.details.internal_exception
.cause_id,
grid_client->latest_result.details.internal_exception
.message);
}
lr_abort();
}

Action()
{
image_client c = {IC_DONE, NULL, NULL};
grid_client gc = {IC_DONE, NULL, NULL};

lr_load_dll("C:\\Users\\User\\Documents\\VuGen\\Scripts\\CVuser1\\imageCli
ent_C_API.dll");

grid_init(&gc, <user_name>, <password>, <project_name>, "192.168.4.63", 80


, IC_FALSE, &exceptionGCB);
grid_lock_device_for_execution(&gc, &c, <test_name>, <device_query>, 10, 4
0000, &exceptionCB);
.
.
.
ic_release_client(&c);

return 0;
}

Initializing a VUGen Grid Client


A VuGen Grid client handler, i.e., a grid_client object must be initialized prior to accessing its fields or call
commands over it.

This should be done using one of Grid init commands:

©2023 Digital.ai Inc. All rights reserved Page 329


Test Execution

const char *grid_init(grid_client *gridClient, const char * userName, const ch


ar * password, const char * projectName, const char * domain, int port, ic_b
ool isSecured, void(*exception_callback)(struct grid_client_t *))
const char *grid_access_key_init(grid_client *gridClient, const char * accessK
ey, const char * domain, int port, ic_bool isSecured, void(*exception_callback
)(struct grid_client_t *))
const char *grid_url_init(grid_client *gridClient, const char * userName, cons
t char * password, const char * projectName, const char * url, void(*excepti
on_callback)(struct grid_client_t *))
const char *grid_url_access_key_init(grid_client *gridClient, const char * acc
essKey, const char * url, void(*exception_callback)(struct grid_client_t *))

This command initializes the given handler of a VUGen grid client (grid_client *gridClient) and associates it
with a SeeTestCloud Grid execution. The handler must be a pointer to structure grid_client located in a valid
memory area, i.e., grid_init does not allocate memory for the handler.
The last parameter is a pointer to a callback function which will be invoked once a test step fails. The
function is expected to be a void function having a single parameter, which is a pointer to structure
grid_client. Value NULL passed into the parameter means you do not wish to register a callback.

Parameters

• gridClient: The handler to be initialized


• accessKey: See more in Use Access Keys for Authentication.
• userName: Name of cloud user with which to execute the test
• password: Password of cloud user with which to execute the test
• projectName: Name of project to use
• url: URL of cloud user with which to execute the test
• domain: The hostname or the IP-address of the cloud server
• port: The port listened by the cloud server
• isSecured: Is the secure connection to a cloud server
• exception_callback: A pointer to a failure-callback function.

This command, as well as other VUGen-grid client commands, is declared in header grid_api.h, which can
be found in <SeeTestAutomation_installation_directory>/clients/vugen/grid_api.h.

Initializing A VUGen Grid Execution Client


A VuGen Grid Execution client handler, i.e., an image_client object must be initialized prior you access its
fields or call commands over it.

This should be done using command grid_lock_device_for_execution:

©2023 Digital.ai Inc. All rights reserved Page 330


Test Execution

const char *grid_lock_device_for_execution(grid_client *gridClient, image_cli


ent *client, const char * testName, const char * deviceQuery, int reservationT
imeInMinutes, long long timeout, void(*exception_callback)(struct image_client
_t *))

This command initializes the given handler of a VUGen grid execution client (image_client *client) and
associates it with a SeeTestCloud Grid execution node. The handler must be a pointer to
structure grid_client located in a valid memory area, i.e., grid_lock_device_for_execution does not allocate
memory for the handler.
The last parameter is a pointer to a callback function which will be invoked once a test step fails. The
function is expected to be a void function having a single parameter, which is a pointer to structure
image_client. Value NULL passed into the parameter means you do not wish to register a callback.

Parameters

• gridClient: The handler to be grid client


• Client: The handler to be initialized
• testName: Name of the test to be shown in Cloud UI and Report
• deviceQuery: XPath Search query to look up devices for test execution. More info can be found in the
documentation.
• reservationTimeInMinutes: Name of the test to be shown in Cloud UI and Report
• timeout: Timeout in milliseconds to wait for an available device according to the search query.
• exception_callback: A pointer to a failure-callback function.

This command, as well as other VUGen-grid client commands, is declared in header grid_api.h, which can
be found in <installation_directory>/clients/vugen/grid_api.h.

Ruby Grid Client

Examples - Ruby Grid Execution For SeeTest

SeeTest Ruby Client - Using Grid Execution


require './grid_client'

begin
grid = Mobile::GridClient.new_client_url("cloudUsername", "cloudPasswo
rd", "cloudProject", "https://cloud.experitest.com")

©2023 Digital.ai Inc. All rights reserved Page 331


Test Execution

client = grid.lockDeviceForExecution("testname","@os='android'", 60, 2


0000, true, false)
.
.
.
client.releaseClient
end

Create a new GridClient. Fill in the user credentials, details about the cloud server and the project to log into:

Mobile::GridClient.new_client(userName, password, projectName, domain, port,


isSecured)
Mobile::GridClient.new_client_access_key(accessKey, domain, port, isSecured)
Mobile::GridClient.new_client_url(userName, password, projectName, url)
Mobile::GridClient.new_client_url_access_key(accessKey, url)

Parameters

• userName: Name of cloud user with which to execute the test


• password: Password of cloud user with which to execute the test
• projectName: Name of the project to use
• accessKey: See more in Use Access Keys for Authentication.
• domain: The hostname or the IP-address of the cloud server
• port: The port listened by the cloud server
• isSecured: Is a secure connection to the cloud server
• URL: URL of cloud user with which to execute the test

Then use the grid client created to request a device to run your test on with the following command:

grid.lockDeviceForExecution(testName, deviceXpathQuery, reservetionTime,


timeout, releaseDevice, onlyAvailable)

Parameters

• testName: Name of the test to be shown in Cloud UI and Report (string)


• deviceQuery: XPath Search query to look up devices for test execution. More info can be found in the
documentation. (string)
• reservationTimeInMinutes: Reservation time in minutes. (integer)
• timeout: Timeout in milliseconds to wait for an available device according to the search query. (long)

©2023 Digital.ai Inc. All rights reserved Page 332


Test Execution

• releaseDevice: (boolean):
◦ Gives the capability to not release a device after the test ends.
◦ default value is 'true' .
◦ In case the device is already reserved or uses future reservations when the test starts then
releaseDevice capability will not have any effect and the device will not be released.
• onlyAvailable: (boolean)

◦ When onlyAvailable=true:

◦ Use only available devices.


◦ If the method without onlyAvailable parameter is used, the default used
is: onlyAvailable=false

◦ When onlyAvailable=false:

◦ Use devices in the following priority: STAW, manual, reserved, available.

Ruby requirements:

Ruby version 2.4 and above.

Gems: rubyzip, rest-client -v 1.8.0

Python Grid Client

Examples - Python Grid Execution For SeeTest

SeeTest Python Client - Using Grid Execution


import grid_client

grid = grid_client.GridClient.new_client_url("cloudUsername", "cloudPassword",


"cloudProject", "https://cloud.experitest.com")
client = grid.lockDeviceForExecution('testname', "@os='android'", 60, 20000)
.
.
.
client.releaseClient()

©2023 Digital.ai Inc. All rights reserved Page 333


Test Execution

Create a new GridClient. Fill in the user credentials, details about the cloud server and the project to log into:

GridClient.new_client(userName, password, projectName, domain, port,


isSecured)
GridClient.new_client_access_key(accessKey, domain, port, isSecured)
GridClient.new_client_url(userName, password, projectName, url)
GridClient.new_client_url_access_key(accessKey, url)

Parameters

• userName: Name of cloud user with which to execute the test


• password: Password of cloud user with which to execute the test
• projectName: Name of the project to use
• accessKey: See more in Use Access Keys for Authentication.
• domain: The hostname or the IP-address of the cloud server
• port: The port listened by the cloud server
• isSecured: Is secure connection the o cloud server
• url: URL of cloud user with which to execute the test

Then use the grid client created to request a device to run your test on with the following command:

Client lockDeviceForExecution(String testName, String deviceQuery, int reservetionTimeInMinutes,


long timeout)

Parameters

• testName: Name of the test to be shown in Cloud UI and Report


• deviceQuery: XPath Search query to look up devices for test execution. More info can be found in the
documentation.
• reservationTimeInMinutes: Name of the test to be shown in Cloud UI and Report
• timeout: Timeout in milliseconds to wait for an available device according to the search query.

Python requirements:

Python version 3.x.

packages: requests

©2023 Digital.ai Inc. All rights reserved Page 334


Test Execution

Webdriver.io Starter Code

You can use any Webdriver.io test framework to run tests using Continuous Testing Cloud.
After setup local environment, you can easily integrate your test with the Cloud by using this config file.

Webdriver.io config file example

exports.config = {
runner: 'local',
hostname: 'cloud.experitest.com',
protocol: 'https',
port: 443,
path: '/wd/hub',

specs: [
'./*.js'
],
capabilities: [{
'experitest:accessKey': '<ACCESS_KEY>', //Or userName, password and projectName if needed
platformName: 'android',
'appium:udid': '<Device-Udid>', //Optional
'appium:appiumVersion': '1.22.2',
'experitest:testName': 'Appium WebdriverIO native test', //Optional
}],
mochaOpts: {
ui: 'bdd',
timeout: 60000
},
}

• In order to use Continuous Testing additional capabilities, you should use the following format:

'experitest:testName' : 'here is the test name',

• In order to use Appium capabilities, you should use the following format:

'appium:udid' : 'Device ID',

The following capabilities can be used when creating the Driver:

Capability Name Meaning Mandatory Default


Value
username Name of cloud user with which to execute the test Yes

password Password of cloud user with which to execute the test Yes

projectName Name of the project to use Only if the cloud


user isassociated

©2023 Digital.ai Inc. All rights reserved Page 335


Test Execution

Capability Name Meaning Mandatory Default


Value
with morethan one
project

accessKey The accessKey of cloud user with which to execute the No


test.This can be used instead of
username&password&projectName

newSessionWaitTimeout Timeout in seconds to wait when trying to create a new No 300


session

newCommandTimeout Timeout in seconds to wait between commands No 60

generateReport Whether to generate a report or not No TRUE

testName Name of the test to be shown in Cloud UI and Report No Auto-


generated

reservationDuration Time in minutes for which to reserve the device No 240 (4 hours)

takeScreenshots Enable or disable taking screenshots for a reportfalse will No TRUE


improve running performances

platformName iOS/Android Yes

Getting Started with Grid Clients

Users can see first hand how our system works, what is required in terms of code and capabilities.

Users have the option to run sample tests on either native or web applications and they can do so with a
combination of languages and frameworks,

and see the result within 5 minutes.

Page Navigation
Click on the 'Automation' button in the main navigation bar.

©2023 Digital.ai Inc. All rights reserved Page 336


Test Execution

Select Mobile/Web mode


The user is able to select Mobile or Browser mode.

©2023 Digital.ai Inc. All rights reserved Page 337


Test Execution

Mobile Mode configuration

Configuration for Mobile Mode:

• OS - iOS/Android
• Phone Platform - Phone/Tablet
• App Type - Native/Web
• Version - available versions

©2023 Digital.ai Inc. All rights reserved Page 338


Test Execution

Web Mode configuration

Configuration for Web Mode:

• Browser Type - Chrome/Safari/Firefox/IE


• Version - available versions
• Desktop OS - available OS

Code Export
The User is able to view the demo code that matches his configuration and his user profile,

and able to select the code language, test framework, and test dependencies.

The button "copy to clipboard" is for copying the script in the Code Export dialog so that the user can paste
the code and run it locally on their IDE.

©2023 Digital.ai Inc. All rights reserved Page 339


Test Execution

Test Execution
Run a demo test with the user configuration.

The scripts for mobile native include the installation of the EriBank Application

• Android - com.experitest.ExperiBank/.LoginActivity

©2023 Digital.ai Inc. All rights reserved Page 340


Test Execution

• iOS - com.experitest.ExperiBank

If the application is not on the user project, there will be a popup dialog requesting permission to upload the
application to the user project

If the user clicks on the 'OK' button, the application will be uploaded to the user's project and the test will be
executed.

If the application is already on the user project, the test will be executed immediately.

The User can see the test running on "Execution" page.

Test Result
The user can see the test flow and it results in the navigation bar.

©2023 Digital.ai Inc. All rights reserved Page 341


Test Execution

And see the report in "Reports" page (provided the reporter is configured).

XCUITest and Espresso


Continuous Testing platform supports the execution of tests created with XCUITest (iOS) and Espresso
(Android) on real devices, simulators, and emulators.

©2023 Digital.ai Inc. All rights reserved Page 342


Test Execution

Test execution is handled via the creation of "Test Execution Plans"

• Execution Plan using XCUITest


• Execution Plan using Espresso
• Manage Test Run with the API
• Manage Test Run with Cucumberish
• Manage Test Run with Cucumber-jvm
• Manage Test Run with Flutter Integration tests

Execution Plan using XCUITest


Before you proceed following the instructions in this section, please make sure that your environment corresponds to
system requirements.

Execution Plans are groups for test requests that can be executed using a cloud server. Execution Plan
allows you to create, manage and run groups of test requests in an easy to work with the interface. Since the
Execution Plan is integrated with other Continuous Testing tools (for example the Test Analytics Client), it
allows you to have more control over the execution of tests and the management and analysis of test results.
The main goal of the Execution Plan with XCTest is to allow the developer and tester to run bulk test
requests.

It involves creating bundles of apps and tests that are paired and uploaded together when creating Execution
Plans.

XCUITest Plan Execution - System


Requirements
In order to be able to create and run XCUITest bundles using plan execution, the following requirements
must be met:

1. The agent hosting the device the tests will run on must be Mac machine.
2. Xcode must be installed on the agent, preferably the latest version but nothing below Xcode 8.

©2023 Digital.ai Inc. All rights reserved Page 343


Test Execution

3. Command Line Tools - To verify that you have Command Line Tools installed: Xcode → Preferences:

4. The agent's OS must be Sierra.


5. The tests can only be executed on devices running iOS 9 and above

When a device is connected to the device hosting machine, we run tests to ensure that system requirements
are met. Among the various verifications we perform is an SDK check, as well as the presence of the latest
Xcode and build.

However, if the device has just been added to the hosting machine, it is recommended that you check that
the device was properly recognized by Xcode. Xcode might fail to recognize the device if discrepancies arise
in SDK version and device symbols. If you attempted to to execute test plans on devices that have yet to be
recognized by Xcode, the test would fail to run.

in Xcode, go to Window → Devices. The device that you connected should appear there without any
warnings:

©2023 Digital.ai Inc. All rights reserved Page 344


Test Execution

Preparing your App and Test Bundles


Creating App and Test Bundles
It is the developer's responsibility to create paired bundles, one being the app bundle and the other being the
XCUITest bundle. These will, later on, be uploaded to cloud to make for a single execution plan. To do so, in
Xcode, the developer must first build the and create the bundles out of the targets of both app and XCUITest.
On the right-hand, you can see the targets section in Xcode where the targets are located and where the
build process is triggered to create the bundles.

©2023 Digital.ai Inc. All rights reserved Page 345


Test Execution

Target Screen Containing Both App and Test

Building the App and Test Bundles


Before you can build the two bundles, you have to make sure that you have properly configured your signing
identity. Otherwise, the build will fail. Also, you can run the test locally to see that it passes and the test
process will create the bundles. This is recommended when first creating the bundles, you can later on just
build the bundles without running the tests.

You can choose one of two ways, through Xcode's GUI or through CLI.

Testing and Building with Xcode GUI

When you have your app and test ready to go, choose a device (simulator or physical device) to run the test
on: Product → Test. This will build the app, deploy it on a device and run the test.

©2023 Digital.ai Inc. All rights reserved Page 346


Test Execution

Testing and Building with CLI

If you are more CLI inclined, you can build the targets from the terminal. In the terminal, navigate to the
folder where the .xcodproj project is located. Then run the following command:

xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp -destination 'pl


atform=<PLATFORM>,name=<DEVICE_NAME>,OS=<OS>'

Some examples:
> xcodebuild test -project MyAppProject.xcodeproj -scheme MyApp
-destination 'platform=OS X,arch=x86_64'
-destination 'platform=iOS,name=Development iPod touch'
-destination 'platform=Simulator,name=iPhone,OS=9.0

For more information, visit's Apple's support page on the subject.

At the end of the test run, two bundles will be created in the DerivedData folder (see the screenshost in the
section below for more information). To find the two bundles in the DerivedData folder: DerivedData/
<your_app>/Build/Products/Debug-<device_test_ran_on>

Building Only with Xcode GUI

In Xcode, click on Product → Build For → Testing.

To find the two bundles in the DerivedData folder: DerivedData/<your_app>/Build/Products/Debug-


<device_test_ran_on>

Building Only with CLI

To build using CLI, navigate to the folder where the project is located and run the following:

xcodebuild -scheme <scheme> build-for-testing

If you do not specify the build directory, the bundles will be created in the folder DerivedData/<your_app>/
Build/Products/Debug-iphoneos

If you do not want to sign the app, or you don't have a signing identity, run the same command with these
additional flags:

xcodebuild -target <app_target_name> -target <test_target_name> build CODE_SIG


N_IDNETITY="" CODE_SIGNING_REQUIRED=NO CONFIGURATION_BUILD_DIR="dir/for/build"

©2023 Digital.ai Inc. All rights reserved Page 347


Test Execution

Choose Device to Run the Test on

©2023 Digital.ai Inc. All rights reserved Page 348


Test Execution

Derived Data Folder Containing Both Bundles

Creating an App .ipa file and Zipping the Test Bundle


Once the app and test bundles have been built using Xcode, look for them in the folder Derived Data or in
the folder where you set them to be created. To find the location of the Derived Data, click on Xcode →
Preferences → Locations. Under Derived Data, find the location of the bundles that you built and navigate to
it. Both bundles will be there under DerivedData/<your_app>/Build/Products/Debug-
<device_test_run_on> with the extension .app, although they will later on be treated differently.

Now that you have both the app and test bundles, create a .ipa file from the one and zip the other. These
files will be uploaded to the cloud when creating an execution plan.

©2023 Digital.ai Inc. All rights reserved Page 349


Test Execution

Create an App .ipa file

After you ran the test and built the app and test bundles, archive the app. To archive the app, go to the target
screen (see first screenshot in this entry). Select the app target and archive it: in Xcode click on Product→
Archive. Then, look for it in the Organizer: in Xcode, click on Window → Organizer. In the organizer, select
the app and click on "Export" → Save for Ad Hoc Deployment. Once the export process is complete, look for
the .ipa file under the folder you chose at the end of the export process.

Alternatively, you can navigate to the folder where the app bundle is located. Add there a .sh (shell script file)
with the following script:

#!/bin/bash
if [ -d "Payload" ]; then
rm -fr Payload/*
else
mkdir Payload fi # if you'd rather copy the .app file, then replace the n
ext line with:
# cp -r $1 Payload
mv $1 Payload
zip -r $2.ipa Payload
rm -fr Payload

Run the shell script with the parameters .app file, name of the output .ipa:

script.sh your_app.app the_app_name #(there is no need to add .ipa in the seco


nd parameter)

Zipping the Test Bundle

In folder where the test bundle is located look for the test bundle (will usually end with -Runner). Right-click
on it and choose "compress".

You now have both the .ipa and the zipped test bundle and you are ready to execute tests.

©2023 Digital.ai Inc. All rights reserved Page 350


Test Execution

Archive View - Export App to .ipa

Execution Plan using Espresso

Android Studio allows you to construct and run Espresso based tests in order to test your Android app. You
can now leverage these tests by creating Execution Plans out of them. All you have to do is retrieve the
app's .apk and the test's .apk files, upload them to the cloud and create an Execution Plan that you can run
on consecutively on multiple devices in the cloud.

©2023 Digital.ai Inc. All rights reserved Page 351


Test Execution

The process of creating the tests, uploading them to the cloud and running the Execution Plan is fairly simple
and straightforward. Follow the instructions below to create and run your Execution Plans using Espresso
and the Grid:

• Preparing your App and Test .apk Files

Preparing your App and Test .apk Files


This section assumes that you have a fully working Android application from a fully configured Android
project.

The first thing you should do is create some tests for your app. To do so, you can simply use Android
Studio's Built-in Test Recorder:

In Android Studio, click on Run → Record Espresso Test.

Record Espresso Test

Select a device to test on.

This will install and launch the app on the device.

©2023 Digital.ai Inc. All rights reserved Page 352


Test Execution

Select a Device

Interact with the app in order for the steps to be recorded

When you are done, click on OK and give the test class a name that reflects the test.

You should end up with a test class that looks like the one appearing in the screenshot below:

©2023 Digital.ai Inc. All rights reserved Page 353


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 354


Test Execution

Record the Steps

©2023 Digital.ai Inc. All rights reserved Page 355


Test Execution

Now that you have some test classes, you are ready to bundle them as .apk. Since Android Studio is using
Gradle, you can run the following commands in the terminal to create the .apk files for both your app and the
test classes:

To create a .apk file for the app

In the terminal run the following command:

gradlew assembleDebug

Alternatively, you can build the .apk using Android Studio's GUI: Click on Build → Build APK.

To create a .apk file for the test classes

In the terminal run the following command:

gradlew assembleAndroidTest

Find both .apk files under your project folder: <project-folder>\build\outputs\apk. In the apk folder you will find
two files:

• app-debug.apk
• app-debug-androidTest.apk

These are the files that you will upload to the cloud when you create your Execution Plan.

Manage Test Run with the API

Continuous Testing Cloud exposes Rest APIs to execute Espresso and XCUI based Tests.

This page provides the details of the API.

The role of the user performing the Rest Operation is specified by the Authorization header.

For more information please visit How To Execute Rest API, for a detailed example.

All actions are also available for project admins and users

©2023 Digital.ai Inc. All rights reserved Page 356


Test Execution

Status of the API Run


This API enabled us to get the status of the Espresso/XCUI test run.

GET /api/v1/test-run/{id}/status

Where id is Test run id.

Response
Response Status: 200 OK
[
{
"status": "SUCCESS",
"data": {
"Test Run Id": "3520316",
"Test Run State": "Finished",
"Number of tests in file" : "11",
"Number of requested tests" : "11",
"Total number of tests": "11",
"Number of passed tests": "3",
"Number of failed tests": "8",
"Number of skipped tests": "0",
"Number of running tests": "0",
"Number of queued tests": "0",
"Number of ignored tests" : "0",
"Link to Reporter": "https://CLOUD_SERVER/reporter/reporter/tes
ts?testView={%22byKey%22:%22test.run.id%22,%22byKeyValue%22:%223520316%22}"
},
"code": "OK"
}
]

Number of tests in file - the number of tests in the uploaded file

Number of requested tests - the number of tests that were selected for execution after
applying includeTests / ignoreTestFile.

"Number of skipped tests" - tests that were not executed because of timeout/cancellation.

"Number of ignored tests" - tests that were not executed because they were ignored by the user
(ignoreTestFile parameter)

Running Async Espresso/XCUITest


Enables users to run Espresso or XCUITest asynchronously, the response received is immediate.

©2023 Digital.ai Inc. All rights reserved Page 357


Test Execution

POST /api/v1/test-run/execute-test-run-async

Parameters

Name Type Mandatory Description


executionType String Yes Specified if it is Espresso or XCUITest

runningType String Yes coverage / fastFeedback

1. Coverage - all of the tests will be executed on all of the selected


devices.

2. Fast feedback - all of the tests will be spread across the selected
devices.

app File Yes (either app or The application is under test.


appUrl
appUrl String or CloudApp) The URL location of the application is under test.

cloudApp Long The ID of the application saved in cloud application service

testApp File Yes espresso / XCUI tests(.zip extension only).


(either testApp or
testAppUrl String testAppUrl or The URL Location of espresso / XCUI tests. (.zip extension only)
CloudTestApp)
cloudTestApp Long The ID of the test app saved in cloud file repository service

deviceQueries String No For coverage mode:List of strings (XPath queries). The test run should
run on devices that match provided queries (device per query).Multiple
queries should be passed in the standard way by repeating the
parameter multiple times.For Fast Feedback:Only one device query
must be provided on the list.The number of devices used is decided by
maxDevices and minDevices parameters.If the maxDevices parameter is
not provided then the execution will try to reserve the maximum number
of devices according to license restriction.It is recommended to use
maxDevices parameter always

uuid String No Provision profile UUID to sign the Application and the test
application.Relevant to iOS execution-only

runTags String No Map as JSON - wanted tags to upload to the reporter.

overallTimeout Long No The number of milliseconds. Timeout for the overall test run. If not
provided - default value (14,400,000) - 4 hours - should be used.

creationTimeout Long No The number of milliseconds. Timeout for test requests in queued status. If
not provided - default value (14,400,000) - 4 hours - should be used.

reservationDuration Long No The reservation time of each session in minutes.The default time is 120
minutes

• the reservationTime cannot exceed the max reservation time


configured for the cloud or project.

©2023 Digital.ai Inc. All rights reserved Page 358


Test Execution

Name Type Mandatory Description


includeTests List of No Run only the specified tests. The supported formats:
Strings

• fullClassName, methodName

• fullClassName.methodName

• fullClassName

• methodName

• packageName

For cucumber/Cucumberish tags, run only the matching tags. Each tag
will be provided separately:

• @tag1

• @tag2

ignoreTestFile File No

This file specifies the tests to exclude.


iOS

• xcscheme file

Android

• the file containing full class and method name, separated with comma,
e.g.

com.example.app.SomeTest, testFoo
com.example.app.AnotherTest, testBar

maxDevices Integer No The maximum number of devices to use during the execution. default
value - max available devices license.Note: Only use in case of
fastFeedback

minDevices Integer No The minimum number of devices to use during the execution. Default
value - 1.Note: Only use in case of fastFeedback

retry Integer No

©2023 Digital.ai Inc. All rights reserved Page 359


Test Execution

Name Type Mandatory Description

An integer from 0 to 5 -
Specifies how many times failed test should be retried
Default Value - 0 (means no retry)

additionalAppIds List of No List of application ids that should be installed on the device/emulator
Longs before starting the Espresso/XCUI test.Application id is returned when
uploading application with Rest API or using the Get Applications REST
API.

retryDifferentDevice boolean No A boolean value specifies whether or not to run a failed test on different
devices according to the "retry" value.Default Value - false (means will
not try to run a failed test on different devices).If "maxDevices" is
specified, then "retry" might be limited to the min between ("maxDevices"
- 1) and "retry".

useUIAutomator boolean No For Android only


A boolean value decides whether or not to disable Continuous Testing's
UIAutomator.
Default Value = false - UIAutomator will not be disabled.
True - UiAutomator will be disabled on Test Start and will be enabled after
it ends

useTestOrchestrator boolean No For Android only


A boolean value decides whether or not to run the test in Test
Orchestrator Mode.
Default Value = false - test will not run in Test Orchestrator Mode
true - test will run in Test Orchestrator Mode

clearPackageData boolean No For Android only


If useTestOrchestrator is true, then clearPackageData makes sure to
remove all shared states from the device's CPU and memory after each
test.
Default Value = false - don't clear shared state data
true - clear shared state data

Response
{
"status": "SUCCESS",
"data": {
"Test Run Id": "3520546",
"Link to Reporter": "https://CLOUD_SERVER/reporter/reporter/tests?test
View={%22byKey%22:%22test.run.id%22,%22byKeyValue%22:%223520546%22}"
},
"code": "OK"
}

Running Sync Espresso/XCUITest


Enables users to run Espresso or XCUITest synchronously, the response received is after the test run.

POST /api/v1/test-run/execute-test-run

Parameters

©2023 Digital.ai Inc. All rights reserved Page 360


Test Execution

Name Type Mandatory Description


executionType String Yes Specified if it is Espresso or XCUITest

runningType String Yes coverage / fastFeedback

1. Coverage - all of the tests will be executed on all of the


selected devices.

2. Fast feedback - all of the tests will be spread across the


selected devices.

app File Yes (either app or Application under test


appUrl or cloudApp)
appUrl String The URL location of the application is under test.

cloudApp Long The ID of the application saved in cloud application service

testApp File Yes (either testApp or espresso / XCUI tests.


testAppUrl or cloudTestApp)
testAppUrl String The URL Location of espresso / XCUI tests(.zip extension
only).

cloudTestApp Long The ID of the test app saved in cloud file repository service

deviceQueries String Yes For coverage mode:List of strings (XPath queries). The
test run should run on devices that match provided queries
(device per query). Multiple queries should be passed in the
standard way by repeating the parameter multiple times.For
Fast Feedback:Only one device query must be provided on
the list.The number of devices used is decided by
maxDevices and minDevices parameters.If the maxDevices
parameter is not provided then the execution will try to
reserve the maximum number of devices according to license
restriction.It is recommended to use maxDevices
parameter always

uuid String No Provision profile UUID to sign the Application and the test
application.

runTags String No Map as JSON - wanted tags to upload to the reporter.

overallTimeout Long No The number of milliseconds. Timeout for the overall test run.
If not provided - default value (14,400,000) - 4 hours - should
be used.

creationTimeout Long No The number of milliseconds. Timeout for test requests in


queued status. If not provided - default value (14,400,000) - 4
hours - should be used.

reservationDuration Long No The reservation time of each session in minutes.The default


time is 120 minutes

• the reservationTime cannot exceed the max reservation


time configured for the cloud or project.

©2023 Digital.ai Inc. All rights reserved Page 361


Test Execution

Name Type Mandatory Description


includeTests List of No Run only the specified tests. If no matching tests were found
Strings an error is reported. The supported formats:

• fullClassName, methodName

• fullClassName.methodName

• fullClassName

• methodName

• packageName

For cucumber tags, run only the matching tags. Each tag will
be provided separately:

• @tag1

• @tag2

ignoreTestFile File No

This file specifies the tests to exclude.


iOS

• xcscheme file

Android

• the file containing full class and method name, separated


with comma, e.g.

com.example.app.SomeTest, testFoo
com.example.app.AnotherTest, testBar

maxDevices Integer No The maximum number of devices to use during the


execution. default value - max available devices
license.Note: Only use in case of fastFeedback

minDevices Integer No The minimum number of devices to use during the execution.
Default value - 1.Note: Only use in case of fastFeedback

©2023 Digital.ai Inc. All rights reserved Page 362


Test Execution

Name Type Mandatory Description


retry Integer No An integer from 0 to 5 - Specifies how many times failed test
should be retriedDefault Value - 0 (means no retry)

additionalAppIds List No List of application ids that should be installed on the device/
emulator before starting the Espresso/XCUI test.Application
id is returned when uploading the application with Rest API.

retryDifferentDevice boolean No A boolean value specifies whether or not to run a failed test
on different devices according to the "retry" value.Default
Value - false (means will not try to run a failed test on
different devices).If "maxDevices" is specified, then "retry"
might be limited to the min between ("maxDevices" - 1) and
"retry".

useUIAutomator boolean No For Android only


A boolean value decides whether or not to disable
Continuous Testing's UIAutomator.
Default Value = false - UIAutomator will not be disabled.
True - UiAutomator will be disabled on Test Start and will be
enabled after it ends

useTestOrchestrator boolean No For Android only


A boolean value decides whether or not to run the test in Test
Orchestrator Mode.
Default Value = false - test will not run in Test Orchestrator
Mode
true - test will run in Test Orchestrator Mode

clearPackageData boolean No For Android only


If useTestOrchestrator is true, then clearPackageData makes
sure to remove all shared states from the device's CPU and
memory after each test.
Default Value = false - don't clear shared state data
true - clear shared state data

Response
{
"status": "SUCCESS",
"data": {
"Test Run Id": "3520409",
"Test Run State": "Finished",
"Number of tests in file" : "11",
"Number of requested tests" : "11",
"Total number of tests": "11",
"Number of passed tests": "3",
"Number of failed tests": "8",
"Number of skipped tests": "0",
"Number of running tests": "0",
"Number of queued tests": "0",
"Link to Reporter": "https://CLOUD_SERVER/reporter/reporter/tests?testView
={%22byKey%22:%22test.run.id%22,%22byKeyValue%22:%223520409%22}"
},
"code": "OK"
}

©2023 Digital.ai Inc. All rights reserved Page 363


Test Execution

Cancel all tests of the executed suite


Cancel all tests of the executed suit.

POST /api/v1/test-run/{id}/cancel

Where id is Test run id.

Java Code Examples


The examples below using the Unirest HTTP library. To compile then use the following dependencies in your
Java Project.

Maven dependency:

<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

Gradle dependency:

dependencies {
compile group: 'com.mashape.unirest', name: 'unirest-java', version: '1
.4.9'
}

Following are the code examples:

executeTestRunAsync
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.File;
import org.junit.Test;

public class ExecuteTestRunAsync {

String urlBase = "http://cloudHost:cloudPort"; // modify hostname and port


as applicable your environment
String user = "admin";
String password = "password"; // modify the admin password as applicable y
our environment

©2023 Digital.ai Inc. All rights reserved Page 364


Test Execution

String url = urlBase + "/api/v1/test-run/execute-test-run-async";


String pathToTestApp = "pathtoTestApp"; // path to XcuiTests or espresso t
ests
String pathToApp = "pathToFIle";

@Test
public void executeTestRunAsync() throws UnirestException {
File app = new File(pathToApp);
File testApp = new File(pathToTestApp);
HttpResponse<String> response = Unirest.post(url)
.basicAuth(user, password)
.queryString("executionType", "espresso")
.queryString("runningType", "coverage")
.queryString("deviceQueries", "@os='android'") // can b
e repeated if multiple queries
.field("app", app)
.field("testApp", testApp)
.asString();
System.out.println(response.getBody());
}
}

executeTestRun
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import java.io.File;
import org.junit.Test;

public class ExecuteTestRun {

String urlBase = "http://cloudHost:cloudPort"; // modify hostname and port


as applicable your environment
String user = "admin";
String password = "password"; // modify the admin password as applicable y
our environment
String url = urlBase + "/api/v1/test-run/execute-test-run";
String pathToTestApp = "pathtoTestApp"; // path to XcuiTests or espresso t
ests
String pathToApp = "pathToFIle";

@Test
public void executeTestRun() throws UnirestException {
File app = new File(pathToApp);
File testApp = new File(pathToTestApp);
Unirest.setTimeouts(0, 0); //set infinity timeout for post reque
st

©2023 Digital.ai Inc. All rights reserved Page 365


Test Execution

HttpResponse<String> response = Unirest.post(url)


.basicAuth(user, password)
.queryString("executionType", "espresso")
.queryString("runningType", "coverage")
.queryString("deviceQueries", "@os='android'") // can b
e repeated if multiple queries
.field("app", app)
.field("testApp", testApp)
.asString();
System.out.println(response.getBody());
}
}

cancelTestRun
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.junit.Test;

public class TestRun {


String urlBase = "http://cloudHost:cloudPort"; // modify hostname and po
rt as applicable your environment
String user = "admin";
String password = "password"; // modify the admin password as applicable
your environment
Long testRunId = testRunId; // need to put here the test run id
String url = urlBase + "/api/v1/test-run/" + testRunId +"/cancel";

@Test
public void cancelTestRun() throws UnirestException {

HttpResponse<String> response = Unirest.get(url)


.basicAuth(user, password)
.asString();

System.out.println(response.getBody());

getTestRunStatus
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

©2023 Digital.ai Inc. All rights reserved Page 366


Test Execution

import com.mashape.unirest.http.exceptions.UnirestException;
import org.junit.Test;

public class TestRun {


String urlBase = "http://cloudHost:cloudPort"; // modify hostname and po
rt as applicable your environment
String user = "admin";
String password = "password"; // modify the admin password as applicable
your environment
Long testRunId = testRunId; // need to put here the test run id
String url = urlBase + "/api/v1/test-run/" + testRunId +"/status";

@Test
public void getTestRunStatus() throws UnirestException {

HttpResponse<String> response = Unirest.get(url)


.basicAuth(user, password)
.asString();

System.out.println(response.getBody());

cURL Command
curl "https://Cloud_URL/api/v1/test-run/execute-test-run-async?deviceQueries=@
os='android'" -H "Authorization: Basic YOUR_CREDENTIALS" -F "executionType=esp
resso" -F "runningType=coverage" -F "app=@APP_PATH" -F "testApp=@TEST_APP_PATH
"

# here "deviceQueries" parameter is passed via query string, as it contains "@


", which curl treats as a file name indicator.
# multiple device queries can be specified by adding the parameter multiple tim
es: "https://Cloud_URL/api/v1/test-run/execute-test-run-async?deviceQueries=..
.&deviceQueries=...".
# if device query contains special characters (e.g. spaces) they should be URL
encoded.

Manage Test Run with Cucumberish

Running Cucumberish features with API uses the same parameters as XCUITest and Espresso with few
behavioral differences as follows:

• Cucumberish scenario is analogous to Test and Cucumberish feature is analogous to suite.

©2023 Digital.ai Inc. All rights reserved Page 367


Test Execution

• You can use includeTests parameter to run specify Tags to be included (analogous to includeTags in
Cucumberish)

• Please note not to change the default Cucumberish framework configurations, especially
not featureNamesPrefix and pretty*NamesAllowed since it's not supported.

• In order that specified tags in includeTests work as expected, make sure to pass nil to both
excludeTags an includeTags in your test app code, i.e.

Cucumberish.executeFeatures(inDirectory: "Features", from: bundle, includeTags: nil, excludeTags:


nil)

• Cucumberish framework translate features to TestClass and scenarios to tests please follow the
following to resolve without having to run the tests:
Feature: removes all non-alphanumeric characters and then capitalize words from the second position
then adds "CCI" prefix, for example, feature: "amazing feature_2" → "CCIamazingFeature2"
Scenario: removes all non-alphanumeric characters and then capitalize words from the second
position and lowercase the first word, for example: "Good Scenario_2"→ "goodScenario2"

Manage Test Run with Cucumber-jvm

How To Run Cucumber Test:

To run via Rest API:

Use same Manage Test Run with the API requests With Espresso/XCUITests for Android/iOS.

• In the "app" field use your regular app apk file.


• In the "testApp" field use the created cucumber test apk file (The "AppName-androidtest.apk" file).
• All other fields are the same as Espresso/XCUITests.

Inside the cloud reports:

©2023 Digital.ai Inc. All rights reserved Page 368


Test Execution

• Each example of a scenario would be mapped to a test entity and execute separately.
• If Scenario Has no examples, the scenario would be a single test entity.

Due to certain limitations with Android 7 Samsung devices, the test report won’t include Cucumber steps.
Instead, it will include Espresso steps.

Supported Android version

Running Cucumber tests is supported only for Android 7 and above.

Manage Test Run with Flutter Integration tests

Limitation

A Flutter report has only one step. If the step fails, it contains the stacktrace and device log.

Android Limitations
• runningType=fastFeedback is not supported with Flutter integration tests. If fastFeedback is
used as runningType, the value is ignored and the test runs in coverage mode.
• Only the ".apk" extension is supported.

Run Flutter Tests


1. Create an instrumentation test file in your application's android/app/src/androidTest/java/com/example/
myapp/ directory (replacing com, example, and myapp with values from your app's package name).
You can name this test file MainActivityTest.java or another name of your choice.

MainActivityTest.java
package com.example.myapp;

import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import org.junit.Rule;

©2023 Digital.ai Inc. All rights reserved Page 369


Test Execution

import org.junit.runner.RunWith;

@RunWith(FlutterTestRunner.class)
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(Main
Activity.class, true, false);
}

2. Update your application's myapp/android/app/build.gradle to make sure it uses androidx's


version of AndroidJUnitRunner and has androidx libraries as a dependency.

build.gradle
android {
...
defaultConfig {
...
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}

dependencies {
testImplementation 'junit:junit:4.12'

// https://developer.android.com/jetpack/androidx/releases/test/#1.2.0
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

Build the Application for Funning


Use the following gradle commands to build an instrumentation test for Android.

Gradle command
pushd android
# flutter build generates files in android/ for building the app
flutter build apk
./gradlew app:assembleAndroidTest
./gradlew app:assembleDebug -Ptarget=<path_to_test>.dart
popd

©2023 Digital.ai Inc. All rights reserved Page 370


Test Execution

To submit for a run, run with executionType=Flutter.

iOS Device Testing


1. Edit tests under integration_test to include the following. It is a workaround for a bug in Flutter with iOS
which causes enterText to fail when the app is built in release mode. For more information see
the issue.

import 'dart:io';
void main() {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
if (Platform.isIOS) {
binding.testTextInput.register();
}
...
}
2. Open the ios/Runner.xcworkspace in Xcode.
3. If you do not have a test target, click File > New > Target..., then click Unit Testing Bundle.
4. Change the Product Name to RunnerTests.
5. Make sure Target to be Tested is set to Runner and language is set to Objective-C.
6. Click Finish.
7. Make sure that the iOS Deployment Target of RunnerTests within the Build Settings section is the same
as Runner, including the minimum target version.
8. Add the new test target to ios/Podfile by embedding in the existing Runner target.

target 'Runner' do
# Do not change existing lines.
...

target 'RunnerTests' do

©2023 Digital.ai Inc. All rights reserved Page 371


Test Execution

inherit! :search_paths
end
end

To build integration_test/foo_test.dart from the command line:

1. Run flutter build ios --config-only integration_test/foo_test.dart.

2. In Xcode, add a test file called RunnerTests.m (or any name of your choice) to the new target and
replace the file:

@import XCTest;
@import integration_test;

INTEGRATION_TEST_IOS_RUNNER(RunnerTests)
3. Click Product > Test to run the integration tests on your selected device.

To deploy it to Continuous Testing Cloud, run this script at the root of your Flutter app:

output="../build/ios_integration"
product="build/ios_integration/Build/Products"

# Pass --simulator if building for the simulator.


flutter build ios integration_test/foo_test.dart --release

pushd ios
xcodebuild build-for-testing \
-workspace Runner.xcworkspace \
-scheme Runner \
-xcconfig Flutter/Release.xcconfig \
-configuration Release \
-derivedDataPath \
$output -sdk iphoneos
popd

pushd $product
mkdir Payload
mv -f Release-iphoneos/Runner.app Payload
zip -r "flutter_test.ipa" "Payload"
popd

For further information see Flutter documentation.

©2023 Digital.ai Inc. All rights reserved Page 372


Test Execution

To submit for a run, run with executionType=Flutter. There is no need to provide the testApp parameter
because the built IPA already contains the xctest plugin.

For more information, see Manage Test Run with the API.

Viewing a Device During Execution

Permissions
• Cloud Administrators can view devices of all running test requests in the system.

• Project Administrators can view devices of all running test requests that were created by users in the
project administrator's project.
• Users can view devices of their own running test requests.

Option 1
Click on the View button:

©2023 Digital.ai Inc. All rights reserved Page 373


Test Execution

Option 2
A link to the device view will be printed out to the console of your IDE when running the test request:

When you visit the link, the device view screen is opened, but actions cannot be performed on the device
screen (view-only mode).

The user can view how the test is running live on the device.

©2023 Digital.ai Inc. All rights reserved Page 374


Test Execution

Running Automated tests using Reserved Device


This article demonstrates how to run automated tests on a device reserved in seetest.io

There are times when you would want to run test, on a device of your choice. It makes perfect sense as a
test user, to reserve a device first and then run the test against the device in such circumstances.

Reserve Device and Making It Ready for Automation


Logon to seetest cloud with your credentials and make sure you are in the Grid View. You can switch to grid
view as shown as below.

©2023 Digital.ai Inc. All rights reserved Page 375


Test Execution

Reserve the device you want to test as shown below.

Once you press the Open button, a new page will get opened in a browser tab.

This page has two sections, left side of the page has the device and operations which can be performed on
it.

Section on right side displays useful utility operations like viewing logs, automation etc.

Now on the right side of screen, click Automation tab followed by "Start" button.

©2023 Digital.ai Inc. All rights reserved Page 376


Test Execution

Once you have completed step before, you will get a screen which looks like screen below.

Make sure you copy the Device ID from this page as shown in the screenshot below.

This concludes all the steps to Reserve and make device ready to run Automation.

©2023 Digital.ai Inc. All rights reserved Page 377


Test Execution

Running the Automation Tests


Lets now move on the Automation code. We will now do a minor modification on the Sample Project in our
git repository and run it again on the Reserved device.

• Fork the git repository.


• Open the project in InteliJ or Eclipse as Gradle project.
• Run the project. Sample Project is packaged with a Readme with all necessary instructions to run the
project.

Once you have the project running, lets do a minor modification to use the reserved device.

Let us consider, the platform to be Android and the Device ID to be FA69TBN03839 (copied previously
from the last step of Reserve Device and making it ready for Automation)

Open TestBase.java and look for initDefaultDesiredCapabilities function and replace it with following
function.

Testbase modification
/**
* Initialize default properties.
*
*/
protected void initDefaultDesiredCapabilities() {
LOGGER.info("Setting up Desired Capabilities");
String accessKey = System.getenv(ENV_VAR_ACCESS_KEY);

if (accessKey == null || accessKey.length() < 10) {


LOGGER.error("Access key must be set in Environment variable SEETEST_I
O_ACCESS_KEY");
LOGGER.info("To get access get to to https://cloud.seetest.io or learn
at https://docs.seetest.io/display/SEET/Execute+Tests+on+SeeTest+-+Obtaining+
Access+Key", accessKey);
throw new RuntimeException("Access key invalid : accessKey - " + acces
sKey);
}

dc.setCapability(SeeTestCapabilityType.ACCESS_KEY, accessKey);
dc.setCapability(MobileCapabilityType.FULL_RESET, FULL_RESET);
// *** Changed code
if ("android".equals(os)) {
dc.setCapability(MobileCapabilityType.UDID, "FA69TBN03839");
LOGGER.info("Reserving device - FA69TBN03839");
} else {
String query = String.format("@os='%s'", os);
dc.setCapability(SeeTestCapabilityType.DEVICE_QUERY, query);

©2023 Digital.ai Inc. All rights reserved Page 378


Test Execution

LOGGER.info("Device Query = {}", query);


}
// *** Changed code
LOGGER.info("Desired Capabilities setup complete");
}

Modification was done to replace the device query with the capability MobileCapabilityType.UDID to set to
specific device for Android platform.

Modification in Test.java
String query = String.format("@os='%s'", os);
dc.setCapability(SeeTestCapabilityType.DEVICE_QUERY, query);
LOGGER.info("Device Query = {}", query);

with

if ("android".equals(os)) {
dc.setCapability(MobileCapabilityType.UDID, "FA69TBN03839");
LOGGER.info("Reserving device", "FA69TBN03839");
} else {
String query = String.format("@os='%s'", os);
dc.setCapability(SeeTestCapabilityType.DEVICE_QUERY, query);
LOGGER.info("Device Query = {}", query);
}

Save and Run the test again.

You will now observe that, all the tests in AndroidTestNGExampleTest.java are run on the device you had
earlier reserved.

If you observe the device which you had reserved in seetest.io you will be able to see the operations
performed in the console log.

Note : Since we would like reserve and then run the test, setting MobileCapabilityType.UDID is important.

However, if you do not want to reserve the device before hand and would like to just choose the device while
running the test, you could use device query as @os='<platform>' and @serialnumber='<deviceid>'.

©2023 Digital.ai Inc. All rights reserved Page 379


Test Execution

Native Applications Testing


The Continuous Testing cloud platform doesn't support applications that were signed for distribution. If you
upload such an application, you might not be able to install it on any of the devices. Make sure to upload the
application in debug configuration. See below for instructions:

Before you start, make sure you prepare your applications for testing:

• Preparing Your Android Application


• Preparing Your iOS Application

If you want to test your applications on remote devices in Continuous Testing Cloud Platform cloud, you
should upload them first to your project. There are three ways you can upload your applications to your
project. One is manually through the user interface and the other two are code like.

Upload Your Application Manually


1. In the cloud, find Applications at the bottom of the left hand side menu and click on it.

©2023 Digital.ai Inc. All rights reserved Page 380


Test Execution

2. Click on Upload, choose the application and upload it.

©2023 Digital.ai Inc. All rights reserved Page 381


Test Execution

3. Select an application from the list to get its bundle id that you specify in the test capabilities.

Upload your Application to Your Project using cURL


cURL is a tool that allows you to send and receive data to servers. You can send and receive data and even
perform actions on the server. Writing curl commands can be a bit tough, so we recommend that you use
Postman. Postman lets you plugin all the required data and in return in generates the proper cURL command
that you can just copy paste into the terminal.

©2023 Digital.ai Inc. All rights reserved Page 382


Test Execution

Watch the video on the right-hand side to learn how to use Postman.

The required data as appears in the video:

• The cloud url with the api endpoint - https://cloud.seetest.io/api/v1/applications/new


• Your access key.
• These parameters in the header:
◦ Cache-Control: no-cache
◦ content-type: multipart/form-data
• file - choose file - if the file is located in your project directory, provide the relative path and not the one
that Postman generates.

Upload Your Application to Your Project Using Your Script


Postman allows you to generate code snippets in various programming analogues. It will save you the time
and effort required for writing these code snippets yourself. The flow is the same as the one for creating a
Curl request (see above) only this time you just choose the programming language that you are working
with.

©2023 Digital.ai Inc. All rights reserved Page 383


Test Execution

Once the application is uploaded, you have to make sure it is installed during the test. The sample
tests include the required Appium Capability that tells Appium what app to install on the device. The format is
always:

iOS
cloud:<bundle_id>, for example cloud:com.company.app

Android
cloud:<app_package/.activity> - for example cloud:com.company.app/.activity

Managing Applications with API

The Continuous Testing Cloud platform exposes several API endpoints that allows you to manage your
applications.

©2023 Digital.ai Inc. All rights reserved Page 384


Test Execution

Using the API endpoints you can perform following operations:

1. Get the list of applications in your project


2. Upload applications to your project
3. Delete applications from your project
4. Install applications on specific devices
5. Uninstall applications from specific devices

To interact with these endpoints, you must first retrieve your access key.

Uploading Applications to Your Project


To upload applications in your project, you need to send a POST request to the endpoint /api/v1/
applications/new.

Optional Parameters
You can add optional parameters to the API end point:

Parameter Value Description


camera true / false The application will include camera libraries

touchId true / false The application will include touch id libraries

uniqueName string String that the you can use later to identify the app uniquely

Example:

/api/v1/applications/new?camera=true&touchId=true&uniqueName=uniqueName

See below for code examples on how to upload applications.

Java
You need the OKHttpClient library.

You can get from Maven (if you use maven or gradle).

Upload Applications with Java

©2023 Digital.ai Inc. All rights reserved Page 385


Test Execution

import okhttp3.*;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class Applications {

@Test
public void uploadApp() throws IOException {
OkHttpClient client = new OkHttpClient();
File app = new File("<PATH_TO_FILE>");

RequestBody formBody = new MultipartBody.Builder()


.setType(MultipartBody.FORM)
.addFormDataPart("file", app.getName(),
RequestBody.create(MediaType.parse("text/plain"), app)
)
.addFormDataPart("other_field", "other_field_value")
.build();

Request request = new Request.Builder()


.url("https://cloud.seetest.io/api/v1/applications/new")
.post(formBody)
.addHeader("Content-Type", "application/x-www-form-urlencoded"
)
.addHeader("Cache-Control", "no-cache")
.addHeader("Authorization", "Bearer <ACCESS_KEY>")
.build();
Response response = client.newCall(request).execute();
System.out.println(response);
}
}

Python
For this code to run, you need the Requests package

You can get it by running the command

pip install requests


Upload Applications with Python
import requests

©2023 Digital.ai Inc. All rights reserved Page 386


Test Execution

url = "https://cloud.seetest.io/api/v1/applications/new"

headers = {
'Authorization': "Bearer <ACCESS_KEY>",
}

app = open('<PATH_TO_FILE>','rb')
files = {'file': app}

requests.post(url, files=files, headers=headers)

C#
For this code to run, you need the RestSharp library.

You can get it by running the command (in NuGet Package Manager)

Install-Package RestSharp
Upload Applications with C Sharp
using RestSharp;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)

{
var client = new RestClient("https://cloud.seetest.io/api/v1/appli
cations/new");
RestRequest restRequest = new RestRequest(Method.POST);
restRequest.RequestFormat = DataFormat.Json;
restRequest.AddHeader("Authorization", "Bearer <ACCESS_KEY>");
restRequest.AddFile("file", "<PATH_TO_APP>");
var response = client.Execute(restRequest);
Console.WriteLine(response.Content);

}
}

©2023 Digital.ai Inc. All rights reserved Page 387


Test Execution

Ruby
For this code to run, you need the ruby's rest-client package

You can get it by running the command

gem install rest-client


Upload Applications with Ruby
require 'rest-client'
url = 'https://cloud.seetest.io/api/v1/applications/new'
auth = 'Bearer <ACCESS_KEY>'
payload = {
:multipart => true,
:file => File.new('PATH_TO_FILE', 'rb')
}

response = RestClient.post(url, payload,


:authorization => auth)

Listing Applications in Your Project


To list applications in your project, you need to send a GET request to the endpoint /api/v1/applications.

The response would be a json that contains all the data about your applications.

See below for code examples on how to retrieve the list of applications

Java
You need the OKHttpClient library.

You can get from Maven (if you use maven or gradle).

Get Applications with Java

©2023 Digital.ai Inc. All rights reserved Page 388


Test Execution

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.junit.Test;

import java.io.IOException;

public class Applications {

@Test
public void listApplications() throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://cloud.seetest.io/api/v1/applications")
.get()
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer <ACCESS KEY>")
.addHeader("Cache-Control", "no-cache")
.addHeader("Postman-Token", "2b15d9e9-b0e2-0c0b-3a7c-bdf7d9427
2b0")
.build();

try {
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

Python
For this code to run, you need the Requests package

You can get it by running the command

pip install requests


Get Applications with Python
import requests

url = "https://cloud.seetest.io/api/v1/applications"

headers = {
'Content-Type': "application/json",
'Authorization': "Bearer <ACCESS_KEY>",

©2023 Digital.ai Inc. All rights reserved Page 389


Test Execution

'Cache-Control': "no-cache",
}

response = requests.request("GET", url, headers=headers)

print(response.text)

C#
For this code to run, you need the RestSharp library.

You can get it by running the command (in NuGet Package Manager)

Install-Package RestSharp

List Applications with C Sharp


using RestSharp;
using System;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)

{
var client = new RestClient("https://cloud.seetest.io/api/v1/appli
cations");
var request = new RestRequest(Method.GET);
request.AddHeader("Cache-Control", "no-cache");
request.AddHeader("Authorization", "Bearer <ACCESS_KEY>");
request.AddHeader("Content-Type", "application/json");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
Console.ReadLine();
}
}
}

Ruby
List Applications with Ruby
require 'uri'
require 'net/http'

©2023 Digital.ai Inc. All rights reserved Page 390


Test Execution

url = URI("https://cloud.seetest.io/api/v1/applications")

http = Net::HTTP.new(url.host, url.port)


http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Content-Type"] = 'application/json'
request["Authorization"] = 'Bearer <ACCESS_KEY>'
request["Cache-Control"] = 'no-cache'

response = http.request(request)
puts response.read_body

Deleting Applications with API


You can delete applications from your project using the endpoint /api/v1/applications/{applicationId}/
delete.

The request is a post request, and you will have to retrieve the application id before you can send the
request to delete.

To get the application id, list the application in your project.

Example of JSON Formatted Response - you can see the application id as the second parameter in the
returned object.

List Response
{
"name":"com.experitest.UIKitCatalog",
"id":173321,
"packageName":null,
"version":"13.2",
"applicationName":"UIKitCatalog",
"notes":null,
"productId":"com.experitest.UIKitCatalog",
"mainActivity":null,
"cameraSupport":false,
"osType":"IOS",
"createdAt":1521963471926,
"versionNumber":0,
"createdAtFormatted":"2018-03-25 10:37:51",
"instrumentByProfile":null,
"nonInstrumented":false,
"bundleIdentifier":"com.experitest.UIKitCatalog"
}

©2023 Digital.ai Inc. All rights reserved Page 391


Test Execution

Java
You need the OKHttpClient library.

You can get from Maven (if you use maven or gradle).

Delete Applications with Java


import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import org.junit.Test;
import java.io.IOException;

public class Applications {

@Test
public void listApplications() throws IOException {
OkHttpClient client = new OkHttpClient();
String appId = "<APP_ID>";
RequestBody requestBody = RequestBody.create(null, "");
Request request = new Request.Builder()
.url("https://cloud.seetest.io/api/v1/applications/" + appId +
"/delete")
.post(requestBody)
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "Bearer ACCESS_KEY")
.addHeader("Cache-Control", "no-cache")
.build();

try {
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}

Python
For this code to run, you need the Requests package

You can get it by running the command

©2023 Digital.ai Inc. All rights reserved Page 392


Test Execution

pip install requests

Delete Applications with Python


import requests

url = "https://cloud.seetest.io/api/v1/applications/{}/delete"
app_id = "<APP_ID>"

headers = {
'Content-Type': "application/json",
'Authorization': "Bearer <ACCESS_KEY>",
'Cache-Control': "no-cache",
}

response = requests.request("POST", url.format(app_id), headers=headers)

print(response.text)

C#
For this code to run, you need the RestSharp library.

You can get it by running the command (in NuGet Package Manager)

Install-Package RestSharp

Delete Applications with C#


using RestSharp;
using System;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)

{
var appId = "<APP_ID>";
var client = new RestClient("https://cloud.seetest.io/api/v1/appli
cations/" + appId + "/delete");
RestRequest restRequest = new RestRequest(Method.POST);

©2023 Digital.ai Inc. All rights reserved Page 393


Test Execution

restRequest.RequestFormat = DataFormat.Json;
restRequest.AddHeader("Authorization", "Bearer <ACCESS_KEY>");
restRequest.AddHeader("Content-Type", "application/json");
var response = client.Execute(restRequest);
Console.WriteLine(response.Content);

}
}
}

Ruby
Delete Applications with Ruby
require 'uri'
require 'net/http'

app_id = '<APP_ID>'
url = URI("https://cloud.seetest.io/api/v1/applications/#{app_id}/delete")

http = Net::HTTP.new(url.host, url.port)


http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request["Authorization"] = 'Bearer <ACCESS_KEY>'
request["Cache-Control"] = 'no-cache'

response = http.request(request)
puts response.read_body

Preparing Your Android Application

Native Applications Testing

Before you can start testing your Android application, you will have to package the app and generate
the .apk file.

©2023 Digital.ai Inc. All rights reserved Page 394


Test Execution

Building The App


Google makes a lot of effort integrating Gradle with Android development. Therefore, the easiest and most
recommended way to do so is to use Gradle.

Your project should have Gradle in it with. When creating an Android Studio project, Android Studio runs
initial configuration, making sure that Gradle is present as an integrative part of the project.

The process is simple and pretty straight forward.

First, make sure that you are in the root of your project folder, not the app folder.

Then run the command:

Windows

gradlew assembleDebug

Linux or Mac

./gradlew assembleDebug

Once the builds is complete, locate the .apk file in the build folder.

Root folder of project → app → build → outputs → apk → app-debug.apk

Upload the app to the cloud.

Preparing Your iOS Application

Before you can upload and start testing your iOS application you need to create the app's package. The
process of building and signing an app is quite complex but is not required in our case. To upload, install and
test application with seetest.io, all you need to do is build the app with debug configuration, no code signing
required (therefore no provisioning profile required).

©2023 Digital.ai Inc. All rights reserved Page 395


Test Execution

Building The App


The best way to build the app is through the command line.

Make sure you have XCode Build tools installed before you start.

Getting Info About The App

To get more info about the app and parameters you need to pass to the build command, open the Mac
terminal and navigate to the project folder. Run the command:

xcodebuild -list -project <your_project_name>.xcodeproj

The output will usually look like like:

Information about project "<PROJECT_NAME>":


Targets:
<TARGET_NAME>

Build Configuration:
Debug
Release

If no build configuration is specified and -scheme is not passed, then "


Release" is used

Schemes:
<SCHEME_NAME>

Example when running command on UICatalog app:

Information about project "UICatalog":


Targets:
UICatalog

Build Configuration:
Debug
Release

©2023 Digital.ai Inc. All rights reserved Page 396


Test Execution

If no build configuration is specified and -scheme is not passed, then "


Release" is used

Schemes:
UICatalog

Building The App

When you are ready to build the app, go ahead and run the command below:

xcodebuild -target <TARGET_NAME> -configuration Debug -destination 'platform=iO


S, OS=9.1' CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO

Parameter Breakdown:

• target - the target app as listed in the information we got from the xcodebuild -list -project command.
• configuration - Debug as we intend to test and debug the app, not release it.
• destination - the destined platform for the app. Apple has several platforms such as iOS, MacOS, tvOS
etc.
◦ platform - in our case, iOS
◦ OS - the minimum OS version that can handle the app
• CODE_SIGN_IDENTITY - should be an empty string as we are not signing the app
• CODE_SIGNING_REQUIRED - should be NO as we are not signing the app

Packaging The App

Once the build is complete, navigate in the terminal to the build folder to locate the app.

cd build/Debug-iphoneos

Once inside the Debug-iphoneos folder, locate the file that ends with .app. Then create a script.sh file with
the following script:

#!/bin/bash
if [ -d "Payload" ]; then
rm -fr Payload/*
else

©2023 Digital.ai Inc. All rights reserved Page 397


Test Execution

mkdir Payload
fi # if you'd rather copy the .app file, then replace the next line with:

# cp -r $1 Payload
mv $1 Payload
zip -r $2.ipa Payload
rm -fr Payload

Save the file and in the terminal run the command:

script.sh your_app.app the_app_name

#(there is no need to add .ipa to the second parameter)

You will then have an file with the extension .ipa. Upload this file to the cloud.

Web - Desktop and Mobile Browsers


Would you like to be able to automate your cross-browser testing scenarios on an endless array of desktop
browsers?

Learn on how to leverage Continuous Testing Selenium Grid - Where we host almost any Desktop OS and
Browser version for you - stop worrying about maintenance, and focus your efforts on Test Development and
analytics.

• Selenium
• Web Test Execution
• Automating Windows Alerts and Popups
• Cypress
• Playwright

Selenium
Selenium is set of different software tools which helps to automate web applications. It can be used in
conjunction with other testing frameworks to build effective automated tests.

With Selenium, you can create automated tests for the layout and UI of your web application, as well as
verify the functionality of various web application components such as signup forms, interactive UI and more.

Selenium allows you to perform, simulate and test actions that a user might perform while interacting with
your web applications.

©2023 Digital.ai Inc. All rights reserved Page 398


Test Execution

Some of the actions it can perform are:

• Clicking on elements
• Sending input data
• Navigating the site

Selenium also allows you to verify the interactivity of your site in case you are using JS libraries such as
jQuery, Angular or React. Think of Selenium as an automated QA tester who manually interacts with the site
in order to verify functionality and uncover bugs and inconsistencies. You will use Selenium so that your
users will eventually have the best and smoothest experience using your web application.

Following images captures test executions on various browsers in Continuous Testing Cloud Platform using
Selenium tests.

Before you proceed with fetching the sample tests, you will have to do one simple but important thing and
that is to fetch your access key.

Your access key allows you to run Selenium tests against Selenium grid in Continuous Testing Cloud
platform

Capabilities In Selenium Tests

Basic Capabilities
Capabilities describes a series of key/value pairs that can customize or configure a Device or Browser
session for testing to Selenium or Appium WebDriver.

©2023 Digital.ai Inc. All rights reserved Page 399


Test Execution

This section describes the available capabilities and examples of their usage.

You can start developing a new framework, or migrate your existing Selenium tests and execute them with
higher performance and stability rates.

See below for the list of basic Desired Capabilities.

Key Type Default Value Description Possible Values


browserName string default: The browser type.

• windows - • chrome
Chrome
• safari
• mac - Safari
• firefox

• internet explorer

• MicrosoftEdge

browserVersion string latest version The browser version.

• browser version

• "latest" : latest version of this browser type in the


Cloud

• "latest-x" : where x is any number of versions


before latest (e.g. if latest is 70 so latest-3 is 67)

platformName random The operating system


type.NOTE: can be a
string conflict with osName
value. • MAC

• WINDOWS

For more basic capabilities, visit Selenium's support page.

Continuous Testing Capabilities


The following list describes Continuous Testing specific capabilities that can be set for browser testing:

©2023 Digital.ai Inc. All rights reserved Page 400


Test Execution

Key Type Default Description Possible Values


Value
osName string Operating system to run the browser on. Case Mac OS X Catalina
sensitive.NOTE: can be a conflict with Mac OS Big Sur
platformName value. Mac OS Monterey
Windows 10
Windows 11

testName string Specifies the test name. This name will appear in any string
SeeTest Reporter and in the generated report.

generateReport boolean True Should a report be generated for this test. true/false

takeScreenshots True Take a screenshot for reports and for reflection in true/false
execution page in the Cloud.
boolean

newCommandTimeout integer 300 Set the timeout in seconds for each command to any number
be processed.

newSessionWaitTimeout integer 300 Set the timeout in seconds for creating a new any number
driver.

seleniumScreenshot boolean false If set to true, will take screenshots using true/false
selenium grid and not native OS API. This means
the test will take longer.NOTE: add this capability
in tests that handle multiple browser windows in
order to get a correct report.

closePopups string Provide information on which native popups to


or close (and how).More information below.
list of
strings

agentName String random The name of the agent that the test will run on. any agent name

maxScreenshotInterval integer 10 The maximum time between consecutive any number


screenshots.
This capability is used to force the test to take
screenshot when there are is a long time
between 2 consecutive steps that change the
state of the browser.

reportType string both The type of the report that should be generated
reports for the test.NOTE: reportType with value
"screenshot" will generate an empty video report,
the HTML report will be found in the video report • "video" - for video
as an attachment report

• "screenshot" - for
HTML report

useNV boolean false Enable HAR recording for this test.More true/false
information about HAR recording here.

ieMode boolean false Enable Internet Explorer compatibility mode in true/false


Edge.NOTE: Works only with browserName
"MicrosoftEdge".This feature is currently
limited to one concurrent session

©2023 Digital.ai Inc. All rights reserved Page 401


Test Execution

Handling native OS popups

If during a selenium web test, the browser or OS displays a native popup that the user wants to close, he can
specify how to close this popup.

Using the capability closePopups the user can specify one or more expressions that specify which native
popups to look for and if found which button to click.

The user can specify one expression or a list of expressions.

For Windows each expression is in the form <regex>::<button-name> where

• regex - Find a popup with a title that contains the regex


• button-name - Name of a button to click on the associated popup

Native popups handling code - Windows

dc.setCapability("closePopups", "Windows Security::OK"); // Close popup to confirm client-


certificate selection for Edge
or
dc.setCapability("closePopups", new String [] { "Windows Security::OK", "TitleRegex::Button" });

For macOS each expression should follow one of the following syntax formats

• <text-to-find>::<button-name> - This will search for a popup with text-to-find in the browser's process
and will press the button with button-name.
• <text-to-find>@<process-name>::<button-name> - This will search for a popup with text-to-find in the
process process-name and will press the button with button-name.

Native popups handling code - MacOS

// Example code to close popup from MacOS keychain security agent


dc.setCapability("closePopups", new String [] { "wants to sign using key@SecurityAgent::Always
Allow" });

A test that has a valid closePopups capability will search for a popup every X seconds where X is 5 by
default.
The default can changed by setting the property popup-monitor-interval-in-seconds in the config/
application.properties file.

©2023 Digital.ai Inc. All rights reserved Page 402


Test Execution

Returned Capabilities
The following list describes Continuous Testing specific capabilities that returns with the driver.

Key Type Description


reportUrl string A link to view the test report in SeeTest Reporter (if the test is configured to generate a report).

sessionId string The session ID of the test.

viewUrl A link to view the test's execution.

string

reportTestId string The test ID in the reporter

Example
Below you can find an example written in Java specifying the capabilities above.

In order to be able to run the below code you will need

• Java 8
• Selenium java jar

Selenium- Grid Execution


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("username", "<cloudUsername>");
dc.setCapability("password", "<cloudPassword>");
dc.setCapability("projectName", "<cloudProject>"); //only required if your use
r has several projects assigned to it. Otherwise, exclude this capability.
//dc.setCapability("accessKey", "<accessKey>"); // can be use instead of usern
ame,password and project.
dc.setCapability("generateReport", true);
dc.setCapability("testName", "<testName>");
dc.setCapability(CapabilityType.PLATFORM, Platform.WIN10);
dc.setCapability(CapabilityType.BROWSER_VERSION, "93.0");
dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX);
dc.setCapability("newCommandTimeout", 500);
dc.setCapability("newSessionWaitTimeout", 500);
dc.setCapability("agentName", "<agentName>");
dc.setCapability("maxScreenshotInterval", 10);
//dc.setCapability("seleniumScreenshot", true);
dc.setCapability("reportType", "video");

RemoteWebDriver driver = new RemoteWebDriver(new URL(cloudurl + "/wd/hub/"), d


c);
String testReportUrl = driver.getCapabilities().getCapability("reportUrl");
String testViewUrl = driver.getCapabilities().getCapability("viewUrl");

©2023 Digital.ai Inc. All rights reserved Page 403


Test Execution

String sessionId = driver.getCapabilities().getCapability("sessionId"); //will


return the session id as String.
String reportTestId = driver.getCapabilities().getCapability("reportTestId");

Available Browsers for Testing

If you want to know which combination of browser and operating system are available for testing, head over
to the Browsers page.

In this page, you will be able to see what combinations are available for testing. Use the drop down at the
bottom of each browser card.

©2023 Digital.ai Inc. All rights reserved Page 404


Test Execution

Viewing Your Automated Selenium Tests

You can view your automated Selenium tests live in the Continuous Testing cloud.

To View Your Automated Selenium Tests

In the cloud, click on Execution in the left hand side bar.

©2023 Digital.ai Inc. All rights reserved Page 405


Test Execution

If you don't have any tests running at the moment, you will see empty grid nodes.

©2023 Digital.ai Inc. All rights reserved Page 406


Test Execution

If any tests are running you, will see them populated in the grid nodes.

Note that there is a Cancel button at the bottom of each test. You can use it to cancel and terminate the test.

Selenium with C Sharp

If you prefer to run your Selenium tests using C Sharp, select one of the sample tests below to see our
platform in action.

Set Access Key

All the scripts below makes use of the grid access key. In order to run the test do the following

• Get your access key


• Replace it with <YOUR_ACCESS_KEY>, in the sample tests below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 407


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Selenium 3 with C Sharp


using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Remote;
using NUnit;
using NUnit.Framework;
using OpenQA.Selenium.Support.UI;

namespace selenium_csharp_first_test
{
[TestFixture]
public class QuickStart
{
private string ACCESS_KEY= "<YOUR_ACCESS_KEY>";
private string CLOUD_URL = "<server>";

private string testName = "Quick Start Test";

protected RemoteWebDriver driver = null;

DesiredCapabilities dc = new DesiredCapabilities();

[SetUp()]
public void SetupTest()
{
dc.SetCapability("testName", testName);
dc.SetCapability("accessKey", ACCESS_KEY);
dc.SetCapability("initialBrowserUrl", "https://seetest.io");
dc.SetCapability(CapabilityType.BrowserName, <BROWSER_NAME>);
driver = new RemoteWebDriver(new Uri(CLOUD_URL), dc);
}

[Test()]
public void QuickStartTestWithSelenium()
{
for (int i = 0; i < 7; i++)
{
driver.Navigate().GoToUrl("https://www.google.com");
new WebDriverWait(driver,TimeSpan.FromSeconds(10) ).Until(driv
er => driver.FindElement(By.Name("q")));
IWebElement searchBar = driver.FindElement(By.Name("q"));

©2023 Digital.ai Inc. All rights reserved Page 408


Test Execution

searchBar.Click();
searchBar.SendKeys("Experitest");
searchBar.SendKeys(Keys.Enter);
}
}

[TearDown()]
public void TearDown()
{
driver.Quit();
}
}
}
Selenium 4 with C Sharp
using NUnit.Framework;
using System;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium;
//for Chrome
using OpenQA.Selenium.Chrome;
//for FireFox
using OpenQA.Selenium.Firefox;
//for Microsoft Edge
using OpenQA.Selenium.Edge;
//for Safari
using OpenQA.Selenium.Safari;
using OpenQA.Selenium.Support.UI;

namespace selenium_csharp_first_test
{
public class QuickStart
{
private string ACCESS_KEY = "<YOUR_ACCESS_KEY>";
private string testName = "Quick Start Test";

private string CLOUD_URL = "<server>";


protected RemoteWebDriver driver = null;

//for Chrome
ChromeOptions options= new ChromeOptions();
//for FireFox
FirefoxOptions options= new FirefoxOptions();
//for Microsoft Edge
EdgeOptions options= new EdgeOptions();
//for Safari
SafariOptions options= new SafariOptions();

[SetUp]
public void SetupTest()

©2023 Digital.ai Inc. All rights reserved Page 409


Test Execution

{
options.AddAdditionalOption("experitest:accessKey",ACCE
SS_KEY);
options.AddAdditionalOption("experitest:testName",testN
ame);
driver = new RemoteWebDriver(new Uri(CLOUD_URL), options);
}

[Test]
public void QuickStartTestWithSelenium()
{
for (int i = 0; i < 7; i++)
{
driver.Navigate().GoToUrl("https://www.google.com");
new WebDriverWait(driver,TimeSpan.FromSeconds(10) ).Until(driv
er => driver.FindElement(By.Name("q")));
IWebElement searchBar = driver.FindElement(By.Name("q"));
searchBar.Click();
searchBar.SendKeys("Experitest");
searchBar.SendKeys(Keys.Enter);
}
}

[TearDown]
public void TearDown()
{
driver.Quit();
}
}
}

Before you begin, make sure to install Selenium dependencies.

Installing the Selenium Package


you can install the Selenium Package in one of two ways:

Installing using NuGet Package Manager

In your Visual Studio project, look for the References object in the Solution Explorer. Right Click on it and
select Manage NuGet Packages.

©2023 Digital.ai Inc. All rights reserved Page 410


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 411


Test Execution

Alternatively, in Visual Studio upper menu click on Tools → NuGet Package Manager → Manage NuGet
Packages for Solution.

Search for Selenium and install the first two packages that appear in the list.

©2023 Digital.ai Inc. All rights reserved Page 412


Test Execution

Installing using NuGet Package Manager Console

In Visual Studio upper menu, click on Tools → NuGet Package Manager - Package Manager Console.

Run the commands:

#for latest Selenium 3 version


Install-Package Selenium.WebDriver -Version 3.141.0
Install-Package Selenium.Support -Version 3.141.0
#for latest Selenium 4 version
Install-Package Selenium.WebDriver
Install-Package Selenium.Support

Note that the commands above install a particular version. Follow updates in NuGet repository:

• Selenium WebDriver
• Selenium Support

Selenium with Java

If you prefer to run your Selenium tests using Java, clone the repository, or select and make use of one of
the sample tests below to see our platform in action.

Set Access Key

All the scripts below makes use of the grid access key. In order to run the test do the following

• Get your access key


• Replace it with <YOUR ACCESS KEY>, in the sample tests below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.

©2023 Digital.ai Inc. All rights reserved Page 413


Test Execution

• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Chrome with Java and JUnit


package Junit;

import java.net.URL;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ChromeTest {


private static final String ACCESSKEY = "<YOUR ACCESS KEY>";

String CLOUDURL = "<server>";


String testName= "Selenium Test on Chrome";
RemoteWebDriver driver;

@Before
public void setUp() throws Exception {

//Set Browser Type


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.CHROME);

//Set Grid capabilities


dc.setCapability("accessKey", ACCESSKEY);
dc.setCapability("generateReport", true);
dc.setCapability("testName", testName);

driver = new RemoteWebDriver(new URL(CLOUDURL), dc);


}

©2023 Digital.ai Inc. All rights reserved Page 414


Test Execution

@Test
public void testSeleniumOnChrome() {
driver.get("https://seetest.io");

new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfEleme


ntLocated(By.xpath("//*[text()='Manual']")));
WebElement manualNavLink = driver.findElement(By.xpath("//*[text()='Man
ual']"));
manualNavLink.click();

WebElement automationNavLink = driver.findElement(By.xpath("//*[text()=


'Automation']"));
automationNavLink.click();

WebElement webinarFooterLink = driver.findElement(By.xpath("//*[text()=


'Webinars']"));

webinarFooterLink.click();

String webinarH2TitleText = driver.findElement(By.xpath("//h2[1]")).get


Text();

System.out.println("The title of the first h2 is: " + webinarH2TitleTex


t);

@After
public void tearDown() {
driver.quit();
}

}
Chrome with Java and TestNG
package TestNG;

import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;

©2023 Digital.ai Inc. All rights reserved Page 415


Test Execution

import org.testng.annotations.Test;

public class ChromeTest {


private static final String ACCESSKEY = "<YOUR ACCESS KEY>";

String CLOUDURL = "<server>";


String testName= "Selenium Test on Chrome";
RemoteWebDriver driver;

@BeforeMethod
public void setUp() throws Exception {

//Set Browser Type


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.CHROME);

//Set Grid capabilities


dc.setCapability("accessKey", ACCESSKEY);
dc.setCapability("generateReport", true);
dc.setCapability("testName", testName);

driver = new RemoteWebDriver(new URL(CLOUDURL), dc);


}

@Test
public void testSeleniumOnChrome() {
driver.get("https://seetest.io");

new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfEleme


ntLocated(By.xpath("//*[text()='Manual']")));
WebElement manualNavLink = driver.findElement(By.xpath("//*[text()='Man
ual']"));
manualNavLink.click();

WebElement automationNavLink = driver.findElement(By.xpath("//*[text()=


'Automation']"));
automationNavLink.click();

WebElement webinarFooterLink = driver.findElement(By.xpath("//*[text()=


'Webinars']"));

webinarFooterLink.click();

String webinarH2TitleText = driver.findElement(By.xpath("//h2[1]")).get


Text();

System.out.println("The title of the first h2 is: " + webinarH2TitleTex

©2023 Digital.ai Inc. All rights reserved Page 416


Test Execution

t);

@AfterMethod
public void tearDown() {
driver.quit();
}

}
Firefox with Java and JUnit
package Junit;

import java.net.URL;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class FirefoxTest {


private static final String ACCESSKEY = "<YOUR ACCESS KEY>";

String CLOUDURL = "<server>";


String testName= "Selenium Test on Firefox";
RemoteWebDriver driver;

@Before
public void setUp() throws Exception {

//Set Browser Type


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX);

//Set Grid capabilities


dc.setCapability("accessKey", ACCESSKEY);
dc.setCapability("generateReport", true);
dc.setCapability("testName", testName);

driver = new RemoteWebDriver(new URL(CLOUDURL), dc);


}

©2023 Digital.ai Inc. All rights reserved Page 417


Test Execution

@Test
public void testSeleniumOnFirefox() {
driver.get("https://seetest.io");

new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfEleme


ntLocated(By.xpath("//*[text()='Manual']")));
WebElement manualNavLink = driver.findElement(By.xpath("//*[text()='Man
ual']"));
manualNavLink.click();

WebElement automationNavLink = driver.findElement(By.xpath("//*[text()=


'Automation']"));
automationNavLink.click();

WebElement webinarFooterLink = driver.findElement(By.xpath("//*[text()=


'Webinars']"));

webinarFooterLink.click();

String webinarH2TitleText = driver.findElement(By.xpath("//h2[1]")).get


Text();

System.out.println("The title of the first h2 is: " + webinarH2TitleTex


t);
}

@After
public void tearDown() {
driver.quit();
}

}
Firefox with Java and TestNG
package TestNG;

import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.AfterMethod;

©2023 Digital.ai Inc. All rights reserved Page 418


Test Execution

import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class FirefoxTest {


private static final String ACCESSKEY = "<YOUR ACCESS KEY>";

String CLOUDURL = "<server>";


String testName= "Selenium Test on Firefox";
RemoteWebDriver driver;

@BeforeMethod
public void setUp() throws Exception {

//Set Browser Type


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX);

//Set Grid capabilities


dc.setCapability("accessKey", ACCESSKEY);
dc.setCapability("generateReport", true);
dc.setCapability("testName", testName);

driver = new RemoteWebDriver(new URL(CLOUDURL), dc);


}

@Test
public void testSeleniumOnFirefox() {
driver.get("https://seetest.io");

new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfEleme


ntLocated(By.xpath("//*[text()='Manual']")));
WebElement manualNavLink = driver.findElement(By.xpath("//*[text()='Man
ual']"));
manualNavLink.click();

WebElement automationNavLink = driver.findElement(By.xpath("//*[text()=


'Automation']"));
automationNavLink.click();

WebElement webinarFooterLink = driver.findElement(By.xpath("//*[text()=


'Webinars']"));

webinarFooterLink.click();

String webinarH2TitleText = driver.findElement(By.xpath("//h2[1]")).get


Text();

©2023 Digital.ai Inc. All rights reserved Page 419


Test Execution

System.out.println("The title of the first h2 is: " + webinarH2TitleTex


t);

@AfterMethod
public void tearDown() {
driver.quit();
}

}
IE with Java and JUnit
package Junit;

import java.net.URL;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

public class IETest {


private static final String ACCESSKEY = "<YOUR ACCESS KEY>";

String CLOUDURL = "<server>";


String testName= "Selenium Test on IE";
RemoteWebDriver driver;

@Before
public void setUp() throws Exception {

//Set Browser Type


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.FIREFOX);

//Set Grid capabilities


dc.setCapability("accessKey", ACCESSKEY);
dc.setCapability("generateReport", true);
dc.setCapability("testName", testName);
dc.setCapability("initialBrowserUrl", "https://www.google.com");
driver = new RemoteWebDriver(new URL(CLOUDURL), dc);

©2023 Digital.ai Inc. All rights reserved Page 420


Test Execution

@Test
public void testSeleniumOnIE() {
driver.get("https://seetest.io");

new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfEleme


ntLocated(By.xpath("//*[text()='Manual']")));
WebElement manualNavLink = driver.findElement(By.xpath("//*[text()='Man
ual']"));
manualNavLink.click();

WebElement automationNavLink = driver.findElement(By.xpath("//*[text()=


'Automation']"));
automationNavLink.click();

WebElement webinarFooterLink = driver.findElement(By.xpath("//*[text()=


'Webinars']"));

webinarFooterLink.click();

String webinarH2TitleText = driver.findElement(By.xpath("//h2[1]")).get


Text();

System.out.println("The title of the first h2 is: " + webinarH2TitleTex


t);
}

@After
public void tearDown() {
driver.quit();
}

}
IE with Java and TestNG
package TestNG;

import java.net.URL;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.BrowserType;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

©2023 Digital.ai Inc. All rights reserved Page 421


Test Execution

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

public class IETest {


private static final String ACCESSKEY = "<YOUR ACCESS KEY>";

String CLOUDURL = "<server>";


String testName= "Selenium Test on IE";
RemoteWebDriver driver;

@BeforeMethod
public void setUp() throws Exception {

//Set Browser Type


DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.IE);

//Set Grid capabilities


dc.setCapability("accessKey", ACCESSKEY);
dc.setCapability("generateReport", true);
dc.setCapability("testName", testName);
dc.setCapability("initialBrowserUrl", "https://www.google.com");

driver = new RemoteWebDriver(new URL(CLOUDURL), dc);


}

@Test
public void testSeleniumOnIE() {
driver.get("https://seetest.io");

new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfEleme


ntLocated(By.xpath("//*[text()='Manual']")));
WebElement manualNavLink = driver.findElement(By.xpath("//*[text()='Man
ual']"));
manualNavLink.click();

WebElement automationNavLink = driver.findElement(By.xpath("//*[text()=


'Automation']"));
automationNavLink.click();

WebElement webinarFooterLink = driver.findElement(By.xpath("//*[text()=


'Webinars']"));

webinarFooterLink.click();

String webinarH2TitleText = driver.findElement(By.xpath("//h2[1]")).get

©2023 Digital.ai Inc. All rights reserved Page 422


Test Execution

Text();

System.out.println("The title of the first h2 is: " + webinarH2TitleTex


t);

@AfterMethod
public void tearDown() {
driver.quit();
}

Before you begin, make sure to install Selenium dependencies. We recommend obtaining the dependencies
with the help of Gradle or Maven.

Fetch Selenium Dependencies with Gradle


In your build.gradle file, in the dependencies group, add the following line:

Dependency in gradle build file


dependencies {
testCompile group: 'org.seleniumhq.selenium', name: 'selenium-java', versi
on: '3.9.0'
}
// change the version to the latest or desired version

Fetch Selenium Dependencies with Maven


In your pom.xml, add the following:

Dependency in Maven POM.xml


<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.9.0</version>
</dependency>

Selenium With Javascript

©2023 Digital.ai Inc. All rights reserved Page 423


Test Execution

WebdriverIO is an open source testing utility for nodejs. It makes possible to develop selenium tests with
Javascript. The article provides more insights on the WebdriverIO framework and its usage.

To run your Selenium tests using WebdriverIO/Javascript, clone the repository, or select and make use of
one of the sample tests below to see our platform in action.

Set Access Key

All the scripts below makes use of the grid access key. In order to run the test do the following

• Get your access key


• Replace it with <YOUR ACCESS KEY>, in the sample tests below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Chrome with Javascript


"use strict";
var webdriverio = require('webdriverio');

function main() {

let options = {
host: '<server>',
protocol: 'https',
port: 443,
path: '',
desiredCapabilities: {
browserName: 'chrome',
accessKey: "<YOUR ACCESS KEY>",
testName: "Javascript Chrome Test"
}
};

webdriverio
.remote(options)
.init()
.url('https://www.seetest.io')
.click("//*[text()='Manual']")

©2023 Digital.ai Inc. All rights reserved Page 424


Test Execution

.click("//*[text()='Automation']")
.click("//*[text()='Webinars']")
.getTitle().then(function (title) {
console.log('Title was: ' + title);
})
.getText("(//h2)[1]").then(function(text){
console.log("The title of the first H2 is: ", text);
})
.end()
.catch(function (err) {
console.log(err);
});
}

main();
Firefox with Javascript
"use strict";
var webdriverio = require('webdriverio');

function main() {

let options = {
host: '<server>',
protocol: 'https',
port: 443,
path: '',
desiredCapabilities: {
browserName: 'firefox',
accessKey: "<YOUR ACCESS KEY>",
testName: "Javascript Firefox Test"
}
};

webdriverio
.remote(options)
.init()
.url('https://www.seetest.io')
.click("div > nav > div > ul > li:nth-child(1)")
.click("//*[text()='Automation']")
.click("//*[text()='Webinars']")
.getTitle().then(function (title) {
console.log('Title was: ' + title);
})
.getText("(//h2)[1]").then(function(text){
console.log("The title of the first H2 is: ", text);
})
.then(function(){
console.log
})

©2023 Digital.ai Inc. All rights reserved Page 425


Test Execution

.end()
.catch(function (err) {
console.log(err);
});
}

main();
IE with Javascript
"use strict";
var webdriverio = require('webdriverio');

function main() {

let options = {
host: '<server>',
protocol: 'https',
port: 443,
path: '',
desiredCapabilities: {
browserName: 'internet explorer',
accessKey: "<YOUR ACCESS KEY>",
testName: "Javascript IE Test"
}
};

webdriverio
.remote(options)
.init()
.url('https://www.seetest.io')
.click("//*[text()='Manual']")
.click("//*[text()='Automation']")
.click("//*[text()='Webinars']")
.getTitle().then(function (title) {
console.log('Title was: ' + title);
})
.getText("(//h2)[1]").then(function(text){
console.log("The title of the first H2 is: ", text);
})
.end()
.catch(function (err) {
console.log(err);
});
}

main();

Before you begin, make sure to install webdriverio bindings for Selenium.

Also make sure that you have the latest Node.js installed on your machine.

©2023 Digital.ai Inc. All rights reserved Page 426


Test Execution

In your terminal or command line, run the command:

npm install --save webdriverio

If you clone the repository, simply run the command:

npm install --save

Selenium With Python

To run Selenium tests using Python, clone the repository, or select and make use of one of the sample tests
below to see our platform in action.

Set Access Key

All the scripts below makes use of the grid access key. In order to run the test do the following

• Get your access key


• Replace it with <YOUR ACCESS KEY>, in the sample tests below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Chrome with Python


import unittest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions

class TestFirefox(unittest.TestCase):
dc = {}
testName = 'Selenium Test on chrome'

©2023 Digital.ai Inc. All rights reserved Page 427


Test Execution

driver = None

def setUp(self):
self.dc['testName'] = self.testName
self.dc['browserName'] = 'chrome'
# Specify the access key in order to run this test against the browser
Grid
self.dc['accessKey'] = '<YOUR ACCESS KEY>'
self.driver = webdriver.Remote('<server>', self.dc)

def test_chrome(self):
self.driver.get("https://seetest.io")
WebDriverWait(self.driver, 10).until(
expected_conditions.presence_of_element_located((By.XPATH, "//*[te
xt()='Manual']")))

manual_nav_link = self.driver.find_element_by_xpath("//*[text()='Manual
']")
manual_nav_link.click()

automation_nav_link = self.driver.find_element_by_xpath("//*[text()='Au
tomation']")
automation_nav_link.click()

webinar_footer_link = self.driver.find_element_by_xpath("//*[text()='We
binars']")
webinar_footer_link.click()

webinars_h2_title_text = self.driver.find_element_by_xpath("//h2[1]").t
ext

print("The title of the first h2 is: " + webinars_h2_title_text)

def tearDown(self):
self.driver.quit()

if __name__ == '__main__':
unittest.main()
Firefox with Python
import unittest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions

class TestFirefox(unittest.TestCase):
dc = {}
testName = 'Selenium Test on Firefox'

©2023 Digital.ai Inc. All rights reserved Page 428


Test Execution

driver = None

def setUp(self):
self.dc['testName'] = self.testName
self.dc['browserName'] = 'firefox'
# Specify the access key in order to run this test against the browser
Grid
self.dc['accessKey'] = '<YOUR ACCESS KEY>'
self.driver = webdriver.Remote('<server>', self.dc)

def test_firefox(self):
self.driver.get("https://seetest.io")
WebDriverWait(self.driver, 10).until(
expected_conditions.presence_of_element_located((By.XPATH, "//*[te
xt()='Manual']")))

manual_nav_link = self.driver.find_element_by_xpath("//*[text()='Manual
']")
manual_nav_link.click()

automation_nav_link = self.driver.find_element_by_xpath("//*[text()='Au
tomation']")
automation_nav_link.click()

webinar_footer_link = self.driver.find_element_by_xpath("//*[text()='We
binars']")
webinar_footer_link.click()

webinars_h2_title_text = self.driver.find_element_by_xpath("//h2[1]").t
ext

print("The title of the first h2 is: " + webinars_h2_title_text)

def tearDown(self):
self.driver.quit()

if __name__ == '__main__':
unittest.main()
Internet Explorer with Python
import unittest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions

class TestIE(unittest.TestCase):
dc = {}
testName = 'Selenium Test on IE'

©2023 Digital.ai Inc. All rights reserved Page 429


Test Execution

driver = None
def setUp(self):
self.dc['testName'] = self.testName
self.dc['browserName'] = 'internet explorer'
self.dc['accessKey'] = '<YOUR ACCESS KEY>'
# Specify the access key in order to run this test against the browser
Grid
self.dc['initialBrowserUrl'] = 'https://seetest.io'
self.driver = webdriver.Remote('<server>', self.dc)

def test_ie(self):
self.driver.get("https://seetest.io")
WebDriverWait(self.driver, 10).until(expected_conditions.presence_of_e
lement_located((By.XPATH, "//*[text()='Manual']")))

manual_nav_link = self.driver.find_element_by_xpath("//*[text()='Manual
']")
manual_nav_link.click()

automation_nav_link = self.driver.find_element_by_xpath("//*[text()='Au
tomation']")
automation_nav_link.click()

webinar_footer_link = self.driver.find_element_by_xpath("//*[text()='We
binars']")
webinar_footer_link.click()

webinars_h2_title_text = self.driver.find_element_by_xpath("//h2[1]").t
ext

print("The title of the first h2 is: " + webinars_h2_title_text)

def tearDown(self):
self.driver.quit()

if __name__ == '__main__':
unittest.main()

Before you begin, make sure to install Python bindings for Selenium.

In your terminal or command line, run the command:

pip install -U selenium

Alternatively, if you don't have pip installed on your machine, you can download the bindings and run the
setup file.

Download the file, unzip it, open your terminal or command line in the unzipped folder and run the command:

©2023 Digital.ai Inc. All rights reserved Page 430


Test Execution

python setup.py install

Selenium with Ruby

If you prefer to run your Selenium tests using Ruby, clone the repository, or select and make use of one of
the sample tests below to see our platform in action.

Set Access Key

All the scripts below makes use of the grid access key. In order to run the test do the following

• Get your access key


• Replace it with <YOUR ACCESS KEY>, in the sample tests below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Chrome with Ruby


require 'test/unit'
require 'selenium-webdriver'
# require 'selenium/webdriver/remote'

class Example < Test::Unit::TestCase


def setup
desired_caps = {
:testName=> 'Running Selenium on Chrome',
:platform=> 'ANY',
:browserName=> 'chrome',
javascript_enabled: true,
css_selectors_enabled: true,
# In order to use the grid code generation, you need to be connected t
o the cloud
:accessKey=> '<YOUR ACCESS KEY>'
}

©2023 Digital.ai Inc. All rights reserved Page 431


Test Execution

@driver = Selenium::WebDriver.for(:remote, :url => '<server>', :desired_ca


pabilities => desired_caps)
end

def test_selenium_on_chrome
@driver.navigate.to "https://seetest.io"

wait = Selenium::WebDriver::Wait.new(:timeout => 10)


wait.until{@driver.find_element(:xpath => "//*[text()='Manual']")}
manual_nav_link = @driver.find_element(:xpath, "//*[text()='Manual']")
manual_nav_link.click

automation_nav_link = @driver.find_element(:xpath, "//*[text()='Automation'


]")
automation_nav_link.click

webinar_footer_link = @driver.find_element(:xpath, "//*[text()='Webinars']"


)

webinar_footer_link.click

webinars_h2_title_text = @driver.find_element(:xpath, "//h2[1]").text

puts("The title of the first h2 is: " + webinars_h2_title_text)

end

def teardown
@driver.quit
end
end
Firefox with Ruby
require 'test/unit'
require 'selenium-webdriver'
# require 'selenium/webdriver/remote'

class Example < Test::Unit::TestCase


def setup
desired_caps = {
:testName=> 'Running Selenium on Firefox',
:platform=> 'ANY',
:browserName => 'firefox',
javascript_enabled: true,
css_selectors_enabled: true,
# In order to use the grid code generation, you need to be connected t
o the cloud
:accessKey=> '<YOUR ACCESS KEY>'

©2023 Digital.ai Inc. All rights reserved Page 432


Test Execution

@driver = Selenium::WebDriver.for(:remote, :url => '<server>', :desired_ca


pabilities => desired_caps)
end

def test_selenium_on_firefox
@driver.navigate.to "https://seetest.io"

wait = Selenium::WebDriver::Wait.new(:timeout => 10)


wait.until{@driver.find_element(:xpath => "//*[text()='Manual']")}
manual_nav_link = @driver.find_element(:xpath, "//*[text()='Manual']")
manual_nav_link.click

automation_nav_link = @driver.find_element(:xpath, "//*[text()='Automation'


]")
automation_nav_link.click

webinar_footer_link = @driver.find_element(:xpath, "//*[text()='Webinars']"


)

webinar_footer_link.click

webinars_h2_title_text = @driver.find_element(:xpath, "//h2[1]").text

puts("The title of the first h2 is: " + webinars_h2_title_text)

end

def teardown
@driver.quit
end
end
Internet Explorer with Ruby
require 'test/unit'
require 'selenium-webdriver'
# require 'selenium/webdriver/remote'

class Example < Test::Unit::TestCase


def setup
desired_caps = {
:testName=> 'Running Selenium on IE',
:initialBrowserUrl=> 'https://seetest.io',
:platform=> 'ANY',
:browserName=> 'internet explorer',
javascript_enabled: true,
css_selectors_enabled: true,
# In order to use the grid code generation, you need to be connected t

©2023 Digital.ai Inc. All rights reserved Page 433


Test Execution

o the cloud
:accessKey=> '<YOUR ACCESS KEY>'
}

@driver = Selenium::WebDriver.for(:remote, :url => '<server>', :desired_ca


pabilities => desired_caps)
end

def test_selenium_on_ie
@driver.navigate.to "https://seetest.io"

wait = Selenium::WebDriver::Wait.new(:timeout => 10)


wait.until{@driver.find_element(:xpath => "//*[text()='Manual']")}
manual_nav_link = @driver.find_element(:xpath, "//*[text()='Manual']")
manual_nav_link.click

automation_nav_link = @driver.find_element(:xpath, "//*[text()='Automation'


]")
automation_nav_link.click

webinar_footer_link = @driver.find_element(:xpath, "//*[text()='Webinars']"


)

webinar_footer_link.click

webinars_h2_title_text = @driver.find_element(:xpath, "//h2[1]").text

puts("The title of the first h2 is: " + webinars_h2_title_text)

end

def teardown
@driver.quit
end
end

Selenium with Serenity

To run your Selenium tests with Serenity and Cucumber ,follow this guide:

©2023 Digital.ai Inc. All rights reserved Page 434


Test Execution

Requirements:
• Download and install Java version 8 or above.
• Download and install IntelliJ IDE.
• Download and install Gradle latest version.

Clone starter project:


• Clone starter project from Experitest GitHub repository.
• Set the project SDK to Java 8 or above.

Add Web Driver capabilities and Continuous Testing


special capabilities:
All the capabilities are added to serenity.properties file (see example below).

Set Access Key

In order to run the test, set your access key:

• Get your access key


• Replace it with <YOUR_ACCESS_KEY>, in the sample configuration below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

// Web driver capabilities


webdriver.remote.url = <server>/wd/hub
webdriver.browserType = chrome

// Continuous testing capabilities


webdriver.accessKey = <YOUR_ACCESS_KEY>
webdriver.agentName = Agent_1

©2023 Digital.ai Inc. All rights reserved Page 435


Test Execution

webdriver.osName = Mac OS Monterey


webdriver.generateReport = true
webdriver.reportType = video

Run your Test:


In the IDE terminal make sure you are in the folder with build.gradle file and run the following command:

gradlew clean test

Authentication with Selenium

Obtain Your Access Key

Authentication as a user is performed using an accessKey.

The Access Key can either be passed as part of the capabilities or as part of the URL.

Capabilities authentication
For accessKey, use the following convention:

DesiredCapabilities dc = new DesiredCapabilities();


dc.setCapability("accessKey", "<accessKey>");

RemoteWebDriver driver = new RemoteWebDriver(new URL(cloudurl + "/wd/hub/"), d


c);

URL authentication
For accessKey, use the following convention:

WebDriver driver = new RemoteWebDriver(new URL("http://:" + accessKey + "@" +


host+":" + port + "/wd/hub/"), dc);

Grid Execution - Running Parallel Tests

Running tests in parallel on multiple devices, often requires using multi-threading in your test scripts. You can
either go with classic multi-threading implementation of the language you use to develop your test scripts, or
use a unit testing framework that handles threading for you.

Java

©2023 Digital.ai Inc. All rights reserved Page 436


Test Execution

• TestNG - highly recommended as it includes efficient and easy instantiation of multiple test instances.
• JUnit

C#

• NUnit

The number of parallel tests on cloud Grid depends on how many Grid Nodes you have in your cloud
account.

To know how many Grid Nodes you have, go to: More -> License -> No. Of Grid Nodes

For example: on this cloud Grid, one can run 10 tests in parallel.

For parallel test execution, it's recommended to create a separate GridClient instance for every Client
instance!

What happens to extra tests requests?


Queued Test

When you try to run tests in parallel and you don't have enough Grid Nodes, the requests that do not have
enough resources enter the Queued mode. When there are available resources, the tests will move to
the Running mode.

Example:

Scenario: Running 4 tests in parallel on a Grid that contains only 3 Grid Nodes.

We can see that the status of the fourth test request is Queued (waiting for resources) and the
other 3 requests are Running.

©2023 Digital.ai Inc. All rights reserved Page 437


Test Execution

When at least one of the Running tests' status turns into Finished, the fourth request status will turn
to Running

From Queued to Running

We can see that the status of the third test request has changed to Finished, and right after it (there are
enough resources), the fourth request is Running.

Grid Execution with Selenium

The following browsers have moved their default mode to be W3C standard:

• Chrome - Starting from version 75


• Safari - Starting from version 12
• Edge (Chromium) - Starting from version 77

Tests written in JAVA require Selenium jar version 3.14 and above.

There are two main aspects of running Selenium-based tests in the grid. The first aspect is initiating a test
session and the other is running tests in parallel on multiple devices.

Initiating a Test Session


To initiate a test session and run a Selenium-based test on the grid, certain capabilities must be specified in
the Desired Capabilities object. The capabilities are:

1. Authentication with Selenium


2. Cloud URL - the URL of the cloud.

In addition, the Selenium test desired capabilities may include more capabilities.

©2023 Digital.ai Inc. All rights reserved Page 438


Test Execution

Parallel Execution
If you run a test using the capabilities as they appear above, it will run on one browser only. However, if you
run this test on multiple threads, every thread creates a different instance of the test class which in turn
initiates another test request. Running tests in parallel require that you understand the concept of multi-
threaded execution (either by built-in specific language implementations or using unit testing frameworks). It
also requires that your license includes the ability to run tests on multiple nodes. For more information about
these two aspects, visit our documentation on the subject.

Setting test report status


There may be cases where the test developer may want to set the test report status manually.

For example,

1. If the test fails on the client-side (and not on Selenium Grid side) the test report generated will be with
Success status.
2. If the test can fail but the test code catches the exception and the test developer would not like this
failure to set the report status to Fail.

To set the test report status from the client code, one can use the commands:

driver.executeScript("seetest:client.setReportStatus", <test-status>, <error-m


essage>);
driver.executeScript("seetest:client.setReportStatus", <test-status>, <error-m
essage>, <stacktrace>);

Where test-status is:

• "true" or "passed" for success


• "skipped" for skipped
• everything else for fail

For example,

driver.executeScript("seetest:client.setReportStatus", "Skipped", "This test s


hould skip");
driver.executeScript("seetest:client.setReportStatus", "Failed", "Element text
is wrong", "java.lang.Throwable at ClientSideFailureTest.clientSideFailure(Cl
ientSideFailureTest.java:82) at ClientSideFailureTest.test(ClientSideFailureTe
st.java:76)");

©2023 Digital.ai Inc. All rights reserved Page 439


Test Execution

Add a step to test reports with the status


Users can add a step in the report from the client code.

driver.executeScript("seetest:client.report", <message>, <step-status>);

Where test-status is:

• "true" for success


• "false" for fail

For example,

driver.executeScript("seetest:client.report", "This step should passed", "true


");
or
driver.executeScript("seetest:client.report", "This step should failed", "fals
e");

Add steps group to the report


Users can add a group of steps in the report.

To begin a steps group, call the following command:

driver.executeScript("seetest:client.startStepsGroup", <group-name>);

To end a steps group, call the following command:

driver.executeScript("seetest:client.stopStepsGroup");

All the steps that appear between 'startStepsGroup' and 'stopStepsGroup' will be part of the group of the
steps.

For example,

driver.executeScript("seetest:client.startStepsGroup", <group-name>);
step_1
step_2
...
step_n
driver.executeScript("seetest:client.stopStepsGroup");

©2023 Digital.ai Inc. All rights reserved Page 440


Test Execution

Add a step to test reports before every 'it'


When users run more than one 'it' with one Driver, you can set testName for each 'it' in the report:

exports.config = {
...
onPrepare: function() {
jasmine.getEnv().addReporter({
specStarted: async function(result) {
await browser.executeScript('seetest:client.startGroup', '
+result.description+');
}
});
},

onComplete: () => {
browser.executeScript('seetest:client.stopGroup);');
console.log('onComplete');
},
...
specs: ['test.js']
}

Add test property (tag) to report

Users can add a test property (tag) to the report from the client code.

driver.executeScript("seetest:client.addTestProperty", <key>, <value>);

For example,

driver.executeScript("seetest:client.addTestProperty", "key", "value");

Download a file to your client computer in a grid session

Users can download a file from the Selenium Agent machine to the local machine in the grid session.

File size up to 50MB.

For example,

byte[] content = null;


Object res = driver.executeScript("seetest:client.getFile", "<SELENIUM_AGENT_F
ILE_NAME>");
content = Base64.getDecoder().decode((String) res);
FileUtils.writeByteArrayToFile(new File("<CLIENTS_FILE_PATH>"), content);

©2023 Digital.ai Inc. All rights reserved Page 441


Test Execution

List all your session's files in a grid session (Chrome only)


Users can list all the files that their session downloaded in the grid session.

The returned type is List<String>.

For example,

List<String> files = (List<String>) driver.executeScript("seetest:client.getFil


eList");
System.out.println("list: " + files);

Running with custom Firefox profile


Mostly used for client certificates.

Firefox saves client certificates in the profile but Selenium uses a temporary profile. To pass this issue we
need to add a capability that will make Selenium run with our custom profile.

First, we need to make a profile and load our certificate on it:

• Launch Firefox and click the menu icon found in the upper-right corner of the browser. After that, click
the Preferences icon.
• Go to the Certificates tab and then click the View Certificates button.
• The previous step should have launched the Firefox Certificate Manager. Click the Your
Certificates tab and then click the Import button.

©2023 Digital.ai Inc. All rights reserved Page 442


Test Execution

• The previous step should launch a browser that you can use to navigate to the directory where your
client certificate file (usually a PKCS12 file with the .p12 or .pfx extension) is stored. Select the file and
enter the required password. If you succeed, you should see a notification that says "Successfully
restored your security certificate(s) and private key(s)." (or something to that effect). Click OK to
proceed.

©2023 Digital.ai Inc. All rights reserved Page 443


Test Execution

• You should then see your newly imported certificate under the Your Certificates collection of your
Firefox Certificate Manager.

Now our custom profile is done.

To use it with selenium we need to take only the files named cert9.db and key4.db and pack them in a zip
file (You can zip the entire profile and not just the certificate part, but it is not recommended):

Now all that is left is to add the profile to the desired capabilities.

File file = new File("<PATH_TO_PROFILE_ZIP_FILE>");


String firefoxProfile = "";
try {
firefoxProfile = Base64.getEncoder().encodeToString(FileUtils.readFileTo
ByteArray(file));
} catch (IOException e) {
e.printStackTrace();
}
dc.setCapability(FirefoxDriver.PROFILE, firefoxProfile);

We will get a driver with the custom profile we supplied.

Grid - Performance Transaction Commands

A performance report is available when executing a transaction. The report contains the following
measurements from the browser:

1. Duration - The transaction durations in milliseconds.


2. Speed Index - Provides a computed overall score of how quickly the final content was painted.

©2023 Digital.ai Inc. All rights reserved Page 444


Test Execution

Note

• The above performance report is an example and can be viewed in SeeTest Reporter.
• To enable the Speed Index calculation in the report, please contact Continuous Testing Support.
• A transaction maximum time is 5 min. After 5 minutes transaction will be canceled
• The transaction will be canceled if driver.quit() is performed. No data will be saved

Report data:

1. The upper left-hand side is the transaction name and application data (name and version)
2. The upper right-hand side is the browser information (name, model, OS, Resolution, and Network
Profile)
3. The rectangles on the right show the measurements of the transaction

StartPerformanceTransaction
Start Performance Transaction collects data on the duration of the browser.

The command must be used with the following EndPerformanceTransaction

the parameter "App version" is for reporter use

©2023 Digital.ai Inc. All rights reserved Page 445


Test Execution

driver.executeScript("seetest:client.startPerformanceTransaction(\"App version
\")");

EndPerformanceTransaction
End Performance Transaction must be performed after StartPerformanceTransaction. It takes the collected
data on the duration and speed index of the test on the current browser and uploads it to SeeTest Reporter.

The collected data can be viewed under the transaction tab in SeeTest Reporter.

The parameter "Transaction name" is for reporter use


Object o = driver.executeScript("seetest:client.endPerformanceTransaction(\"Tr
ansaction name\")");
Example
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.net.MalformedURLException;
import java.net.URL;

public class PerformanceTransaction {


private RemoteWebDriver driver;

@Before
public void setUp() {
DesiredCapabilities dc = new DesiredCapabilities();
URL url = null;
try {
url = new URL("<Cloud URL>");
} catch (MalformedURLException e) {
e.printStackTrace();
}
dc.setCapability("username", "<username>");
dc.setCapability("password", "<password>");
driver = new RemoteWebDriver(url, dc);
}

@Test
public void PerformanceTransactionTest() {
driver.executeScript("seetest:client.startPerformanceTransaction(\"App
Version\")");
driver.get("https://www.netflix.com/il-en/login");
Object o = driver.executeScript("seetest:client.endPerformanceTransact
ion(\"TransactionName\")");
System.out.println(o.toString());

©2023 Digital.ai Inc. All rights reserved Page 446


Test Execution

@After
public void tearDown() {
driver.quit();
}
}

Har Recording
Network traffic (HAR) will not be recorded in the transaction if tunneling is turned on

Start/Stop captures HAR during transactions for a cloud browser. The capture will start when
startPerformanceTransaction is executed.

The capture will stop when endPerformanceTransaction is executed.

Recording HTTPS Traffic requires a configuration by the Cloud admin, for more instruction click here

HAR files are produced only after the end of the test, you can view/download them after the test is finished
and not during it's execution(for example in java written test the HAR file are produced after driver.quit()).

Parameters

capability Value Description


key String useNV

value boolean true/false (false by default)

After the test you can go to the report that has the HAR file attached you can view it by clicking the 3 dot
button at the right of the transaction's name:

©2023 Digital.ai Inc. All rights reserved Page 447


Test Execution

View HAR File Example


HAR files can be viewed using a HAR file viewer. The latest version of the HAR file viewer created by Jan
Odvarko ([email protected]), the project can be found here.

The purpose of this tool is to visualize the HTTP Archive (HAR) log files created by HTTP tracking tools.

These files contain a log of HTTP client/server conversation and can be used for additional analysis of e.g.
page load performance.

Basic usage
Preview tab in the HAR file viewer shows the list of HTTP requests recorded with all its basic details like

• method
• URL
• response status
• response (compressed and uncompressed)
• response time

©2023 Digital.ai Inc. All rights reserved Page 448


Test Execution

You can see further details by clicking on the plus icon:

©2023 Digital.ai Inc. All rights reserved Page 449


Test Execution

HAR tab in the HAR file viewer, you can inspect the "raw" values of the har file as JSON tree:

Private/Incognito mode

Selenium can open the browsers in private mode.

In order to open the browser in private mode, each browser requires different desired capabilities.

©2023 Digital.ai Inc. All rights reserved Page 450


Test Execution

Private mode in Chrome:

Private mode in Chrome


DesiredCapabilities dc = new DesiredCapabilities();

// ...

ChromeOptions options = new ChromeOptions();


options.addArguments("--incognito");
dc.setCapability("goog:chromeOptions", options);

RemoteWebDriver driver = new RemoteWebDriver(new URL(URL), dc);

Private mode in Firefox:

Private mode in Firefox


DesiredCapabilities dc = new DesiredCapabilities();

// ...

FirefoxOptions options = new FirefoxOptions();


options.addArguments("--private");
dc.setCapability("moz:firefoxOptions",options);

RemoteWebDriver driver = new RemoteWebDriver(new URL(URL), dc);

Private mode in Microsoft Edge:

Private mode in Microsoft Edge


DesiredCapabilities dc = new DesiredCapabilities();

// ...

Map<String, Object> edgeOptions = new HashMap<>();


edgeOptions.put("args", ImmutableList.of("-inprivate"));
dc.setCapability("ms:edgeOptions", edgeOptions);

RemoteWebDriver driver = new RemoteWebDriver(new URL(URL), dc);

Private mode in Internet Explorer:

Private mode in Internet Explorer is not supported.

CDP Support

Selenium 4 introduced a new API that utilizes CDP (Chrome DevTools Protocol) to allow the user to interact
with Chrome DevTools on Chromium-based browsers.

CDP is supported on Microsoft Edge and Chrome. Firefox only partially supports CDP API.

©2023 Digital.ai Inc. All rights reserved Page 451


Test Execution

CDP allows the user to do several things with the Chrome DevTools, we will describe some examples.

Listen to console logs


In this example, we will print the console logs of the browser.

Console logs test


private WebDriver driver;

@BeforeEach
void setUp() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, Browser.CHROME.browserNa
me());
dc.setCapability("accessKey", <ACCESS_KEY>);

driver = new RemoteWebDriver(new URL(<CLOUD_URL>), dc);


driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

@Test
void consoleLogsTest() {
driver = new Augmenter().augment(driver);
DevTools devTools = ((HasDevTools) driver).getDevTools();
devTools.createSession();
devTools.send(Log.enable());
devTools.addListener(Log.entryAdded(),
logEntry -> {
System.out.println("log: "+logEntry.getText());
System.out.println("level: "+logEntry.getLevel());
});
driver.get("http://the-internet.herokuapp.com/broken_images");
}

@AfterEach
public void tearDown() {
System.out.println("Report URL: "+ ((HasCapabilities) driver).getCapab
ilities().getCapability("reportUrl"));
driver.quit();
}

Change Geolocation
In this example, we will change the geolocation of the browser.

Geolocation test

©2023 Digital.ai Inc. All rights reserved Page 452


Test Execution

private WebDriver driver;

@BeforeEach
void setUp() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, Browser.CHROME.browserNa
me());
dc.setCapability("accessKey", <ACCESS_KEY>);

driver = new RemoteWebDriver(new URL(<CLOUD_URL>), dc);


driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

@Test
void geolocationTest() {
double expectedLatitude = 52.5043;
double expectedLongitude = 13.4501;

driver = new Augmenter().augment(driver);


driver.get("https://my-location.org/");

// Change geolocation
DevTools devTools = ((HasDevTools) driver).getDevTools();
devTools.createSession();
devTools.send(Emulation.setGeolocationOverride(Optional.of(expectedLat
itude),
Optional.of(expectedLongitude),
Optional.of(1)));

driver.get("https://my-location.org/");

// Extract new geolocation


double actualLatitude = Double.parseDouble(driver.findElement(By.xpath(
"//*[@id='latitude']")).getText());
double actualLongitude = Double.parseDouble(driver.findElement(By.xpat
h("//*[@id='longitude']")).getText());

Assertions.assertEquals(expectedLatitude, actualLatitude, "Wrong latit


ude");
Assertions.assertEquals(expectedLongitude, actualLongitude, "Wrong lon
gitude");
}

@AfterEach
public void tearDown() {
System.out.println("Report URL: "+ ((HasCapabilities) driver).getCapab
ilities().getCapability("reportUrl"));
driver.quit();
}

©2023 Digital.ai Inc. All rights reserved Page 453


Test Execution

Network interception
In this example, we will intercept network communication with the browser to show a message that we want.

Network interception test


private WebDriver driver;

@BeforeEach
void setUp() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, Browser.CHROME.browserNa
me());
dc.setCapability("accessKey", <ACCESS_KEY>);

driver = new RemoteWebDriver(new URL(<CLOUD_URL>), dc);


driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
}

@Test
void networkInterceptionTest() {
driver = new Augmenter().augment(driver);
NetworkInterceptor interceptor = new NetworkInterceptor(
driver,
Route.matching(req -> true)
.to(() -> req -> new HttpResponse()
.setStatus(200)
.addHeader("Content-Type", MediaType.HTML_UTF_8.toString())
.setContent(utf8String("Creamy, delicious cheese!"))));

driver.get("https://example-sausages-site.com");

String source = driver.getPageSource();


Assertions.assertTrue(source.contains("delicious cheese!"));
}

@AfterEach
public void tearDown() {
System.out.println("Report URL: "+ ((HasCapabilities) driver).getCapab
ilities().getCapability("reportUrl"));
driver.quit();
}

Additional Browser Capabilities Using digitalai:options

Use the JSON object digitalai:options to use Continuous Testing Capabilities.

©2023 Digital.ai Inc. All rights reserved Page 454


Test Execution

New Method
DesiredCapabilities dc = new DesiredCapabilities();
//w3c standard capabilites
dc.setCapability("browserName", "chrome");
dc.setCapability("browserVersion", "100");
//Continuous testing special capabilities
Map<String, Object> options = new HashMap<>();
options.put("testName", "selenium test");
dc.setCapability("digitalai:options", options)

Web Test Execution


wIn this section, we will show how to run Web Selenium tests on the grid.

Tests developed using Selenium can run on the grid and in parallel if required. All that is required is
modifying the capabilities of existing tests such that they include additional details such as cloud URL,
credentials for running tests on the grid and project name. Running tests in Selenium using the grid allows
you to expand the scope of your testing abilities, allowing you to run tests on multiple browsers of different
kinds and operating systems.

Below you can find resources that will help you set up and execute your Selenium-based tests on the grid.

• Supported Browsers
• WebdriverIO
• Protractor
• Web Tests Management
• NightWatchJS

Supported Browsers

The Browsers page in Digital.ai Continuous Testing displays all supported browser types (Chrome, Firefox,
Safari, Microsoft Edge), versions and operating systems that can run Selenium Automated and Manual tests.

Checking Browser Versions


1. Click on a browser type to see all available OS for this browser.
2. Click an OS to see all the version available for this browser type and OS combination.

For example, for Chrome on Mac OS Big Sur, we have version 97 available for testing.

©2023 Digital.ai Inc. All rights reserved Page 455


Test Execution

If a browser name is grayed out, it means that it is not available for testing.

For example, here, Safari browser is not available for testing.

©2023 Digital.ai Inc. All rights reserved Page 456


Test Execution

Fully Supported Browsers


These browsers are being tested daily to ensure high quality performance.

Browser Versions
Chrome latest 5 versions and beta version.

Firefox latest 5 versions and beta version.

Microsoft Edge latest 5 versions and beta version.

Safari latest 3 versions.

Additional supported browsers


For the full list of supported browsers for Digital.ai Continuous Testing visit this page.

Choosing a Client
For best behavior we recommend using the latest version of the client for the framework of your choosing:

Client Releases page


Selenium (java/Ruby/Python) Selenium releases page

WebDriverIO WebDriverIO releases page

NightWatchJS NightWatchJS releases page

We do not recommend using deprecated clients like Selenium 2 and Protractor. These clients are not tested
daily and their behavior is unpredictable

Working with Chrome Devtools Protocol (CDP)


To properly work with CDP commands, you have to choose a matching pair of Selenium client version and
browser version, check the client version and supported browser versions in this page

We recommend using the latest version of Selenium client to properly work with the latest browsers.

Ask your Cloud Administrator if you need to add more browsers.

©2023 Digital.ai Inc. All rights reserved Page 457


Test Execution

WebdriverIO

• Authentication with WebdriverIO


• Grid Execution with WebdriverIO

Authentication with WebdriverIO


Authentication can be done either with a username and password or with an accessKey.

The username and password or accessKey can either be passed as part of the capabilities.

Since WebDriverIO version 7.0.0, authentication is possible with access key only

Capabilities authentication
For username and password, use the following convention:

wdio.conf.js
exports.config = {
......
capabilities: [{
username : <cloudUsername>,
password : <cloudPassword>,
projectName : <cloudProject>,
.....
}],
...
}

For accessKey, use the following convention:

wdio.conf.js
exports.config = {
......
capabilities: [{
'experitest:accessKey' : <accessKey>,
.....
}],
...
}

Grid Execution with WebdriverIO


There are two main aspects of running WebdriverIO tests in the grid. The first aspect is initiating a test
session and the other is running a test in parallel on multiple devices.

©2023 Digital.ai Inc. All rights reserved Page 458


Test Execution

Initiating a Test Session


To initiate a test session and run a WebdriverIO test on the grid, certain capabilities must be specified in the
Desired Capabilities object. The capabilities are:

1. Authentication with WebdriverIO


2. Cloud URL - the URL of the cloud.

In addition, the WebdriverIO test desired capabilities may include the following capabilities:

• testName - Specifies the test name. This name will appear in SeeTest Reporter and in the generated
report
• generateReport - By default every WebdriverIO test generates a report and takes screenshots after
each command. To disable reports (and screenshots) pass this capability with a false value
• takeScreenshots - take a screenshot of reports and the device reflection in the Grid page
• platformName - run the test on the specified platform (Mac, Windows, iOS, etc...)
• browserName - run the test on the specified browser (default is chrome)
• browserVersion - run the test on the specified browser version (check which version are supported in
your lab)
• waitforTimeout - Default timeout for all waitFor* commands.
• connectionRetryTimeout - Default timeout in milliseconds for request if Selenium Grid doesn't send a
response.

In order to use Continuous Testing additional capabilities, you should use the following format:

'experitest:testName' : 'here is the test name',

If the WebdriverIO test is configured to generate a report when the test is finished a detailed report will be
created in SeeTest Reporter.

Below you can find an example written in Javascript specifying the capabilities above.

WebdriverIO- Grid Execution


exports.config = {
host: '<cloudurl>',
port: <port>,
path: '/wd/hub',
protocol: 'https', //or http if the cloud doesn't use SSL

©2023 Digital.ai Inc. All rights reserved Page 459


Test Execution

maxInstances: 10, //how many tests should run in parallel

capabilities: [{
'experitest:generateReport' : false,
'experitest:takeScreenshots' : false,
'browserName': 'chrome',
'platformName': 'mac',
'browserVersion': '61'
}],

waitforTimeout: 60000,
connectionRetryTimeout: 90000,

......
}

Parallel Execution
If you run a test using the capabilities as they appear above, it will run on one device only. However, if you
run this test on multiple threads, every thread creates a different instance of the test class which in turn
initiates another test request. Running tests in parallel requires that you understand the concept of multi-
threaded execution (either by built-in specific language implementations or using unit testing frameworks). It
also requires that your license includes the ability to run tests on multiple nodes. For more information about
these two aspects, visit our documentation on the subject.

Protractor

• Authentication with Protractor


• Grid Execution with Protractor

Authentication with Protractor


Authentication can be done either with a username and password or with an accessKey.

The username and password or accessKey can either be passed as part of the capabilities.

Capabilities authentication
For username and password, use the following convention:

©2023 Digital.ai Inc. All rights reserved Page 460


Test Execution

protractor.conf.js
exports.config = {
......
capabilities: {
'username': <cloudUsername>,
'password': <cloudPassword>,
'projectName': <cloudProject>,
.....
},
...
};

For accessKey, use the following convention:

protractor.conf.js
exports.config = {
......
capabilities: {
'accessKey': <accessKey>,
.....
},
...
};

Grid Execution with Protractor


There are two main aspects of running Protractor tests in the grid. The first aspect is initiating a test session
and the other is running test in parallel on multiple devices.

Initiating a Test Session


To initiate a test session and run a Protractor test on the grid, certain capabilities must be specified in the
Desired Capabilities object. The capabilities are:

1. Authentication with Protractor


2. Cloud URL - the URL of the cloud.

In addition, the Protractor test desired capabilities may include the following capabilities:

• testName - Specifies the test name. This name will appear in SeeTest Reporter and in the generated
report
• generateReport - By default every Protractor test generates a report and takes screenshots after each
command. To disable reports (and screenshots) pass this capability with a false value
• takeScreenshots - take a screenshot of reports and the device reflection in the Grid page
• platformName - run the test on the specified platform (Mac, Windows, iOS, etc...)

©2023 Digital.ai Inc. All rights reserved Page 461


Test Execution

• browserName - run the test on the specified browser (default is chrome)


• browserVersion - run the test on the specified browser version (check which version are supported in
your lab)

• newCommandTimeout - change the default timeout for each command in the test (default is 300
seconds)

• newSessionWaitTimeout - change the default timeout for creating a new driver (default is 300 seconds)

If the Protractor test is configured to generate report, when the test is finished a detailed report will be
created in SeeTest Reporter.

Below you can find an example written in Javascript specifying the capabilities above.

Protractor- Grid Execution


exports.config = {
capabilities: {
'generateReport':false,
'takeScreenshots':false,
'browserName': 'chrome',
'platformName': 'mac',
'browserVersion': '61',
'accessKey': '<accessKey>' // can be use instead of username,password
and project.
//'username': '<cloudUsername>',
//'password': '<cloudPassword>',
//'projectName': '<cloudProject>' //only required if your user
has several projects assigned to it. Otherwise, exclude this capability.
},

seleniumAddress: 'http://yourcloudaddress:port/wd/hub', //use ht


tps if the cloud doesn't use SSL
......
};

Parallel Execution
If you run a test using the capabilities as they appear above, it will run on one device only. However, if you
run this test on multiple threads, every thread creates a different instance of the test class which in turn
initiates another test request. Running tests in parallel requires that you understand the concept of multi-
threaded execution (either by built-in specific language implementations or using unit testing frameworks). It
also requires that your license includes the ability to run tests on multiple nodes. For more information about
these two aspects, visit our documentation on the subject.

©2023 Digital.ai Inc. All rights reserved Page 462


Test Execution

Web Tests Management

SeeTest Cloud acts as a Selenium Hub.

Every Selenium test that passes via SeeTest Cloud and has started running, creates a Test Request.

The user can cancel a Selenium Test by canceling its associated Test Request.

When the test is finished, a report is generated and uploaded to SeeTest Test Analytics.

©2023 Digital.ai Inc. All rights reserved Page 463


Test Execution

Pressing the "EXTERNAL REPORT" button opens the generated report in a new tab:

NightWatchJS

• Grid Execution with NightWatchJS


• Authentication with NightWatchJS

©2023 Digital.ai Inc. All rights reserved Page 464


Test Execution

Grid Execution with NightWatchJS


There are two main aspects of running NightWatchJS tests in the grid. The first aspect is initiating a test
session and the other is running a test in parallel on multiple browsers.

Initiating a Test Session


To initiate a test session and run a NightWatchJS test on the grid, certain capabilities must be specified in the
Desired Capabilities object. The capabilities are:

1. Authentication with NightWatchJS


2. Cloud URL - the URL of the cloud.

In addition, the NightWatchJS test desired capabilities may include the following capabilities:

• testName - Specifies the test name. This name will appear in SeeTest Reporter and in the generated
report
• generateReport - By default every NightWatchJS test generates a report and takes screenshots after
each command. To disable reports (and screenshots) pass this capability with a false value
• takeScreenshots - take a screenshot of reports and the device reflection in the Grid page
• platformName - run the test on the specified platform (Mac, Windows, iOS, etc...)
• browserName - run the test on the specified browser (default is chrome)
• browserVersion - run the test on the specified browser version (check which version are supported in
your lab)

• newCommandTimeout - change the default timeout for each command in the test (default is 300
seconds)

• newSessionWaitTimeout - change the default timeout for creating a new driver (default is 300 seconds)

In order to use Continuous Testing additional capabilities, you should use the following format:

testName : 'here is the test name',

If the NightWatchJS test is configured to generate a report when the test is finished a detailed report will be
created in SeeTest Reporter.

Below you can find an example written in Javascript specifying the capabilities above.

NightWatchJs - Grid Execution


module.exports = {
selenium : {

©2023 Digital.ai Inc. All rights reserved Page 465


Test Execution

start_process : false,
selenium_host : '<cloudurl>',
server_path:'/wd/hub',
selenium_port : <port>
},

test_settings : {
default : { //default environment
selenium_port : <port>,
selenium_host : '<cloudurl>',
use_ssl : true, //or false if the cloud doesn't use SSL
desiredCapabilities : {
browserName:'chrome',
platformName:'mac',
accessKey : '<ACCESS_KEY>',
testName : 'NighwatchJSTest',
javascriptEnabled : true,
takeScreenshots : true,
newCommandTimeout : 300,
newSessionWaitTimeout : 300
}
}
}
};

Authentication with NightWatchJS


Authentication can be done either with a username and password or with an accessKey.

The username and password or accessKey can be passed as part of the capabilities.

Capabilities authentication
For username and password, use the following convention:

nightwatch.conf.js
exports.config = {
......
test_settings : {
default : {
......
desiredCapabilities : {
username : <cloudUsername>,
password : <cloudPassword>,
projectName : <cloudProject>,
.....
}

©2023 Digital.ai Inc. All rights reserved Page 466


Test Execution

}
}
...
}

For accessKey, use the following convention:

nightwatch.conf.js
exports.config = {
......
test_settings : {
default : {
......
desiredCapabilities : {
.....
accessKey: <accessKey>,
.....
}
}
}
...
}

Automating Windows Alerts and Popups


Important

• AutoIt scripts work on windows only.


• Works with AutoIt3 only.

Selenium Agent is able to run native scripts with AutoIt. To run a native script use the command:

driver.executeScript("seetest:client.runAutomationScript("Your script")", [TIM


EOUT_IN_MSEC]);

Please note

• Every line in the script should end with a "\n" character.


• Strings passed in the script should be in ' and not ".
• Timeout is the time frame in which the script should be done, default is 20 seconds.

The script will run on Selenium Agent's machine and will throw an error if the script fails or hit a timeout of 20
seconds.

Example
import org.junit.After;
import org.junit.Before;

©2023 Digital.ai Inc. All rights reserved Page 467


Test Execution

import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.net.MalformedURLException;
import java.net.URL;

public class PerformanceTransaction {


private RemoteWebDriver driver;

@Before
public void setUp() {
DesiredCapabilities dc = new DesiredCapabilities();
URL url = null;
try {
url = new URL("<Cloud URL>");
} catch (MalformedURLException e) {
e.printStackTrace();
}
dc.setCapability("username", "<username>");
dc.setCapability("password", "<password>");
dc.setCapability("platformName", CapabiltyType.WINDOWS);
driver = new RemoteWebDriver(url, dc);
}

@Test
public void automationScriptTest() {
String script = "WinWaitActive('Windows Security')\nSend('[USER
]')\nSend('[PASS]')\nSend('[ENTER]')";
String ret = (String) driver.executeScript("seetest:client.runA
utomationScript", script, 20000);

System.out.println(ret);
}

@After
public void tearDown() {
driver.quit();
}
}

Cypress
Cypress is a front-end testing tool for web applications using modern JavaScript frameworks.

Cypress enables you to write these types of tests:

©2023 Digital.ai Inc. All rights reserved Page 468


Test Execution

• End-to-end tests
• Integration tests
• Unit tests

It can test anything that runs on a browser.

Requirements
Cypress Support is available only in SaaS clouds.

In order to run Cypress projects in Cloud, you need to have a Docker Swarm and Execution Service set up in
your environment.

Cypress projects are run inside containers in Docker Swarm using the Execution Service API.

In order to run Cypress project Cloud, you need to have Browser license.

Execution Service API


The role of the user performing the Rest Operation is specified by the Authorization header.

For a detailed example see How To Execute Rest API.

Start a Cypress Execution

This enables users to run Cypress projects.


Cypress projects are run asynchronously. The response received is immediate.
Our Cypress support includes version 10.

POST /api/v1/executions

Parameters

Name Type Mandatory Description


type String Yes Specify execution type. For Cypress use Cypress.

project File Yes The Cypress project to run.


Compress the entire Cypress project and select the .zip file.
A valid project contains a cypress.json file in the root directory.

conf JSON String No A configuration file for the requested execution.


Please read the next section for more information about the configuration.

POST Cypress Execution Response


{
"status": "SUCCESS",

©2023 Digital.ai Inc. All rights reserved Page 469


Test Execution

"data": {
"Test Run Id": "3520546",
"Link to Reporter": "https://CLOUD_SERVER/reporter/#/test-view-view/-1
?testView={%22byKey%22:%22test.run.id%22,%22byKeyValue%22:%223520546%22}"
},
"code": "OK"
}

Cypress Configuration

In order to run Cypress project, a configuration must be supplied.


There are 2 options to add configuration:

• Add the conf parameter as a JSON string to the POST request.


• Create a file named digitalai.json with the required configuration in the root directory of the project.

If both options are used, the file is ignored.

Configuration Parameters:

Name Type Mandatory Description


browsers List Yes

A list of browser names and cypress versions to run the project on. Each entry in
the list is as follows:

{
"browser": "browser name"
"imageVersion": "cypress image version"
}

Supported browsers are Chrome, Firefox and Electron.

runTags Map No

A map of tags and their values to add to the report of each test in the project. For
example:

{
"tag 1": "tag 1 value"
"tag 2": "tag 2 value"
}

exclude List No

A list of test names to exclude from the project while running. For example:

©2023 Digital.ai Inc. All rights reserved Page 470


Test Execution

Name Type Mandatory Description

"exclude":
[
"actions.spec.js",
"badTest.spec.js"
]

npm_dependencies List No

A list of npm dependencies that need to be installed before running the project.
For example:

"npm_dependencies":
[
"npm-package1",
"npm-package2",
...
]

runConfFile String No

A configuration file to run the project with. This file must be located in the root
directory.

"myConfigFile.json"

Cypress configuration example


{
"browsers": [{
"browser": "chrome",
"imageVersion": "8.3.0"
},
{
"browser": "chrome",
"imageVersion": "8.2.0"
},
{
"browser": "firefox",
"imageVersion": "8.2.0"
},
{
"browser": "electron",
"imageVersion": "8.1.0"
}

©2023 Digital.ai Inc. All rights reserved Page 471


Test Execution

],
"runTags": {
"tag 1" : "tag 1 value",
"tag 2" : "tag 2 value",
"tag 3" : "tag 3 value"
},
"exclude": [
"actions.spec.js",
"badTest.spec.js"
],
"npm_dependencies": [
"npm-package1",
"npm-package2"
],
"runConfFile": "myConfigFile.json"
}

Get Cypress Execution Status

This obtains the Cypress execution status based on execution ID.

The ability to obtain an execution status depends on the user type.

• A user can get only his own session status.


• A project admin can get his own session status and the statuses from other users of his project.
• An admin can get any session status on his cloud.

GET /api/v1/executions/{Execution_ID}/status

Get Cypress Execution Response


{
"code": "OK",
"data": {
"Test Run Id": "3023f8be-783e-4b70-b830-3ca2e4bd3f7a",
"Test Run State": "RUNNING",
"Number of requested browsers": "2",
"Number of browsers completed": "0",
"Number of browsers running": "2",
"Number of browsers in queue": "0",
"Link to Reporter": "https://CLOUD_SERVER/reporter/reporter/dashboard/
#/test-view-view/-1?testView=%7B%22byKey%22:%22test.run.id%22,%22byKeyValue%22
:%223023f8be-783e-4b70-b830-3ca2e4bd3f7a%22%7D"
},
"status": "SUCCESS"
}

©2023 Digital.ai Inc. All rights reserved Page 472


Test Execution

Cancel Cypress Execution

This cancels a Cypress execution project by execution ID.

The ability to cancel an execution depends on the user type.

• A user can cancel only his own execution.


• A project admin can cancel his own execution executions from other users of his project.
• An admin can cancel any execution on his cloud.

PUT /api/v1/executions/{executionId}/actions/cancel

Response if session canceled successfully


Execution session id - <session id> canceled
Response if user has no privileges to cancel the session
{
"status": "ERROR",
"data": {
"User": "Security Error"
},
"code": "FORBIDDEN"

Get Cypress Execution Logs

This gets the logs of a certain Cypress run.

The ability to obtain the logs of a run depends on the user type.

• A user can get only his own session logs.


• A project admin can get his own session logs and from other users of his project.
• An admin can get any session logs on his cloud.

GET /api/v1/executions/{Execution_ID}/logs

The response is a zip file with the logs or an error message if any error occurred.

Playwright
Playwright is a testing tool for web applications using modern JavaScript frameworks. It enables you to write
end-to-end tests, and can test anything that runs on a browser.

©2023 Digital.ai Inc. All rights reserved Page 473


Test Execution

Playwright support is available only in SaaS clouds.

In order to run Playwright jobs in the Cloud, you need to have a Docker Swarm and Execution Service set up
in your environment.

Playwright projects are run inside containers in a Docker Swarm using the Execution Service API.

In order to run a Playwright project Cloud need to have Browser license.

Playwright Project
A Playwright project requires a configuration. The configuration contains a list of browsers and image
versions.

The list of browsers be supplied in a file named playwright.config.js which must be located in the root folder.
In this case, the image versions are supplied separately and apply to all browsers.

playwright.config.js
projects: [
{
name: 'browser name'
},

...
,
{
name: 'browser name'
}
]

If the playwright.config.js file is not supplied, this information must be supplied with the Image Versions.

Image Versions

The image versions must be provided. You can do this in one of these ways:

• conf parameter as a JSON string to the POST request.


• File named digitalai.json with the required configuration in the root directory of the project.

If you use both options, the conf parameter is used.

©2023 Digital.ai Inc. All rights reserved Page 474


Test Execution

Conf Parameter

Name Type Mandatory Description


browsers List Yes

A list of browser names and playwright versions to run the project on. If
playwright.config.js is not used, this is the format:

{
"browser": "browser name"
"imageVersion": "playwright image version"
}

When playwright.config.js is used, this is the format:

{
"imageVersion": "playwright image version"
}

Supported browsers are Chromium, Firefox, and Webkit.

digitalai.json

digitalai.json File With No playwright.config.js File


{
"browsers": [{
"browser": "chromium",
"imageVersion": "1.28.0"
},
{
"browser": "firefox",
"imageVersion": "1.28.1"
},
{
"browser": "webkit",
"imageVersion": "1.28.1"
}
]
}
digitalai.json File With playwright.config.js File
{
"browsers": [{
"imageVersion": "1.28.0"
},
{

©2023 Digital.ai Inc. All rights reserved Page 475


Test Execution

"imageVersion": "1.28.1"
}
]
}

NPM Dependencies

A Playwright project can contain a package.json file where you can add your NPM dependencies. To run a
Playwright project with external NPM packages:

1. Add the required packages to the project's package.json file.


2. Add package.json to the project zip.
3. Make sure the file is located in the root folder of the project.

Execution Service API


The role of the user performing the Rest Operation is specified by the Authorization header. For a detailed
example see How To Execute Rest API.

Several API calls are used for Playwright projects. The ability to perform operators on projects depends on
your permissions level:

• User - You can perform operations on your jobs only.


• Project Administrator - You can perform operations on any jobs in your project.
• Cloud Administrator - You can perform operations on all jobs in your Cloud.

Execute a Playwright Job

Playwright projects are run asynchronously. The response received is immediate.

POST /api/v1/executions

Parameters

Name Type Mandatory Description


type String Yes Specify execution type. For Playwright use 'Playwright'.

project File Yes Playwright project in a zip file.


See Playwright Project for more information.

conf JSON String No A configuration file for the requested execution.


See Playwright Project for more information.

©2023 Digital.ai Inc. All rights reserved Page 476


Test Execution

POST Playwright Execution Response


{
"status": "SUCCESS",
"data": {
"Test Run Id": "3520546",
"Link to Reporter": "https://CLOUD_SERVER/reporter/#/test-view-view/-1
?testView={%22byKey%22:%22test.run.id%22,%22byKeyValue%22:%223520546%22}"
},
"code": "OK"
}

Get Playwright Execution Status

GET /api/v1/executions/{Execution_ID}/status

Get Playwright Execution Response


{
"code": "OK",
"data": {
"Test Run Id": "3023f8be-783e-4b70-b830-3ca2e4bd3f7a",
"Test Run State": "RUNNING",
"Number of requested browsers": "2",
"Number of browsers completed": "0",
"Number of browsers running": "2",
"Number of browsers in queue": "0",
"Link to Reporter": "https://CLOUD_SERVER/reporter/reporter/dashboard/
#/test-view-view/-1?testView=%7B%22byKey%22:%22test.run.id%22,%22byKeyValue%22
:%223023f8be-783e-4b70-b830-3ca2e4bd3f7a%22%7D"
},
"status": "SUCCESS"
}

Cancel Playwright Execution

You can cancel a Playwright execution job using its run id.

PUT /api/v1/executions/{executionId}/actions/cancel

Response If Session Canceled Successfully


Execution session id - <session id> canceled
Response If User Has No Privileges to Cancel the Session

©2023 Digital.ai Inc. All rights reserved Page 477


Test Execution

{
"status": "ERROR",
"data": {
"User": "Security Error"
},
"code": "FORBIDDEN"

Get Playwright Execution Logs

GET /api/v1/executions/{Execution_ID}/logs

The response is a zip file with the logs or an error message if any error occurred.

Best Practices and Tips


Wondering what are the best design patterns and considerations that you should take while developing a test
automation framework? This section covers some of the industry's best practices and tips that could be
applied for test execution!

• Design Patterns - Page Object Model


• Parallel Tests Execution

Design Patterns - Page Object Model

Introduction
Creating tests for UI based applications using Selenium/Appium libraries have two parts,

• Locating the UI elements.

• Perform Operations on these elements and additionally assert some specific conditions.

But as the UI Screens become complex with many pages and elements, corresponding automated tests also
become more complex and un-maintainable.

Adding to this misery is when more automation engineers continue to add and extend tests, a lot of code
gets duplicated and any change in UI functionality can lead to substantial changes in tests.

©2023 Digital.ai Inc. All rights reserved Page 478


Test Execution

To address these issues, developers have taken the approach of formalizing a Design Pattern called Page
Object Model (POM)

The POM design pattern dictates that there should be a separation between test classes, and pages
(business objects), this methodology allows test projects to decouple responsibilities (tests VS. page logic)
and expand their projects rapidly.

Quick and Easy - Clone our Page Object Model Repository


Now that you are all set, with basics of Page Object Model. Let's try out a sample to demonstrate POM in
action.

1. Find the sample test in our git repository.


2. Fork the repository.
3. Edit the test and hit Run

Before you proceed with fetching the sample tests, you will have to do two more things, very simple but
important ones:

1. If you plan to test a native or hybrid app - Upload your app to your project
2. Fetch your access key

Example (Legacy Style Tests)


The code snippet below shows Java-based test classes implemented using TestNG framework.

public class TestClass1 {

@BeforeClass
public void init() {
// Initialize driver
}

@Test
public void testLogin() {
// LOGIN
driver.findElement(By.xpath("//*[@id='username']")).sendKeys();
driver.findElement(By.xpath("//*[@id='password']")).sendKeys();
driver.findElement(By.xpath("//*[@id=loginButton']")).click());

©2023 Digital.ai Inc. All rights reserved Page 479


Test Execution

}
}
public class TestClass2 {
@BeforeClass
public void init() {
// Initialize driver
}

public void testBuyTickets() {


// LOGIN
driver.findElement(By.xpath("//*[@id='username']")).sendKeys();
driver.findElement(By.xpath("//*[@id='password']")).sendKeys();
driver.findElement(By.xpath("//*[@id=loginButton']").click());

//Test Buy Tickets


driver.findElement(By.xpath("//*[@id=flightId']")).sendKeys();
driver.findElement(By.xpath("//*[@id=name']")).sendKeys();
driver.findElement(By.xpath("//*[@id=address']")).sendKeys();
driver.findElement(By.xpath("//*[@id=amt']"));
driver.findElement(By.xpath("//*[@id=buyTicket']")).click();
}
}

As you can see, login operation is duplicated in both test classes i.e. in TestClass1 and TestClass2. Over a
period of time, such duplicate code will increase leading affecting maintainability of test software.

Imagine if there is a slight change in the UI screen, all the affected tests have to be modified and reviewed
for validity. One more drawback in the test is that the UI functionality and tests are clustered together at one
place which makes code unorganized. It is easy to kick-start creating tests by using an approach discussed
above, but in the long term, this is not feasible and is not a great way to develop tests.

Page Object Model (POM)

Page Object Model is a design pattern which separates the UI elements and tests or operations performed
on those elements. Typically the UI elements and all its associated logic is implemented as Page Objects.
Tests are completely independent and perform operations on these Page Objects.

Implementation involves following steps:

1. Review the overall flow of UI Screens.

©2023 Digital.ai Inc. All rights reserved Page 480


Test Execution

2. Create a Page class for every UI screen.

3. A Page Class should return another Page class (via an operation) which represents the next screen in
a flow.

4. Create Test classes and test methods which perform operations on Page Objects.

Here is an example using the TestNG framework to develop a simple Test using POM.

1. Create a Page Object Base Class

package pageobjects;
public abstract class PageBase {
protected <AndroidElement> driver = null;

public PageBase(AndroidDriver androidDriver) {


driver = androidDriver;
}
}

2. Create a concrete Object Page Class

public class LoginPage extends PageBase {


private AndroidElement usernameElement;
private AndroidElement passwordElement;
private AndroidElement loginButtonElement;

/**
* Constructor
*/
public LoginPage(AndroidDriver androidDriver) {
super(androidDriver);
usernameElement = driver.findElement(By.xpath("//*[@id='usernameText
Field']"));
passwordElement = driver.findElement(By.xpath("//*[@id='passwordTextFiel
d']"));
loginButtonElement = driver.findElement(By.xpath("//*[@id='loginButton']
"));
}

©2023 Digital.ai Inc. All rights reserved Page 481


Test Execution

/**
* Login
* @param userName
* @param password
*/
public Page login(String userName, String password) {
usernameElement.sendKeys(userName);
passwordElement.sendKeys(password);
loginButtonElement.click();
return HomePage(driver);
}

3. Create Test Class

package tests;
**
* Tests for Example Application.
*/
public class ExampleAppTests {
private <AndroidElement> driver = null;

@Before
public void setUp() {
// Init Driver
driver = ....;
}

@Test
public void loginTest() {
try {
LoginPage loginPage = new LoginPage(driver);
loginPage.initialize(driver);
loginPage.login("company1121", "company1121");
}
catch(Exception e){
Assert.fail("Should not have thrown any exception" + e.getStackTra
ce());
}
}
@Test
public void loginTest() {
try {
LoginPage loginPage = new LoginPage(driver);
HomePage homePage = loginPage.login("company1121", "company1121");
homePage.buyTickets(....);
}

©2023 Digital.ai Inc. All rights reserved Page 482


Test Execution

catch(Exception e){
Assert.fail("Should not have thrown any exception" + e.getStackTra
ce());
}
}

From the example above, Tests (ExampleAppTests) are separated from the Page Objects and their
associated Elements (LoginPage ).

Summary
Page Object Model is a great way to develop tests for UI applications.

• Make Test Suites Structured, Maintainable and Reusable.

• The core strategy is to separate UI Locator logic to Page Objects and Test logic to Test Objects

Parallel Tests Execution


One of the advantages of executing tests in parallel is it speeds up the execution time of Tests which in turn
facilitates speeding up the Continuous Integration Process.

Parallelism in Continuous Testing cloud


Continuous Testing cloud and hosted services supports parallelism of Appium or Selenium tests by the
implementation of SeeTestGrid the grid is an extension of the current Selenium Grid model, and it supports
queuing tests and allocating agents based of desired capabilities to a test Session. seetest.io has the
capability to run concurrent tests for one or more users in your project.

Grid Execution provides more details on this concept.

©2023 Digital.ai Inc. All rights reserved Page 483


Test Execution

Parallelism in Automated Tests


Just having the support of parallelism in the Continuous Testing is not enough. In order to execute tests in
parallel for a specific client session,

1. Multi-Threading support of the language in which tests are developed can be used.
or
2. Parallel execution feature of Test Framework using which tests are developed can be made use of
and is the preferred solution.

We also need to ensure that to develop tests which can be executed simultaneously, we need to develop
tests adhering to some best practices.

They are,

• Independent Tests Methods: Tests should be independent of each other.


• Usage of thread safe references: Tests should use thread safe variables. For example, avoid the
usage of static references in the tests.
• Repeatable: Tests should return always the same results for the same version of the application and
test inputs.

As an example, let's discuss the support of parallel execution of tests in TestNG framework. Concepts
discussed in the section below will kick-start the process of building a reliable Parallel Tests.

Parallelism using TestNG


The quick and easy way :

Now that you are all set, with basics of Parallel test execution. Let's try out a sample to demonstrate these
concepts.

1. Find the sample test in our git repository.


2. Fork the repository.
3. Follow the steps in Readme packaged in the sample project and run the test using command gradlew
runTestsParallel.

Before you proceed with fetching the sample tests, you will have to do two more things, very simple but
important ones:

©2023 Digital.ai Inc. All rights reserved Page 484


Test Execution

1. If you plan to test a native or hybrid app - Upload your app to your project
2. Fetch your access key

Further Reading
Before we discuss parallel execution, here are some basics of TestNG.

TestNG provides a parallel attribute in testng.xml. Basically, this is a way to instruct TestNG's engine to run
tests in multiple threads.

The behavior of the thread execution depends upon what value this attribute is assigned in testng.xml.

Value Definition example in testng.xml Description


methods <suite name="My Run all your test methods in separate threads.
suite" parallel="methods">

tests <suite name="My Run all the methods in the same <test> tag in the same thread
suite" parallel="tests">

classes <suite name="My Run all the methods in the same class in the same thread, but each
suite" parallel="classes"> class will be run in a separate thread.

instances <suite name="My Run all the methods in the same instance in the same thread, but
suite" parallel="instances"> two methods on two different instances will be running in different
threads

Here is a simple example of testng.xml with parallel attribute.

TestNG with parallel attribute


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestNGRunParallelClassesExample" parallel="classes" verbose="2">
<!-- preserve-order=true ensures that the order is -->
<test name="TestNGRunParallelClassesExample">
<classes>
<class name="io.appium.testng.TestNGRunParallelClassesExample">
</classes>
</test>
</suite>

Although this looks simple yet the onus is on Test Developers to develop robust and reliable parallel
execution test mechanism. Let's take an example to elaborate on this.

Consider the following scenario,

©2023 Digital.ai Inc. All rights reserved Page 485


Test Execution

1. The parallel attribute is defined with a value of methods. This means that every test method defined
in TestNG class will be executed in a separate thread.

Parallel at mehods level


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestNGRunParallelClassesExample" parallel="methods" verbose="
2">
<!-- preserve-order=true ensures that the order is -->
<test name="TestNGRunParallelClassesExample">
<classes>
<class name="io.appium.testng.TestNGRunParallelClassesExample">
</classes>
</test>
</suite>

2. Appium or Selenium Driver is setup using @Beforeclass Annotation. This means that the Driver is set
up on once for a TestNG class.

WebDriver Creation in @BeforeClass


public class TestBase {
protected AndroidDriver<AndroidElement> driver = null;
@BeforeClass
public void setUp() {
driver = new AndroidDriver<>(new URL("https://cloud
.seetest.io/wd/hub"), dc);
}
@Test
public void test1() {
driver.findelement(By.xpath("//*[@id='test1']"));
}
@Test
public void test2() {
driver.findelement(By.xpath("//*[@id='test2']"));
}
}

The test developed using the strategy above will not give reliable results.

©2023 Digital.ai Inc. All rights reserved Page 486


Test Execution

The reason being that Appium Driver created in @BeforeClass annotated function is shared in all the test
methods. However, every test method is run in separate thread simultaneously. Sharing the same Driver
instance will make it thread-unsafe resulting in unreliable results.

So in such cases, it is best to use a parallel attribute with "classes" as value, this will ensure that all test
methods are run in same thread within a TestNG class.

If you choose to parallelism at methods level, Web Driver needs to be set up in every test methods to make
it thread-safe. Of course, this becomes very resource intensive since every test method will create a driver
instance.

WebDriver at @Test
public class TestBase {

private AndroidDriver<AndroidElement> driver = null;

@Test
public void test1() {
AndroidDriver<AndroidElement> driver = new AndroidDrive
r<>(new URL("https://cloud.seetest.io/wd/hub"), new DesiredCapabilities());
driver.findelement(By.xpath("//*[@id='test1']"));
}

@Test
public void test2() {
AndroidDriver<AndroidElement> driver = new AndroidDrive
r<>(new URL("https://cloud.seetest.io/wd/hub"), new DesiredCapabilities());
driver.findelement(By.xpath("//*[@id='test2']"));
}
}

Parallel Tests - Best Practices

This article builds on the article, Parallel Tests Execution and focuses more on the best practices to execute
tests in parallel.

In the original article, there are mentions of these practices, we will discuss those with more detail.

The example provided in this article is based on our Sample code. Below are the steps to get the sample
code.

©2023 Digital.ai Inc. All rights reserved Page 487


Test Execution

1. Find the sample test in our git repository.


2. Fork the repository.

Listed below are good practices that will go a long way for a successful implementation of parallel execution
of tests.

• Include parallelism at test design/development stage


• Independent Test methods
• Parallelism and Logging
• Avoid usage of static variables in tests
• Parallelism and Test Drivers

Include parallelism at test design/development stage


As discussed in the original article, running parallel tests strategy cannot be employed at the final stage of
test development and by just running tests in parallel. Parallelism needs to be thought at an early stage of
the design and development of the Test Suite.

Although most of the Test framework and their language provides a way to run a test in parallel, it has
observed that this is not enough. Significant changes need to be done in Tests to make this work.

Independent test methods/Tests


Tests should have a specific object and should not depend on another test. This is a very important
consideration and every test developer needs to be educated about this.

Let's discuss this with an example.

Dependent test methods example


@Test
public void eriBankLogin(@Optional("company") String userName, @Optional("comp
any") String password) {
LOGGER.info("Enter eriBankLogin - " + "userName = " + userName + " passwor
d = " + password);
// Find Element commands for Find Login elements.
driver.findElement(ELEMENTS.LOGIN_USER.getBy(TYPE.ANDROID)).sendKeys(userNa
me);
driver.findElement(ELEMENTS.LOGIN_PASS.getBy(TYPE.ANDROID)).sendKeys(passwo

©2023 Digital.ai Inc. All rights reserved Page 488


Test Execution

rd);
driver.findElement(ELEMENTS.LOGIN_BUTTON.getBy(TYPE.ANDROID)).click();
LOGGER.info("Exit eriBankLogin");
}

@Test (dataProvider = "makePaymentsData")


public void makePaymentTest(String phone, String name, String amount, String c
ountry) {
LOGGER.info("Enter makePaymentTest - Phone = " + phone + " name = "
+ name + " amount = " + amount + " country = " + country);
driver.findElement(ELEMENTS.PAYMENT_BUTTON.getBy(TYPE.ANDROID)).click();
driver.findElement(ELEMENTS.PHONE.getBy(TYPE.ANDROID)).sendKeys(phone);
driver.findElement(ELEMENTS.NAME.getBy(TYPE.ANDROID)).sendKeys(name);
driver.findElement(ELEMENTS.AMOUNT.getBy(TYPE.ANDROID)).sendKeys(amount);
driver.findElement(ELEMENTS.COUNTRY.getBy(TYPE.ANDROID)).sendKeys(country);
driver.findElement(ELEMENTS.SEND_PAYMENT_BUTTON.getBy(TYPE.ANDROID)).click(
);
driver.findElement(ELEMENTS.YES_BUTTON.getBy(TYPE.ANDROID)).click();
LOGGER.info("Exit makePaymentTest");
}

Two test methods i.e makePaymentsData and eriBankLogin are dependent on each other.

The test makePaymentsData assumes, that eriBankLogin will be called before and hence the state of the
user will be logged in. However, when tests are run in parallel or the order of the execution changes then
makePaymentTests will fail.

The sample code performs login operation @BeforeMethod, which ensures it will be always called before
executing any test method.

To conclude, It is of utmost importance to develop a method which is independent of each other.

Parallelism and Logging

When tests are run in parallel, it's not easy to figure out what exactly is happening at execution time. The
tester needs to know the sequence of the test suite and individual tests.

Generally, logs provide this information. Most of the popular languages achieve parallelism using "Threads".
Hence it is a matter of utmost importance that Thread Identifier should find a place in the logs.

Log generated when test executed in parallel WITHOUT thread identifier.

Without thread identifier

©2023 Digital.ai Inc. All rights reserved Page 489


Test Execution

INFO 28-11-2018 17:13:34,140 [TestNG] i.a.t.AndroidTestNGExampleTest: Enter i


nitDefaultDesiredCapabilities
INFO 28-11-2018 17:13:34,140 [TestNG] i.a.t.AndroidTestNGExampleTest: Setting
up Desired Capabilities
INFO 28-11-2018 17:13:34,139 [TestNG] i.a.t.IOSTestNGExampleTest: Enter initD
efaultDesiredCapabilities
INFO 28-11-2018 17:13:34,140 [TestNG] i.a.t.IOSTestNGExampleTest: Setting up
Desired Capabilities
INFO 28-11-2018 17:13:34,139 [TestNG] SeeTestProperties: --------- END ------
---
INFO 28-11-2018 17:13:34,142 [TestNG] SeeTestProperties: Exit loadInitPropert
ies() ...
INFO 28-11-2018 17:13:34,142 [TestNG] i.a.t.WebTestNGExampleTest: Enter initD
efaultDesiredCapabilities
INFO 28-11-2018 17:13:34,142 [TestNG] i.a.t.WebTestNGExampleTest: Setting up
Desired Capabilities
INFO 28-11-2018 17:13:34,150 [TestNG] i.a.t.IOSTestNGExampleTest: Device Quer
y = @os='ios'

Log generated when test executed in parallel WITH thread identifier

With Thread Identifier


INFO 28-11-2018 17:13:34,140 [TestNG:11] i.a.t.AndroidTestNGExampleTest: Ente
r initDefaultDesiredCapabilities
INFO 28-11-2018 17:13:34,140 [TestNG:11] i.a.t.AndroidTestNGExampleTest: Sett
ing up Desired Capabilities
INFO 28-11-2018 17:13:34,139 [TestNG:12] i.a.t.IOSTestNGExampleTest: Enter in
itDefaultDesiredCapabilities
INFO 28-11-2018 17:13:34,140 [TestNG:12] i.a.t.IOSTestNGExampleTest: Setting
up Desired Capabilities
INFO 28-11-2018 17:13:34,139 [TestNG:13] SeeTestProperties: --------- END ---
------
INFO 28-11-2018 17:13:34,142 [TestNG:13] SeeTestProperties: Exit loadInitProp
erties() ...
INFO 28-11-2018 17:13:34,142 [TestNG:13] i.a.t.WebTestNGExampleTest: Enter in
itDefaultDesiredCapabilities
INFO 28-11-2018 17:13:34,142 [TestNG:13] i.a.t.WebTestNGExampleTest: Setting
up Desired Capabilities
INFO 28-11-2018 17:13:34,150 [TestNG:12] i.a.t.IOSTestNGExampleTest: Device Q
uery = @os='ios'

As we can see from above, the second snippet of the log is much clearer to a user as it clearly gives an
indication that "AndroidTestNGExampleTest" is executed in thread "11".

There is also more clarity to the user how the tests were executed by the run-time engine.

©2023 Digital.ai Inc. All rights reserved Page 490


Test Execution

Avoid usage of static variables in tests


Using static variables should be avoided because in a parallel execution environment this will invariably
result in conflicts.

Let us consider the following example.

The code snippet is a Factory class that returns a driver which is static i.e one per class.

A Factory class to get appium driver


public class DriverFactory {
private static AppiumDriver driver;

public static AppiumDriver getDriver(DesiredCapabilities dc) {


if (driver == null) {
driver = new AndroidDriver("<seetest_cloud_url>", dc) :
}
return driver;
}
}

Assume two different tests try to make use of it.

Classes using Factory class for get the Driver


public class A {
@Test
public void testA() {
DesiredCapabilities dc = new DesiredCapabilities();
.
.
AppiumDriver driver = DriverFactory.getDriver();
.
.
driver.quit();
}
}

public class B {
@Test
public void testB() {

DesiredCapabilities dc = new DesiredCapabilities();


.
.
AppiumDriver driver = DriverFactory.getDriver();

©2023 Digital.ai Inc. All rights reserved Page 491


Test Execution

.
driver.quit();
}
}

Let's consider Class A and Class B belong to Test1 and Test2 respectively and both tests are run in parallel.

This would mean test methods, testA and testB both will grab the driver simultaneously and will lead to
conflicts.

Many such examples can be given which shows that using static variables is not a good idea for parallel
execution of tests and hence should be avoided.

Parallelism and Test drivers

Automation tests for Mobile and Web applications are generally achieved using test drivers provided by
libraries like Appium/Selenium.

Test driver for a Mobile application and browser

Parallelism can be achieved at different levels, Let us consider a test suite whose composition looks like the
diagram below.

©2023 Digital.ai Inc. All rights reserved Page 492


Test Execution

With regards to parallelism, Here are important observations.

1. Individual test methods like test-1-A and test-1-B can be run parallel.
2. Tests, Test-1 and Test-2 can be run parallel. In this case, individual test methods will be run in the
parent thread.

Choosing the first strategy will mean that the test driver needs to be created in the test methods to avoid
thread conflicts. This is becoming counterproductive because this will lead to frequent acquisition and
release of devices affecting the performance of the test.

It is hence recommended from seetest.io perspective to keep parallel execution in between tests i.e
multiple tests running in parallel which means test drivers to be setup per Test.

Appium driver setup at class/test level using TestNG framework


@BeforeClass
public void setUp(@Optional("android") String os, ITestContext testContext) {
DesiredCapabilities dc = DesiredCapabilities();
driver = os.equals("android") ?
new AndroidDriver(SeeTestProperties.SEETEST_IO_APPIUM_URL, dc) :
new IOSDriver(SeeTestProperties.SEETEST_IO_APPIUM_URL, dc);
.
.
}

Test driver for Browser only application


seetest.io cloud also provides browser only instances for testing.

Since browsers are less resource-intensive, it is fine to develop test suites with a view to run individual test
methods in parallel.

In such scenarios language concept such as Java's ThreadLocal is a good choice which ensures returned
drivers are per thread. Even if testA and testB are executed in parallel they will use a webdriver per thread
thus avoiding conflicts.

Web Driver in individual test method using ThreadLocal


public class WebTestExample {
...
private ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>()
;

protected void createWebDriver() {


// Launch and set for the current thread.
webDriver.set(new RemoteWebDriver(new URL("https://cloud.seetes
t.io:443/wd/hub"), capabilities));
}

©2023 Digital.ai Inc. All rights reserved Page 493


Test Execution

@Test
public void testA() {
// Get the driver for current thread.
WebDriver driver = createWebDriver().get();
....
}

@Test
public void testA() {
// Get the driver for current thread
WebDriver driver = createWebDriver().get();
....
}

Device Restrictions and Cleanup


Since our devices are public and shared, we enforce certain restrictions in terms of accessing device settings
and installing applications.

In addition, we employ a cleanup process after a device is released in order to provide the next tester with a
clean device that is ready for use.

• Device Restrictions
• Device Cleanup Cycle

Device Restrictions

Access to Device Settings


To make sure our devices stay intact, we restrict access to device settings by default.

If you try to launch device settings (iOS or Android) the application will be blocked from launching.

©2023 Digital.ai Inc. All rights reserved Page 494


Test Execution

Access to device settings is reserved to paying users only. If you wish to be granted access to device
settings, consider purchasing one of our plans.

In special cases, and according with requirements, we might grant access to device settings upon request. If
you are not a paying user and you wish to access device settings, please contact us. We reserve the right to
grant or deny access to device settings.d

Restricted Applications
Our system blocks a variety of applications according to standard security considerations. Any attempt to
install such restrict applications will result in immediate removal from our system.

Installing Applications not from the App Store or


Google Play
We cannot guarantee the successful installation of applications that were obtained from sources other than
App Store or Google Play.

In many cases, applications are configured such that they are only allowed to be installed and launched on
specific devices and under specific developer licenses.

We recommend that you upload and install applications that were built in debug configurations. See below to
learn how to produce Android or iOS applications in debug configuration:

• Preparing Your Android Application


• Preparing Your iOS Application

Device Cleanup Cycle

Once a device is released, a cleanup process then takes place.

The purpose of the cleanup purpose is to make sure that the next tester gets a clean device.

©2023 Digital.ai Inc. All rights reserved Page 495


Test Execution

The Cleanup Process


The cleanup process consists of the following steps:

1. Application Cleanup
2. Web Cleanup
3. Apple and Google Account Removal

Application Cleanup
Any application that was installed during a test session is removed once the device is released.

Keep in mind that if you run automated tests one after another, you cannot rely on the application to be
installed on the device. Since all applications are deleted at the end of a test session, you will have to
reinstall the application at the beginning of each test.

Web Cleanup
When a device is released from a test session, browser (Safari on iOS, Android on Chrome) cache and
cookies are deleted.

This means that the browser will hold no history or site related data.

Even though we clear browser cache and cookies, we strongly recommend that you sign out of any account
that you signed into during a test session.

Apple and Google Account Removal


Any Apple or Google accounts that you sign into during a test session are removed.

Even though remove such accounts, we strongly recommend that you sign out of any account that you
signed into during a test session.

©2023 Digital.ai Inc. All rights reserved Page 496


Test Execution

Integrations
Continuous Testing integrates with various Continuous Integration Tools and Frameworks.

Such frameworks and Integrations allows you to achieve following.

• Develop automated tests.


• Run automated tests and Verify the build.

For documentation on Continuous Integration and Frameworks please follow :

• Continuous Integrations
• Frameworks
• Analytics
• Digital.ai Application Protection
• Dai-CT Execution Command Line Interface

Continuous Integrations
Continuous Testing integrates with various Continuous Integration Tools. You can view the CI diagram to get
the hang of the CI process.

©2023 Digital.ai Inc. All rights reserved Page 497


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 498


Test Execution

Such integration allows you to run tests on your code and verify the build. If the build is successful the
process continues on to run tests on your application or mobile website. This way you can make sure that no
faulty code is integrated into the work of other developers.

Bitbucket

Bitbucket is a web hosted, source control service like GitHub. It allows you and your development team to
branch in and out for better source code control and regulated integration. Unlike GitHub, Bitbucket actually
allows you to build, run and test your code for CI/CD purposes. This is achieved through
Bitbucket Pipeline .

To use seetest.io with Bitbucket Pipeline, follow the instructions below:

1. Import any of our Sample Git Repositories

• Appium Test with Java


• Appium Test with C#
• Appium Test with Python
• Appium Test with Ruby

In Bitbucket click on Add (Plus sign on the left hand side)

©2023 Digital.ai Inc. All rights reserved Page 499


Test Execution

Click on Repository

©2023 Digital.ai Inc. All rights reserved Page 500


Test Execution

1. Choose import repository


2. Paste the repository URL
3. Click on Create Repository

©2023 Digital.ai Inc. All rights reserved Page 501


Test Execution

2. Enable Pipeline
Once Bitbucket has finished import the repository, you will have to enable the Pipeline. In your repository
click on Pipelines in the left-hand side panel. Bitbucket will recognize the bitbucket-pipelines.yml file that
we included in our sample repository. All that is left for you is to enable to pipeline.

To learn more about Bitbucket pipeline configuration, visit Bitbucket's documentation.

©2023 Digital.ai Inc. All rights reserved Page 502


Test Execution

The first build will fail because there is no Environment Variable that contains seetest.io access key. You can
simply stop the pipeline to prevent it from failing.

©2023 Digital.ai Inc. All rights reserved Page 503


Test Execution

3. Set Environment Variable

Click on Settings in the left hand side panel and under Pipelines choose Environment Variables.

Name the variable and put your Continuous Testing cloud platform's access key as value. Check the option
to secure the access key value.

4. Trigger a Build

In the left hand side panel click on Pipelines, click on the relevant pipeline and then click Rerun.

©2023 Digital.ai Inc. All rights reserved Page 504


Test Execution

circleci

circleci is an advanced CI/CD tool that lets you setup and run a customizable build-test-integration process.

To use circleci with your Continuous Testing, follow the steps below:

1. Fork Git Repository

Choose any of our git repositories and fork them.

• Appium Test with Java


• Appium Test with Python
• Appium Test with Ruby

Each git repository contains the .circleci directory with a config.yml file that specifies build properties and
build steps

To learn more about configuring your circleci pipeline .yml file, visit circleci documentation.

Currently, circleci does not support .NET, which means that C# projects cannot be run.

©2023 Digital.ai Inc. All rights reserved Page 505


Test Execution

2. Authorize GitHub in circleci

In your account click on Projects → Authorize GitHub:

©2023 Digital.ai Inc. All rights reserved Page 506


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 507


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 508


Test Execution

If you signed in using Google or some other Oauth service, simply authorize GitHub in your account.

©2023 Digital.ai Inc. All rights reserved Page 509


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 510


Test Execution

3. Choose your Organization

If you are part of an organization, you can choose the organization in order for circleci to get access to the
repositories under this organization

4. Set Access Key of Continuous Testing Cloud platform as an


Environment Variable

Go to Settings and under Projects click the cogwheel next to the relevant git repository:

©2023 Digital.ai Inc. All rights reserved Page 511


Test Execution

Set your access key as environment variable:

Get your Continuous Testing cloud platform's access key

©2023 Digital.ai Inc. All rights reserved Page 512


Test Execution

5. Trigger Build

Setup your project: go to Projects → Add Project. Next to the relevant repository click Setup Project. In
the next screen click Start Building. As your repository already contains the config.yml file, circleci will know
how to trigger the build.

We recommend referencing circleci's documentation to learn more about their robust CI abilities.

Jenkins

Jenkins is a free and open source Continuous Integration server. It is usually installed locally which makes it
easier to manage and monitor. It is robust, easy to use, and offers many helpful plugins for various purposes
such as integrating with GitHub, injecting environment variables, building .NET projects and many more.

To use seetest.io with Jenkins, follow the instruction below:

1. Download and Install Jenkins

Download Jenkins

Install Jenkins

It is highly recommended that you install the suggested plugins. You will be prompted to install them the first
time you access Jenkins after installation.

2. Fork any of our Sample Git Repositories

• Appium Test with Java


• Appium Test with C#
• Appium Test with Python
• Appium Test with Ruby

©2023 Digital.ai Inc. All rights reserved Page 513


Test Execution

3. Configure Git Credentials

In order for Jenkins to be able to check out the source code from your Git Repository, you need to provide
your Git Credentials. You will later choose these credentials when creating a new Jenkins Job.

From Jenkins main screen, go to Credentials → System → Global credentials (unrestricted). Click
on Add Credentials.

4. Create a new Jenkins Job

From Jenkins main screen, click on create new jobs. Name your project, choose Freestyle project and
click OK.

©2023 Digital.ai Inc. All rights reserved Page 514


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 515


Test Execution

5. Configure the Jenkins Job

Under the General Tab, check the box next to This project is parameterized, open the Add Parameter
drop-down list and choose Password Parameter.

Name the parameter SEETEST_IO_ACCESS_KEY and specify the access key of Continuous Testing user
account.

This will be added as an environment variable in build time. You can access this environment variable from
your code and pass it as access key in the desired capabilities.

Under the Source Code Management tab, choose Git, paste the desired repository in the Repository URL
field and choose your credentials that you setup in the step #3.

©2023 Digital.ai Inc. All rights reserved Page 516


Test Execution

6. Configure Build Steps

In order for Jenkins to be able to trigger the build properly regardless of the programming language you are
using, you will have to specify at least one build step.

Under the Build tab, click on Add build step.

The build step is different for each sample git repository that we provided. See below what build step needs
to be specified for each git repository.

• Jenkins Plugin
• Running a C# Jenkins Job
• Running a Java Jenkins Job
• Running a Python Jenkins Job
• Running a Ruby Jenkins Job

©2023 Digital.ai Inc. All rights reserved Page 517


Test Execution

Jenkins Plugin
The Jenkins Plugin is the ultimate solution for the Jenkins CI environment, which would like to automate
mobile application tests on both Android and iOS platforms.

It provides integration abilities with SeeTest SaaS and on-premise environments.

Configurations
After installing the plugin, check the option "Connect to Continuous Testing Cloud API" in your build
environment:

Then, you can add the Continuous Testing's cloud URL and Access Key on which you would like to execute.

Now you are ready to explore the features that the plugin provides:

• View the last Jenkins job reports


• Choose devices and browsers in Jenkins

©2023 Digital.ai Inc. All rights reserved Page 518


Test Execution

• Execute XCUItest and espresso in Jenkins


• Upload application in Jenkins

View the last Jenkins job reports


After running tests with Jenkins, you can see your results at the last build in your job.

At the end of the execution, get all the reports related to the execution in Jenkins as a table

How to use:

For builds that use XCUITest and Espresso build step, there is no change needed.

When running a jar or Git project using Jenkins we need to add a capability:

DesiredCapabilities dc = new DesiredCapabilities();


String project = System.getenv("JOB_BASE_NAME"); // Jenkins version 2.
X
if (project == null){
project = System.getenv("JOB_NAME"); // Jenkins version 1.X
}
String buildNumber = System.getenv("BUILD_NUMBER");
dc.setCapability("jenkins", project + "-" + buildNumber);

©2023 Digital.ai Inc. All rights reserved Page 519


Test Execution

Choose devices and browsers in Jenkins


After choosing credentials for Cloud, all available browsers and devices for the user will be shown in 2
different lists:

Devices list
This list will present the user with all available devices to choose from.
Chosen devices will be populated in the environment variable CONTINUOUS_TESTING_DEVICES in JSON
format.

Example
[
{
"udid": "1115fbd4746c2f05",
"deviceName": "Samsung S6 Edge",
"deviceOs": "Android",
"osVersion": "7.0",
"model": "SM-G928C",
"manufacturer": "samsung",
"deviceCategory": "PHONE",
"region": "Europe - Master",
"tags": [
"stable",
"new_device_2019"
"expensive"
]
}, {
"udid": "sfkgjhhsdjkfhs",
"deviceName": "Samsung S7",
"deviceOs": "Android",

©2023 Digital.ai Inc. All rights reserved Page 520


Test Execution

"osVersion": "8.0",
"model": "SM-G929C",
"manufacturer": "samsung",
"deviceCategory": "PHONE",
"region": "Europe - Master",
"tags": [
"stable",
"new_device_2019"
"expensive"
]
}
]

Browsers List
This list will present the user with all available browsers to choose from.
Chosen browsers will be populated in the environment variable CONTINUOUS_TESTING_BROWSERS in
JSON format.

Example
[
{
"browserName" : "MicrosoftEdge",
"browserVersion" : "90.0.478.25",
"platform" : "WIN10",
"osName" : "Windows 10",
"agentName" : "Bloop",
"region" : "Master"
}, {
"browserName" : "MicrosoftEdge",
"browserVersion" : "89.0.416.68",
"platform" : "WIN10",
"osName" : "Windows 10",
"agentName" : "Bloop",
"region" : "Master"
}
]

Execute XCUItest and espresso in


Jenkins
You can add a build step: "Execute XCUITest or Espresso tests" and provide some parameters in order to
execute XCUITest or Espresso tests on real devices/virtual devices located in Continuous Testing's cloud.

©2023 Digital.ai Inc. All rights reserved Page 521


Test Execution

Parameters:

• Framework Type: select Espresso or XCUItest


• Running type: Select Fast Feedback or Coverage.
◦ Fast Feedback - Get results for all the tests as soon as possible (will utilize all the devices that
match the device query)
◦ Coverage - Will run all the tests once on every device in the device query (you can write more
than one query)
• The application under test - Provide a path to the application location
• Test Application - the test application (containing all the tests)
• Device Query - List of strings (XPath queries). The tests will run on devices that match the provided
query (1 device per query).

Upload application in Jenkins


You can add a build step: Upload application to Cloud and specify the path to your application

Advanced options:

©2023 Digital.ai Inc. All rights reserved Page 522


Test Execution

• Provide UUID (Optional for iOS)


• Provide a unique app name
• Include touchID libraries and allow mocking fingerprint authentication
• Include Camera libraries and allow simulating camera options
• Custom Keystore (Optional for Android)
• Allow resigning of application (Optional for iOS)

Running a C# Jenkins Job

If you chose our C# Git Project, you will have to go through a few steps that include installing plugins and
adding command line utilities.

Installing Jenkins MSBuild plugin

For Jenkins to be able to run .NET builds you will have to install MSBuild plugin.

From Jenkins main screen, click on Manage Jenkins → Manage Plugins. In the plugins screen switch to
Available, search for MSBuild and install the plugin.

©2023 Digital.ai Inc. All rights reserved Page 523


Test Execution

Specifying the MSBuild Executable

From Jenkins main screen, click on Manage Jenkins → Global Tool Configuration. Look for MSBuild and
expand MSBuild installations.

Specify the build name and the path to the executable.

Adding Nuget Package Manager Command Line Utility

The C# project requires certain packages that are not included in the repository. The Nuget Package
Manager restores these packages after Jenkins pulls the repository.

1. Download the Nuget executable.


2. Place it in a folder of your choice and add it to your system environment variable by specifying its path.

You will have to restart Jenkins in order for it to be able to access the update list of environment variables.

©2023 Digital.ai Inc. All rights reserved Page 524


Test Execution

Specify The Build Steps

1. Click on Add build step and choose Execute Batch Command. Add the command:

nuget restore appium-csharp_first-test.sln

2. Click on Add build step and choose Build a Visual Studio project or solution using
MSBuild. Choose the MSBuild Version and the MSBuild Build File.

1. MSBuild Version is the name of you gave the MSBuild Installation in Specifying the MSBuild
Executable step.
2. MSBuild Build File is the solution file. specify appium-csharp_first-test.sln - this file is present in
the list of files from the repository.

1. Click on Add build step and choose Execute Batch Command. Add the command:

packages\NUnit.ConsoleRunner.3.7.0\tools\nunit3-console ./appium-csharp_fir
st-test/bin/Debug/appium-csharp_first-test.dll

Scroll all the way down and click Save or Apply.

©2023 Digital.ai Inc. All rights reserved Page 525


Test Execution

You are all set! Go to the project homepage and click on Build with Parameters and then click on Build.

Running a Java Jenkins Job

If you chose our Java Git Project, you will have to specify a build step that invokes a Gradle test task.

In the job configuration screen, scroll down to Build.

Click on Add build step and choose Invoke Gradle Script

©2023 Digital.ai Inc. All rights reserved Page 526


Test Execution

In the Tasks field, specify the test task.

Choose Use Gradle Wrapper

And check Make gradlew executable

Scroll all the way down and click Save or Apply.

You are all set! Go to the project homepage and click on Build with Parameters and click on Build.

©2023 Digital.ai Inc. All rights reserved Page 527


Test Execution

Running a Python Jenkins Job


If you chose our Python Git Project, you will have to specify a build step that runs the python test runner.

Before you begin, make sure that Python is installed on the machine that Jenkins runs on and that Python
executable was added as Environment Variable. Make sure to also install Appium dependencies by running
the command

pip install Appium-Python-Client

In the job configuration screen, scroll down to Build.

Click on Add build step and choose Execute Batch Command.

Depending on the environment that Jenkins operates on (Windows or UNIX), choose either Execute
Windows Batch Command or Execute Shell.

©2023 Digital.ai Inc. All rights reserved Page 528


Test Execution

Add the command:

python -m unittest test_runner.py

Scroll all the way down and click Save or Apply.

©2023 Digital.ai Inc. All rights reserved Page 529


Test Execution

You are all set! Go to the project homepage and click on Build with Parameters and then click on Build.

Running a Ruby Jenkins Job

If you chose our Ruby Git Project, you will have to specify a build step runs the Ruby test runner.

Before you begin, make sure that Ruby is installed on the machine that Jenkins runs on and that Ruby
executable was added as Environment Variable. Make sure to also install Appium and parallel tests
dependencies by running the commands:

gem install appium_lib


gem install parallel_tests

In the job configuration screen, scroll down to Build.

Click on Add build step and choose Execute Batch Command.

Depending on the environment that Jenkins operates on (Windows or UNIX), choose either Execute
Windows Batch Command or Execute Shell.

©2023 Digital.ai Inc. All rights reserved Page 530


Test Execution

Add the command

parallel_test android_app_test.rb android_web_test.rb ios_app_test.rb ios_web_


test.rb

Scroll all the way down and click Save or Apply.

You are all set! Go to the project homepage and click on Build with Parameters and then click on Build.

©2023 Digital.ai Inc. All rights reserved Page 531


Test Execution

Travis CI

Travis CI is CI/CD tool that allows you to build and test your code, for safe and fast code integration. It is
designed specifically to integrate with GitHub.

To use seetest.io with Travis CI, follow the instruction below:

1. Fork Git Repository

Choose any of our git repositories and fork them.

• Appium Test with Java


• Appium Test with C#
• Appium Test with Python
• Appium Test with Ruby

©2023 Digital.ai Inc. All rights reserved Page 532


Test Execution

2. Sync Travis CI with Your GitHub Account

Head over to Travis CI and click on Sign in with GitHub at the upper right-hand corner.

Authorize Travis CI to give it access to your repositories.

©2023 Digital.ai Inc. All rights reserved Page 533


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 534


Test Execution

3. Choose the repositories you wish to work with in Travis CI

• See that your organization appears in the list. If you are not part an organization, you will not have
organization listed but you will still be able to see your repositories.
• If you are part of an organization but it is missing from the list, click on Review and add your
authorized organizations. This will redirect you to GitHub where you can authorize Travis CI to see
and access repositories under given organization.
• Enable the desired repository by clicking on the switch button next to the repository.

©2023 Digital.ai Inc. All rights reserved Page 535


Test Execution

4. Set your access key as an environment variable

See the picture above. Next to the repository, you will see a cogwheel icon. Click on it to access the
repository settings.

Once in the repository settings, look for the Environment Field and add your Continuous Testing cloud
platform's access key . Your access key is encrypted by Travis CI and will no appear in the log.

5. Trigger a build

Once everything is set, in the repository screen in Travis CI click on More Options → Trigger build.

©2023 Digital.ai Inc. All rights reserved Page 536


Test Execution

If you want Travis CI to run builds on push to repository, you will have to add it as an integration service in
GitHub. In GitHub go to the repository. Click on Settings → Integration & services → Add Service. Look
for Travis CI, choose it and then click Add Service (no need for other details). Now, whenever you push
changes to the repository, Travis CI will be notified and trigger a build.

Azure DevOps

Azure DevOps is an advanced tool by Microsoft that provides version control, requirements management,
automated builds, testing and release management capabilities.

To use Azure DevOps with your Continuous Testing, follow the steps below:

1. Fork Git Repository

Choose any of our git repositories and fork them.

• Appium Test with Java


• Appium Test with Python
• Appium Test with Ruby

Each git repository contains the .azure-pipelines.yml file that specifies build properties and build steps.

To learn more about configuring your azure pipeline .yml file, visit azure documentation.

©2023 Digital.ai Inc. All rights reserved Page 537


Test Execution

2. Authorize GitHub in Azure DevOps

In your Azure → GitHub connections → Connect your GitHub account.

©2023 Digital.ai Inc. All rights reserved Page 538


Test Execution

3. Create your pipleline

You can simply click on "Pipelines" and create your pipeline.

©2023 Digital.ai Inc. All rights reserved Page 539


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 540


Test Execution

Select your code repository from the options displayed on the screen.

Select the relevant project from the project list.

©2023 Digital.ai Inc. All rights reserved Page 541


Test Execution

Choose your project's repository

Review your .yml file and add any required tasks. You can click on "Variables" in order to add environment
variables ()

©2023 Digital.ai Inc. All rights reserved Page 542


Test Execution

4. Set Access Key of Continuous Testing Cloud platform as an


Environment Variable

Go to Pipelines and under Library click on "Add" and set your access key and cloud URL as environment
variable:

Get your Continuous Testing cloud platform's access key

You can access these parameters from your code environment.

©2023 Digital.ai Inc. All rights reserved Page 543


Test Execution

5. Trigger Build

After setting up your project: go to Pipelines, and select your pipeline. In the next screen click Run
Pipeline. As your repository already contains the .azure-pipelines.yml file,Azure DevOps will know how to
trigger the build.

We recommend referencing Azure DevOps documentation to learn more about Azure DevOps abilities.

Frameworks

Frameworks are abstractions wherein generic functionality can be made use to enhance or selectively
modify to develop customized applications in a reasonably quick time.

There are many frameworks are available to author automated tests and subsequently run in Continuous
Testing platform.

The following are documentation for some of these frameworks.

©2023 Digital.ai Inc. All rights reserved Page 544


Test Execution

• JUnit
• TestNG
• Webdriver.io

JUnit

Junit is a testing framework that was designed for JVM. It allows you to encase your code in a testing
workflow template.

What Does this Mean?


The default unit testing template defines one method for setting up the test, one method for executing the
test, and one test for cleaning up once the test has been executed (whether the test succeeded or not).
Consider the code template below:

JUnit Class Example


import org.junit.*;

public class JUnitExample {

@BeforeClass
public static void setUpTestClass() {
System.out.println("--- START : run tests from class ---");
}

@Before
public void setUpTestMethod() {
System.out.println("--- About to ENTER test method ---");
}

@Test
public void test1() {
System.out.println("I'm test1");
}

@Test
public void test2() {
System.out.println("I'm test2");
}

@After
public void tearDownMethod() {
System.out.println("--- About to EXIT test method ---");

©2023 Digital.ai Inc. All rights reserved Page 545


Test Execution

@AfterClass
public static void tearDownClass() {
System.out.println("--- FINISH : tests from class --- ");
}

Output :

--- START : run tests from class ---


--- About to ENTER test method ---
I'm test1
--- About to EXIT test method ---
--- About to ENTER test method ---
I'm test2
--- About to EXIT test method ---
--- FINISH : tests from class ---

As you can see, each method is marked with an annotation that defines its role in the test workflow:

@BeforeClass - This method will set up the test Class (e.g runs once before all @Test methods are
executed in the class context)

@Before - This method that prepares all the parameters needed for a @Test Method. It is annotated as
@Before because it runs before the test method.

@Test - the method where the test steps are defined, annotated with @Test of course.

@After - the method that cleans up after the @Test Method has finished running, runs after the test method
has finished running.

@AfterClass - This method tear downs after the execution of all @Test methods in the class (e.g runs once
after all @Test methods are executed in the class context)

Without JUnit, you would have to create an instance of the test class and run inside a static main method.
JUnit frees from the need to write create a class test instance and run it in some main method. Like we
always like to say, No Hassle!

Getting Started with JUnit


To use JUnit, you should obtain the required JUnit dependencies. You can do it in one of two ways:

©2023 Digital.ai Inc. All rights reserved Page 546


Test Execution

1. Download JUnit .jars and add it to your project's classpath.


2. Get the jar by specifying the dependency in Gradle.

The second method, using Gradle is the better way because it allows you to export your project to other
team members or host it in a git repository.

To learn more about JUnit, visit their documentation.

TestNG

The Basics
TestNG is an open source Java testing framework which is powerful yet easy to use. TestNG is designed to
cover all categories of tests: unit, functional, end-to-end, integration, etc.

Before moving ahead with TestNG, it is important to understand it's basic architecture. Diagram below
depicts its architecture at high level.

©2023 Digital.ai Inc. All rights reserved Page 547


Test Execution

Below are some terminologies used in above diagram to help us understand more about the architecture.

Suite → Top level of any TestNG project and is maintained as an XML artifact.

Test → Representation of Test which can be one or more in a Suite.

Classes → Also known as TestNG class, contains one or more test methods.

Methods → An Optional container for one or more test methods. These test methods contains actual test
code.

TestNG executes any test suite, following the order defined by the testng.xml. Test developers can plugin
their logic in this flow of execution using special configuration Annotations.

Listed below are these Annotations with their description.

Annotation Description
@BeforeSuite The annotated method will be run before all tests in this suite have run.

@AfterSuite The annotated method will be run after all tests in this suite have run.

@AfterTest The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.

@BeforeGroups The list of groups that this configuration method will run before. This method is guaranteed to run shortly before
the first test method that belongs to any of these groups is invoked.

@AfterGroups The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the
last test method that belongs to any of these groups is invoked.

@BeforeClass The annotated method will be run before the first test method in the current class is invoked.

@AfterClass The annotated method will be run after all the test methods in the current class have been run.

@BeforeMethod The annotated method will be run before each test method.

@AfterMethod The annotated method will be run after each test method.

Quick and Easy - Run TestNG Tests for Mobile \ Web with
seetest.io
Now that you are all set, with basics of TestNG and Mobile/Browser testing.

1. Find the sample test in our git repository.


2. Fork the repository.

3. Edit the test and hit Run.

Before you proceed with fetching the sample tests:

©2023 Digital.ai Inc. All rights reserved Page 548


Test Execution

1. If you plan to test a native or hybrid app, upload your app to your project.
2. Fetch your access key.

TestNG - Further Reading - Advanced Concepts


To start using TestNG, you need its libraries. There are two ways you can do it and actually depends on
underlying build mechanism of the test suite.

1. Build and Use the library


In case the underlying build system of your project does not have capability of Automatic discovery of
dependency (Example: Maven or Gradle), then you will have to build TestNG source and then use the
Jars.

$ git clone git://github.com/cbeust/testng.git


$ cd testng
$ ./build-with-gradle

The Jars will be built in target directory which can be used set in your classpath for the project.

2. Configure dependency

If the your project uses Gradle or Maven, then TestNG dependency needs to be configured.

Maven: Configure following in pom.xml.


'

<repositories>
<repository>
<id>jcenter</id>
<name>bintray</name>
<url>http://jcenter.bintray.com</url>
</repository>
</repositories>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.10</version>
<scope>test</scope>
</dependency>

Gradle : Configure following in build.gradle.

©2023 Digital.ai Inc. All rights reserved Page 549


Test Execution

repositories {
jcenter()
}
dependencies {
compile 'org.testng:testng:6.10'
}

Automated test using TestNG

TestNG is a feature rich framework but to write a very basic test its a simple task.

1. Write business logic of the test.

Test Method
package test;
public class HelloWorldTest {
@Test
public void testHelloWorld() {
// write business logic for test
}
}

Notice the "@Test" annotation above, this annotation marks a function as test so that TestNG engine
runs it as a test without even being configured in testng.xml

2. Create a testng.xml

testng.xml
<suite name="Suite1" verbose="1" >
<test name="HelloWorldTest" >
<classes>
<class name="test.HelloWorldTest" />
</classes>
</test>

3. Run the TestNG

Assuming TestNG is set in your classpath, TestNG can be invoked as below

java org.testng.TestNG testng.xml

©2023 Digital.ai Inc. All rights reserved Page 550


Test Execution

Mobile and Browser Testing using TestNG


TestNG at its core is a Java testing framework, but it does not have direct capabilities to test Mobile and
Browser based applications. Hence we need Java based libraries in conjunction with TestNG to achieve the
same.

Appium and Selenium software provide Java based client bindings to interact with Appium/Selenium
servers which work on Mobile devices and Browsers.

In order to use TestNG in conjunction with Appium and Selenium you will have to do the following,

1. Download Java bindings for Appium or Configure Appium/Selenium dependency in build tool.

Assuming if you are using Gradle as build system, you need to configure dependencies
in build.gradle as shown below.

repositories {
mavenCentral()
}

dependencies {
compile group: 'io.appium', name: 'java-client', version: '+'
compile group: 'org.testng', name: 'testng', version: '6.9.10'
}

Notice the 'io.appium' group above.

Note: Best practice is to create the Gradle Project/Maven Project using IntelliJ or Eclipse and configure
dependency in build tool.

2. Implement a TestNG class which uses Appium library.

Typically, we need to first setup/create a Driver instance for testing an Device or Browser. This is done
by creating Desired Capabilities and then using it to create the Dri

Create Desired Capabilities:

Desired Capabilities are features which Client requests to Appium/Selenium server.

Desired Capabilities for Mobile


DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");

©2023 Digital.ai Inc. All rights reserved Page 551


Test Execution

capabilities.setCapability("appActivity", ".loginActivity");
capabilities.setCapability("appPackage", "com.experitest.ExperiBank/.Login
Activity");

In the above example client is requesting specific Android application on an Android Device.

Desired Capabilities for Browser


DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability("platformName", "Android");
capabilities.setCapability(CapabilityType.BROWSER_NAME, "chrome");

In the above example client is requesting a chrome browser on that an Android Device .

Create a Driver with desired capabilities

Create Driver for an Android Device


AndroidDriver driver = new AndroidDriver<AndroidElement>(new URL("https://
cloud.seetest.io:443/wd/hub"), capabilities);

First argument is the appium service and second argument is capabilities object.

Similarly, browser application can be tested by creating an instance of RemoveWebDriver object.

Create Driver for Browser


RemoteWebDriver = new RemoteWebDriver (new URL("https://cloud.seetest.io:4
43/wd/hub"), capabilities);

Driver creation ideally should be done in a function with "@BeforeClass" TestNG annotation since it
can be reused in all the test methods.

@BeforeClass
public class EriBankTest {
private DesiredCapabilities capabilities = new DesiredCapabilitie
s();
private AndroidDriver driver = new AndroidDriver<AndroidElement>()
;

@BeforeClass
public void setup() {
capabilities.setCapability("platformName", "Android");

©2023 Digital.ai Inc. All rights reserved Page 552


Test Execution

capabilities.setCapability("appActivity", ".loginActivity")
;
capabilities.setCapability("appPackage", "com.experitest.Ex
periBank/.LoginActivity");
AndroidDriver driver = new AndroidDriver<AndroidElement>(ne
w URL("https://cloud.seetest.io:443/wd/hub"), capabilities);
}
}

• Implement Test Methods in TestNG class.

Once the Driver is created, it can be used to Locate the elements in Mobile application or Browser
and test or automate.

Test Method for a Mobile application:

Test Method for Device Application


@Test
public void testLogin() {
// Locate the elements to test.
driver.findElement(By.xpath("//*[@id='usernameTextField']")).sendKe
ys(userName);
driver.findElement(By.xpath("//*[@id='passwordTextField']")).sendKe
ys(password);
driver.findElement(By.xpath("//*[@id='loginButton']")).click();
}

Test Method for a Browser:

Test Method for Browser


@Parameters({"title"})
public void testGetTitle(String title) {
driver.get("http://google.com");
Asserts.assert(driver.getTitle(),title);
}

©2023 Digital.ai Inc. All rights reserved Page 553


Test Execution

Extending Sample TestNG Project


Now that you have got the sample test from the git repository running, lets try to extend it to run for a your
own application instead of EriBank application to a specific targeted device in seetest cloud.

Here are the step by step procedure to achieve that.

1. Open the appium-java-testng project in IntelliJ or Eclipse as Gradle project.

2. Upload your application to a project manually by following the documentation in Native Applications
Testing.

3. Modify the relevant <platform>.app.name property in src/main/java/resources/


seetest.properties with the correct application name.

Note : The link Native Applications Testing mentions about the application name which can be used
as a value for <platform>.app.name property under heading "Upload your Application Manually".

4. Create a class under the package io.appium.testng. Please use the template class below to kick start
your testing.

Java Template class for extending tests


package io.appium.testng;

import io.appium.java_client.remote.MobileCapabilityType;
import org.testng.annotations.Optional;
import org.testng.annotations.Test;
import utils.SeeTestProperties;

public class FirstTest extends TestBase {

/**
* Sets up the default Desired Capabilities.
*/
protected void initDefaultDesiredCapabilities() {
LOGGER.info("Enter initDefaultDesiredCapabilities");
super.initDefaultDesiredCapabilities();

©2023 Digital.ai Inc. All rights reserved Page 554


Test Execution

this.setAppCapability(os);
buildDeviceQuery();
LOGGER.info("Exit initDefaultDesiredCapabilities");
}

/**
* sets the application ("app") capability based on the OS and the pro
perty which was defined in the seetest.properties file
*
* @param os
*/
private void setAppCapability(@Optional("android") String os) {
String appName = os.equals("android") ?
properties.getProperty(SeeTestProperties.Names.ANDROID_APP
_NAME) :
properties.getProperty(SeeTestProperties.Names.IOS_APP_NAM
E);

appName = String.format("%s%s", "cloud:", appName);


LOGGER.info("Setting up {} as app capability", appName);
dc.setCapability(MobileCapabilityType.APP, appName);
}

private void buildDeviceQuery() {


this.deviceQuery = String.format("%s and %s","@os='" + os + "'", "
@serialnumber='LGH990f2578648'");
dc.setCapability(SeeTestCapabilityType.DEVICE_QUERY, this.deviceQu
ery);
LOGGER.info("Device Query in buildDeviceQuery() - " + this.deviceQ
uery);
}

@Test()
public void firstTest() {
// add the operations and tests.
}
}

a) firstTest function can be added with any functionality you want to test.

©2023 Digital.ai Inc. All rights reserved Page 555


Test Execution

b) Please Edit @serialnumber in buildDeviceQuery function (i.e. @serialnumber='LGH990f2578648')


to any Device ID of your choice by following this video

5. Now edit the src/main/java/testng.xml to add following reference of the Test class ( <test
name="FirstTest">) we introduced before, at Step 3.

testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="TestNGExample" configfailurepolicy="continue" verbose="2">
<!--<parameter name = "userName" value="company"/>
<test name="AndroidTestNGExample">
<classes>
<class name="io.appium.testng.AndroidTestNGExampleTest">
<parameter name = "userName" value="company"/>
<parameter name = "os" value="android"/>
<methods>
<include name="makePaymentTest" />
<include name="balanceTest" >
<parameter name = "expectedBalance" value="90"/>
</include>
<include name="dummyTest()"/>
</methods>
</class>
</classes>
</test>
<test name="IOSTestNGExample">
<parameter name = "os" value="ios"/>
<classes>
<class name="io.appium.testng.IOSTestNGExampleTest">
<methods>
<include name="makePaymentTest" />
<include name="balanceTest" >
<parameter name = "expectedBalance" value="90"/>
</include>
</methods>

©2023 Digital.ai Inc. All rights reserved Page 556


Test Execution

</class>
</classes>
</test>
<test name="WebTestNGexample">
<classes>
<class name="io.appium.testng.WebTestNGExampleTest">
<parameter name = "os" value="android"/>
<methods>
<include name="titleTest" >
<parameter name = "url" value="http://google.com"/>
<parameter name = "title" value="Google"/>
</include>
</methods>
</class>
</classes>
</test>-->
<test name="FirstTest">
<classes>
<class name="io.appium.testng.FirstTest">
<parameter name = "os" value="android"/>
</class>
</classes>
</test>
</suite>

Note :

• Other tests in the testng.xml are commented because they depend on EriBank application.

• It's important to have right combination of the parameter name ="os" in the testng.xml and Device
ID, i.e the value (android or ios) needs to same as the operating system of Device ID.

6. Run the modified project using modified testng.xml.

©2023 Digital.ai Inc. All rights reserved Page 557


Test Execution

Webdriver.io

If you are using Webdriver.io to automate your tests, you can port your executions to Continuous Testing
Cloud and run these tests on Real mobile devices and browsers.

Set up

Appium (Mobile Devices): Additional capabilities for mobile devices can be found here: Capabilities in
Appium Based Tests

Selenium (Desktop Browsers): Additional capabilities for browsers can be found here: Capabilities In
Selenium Tests

Set up
Running your tests with WebdriverIO is easy. This guide will help you to set up your project in a few steps

Webdriverio setup
Setup your project

Make a new project directory manually or executing on the command line:

Shell
# Create a new folder for WebDriverIO
mkdir webdriverio
cd webdriverio

# Run npm command to init WebDriverIO


npm init wdio .

# Click ENTER (confirm) on all the questions from the command

#Create a spec file


mkdir test\specs && cd test\specs
echo myTest > myTest.js

©2023 Digital.ai Inc. All rights reserved Page 558


Test Execution

Webdriver.IO integration - Selenium


Webdriverio Selenium Test example
Open myTest.js file and write:

myTest.js Example
const assert = require('assert')
describe('webdriver.io page', () => {
it('should have the right title', async () => {
await browser.url('https://digital.ai/continuous-testing')
const title = await browser.getTitle()
assert.strictEqual(title, 'Digital.ai Continuous Testing | Scalable Ap
p & Device Testing Tool')
})
})

For more advanced capabilities that Continuous Testing offers,


check here.

wdio.config.js example
exports.config = {
runner: 'local',
hostname: '<cloud-ip>',
protocol: 'https',
port: 443,
path: '/wd/hub',

specs: [
'./test/specs/**/*.js'
],
capabilities: [{
'experitest:accessKey': '<AccessKey>',
// Or userName, password and projectName if needed
platformName: 'windows', // Optio
nal
browserVersion: 'latest', // Optio
nal
browserName: 'firefox',
// Optional
'experitest:testName': 'Selenium WebdriverIO test', // Optional
}],

mochaOpts: {
ui: 'bdd',

©2023 Digital.ai Inc. All rights reserved Page 559


Test Execution

timeout: 60000
},
}

Webdriverio Run

Window run

To run your tests, execute:

bash
npx wdio run .\wdio.conf.js
Mac run

To run your tests, execute:

bash
npx wdio run ./wdio.conf.js

Webdriver.IO Integration - Appium


Note:

As the latest version of Webdriver.io client is W3C compliant, we recommend using Appium-OSS mode of
execution in order to run these tests.

Native App Test


iOS test example
describe('Eribank test', () => {
it('Login test', async () => {
const username = await $('//*[@name="usernameTextField"]'); //find el

©2023 Digital.ai Inc. All rights reserved Page 560


Test Execution

ement
const password = await $('//*[@name="passwordTextField"]');
const loginButton = await $('//*[@name="loginButton"]');
await username.setValue('company'); //send key
await password.setValue('company');
await loginButton.click(); //click
})
})
Android test example
describe('Eribank test', () => {
it('Login test', async () => {
const username = await $('//*[@text="Username"]'); //find element
const password = await $('//*[@text="Password"]');
const loginButton = await $('//*[@text="Login"]');
await username.setValue('company'); //send key
await password.setValue('company');
await loginButton.click(); //click
})
})

For more advanced capabilities, see Capabilties in Appium Based Tests.

wdio.config.js example
exports.config = {
runner: 'local',
hostname: '<cloud-ip>',
protocol: 'https',
port: 443,
path: '/wd/hub',

specs: [
'./*.js'
],
capabilities: [{
platformName: '<platform>', // 'ios' for iOS
tests, 'android' for Android tests
'appium:options': {
'udid': '<Device-Udid>',
// Optional
'bundleId': 'com.experitest.ExperiBank', // for i
OS
'appPackage': 'com.experitest.ExperiBank', // for Android
'app': "cloud:com.experitest.ExperiBank/.LoginActivity",
},
'digitalai:options': {
'testName': "Appium WebdriverIO native test", //Optional
'accessKey': "<AccessKey>", // Or userName,
password and projectName if needed
'appiumVersion': "1.22.3",

©2023 Digital.ai Inc. All rights reserved Page 561


Test Execution

},
}],
mochaOpts: {
ui: 'bdd',
timeout: 180000
},

Web Test
Web test example
const assert = require('assert')
describe('webdriver.io page', () => {
it('should have the right title', async () => {
await browser.url('https://digital.ai/continuous-testing')
const title = await browser.getTitle()
assert.strictEqual(title, 'Digital.ai Continuous Testing | Scalable Ap
p & Device Testing Tool')
})
})

For more advanced capabilities, see Capabilties in Appium Based Tests.

wdio.config.js example
exports.config = {
runner: 'local',
hostname: '<cloud-ip>',
protocol: 'https',
port: 443,
path: '/wd/hub',

specs: [
'./*.js'
],
capabilities: [{
platformName: '<platform>', // 'ios'
for iOS tests, 'android' for Android tests
browserName': 'chrome',
'appium:options': {
'udid': '<Device-Udid>',
// Optional
},
'digitalai:options': {
'testName': "Appium WebdriverIO webtest", // Optional
'accessKey': "<AccessKey>", // Or userNam
e, password and projectName if needed
'appiumVersion': "1.22.3",
}
},

©2023 Digital.ai Inc. All rights reserved Page 562


Test Execution

],

mochaOpts: {
ui: 'bdd',
timeout: 180000
},
}

Webdriver.io Run
To run your tests, run the applicable command in a command line window:

• Windows: npx wdio run .\wdio.conf.js


• Mac: npx wdio run ./wdio.conf.js

Analytics
Analytics Tools and Frameworks are key for faster availability for data.

Currently Continuous Testing Cloud supports integration with ElasticSearch.

ElasticSearch

The reporter can send test data to an ElasticSearch instance for further analysis and reporting.

Requirements
Integration between Reporter and ElasticSearch has these requirements:

• Elasticsearch supported version: 7.5 through 7.117 and 8.0 through 8.6
• Either user/password or API key:
◦ user/password: Must be associated with the role with the following privileges:
◦ index name "*", privileges: "view_index_metadata"
◦ index name "reporter_tests_*", privileges: "create_index", "read", "write"
◦ API key: Must be created with the following privileges:
◦ index name "*", privileges: "view_index_metadata"
◦ index name "reporter_tests_*", privileges: "create_index", "read", "write"

©2023 Digital.ai Inc. All rights reserved Page 563


Test Execution

Configuration
Elasticsearch integration is configured with the following application.properties entries:

Key Description
elastic.url URL of ElasticSearch instance required.

elastic.username Elasticsearch's user name, required unless an API key is used.

elastic.password Elasticsearch's password, required unless an API key is used.

elastic.apikey API Key.

elastic.tests-sender.cron See "CRON expression" section in Cron.

elastic.tests-sender.async- Size of dedicated asynchronous executor's thread pool called elasticTestsAsyncExecutor.


count The default is 2.

elastic.tests-sender.bulk-size How many tests' operations to send per bulk.

elastic.tests-sender.bulk-count How many bulks to send per run.

elastic.tests-sender.enable- Initial enable state of sender. The default is false. Note: After configuring ElasticSearch in
initial reporter, set this to true.

cust.id Customer ID. This is needed to distinguish customers' indexes when they share an Elasticsearch
instance.

elastic.index_name If present Reporter will send tests in the mode index per environmen" (see below).

elastic.env Environment’s name, used for "index per environment" to feed test’s document "env" property.
Must be present if elastic_index is configured.

Control and Monitoring Rest Interfaces

Endpoint Method Purpose


/api/elastic/tests/state GET Shows the current state of Elasticsearch tests' sender

• Enabled: y/n

• Bulk size.

• Bulk count.

• The last time was enabled or disabled.

• Active (running) senders.

• Run count since last enable.

• The operation sent since the last enable.

©2023 Digital.ai Inc. All rights reserved Page 564


Test Execution

Endpoint Method Purpose

• Failed operations since last enable.

• Total bulks sent.

• Total time spent sending bulks.

• Average time per bulk.

/api/elastic/tests/disable GET Disable the sender.If is disabled scheduled task does nothing, just emits a log warning
Senders not enabled, nothing to do.

/api/elastic/tests/enable GET Enable the sender.

/api/elastic/tests/clear GET Clear counters.

Set the Project sendTestsToElastic Property


The reporter sends the project's tests when sendTestsToElastic is set to true. To change this, issue a
PUT to {reporterUrl}/api/projects with the following JSON payload:

{ "id": <project's ID>, "sendTestsToElastic": <true | false> }

This requires credentials via HTTP BASIC AUTHENTICATION or using token (bearer) authentication, and
the user must be a Cloud Administrator.

Indexes
Index Per Project or Per Environment
The reporter can create an index per Reporter’s project or one index for the environment. In this case all the
project’s tests are sent to the same index. Reporter determines which index is used based on the
configuration key elastic.index_name. If it is present, only one index is used for the Reporter’s
instance. If you use an index per environment, ensure that the user can create indexes. Consult the
ElasticSearch documentation.

©2023 Digital.ai Inc. All rights reserved Page 565


Test Execution

ElasticsSearch Index Creation


Index Per Project

The reporter creates one index for each project whose sendTestsToElastic property is set to true.

Big customers may have their own private Elasticsearch instance but small customers may not. They may be
sharing an ElasticSearch instance so this is the index name structure used is:

reporter_tests_${<cust.id>}_${<project.id>}

• cust.id: Customer ID assigned by Continuous Testing Cloud. This is always an alphanumeric lowercase
string (no special chars). This must be set in the application.properties.
• project.id: ID of the project the tests belong to.

Storage settings such as shards and replicas are the responsibility of the ElasticSearch administrator.

Elasticsearch Index Template


Before Reporter can create and send the test to index, ElasticSearch's admin must create the template
named reporter_tests_template.

Search Template
PUT _index_template/reporter_tests_template
{
"index_patterns":[
"reporter_tests_*"
],
"template": {
"settings": {
"number_of_shards": 1
},
"mappings":{
"_source": {
"enabled": true
},
"properties":{
"id":{
"type":"long"
},
"name":{
"type":"text"
},
"startTime":{
"type":"date"
},

©2023 Digital.ai Inc. All rights reserved Page 566


Test Execution

"duration":{
"type":"long"
},
"status":{
"type":"keyword"
},
"success":{
"type":"boolean"
},
"date":{
"type":"date"
},
"hasReport":{
"type":"boolean"
}
}
}
}
}

Digital.ai Application Protection


Digital.ai's Application protection shield apps from reverse engineering, tampering, API exploits, and other
attacks that can put your business, your customers, and your bottom line at risk.

Prerequisites
A protected application might fail to be uploaded to the cloud if any change has been made to it during the
upload.

To avoid any modification to the app:

• Do not instrument the app.


• Do not add Camera, Fingerprint or Network instrumentations.
• Keep the original signature - Make sure the signing provision profile / Keystore used when signing the
app allows you to install it on the cloud devices and choose "Allow resign parameter to be false (allow
resign applies only to iOS).

©2023 Digital.ai Inc. All rights reserved Page 567


Test Execution

1. Upload your application


A Protected application can be uploaded in these ways:

• Upload through RESTful API


• Upload through Applications page (UI)

Upload Application through REST API

No Other parameters other than the mentioned below when working with a protected application.

POST /api/v1/applications/new

Parameters

Name Type Mandatory Description


file File Yes A multi-part file

uniqueName String No String that the user can use later to identify the app uniquely

project String No Available for cloud admin only, if the project isn't specified, it will be uploaded to Default
project.Project name can be provided or a project id in the following format:id:<id>. For
example: id:123.

Additional Parameter for iOS

Name Type Mandatory Description


allowResign Boolean No Should be set to false to force the cloud to keep the original signature.

Upload Application through the Applications page (UI)

Navigate to the 'Applications' page

©2023 Digital.ai Inc. All rights reserved Page 568


Test Execution

Upload Application:

Step 1: Click 'Upload'

Step 2: Select the file to be uploaded

Do not check the following checkboxes (Android only):

Include simulate capture (camera) libraries

Include Touch ID (fingerprint) libraries

Support Network Capture

©2023 Digital.ai Inc. All rights reserved Page 569


Test Execution

Step 3: Click add to start uploading the application

To disable allowResign for iOS devices:

1. Select the application and click on edit


2. Uncheck "Allow Profile Resign"
3. Click "Save"

©2023 Digital.ai Inc. All rights reserved Page 570


Test Execution

2. Install your Application


Now that the application is uploaded, there are several ways to install it.

For protected applications, make sure that you do not install the app in instrumented mode:

• During a manual session


• In an Appium test, "instrumentApp" capability must not be used or set to false
• Using the "Install" command - set the "instrument" parameter to false
• Install through RESTful API - instrument parameter must not be used or set to false

©2023 Digital.ai Inc. All rights reserved Page 571


Test Execution

3. Launch your Application


Now that the application is uploaded and installed there are several ways to launch it.

For protected applications, make sure that you do not launch the app in instrumented mode:

• During a manual session


• In an Appium test, "instrumentApp" capability must not be used or set to false
• Using the "Launch" command - set the "instrument" parameter to false

Dai-CT Execution Command Line Interface


This feature lets you run multiple execution types easily from the terminal against Continuous Testing Cloud.

Installation
To install the package, run this following command (with sudo permissions):

npm install -g dai-ct

Configuration
The CLI must be configured before running it.

To configure the CLI, add a file named credentials.json in the root directory of the project. It needs to contain:

• cloudUrl
• accessKey

This file needs to be in json format.

credentials.json Example
{
"cloudUrl" : "https://mycloud.experitest.com",
"accessKey" : "myAccessKey"
}

Run Cypress and Playwright Tests


You can run Cypress or Playwright projects.

©2023 Digital.ai Inc. All rights reserved Page 572


Test Execution

Cypress and Playwright projects are run asynchronously. The response received is immediate.

dai-ct cypress run -p or --project <path to the project> -c or --conf <path to conf file>

dai-ct playwright run -p or --project <path to the project> -c or --conf <path to conf file>

Parameters

Name Mandatory Description


-p or --project Yes Cypress project to run

-c or --conf No Configuration file for the requested execution.


A file named digitalai.json (in json format) with the required configuration.
For more information, see :

• Start a Cypress Execution

• Execute a Playwright Job

Run Cypress Command Example


dai-ct cypress run -p /Users/MyUser/Documents/cypressProject --conf digitalai.
json
Run Playwright Command Example
dai-ct playwright run -p /Users/MyUser/Documents/playwrightProject --conf digi
talai.json

Run Espresso and XCUITest Tests


You can run Espresso or XCUITest projects.

Espresso and XCUITest projects are run asynchronously, the response received is immediate

dai-ct espresso run -a or --app <path to the app> -t or --testApp <path to the test app file> -c or --
conf <path to conf.json file>

dai-ct xcuitest run -a or --app <path to the app> -t or --testApp <path to the test app file> -c or --
conf <path to conf.json file>

Parameters

Name Mandatory Description


-c or --conf Yes

©2023 Digital.ai Inc. All rights reserved Page 573


Test Execution

Name Mandatory Description

Configuration file for the execution.


A file named conf.json (in json format) with the required parameters for the
executions.
For more information see Running Async Espresso/XCUITest.

Only the mandatory parameters are supported:

• runningType

• deviceQueries

• appUrl

• testAppUrl

-a or --app No (only if appUrl is provided in Application under test


the conf.json)

-t or --testApp No (only if testAppUrl is provided Espresso / XCUI tests(.zip extension only)


in the conf.json)

Run Espresso Command Example


dai-ct espresso run -a /Users/MyUser/Documents/myApp.apk -t /Users/MyUser/Docu
ments/myTests.apk -c conf.json
Run XCUITest Command Example
dai-ct xcuitest run -a /Users/MyUser/Documents/myApp.ipa -t /Users/MyUser/Docu
ments/myTests.zip -c conf.json
conf.json Example
{
"runningType": "coverage", //Mandatory
"deviceQueries" : "@os='android'", //Mandatory
"appUrl" : "https://actualapp.apk", //Not Mandatory if App argument is given
in cli
"testAppUrl" : "https://testapp.apk" //Not Mandatory if TestApp argument is
given in cli
}

Terminology
Our platform provides testers and developers with simplified views that help you easily grasp test executions
which are taking place in your projects

©2023 Digital.ai Inc. All rights reserved Page 574


Test Execution

As a user, you have a consolidated view of all tests cases which are currently running - with capabilities such
as queue management, visual grid view, and test lifecycle control

• Test Request
• Test Execution Plan
• Direction

Test Request
A Test Request is an entity that governs the test executions in the Continuous testing Digital Assurance Lab.
Each test request starts with the Appium driver issuing a Test Request (this is usually done by requesting
suitable resources for the required test, Desired Capabilities).

You can view all Test Requests by visiting the Execution page and choosing the List View:

The Test Request life-cycle is described under the Test Request Statuses Page.

©2023 Digital.ai Inc. All rights reserved Page 575


Test Execution

Tests Requests Statuses

Continuous Testing Digital Assurance Lab processes the Test Requests and displays them in the Test
Request table.

When an available device and an executor grid node are located and allocated to the client, a test run starts,
and the Test Request status will change to "Running".

If a Test Request is waiting for available resources (device, grid node executor or grid execution license) -
the Test Request status will be "Queued".

The following are all possible Test Request statuses:

Status Description
Queued The Test Request is waiting for resources to free up (device\browser availability, etc.).

Running Once the resources are available, the test executes and is now in progress.

Finished The Test Request had finished and received the complete signal ("FINISH") from the executor.

Terminated The test execution ended before receiving the "FINISH" signal.

Canceled The user has decided to cancel the Test Request session.

Timeout The connection between the driver and the grid node was lost.

Cancel A Test Request

Queued or Running test requests can be canceled using the "Cancel" button.

Permissions:

• Cloud Administrators can cancel all test requests in the system.


• The Project Administrator can cancel test requests that were created by users in this project, except for
those created by a Project Administrator.
• The user can cancel his own test requests.

Select the test requests you intend to cancel, and click on the Cancel button:

(When some of the selected test requests are not eligible for cancellation, the button will be deactivated)

©2023 Digital.ai Inc. All rights reserved Page 576


Test Execution

Similarly, the test can be canceled in Grid view as shown below by clicking the cancel button.

Click Yes in the confirmation dialog:

©2023 Digital.ai Inc. All rights reserved Page 577


Test Execution

Test requests status will change to Canceled.

Delete A Test Request

Canceled, Finished or Terminated test requests can be deleted using "Delete" button.

Permissions:

• Cloud Administrator can delete all test requests in the system.


• Project Administrator can delete test requests that were created by users in this project.
• The user can delete his own test requests.

Select tests and click on Delete button:

©2023 Digital.ai Inc. All rights reserved Page 578


Test Execution

Click Delete in confirmation dialog:

Test request status will change to "Deleted".

Debug A Test Request

As an automation user that does execution in the grid, users are able to put breakpoints in their test code,
then go to the grid view, identify their test, and click on debug.

1. Go to "Execution" page - Grid view


2. Find your grid test request
3. Click on the "Debug" Button

©2023 Digital.ai Inc. All rights reserved Page 579


Test Execution

The cloud will open a Web session on the device.

*When the new session starts Development license will be taken and the Mobile Execution license will be
released.

Test Execution Plan


Test Execution relies on Execution Plans which are groups of test requests that can be executed using the
cloud server.

The goal is to provide the user with an interface to group test requests, and initiate test sessions (execute
tests) with managed resources (devices/nodes/conditions etc.).

The run is a part of the SeeTestGrid offering and is integrated with different Continuous Testing tools (Cloud
UI/Grid Clients/Reporter Client).

The tests are based on Espresso and XCUITest.

XCUITest (iOS) - The XCUITest framework enables you to write unit tests for your Xcode projects that
integrate seamlessly with the Xcode testing workflow.

Espresso (Android) - Android application testing platform, targeted towards app developers.

©2023 Digital.ai Inc. All rights reserved Page 580


Test Execution

To learn how to develop, create and run test plans, please visit the resources below:

• Execution Plan using XCUITest


• Execution Plan using Espresso
• Manage Test Run with the API
• Manage Test Run with Cucumberish
• Manage Test Run with Cucumber-jvm
• Manage Test Run with Flutter Integration tests

Direction
• When using one of these commands, you are required to enter the direction of the search box:
◦ GetTextIn
◦ VerifyIn
◦ IsFoundIn
• When using Swipe: You are required to enter the direction in which the screen will move. Notice that
the Swipe direction is opposite to the movement of the finger or mouse.

Troubleshooting
Mobile tests execution time is too long
When running mobile tests using SeeTest Digital Assurance Lab, we take screenshot after each command.

Taking screenshot can take a long time and cause the whole test to take longer. If you wish to give up on a
test report creation you should include this capability in your test:

Code example
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("deviceQuery", "@os='android');
dc.setCapability("username", "cloudUsername");
dc.setCapability("password", "cloudPassword");
dc.setCapability("projectName", "cloudProject");

//Add this capability in order to disable reports & get faster execution times
dc.setCapability("generateReport", false);

AndroidDriver driver = new AndroidDriver<>(new URL("http://"+cloudHost+":"+clo


udPort), dc);

©2023 Digital.ai Inc. All rights reserved Page 581


Test Execution

Web tests fail with Timeout

When running web tests using SeeTest Digital Assurance Lab, we take screenshot after each command.

Taking screenshot can take a long time (particularly in Internet Explorer), so when running web grid tests on
SeeTest Digital Assurance Lab user should do one of the following:

1. Disable taking screenshots by adding the capability takeScreenshots=false in the conf.js file.
2. Increase default timeout. In Protractor it's done by adding the following piece of code to the
exports.config in conf.js file:

protractor.conf.js
exports.config = {
..
..
jasmineNodeOpts: {
defaultTimeoutInterval: 2500000
},
..
..
}

Unable to Install Application


If you are unable to install an application either by manually installing it or by installing it via test script,

Please make sure that the following conditions are met:

1. The device you are trying to install the application on, has the minimum required operating system
version that is configured in the application. i.e. if an application is only compatible with iOS 10 and
above, make sure to install it on iOS 10 and above devices only.

2. The applications is built in debug configuration. Any application that is built in production or
distribution configuration might fail to install. See the resources below to learn how to build your
application in debug configuration.
1. Preparing Android Applications
2. Preparing iOS Applications

3. Installing in Automation Tests:


1. Make sure that the application was added to your project.

2. Make sure to add cloud: before the bundle id or app package

Capabilities setting

©2023 Digital.ai Inc. All rights reserved Page 582


Test Execution

// Android
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.eriba
nk/com.experitest.ExperiBank.LoginActivity");

// iOS
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.Exper
iBank");

Unable to Launch Application


If you are unable to launch an application either manually or via test script,

Please make sure that the following conditions are met:

1. The device you are trying to install the application on, has the minimum required operating system
version that is configured in the application. i.e. if an application is only compatible with iOS 10 and
above, make sure to install it on iOS 10 and above devices only.

2. The applications are built in debug configuration. Any application that is built in production or
distribution configuration might fail to install. See the resources below to learn how to build your
application in debug configuration.
1. Preparing Android Applications
2. Preparing iOS Applications

3. If you are trying to launch the application during an automated test:


1. Make sure that the application was added to your project.

2. In the capabilities, make sure to add cloud: before the bundle id or app package. This should
install the application on the device before the test starts:

Capabilities with Cloud: key


// Android
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.eriba
nk/com.experitest.ExperiBank.LoginActivity");

// iOS
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.Exper
iBank");

©2023 Digital.ai Inc. All rights reserved Page 583


Test Execution

3. In the capabilities, make sure to specify the correct app package, app activity or bundle id:

Correct App Package


// Android
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.experit
est.ExperiBank");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".LoginActi
vity");

// iOS
dc.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.experitest.Ex
periBank");

Tests execution time is too long

When running mobile tests using the Continuous Testing Cloud platform, screenshots are taken after each
command which results in a longer duration of test runs.

If you want to skip the report creation which actually is the reason for screenshot capture, you can set the
relevant capability to disable the report.

This is done by setting generateReport capability as disable, see below.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Code Example

©2023 Digital.ai Inc. All rights reserved Page 584


Test Execution

DesiredCapabilities dc = new DesiredCapabilities();


dc.setCapability("deviceQuery", "@os='android');
dc.setCapability("projectName", "cloudProject");
dc.setCapability("accessKey", accessKey);
dc.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.experitest.Expe
riBank");
dc.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".LoginActivity");

//Add this capability in order to disable reports & get faster execution times
dc.setCapability("generateReport", false);
AndroidDriver driver = new AndroidDriver(new URL("<server>"), dc);

iOS 13 Security Related Limitations


Apple has further increased security features from iOS 13 and above.

As a consequence, there are some behavioral changes, specifically in Password Fields and Security
Popups.

This is applicable only for Manual or Interactive mode.

Password Fields
Password fields will appear blank, and on user input, the keyboard will not be displayed. Even after input was
inserted into the password text field, the text will remain invisible.

See below (note that the 'x' option on the right of the text field is on, meaning there is text in the field),

©2023 Digital.ai Inc. All rights reserved Page 585


Test Execution

Workaround/Solution

Use Object Spy to inspect the fields like a password so that it can be reviewed and crosschecked that these
are valid fields.

Security Popups
Some applications location permission may not appear and some times the device may seem unresponsive.

Workaround/Solution

Navigate to iOS settings → privacy to approve the location. Relaunch your application.

Timeout Issues
This page collates the troubleshooting issues related to timeout while executing tests.

• SeeTest tests fail with Timeout


• Web Tests Fail with Timeout
• Appium Tests Fail With Timeout

©2023 Digital.ai Inc. All rights reserved Page 586


Test Execution

SeeTest tests fail with Timeout

High latency between the client's environment, the cloud, and the device could occasionally test to fail due
to XML-RPC timeout.
If this happens frequently, a user could set an XML-RPC connection timeout and reply timeout.

At the start of your test, add the following lines, where [TIMEOUT] is the new timeout, in milliseconds.

System.setProperty("xmlrpc.connTimeout", "[TIMEOUT]");
System.setProperty("xmlrpc.replyTimeout", "[TIMEOUT]");

The default timeout is 60 seconds.

When there are delays between SeeTest command calls (more than 60 seconds), and tests fail with timeout
status, the following option should be set in the cloud server application.properties file to bigger value:

cloud.server.grid-monitor-timeout-in-seconds=180

The default timeout is 60 seconds.

Web Tests Fail with Timeout

When running web tests using Continuous Testing Cloud, screenshots are taken after each command.

Taking a screenshot can take a long time (particularly in Internet Explorer). When running web grid tests on
Continuous Testing Cloud, do one of the following to skip taking screenshots:

• Disable taking screenshots by adding "takeScreenshots=false" to the conf.js file.


• Increase the default timeout. In Protractor it's done by adding the following piece of code to
exports.config in conf.js.

protractor.conf.js
exports.config = {
..
..
jasmineNodeOpts: {
defaultTimeoutInterval: 2500000
},
..

©2023 Digital.ai Inc. All rights reserved Page 587


Test Execution

..
}

Appium Tests Fail With Timeout

When executing automated tests using Appium, you might come across issues where tests never make it to
the execution phase. In such cases, tests will time out.

When a test is queued and awaits execution, you will see it in the queued section of the notifications bar.

However, the test might not make to the execution phase. These are some reasons why this might happen.

• Incorrect Capabilities

Passing correct and valid Appium capabilities is a crucial part of making sure tests will be executed as
intended. Make sure that you passed device setup capabilities correctly, without any typos etc.

• Device in Use

If you set the capabilities such that the test would run a specific device, it is possible that the device will
be used by someone else when you attempt to execute the tests. If the device is not released during
the queued test phase, the test will timeout and fail. Make sure that the device you want to test on is
available. To be sure, reserve the device if you know that you will be executing the test at a fixed time.

Getting Started
This section describes the first steps to consider in order to execute your tests against the Continuous
Testing platform.

Obtaining Access Key

©2023 Digital.ai Inc. All rights reserved Page 588


Test Execution

Getting Access Key


The cloud platform gives you access to remote testing if you specify your username and password in the
Desired Capabilities. But you probably don't want your password (or any password for that matter) lying
around in your code. For this purpose, we created the access key. Specify the access key in the set of test
capabilities to gain access to remote testing.

In the Continuous Testing cloud platform, Click on your profile → Get Access Key.

After the clicking the Get Access Key, in the displayed popup, copy the access key to the clipboard as
shown below to obtain the Access Key.

©2023 Digital.ai Inc. All rights reserved Page 589


Test Execution

Once you have obtained the access key, add it to the Desired Capabilities as shown in the code snippets
below in different languages.

Replace <server> with the appropriate URL.

• Public Continuous Testing Cloud - https://cloud.seetest.io/wd/hub/.


• Dedicated Continuous Testing Cloud environment - Your own domain. For example: https://
company.experitest.com/wd/hub/
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub

Java
String accessKey = "<Your Access Key>"
dc.setCapability("accessKey", accessKey);
driver = new AndroidDriver(new URL("<server>"),dc);
C Sharp
string accessKey = "<Your Access Key>"
dc.SetCapability("accessKey", accessKey);
driver = new AndroidDriver<AndroidElement>(new Uri("<server>"), dc);
Python
accesskey = '<Your Access Key>'
self.dc['accessKey'] = self.accessKey
self.driver = webdriver.Remote('<server>', self.dc)
Ruby
desired_caps = {
caps: {
accessKey: '<Your Access Key>',
appium_lib: {

©2023 Digital.ai Inc. All rights reserved Page 590


Test Execution

server_url: '<server>',
}
},

Resetting Access Key

All users can invalidate their Access Key by using the Reset AccessKey feature from user profile page.
Ongoing grid tests may fail after invalidating the old access key.

Log in to SeeTest cloud and click on 'My account' from the user profile at top right corner.

Click on the 'Reset AccessKey' button. This will invalidate old access key and create new.

Warning: in case you are assigned to multiple projects all your access keys will be reset.

©2023 Digital.ai Inc. All rights reserved Page 591


Test Execution

Once the Access Key reset is successful, new Access Key can be retrieved from the 'Get Access Key'
feature as shown above.

Tutorial - Run Your First Automated Test


You can see firsthand how our system works and what is required in terms of code and capabilities.

You have the option to run sample tests on either native or web applications and can do so with a
combination of languages and frameworks, and see the result within 5 minutes.

Page Navigation
Click Automation in the main navigation bar.

©2023 Digital.ai Inc. All rights reserved Page 592


Test Execution

Select Mobile/Web mode


You can select Mobile or Browser mode.

©2023 Digital.ai Inc. All rights reserved Page 593


Test Execution

Mobile Mode Configuration

These configurations are available for Mobile Mode:

• OS - iOS/Android
• Phone Platform - Phone/Tablet
• App Type - Native/Web
• Version - Available versions

©2023 Digital.ai Inc. All rights reserved Page 594


Test Execution

Web Mode Configuration

These configurations are available for Web Mode:

• Browser Type - Chrome/Safari/Firefox/IE


• Version - Available versions
• Desktop OS - available OS

Code Export
You can view the demo code that matches your configuration and user profile. You can select the code
language, test framework, and test dependencies.

To copy code for use in your IDE, click the Copy to Clipboard button.

©2023 Digital.ai Inc. All rights reserved Page 595


Test Execution

Test Execution
To execute a test, click RUN TEST.

©2023 Digital.ai Inc. All rights reserved Page 596


Test Execution

The scripts for mobile native include the installation of the EriBank Application

• Android - com.experitest.ExperiBank/.LoginActivity
• iOS - com.experitest.ExperiBank

If the application is not in your project, a popup dialog requesting permission to upload the application to the
user project is dsplayed.

If you click OK, the application is uploaded to your project and the test is executed.

If the application is already in your project, the test is executed immediately.

You can see the test running on Tests Execution page.

©2023 Digital.ai Inc. All rights reserved Page 597


Test Execution

Test Result
You can see the test flow and it results in the navigation bar.

You can also see the report in "Reports" page (provided the reporter is configured).

©2023 Digital.ai Inc. All rights reserved Page 598


Test Execution

Tutorial - Configure your "Reports Dashboard"


Reporter is an intuitive analytic tool for searching and analyzing tests results for mobile and web tests.

Adding Tests to Reporter


After cloud is configured with the Reporter adding tests is easy, you can do it by:

1. Run any grid tests


• running grid test will automatically be added to the reporter
• frameworks supported: Appium, SeeTest, XCtest, Espresso, and Selenium tests
• the easiest way to add a sample test is to run the demo tests from the Quick Start page in the
cloud:

©2023 Digital.ai Inc. All rights reserved Page 599


Test Execution

2. Using the Manager Client from your automation project (currently supported only Java)
3. Using Rest API

Test properties

Each test has his own properties, some of them are automatically generated by the Cloud like device.os,
device.version and more

You can easily add your own properties using the Manager Client

Create your first Tests View


Test view is the main page in the reporter, its allow you to easily view your last build results and
navigate between different builds

1. To create a test view open the Tests View page and click on 'Create'
2. Select the View By property - this filed will determine according to what we will distinguish between the
different runs, for example, you can select the 'date' property
Each day will represent a different running
3. Add your filter arguments in the filter bar
4. Save the Tests View

©2023 Digital.ai Inc. All rights reserved Page 600


Test Execution

Adding Tests View to Dashboard


1. Go to the Tests View page and select your Tests View
2. Switch on the 'Add To Dashboard' switch button
3. Go to the Dashboard page

©2023 Digital.ai Inc. All rights reserved Page 601


Test Execution

Test Analytics
Reporter is a BI system for QA organizations, it collects all of your testing data and tries to provide you with a
view of the quality of the application or service under test.

It also helps you in the process of analyzing the execution and identifies the root cause of the issues that
failed.

All analytics tools are supported by the following browsers:

• Chrome
• Edge
• Firefox
• Safari

Notification Bar
The notification bar allows fast access in real time to queued and running.

The notification bar is visible on all cloud pages.

©2023 Digital.ai Inc. All rights reserved Page 602


Test Execution

Queued Tests

The queued tests are displayed with the following icon:

The number in the green circle represents the number of currently queued tests.

Clicking on the icon will show you the latest 5 queued tests.

©2023 Digital.ai Inc. All rights reserved Page 603


Test Execution

A queued test can be canceled using the following button:

The View All link will redirect you to the Execution page (list view).

Running Tests

The running tests are displayed with the following icon:

The number in the green circle represents the number of currently running tests.

Clicking on the icon will show you the latest 5 running tests.

For each test the following information is displayed:

©2023 Digital.ai Inc. All rights reserved Page 604


Test Execution

1) Test name

2) Mobile/desktop test icon

3) Device model for mobile tests / Platform for desktop tests

4) OS icon and version for mobile tests / Browser name and version for desktop tests

5) Test duration (minutes and seconds)

6) Test status (Passed / Failed / Incomplete)

UI Actions
• Test View
• Project Settings
• Transaction View
• Dashboard

Test View

• Filters
• Date range
• Delete tests
• Export

©2023 Digital.ai Inc. All rights reserved Page 605


Test Execution

Filters
Saved Filter Sets.
List.
A "Filter Set" is, as its name implies, a set of filter items used to show only those tests which match with the
desired set.

You will find previously stored filter sets below the project name/search stripe:

You can sort the filter sets by name (default) or by the creator.

To load then apply to test the desired filter set just click it, for example, "SA 26730":

In case you haven't saved any filter set in the past you will see this:

©2023 Digital.ai Inc. All rights reserved Page 606


Test Execution

When you click on it the filter items panel (see below) is expanded so you can start adding filter items.

Options.
Clicking on triple dots in the filter set's opens then filter set's options menu:

• Manage: Allows renaming the Filter Set Name.


• Delete Filter: Delete the Filter (Pending Confirmation)
• Add to Dashboard: Determine if there is a Widgit representing this Filter Set on the Dashboard

Filter Items Panel.


Each filter set is composed of filter items which can add or remove at your convenience:

©2023 Digital.ai Inc. All rights reserved Page 607


Test Execution

Sections:
Header:

"Filter" button: Expands or collapses the panel.

"Filter by" pills: Shows current filter items as "pills"; you can remove an item by clicking on the "x" icon of
the pill.

Item list:

Each row is a filter item which can be edited by selecting a different property and/or value or can be deleted
with the button with the "x" icon at the right of the row.

To remove an Item filter you can use either "x" in the pill shown in the header or the "x" button on the row in
the items list.

Depending on the selected property there are three filter item types:

Property Filter item type


status

The reporter will show you a fixed list of possible values:

For all tests simply remove the filter item.

date

any other

©2023 Digital.ai Inc. All rights reserved Page 608


Test Execution

Property Filter item type

The reporter will show you the distinct values got from project's test, for example:

IMPORTANT:When the list of values exceeds more than the configured limit (1000 by default) a warning message is

shown: This limit is needed because there are

some test keys that have too many different values (in the order of thousands) that cannot be rendered by the UI
because of memory and CPU constraints which in extreme cases makes the application get stuck.

When the item is complete (property and value(s) selected) the item is applied to the test list.

Footer:

Button Action
Add filter Adds a new filter item.

Clear all Clear all filter items.

Save changes Save current filter set; if it hasn't been saved previously will ask for a name for the set.

Save as new filter

Save current filter set as a different set:

©2023 Digital.ai Inc. All rights reserved Page 609


Test Execution

Button Action

Filter name must:

• Contains any alphanumeric character and space - other characters aren't allowed.

• The minimum length is 3 characters.

Press the tab key to leave the name's edit control, if validation fails a question mark icon is displayed, you can
click the icon to see the message, example:

Date range
Setting range.
To open the data range selection dialog click on the "Add or change data range" button ( ) in the filter bar:

©2023 Digital.ai Inc. All rights reserved Page 610


Test Execution

Then select the desired range:

Clicking on the calendar button ( ) or selecting the input box the calendar is shown:

button applies the range creating new filter item(s) or updating existing filter item(s), clears the range
removing filter item(s) if any,

For example, selecting this date range:

©2023 Digital.ai Inc. All rights reserved Page 611


Test Execution

Results in this filter items:

You can remove any of the items using the "x" button.

Date range persistence.


Date range persists at session level: Selected range is applied to new test views or when switching between
test views but if you close the tab or log out Reporter the range is lost.

If you save a test-view with a date range, it'll be saved to the DB as part of the test-view and will be restored
when you will open that test view again.

Note that you can select "date" and filter by such property in "View By" panel, for example (note the orange
border on panel and filter item) independent from the selected range using "Add or change data range":

Such filter is persisted in the database as any other user set filter.

Delete tests
When Cloud Admin enable delete tests to users (see here), the list of tests has a test selector in the first
column:

©2023 Digital.ai Inc. All rights reserved Page 612


Test Execution

You can select or deselect tests with the checkbox in the header area:

As soon as you start selecting tests the button "delete" is enabled:

©2023 Digital.ai Inc. All rights reserved Page 613


Test Execution

You must confirm tests deletion:

The action is registered in the Reporter's log, for example:

2019-03-19 08:44:39.509 INFO [http-nio-9011-exec-8] TestServiceImpl 49 test:


(28547, "Add Data Items") of project:(5, "default"), deleted by admin.

Tip for deleting 100s of test:

• Adjust filter for desired tests to delete, for example, Status = "Incomplete" and specific date range.

• Change page size to 100 (bottom of the screen):

• Use the checkbox in the header to select all tests.

©2023 Digital.ai Inc. All rights reserved Page 614


Test Execution

Export
You can export tests data for the current filter set by clicking the "Export" button:

Export to Excel CSV (all Export to CSV all tests which match the current filter, for each test all user-defined
columns) columns/key/properties.

Export to Excel CSV (current Export to CSV all tests which match the current filter, for each test current, selected columns
columns) ("Columns" button in the header bar of tests list).

Export summary to PDF Export to PDF summary graphs (Bar and Pie) applying the current filter.

Export summary to HTML Export to HTML summary graphs (Bar and Pie) applying the current filter.

Project Settings

If you are a Cloud Administrator or a Project Administrator, you can a Project to Reporter using the Project
Settings page.

1. Click your profile, then click Go to Reporter.

2. Click Settings -> Projects Management.

©2023 Digital.ai Inc. All rights reserved Page 615


Test Execution

Cloud Administrator View

Project Administrator View

If you are a Cloud Administrator, not only do have access to all the registered projects, you can also:

• Add a new project.


• Switch-on or switch-off the "Add to Admin Dashboard" flag.
• Switch-on or switch-off "Allow Users Delete Tests".

If you are a Project Administrator, you can can only see the current project's configuration and cannot edit it.

Add a Project
As a Cloud Administrator you can add projects already registered in Cloud to Reporter.

To add a project:

©2023 Digital.ai Inc. All rights reserved Page 616


Test Execution

1. Click Add.

2. Start typing the name. Reporter lists those projects which contain the word(s) you entered and haven't
been registered in Reporter.

3. Select the project, then click Add.


You can change the settings ("Add to Admin Dashboard" and "Allow Users Delete Tests") at will
including Storage Management and Fields Management.

©2023 Digital.ai Inc. All rights reserved Page 617


Test Execution

Transaction View

Transaction View can be used to view all the recorded performance transactions.

To view the transactions click on the Transactions link in the SeeTest Reporter.

Table
Sort

To sort by a measure simply click on the column's header:

©2023 Digital.ai Inc. All rights reserved Page 618


Test Execution

To change sort direction click header again.

Manage Columns

Above the table, to the right, there is a 'Manage Columns' button that enables us to add and remove columns
for a better view experience.

©2023 Digital.ai Inc. All rights reserved Page 619


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 620


Test Execution

Grouping

You can group transactions by "key" columns (App Name, App Version, Device OS, and OS version).

To do so, click on the "Group by" button and choose the desired column from the drop-down.

Summary values on "key" columns are count distinct, for example in the above image 2nd 3rd-row value "2"
in "App Version" means that there are two different versions in that group.

©2023 Digital.ai Inc. All rights reserved Page 621


Test Execution

Summary values on measure columns are average.

To expand the group and see the transaction detail, click on the button:

To collapse the group click on the button.

By default the grouping key is sorted ascending, you can invert clicking in the grouping panel:

©2023 Digital.ai Inc. All rights reserved Page 622


Test Execution

Finally to remove grouping, click on "Group by" and then the "x" icon.

Open transaction

Clicking on the selected Transaction name will open the Transaction Report.

©2023 Digital.ai Inc. All rights reserved Page 623


Test Execution

Filters
To filter records you can add new items in the filter panel. To open the panel click the "Filters" button:

Every change in the filters will be immediately applied to the table.

©2023 Digital.ai Inc. All rights reserved Page 624


Test Execution

You can add filter items as many as you want, each new item is connected to previous ones with AND
connector.

To remove a filter item simply click on the "x" icon at the right side of the panel.

Chart
After grouping, a chart displaying information is presented. Displayed in the range axis is the selected field
from the drop-down button. Displayed on the domain axis are the values of the grouped field.
In accordance with filter, group, sorting, and search string applied the data is presented in the graph.

©2023 Digital.ai Inc. All rights reserved Page 625


Test Execution

Search
In addition to the filter, you can also search text. The selected search will be added to the current filter
selection.

Export to CSV
On the right side of the screen, you can click the export button. Clicking it will download a CSV file containing
the filtered transactions.

Delete Transactions
It is possible to delete transactions for administrators. In admin mode, there is a 'Delete' button next to the
'Export to CSV' button. Pressing it will delete all checked transactions.
After pressing delete, a dialog will open to assert the delete action. Deleting a transaction will delete all
related transaction data (transaction video file, HAR file, etc.)

©2023 Digital.ai Inc. All rights reserved Page 626


Test Execution

Transaction Report

©2023 Digital.ai Inc. All rights reserved Page 627


Test Execution

Transaction Report Screen


You can see all the graphs synchronized with the video.

View HAR File


To view a HAR file attached, click the hamburger icon, then click View HAR file.

©2023 Digital.ai Inc. All rights reserved Page 628


Test Execution

The HAR file can be viewed using a HAR file viewer. You can use the viewer here.

The purpose of this tool is to visualize the HTTP Archive (HAR) log files created by HTTP tracking tools.

These files contain a log of HTTP client/server conversation and can be used for additional analyses, for
example, page load performance.

©2023 Digital.ai Inc. All rights reserved Page 629


Test Execution

Basic Usage
The Preview tab in the HAR file viewer shows the list of HTTP requests recorded with all its basic details like:

• method
• URL
• response status
• response (compressed and uncompressed)
• response time

To see further details, click the applicable plus icon.

©2023 Digital.ai Inc. All rights reserved Page 630


Test Execution

To inspect the raw values, click the HAR tab. The values are displayed in a JSON tree.

©2023 Digital.ai Inc. All rights reserved Page 631


Test Execution

Dashboard

Reporting Dashboard allows Admins or Users to view the summary of tests run.

Following are the types of dashboards.

• Cloud Admin Dashboard

©2023 Digital.ai Inc. All rights reserved Page 632


Test Execution

• Project Dashboard

Cloud Admin Dashboard


Cloud Admin Dashboard shows the selected filter sets summary pie charts of selected projects:

Each pie displays the latest two dates found for the filter set.

Actions.
• Clicking on the filter set's name redirects to the Tests page loading the clicked filter set.
• Clicking on a date does as above but adds or updates date filter item in the filter set.
• Clicking on the doughnut's slice (test status) does as clicking date adding or updating status filter
item in the filter set.

©2023 Digital.ai Inc. All rights reserved Page 633


Test Execution

How to configure.
From Settings > Project Management Cloud admins can select what project will be shown in the dashboard:

Project Dashboard
Project Dashboard shows the selected filter sets summary pie charts of the currently selected project:

©2023 Digital.ai Inc. All rights reserved Page 634


Test Execution

Each pie display the latest two dates found for the filter set.

Actions.
• Clicking on the filter set's name redirects to the Tests page loading the clicked filter set.
• Clicking on a date does as above but adds or updates date filter item in the filter set.
• Clicking on the doughnut's slice (test status) does as clicking date adding or updating status filter
item in the filter set.

How to configure.
From the Tests page, Cloud admins, Project admins, or the creator of the filter set can switch the "Add to
dashboard" flag:

©2023 Digital.ai Inc. All rights reserved Page 635


Test Execution

Test Notifications Bar


The Test notifications bar allows you to keep track of the status of automated tests that you run in the cloud.

The notifications bar lists two type of statuses:

Queued Test
These are tests that await execution. All tests enter the queue before being executed. A test will normally
move to the running list unless conditions do not allow it to start running. For example, a test might be
configured to run on a specific device but the at the time of initiating the test, the device was already taken.
To view the list of the last five tests that entered the queue, open notification bar and click on 'Queued Tests'
tab.

To view the full list of tests in the queue, click on View All.

©2023 Digital.ai Inc. All rights reserved Page 636


Test Execution

Running Tests
These are tests that moved from the queue and started running. To view the last five tests that started
running, click on the running monitor icon.

To view the full list of running tests, click on View All.

©2023 Digital.ai Inc. All rights reserved Page 637


Test Execution

Test Results
After a test has finished running a report is generated and added to the list of reports. To view reports of the
tests, click on "Reports" in the notification bar. To view a specific report, select the report from the table and
open it.

©2023 Digital.ai Inc. All rights reserved Page 638


Test Execution

Test Results
All test reports (both manual and automated reports) are displayed on the Reports page.

You can access the Reports page by clicking on the monitor icon in the notifications bar and then clicking
View All.

Test Report Data


Every test report contains the following data:

©2023 Digital.ai Inc. All rights reserved Page 639


Test Execution

1. ID - ID of the test in the system


2. Test Name - the name of test that was configured in the capabilities.
3. Status - whether the test passed, failed or was never completed
4. Type - device type
5. Platform - device model (for mobile tests) or browser type (for desktop web tests)
6. OS - operating system.
7. Duration - how long it took the test to finish.
8. Created - the time the test entered the queue.
9. Started - the time the test moved from queue to running.
10. Executor - whether the test was a manual or automated test.
11. User - The user who executed the test.

Filtering Reports
The Reports page includes 6 categories by which you can filter tests and customize the view:

1. Status
1. Passed
2. Failed
3. Incomplete
2. Type
1. Mobile (Appium)
2. Web (Selenium)
3. OS
1. iOS
2. Android
3. Windows
4. Mac OSX
4. Platform - device model (e.g. iPhone 6, Nexus 5), or browser type (e.g. Chrome, Firefox, Safari)

©2023 Digital.ai Inc. All rights reserved Page 640


Test Execution

5. Date Range
1. Today
2. Last 7 days
3. Last 30 days
4. All
6. Executor
1. Manual - reports that were generated manually.
2. Grid - reports that were generated for automated tests.

Accessing Report
To access the detailed report, click on the report name.

You will then be redirected to a page that displays the report that is generated for automated tests, or the one
that you generated for you manual tests.

©2023 Digital.ai Inc. All rights reserved Page 641


Test Execution

Automated Test Reports

Every time you run an automated test on the Continuous Testing cloud platform, a shareable HTML report is
generated automatically.

The report includes the following data:

1. Test Capabilities
2. Test Steps
3. Screenshots
4. Command Parameters and Output
5. Debug Data
6. Error Messages (including exceptions)

You can use the report to analyze failures and adjust test cases. The report can be shared with other
developers and testers and can really boost collaboration and productivity.

Obtaining The Report


Whenever you run an automated test on the grid, a report URL and a report ID are added to the test
capabilities. You can obtain the report URL by printing it to the log or console. The capabilities names
are reportURL and reportTestId.

The best way is to print the report URL and report ID in the teardown stage of the test.

Getting Report URL in Java


@After
public void tearDown() {
if (driver != null)
{
driver.quit();
System.out.println("Report URL : " + driver.getCapabilities().getCapab
ility("reportUrl"));
System.out.println("Report ID: " + driver.getCapabilities().get
Capability("reportTestId"));
}
}

©2023 Digital.ai Inc. All rights reserved Page 642


Test Execution

Getting Report URL in Python


def tearDown(self):
if self.driver is not None:
print(self.driver.capabilities.get("reportUrl"))
print(self.driver.capabilities.get("reportTestId"))
self.driver.quit()
Getting Report URL in C Sharp
[TearDown()]
public void TearDown()
{
if (driver != null)
{
Console.WriteLine(driver.Capabilities.GetCapability("reportUrl
"));
Console.WriteLine(driver.Capabilities.GetCapability("reportTes
tId"));
driver.Quit();
}
}
Getting Report URL in Ruby
def teardown
puts @driver.capabilities['reportUrl']
puts @driver.capabilities['reportTestId']
@driver.quit
end

Understanding The Report


Watch the video to see what the report looks like and how you can browse the report to see the relevant
information.

The first tab in the report is the execution summary. It lists information related to test execution, device, and
capabilities.

The next three tabs are the init steps. The init steps include initializing test capabilities, test type, and test
context (Native or Web)

All steps following the steps listed above are the steps of the test itself. These include:

• Screenshots of the device at the time the step took place (when a command was executed) -
screenshots correspond to each and every step of the test. For every step there is a screenshot of the
device at the time a specific command was executed. For every text that is sent to an input field, for
every click or any other gesture, a screenshot is taken to display the device state at the time of carrying

©2023 Digital.ai Inc. All rights reserved Page 643


Test Execution

out the command. The screenshots add a visual dimension that really helps you understand the cause
the of failures if such occur.

Your browser does not support the video tag.

• Command parameters - For each step, under the Debug Properties tab, there is a collapsible section
called Command Parameters. You can see under this section the parameters that were passed to the
command as well as additional information.
• Command output and result - For each step, under the Result Details tab, there is a section
titled Result Data. If the command that was used returns some value, you will see the returned value
under Result Data. It could the text of an element, the page source (XML of node hierarchy) and more.

Disabling The Report


If you don't want to generate a report, you can do so by passing a capability to disable the report.

report.disable = true
Disable Report using Java
dc.setCapability("report.disable", true);
Disable Report using Python
self.dc['report.disable'] = True
Disable Report using C Sharp
dc.SetCapability("report.disable", true);
Disable Report using Ruby
desired_caps = {
caps: {
# other caps
report.disable: true,
# other caps
appium_lib: {
server_url: 'https://cloud.seetest.io:443/wd/hub',
}
}

CI Integration

Generate Custom Filter Set link:


You can generate a LINK to your customized Filter Set with the following format:

http://<reporter's host>:<reporter's port>/reporter/tests?testView=<Filter Set url encoded>

©2023 Digital.ai Inc. All rights reserved Page 644


Test Execution

Paramater Description

<reporter's Reporter's URL, for example: localhost:9000


host>:<reporter's
port>

<Filter Set object


URL encoded>

{"filter": [{"property": "device.os", "operator": "=", "value": "iOS"}]}

Filter Set object in URL Encoding

%7B%22filter%22%3A+%5B
%7B%22property%22%3A+%22device.os%22%2C+%22operator%22%3A+%22%3D%22%2C+%22va
lue%22%3A+%22iOS%22%7D%5D%7D%0D%0A

Filter Set Object.


Define the query expression by adding filters items, each filter item has its key name, operator, and key
value, for example, filter key 'os.version' with operator equal '=' and value '12.0'
We currently support only the equal '=' operator

Only Filter
{
"filter": [{"property": "os.version", "operator": "=", "value": "12.0"}
]
}

Example

View By + Filter + Columns


{
"filter": [{"property": "os.version", "operator": "=", "value": "12.0"}
],
}

Encoding JSON to URL using JavaScript code

Simply create a JavaScript object then encode it, for example:

©2023 Digital.ai Inc. All rights reserved Page 645


Test Execution

...
let testView = {
filter: [ { property: "test_group", operator: "=", value: groupName } ]
};
let url = reporterUrl + encodeURIComponent(JSON.stringify(testView));
window.open(url);
...

Performance Pipeline
Introduction
Application owners want to test the latest version of their application, say "Banking Self-Care", and how it
measures (memory usage, CPU usage, battery consumption, network bandwidth usage or duration) and how
this has changed over previous versions. For a given transaction name and measure we define an accepted
change (in "comparison target") and if the measure has changed to be equal or below that value it is
acceptable ("ok") otherwise (obviously) not acceptable ("fail"). For example, maximum memory usage should
not vary, for the latest version over past versions, or more than 5% for the "Inquiry" transaction:

Previous version Change (last over previous)

Latest version

100M 90M (100 - 90) / 90 = 11%

Input

• Filter: application name and device OS.


• Base version: The version I want to compare to older versions; can be specific version string ("7.0") or
"latest".
• How many previous versions will be used for the comparison?
• List of accepted change % per transaction name and measure (comparison targets).

Example:

• Filter:
◦ Application name: "Banking Self-Care"
◦ Device OS: "Android"

©2023 Digital.ai Inc. All rights reserved Page 646


Test Execution

• Base version: "7.0"


• Previous versions: 2

• Comparison targets:

Transaction name Measure Accepted change %

Inquiry Max Memory 10%

Inquiry Max CPU 5%

Transfer Bytes uploaded 15%

Transfer Bytes downloaded 20%

Output

For each comparison target (transaction/measure/maximum accepted change) a row will be returned with
the following properties:

• Transaction name
• Measure name
• Base value: the average of values for the measure for the base version.
• Base count: how many transactions' measures are found for the base version.
• Previous value: the average of average by version (see example below) of measured values of the 2
previous versions.
• Previous count: how many transactions' measures are found for the 2 previous versions.
• Previous key count: how many different versions found.
• Accepted change %: same as in the request.
• Actual change %: change of the "Base value" over "Previous value".
• Status: "ok" in case "Actual change %" <= "Accepted change %" else "fail".

Example:

We have the values of Max Memory of different transaction tests for "Banking Self-Care" on "Android" OS for
"Inquiry" transaction:

Version Max Memory

7.0 110

7.0 105

7.0 107

7.0 99

6.9 80

©2023 Digital.ai Inc. All rights reserved Page 647


Test Execution

6.9 79

6.9 88

6.9 95

6.9 88

6.9 120

6.8 125

6.8 110

6.7 50

6.7 65

The request asked for base version "7.0", the base value is the average of those values is 105.25.

Requested previous versions are 2 which are "6.9" and "6.8", the average of those values is 91.67 and 117.5
respectively, the final average is 104.58.

Actual change: ((105.25 - 98.125) / 98.125) * 100 = 0.64

Resulting row for first acceptance criteria will be:

• Transaction name: "Inquiry"


• Measure name: "memMax"
• Base value: 105.25
• Base count: 4
• Previous value: 104.58
• Previous count: 8
• Previous key count: 2
• Accepted change %: 10.9
• Actual change %: 0.64
• Status: ok

Endpoint
POST /api/transactions/compare?token=<accessKey>

Since the feature is meant to be used in automated pipeline, we must provide the accessKey string which
you get from Cloud > "User menu" > "Get access key". Remember to select the desired project before
getting the access key.

When the Cloud is operating in single-port mode, you must add the "/reporter" context to the request, for
example, if Cloud's URL is www.mycloud.com the URL for the request would be www.mycloud.com/
reporter/API/transactions/compare.

©2023 Digital.ai Inc. All rights reserved Page 648


Test Execution

Request body object


{
"filter": [ ...<filter expression>... ],
"baseKey": <string>,
"baseKeyValue": <string value>,
"compareCount": <integer>,
"comparisonTargets": [
{
"name": <string>,
"measure": <string>,
"acceptedChange": <numeric>
}, ...
]
}

Property Notes
filter Simple comparison expression is a 3 element array composed of property name followed by the comparison operator ("=", ">", ">
"startswith", "endswidth", "contains") then a value, example:[ "appName", "=", "Bank" ]In case you have more than one compariso
include each simple comparison expression array as elements of enclosing array and include the logical operator ("and" / "or") be
example:[ [ "appName", "=", "Bank" ], "and", [ "deviceOs", "=", "Android"] ]Currently accepted left side for comparison expression
"deviceOs".

baseKey Transaction's property to be used to compute average values to be compared. As today the only supported base key is appVersio

baseKeyValue The base key used to compute measures value which will be compared against "older" values. We only accept appVersion as ba
description is "base version to be compared against previous versions". he constant string "latest" means the maximum base key

compareCount How many older base key values ("versions") before base key value will be used to compute measured values to be compared ag
value ("base version").

comparisonTargets List of comparisons to be performed:

name Transaction name.

measure Transaction’s measure property name to be computed then


compared:cpuAvgcpuMaxmemAvgmemMaxbatteryAvgbatteryMaxtotalUploadedBytestotalDownloadedByte

acceptedChange Maximum accepted change.

Examples:

{
"filter": [ "appName", "=", "com.experitest.ExperiBank" ],
"baseKey": "appVersion"
"baseKeyValue": "7.0.7",
"compareCount": 5,
"comparisonTargets": [
{
"name": "EriBank Transaction Withdrawn",
"measure": "maxMem",

©2023 Digital.ai Inc. All rights reserved Page 649


Test Execution

"acceptedChange": 5.0
},
{
"name": "EriBank Transaction Deposit",
"measure": "maxCpu",
"acceptedChange": 15.0
}
]
}

{
"filter": [
[ "deviceOs", "=", "Android" ],
"and",
[ "appName", "=", "com.experitest.ExperiBank" ]
],
"baseKey": "appVersion"
"baseKeyValue": "latest",
"compareCount": 10,
"comparisonTargets": [
{
"name": "Inquiry",
"measure": "maxMem",
"acceptedChange": 20.0
}
]
}

Response object

The response is an array of objects corresponding one element for each comparisonTarget in the request:

[
{
"name": <string>,
"measure": "<string>",
"baseValue": <number>,
"baseCount": <integer>,
"prevValue": <number>,
"prevCount": <integer>,
"prevKeyCount": <integer>,
"acceptedChange": <number>,
"actualChange": <number>,
"status": <string>
"reason": <string>,
"link": <string>
} ...
]

©2023 Digital.ai Inc. All rights reserved Page 650


Test Execution

Property Notes
name Transaction name.

measure Compared measure.

baseValue The value computed for base key value ("version")

baseCount How many non-null measure values found for the base key value.

prevValue The value computed for previous base key values found ("previous versions").

prevCount How many non-null measure values found for previous base key values ("previous versions").

prevKeyCount How many distinct previous key values were found. For example, for the run, we are comparing "Inquiry" and
"Deposit" transactions for the version "7.0" against previous 2 versions: "6.9" and "6.8":

Version Transaction Measure

7.0 Inquiry 100

6.9 Inquiry 92

6.9 Inquiry 90

6.8 Inquiry 87

7.0 Deposit 100

6.8 Deposit 95

Response contains:{ "name: "Inquiry", … "prevKeyCount": 2, ... },{ "name: "Deposit", … "prevKeyCount":
1, ... }, ...

acceptedChange Same as request.

actualChange Computed change:((baseValue - prevValue) / prevValue) * 100

status "ok" or "fail".

reason Reason of "fail", can be one of the following lists:

• "Change above accepted value."

• "Value for [baseKey] = [base key values]] not found" (example: "Value for appVersion = [ 7.0, 6.9 ] not found".

link Link to transaction’s page with JSON url encoded "options" containing:

• Project name

• Group by key name

• Filter containing request filter plus previous base key values found ("previous versions")

Example ("options" not encoded for clarity):https://experitest.com/reporter/reporter/transactions?


options={"projectName":"Default","groupBy":"appVersion","filter":[["appName","=","Bank"],"and",

©2023 Digital.ai Inc. All rights reserved Page 651


Test Execution

Property Notes
["appVersion","in",["6.9","6.8"]],"and",["name","=","Inquiry"]]}Worth mentioning that the generated link is aware of
Reporter running behind Cloud in "single port" mode.

Java Example
Stand alone, reporter.
package com.experitests.manager.examples;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import org.junit.Assert;
import org.junit.Test;

public class TransPerfExample1 {


String baseUrl = "http://cloud/reporter/api/transactions/compare";
String token = "xxxxx...xxxxx";

@Test
public void test1() throws Exception {
String request = "{\n" +
"\t\"filter\": [\"appName\", \"=\", \"Bank\"],\n" +
"\t\"baseKey\": \"appVersion\",\n" +
"\t\"baseKeyValue\": \"7.0\",\n" +
"\t\"compareCount\": 1,\n" +
"\t\"comparisonTargets\": [\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"cpuMax\", \"accep
tedChange\": 10.0 },\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"memMax\", \"accep
tedChange\": 10.0 },\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"batteryMax\", \"a
cceptedChange\": 10.0 },\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"totalDownloadedBy
tes\", \"acceptedChange\": 10.0 }\n" +
"\t]\n" +
"}";
HttpResponse<String> response = Unirest.post(baseUrl + "?token=" + tok
en)
.header("Content-Type", "application/json")
.body(request)
.asString();
int status = response.getStatus();
Assert.assertEquals(200, status);
if (status == 200) {
System.out.println(response.getBody());

©2023 Digital.ai Inc. All rights reserved Page 652


Test Execution

}
}
}

Cloud in single port:

(note the "/reporter" in baseUrl)

package com.experitests.manager.examples;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import org.junit.Assert;
import org.junit.Test;

public class TransPerfExample2 {


String baseUrl = "http://cloud/reporter/api/transactions/compare";
String token = "xxxxx...xxxxx";

@Test
public void test1() throws Exception {
String request = "{\n" +
"\t\"filter\": [\"appName\", \"=\", \"Bank\"],\n" +
"\t\"baseKey\": \"appVersion\",\n" +
"\t\"baseKeyValue\": \"7.0\",\n" +
"\t\"compareCount\": 1,\n" +
"\t\"comparisonTargets\": [\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"cpuMax\", \"accep
tedChange\": 10.0 },\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"memMax\", \"accep
tedChange\": 10.0 },\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"batteryMax\", \"a
cceptedChange\": 10.0 },\n" +
"\t\t{ \"name\": \"Inquiry\", \"measure\": \"totalDownloadedBy
tes\", \"acceptedChange\": 10.0 }\n" +
"\t]\n" +
"}";
HttpResponse<String> response = Unirest.post(baseUrl + "?token=" + tok
en)
.header("Content-Type", "application/json")
.body(request)
.asString();
int status = response.getStatus();
Assert.assertEquals(200, status);
if (status == 200) {
System.out.println(response.getBody());
}

©2023 Digital.ai Inc. All rights reserved Page 653


Test Execution

}
}

Reporting Data

• Reporting and Client Side Failures


• Java Support
• Rest API

Reporting and Client Side Failures


Introduction
During an automation test, Assertion or Exceptions can be thrown outside any context of SeeTest client.

This fails the test but because the exception isn't happening during any execution in SeeTest Server, the test
status will be displayed as Passed instead of Failed.

For example, let us consider the following test case.

DeviceByZeroTest
@Test(priority = 1)
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

As we can see there is a divide by zero error, the cause for it was purely based on the client code with no
involvement of SeeTest Cloud Server.

However, if we observe in the SeeTest Cloud Portal test result, there are no errors and the report status will
be displayed as "Passed".

Test Results without Listeners - Test will be displayed as Passed, on


any client-side errors.

In such situations, SeeTest recommends integrating SeeTest Reporting Listeners into the Tests. These
listeners will report to the "Grid reporter" any exception or failed assertion and mark the test as failed.

©2023 Digital.ai Inc. All rights reserved Page 654


Test Execution

Test Results with Listeners - Test will be displayed as Failed, on any


client-side errors.

Setup
Each testing framework has been split into 3 jars. Typically these jars are bundled when you install Appium
Studio

• TestNG 6.9.10
• Junit 4.12
• Junit 5.2.0

Libraries bundled with SeeTest Client

Libraries are located under the client folder reporter <SeeTest installation folder>\clients\reporter\java

• reporter-testng.jar
• reporter-junit4.jar
• reporter-junit5.jar

Code Usage
TestNG

There are many ways to configure a listener in TestNG.

Create a build.gradle file and configure dependency

TestNG Gradle Dependency


dependencies {
compile group: 'org.testng', name: 'testng', version: '6.9.10'
compile fileTree(dir: '<seeTest\Appium Installation folder>\\clients\\r
eporter\\java', include:'reporter*.jar')

// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\
java', include: '*.jar')
}

©2023 Digital.ai Inc. All rights reserved Page 655


Test Execution

Implement a TestNG Class (in this example 'AppiumDriver') with setup and teardown function. See
"@Listeners({com.experitest.reporter.testng.Listener.class})" annotation below in code. Listener
communicates to Grid Reporter the Client side failure.

Test Class
package com.experitest.testng;
.....
@Listeners({com.experitest.reporter.testng.Listener.class})
public class AppiumDriver {
protected AndroidDriver driverAndroid;
@BeforeMethod
public void setup(){
System.out.println(">>>>>> I'm in Setup");
DesiredCapabilities dcAdroid = new DesiredCapabilities;
dcAdroid.setCapability("deviceQuery", "@os='android'");
// Please replace YOUR_CLOUD_ACCESSKEY with your cloud access key
dcAdroid.setCapability("accessKey", "YOUR_CLOUD_ACCESSKEY");
dcAdroid.setCapability(MobileCapabilityType.APP, "cloud:com.experi
test.ExperiBank/.LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".
LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "co
m.experitest.ExperiBank");

String url = new URL("http://" + HOST_NAME_GRID + "8080:/wd/hub");


System.out.println(dcAdroid);
driverAndroid = new AndroidDriver(url, dcAdroid);
}

@AfterMethod
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
driverAndroid.quit();
driverAndroid = null;
System.out.println(">>>>>> Reports generated");
}

Implement test functions and include in TestNG class above. See divideByZero function which produces and
client-side error.

Test methods
@Test(priority = 0)
public void methodPass() {
System.out.println(">>>>>> I'm in method pass");
}

@Test(priority = 1)

©2023 Digital.ai Inc. All rights reserved Page 656


Test Execution

public void dividedByZero() {


System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

@Test(dependsOnMethods = { "dividedByZero" })
public void methodSkip() {
System.out.println(">>>>>> I'm in method skip");
}

If the test passes in the TestNG framework, the test will be reported as passed, even if a step (or more) had
failed in the test itself.

JUnit4 using Runner

Configure Gradle Dependency

Gradle Junit4 Dependency


//JUnit4
dependencies {
compile group: 'junit', name: 'junit', version: '4.12'
compile '<seeTest Installation folder>\\clients\\reporter\\java\\reporter-
junit4.jar'

// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\java
', include: '*.jar')
}

First set the annotation relevant to the runner as a class annotation

Class Anotation @RunWith


@RunWith(ReporterRunner.class)
public class SeeTestAutomationTestClass {
.....

Then make sure you have one of the following class property, the name of the property is not important

Class Property
// And/OR
protected SeeTestClient seeTestClient;
// And/OR
protected AndroidDriver driverAndroid;
// And/OR
protected IOSDriver driverIOS;

Initialize the driver as you would usually do

©2023 Digital.ai Inc. All rights reserved Page 657


Test Execution

Setup Driver

@Before
public void setup(){
System.out.println(">>>>>> I'm in Setup");
DesiredCapabilities dcAdroid = new DesiredCapabilities;
dcAdroid.setCapability("deviceQuery", "@os='android'");
// Please replace YOUR_CLOUD_ACCESSKEY with your cloud access key
dcAdroid.setCapability("accessKey", "YOUR_CLOUD_ACCESSKEY");
dcAdroid.setCapability(MobileCapabilityType.APP, "cloud:com.experit
est.ExperiBank/.LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".
LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "co
m.experitest.ExperiBank");

String url = new URL("http://" + HOST_NAME_GRID + "8080:/wd/hub");


System.out.println(dcAdroid);
driverAndroid = new AndroidDriver(url, dcAdroid);
}

@After
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
driverAndroid.quit();
driverAndroid = null;
System.out.println(">>>>>> Reports generated");
}

Run a test that generates an exception

Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

JUnit4 using a Rule

Set Gradle Dependency

Gradle Junit4 Dependency


//JUnit4
dependencies {
compile group: 'junit', name: 'junit', version: '4.12'

©2023 Digital.ai Inc. All rights reserved Page 658


Test Execution

compile '<seeTest Installation folder>\\clients\\reporter\\java\\reporter-


junit4.jar'

// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\
java', include: '*.jar')
}

First set the Rule declaration

Class Anotation @RunWith


public class SeeTestAutomationTestClass {

@Rule
public ReporterRule reporterRule = new ReporterRule(this);

Then make sure you have one of the following class property, the name of the property is not important

Class Property
// And/OR
protected SeeTestClient seeTestClient;
// And/OR
protected AndroidDriver driverAndroid;
// And/OR
protected IOSDriver driverIOS;

Initialize the driver as you would usually do

Setup Driver
@Before
public void setup(){
System.out.println(">>>>>> I'm in Setup");
DesiredCapabilities dcAdroid = new DesiredCapabilities;
dcAdroid.setCapability("deviceQuery", "@os='android'");
// Please replace YOUR_CLOUD_ACCESSKEY with your cloud access key
dcAdroid.setCapability("accessKey", "YOUR_CLOUD_ACCESSKEY");
dcAdroid.setCapability(MobileCapabilityType.APP, "cloud:com.experi
test.ExperiBank/.LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".
LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "co
m.experitest.ExperiBank");

String url = new URL("http://" + HOST_NAME_GRID + "8080:/wd/hub");


System.out.println(dcAdroid);
driverAndroid = new AndroidDriver(url, dcAdroid); }

©2023 Digital.ai Inc. All rights reserved Page 659


Test Execution

Replace all references from @After to @AfterWithSeeTestReporter

@AfterWithSeeTestReporter method
@AfterWithSeeTestReporter
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
driverAndroid.quit();
driverAndroid = null;
System.out.println(">>>>>> Reports generated");
}

@After can't be used because it runs before we get to the part the failed status is sent to the server thus
closing the driver will cause the setReporterStatus request to fail.

So another annotation ( @AfterWithSeeTestReporter ) is used to replace it

This will call the tearDown right after the status is sent.

Run a test that generates an exception

Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

JUnit5

Set Gradle Dependency

Gradle Junit5 Dependency


//JUnit5
dependencies {
compile 'org.junit.jupiter:junit-jupiter-api:5.2.0'
compile '<seeTest Installation folder>\\clients\\reporter\\java\\reporter-
junit5.jar'

// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\
java', include: '*.jar')
}

First set the annotation relevant to the runner as a class annotation

Class Anotation @RunWith

©2023 Digital.ai Inc. All rights reserved Page 660


Test Execution

@ExtendWith(SeeTestReporterExceptionExtension.class)
public class SeeTestAutomationTestClass {
.....

Then make sure you have one of the following class property, the name of the property is not important

Class Property
// And/OR
protected SeeTestClient seeTestClient;
// And/OR
protected AndroidDriver driverAndroid;
// And/OR
protected IOSDriver driverIOS;

Initialize the driver as you would usually do

Setup Driver
@BeforeEach
public void setup(){
System.out.println(">>>>>> I'm in Setup");
DesiredCapabilities dcAdroid = new DesiredCapabilities;
dcAdroid.setCapability("deviceQuery", "@os='android'");
// Please replace YOUR_CLOUD_ACCESSKEY with your cloud access key
dcAdroid.setCapability("accessKey", "YOUR_CLOUD_ACCESSKEY");
dcAdroid.setCapability(MobileCapabilityType.APP, "cloud:com.experi
test.ExperiBank/.LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_ACTIVITY, ".
LoginActivity");
dcAdroid.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "co
m.experitest.ExperiBank");

String url = new URL("http://" + HOST_NAME_GRID + "8080:/wd/hub");


System.out.println(dcAdroid);
driverAndroid = new AndroidDriver(url, dcAdroid);
}
@AfterEach
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
driverAndroid.quit();
driverAndroid = null;
System.out.println(">>>>>> Reports generated");
}

Run a test that generates an exception

Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");

©2023 Digital.ai Inc. All rights reserved Page 661


Test Execution

int e = 1 / 0;
}

Java Support
This section details how Java is supported in Test Execution.

Grid - SeeTest Client


1. Introduction
During an automation test Assertions or Exceptions can be thrown outside any context of the SeeTest client.

This fails the test, but because the exception isn't happening during any execution in the SeeTest Server, the
test isn't shown in the report as Failed.

This library will report to the Grid reporter any exception or failed assertion and mark the test as failed.

2. Setup
Each testing framework have been split into 3 jars

• TestNG 6.9.10
• Junit 4.12
• Junit 5.2.0

2.1 Libraries bundled with SeeTest Client

Libraries are located under the client folder reporter <SeeTest installation folder>\clients\reporter\java

• reporter-junit4.jar
• reporter-junit5.jar
• reporter-testng.jar

2.2 Libraries set as dependencies using local jar and global repository.

Gradle

©2023 Digital.ai Inc. All rights reserved Page 662


Test Execution

//JUnit5
dependencies {
compile 'org.junit.jupiter:junit-jupiter-api:5.2.0'
compile '<seeTest Installation folder>\\clients\\reporter\\java\\reporter-
junit5.jar'

//SeeTest Client
compile fileTree(dir: '<seeTest Installation folder>\\clients\\java', in
clude: '*.jar')
}

//JUnit4
dependencies {
compile group: 'junit', name: 'junit', version: '4.12'
compile '<seeTest Installation folder>\\clients\\reporter\\java\\reporter-
junit4.jar'

// SeeTest Client
compile fileTree(dir: '<seeTest Installation folder>\\clients\\java', in
clude: '*.jar')
}

//TestNG
dependencies {
compile group: 'org.testng', name: 'testng', version: '6.9.10'
compile '<seeTest Installation folder>\\clients\\reporter\\java\\reporter-
testng.jar'

// SeeTest Client
compile fileTree(dir: '<seeTest Installation folder>\\clients\\java', in
clude: '*.jar')
}
Maven Dependencies
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.jupiter.version}</version>
</dependency>
<dependency>
<groupId>com.experitest</groupId>
<artifactId>reporter</artifactId>
<systemPath>${SeeTest.Installation.Folder}/reporter/java/reporter-junit5.jar<
/systemPath>
</dependency>
<dependency>
<groupId>io.appium</groupId>
<artifactId>java-client</artifactId>

©2023 Digital.ai Inc. All rights reserved Page 663


Test Execution

<version>4.1.2</version>
</dependency>

3. Code Usage:
3.1 Prerequisite

In order to get access to the client, it is mendatory that either one instance of the following object is a
property on the test class

• com.experitest.appium.SeeTestClient
• com.experitest.client.Client
• IOSDriver
• AndroidDriver

3.1 JUnit4 using Runner

1) First set the annotation relevant to the runner as class annotation

Class Anotation @RunWith


@RunWith(ReporterRunner.class)
public class SeeTestAutomationTestClass {
.....

2) Then make sure you have one of the following class property, the name of the property is not important

Class Property
...
protected Client client;
protected GridClient grid = null;
private String accessKey = "eyJ4c.......";
final String HOST_NAME = "seetest.appium.pc";
private String host = "http://" + HOST_NAME + ":8080/wd/hub";
...

3) Initialize the driver as you would usually do

Setup Driver
@Before
public void setup(){
System.out.println(">>>>>> I'm in Setup");

©2023 Digital.ai Inc. All rights reserved Page 664


Test Execution

String name = testInfo.getTestMethod().get().getName();


Logger.setLevel(Level.DEBUG);
String deviceOS = "ios";
grid = new GridClient(accessKey, host);
client = grid.lockDeviceForExecution(name, "@os='" + deviceOS +
"'", 10, 50000);
client.setReporter("xml", "reports", name);
}
@After
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
client.generateReport(false);
client.releaseClient();
System.out.println(">>>>>> Reports generated");
}

4) Run a test that generate an exception

Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

3.2 JUnit4 using a Rule

1) First set the Rule declaration

Class Anotation @RunWith


public class SeeTestAutomationTestClass {

@Rule
public ReporterRule reporterRule = new ReporterRule(this);

2) Then make sure you have one of the following class property, the name of the property is not important

Class Property
...
protected Client client;
protected GridClient grid = null;
private String accessKey = "eyJ4c.......";
final String HOST_NAME = "seetest.appium.pc";
private String host = "http://" + HOST_NAME + ":8080/wd/hub";
...

3) Initialize the driver as you would usually do

©2023 Digital.ai Inc. All rights reserved Page 665


Test Execution

Setup Driver
@Before
public void setup(){
System.out.println(">>>>>> I'm in Setup");
String name = testInfo.getTestMethod().get().getName();
Logger.setLevel(Level.DEBUG);
String deviceOS = "ios";
grid = new GridClient(accessKey, host);
client = grid.lockDeviceForExecution(name, "@os='" + deviceOS +
"'", 10, 50000);
client.setReporter("xml", "reports", name);
}

4) Replace all references from @After to @AfterWithSeeTestReporter

@AfterWithSeeTestReporter method
@AfterWithSeeTestReporter
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
client.generateReport(false);
client.releaseClient();
System.out.println(">>>>>> Reports generated");
}

@After can't be used because it runs before we get to the part the failed status is sent to the server thus
closing the driver will cause the setReporterStatus request to fail.

So another annotation ( @AfterWithSeeTestReporter ) is used to replace it

This will call the tearDown right after the status is sent.

4) Run a test that generate an exception

Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

3.3 JUnit5

1) First set the annotation relevant to the runner as class annotation

Class Anotation @RunWith


@ExtendWith(SeeTestReporterExceptionExtension.class)
public class SeeTestAutomationTestClass {
.....

©2023 Digital.ai Inc. All rights reserved Page 666


Test Execution

2) Then make sure you have one of the following class property, the name of the property is not important

Class Property
...
protected Client client;
protected GridClient grid = null;
private String accessKey = "eyJ4c.......";
final String HOST_NAME = "seetest.appium.pc";
private String host = "http://" + HOST_NAME + ":8080/wd/hub";
...

3) Initialize the driver as you would usually do

Setup Driver
@BeforeEach
public void setup(){
System.out.println(">>>>>> I'm in Setup");
String name = testInfo.getTestMethod().get().getName();
Logger.setLevel(Level.DEBUG);
String deviceOS = "ios";
grid = new GridClient(accessKey, host);
client = grid.lockDeviceForExecution(name, "@os='" + deviceOS +
"'", 10, 50000);
client.setReporter("xml", "reports", name);
}
@AfterEach
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
client.generateReport(false);
client.releaseClient();
System.out.println(">>>>>> Reports generated");
}

4) Run a test that generate an exception

Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

3.4 TestNG

There are many ways to configure a listener in TestNG

In this example we are going to use an XML definition file

©2023 Digital.ai Inc. All rights reserved Page 667


Test Execution

Test Suite Definition


<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Log Suite Example" verbose="1">
<listeners>
<listener class-name="com.experitest.reporter.testng.Listener" />
</listeners>

<test name="TestNG logs sample" preserve-order="true">


<classes>
<class name="com.experitest.testng.AppiumDriver">
<methods>
<include name="methodPass" />
<include name="dividedByZero" />
<include name="methodSkip" />
</methods>
</class>
</classes>
</test>

</suite>

1) First set the class according to the XML

Class Declaration
package com.experitest.testng;
.....
public class AppiumDriver {
.....

2) Then make sure you have one of the following class property, the name of the property is not important

Class Property
...
protected Client client;
protected GridClient grid = null;
private String accessKey = "eyJ4c.......";
final String HOST_NAME = "seetest.appium.pc";
private String host = "http://" + HOST_NAME + ":8080/wd/hub";
...

3) Initialize the driver as you would usually do

Setup Driver
@BeforeMethod
public void setup(){
System.out.println(">>>>>> I'm in Setup");
String name = testInfo.getTestMethod().get().getName();
Logger.setLevel(Level.DEBUG);

©2023 Digital.ai Inc. All rights reserved Page 668


Test Execution

String deviceOS = "ios";


grid = new GridClient(accessKey, host);
client = grid.lockDeviceForExecution(name, "@os='" + deviceOS +
"'", 10, 50000);
client.setReporter("xml", "reports", name);
}
@AfterMethod
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
client.generateReport(false);
client.releaseClient();
System.out.println(">>>>>> Reports generated");
}

4) Run a test that generate an exception

Test method
@Test(priority = 0)
public void methodPass() {
System.out.println(">>>>>> I'm in method pass");
}

@Test(priority = 1)
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}

@Test(dependsOnMethods = { "dividedByZero" })
public void methodSkip() {
System.out.println(">>>>>> I'm in method skip");
}

TestNG Support
We provide you with Native integration into the TestNG testing framework.

Getting Started
To integrate TestNG:

1. Add manager-client.jar to your project.


2. Add the @Listeners annotation.
3. Add the Reporter Server URL.

©2023 Digital.ai Inc. All rights reserved Page 669


Test Execution

4. Create a new ManagerPublisher.


5. Use the created instance to report tags and files.
The listener automatically extracts as much data as possible for you.

Capabilities
• Automatically capture the output, trace, and stacktraces and adds them to the test
• Add attachments (PDF, HTML reports) to the test
• Add test tags

Simple Example
import com.experitest.manager.api.ManagerPublisher;
import com.experitest.manager.client.PManager;
import com.experitest.manager.testng.ManagerTestNGListener;
import org.testng.annotations.*;

import java.io.File;
import java.lang.reflect.Method;

@Listeners(ManagerTestNGListener.class)
public class SimpleExampleTestNG {

static {
System.setProperty("manager.url", "localhost:9011");
System.setProperty("manager.url", "<Cloud url>:<reverse proxy port>/re
porter");// in case using Reporter that configure to a single port cloud
System.setProperty("manager.accesskey", "accesskey"); // in cas
e using Reporter that configure to a cloud
}

private ManagerPublisher managerPublisher = null;

@BeforeMethod
public void setup(Method method){

// Init the managerPublisher in the before method section


managerPublisher = PManager.createManagerPublisher(method.getName());
}

@Test
public void simpleTest() {

// Test goes here

©2023 Digital.ai Inc. All rights reserved Page 670


Test Execution

// Add key value tag


managerPublisher.addProperty("team", "automation");
}

@AfterMethod
public void tearDown() {

// Add custom report folder


managerPublisher.addReportFolder(new File("//path//to//file"));
}
}

Plain Java
You can use Java without plugins or frameworks.

Usage
Using plain java testing is not recommended (for scaleability reasons).

This API can be used to create a composition, or simply to create unsupported plugins.

Capabilities
• Create a test
• Add attachments (PDF, HTML reports) to the test
• Add test tags

Simple Example
public class PlainJavaExample {

static {
System.setProperty("manager.url", "localhost:9011");
System.setProperty("manager.url", "<Cloud url>:<reverse proxy port>/re
porter");// in case using Reporter that configure to a single port cloud
System.setProperty("manager.accesskey", "accesskey"); // in cas
e using Reporter that configure to a cloud
}

public static void main(String[] args) {


ManagerPublisher managerPublisher = PManager.createManagerPublisher("te
st name");

©2023 Digital.ai Inc. All rights reserved Page 671


Test Execution

managerPublisher.addProperty("key1", "value1");
managerPublisher.addProperty("test-version", "24");
managerPublisher.addReportFolder(new File("/path/to/file"));

// mark test as finished


managerPublisher.finishTest(true);

// since all network request is async


// call .waitForPublish() to wait for
// all the request to finish
managerPublisher.waitForPublish();
}
}

JUnit 4
We provide you with Native integration into JUnit 4 testing framework.

Getting Started
To integrate JUnit into your test:

1. Add manager-client.jar to your project.


2. Add the @RunWith annotation.
3. Add the Reporter Server URL.
4. Create a new ManagerPublisher.
5. Use the created instance to report tags and files.
The listener automatically extracts as much data as possible for you.

Capabilities
• Automatically capture the output, trace, and stacktraces and adds them to the test
• Add attachments (PDF, HTML reports) to the test
• Add test tags

Simple Example
import com.experitest.manager.api.ManagerPublisher;
import com.experitest.manager.client.PManager;
import com.experitest.manager.junit.ManagerTestRunner;
import org.junit.*;

©2023 Digital.ai Inc. All rights reserved Page 672


Test Execution

import org.junit.rules.TestName;
import org.junit.runner.RunWith;

import java.io.File;

@RunWith(ManagerTestRunner.class)
public class SimpleExampleJUnit {

static {
System.setProperty("manager.url", "localhost:9011");
System.setProperty("manager.url", "<Cloud url>:<reverse proxy p
ort>/reporter");// in case using Reporter that configure to a single port cloud
System.setProperty("manager.accesskey", "accesskey"); // in cas
e using Reporter that configure to a cloud
}

private ManagerPublisher managerPublisher = null;

@Rule
public TestName testName = new TestName();

@Before
public void setup() {

// Init the managerPublisher in the before section


managerPublisher = PManager.createManagerPublisher(testName.getMethodN
ame());
}

@Test
public void simpleTest() {

// Test goes here

// Add key value tag


managerPublisher.addProperty("team", "automation");
}

@After
public void tearDown() {

// Add custom report folder


managerPublisher.addReportFolder(new File("//path//to//file"));
}
}

©2023 Digital.ai Inc. All rights reserved Page 673


Test Execution

Optional Configuration

Key Description Default Possible Values


Value
manager.url The URL of the reporter server empty "localhost:9011",
"myreporter.com"

manager.accesskey Access key to be used for authentication empty "myaccesskey"

manager.user Username to be used for authentication empty "myusername"

manager.password Password to be used for authentication empty "mypassword"

manager.project Project name to be used for authentication empty "myprojectname"

manager.report.skip When set to true, the test listeners (for TestNG and false "true", "false"
JUnit) will upload result for ignored \ skipped tests

manager.exclude.keys Comma separated keys that will not be sent to the server empty "secret.prop1,
secret.prop2,
secret.prop3"

Usage
You can set them directly.

System.setProperty("manager.url", "localhost:9011");
System.setProperty("manager.user", "myusername");
System.setProperty("manager.password", "mypassword");
System.setProperty("manager.exclude.keys", "secret, password");
System.setProperty("manager.report.skip", "true");

You can use a file named "manager.properties" in the current working directory.

manager.properties
manager.url=localhost:9011
manager.user=myusername
manager.password=mypassword
manager.exclude.keys=secret, password
manager.report.skip=true

Rest API
URL Parameters

©2023 Digital.ai Inc. All rights reserved Page 674


Test Execution

Some of the endpoints use URL parameters. Make sure you are familiar with how to use it with POSTMAN.

Use REST APIs Using Postman.

The Reporter provides you with a Rest API that gives you direct access to the test data and statistics. some
of these commands can be done in the reporter web portal.

The user performing the Rest Operation is authorized by the 'Authorization' header of type 'Bearer' by
Access Key.

For more information see How To Execute Rest API.

The following sections provide details in the usage of these APIs.

Concepts
• Keys - Key and value construct a tag. Each test has a subset of available tags with various values that
describe the test specifics. Example: date.
• Projects - Concept derived from the cloud. Each project has it's own resources (users, devices) and
can be used to created a separation of testing efforts.
• Tests - Single test execution instance

Authentication
If the Reporter server is configured to be secured, you need to authenticate all the requests to the server.

We support these authentication methods:

Basic Authentication

Add the authentication headers as follows:

Authentication: Basic < Base64 encoded <username>:<password> >


ReporterProject: <project name>

Access Key

Generate access from Continuous Testing Cloud.

This key identifies the user and its project.

For additional information about generating access keys in Continuous Testing Cloud, see Rest API - Keys.

©2023 Digital.ai Inc. All rights reserved Page 675


Test Execution

Add the token to your request as follows:

Authentication: Bearer <access key>

The examples use the Unirest HTTP library. To compile and run them, use the following Maven dependency:

Maven Dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

Rest API - Support Data


The SeeTest Reporter provides you with a Rest API that gives you direct access to the test data and
statistics. The support data REST API enables you to conduct actions related support data (collect etc)

Concepts
1. Key - Key and value construct a tag. Each test has a subset of available tags with various values that
describe the test specifics. Example: date.
2. Project - Concept derived from the cloud. Each project has it's own resources (users, devices) and can
be used to created separation of testing efforts.
3. Test - Single test execution instance.

Flow

Gets support data (config, logs, and data), flows:

©2023 Digital.ai Inc. All rights reserved Page 676


Test Execution

Flow #1:

The client waits until the file is ready then grabs it.

/options (optional) > /prepare > /file

Flow #2:

The client polls from time to time until the files are ready then grabs it.

/options (optional) > /start > /status (repeat periodically until state <> RUNNING) > /file

Get Support Data Options


Returns what can be included in the support data file, properties are:

config Reporter's configuration files (config/ folder).

logs Reporter's log files(logs/ folder).

database Reporter's database's data, true when pg_dump utility is available.

databaseConfig PG's configuration file, true when:

• PG is running in the same host as Reporter.

• Reporter's database user has permission to query the 'data_directory' setting.

• Reporter's OS user has permissions to access PG's 'data_directory'.

databaseLog PG's log files (latest <=10 MB), same rules as above.

• This API is available for cloudAdmin only.

GET /reporter/api/supportData/options

Response
Response Status: 200 OK[ {
"config": true,
"logs": true,
"database": false,
"databaseConfig": true,
"databaseLog": true
}]

©2023 Digital.ai Inc. All rights reserved Page 677


Test Execution

Set Support Data Options


Prepares the support file replying until is ready.

• This API is available for cloudAdmin only.

POST /reporter/api/supportData/prepare

JSON parameter

Name Type Mandatory Description


config Boolean Yes Reporter's configuration files (config/ folder).

logs Boolean Yes Reporter's log files(logs/ folder).

logs Boolean Yes Reporter's database's data, true when pg_dump utility is available.

databaseConfig Boolean Yes PG's configuration file, true when:

• PG is running in the same host as Reporter.

• Reporter's database user has permission to query the 'data_directory' setting.

• Reporter's OS user has permissions to access PG's 'data_directory'.

databaseLog Boolean Yes PG's log files (latest <=10 MB), same rules as above.

Response
Response Status: 200 OK[ {
"config": true,
"logs": true,
"database": false,
"databaseConfig": true,
"databaseLog": true
}]

Start Support Data


Start the support file preparation in the background, the payload is the same as above.

• This API is available for cloudAdmin only.

POST /reporter/api/supportData/start

JSON parameter

©2023 Digital.ai Inc. All rights reserved Page 678


Test Execution

Name Type Mandatory Description


config Boolean Yes Reporter's configuration files (config/ folder).

logs Boolean Yes Reporter's log files(logs/ folder).

logs Boolean Yes Reporter's database's data, true when pg_dump utility is available.

databaseConfig Boolean Yes PG's configuration file, true when:

• PG is running in the same host as Reporter.

• Reporter's database user has permission to query 'data_directory' setting.

• Reporter's OS user has permissions to access PG's 'data_directory'.

databaseLog Boolean Yes PG's log files (latest <=10 MB), same rules as above.

Support Data Status


• This API is available for cloudAdmin only.

GET /reporter/api/supportData/status

Return the current status of the support file preparation, properties are::

state One of this: IDLE, RUNNING, COMPLETED, CANCELING, CANCELED, ERROR

startedAt Reporter's log files(logs/ folder).

startedBy Username who started the process.

canceledBy Username who canceled the process (status CANCELING or CANCELED)

progress Percentage completed.

finishedAt Timestamp in which the process finished or canceled.

error n case the process ended because of an unexpected error, here is the error message.

Note that "progress" may be slightly more than 100%; this is because at the beginning of the process the
total data size is computed but it increases while the process runs.

Get Support Data


Gets the support data file.

• This API is available for cloudAdmin only.

©2023 Digital.ai Inc. All rights reserved Page 679


Test Execution

GET /reporter/api/supportData/file

Code Example

The examples below using the Unirest HTTP library. To compile and run them, use the following
Maven dependency:

Maven dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

Java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.apache.http.HttpHeaders;
import org.junit.Test;

import java.io.File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class APIConfluence {


private HttpResponse<String> responseString;

private HttpResponse<InputStream> responseInputStream;

private String urlBase = "http://hostname:port/"; //TODO: modify hostnam


e and port of your Reporter
private String user = "user"; //TODO: user name

©2023 Digital.ai Inc. All rights reserved Page 680


Test Execution

private String password = "....."; //TODO: user password


private String accessKey= "....."; //TODO: user access key
String projectName = "projectName";//TODO: project name is here
String projectID = "projectID";//TODO: project ID is here

private String testID = "test ID";//TODO: test ID is here

@Test
public void getSupportDataOptions() {
String url = urlBase + "/api/supportData/options";

try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void prepareSupportData() {
String url = urlBase + "/api/supportData/prepare";

try {
responseString = Unirest.post(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.body("{\n" +
" \"config\" : true,\n" +
" \"logs\" : true,\n" +
" \"database\" : true,\n" +
" \"databaseConfig\" : true,\n" +
" \"databaseLog\" : true\n" +
"}")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void getSupportDataFile() {
String url = urlBase + "/api/supportData/file";

try {

©2023 Digital.ai Inc. All rights reserved Page 681


Test Execution

responseInputStream = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asBinary();

String destination = "destination";//TODO: Path to save the file -


zip file
writeToFile(destination);

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void startSupportData() {
String url = urlBase + "/api/supportData/start";

try {
responseString = Unirest.post(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.body("{\n" +
" \"config\" : true,\n" +
" \"logs\" : true,\n" +
" \"database\" : true,\n" +
" \"databaseConfig\" : true,\n" +
" \"databaseLog\" : true\n" +
"}")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void getSupportDataStatus() {
String url = urlBase + "/api/supportData/status";

try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}

©2023 Digital.ai Inc. All rights reserved Page 682


Test Execution

}
private void writeToFile(String destination) {
InputStream inputStream = responseInputStream.getRawBody();
try {
FileOutputStream fileOutputStream = new FileOutputStream(destinatio
n);

int bytesRead = -1;


byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
}
fileOutputStream.close();

} catch (IOException e) {
e.printStackTrace();
}
}
}

Rest API - Transactions


The SeeTest Reporter provides you with a Rest API that gives you direct access to the test data and
statistics.

For documentation on Transaction View see Transaction View.

Concepts
1. Key - Key and value construct a tag. Each test has a subset of available tags with various values that
describe the test specifics. Example: {device.os : Android}.

2. Project - Concept derived from the cloud. Each project has it's own resources (users, devices) and can
be used to created separation of testing efforts.
3. Test - Single test execution instance.

©2023 Digital.ai Inc. All rights reserved Page 683


Test Execution

The role of the user performing the Rest Operation is specified by the 'Authorization' header.

For more information please visit How To Execute Rest API, for a detailed example.

Get test Transactions


Returns JSON representation of existing Test Transaction with received {id}.

If it does not exist a status 404 is returned.

• This API is available for all user roles.

GET /reporter/api/transactions/{ids}

{id} - id of the transaction.

Response
Response Status: 200 OK{
"id": 744,
"name": "Test Rail",
"appName": "com.apple.springboard",
"appVersion": "",
"startTime": 1584958844127,
"deviceUid": "00008020-00152DA11A68002E",
"deviceName": "iPhone xs b0227",
"deviceModel": "iPhone XS",
"deviceOs": "iOS",
"deviceManufacturer": "Apple",
"deviceVersion": "13.3",
"deviceScreen": "1125 x 2436",
"deviceType": "PHONE",
"networkProfile": "",
"cpuAvg": 211.10688234412152,
"cpuMax": 836.3230590820312,
"memAvg": 553.8927731721298,
"memMax": 622.5054931640625,
"batteryAvg": 374.1950969080771,
"batteryMax": 490.32733154296875,
"totalUploadedBytes": 0,
"totalDownloadedBytes": 0,
"duration": 31283,
"speedIndex": -1,
"videoStart": 1584958844127,
"videoEnd": 1584958875410,
"userName": "admin",
"testId": 639,
"date": "2020-03-23",
"projectId": 1,
"projectName": "Default",

©2023 Digital.ai Inc. All rights reserved Page 684


Test Execution

Response
"attachmentList": []
}

Delete test Transactions


Delete the test transactions identified by the received IDs. One or more ids can be provided, separated by a
comma.

Example: /api/transactions/3,4,23

• This API is available for cloudAdmin and projectAdmin only.

DELETE /reporter/api/transactions/{ids}

{id} - id of the transaction.

Comparison of transaction's measuresfilter

It generates a comparison of average transaction measures between the latest base key-value and older key
values.

POST /reporter/api/transactions/compare?token=<accessKey>

Json parameter

Name Type Mandatory Description

Response
Response Status: 200 OK{
"id": 56,
"name": "newTestViewsGroup",
"byKey": "date",
"byKeyDesc": true,
"groupByKey1": "device.os",
"groupByKey2": "device.version",
"filter": [],
"keys": [
"date",
"app"

©2023 Digital.ai Inc. All rights reserved Page 685


Test Execution

Response
],
"createdBy": "admin"
}

See Performance Pipeline for more details

Download HAR file

• This API is available for all user roles.

Downloads the HAR file attached to the transaction id received as the path parameter.

GET /reporter/api/transactions/{id}/har

Parameters

Name Type Mandatory Description


token String Yes Access Key

See Performance Pipeline for more details

Download Video file

• This API is available for all user roles.

Downloads the video file attached to the transaction id received as the path parameter.

GET /reporter/api/transactions/{id}/video

Parameters

Name Type Mandatory Description


token String Yes Access Key

©2023 Digital.ai Inc. All rights reserved Page 686


Test Execution

Code Example

The examples below using the Unirest HTTP library. To compile and run them, use the following
Maven dependency:

Maven dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

Java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import org.junit.Test;

import java.io.InputStream;

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import org.junit.Assert;
import org.junit.Test;

import java.io.*;
import java.util.List;

public class APIConfluenceTransactions {


private HttpResponse<String> responseString;
private HttpResponse<InputStream> responseInputStream;

private String urlBase = "<Reporter URL>"; //TODO: modify hostname and p


ort of your Reporter

private String user = "<User>"; //TODO: user name


private String password = "<Password>"; //TODO: user password
@Test
public void deleteMultipleTransactions() {

©2023 Digital.ai Inc. All rights reserved Page 687


Test Execution

int from = 1;
int to = 1000;
int step = 100;

for (int start = from; start< to; start=start+ step){


System.out.println(start);
StringBuffer toDelete =new StringBuffer(start+"");
for(int i = start+1; i<start+ step; i++){
toDelete.append(","+i);
}
deleteTranactions(toDelete.toString());
}

private void deleteTranactions(String toDelete) {


String url = urlBase + "/api/testtx/"+toDelete;

try {
responseString = Unirest.delete(url)
.basicAuth(user, password)
.queryString("projectName","default")
.header("content-type", "application/json")
.asString();

System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
}
}

public void testDownloadHar() throws Exception {


String url= urlBase + "/api/transactions/%d/har";
long transId = <transaction id>;
String token = <...accesToken...>

url = String.format(url, transId);


HttpResponse<InputStream> response = Unirest.get(url)
.queryString("token", token)
.asBinary();
int status = response.getStatus();
Assert.assertEquals(200, status);
if (status == 200) {
List<String> disposition = response.getHeaders().get("Content-Disp
osition");
String fileName = "harfile";
if (disposition != null && !disposition.isEmpty()) {

©2023 Digital.ai Inc. All rights reserved Page 688


Test Execution

fileName = disposition.get(0).split("=")[1];
}
fileName = "/tmp/" + fileName;
saveToFile(response.getBody(), fileName);
Assert.assertTrue(new File(fileName).exists());
}
}

public void testDownloadVideo() throws Exception {


String url= urlBase + "/api/transactions/%d/video";
long transId = <transaction id>;
String token = <...accesToken...>

url = String.format(url, transId);


HttpResponse<InputStream> response = Unirest.get(url)
.queryString("token", token)
.asBinary();
int status = response.getStatus();
Assert.assertEquals(200, status);
if (status == 200) {
List<String> disposition = response.getHeaders().get("Content-Disp
osition");
String fileName = "videofile.mp4";
if (disposition != null && !disposition.isEmpty()) {
fileName = disposition.get(0).split("=")[1];
}
fileName = "/tmp/" + fileName;
saveToFile(response.getBody(), fileName);
Assert.assertTrue(new File(fileName).exists());
}
}

static void saveToFile(InputStream in, String fileName) throws IOException


{
try (OutputStream out = new FileOutputStream(fileName)) {
byte[] buffer = new byte[1024];
int readCount;
while ((readCount = in.read(buffer)) != -1) {
out.write(buffer, 0, readCount);
}
}
}
}

©2023 Digital.ai Inc. All rights reserved Page 689


Test Execution

Rest API - TestView


The SeeTest Reporter provides you with a Rest API that gives you direct access to the test data and
statistics.

For documentation on Test View see Test View.

Concepts
1. Key - Key and value construct a tag. Each test has a subset of available tags with various values that
describe the test specifics. Example: {device.os: Android}.

2. Project - Concept derived from the cloud. Each project has it's own resources (users, devices) and can
be used to created separation of testing efforts.
3. Test - Single test execution instance.

The role of the user performing the Rest Operation is specified by the 'Authorization' header.

For more information please visit How To Execute Rest API, for a detailed example.

Get test views groups


List all test views of the currently selected project.

Test View's returned properties:

1. id : Id of the test view group.


2. name : Name of the test view group.
3. byKey : Key name selected in "View by" panel.
4. createdBy : User who created the test view group.
5. showInDashboard : Is the "add to dashboard" button enabled.

• This API is available for all user roles.

GET /reporter/api/testView

©2023 Digital.ai Inc. All rights reserved Page 690


Test Execution

Response
Response Status: 200 OK[
{
"name": "Android OS",
"id": 54,
"createdBy": "admin",
"byKey": "date"
},
{
"name": "Default",
"id": 50,
"byKey": "date",
"showInDashboard": true
},
...
]

Create test views group


Creates full test view.

• This API is available for all user roles

POST /reporter/api/testView

JSON parameter

Name Type Mandatory Description


name String Yes Name of the newly created test view group

byKey String Yes The key name selected in the "View by" panel.

groupByKey1 String Yes The key name selected in "Group by" left panel

groupByKey2 String Yes The key name selected in "Group by" right panel

keys List No keys to be included in the newly created test views group

showInDashboard Boolean No Show the test views group in the dashboard ( default value is false)

Response
Response Status: 200 OK{
"id": 56,
"name": "newTestViewsGroup",
"byKey": "date",
"byKeyDesc": true,
"groupByKey1": "device.os",
"groupByKey2": "device.version",
"filter": [],
"keys": [

©2023 Digital.ai Inc. All rights reserved Page 691


Test Execution

Response
"date",
"app"
],
"createdBy": "admin"
}

Update test views group


Updates selected properties of the test view. The expected body for this service is:

• This API is available for all user roles with permission to access the desired project.

PUT /reporter/api/testView

JSON parameter

Name Type Mandatory Description


id Number Yes Id of the test view group

name String No The new name of the test view group

showInDashboard Boolean No Show the test views group in the dashboard ( default value is false)

Response
Response Status: 200 OK{
"id": 56,
"name": "newTestViewsGroup",
"byKey": "date",
"byKeyDesc": true,
"groupByKey1": "device.os",
"groupByKey2": "device.version",
"filter": [],
"keys": [
"date",
"app"
],
"createdBy": "admin"
}

Get filtered test views


Show list of test views of the currently selected project based on given properties.

Test View's returned properties:

©2023 Digital.ai Inc. All rights reserved Page 692


Test Execution

• count: Number shows the total count of records.


• data: List holds data of each test views as JSON contains the following properties:
◦ id: Id of the test view group.
◦ name: Name of the test view group.
◦ byKey : Key name selected in "View by" panel.
◦ createdBy: User who created the test view group.
◦ showInDashboard: Is the "add to dashboard" button enabled.

• This API is available for all user roles with permission to access the desired project.

POST /reporter/api/testView/list

JSON parameter

Name Type Mandatory Description


limit Number Yes limit length or returned data

page Number Yes Starting at 1

Sort List No Sort by given properties.format : [ { "property": "fieldName", "descending": false }, ... ]

searchValue String No Return test views which name contains this value, case insensitive

Response
Response Status: 200 OK{
"count": 2,
"data": [
{
"name": "Android OS",
"id": 54,
"createdBy": "admin",
"byKey": "date"
}
]
}

Get test view


Retrieves the test view by its {id}.

Returns the full test view entities.

• This API is available for all user roles with permission to access the desired project.

©2023 Digital.ai Inc. All rights reserved Page 693


Test Execution

GET /reporter/api/testView/{id}

{id} - id of the test view group.

Response
Response Status: 200 OK{
"id": 54,
"name": "Android OS",
"byKey": "date",
"byKeyDesc": true,
"groupByKey1": "device.os",
"groupByKey2": "device.version",
"filter": [
{
"id": 50,
"testViewId": 54,
"operator": "=",
"value": "Android",
"isByKey": false,
"isStatus": false,
"persisted": true,
"property": "device.os"
}
],
"keys": [
"date",
"device.os",
"device.version"
],
"createdBy": "admin"
}

Get tests counts


Retrieves tests counts of the test view given by it's {id}.

• This API is available for all user roles with permission to access the desired project.

GET /reporter/api/testView/{id}/summary

{id} - id of the test view group.

Parameters

Name Type Mandatory Description


filter JSON No Filter by test view's name. value example : {"device.os":"Android"}

©2023 Digital.ai Inc. All rights reserved Page 694


Test Execution

Response
Response Status: 200 OK{
"data": [
{
"passedCount": 2,
"failedCount": 0,
"incompleteCount": 0,
"skippedCount": 0,
"_count_": 2
}
]

Delete test view


Deletes the test view identified by it's {id}.

• This API is available for all user roles with permission to access the desired project.

DELETE /reporter/api/testView/{id}

{id} - id of the test view group.

Code Example

The examples below using the Unirest HTTP library. To compile and run them, use the following
Maven dependency:

Maven dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

Java
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

©2023 Digital.ai Inc. All rights reserved Page 695


Test Execution

import com.mashape.unirest.http.Unirest;
import static org.junit.Assert.fail;
import com.mashape.unirest.http.HttpResponse;

import java.io.InputStream;

public class REST_API_testView {

private HttpResponse<String> responseString;

private String urlBase = "HOSTNAME"; //TODO: modify hostname and port of


your Reporter
private String user = "<USERNAME>"; //TODO: user name
private String password = "<PASSWORD>"; //TODO: user password
private String accessKey= "<ACCESS_KEY>"; //TODO: user access key
String projectName = "<Project Name>";//TODO: project name is here
String projectID = "projectID";//TODO: project ID is here

private String testID = "test ID";//TODO: test ID is here


//************************************************************************
****************************************//

@Test
public void get_testView() {
String url = urlBase + "/api/testView";

try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}

//************************************************************************
****************************************//

@Test
public void create_testView() {
String url = urlBase + "/api/testView";
try {
responseString = Unirest.post(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.body("{\n" +

©2023 Digital.ai Inc. All rights reserved Page 696


Test Execution

" \"name\": \"newTestView\",\n" +


" \"byKey\":\"date\",\n" +
" \"groupByKey1\": \"device.os\",\n" +
" \"groupByKey2\": \"device.os\",\n" +
" \"showInDashboard\": true,\n" +
" \"viewBy\": \"data\"\n" +
"\n" +
"}")
.asString();
System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
fail("Failed in REST API");
}
}

//************************************************************************
****************************************//

@Test
public void update_testView() {
String url = urlBase + "/api/testView";
try {
responseString = Unirest.put(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.body("{\n" +
" \"id\":1051,\n" +
" \"name\":\"newTestViewName\",\n" +
" \"showInDashboard\": true\n" +
"}")
.asString();
System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
fail("Failed in REST API");
}
}

//************************************************************************
****************************************//

@Test
public void filter_testView() {
String url = urlBase + "/api/testView/list";
try {
responseString = Unirest.post(url)

©2023 Digital.ai Inc. All rights reserved Page 697


Test Execution

.basicAuth(user, password)
.header("content-type", "application/json")
.body("{\n" +
" \"limit\":2,\n" +
" \"page\": 1,\n" +
" \"searchValue\":\"def\"\n" +
"}")
.asString();
System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
fail("Failed in REST API");
}
}

//************************************************************************
****************************************//

@Test
public void get_testView_by_id() {
String url = urlBase + "/api/testView/"+1051;
try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}

//************************************************************************
****************************************//

@Test
public void get_testView_count() {
String url = urlBase + String.format("/api/testView/%d/summary",1051);
try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.queryString("filter","{\"device.os\":\"Android\"}")
.asString();
System.out.println(responseString.getBody());
System.out.println("done");
} catch (Exception e) {
e.printStackTrace();

©2023 Digital.ai Inc. All rights reserved Page 698


Test Execution

}
}

//************************************************************************
****************************************//

@Test
public void delete_testView_count() {
String url = urlBase + String.format("/api/testView/%d",1151);
try {
responseString = Unirest.delete(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}
}

Rest API - Projects


The Reporter provides you with a Rest API that gives you direct access to the test data and statistics.

Definition
• Project - Concept derived from the cloud. Each project has it's own resources (users, devices) and can
be used to created separation of testing efforts.

The role of the user performing the Rest Operation is specified by the 'Authorization' header.

For more information see How To Execute Rest API.

©2023 Digital.ai Inc. All rights reserved Page 699


Test Execution

API Calls
Get All Projects

List all projects.

• This API is available for all user roles.

GET /reporter/api/projects

Response
Response Status: 200 OK[ {
"id": 1,
"name": "Default",
"created": 1578229200152,
"attachmentsCurrentTotalSize": 0,
"attachmentsMaxAllowedSize": 1000,
"usagePct": 0.0,
"allowNewKeysFromCode": true,
"allowUsersDeteleTests": false,
"showInAdminDashboard": false
},
{
"id": 20,
"name": "someOldProject",
"created": 1578229209981,
"attachmentsCurrentTotalSize": 0,
"attachmentsMaxAllowedSize": 1000,
"usagePct": 0.0,
"allowNewKeysFromCode": true,
"allowUsersDeteleTests": false,
"showInAdminDashboard": false
}
...
]

Change Project Name

Change the project name.

• This API is available for Cloud Administrators only.

PUT /reporter/api/projects/{oldName}/{newName}

Download Test's Attachments by Project ID

Download all the attachments of a given test under a specific project as a zip file.

©2023 Digital.ai Inc. All rights reserved Page 700


Test Execution

Note that projectId is the Reporter's project ID, not the Cloud's.

The filename of the exported attachments is test_id_{testId}_attachments.zip

• This API is available for all user roles.

GET /reporter/api/{projectId}/{testId}/attachments

{projectId} - ID of the reporter's project.

{testId} - ID of the test.

Download Test's Attachments by Project Name

Download all the attachments of a given test under a specific project as a zip file.

The filename of the exported attachments is test_id_<testid>_attachments.zip

• This API is available for all user roles.

GET /reporter/api/{projectName}/{testId}/attachments-name

{projectName} - name of the project.

{testId} - id of the test.

Code Example
The examples below use the Unirest HTTP library. To compile and run them, use the following Maven
dependency:

Maven dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

©2023 Digital.ai Inc. All rights reserved Page 701


Test Execution

Java Code Example


import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.apache.http.HttpHeaders;
import org.junit.Test;

import java.io.File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class APIConfluence {


private HttpResponse<String> responseString;

private HttpResponse<InputStream> responseInputStream;

private String urlBase = "http://hostname:port/"; //TODO: modify hostnam


e and port of your Reporter
private String user = "user"; //TODO: user name
private String password = "....."; //TODO: user password
private String accessKey= "....."; //TODO: user access key
String projectName = "projectName";//TODO: project name is here
String projectID = "projectID";//TODO: project ID is here

private String testID = "test ID";//TODO: test ID is here

@Test
public void getAllProjects() {
String url = urlBase + "/api/projects";

try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();

System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
}
}

©2023 Digital.ai Inc. All rights reserved Page 702


Test Execution

@Test
public void changeProjectName() {
String oldName = "oldName";//TODO project old name
String newName = "newName";//TODO project new name
String url = urlBase + "/api/projects/" + oldName + "/" + newName + "/
";
try {
responseString= Unirest.put(url)
.basicAuth(user, password)
.header("Content-Type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (UnirestException e) {
e.printStackTrace();
}
}

@Test
public void getAttachmentsByProjectID() {

try {
String url = urlBase + "/api/" + projectID + "/" + testID + "/atta
chments";

responseInputStream = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asBinary();

String destination = "destination";//TODO: Path to save the file -


zip file
writeToFile(destination);

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void getAttachmentsByProjectName() {
String url = urlBase + "/api/" + projectName + "/" + testID + "/attach
ments-name";

try {
responseInputStream = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")

©2023 Digital.ai Inc. All rights reserved Page 703


Test Execution

.asBinary();

String destination = "destination";//TODO: Path to save the file -


zip file
writeToFile(destination);

} catch (Exception e) {
e.printStackTrace();
}
}

private void writeToFile(String destination) {


InputStream inputStream = responseInputStream.getRawBody();
try {
FileOutputStream fileOutputStream = new FileOutputStream(destinatio
n);

int bytesRead = -1;


byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
}
fileOutputStream.close();

} catch (IOException e) {
e.printStackTrace();
}
}
}

Rest API - Tests


Using URL Parameters

Some of the endpoints use URL parameters. Make sure you are familiar with how to use it with Postman.

Use REST APIs Using Postman

©2023 Digital.ai Inc. All rights reserved Page 704


Test Execution

The SeeTest Reporter provides you with a Rest API that gives you direct access to the test data and
statistics.

Concepts
1. Key - Key and value construct a tag. Each test has a subset of available tags with various values that
describe the test specifics. Example: date.
2. Project - Concept derived from the cloud. Each project has its own resources (users, devices) and can
be used to create a separation of testing efforts.
3. Test - Single test execution instance.

Get Test By ID
Test with a specified id of the currently selected project.

• This API is available for all user roles.

GET /reporter/api/tests/{id}

Response
Response Status: 200 OK[ {
"id": 2795,
"name": "quickStartFirefoxTest",
"startTime": 1578562056457,
"duration": 145440,
"status": "Failed",
"success": false,
"keyValuePairs": {
"date": "2020-01-09",
"test.type": "Web",
"maxScreenshotInterval": "0.0",
"cause": "no such element: Unable to locate element: {\"method\":\"xpath\",\"selector\":\"//button[@name='login']\"}",
"newSessionWaitTimeout": "60.0",
"acceptSslCerts": "true",
"goog:loggingPrefs": "{performance=ALL}",
"goog:chromeOptions": "{args=[disable-extensions, start-fullscreen, disable-web-security, disable-features=NetworkService, --window-
size=1920,1080], prefs={download.directory_upgrade=true, safebrowsing_for_trusted_sources_enabled=false, profile.default_content_settings.popups=
"newCommandTimeout": "1200.0",
"browserVersion": "78.0.3904.108",
"browserName": "chrome",
"os.name": "Windows 10",
"javascriptEnabled": "true",
"platformName": "WIN10",
"test.framework": "Selenium",
"user": "assafm",
"testName": "quickStartFirefoxTest"
},
"testAttachments": [
{
"id": 12765,

©2023 Digital.ai Inc. All rights reserved Page 705


Test Execution

Response
"filePath": "/attachments/1/2020-01-09/2795/testreportfadfdf1b69bf185a825a5aeb556d1d7876785376898260938183611384077293385164/
index.html",
"captionName": "",
"type": "zip",
"size": 4311336
}
],
"hasReport": true
}]

Get Test By ProjectName - ID


Test with a specified id of the specified selected project.

• This API is available for all user roles with permission to access the desired project.

GET /reporter/api/tests/{id}/project/{projectName}

Response
Same As Above

Get Test By Manual Report Identifier (report_api_id)


Test with a specified Report API Id.

• This API is available for all user roles.

• Note: By default includeSteps parameter is false, and the test steps are not returned from the API
call, user should add includeSteps=true to the REST API call in order to get the steps as well.

Note: The report_api_id is the "report_api_id" output parameter (A.K.A test plan id) that the client got
from the start web-control API call.

GET /reporter/api/tests?report_api_id={report_api_id}&includeSteps=true

Response

©2023 Digital.ai Inc. All rights reserved Page 706


Test Execution

Response Status: 200 OK

{
"id": 31400,
"name": "Manual Report",
"startTime": "2021-06-27T14:06:03.241+0000",
"duration": 31642,
"status": "Passed",
"success": true,
"keyValuePairs": {
"date": "2021-06-27",
"device.majorVersion": "14",
"device.os": "iOS",
"report_api_id": "649d19f5-ce99-4ec2-9798-032c03deff9b",
"device.serialNumber": "5f1ab522dd414f0c97a8a5d724d60d0c1db10e8
3",
"device.version": "14.2",
"device.model": "iPhone 8",
"device.name": "B0231",
"device.manufacture": "Apple",
"user": "user",
"device.screenSize": "750x1334"
},
"testAttachments": [
{
"id": 184613,
"filePath": "/attachments/1/2021-06-27/31400/video632777
93877005350553446619010767961978.mp4",
"filenameToOpen": null,
"originalFileName": null,
"captionName": null,
"type": "data_item",
"size": 847132
},
{
"id": 184615,
"filePath": "/attachments/1/2021-06-27/31400/executionPl
anDeviceLog-27_06_2021_17_06_03-5f1ab522dd414f0c97a8a5d724d60d0c1db10e83-71983
952068706984654385528224304717977.log",
"filenameToOpen": null,
"originalFileName": null,
"captionName": "",
"type": "log",
"size": 1045829
}
],
"count": null,
"minMergedSuccess": null,
"failedCount": null,

©2023 Digital.ai Inc. All rights reserved Page 707


Test Execution

"hasReport": true,
"steps": [
{
"name": "Step 1",
"id": 1,
"startTime": 1624802764674,
"duration": 3864,
"description": "Step 1 description",
"expectedResult": "what should happen in step 1",
"actualResult": null,
"status": "PASSED",
"subSteps": [
{
"name": "Swipe from 1306,1876 to 452,18
80",
"id": 2,
"startTime": 1624802764674,
"duration": 322
},
{
"name": "Swipe from 122,1642 to 856,161
4",
"id": 3,
"startTime": 1624802766735,
"duration": 261
},
{
"name": "Swipe from 1360,1834 to 296,17
60",
"id": 4,
"startTime": 1624802768271,
"duration": 267
}
]
},
{
"name": "Step 2",
"id": 5,
"startTime": 1624802773337,
"duration": 6935,
"description": "step 2 description",
"expectedResult": "What should happen in step 2",
"actualResult": null,
"status": "PASSED",
"subSteps": [
{
"name": "Click 150,2500",
"id": 6,
"startTime": 1624802773337,

©2023 Digital.ai Inc. All rights reserved Page 708


Test Execution

"duration": 82
},
{
"name": "Click 726,1810",
"id": 7,
"startTime": 1624802775190,
"duration": 85
},
{
"name": "Click 714,1446",
"id": 8,
"startTime": 1624802775743,
"duration": 84
},
{
"name": "Click 772,1142",
"id": 9,
"startTime": 1624802776241,
"duration": 82
},
{
"name": "Click 784,710",
"id": 10,
"startTime": 1624802776719,
"duration": 100
},
{
"name": "{home}",
"id": 11,
"startTime": 1624802780272,
"duration": 0
}
]
},
{
"name": "Step 3",
"id": 12,
"startTime": 1624802785208,
"duration": 7213,
"description": "Step 3 description",
"expectedResult": "What should happen in step 3",
"actualResult": "Actual",
"status": "PASSED",
"subSteps": [
{
"name": "Swipe from 314,1218 to 1256,11
56",
"id": 13,
"startTime": 1624802785208,

©2023 Digital.ai Inc. All rights reserved Page 709


Test Execution

"duration": 164
},
{
"name": "Click 984,1622",
"id": 14,
"startTime": 1624802787559,
"duration": 100
},
{
"name": "Swipe from 950,2202 to 868,133
4",
"id": 15,
"startTime": 1624802789417,
"duration": 220
},
{
"name": "Swipe from 910,1064 to 952,225
0",
"id": 16,
"startTime": 1624802791211,
"duration": 235
},
{
"name": "{home}",
"id": 17,
"startTime": 1624802792421,
"duration": 0
}
]
}
]
}

Get Tests List


List the tests of the currently selected project given TestsRequest (filter, sort, limit, offset, keys to include)
object sent.

• This API is available for all user roles with permission to access the desired project.

POST /reporter/api/tests/list

POST /reporter/api/tests/list?projectId={projectId}

©2023 Digital.ai Inc. All rights reserved Page 710


Test Execution

POST /reporter/api/tests/list?projectName={projectName}

{projectName} - Name of the Project

{projectId} - Project ID

JSON parameter

Name Type Mandatory Description


returnTotalCount Boolean No return total record count, default false

limit Number No limit length or returned data

page Number No Starting at 1

searchValue String No Return test views which name contains this value,case insensitive

Sort List No Sort by given properties.format :[ { "property": "fieldName", "descending":


false }, ... ]

filter List No Filter by given properties.format :[ { "property":"fieldName or key", "operator": "=",


"value": "string value"}, ... ]

keys List No keys to be included in the response else only test's fixed columns returned
format :
"keys": [ "key1", "key2", ...]

Response
Response Status: 200 OK[{
"count": 2795,
"data": [
{
"test_id": 3,
"name": "Quick Start iOS Native Demo",
"start_time": 1571202942000,
"duration": 13057,
"status": "Incomplete",
"status_code": 2,
"success": false,
"attachments_size": 0,
"attachment_count": 0,
"has_attachment": "N",
"date": "2019-10-16"
},
{
"test_id": 149,
"name": "adb restriction test",
"start_time": 1571719774473,
"duration": null,
"status": "Incomplete",
"status_code": 2,
"success": false,
"attachments_size": null,
"attachment_count": 0,
"has_attachment": "N",

©2023 Digital.ai Inc. All rights reserved Page 711


Test Execution

Response
"date": "2019-10-22"
},
...
]

Get Tests Grouped


Returns groupedcounts from tests givenTestsRequest(filter, sort, keys to group by, pivot by for counts: such
success and/or status_code) object sent.

• This API is available for all user roles with permission to access the desired project.

POST /reporter/api/tests/grouped

POST /reporter/api/tests/grouped?projectId={projectId}

POST /reporter/api/tests/grouped?projectName={projectName}

{projectName} - Name of the Project

{projectId} - Project ID

JSON parameter

Name Type Mandatory Description


returnTotalCount Boolean No return total record count, default false

pivotBy List No string array which can contain "success" and/or "status".:

"success" adds two columns to each result"successCount" and


"unsuccessCount".
"status" adds tree columns: "passedCount", "failedCount", "incompleteCount".

keys List No property are the keys used to "group by".

• All resulting rows include the column "count" along "pivotBy" columns if any.

©2023 Digital.ai Inc. All rights reserved Page 712


Test Execution

Response
Response Status: 200 OK[ {
"count": 1,
"data": [
{
"_count_": 2795
}
]
}]

Get a Distinct Key Value


Returns distinct key values from tests given TestsRequest(filter, sort) object sent.

JSON parameter

Name Type Mandatory Description


keys List Yes Return key values based on this list

• This API is available for cloudAdmin and projectAdmin with permission to access the desired project.

POST /reporter/api/tests/distinct

POST /reporter/api/tests/distinct?projectId={projectId}

POST /reporter/api/tests/distinct?projectName={projectName}

{projectName} - Name of the Project

{projectId} - Project ID

JSON parameter: Same As Above

©2023 Digital.ai Inc. All rights reserved Page 713


Test Execution

Response

Response Status: 200 OK[{


"data": [
{
"date": "1911-7-3",
"device.os": null,
"device.version": null,
"key008": "",
"test_id": 1390
},
{
"date": "1911-7-3",
"device.os": null,
"device.version": null,
"key008": "",
"test_id": 1395
},
{
"date": "1911-7-3",
"device.os": null,
"device.version": null,
"key008": "",
"test_id": 1396
},
{
"date": "1911-7-3",
"device.os": null,
"device.version": null,
"key008": "",
"test_id": 1398
}, . . .]

GET CSV File


Get tests in CSV format given TestsRequest (filter, sort, limit, offset, keys to include).

• This API is available for all user roles.

GET /reporter/api/tests/csv?request={TestRequest}

GET /reporter/api/tests/csv?request={TestRequest} &projectId={projectId}

GET /reporter/api/tests/csv?request={TestRequest} &projectName={projectName}

©2023 Digital.ai Inc. All rights reserved Page 714


Test Execution

{projectName} - Name of the Project

{projectId} - Project ID

Json parameter : Same As Above

Example Body:

Request
{
"returnTotalCount": true,
"limit": 10,
"page": 1,
"sort": [],
"keys": [
"date",
"device.os",
"device.version"
],
"filter": [
{
"property": "date",
"operator": "=",
"value": "2020-01-05"
}
]
}

Delete Test
As the name suggests, deletes the desired tests, payload is an array of ID of the tests to be deleted, for
example: [ 5, 67, 100 ]

• This API is available for all user roles with permission to access the desired project.

POST /reporter/api/tests/delete

POST /reporter/api/tests/delete?projectId={projectId}

POST /reporter/api/tests/delete?projectName={projectName}

{projectName} - Name of the Project

©2023 Digital.ai Inc. All rights reserved Page 715


Test Execution

{projectId} - Project ID

Body parameter

Type Mandatory Description


List Yes An array of the ID of the tests to be deleted, for example:[ 5, 67, 100 ]

Download Attachments
Download all the attachments of testId as a zip file.

The filename of the exported attachments is test_id_{testId}_attachments.zip

• This API is available for all user roles with permission to access the desired project.

GET /reporter/api/{testId}/attachments

{testId} - Id of the required test.

Code Example

The examples below using the Unirest HTTP library. To compile and run them, use the following
Maven dependency:

Maven dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

Java

©2023 Digital.ai Inc. All rights reserved Page 716


Test Execution

import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.apache.http.HttpHeaders;
import org.junit.Test;

import java.io.File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class APIConfluenceTests {


private HttpResponse<String> responseString;

private HttpResponse<InputStream> responseInputStream;

private String urlBase = "http://hostname:port/"; //TODO: modify hostnam


e and port of your Reporter
private String user = "user"; //TODO: user name
private String password = "....."; //TODO: user password
private String accessKey= "....."; //TODO: user access key
String projectName = "projectName";//TODO: project name is here
String projectID = "projectID";//TODO: project ID is here

private String testID = "test ID";//TODO: test ID is here

@Test
public void getSpecifiedTest() {
String url = urlBase + "/api/tests/" + testID;
try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
}
}

@Test

©2023 Digital.ai Inc. All rights reserved Page 717


Test Execution

public void getTestsByProjectName() {

String url = urlBase + "/api/tests/" + testID + "/project/" + projectN


ame + "/";

try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();

System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void TestsList() {
String url = urlBase + "/api/tests/list";
HttpResponse<JsonNode> response = null;
try {
response = Unirest.post(url)
.basicAuth(user, password)
.header("Content-Type", "application/json")
.body("{\"returnTotalCount\":true, \"limit\":10, \"page\":
1, \"sort\":[{\"property\":\"test_id\",\"descending\":false}],\r\n" +
" \"keys\":[\"date\",\"device.os\",\"device.vers
ion\"],\r\n" +
" \"filter\":[{\"property\":\"device.os\",\"opera
tor\":\"=\",\"value\":\"iOS\"}]}")//TODO: insert key and value
.asJson();
} catch (UnirestException e) {
e.printStackTrace();
}
if (Objects.nonNull(response)) {
System.out.println(response.getBody());
}
}

@Test
public void getGroupedCounts() {
String url = urlBase + "/api/tests/grouped";

try {

©2023 Digital.ai Inc. All rights reserved Page 718


Test Execution

String body = "{\"returnTotalCount\":true, \"limit\":10, \"page\":


1,\r\n" +
" \"keys\":[\"date\",\"device.os\",\"device.version\"],\
r\n" +
" \"filter\":[{\"property\":\"date\",\"operator\":\"=\",\
"value\":\"2020-01-05\"}]}";
responseString = Unirest.post(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.body(body)//TODO: insert key and value
.asString();
System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void getDistinctKey() {
String url = urlBase + "api/tests/distinct";

try {
String body = "{\"returnTotalCount\":true, \"limit\":10, \"page\":
1," +
" \"sort\":[{\"property\":\"test_id\",\"descending\":false
}],\r\n" +
" \"keys\":[\"date\",\"device.os\",\"device.version\",\"
test_id\"],\r\n" +
" \"filter\":[{\"property\":\"date\",\"operator\":\"=\","
+ "\"value\":\"2020-01-05\"}]" +
"}";
responseString = Unirest.post(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.body(body)//TODO: insert key and value
.asString();

System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void getCSV() {
String url = urlBase + "/api/tests/csv";
try {

©2023 Digital.ai Inc. All rights reserved Page 719


Test Execution

String request="{\"returnTotalCount\":true, \"limit\":10, \"page\"


:1," +
" \"sort\":[],\r\n" +
" \"keys\":[\"date\",\"device.os\",\"device.version\"],\r\
n" +
" \"filter\":[{\"property\":\"date\",\"operator\":\"=\"," +
"\"value\":\"2020-01-05\"}]" +
"}";
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.queryString("request",request)
.queryString("projectId","1")
.queryString("projectName","Default")
.asString();
System.out.println(responseString.getBody());

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void deleteTests() {
String url = urlBase + "api/tests/delete";

try {
responseString = Unirest.post(url)
.basicAuth(user, password)
.queryString("projectId","1")
.header("content-type", "application/json")
.body("[<testID1>,<testID2>,...]") //TODO: insert test id
list to be deleted
.asString();

} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void getAttachmentsByTestID() {
String url = urlBase + "/api/" + testID + "/attachments";

try {
responseInputStream = Unirest.get(url)
.basicAuth(user, password)

©2023 Digital.ai Inc. All rights reserved Page 720


Test Execution

.header("content-type", "application/json")
.asBinary();

String destination = "destination";//TODO: Path to save the file -


zip file
writeToFile(destination);

} catch (Exception e) {
e.printStackTrace();
}
}
private void writeToFile(String destination) {
InputStream inputStream = responseInputStream.getRawBody();
try {
FileOutputStream fileOutputStream = new FileOutputStream(destinatio
n);

int bytesRead = -1;


byte[] buffer = new byte[4096];
while ((bytesRead = inputStream.read(buffer)) != -1) {
fileOutputStream.write(buffer, 0, bytesRead);
}
fileOutputStream.close();

} catch (IOException e) {
e.printStackTrace();
}
}

Rest API - Download Test Video


The Reporter provides you with a Rest API that gives you direct access to the test data and statistics.

Download Test Video


You can download the Video report video as an mp4 file using these methods (Provided there is a video to
download).

• This API is available for all user roles with permission to access the desired project.

©2023 Digital.ai Inc. All rights reserved Page 721


Test Execution

GET /reporter/api/tests/{id}/video

Code Example
The examples below using the Unirest HTTP library. To compile and run them, use the following Maven
dependency:

Maven dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>
Java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.apache.http.HttpHeaders;
import org.junit.Test;

import java.io.File;

import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class APIConfluenceDownloadVideo {


private HttpResponse<String> responseString;

private HttpResponse<InputStream> responseInputStream;

private String urlBase = "http://hostname:port/"; //TODO: modify hostnam


e and port of your Reporter
private String accessKey= "....."; //TODO: user access key
private String testID = "test ID";//TODO: test ID is here

©2023 Digital.ai Inc. All rights reserved Page 722


Test Execution

@Test
public void testFullDownloadWithExistingTestByParts() throws UnirestExcept
ion, IOException {
String downloadDestination = "<File path including file name on your fil
e system. e.g. /temp/newFile.mp4>"; //TODO: modify file path
downloadVideoFileByParts(testID, downloadDestination);
}

public ContentRange downloadVideoBytes(String managerTestId, FileOutput


Stream out, long start, long end) throws UnirestException, IOException {
final String url = String.format("%s/api/tests/%s/video", urlBase, man
agerTestId);
HttpResponse<InputStream> responseString = Unirest.get(url)
.header(HttpHeaders.AUTHORIZATION, "Bearer " + accessKey)
.header(HttpHeaders.RANGE, "bytes=" + start + "-" + end)
.asBinary();
InputStream in = responseString.getBody();
byte[] readBytes = new byte[1024];
while(in.read(readBytes) != -1) {
out.write(readBytes);
}
return new ContentRange(responseString.getHeaders().getFirst("Content-
Range"));
}

private void downloadVideoFileByParts(String managerTestId, String downloa


dDestination) throws UnirestException, IOException {
Path downloadFile = Paths.get(downloadDestination);
if (Files.notExists(downloadFile.getParent())) {
Files.createDirectories(downloadFile.getParent());
}
try(FileOutputStream out = new FileOutputStream(downloadDestination))
{
long start = 0;
long end = 1;
ContentRange contentRange;
do {
contentRange = downloadVideoBytes(managerTestId, out, start *
1024, end * 1024 - 1);
start++;
end++;
} while(contentRange.end < contentRange.total - 1);
}
}

class ContentRange {
Long start, end, total;
public ContentRange(String contentRange) {
String[] range = contentRange.split("[ -/]");

©2023 Digital.ai Inc. All rights reserved Page 723


Test Execution

this.start = Long.valueOf(range[1]);
this.end = Long.valueOf(range[2]);
this.total = Long.valueOf(range[3]);
}
}
}

Rest API - Keys


The Reporter provides you with a Rest API that gives you direct access to the test data and statistics. In this
page, you will find out how to manage keys (get, create, remove)

Concept
• Key -Key and value construct a tag. Each test has a subset of available tags with various values that
describe the test specifics. Example: {device.os : Android}.

The role of the user performing the Rest Operation is specified by the 'Authorization' header.

For more information see How To Execute Rest API.

Get All Keys


Get the information on all the keys the user has access to.

• This API is available for all user roles.

GET /reporter/api/keys

Response
Response Status: 200 OK[
{
"id": 13,
"name": "browserName",
"index": 11,

©2023 Digital.ai Inc. All rights reserved Page 724


Test Execution

Response
"dataType": "STRING",
"valueCount": 0,
"protected": true
},
...
]

Create a New Key


Create a new key in the cloud.

• This API is available for the Cloud Administator only.

POST /reporter/api/keys

JSON parameter

Name Type Mandatory Description


name String Yes Name of the new key

type String Yes Type of the new key

Response
Response Status: 200 OK{
"id": 40,
"name": "new_key2",
"index": 19,
"dataType": "STRING",
"valueCount": 0,
"protected": false
}

Remove Key
Deletes the key identified by {id}.

• This API is available for the Cloud Administrator only.

DELETE /reporter/api/keys/{id}

{id} - One or more ids can be provided, separated by a comma.

Example: /reporter/api/keys/3,4,23

You can retrieve the key ID using the Get Keys Rest API.

©2023 Digital.ai Inc. All rights reserved Page 725


Test Execution

Code Example
This example uses the Unirest HTTP library. To compile and run them, use the following Maven
dependency:

Maven dependency
<dependency>
<groupId>com.mashape.unirest</groupId>
<artifactId>unirest-java</artifactId>
<version>1.4.9</version>
</dependency>

Java Code Example


import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.JsonNode;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.apache.http.HttpHeaders;
import org.junit.Test;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;

public class APIConfluence {


private HttpResponse<String> responseString;

private HttpResponse<InputStream> responseInputStream;

private String urlBase = "http://hostname:port/"; //TODO: modify hostnam


e and port of your Reporter
private String user = "user"; //TODO: user name
private String password = "....."; //TODO: user password
private String accessKey= "....."; //TODO: user access key
String projectName = "projectName";//TODO: project name is here
String projectID = "projectID";//TODO: project ID is here

private String testID = "test ID";//TODO: test ID is here

@Test

©2023 Digital.ai Inc. All rights reserved Page 726


Test Execution

public void getKeys() {


String url = urlBase + "/api/keys";

try {
responseString = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void setKey() {
String url = urlBase + "/api/keys";
try {
responseString = Unirest.post(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.body("{ \"name\": \"newKey\", \"type\": \"STRING\" }")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}

@Test
public void deleteKey() {
String url = urlBase + String.format("/api/keys/%d","<keyId>"); //TODO
: modify key ID
try {
responseString = Unirest.delete(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asString();
System.out.println(responseString.getBody());
} catch (Exception e) {
e.printStackTrace();
}
}
}

©2023 Digital.ai Inc. All rights reserved Page 727


Test Execution

Video Report

This page provides useful information on Video Reports in Continuous Testing.

Video Report
Report contains a video of the test run. It is generated only for tests that were finished in an orderly fashion
(INCOMPLETE tests may not have a video in the report)

Video time is connected to the current step marked and to the log panel at the bottom.

Object Spy
When looking at a failed test report, object spy tab will appear at the device info line. Clicking it opens the
object spy.

(example object spy tab of a failed test)

©2023 Digital.ai Inc. All rights reserved Page 728


Test Execution

Object Spy is used to inspect an application's elements at the time command driver.quit() was executed
(when object spy is available, an icon of binoculars appears by the step).

The element tree is a representation of an XML file. Each element represents a node and its properties in the
tree module.

The info presented in the object spy is the application's state when a user performed the command
driver.quit().

Selecting Elements in the Object Spy

You can click on any element to select it. Clicking on an element will highlight it and show you
its properties located in the XML tree. i.e:

Clicking on an image element or a tree element will:

• mark the element in the image


• change the selected element properties
• navigate the hierarchy tree to it.

Searching elements in Object Spy

You can select and isolate elements using the search bar on top of Object Spy. There are two types of
search you can perform -

Search By Text

Select `Text` from the left drop down in search bar and type a text in the search text box to search for any
element.

©2023 Digital.ai Inc. All rights reserved Page 729


Test Execution

Search By XPath

Select 'XPath' from the left drop down in search bar and type a valid XPath expression in search text box. It
will show you results and highlight the first element based on your search. You can also navigate to other
search results by using the up/down arrow sign in right side of search bar.

©2023 Digital.ai Inc. All rights reserved Page 730


Test Execution

If you wish to retrieve several XPath queries of the different properties of an element instead of manually
querying for combination of XPaths, you can go with the option of "Add to Filter". Select the property for
which you wish to obtain the XPath and click on the "Add to Filter" icon (shown in image below). Repeat the
process for other properties if necessary.

Attachments
At the top right corner you'll find a 3 dots button. Clicking it shows the attachments menu of the report.

Menu content:

• External Report
• Downloads
• Create a Jira issue (below)

Clicking 'External report' will open the External Report in the browser for viewing.

©2023 Digital.ai Inc. All rights reserved Page 731


Test Execution

Clicking 'Downloads' will open a popup that enables you to download each of the attachments (including the
external report).

Following attachments are specific to the framework you are working on and are available to download (if
they were generated):

Selenium

• Video

©2023 Digital.ai Inc. All rights reserved Page 732


Test Execution

• External Report

Espresso

• Video
• Device log
• Trace
• Additional espresso specific log files if test fails

Appium

• Video
• Device log
• Container log
• Appium Server log
• WDA log

XCUITest

• Video
• Device log
• Process output

Grid (Seetest & Appium)

• Video
• Device log
• External Report
• Elements XML - Available for Appium. Generated on test failure. Represents the screen at the point of
time driver.quite()

User attachments

Additional attachments can be uploaded for each test by using the ManagerPublisher class (Available for
Java only)

©2023 Digital.ai Inc. All rights reserved Page 733


Test Execution

Create a Jira Issue


Besides downloading attachments you can also create a Jira issue clicking on the three dots option, on the
upper right-hand-side:

To be able to create a Jira issue from this page follow the instructions here on how to configure it.

For more information about creating issues please visit Creating Issues via direct HTML links.

Multi Device Report


Description
In order to connect several reports, users can use the multiTestId test property. It available for Grid tests. To
enable this, select "Allow users to create new fields from code environment".

In the generated report you can swap between related tests by clicking the 'Device' field at the top left of the
report.

©2023 Digital.ai Inc. All rights reserved Page 734


Test Execution

After clicking a list of devices is presented with their names.

©2023 Digital.ai Inc. All rights reserved Page 735


Test Execution

Examples

Appium
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.openqa.selenium.remote.DesiredCapabilities;

import java.net.URL;
import java.util.UUID;

public class AppiumExample {


private final static String host = "<Cloud URL>";
private final static String accessKey = "<Your Access Key>";
private static String multiLink = String.valueOf(UUID.randomUUID());
private String reportDirectory = "reports";
private String reportFormat = "xml";

©2023 Digital.ai Inc. All rights reserved Page 736


Test Execution

private String firstDeviceTestName = "Multi Device Test- Device 1";


private String secondDeviceTestName = "Multi Device Test- Device 2";
AndroidDriver<AndroidElement> driver1;
AndroidDriver<AndroidElement> driver2;

public DesiredCapabilities mustHaveCapabilitiesForMultiDeviceReport(String


testName){
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("reportDirectory", reportDirectory);
dc.setCapability("reportFormat", reportFormat);
dc.setCapability("testName", testName);
dc.setCapability("accessKey", accessKey);
dc.setCapability("multiTestId", multiLink);// This line makes the conn
ection
return dc;
}

@BeforeEach
public void beforeEach(TestInfo testInfo) throws Exception {
driver1 = new AndroidDriver<>(new URL(host + "/wd/hub"), getCapabiliti
esForDevice1());
driver2 = new AndroidDriver<>(new URL(host + "/wd/hub"), getCapabiliti
esForDevice2());

}
@Test
public void firstDevice() {
// Your test logic....
}

@AfterEach
public void afterEach(TestInfo testInfo) {
driver1.quit();
driver2.quit();
}

public DesiredCapabilities getCapabilitiesForDevice1() {


DesiredCapabilities dc = mustHaveCapabilitiesForMultiDeviceReport(first
DeviceTestName);
dc.setCapability("newCommandTimeout", 120000);

//.... additional capabilities....


return dc;
}
public DesiredCapabilities getCapabilitiesForDevice2() {
DesiredCapabilities dc = mustHaveCapabilitiesForMultiDeviceReport(seco
ndDeviceTestName);
dc.setCapability("newCommandTimeout", 120000);

©2023 Digital.ai Inc. All rights reserved Page 737


Test Execution

//.... additional capabilities....


return dc;
}
}
Seetest
import com.experitest.client.Client;
import com.experitest.client.GridClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.UUID;

public class STAExample {


private final static String host = "<Cloud URL>";
private final static String accessKey = "<Your Access Key>";
private static String multiLink = String.valueOf(UUID.randomUUID());
private String reportDirectory = "reports";
private String reportFormat = "xml";
private String firstDeviceTestName = "Multi Device Test- Device 1";
private String secondDeviceTestName = "Multi Device Test- Device 2";
protected Client client1;
protected Client client2;

@BeforeEach
public void beforeEach() {
GridClient grid1 = new GridClient(accessKey, host);
GridClient grid2 = new GridClient(accessKey, host);
client1 = grid1.lockDeviceForExecution(firstDeviceTestName, "", 10, 500
00);
client2 = grid2.lockDeviceForExecution(secondDeviceTestName, "", 10, 5
0000);
client1.setProperty("controller.idle.timeout",""+120000 );
client2.setProperty("controller.idle.timeout",""+120000 );
client1.setReporter(reportFormat, reportDirectory, firstDeviceTestName)
;
client2.setReporter(reportFormat, reportDirectory, secondDeviceTestNam
e);
client1.addTestProperty("multiTestId",multiLink);
client2.addTestProperty("multiTestId",multiLink);

}
@Test
public void test(){
//Your test logic

©2023 Digital.ai Inc. All rights reserved Page 738


Test Execution

@AfterEach
public void afterEach(){
client1.generateReport(false);
client2.generateReport(false);
client1.releaseClient();
client2.releaseClient();
}
}

Manual Test Report


When working with devices in manual mode, you can record your activity and generate a manual report. This
report can, later on, be viewed, shared and played as a video recording. Generating such reports is the best
way to document reproducible bugs and flaws in the app or mobile website.

To begin, open a device in manual mode or automation mode.

Start The Recording


The report generator is located inside the utilities console that is located right of the device. If it is not
present, expand it by clicking on the expand button on the bottom right hand side.

Expand the utilities console

©2023 Digital.ai Inc. All rights reserved Page 739


Test Execution

Once you have expanded the utilities console, click on the Report tab.

Naming the report and action groups


Give your report a meaningful name. Click on the name of the report and rename it. You can also rename
action groups inside the report.

©2023 Digital.ai Inc. All rights reserved Page 740


Test Execution

Start Recording
Click on the record button and start interacting with the application or website. For every action that you take,
an entry will be added.

©2023 Digital.ai Inc. All rights reserved Page 741


Test Execution

Adding Action Groups


In the example given, we've logged in to the app and can now make payment. So we can define the first
group as login group and the next group as a make payment group.

To add another action group, click the plus icon. Name your group and continue testing.

©2023 Digital.ai Inc. All rights reserved Page 742


Test Execution

Saving the Report


Once you are done testing, pause the recorder and save the report.

©2023 Digital.ai Inc. All rights reserved Page 743


Test Execution

Viewing, Sharing, Playing The Report


Head back to the cloud main page. In the left hand side menu click on Reports. Locate your report and click
to open the report.

The report will open in a new window. You can step through the report, view the different stages, and play the
record as a video.

©2023 Digital.ai Inc. All rights reserved Page 744


Test Execution

Performance Report
A performance report is available when executing a transaction. The report contains the following
measurements:

• Duration - Transaction durations in milliseconds.


• Memory - Average and maximum values for the transaction.
• Battery - Average and maximum values for the transaction.
• CPU - Average and maximum values for the transaction.
• Network - Total of Uploaded/Downloaded KBs during the transaction.
• Speed Index - Computed overall score of how quickly the final content was painted.

©2023 Digital.ai Inc. All rights reserved Page 745


Test Execution

For selenium tests, only Speed Index and Duration information are available.

To enable the Speed Index calculation on your system, contact Continuous Testing Cloud support.

Report Data
• The upper left-hand side is the transaction name and application data (name and version).
• The upper right-hand side is in accordance with the type of test.
◦ Mobile - Device information (name, model, OS, Resolution and Network Profile)
◦ Selenium - Selenium session information (browser name, browser version, and OS)
• The rectangles on the right show the measurements of the transaction.

Download the HAR File


1. At the top click the hamburger button.
2. Click 'Download HAR file'.

The HAR file is available only for mobile tests.

©2023 Digital.ai Inc. All rights reserved Page 746


Test Execution

Test Analytics and Reporting


Continuous Testing comes with robust reporting and test analytics capabilities:

Manual Reporting - Allows you to record steps that you take while manually testing your native or web
applications. The report that is generated can then be shared with other developers and testers. A strong
feature of this reporting capability is being able to browse through steps and run the report as if it was a
video recording.

Automation Reporting - For every automated test that you run, Continuous Testing creates a detailed HTML
based report.

The report includes,

• Device and test capabilities,


• Device logs, Screenshots of each and every step and error messages in case the test failed.

Analytics - Continuous Testing integrates with SeeTestReporter.

SeeTestReporter is a report analytics platform that consolidates test report and allows you to analyze test
cases.

©2023 Digital.ai Inc. All rights reserved Page 747


Test Execution

Listing Reports
Reports (both for manual and automated tests) are displayed in the Reports view. The tests are displayed in
tabular form that you can browse through and filter out to create specific segments of tests that you
executed.

Each test contains the following data:

• ID - the ID of the test


• Test Name - the name of the test that was specified in the test's capabilities. In case of a manual test, it
would be the name that was given to the report itself.
• Status - the final status of the test, passed, failed or incomplete.

• Type - mobile (Appium tests) or desktop (Selenium tests).


• Platform - the device that the test was run on. Specifies the device model in case a mobile test was
executed, and browser and browser version in case a test was run on browser.
• OS - operating system of the device or, in case of a Selenium test, operating system of the machine
that
• Duration - how long it took the test to execute.
• Created - the time the test was added to the queue.
• Started - the time the test started running.
• Executor - the nature of the test, whether it was a manual, or automated test.

Viewing Reports
To view the report simply click on its name. A detailed report will open a new tab.

Filtering Reports
The report view allows you to filter the reports so that you can view a specific test or a set of tests with
common properties (such as type, platform, operating system or executor).

©2023 Digital.ai Inc. All rights reserved Page 748


Test Execution

For every column in the table, there is a corresponding filter. Simply click on the filter to expand the selection.
Select the test properties that you want to include or exclude.

Application Crash Reporting


You can attach Device crash reports to the test report for future analysis.

This is supported in:

• SeeTest Grid
• Appium Grid
• Appium OSS

To enable the feature, do one of the following:

• To set it in Appium, set the attachCrashLogToReport capability to true.

dc.setCapability("attachCrashLogToReport", true);
• To set is in the Cloud:
• Click Settings → Projects.
• Select the project, then click → Manage → Preferences.
• Under Automation click Automation Type.
• Make sure Use Appium Grid is selected.

©2023 Digital.ai Inc. All rights reserved Page 749


Test Execution

• Click Add.
• Under Property Name enter attach.crash.log.to.report.
• Under Property Value enter True.
• Click Save ( ).

• The new crash log is created during the test session.


• When collecting crash logs, the collect.crash.log tag in the reporter is set to True.
• If there is a crash, test property "appCrashed" is set to True, otherwise it is False.
• In Android, if there is no crash, device_crash.log is not uploaded.
• In iOS, even if there is no crash, the crash zip file is uploaded. If there is a crash, the zip file includes
an IPS file.

The device crash log is attached with the other attachment files.

©2023 Digital.ai Inc. All rights reserved Page 750


Test Execution

©2023 Digital.ai Inc. All rights reserved Page 751


Test Execution

The crash log file name depends on the OS.

• Android: device_crash.log.

• iOS: deviceCrashLogs.zip.

©2023 Digital.ai Inc. All rights reserved Page 752


Test Execution

Test Execution
Explore the topics below to learn more about Test Execution with Continuous Testing Cloud.

This space is dedicated for those who already have created test suites, driven by Selenium, Appium,
Espresso or XCUITest

Here you can find detailed information on topics like:

• Migrating your test suites to Continuous Testing Cloud.


• Parallel test execution on Web \ Mobile devices.
• Viewing and analyzing test results.

©2023 Digital.ai Inc. All rights reserved Page 753

You might also like