Test Execution 11-25-2023
Test Execution 11-25-2023
Test Execution
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:
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.
1. If you plan to test a native or hybrid app, upload your app to your project.
2. Obtain an Access Key
Continuous Testing Cloud supports Appium open-source execution when any Appium Tests are run.
• 1.22.3
• 2.1.3
Application Capability
For example:
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");
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.
reportDisable (report.disable) Automated Test Reports iOS/Android Use this capability to choose if a report is
generated.
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.
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.
AudioReport Attaching Audio to iOS/Android Attaches a device audio to the video report.
Video Report
Code Examples
@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
@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);
//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");
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();
}
}
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.
main.dart
import 'package:flutter_driver/driver_extension.dart';
void main() {
enableFlutterDriverExtension();
runApp(const MyApp());
}
pubspec.yaml
dev_dependencies:
test: any
flutter_driver:
sdk: flutter
flutter_test:
sdk: flutter
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("automationName", "Flutter");
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.
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.
To make sure you are running Appium Server 2.x, run: appium -v
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("automationName", "Espresso");
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\" , " +
"\"androidx.compose.ui:ui-tooling:1.1.1\" , " +
"\"androidx.compose.foundation:foundation:1.1.1\" , "
+
"\"androidx.compose.material:material:1.1.1\" ] }");
4. Uninstall Espresso Server from Android device, so that Appium Server installs it.
To see where the Espressor server is located, check the in Appium server log.
capabilities.setCapability("espressoServerUniqueName", "espresso_jetsurvey");
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;
/**
* 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
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\" ] }");
@Test
public void jetSurvey() {
// Espresso server is created during Appium driver creation.
}
@AfterAll
public static void tearDown() {
if (driver != null)
driver.quit();
}
}
import java.net.MalformedURLException;
import java.net.URL;
@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");
@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.
Troubleshooting
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: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
driver.installApp("cloud
:unqiueName=app_unique_n
ame")
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")
Android
driver.installApp("cloud
:com.experitest.ExperiBa
nk/.LoginActivity:keepDa
ta=true")
@Test
public void test(){
Map<String, Obje
ct> launchOptionsMap = n
ew HashMap();
launchOptionsMap
.put("relaunch", true);
envVars.put("sec
ret_key", "DFSF5343543CA
A");
envVars.put("DEB
UG", true);
launchOptionsMap
.put("launch_env",envVar
s);
String bundleId
= "com.apple.AppStore";
Gson gsonObj = n
ew Gson();
String jsonStr =
gsonObj.toJson(launchOp
tionsMap).replace("\"",
"\\\"");
driver.executeSc
ript("seetest:client.lau
nch", bundleId, jsonStr)
;
}
driver.executeScript("s
eetest:client.setAuthent
icationReply", "AUTHENTI
CATION_SUCCEEDED", "1000
0");
// Simulates a capture.
It works only with a URL
, not local files
driver.executeScript("se
etest:client.simulateCap
ture", "<FILE_URL>");
// or files uploaded to t
he cloud through file rep
ository
driver.executeScript("se
etest:client.simulateCap
ture", "cloud:<FILE_UNIQ
UE_NAME>");
driver.executeScript("se
etest:client.startPerfor
manceTransaction", "Moni
tor");
Youn need to
use endPerformanceTransaction
at the end.
driver.executeScript("se
etest:client.startPerfor
manceTransactionForAppli
cation", "com.experitest
.ExperiBank", "Monitor")
;
You need to
use endPerformanceTransaction
at the end.
driver.executeScript("se
etest:client.endPerforma
nceTransaction", "<Repor
t Name>");
driver.executeScript("se
etest:client.sendKeysWit
hBT", "" + Keys.CONTROL+
Keys.ALT + "I");
driver.executeScript("se
etest:client.hybridClear
Cache()");
driver.executeScript("se
etest:client.startStepsG
roup", "<Group Name">);
driver.executeScript("se
etest:client.stopStepsGr
oup");
driver.executeScript("se
etest:client.setNetworkC
• airplane_mode
• wifi
• mobile_data
• bluetooth
driver.executeScript("se
etest:client.getNetworkC
onnection", "<MODE>");
driver.executeScript("se
etest:client.addTestProp
erty", "<propertyName>",
"<propertyValue>");
driver.executeScript("se
etest:client.setLocation
PlaybackFile", "cloud:Lo
cationCsvFile", delay, "
LocationProvider");
driver.executeScript("se
etest:client.waitForSetL
ocationEnd", 5000);
driver.executeScript("se
etest:client.setPasscode
");
driver.executeScript("se
etest:client.clearPassco
de");
driver.executeScript("se
etest:client.setNetworkC
onditions", "Monitor", 6
0000);
driver.executeScript("se
etest:client.clearLocati
on");
driver.executeScript("se
etest:client.stopLocatio
nPlayback");
driver.executeScript("se
etest:client.activateVoi
ceAssistance", "open goo
gle");
For more supported Continuous Testing Cloud commands for Appium OSS, see Using The File Repository.
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:
URL authentication
For accessKey, use the following convention:
This article explains how to run automated tests on a device that you have already opened from a web
desktop browser.
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.
2. On right side of the screen, click Automation > LET'S START AUTOMATING.
3. Copy the Device ID. The device is reserved and ready to run Automation.
Testbase Modification
/**
* 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.
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.
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.
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
and enrich your test with capabilities and actions that are not included in and cannot be achieved using
Appium.
• 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:
repositories {
maven{
url "https://cloud.experitest.com/repo/"
}
mavenCentral()
}
dependencies {
compile 'com.experitest:appium-seetest-extension:+'
}
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.
Parameters
Name Value Description
Action string Action to execute
Usage
...
...
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'
Example
...
...
//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 example:
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.
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.
...
...
// reboot and wait 2 minutes for the device to reload
// unlock the device after reboot
if(seetest.reboot(120000)){
seetest.deviceAction("Unlock")
}
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
Usage
Replace <server> with the appropriate URL.
Example
Using Run Command
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
...
...
// call a number
seetest.run("adb shell am start -a android.intent.action.CALL -d tel:+65123456
78");
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.
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.
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");
ClearLocation
Description
Use this command to reset the device’s location services after you execute SetLocation.
Usage
Replace <server> with the appropriate URL.
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.
Usage
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
Usage
Replace <server> with the appropriate URL.
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.
Usage
Replace <server> with the appropriate URL.
• 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:
• False - Vertical
Usage
Example
...
...
//Command performs and pinch action
seetest.pinch(true, 600, 1000, 700, false)
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
Supported Properties
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.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.
Android .instrumentation.security none, smart, hard (default value: smart) Disable the Android LayoutParams FLAG_SEC
Note
This property is available also as an 'app-prope
be declared and set on/off in the app.properties
• 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:
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.
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
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:
• Dismiss
It only works with iOS 9 and above.
• Don't allow
• Close
• Cancel
• Not now
• "...Later"
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
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.
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
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.
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.
Example
SetProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
// 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.
Example
...
...
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:
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
Host device.host The IP and port of the host machine (127.0.0.1 or USB
for local devices)
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
Instrumentation version instrumentation.version Only for iOS devices, for instrumented applications
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.
GetProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
// 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
Usage
Command can be used to swipe in a given direction from an offset.
swipe
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
// Swipes right from an offset
seetest.swipe("Right", 10, 500);
For example:
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.
Parameters
Name Value Description
Network type Checks if a device is in given network type.
• airplane_mode
• wifi
• mobile_data
Usage
Command can be used to check if a device is in a given network mode.
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.
Usage
HybridClearCache
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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
If Profile is not set (empty), the default profile (no network limitations) is selected.
Usage
Network Profile Virtualization is enabled for the Project Administrators. Subsequent to this the profile name
can be used to set the network condition.
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);
// Do Test
SetAuthenticationReply
Description
Use this command to simulate different authentication responses on applications that request a user
fingerprint authentication.
Limitations
• 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
• 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
Usage
Replace <server> with the appropriate URL.
SetAuthenticationReply
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
...
...
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
Time Int
Usage
In order to flick the screen you can add the command 'flick', provide the direction and offset.
• 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
Usage
Replace <server> with the appropriate URL.
• 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.
Example
ReceiveIncomingCall
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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.
• 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>");
...
...
GetRunningApplications
Description
This command returns all the running applications on the device as a String array.
Usage
Replace <server> with the appropriate URL.
Example
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.
Example:
GetConnectedDevice
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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
Example
CloseAllApplications
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
seetest.closeAllApplications();
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.
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.
Parameters
Name Type Possible Values Description
Connection String Connection type.
• airplane_mode
• wifi
• mobile_data
• Bluetooth
Usage
Replace <server> with the appropriate URL.
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);
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.
GetApplicationInfo
Description
Use this command to get specific application info, given a key parameter for the requested information.
Parameters
Name Type Description
BundleId String Application package name.
Key String The requested info key name.These are valid for iOS and Android:
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.
This feature is only supported for primitive types, for example, objects whose value type is NSString,
NSNumber, or NSDate.
You can find more properties by inspecting the info.plist file in the application IPA.
Usage
Replace <server> with the appropriate URL.
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.
Usage
Replace <server> with the appropriate URL.
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.
Parameters
Name Type Description
Text String Clipboard Text
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
Usage
Replace <server> with the appropriate URL.
Example
StartLoggingDevice
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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
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)
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.
Example
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);
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
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
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.
SetPasscode
Description
Use this command to set a default passcode to the device. If it fails, it throws an exception.
Usage
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.
Usage
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
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");
...
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.
mockReciever String Receiver to use for mocking: gps / network/ gps,network. Supported only for Android.
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.
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 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.
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
Example
Replace <server> with the appropriate URL.
...
...
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
...
...
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.
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.
....
....
Normally when using this command, you use the launch command with it.
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
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:
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).
Example
...
...
iOS
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.
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
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
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.
The examples below show a couple of use cases for this feature for users who are using JAVA and Ruby
Clients.
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);
launchOptions.add("launch_env",envVars);
client.launchWithOptions("com.experitest.ExperiBank", launchOptions.toString()
);
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:
◦ -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.
...
...
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
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.
Example
Replace <server> with the appropriate URL.
...
...
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
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.
...
...
// 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.
Parameters
Name Value Description
Zone string Select Zone - Native or Web
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
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.
...
...
// 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
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.
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
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
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.
...
...
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
Usage:
This command can be used get any property element.
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"));
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.
Example
GetAllValues
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
// 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.
Usage
Command is used to set value for a property of an Element in the device screen.
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
Touch commands supported in iOS only in instrumented Native zone, Android supports all zones
TouchDownCoordinate
Description
Parameters
Name Value
Horizontal Coordinate Integer Horizontal 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
TouchUp
Description
Usage
Replace <server> with the appropriate URL.
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
Parameters
• 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
TouchMove
Description
Touch move to element, this command should come after touchDown or touchDownCoordinate commands.
Parameters
• 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
TouchUp
Description
Usage
Replace <server> with the appropriate URL.
Touch Commands
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
ElementSendText
Description
Send text to an element
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
Usage
Replace <server> with the appropriate URL.
Example
ElementSendText
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
ElementListSelect
Description
Select an element within a list (first making the element visible)
Parameters
Name Value Description
List locator String A String identifier of List locator
Usage
The command can be used to select an element in a List.
Example
Click the parent of the list element and note down the list locator identifier which is in this case
"accessibility=conutryView".
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.
ElementListSelect
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
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
Usage
Command to check of element is found in screen. If not found throws and exception.
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
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.
Example
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
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.
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.
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
• NATIVE
• WEB
• TEXT
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)
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.
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 Zone Name String with available zones Zones which define the way the element will be identified.
• NATIVE
• WEB
• TEXT
Usage
Uses zones to identify the list Locator and the element Locator
Example
Image and code below displays how this command can be used.
ElementListPick
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
//
ElementListVisible
Description
Matching command to ElementListSelect. Will make an element on a list visible.
Parameters
Name Value Description
List locator String A String identifier of List locator
Usage
This is actually elementListSelect command with click parameter of false.
Example
Click the parent of the list element and note down the list locator identifier which is in this case
"accessibility=conutryView".
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.
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);
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.
Usage
Equivalent command to the swipe command. This command will swipe inside a container and not the entire
screen.
Example
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
Element to find Zone String as valid zones Zone of the sought element
• NATIVE
• WEB
• TEXT
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).
Usage
Command could be used to scroll down till element is not found
Example
ElementSwipeWhileNotFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
FlickCoordinate
Description
Flick the screen from X, Y in a given direction
Parameters
Name Value Description
X Integer Horizontal Coordinate in screen pixels
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.
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");
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.
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.
FlickElement
...
...
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.
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 Count String with one of the following values The zone to extract the text from
Zone
• WEB
• TEXT
Usage
Similar command to getElementCount command which will count elements based on a container.
Example
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);
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
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
Usage
Command can be used to get text for certain area.
Example
In this example we will try to get all the text of the Web part from the EriBank Application.
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
Usage
Replace <server> with the appropriate URL.
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.
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 Find Zone String with one of the following values Find Element Zone
• NATIVE
• WEB
• TEXT
Usage
Command can be used to find and Element using an other element.
Example
In the following example, we will try to find the ‘Make Payment’ button using the ‘Mortgage Request’ button.
IsFoundIn
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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
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
Usage
Command can be used to verify an element is present in relation with another element.
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.
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.
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
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.
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
Usage
Command can be used to wait for an element to disappear until a given time.
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.
Parameters
Name Value Description
Zone String with one of the following Zones which define the way the element will be identified.
values
• NATIVE
• WEB
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.
Usage
Command can be used to force touch an element.
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.
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.
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)
Note: Wheelindex is only relevant for iOS, because a picker in iOS might have multiple wheels.
Usage
Replace <server> with the appropriate URL.
Example
SetPickerValues
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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.
A gesture consists of one or more event sequences (paths), where each path is executed with a different
finger.
StartMultiGesture
Description
Indicate to SeeTest that the following commands sent from the client are grouped under the multi gesture
step.
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
• NATIVE
• WEB
• TEXT
MultiTouchDownCoordinate
Description
Adds a touch down event on the given coordinate, with the given finger index.
Parameters
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
MultiTouchMoveCoordinate
Description
Adds a move event to the given coordinate, with the given finger index.
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
MultiTouchUp
Description
Parameters
MultiClick
Description
Adds a click on the given element, with the given finger index.
Parameters
• NATIVE
• WEB
• TEXT
MultiClickCoordinate
Description
Adds a click one the given coordinate, with the given finger index
Parameters
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.
MultiWait
Description
Parameters
Name Value Description
Direction String Direction of the swipe motion.
Usage
Replace <server> with the appropriate URL.
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);
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.
Parameters
Name Value Description
Zone String with valid values as Select Zone
• NATIVE
• WEB
• TEXT
Script String The Native API script that will run on the identified element
Usage
Command be used to run scripts based on Native API call. See the example below.
Example
then this command can be used to execute the script such that all actions above can be performed.
...
...
// 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
);");
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
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.
Example
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");
...
...
GetPickerValues
Description
Get all values from picker element.
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
Usage
Command can be used to get all the values of a picker element.
Example
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);
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.
Parameters
Name Value Description
Zone String with one of the following values Select the Zone in which the table is stored
• NATIVE
• WEB
• TEXT
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.
Example
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.
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
Return Value
• True - Property and value were added.
• False - Addition of the property failed.
Usage
Replace <server> with the appropriate URL.
AddTestProperty
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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
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.
...
...
// Records the Audio file
seetest.startAudioRecording("C:\\AudioFilesToPlay\\OpeningWaze.wav");
seetest.stopAudioRecording();
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.
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
...
...
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:
Parameters
Name Value Description
Timeout Integer Time in milliseconds until execution ends.
Usage
Replace <server> with the appropriate URL.
...
...
// 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
Similarity Integer Integer number between 80-100. Enables to define the tolerance of changes when searching for the image.
Usage
Example
CaptureElement
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
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.
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");
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.
Usage
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.
Usage
This should be a part of teardown function of the test.
Example
GenerateReport
{
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
}
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.
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();
GetCurrentActivity
Description
Use this command to retrieve the foreground activity name.
Usage
GetCurrentActivity
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
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.
This command throws an exception for devices which do not support the command.
Usage
Replace <server> with the appropriate URL.
GetCurrentApplication
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
GetDevicesInformation
Description
Use this command to retrieve all information for a device. This returns an XML string.
XML Attributes
os string Device OS
status string Current status of device(unreserved offline, unreserved online, reserved online, etc.)
version string Device full operating system version (build number inclusive)
versionnumber double Device full operating system version (build number exclusive)
Usage
Replace <server> with the appropriate URL.
GetDevicesInformation
...
...
GetInstalledApplications
Description
Use this command to get a list of applications installed on the device.
Usage
Replace <server> with the appropriate URL.
GetInstalledApplications
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
seetest.getInstalledApplications();
GetLastCommandResultMap
Description
Use this command to retrieve information on the last command executed.
Usage
Replace <server> with the appropriate URL.
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.
Usage
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.
If the dump type is not supported on the current page, and empty XML is returned.
Usage
Replace <server> with the appropriate URL.
Example
getVisualDump
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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
• WEB
• TEXT
Usage
Example
In this example, while element "Expense : 4" is not found, Add is clicked.
PressWhileNotFound
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
...
...
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.
Example
SetProjectBaseDirectory
...
...
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.
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.
• 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.
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.
If an empty String or Null are sent as the SIM card name, any sim card already assigned is unassigned from
the device.
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.
• 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>");
...
...
Accessibility Inspection
Appium Automation provides an API to interact with the accessibility inspector service directly.
• 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.
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.
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.
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);
...
...
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.
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);
...
...
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.
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);
...
...
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.
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);
...
...
AccessibilityStop
Description
Use this command to stop the Accessibility Inspector service on the device.
Parameters
None.
Usage
Replace <server> with the appropriate URL.
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();
AccessibilityStart
Description
Use this command to run the Accessibility Inspector service on the device.
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.
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);
...
...
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.
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
Usage
Replace <server> with the appropriate URL.
Example
// 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();
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.
Such capabilities allow you to customize the report and tailor it to your specific test needs.
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.
...
...
seetest.report("THIS STEP HAS SUCCEEDED", true);
...
seetest.report("THIS STEP HAS FAILED", false);
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.
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.
...
...
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.
Parameters
Name Value Description
showPassImageInReport boolean true - show images only for failed steps
Example
Replace <server> with the appropriate URL.
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();
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
Example
Replace <server> with the appropriate URL.
...
...
SetReportStatus
Description
Overrides final report status. Used in order to match a local test result with the report result.
Parameters
Name Value Description
status String status with below valid values. Test status to set
• Failed
• Skipped
• Passed
Usage
SetReportStatus
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "deviceid");
...
...
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
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
.....
.....
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.
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.
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();
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.
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.
....
....
Default behavior can be configured by setting app.properties file as per properties described below.
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).
true or false
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.
Notes:
• 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.
• All System Resources Monitoring are available for both non-instrumented and instrumented
applications.
Memory
Continous Testing provides CPU metrics data based on 'adb shell dumpsys meminfo'.
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',
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.
GetCounter
Description
Returns the monitor (CPU/Memory/Battery) value on the given time
Parameters
Name Value Description
CounterName String
• CPU
• Memory
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.
Example
GetCounter
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);
// get Count for cpu
client.GetCounter("cpu");
GetMonitorsData
Description
Return the content of the monitor values as a string in CSV format.
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
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");
• 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
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.
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.
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
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
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).
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");
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:
Example
StartMonitor
...
...
// 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.
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:
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.findElement(By.xpath("//*[@id='loginButton']")).click();
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:
• 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");
...
...
Result Example
{
"transactionName": "transaction test",
"transactionId": 10,
"appName": "com.experitest.ExperiBank",
"appVersion": "1.2890",
"deviceInfo": {
"uid": "RGF8MM81FK8SV",
"model": "SM-G973F",
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.
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:
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");
...
...
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.
Example
SetDefaultClickDownTime
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
SetDefaultTimeOut
Description
Use this command to set the default timeout for other commands.
Parameters
Name Type Description
Timeout Integer Timeout in milliseconds
Usage
Replace <server> with the appropriate URL.
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
Usage
Replace <server> with the appropriate URL.
Example
setDragStartDelay
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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.
• 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.
• 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
Usage
Replace <server> with the appropriate URL.
Example
Speed
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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.
Parameters
Name Type Description
AutoScroll Boolean
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.
Example
SetWebAutoScroll
DesiredCapabilities dc = new DesiredCapabilities();
driver = new AndroidDriver(new URL("<server>"), dc);
seetest = new SeeTestClient(driver);
dc.setCapability(MobileCapabilityType.UDID, "<deviceid>");
...
...
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.
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) :
}
Supported Properties
• 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).
• WATCH
• PHONE
• TABLET
tag Device tag (that was added by Cloud / Project Example: new_device
administrator)
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
Example Description
• iPhone model
• iOS
• iPhone model
• iOS
• iOS
Device Setup
Use Device Setup to select the desired device(s).
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.
• On-premises Continuous Testing Cloud environment - Your designated URL. For example: https://
company.com/wd/hub
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
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
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.
Following are the code samples in difference languages to use the capability.
Java
DesiredCapabilities dc = new DesiredCapabilities();
dc.setBrowserName(MobileBrowserType.CHROME);
driver = new AndroidDriver('<server>', dc);
driver.get("seetest.io");
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'
Name Description
// To support Android app you should add the'appPackage' and the 'appActivi
ty' capabilities
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
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
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:
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
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
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
C Sharp
// 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.AutoWebView, true);
driver = new IOSDriver<>('<server>', dc);
Android Only
Name Description
noReset Don't reset app state before this session.Default false.
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
....
....
self.dc['platformName'] = 'android'
self.dc['app'] = 'cloud:com.experitest.eribank/com.experitest.ExperiBank.Login
Activity'
self.dc['instrumentApp'] = True
self.dc['fullReset'] = True
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);
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.
Java
dc.setBrowserName(MobileBrowserType.CHROME);
Python
self.dc['browserName'] = 'chrome'
C Sharp
dc.SetCapability(MobileCapabilityType.BrowserName, MobileBrowserType.Chrome);
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":
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.
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
Java
public void test() throws MalformedURLException {
IOSDriver<IOSElement> driver = null;
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;
// 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();
}
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.
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'
},
Java
C#
Python
In your test script, initialize the driver using the newly created driver classes.
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>',
}
}
1. Set up the device for audio recording support (see Audio and Screen Readers Support Using a
Bluetooth Adapter).
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
If you don't find the programming language or framework that you were looking for, contact us using chat or
email.
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.
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;
@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");
@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;
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;
@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");
@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"));
}
}
}
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;
@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
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;
@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");
@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"));
}
}
To make use of the Appium Java Client, add a dependency to your Maven and Gradle projects.
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
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).
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.
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#";
[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");
[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()]
namespace AppiumCsharpFirstTest
{
public class iOSAppTest
{
[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");
[Test()]
[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#";
[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");
[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
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";
[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)
;
[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();
}
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
1. If you plan to test a native or hybrid app, upload your app to your project.
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:
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.
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:
[SetUp()]
public void SetupTest()
{
dc.SetCapability("testName", testName);
dc.SetCapability("accessKey", accessKey);
dc.SetCapability(MobileCapabilityType.PlatformName, "iOS");
dc.SetCapability("autoDismissAlerts", true);
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.
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.
Python
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.
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()
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()
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:
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()
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:
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.
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']")
.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);
});
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',
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.
Getting Started
• Find the sample test in the git repository.
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.
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'
}
}
@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'
},
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
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'
},
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
end
def teardown
puts @driver.capabilities['reportUrl']
@driver.quit
end
end
Prerequisites
• Ruby
• 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:
ruby testfile.rb
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
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 {
static {
ThreadFactory threadFactory = new DefaultThreadFactory("netty-client-t
imer", true);
/**
* 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));
}
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);
@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);
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;
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");
}
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
@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));
@Override
public void cleanupIdleClients() {
this.pool.evictAll();
}
}
Example
dc.setCapability("platformName", "ios");
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
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
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()
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).
Commands
A unique file name must be provided using the "cloud:" prefix.
• 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");
File 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
Examples
Simulate Capture
// File with unique name my_image must exist in file repository
driver.executeScript("seetest:client.simulateCapture", "cloud:my_image");
driver.executeScript("seetest:client.startAudioPlay", "cloud:my_music");
driver.executeScript("seetest:client.waitForAudioPlayEnd", "10000");
It is still possible to start Appium session using cloud address (same as before 21.10)
Recommendation
For better performance users should choose the cloud region with the lowest latency from client machines
where Appium tests are running.
Architecture
The new architecture has 2 goals:
Appium commands flow (except for starting and ending Appium session)
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
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.
automationName - XCUITest
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - iOS
udid - Device Serial Number
browserName - Safari
automationName - UIAutomator2
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - Android
udid - Device Serial Number
browserName - Chrome
Start Session
Once all the necessary Capabilities are populated, we can "Start Session"
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 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.
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)
automationName - XCUITest
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - iOS
udid - Device Serial Number
browserName - safari
automationName - UIAutomator2
deviceName - Name of the target device, but can be generic such as "Samsung"
platformName - Android
udid - Device Serial Number
browserName - Chrome
You can use this checkbox to add the Appim prefix automatically.
Appium supports Image Locator Strategy, which relies on the OpenCV library.
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.
Usage Examples
Gradle Dependency
implementation 'io.appium:java-client:8.3.0'
By imageLocator = AppiumBy.image(base64EncodedImageFile);
element.click();
With the release of Appium 2, there have been improvements and additions to test capabilities.
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.
For more information on migrating from Appium 1.x to 2x see Migrating from Appium 1.x to Appium 2.x.
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
For example, to use Appium 2 you need to set the appiumVersion capability as an option in the object.
Code Examples
Java
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability("platformName","iOS");
Map<String, Object> digitalaiOptions = new HashMap<>();
digitalaiOptions.put("appiumVersion", "2.0.0");
dc.setCapability("digitalai:options", digitalaiOptions);
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 = {
'appiumVersion': '2.0.0',
desired_caps['digitalai:options'] = digitalai_options
'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).
dc.setCapability("selfHealing", true);
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:
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");
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
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.)
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.
accessKey
AndroidDriver driver = new AndroidDriver<>(new URL("http://:"+accessKey+"@"+ho
st+":"+port+"/wd/hub"), dc);
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)
Cloud Project
Cloud Admin will always run the test in the "Default" project. Cloud project provided to grid client is not
used.
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:
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:
When onlyAvailable=false:
SetConnectionInfo String username, String password, String Project, String hostname, int port,
boolean isSecured
Then use the grid client created to request a device to run your test on. Do so with the following command:
If you want to generate a report when the test is finished, you need to set a reporter
Registering imageClient.dll
You will need to register imageClient.dll file to be able to run a Grid Test
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"
/* 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();
}
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");
return 0;
}
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
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.
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
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.
begin
grid = Mobile::GridClient.new_client_url("cloudUsername", "cloudPasswo
rd", "cloudProject", "https://cloud.experitest.com")
Create a new GridClient. Fill in the user credentials, details about the cloud server and the project to log into:
Parameters
Then use the grid client created to request a device to run your test on with the following command:
Parameters
• 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:
◦ When onlyAvailable=false:
Ruby requirements:
Create a new GridClient. Fill in the user credentials, details about the cloud server and the project to log into:
Parameters
Then use the grid client created to request a device to run your test on with the following command:
Parameters
Python requirements:
packages: requests
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.
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:
• In order to use Appium capabilities, you should use the following format:
password Password of cloud user with which to execute the test Yes
reservationDuration Time in minutes for which to reserve the device No 240 (4 hours)
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,
Page Navigation
Click on the 'Automation' button in the main navigation bar.
• OS - iOS/Android
• Phone Platform - Phone/Tablet
• App Type - Native/Web
• Version - available versions
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.
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
• 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.
Test Result
The user can see the test flow and it results in the navigation bar.
And see the report in "Reports" page (provided the reporter is configured).
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.
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.
3. Command Line Tools - To verify that you have Command Line Tools installed: Xcode → Preferences:
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:
You can choose one of two ways, through Xcode's GUI or through CLI.
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.
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:
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
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>
To build using CLI, navigate to the folder where the project is located and run the following:
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:
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.
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:
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.
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.
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:
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:
Select a Device
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:
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:
gradlew assembleDebug
Alternatively, you can build the .apk using Android Studio's GUI: Click on Build → Build APK.
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.
Continuous Testing Cloud exposes Rest APIs to execute Espresso and XCUI based Tests.
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
GET /api/v1/test-run/{id}/status
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 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)
POST /api/v1/test-run/execute-test-run-async
Parameters
2. Fast feedback - all of the tests will be spread across the selected
devices.
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
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
• 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
• 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
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".
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"
}
POST /api/v1/test-run/execute-test-run
Parameters
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.
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.
• 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
• xcscheme file
Android
com.example.app.SomeTest, testFoo
com.example.app.AnotherTest, testBar
minDevices Integer No The minimum number of devices to use during the execution.
Default value - 1.Note: Only use in case of fastFeedback
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".
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"
}
POST /api/v1/test-run/{id}/cancel
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'
}
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;
@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;
@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
cancelTestRun
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.junit.Test;
@Test
public void cancelTestRun() throws UnirestException {
System.out.println(response.getBody());
getTestRunStatus
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import com.mashape.unirest.http.exceptions.UnirestException;
import org.junit.Test;
@Test
public void getTestRunStatus() throws UnirestException {
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
"
Running Cucumberish features with API uses the same parameters as XCUITest and Espresso with few
behavioral differences as follows:
• 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 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"
Use same Manage Test Run with the API requests With Espresso/XCUITests for Android/iOS.
• 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.
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.
MainActivityTest.java
package com.example.myapp;
import androidx.test.rule.ActivityTestRule;
import dev.flutter.plugins.integration_test.FlutterTestRunner;
import org.junit.Rule;
import org.junit.runner.RunWith;
@RunWith(FlutterTestRunner.class)
public class MainActivityTest {
@Rule
public ActivityTestRule<MainActivity> rule = new ActivityTestRule<>(Main
Activity.class, true, false);
}
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'
}
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
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
inherit! :search_paths
end
end
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"
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
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.
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:
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.
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.
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.
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.
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);
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);
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);
}
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>'.
Before you start, make sure you prepare your applications for testing:
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.
3. Select an application from the list to get its bundle id that you specify in the test capabilities.
Watch the video on the right-hand side to learn how to use Postman.
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
The Continuous Testing Cloud platform exposes several API endpoints that allows you to manage your
applications.
To interact with these endpoints, you must first retrieve your access key.
Optional Parameters
You can add optional parameters to the API end point:
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
Java
You need the OKHttpClient library.
You can get from Maven (if you use maven or gradle).
import okhttp3.*;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
@Test
public void uploadApp() throws IOException {
OkHttpClient client = new OkHttpClient();
File app = new File("<PATH_TO_FILE>");
Python
For this code to run, you need the Requests package
url = "https://cloud.seetest.io/api/v1/applications/new"
headers = {
'Authorization': "Bearer <ACCESS_KEY>",
}
app = open('<PATH_TO_FILE>','rb')
files = {'file': app}
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);
}
}
Ruby
For this code to run, you need the ruby's rest-client package
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).
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.junit.Test;
import java.io.IOException;
@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
url = "https://cloud.seetest.io/api/v1/applications"
headers = {
'Content-Type': "application/json",
'Authorization': "Bearer <ACCESS_KEY>",
'Cache-Control': "no-cache",
}
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
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'
url = URI("https://cloud.seetest.io/api/v1/applications")
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
The request is a post request, and you will have to retrieve the application id before you can send the
request to delete.
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"
}
Java
You need the OKHttpClient library.
You can get from Maven (if you use maven or gradle).
@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
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",
}
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
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);
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")
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
Before you can start testing your Android application, you will have to package the app and generate
the .apk file.
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.
First, make sure that you are in the root of your project folder, not the app folder.
Windows
gradlew assembleDebug
Linux or Mac
./gradlew assembleDebug
Once the builds is complete, locate the .apk file in the build folder.
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).
Make sure you have XCode Build tools installed before you start.
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:
Build Configuration:
Debug
Release
Schemes:
<SCHEME_NAME>
Build Configuration:
Debug
Release
Schemes:
UICatalog
When you are ready to build the app, go ahead and run the command below:
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
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
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
You will then have an file with the extension .ipa. Upload this file to the cloud.
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.
• 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
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.
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.
• windows - • chrome
Chrome
• safari
• mac - Safari
• firefox
• internet explorer
• MicrosoftEdge
• browser version
• WINDOWS
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.
agentName String random The name of the agent that the test will run on. any agent name
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.
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.
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.
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.
Returned Capabilities
The following list describes Continuous Testing specific capabilities that returns with the driver.
string
Example
Below you can find an example written in Java specifying the capabilities above.
• Java 8
• Selenium java jar
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.
You can view your automated Selenium tests live in the Continuous Testing cloud.
If you don't have any tests running at the moment, you will see empty grid nodes.
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.
If you prefer to run your Selenium tests using C Sharp, select one of the sample tests below to see our
platform in action.
All the scripts below makes use of the grid access key. In order to run the test do the following
• 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
namespace selenium_csharp_first_test
{
[TestFixture]
public class QuickStart
{
private string ACCESS_KEY= "<YOUR_ACCESS_KEY>";
private string CLOUD_URL = "<server>";
[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"));
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";
//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()
{
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();
}
}
}
In your Visual Studio project, look for the References object in the Solution Explorer. Right Click on it and
select Manage NuGet Packages.
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.
In Visual Studio upper menu, click on Tools → NuGet Package Manager - Package Manager Console.
Note that the commands above install a particular version. Follow updates in NuGet repository:
• Selenium WebDriver
• Selenium Support
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.
All the scripts below makes use of the grid access key. In order to run the test do the following
• 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
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;
@Before
public void setUp() throws Exception {
@Test
public void testSeleniumOnChrome() {
driver.get("https://seetest.io");
webinarFooterLink.click();
@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;
import org.testng.annotations.Test;
@BeforeMethod
public void setUp() throws Exception {
@Test
public void testSeleniumOnChrome() {
driver.get("https://seetest.io");
webinarFooterLink.click();
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;
@Before
public void setUp() throws Exception {
@Test
public void testSeleniumOnFirefox() {
driver.get("https://seetest.io");
webinarFooterLink.click();
@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;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@BeforeMethod
public void setUp() throws Exception {
@Test
public void testSeleniumOnFirefox() {
driver.get("https://seetest.io");
webinarFooterLink.click();
@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;
@Before
public void setUp() throws Exception {
@Test
public void testSeleniumOnIE() {
driver.get("https://seetest.io");
webinarFooterLink.click();
@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;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@BeforeMethod
public void setUp() throws Exception {
@Test
public void testSeleniumOnIE() {
driver.get("https://seetest.io");
webinarFooterLink.click();
Text();
@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.
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.
All the scripts below makes use of the grid access key. In order to run the test do the following
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']")
.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
})
.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.
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.
All the scripts below makes use of the grid access key. In order to run the test do the following
class TestFirefox(unittest.TestCase):
dc = {}
testName = 'Selenium Test on chrome'
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
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'
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
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'
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
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
Before you begin, make sure to install Python bindings for 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:
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.
All the scripts below makes use of the grid access key. In order to run the test do the following
def test_selenium_on_chrome
@driver.navigate.to "https://seetest.io"
webinar_footer_link.click
end
def teardown
@driver.quit
end
end
Firefox with Ruby
require 'test/unit'
require 'selenium-webdriver'
# require 'selenium/webdriver/remote'
def test_selenium_on_firefox
@driver.navigate.to "https://seetest.io"
webinar_footer_link.click
end
def teardown
@driver.quit
end
end
Internet Explorer with Ruby
require 'test/unit'
require 'selenium-webdriver'
# require 'selenium/webdriver/remote'
o the cloud
:accessKey=> '<YOUR ACCESS KEY>'
}
def test_selenium_on_ie
@driver.navigate.to "https://seetest.io"
webinar_footer_link.click
end
def teardown
@driver.quit
end
end
To run your Selenium tests with Serenity and Cucumber ,follow this guide:
Requirements:
• Download and install Java version 8 or above.
• Download and install IntelliJ IDE.
• Download and install Gradle latest version.
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:
URL authentication
For accessKey, use the following convention:
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
• 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!
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.
When at least one of the Running tests' status turns into Finished, the fourth request status will turn
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.
The following browsers have moved their default mode to be W3C standard:
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.
In addition, the Selenium test desired capabilities may include more capabilities.
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.
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:
For example,
For example,
driver.executeScript("seetest:client.startStepsGroup", <group-name>);
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");
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']
}
Users can add a test property (tag) to the report from the client code.
For example,
Users can download a file from the Selenium Agent machine to the local machine in the grid session.
For example,
For example,
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.
• 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.
• 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.
• You should then see your newly imported certificate under the Your Certificates collection of your
Firefox Certificate Manager.
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.
A performance report is available when executing a transaction. The report contains the following
measurements from the browser:
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.
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.
import java.net.MalformedURLException;
import java.net.URL;
@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());
@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.
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
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:
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
HAR tab in the HAR file viewer, you can inspect the "raw" values of the har file as JSON tree:
Private/Incognito mode
In order to open the browser in private mode, each browser requires different desired capabilities.
// ...
// ...
// ...
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.
CDP allows the user to do several things with the Chrome DevTools, we will describe some examples.
@BeforeEach
void setUp() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, Browser.CHROME.browserNa
me());
dc.setCapability("accessKey", <ACCESS_KEY>);
@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
@BeforeEach
void setUp() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, Browser.CHROME.browserNa
me());
dc.setCapability("accessKey", <ACCESS_KEY>);
@Test
void geolocationTest() {
double expectedLatitude = 52.5043;
double expectedLongitude = 13.4501;
// 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/");
@AfterEach
public void tearDown() {
System.out.println("Report URL: "+ ((HasCapabilities) driver).getCapab
ilities().getCapability("reportUrl"));
driver.quit();
}
Network interception
In this example, we will intercept network communication with the browser to show a message that we want.
@BeforeEach
void setUp() throws MalformedURLException {
DesiredCapabilities dc = new DesiredCapabilities();
dc.setCapability(CapabilityType.BROWSER_NAME, Browser.CHROME.browserNa
me());
dc.setCapability("accessKey", <ACCESS_KEY>);
@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");
@AfterEach
public void tearDown() {
System.out.println("Report URL: "+ ((HasCapabilities) driver).getCapab
ilities().getCapability("reportUrl"));
driver.quit();
}
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)
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.
For example, for Chrome on Mac OS Big Sur, we have version 97 available for testing.
If a browser name is grayed out, it means that it is not available for testing.
Browser Versions
Chrome latest 5 versions and beta version.
Choosing a Client
For best behavior we recommend using the latest version of the client for the framework of your choosing:
We do not recommend using deprecated clients like Selenium 2 and Protractor. These clients are not tested
daily and their behavior is unpredictable
We recommend using the latest version of Selenium client to properly work with the latest browsers.
WebdriverIO
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>,
.....
}],
...
}
wdio.conf.js
exports.config = {
......
capabilities: [{
'experitest:accessKey' : <accessKey>,
.....
}],
...
}
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:
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.
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
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:
protractor.conf.js
exports.config = {
......
capabilities: {
'username': <cloudUsername>,
'password': <cloudPassword>,
'projectName': <cloudProject>,
.....
},
...
};
protractor.conf.js
exports.config = {
......
capabilities: {
'accessKey': <accessKey>,
.....
},
...
};
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...)
• 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.
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.
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.
Pressing the "EXTERNAL REPORT" button opens the generated report in a new tab:
NightWatchJS
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:
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.
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
}
}
}
};
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>,
.....
}
}
}
...
}
nightwatch.conf.js
exports.config = {
......
test_settings : {
default : {
......
desiredCapabilities : {
.....
accessKey: <accessKey>,
.....
}
}
}
...
}
Selenium Agent is able to run native scripts with AutoIt. To run a native script use the command:
Please note
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;
import org.junit.Test;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.MalformedURLException;
import java.net.URL;
@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.
• End-to-end tests
• Integration tests
• Unit tests
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.
POST /api/v1/executions
Parameters
"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
Configuration Parameters:
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"
}
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:
"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"
],
"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 /api/v1/executions/{Execution_ID}/status
PUT /api/v1/executions/{executionId}/actions/cancel
The ability to obtain the logs of a run depends on the user type.
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.
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.
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
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"
}
{
"imageVersion": "playwright image version"
}
digitalai.json
"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:
Several API calls are used for Playwright projects. The ability to perform operators on projects depends on
your permissions level:
POST /api/v1/executions
Parameters
GET /api/v1/executions/{Execution_ID}/status
You can cancel a Playwright execution job using its run id.
PUT /api/v1/executions/{executionId}/actions/cancel
{
"status": "ERROR",
"data": {
"User": "Security Error"
},
"code": "FORBIDDEN"
GET /api/v1/executions/{Execution_ID}/logs
The response is a zip file with the logs or an error message if any error occurred.
Introduction
Creating tests for UI based applications using Selenium/Appium libraries have two parts,
• 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.
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.
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
@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());
}
}
public class TestClass2 {
@BeforeClass
public void init() {
// Initialize driver
}
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 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.
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.
package pageobjects;
public abstract class PageBase {
protected <AndroidElement> driver = null;
/**
* 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']
"));
}
/**
* Login
* @param userName
* @param password
*/
public Page login(String userName, String password) {
usernameElement.sendKeys(userName);
passwordElement.sendKeys(password);
loginButtonElement.click();
return HomePage(driver);
}
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(....);
}
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.
• The core strategy is to separate UI Locator logic to Page Objects and Test logic to Test Objects
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,
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.
Now that you are all set, with basics of Parallel test execution. Let's try out a sample to demonstrate these
concepts.
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
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.
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
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.
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.
2. Appium or Selenium Driver is setup using @Beforeclass Annotation. This means that the Driver is set
up on once for a TestNG class.
The test developed using the strategy above will not give reliable results.
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 {
@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']"));
}
}
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.
Listed below are good practices that will go a long way for a successful implementation of parallel execution
of tests.
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.
rd);
driver.findElement(ELEMENTS.LOGIN_BUTTON.getBy(TYPE.ANDROID)).click();
LOGGER.info("Exit eriBankLogin");
}
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.
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.
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.
The code snippet is a Factory class that returns a driver which is static i.e one per class.
public class B {
@Test
public void testB() {
.
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.
Automation tests for Mobile and Web applications are generally achieved using test drivers provided by
libraries like Appium/Selenium.
Parallelism can be achieved at different levels, Let us consider a test suite whose composition looks like the
diagram below.
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.
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.
@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();
....
}
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
If you try to launch device settings (iOS or Android) the application will be blocked from launching.
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.
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:
The purpose of the cleanup purpose is to make sure that the next tester gets a clean device.
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.
Even though remove such accounts, we strongly recommend that you sign out of any account that you
signed into during a test session.
Integrations
Continuous Testing integrates with various Continuous Integration Tools and Frameworks.
• 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.
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 .
Click on Repository
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.
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.
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.
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:
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.
If you signed in using Google or some other Oauth service, simply authorize GitHub in your account.
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
Go to Settings and under Projects click the cogwheel next to the relevant git repository:
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.
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.
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.
From Jenkins main screen, click on create new jobs. Name your project, choose Freestyle project and
click OK.
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.
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.
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
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.
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:
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:
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",
"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"
}
]
Parameters:
Advanced options:
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.
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.
From Jenkins main screen, click on Manage Jenkins → Global Tool Configuration. Look for MSBuild and
expand MSBuild installations.
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.
You will have to restart Jenkins in order for it to be able to access the update list of environment variables.
1. Click on Add build step and choose Execute Batch Command. Add the command:
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
You are all set! Go to the project homepage and click on Build with Parameters and then click on Build.
If you chose our Java Git Project, you will have to specify a build step that invokes a Gradle test task.
You are all set! Go to the project homepage and click on Build with Parameters and click on Build.
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
Depending on the environment that Jenkins operates on (Windows or UNIX), choose either Execute
Windows Batch Command or Execute Shell.
You are all set! Go to the project homepage and click on Build with Parameters and then click on Build.
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:
Depending on the environment that Jenkins operates on (Windows or UNIX), choose either Execute
Windows Batch Command or Execute Shell.
You are all set! Go to the project homepage and click on Build with Parameters and then click on Build.
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.
Head over to Travis CI and click on Sign in with GitHub at the upper right-hand corner.
• 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.
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.
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:
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.
Select your code repository from the options displayed on the screen.
Review your .yml file and add any required tasks. You can click on "Variables" in order to add environment
variables ()
Go to Pipelines and under Library click on "Add" and set your access key and cloud URL as environment
variable:
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.
• 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.
@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 ---");
@AfterClass
public static void tearDownClass() {
System.out.println("--- FINISH : tests from class --- ");
}
Output :
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!
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.
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.
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.
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.
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. If you plan to test a native or hybrid app, upload your app to your project.
2. Fetch your access key.
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.
<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>
repositories {
jcenter()
}
dependencies {
compile 'org.testng:testng:6.10'
}
TestNG is a feature rich framework but to write a very basic test its a simple task.
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>
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'
}
Note: Best practice is to create the Gradle Project/Maven Project using IntelliJ or Eclipse and configure
dependency in build tool.
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
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.
In the above example client is requesting a chrome browser on that an Android Device .
First argument is the appium service and second argument is capabilities object.
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");
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);
}
}
Once the Driver is created, it can be used to Locate the elements in Mobile application or Browser
and test or automate.
2. Upload your application to a project manually by following the documentation in Native Applications
Testing.
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.
import io.appium.java_client.remote.MobileCapabilityType;
import org.testng.annotations.Optional;
import org.testng.annotations.Test;
import utils.SeeTestProperties;
/**
* Sets up the default Desired Capabilities.
*/
protected void initDefaultDesiredCapabilities() {
LOGGER.info("Enter initDefaultDesiredCapabilities");
super.initDefaultDesiredCapabilities();
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);
@Test()
public void firstTest() {
// add the operations and tests.
}
}
a) firstTest function can be added with any functionality you want to test.
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>
</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.
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
Shell
# Create a new folder for WebDriverIO
mkdir webdriverio
cd webdriverio
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')
})
})
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',
timeout: 60000
},
}
Webdriverio Run
Window run
bash
npx wdio run .\wdio.conf.js
Mac run
bash
npx wdio run ./wdio.conf.js
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.
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
})
})
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",
},
}],
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')
})
})
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",
}
},
],
mochaOpts: {
ui: 'bdd',
timeout: 180000
},
}
Webdriver.io Run
To run your tests, run the applicable command in a command line window:
Analytics
Analytics Tools and Frameworks are key for faster availability for data.
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"
Configuration
Elasticsearch integration is configured with the following application.properties entries:
Key Description
elastic.url URL of ElasticSearch instance required.
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.
• Enabled: y/n
• Bulk size.
• Bulk count.
/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.
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.
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.
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"
},
"duration":{
"type":"long"
},
"status":{
"type":"keyword"
},
"success":{
"type":"boolean"
},
"date":{
"type":"date"
},
"hasReport":{
"type":"boolean"
}
}
}
}
}
Prerequisites
A protected application might fail to be uploaded to the cloud if any change has been made to it during the
upload.
No Other parameters other than the mentioned below when working with a protected application.
POST /api/v1/applications/new
Parameters
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.
Upload Application:
For protected applications, make sure that you do not install the app in instrumented mode:
For protected applications, make sure that you do not launch the app in instrumented mode:
Installation
To install the package, run this following command (with sudo permissions):
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
credentials.json Example
{
"cloudUrl" : "https://mycloud.experitest.com",
"accessKey" : "myAccessKey"
}
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
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
• runningType
• deviceQueries
• appUrl
• testAppUrl
Terminology
Our platform provides testers and developers with simplified views that help you easily grasp test executions
which are taking place in your projects
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.
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".
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.
Queued or Running test requests can be canceled using the "Cancel" button.
Permissions:
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)
Similarly, the test can be canceled in Grid view as shown below by clicking the cancel button.
Canceled, Finished or Terminated test requests can be deleted using "Delete" button.
Permissions:
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.
*When the new session starts Development license will be taken and the Mobile Execution license will be
released.
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).
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.
To learn how to develop, create and run test plans, please visit the resources below:
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);
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
},
..
..
}
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
Capabilities setting
// Android
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.eriba
nk/com.experitest.ExperiBank.LoginActivity");
// iOS
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.Exper
iBank");
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
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:
// iOS
dc.setCapability(MobileCapabilityType.APP, "cloud:com.experitest.Exper
iBank");
3. In the capabilities, make sure to specify the correct app package, app activity or bundle id:
// iOS
dc.setCapability(IOSMobileCapabilityType.BUNDLE_ID, "com.experitest.Ex
periBank");
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.
Code Example
//Add this capability in order to disable reports & get faster execution times
dc.setCapability("generateReport", false);
AndroidDriver driver = new AndroidDriver(new URL("<server>"), dc);
As a consequence, there are some behavioral changes, specifically in Password Fields and Security
Popups.
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),
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.
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]");
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
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:
protractor.conf.js
exports.config = {
..
..
jasmineNodeOpts: {
defaultTimeoutInterval: 2500000
},
..
..
}
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.
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.
Once you have obtained the access key, add it to the Desired Capabilities as shown in the code snippets
below in different languages.
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: {
server_url: '<server>',
}
},
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.
Once the Access Key reset is successful, new Access Key can be retrieved from the 'Get Access Key'
feature as shown above.
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.
• OS - iOS/Android
• Phone Platform - Phone/Tablet
• App Type - Native/Web
• Version - Available versions
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.
Test Execution
To execute a test, click RUN TEST.
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.
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).
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
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
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.
• Chrome
• Edge
• Firefox
• Safari
Notification Bar
The notification bar allows fast access in real time to queued and running.
Queued Tests
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.
The View All link will redirect you to the Execution page (list view).
Running Tests
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.
1) Test name
4) OS icon and version for mobile tests / Browser name and version for desktop tests
UI Actions
• Test View
• Project Settings
• Transaction View
• Dashboard
Test View
• Filters
• Date range
• Delete tests
• Export
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:
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:
Sections:
Header:
"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:
date
any other
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
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.
Save changes Save current filter set; if it hasn't been saved previously will ask for a name for the set.
Button Action
• Contains any alphanumeric character and space - other characters aren't allowed.
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:
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,
You can remove any of the items using the "x" button.
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:
You can select or deselect tests with the checkbox in the header area:
• Adjust filter for desired tests to delete, for example, Status = "Incomplete" and specific date range.
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.
If you are a Cloud Administrator, not only do have access to all the registered projects, you can also:
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:
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.
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
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.
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.
To expand the group and see the transaction detail, click on the button:
By default the grouping key is sorted ascending, you can invert clicking in the grouping panel:
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.
Filters
To filter records you can add new items in the filter panel. To open the panel click the "Filters" button:
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.
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.)
Transaction Report
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.
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 inspect the raw values, click the HAR tab. The values are displayed in a JSON tree.
Dashboard
Reporting Dashboard allows Admins or Users to view the summary of tests run.
• Project Dashboard
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.
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:
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:
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.
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.
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.
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.
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)
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.
Every time you run an automated test on the Continuous Testing cloud platform, a shareable HTML report is
generated automatically.
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.
The best way is to print the report URL and report ID in the teardown stage of the test.
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
out the command. The screenshots add a visual dimension that really helps you understand the cause
the of failures if such occur.
• 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.
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
Paramater Description
%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
Only Filter
{
"filter": [{"property": "os.version", "operator": "=", "value": "12.0"}
]
}
Example
...
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:
Latest version
Input
Example:
• Filter:
◦ Application name: "Banking Self-Care"
◦ Device OS: "Android"
• Comparison targets:
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:
7.0 110
7.0 105
7.0 107
7.0 99
6.9 80
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.
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.
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").
Examples:
{
"filter": [ "appName", "=", "com.experitest.ExperiBank" ],
"baseKey": "appVersion"
"baseKeyValue": "7.0.7",
"compareCount": 5,
"comparisonTargets": [
{
"name": "EriBank Transaction Withdrawn",
"measure": "maxMem",
"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>
} ...
]
Property Notes
name Transaction name.
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":
6.9 Inquiry 92
6.9 Inquiry 90
6.8 Inquiry 87
6.8 Deposit 95
Response contains:{ "name: "Inquiry", … "prevKeyCount": 2, ... },{ "name: "Deposit", … "prevKeyCount":
1, ... }, ...
• "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
• Filter containing request filter plus previous base key values found ("previous versions")
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;
@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());
}
}
}
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;
@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());
}
}
}
Reporting Data
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.
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".
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.
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 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
// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\
java', include: '*.jar')
}
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");
@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)
@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.
// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\java
', include: '*.jar')
}
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;
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");
@After
public void tearDown() {
System.out.println(">>>>>> Before closing driver");
driverAndroid.quit();
driverAndroid = null;
System.out.println(">>>>>> Reports generated");
}
Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}
// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\
java', include: '*.jar')
}
@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;
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");
@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.
This will call the tearDown right after the status is sent.
Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}
JUnit5
// Appium Driver
compile group: 'io.appium', name: 'java-client', version: '5.0.4'
compile fileTree(dir: '<seeTest Installation folder>\\clients\\appium\\
java', include: '*.jar')
}
@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;
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");
Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}
Java Support
This section details how Java is supported in Test Execution.
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
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
//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>
<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
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";
...
Setup Driver
@Before
public void setup(){
System.out.println(">>>>>> I'm in Setup");
Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}
@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";
...
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);
}
@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.
This will call the tearDown right after the status is sent.
Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}
3.3 JUnit5
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";
...
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");
}
Test method
@Test
public void dividedByZero() {
System.out.println(">>>>>> I'm in method divided by zero");
int e = 1 / 0;
}
3.4 TestNG
</suite>
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";
...
Setup Driver
@BeforeMethod
public void setup(){
System.out.println(">>>>>> I'm in Setup");
String name = testInfo.getTestMethod().get().getName();
Logger.setLevel(Level.DEBUG);
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:
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
}
@BeforeMethod
public void setup(Method method){
@Test
public void simpleTest() {
@AfterMethod
public void tearDown() {
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
}
managerPublisher.addProperty("key1", "value1");
managerPublisher.addProperty("test-version", "24");
managerPublisher.addReportFolder(new File("/path/to/file"));
JUnit 4
We provide you with Native integration into JUnit 4 testing framework.
Getting Started
To integrate JUnit into your test:
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.*;
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
}
@Rule
public TestName testName = new TestName();
@Before
public void setup() {
@Test
public void simpleTest() {
@After
public void tearDown() {
Optional Configuration
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
Some of the endpoints use URL parameters. Make sure you are familiar with how to use it with 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.
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.
Basic Authentication
Access Key
For additional information about generating access keys in Continuous Testing Cloud, see Rest API - Keys.
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>
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
Flow #1:
The client waits until the file is ready then grabs it.
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
databaseLog PG's log files (latest <=10 MB), same rules as above.
GET /reporter/api/supportData/options
Response
Response Status: 200 OK[ {
"config": true,
"logs": true,
"database": false,
"databaseConfig": true,
"databaseLog": true
}]
POST /reporter/api/supportData/prepare
JSON parameter
logs Boolean Yes Reporter's database's data, true when pg_dump utility is available.
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
}]
POST /reporter/api/supportData/start
JSON parameter
logs Boolean Yes Reporter's database's data, true when pg_dump utility is available.
databaseLog Boolean Yes PG's log files (latest <=10 MB), same rules as above.
GET /reporter/api/supportData/status
Return the current status of the support file preparation, properties are::
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 /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;
@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 {
responseInputStream = Unirest.get(url)
.basicAuth(user, password)
.header("content-type", "application/json")
.asBinary();
} 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();
}
}
private void writeToFile(String destination) {
InputStream inputStream = responseInputStream.getRawBody();
try {
FileOutputStream fileOutputStream = new FileOutputStream(destinatio
n);
} catch (IOException e) {
e.printStackTrace();
}
}
}
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 /reporter/api/transactions/{ids}
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",
Response
"attachmentList": []
}
Example: /api/transactions/3,4,23
DELETE /reporter/api/transactions/{ids}
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
Response
Response Status: 200 OK{
"id": 56,
"name": "newTestViewsGroup",
"byKey": "date",
"byKeyDesc": true,
"groupByKey1": "device.os",
"groupByKey2": "device.version",
"filter": [],
"keys": [
"date",
"app"
Response
],
"createdBy": "admin"
}
Downloads the HAR file attached to the transaction id received as the path parameter.
GET /reporter/api/transactions/{id}/har
Parameters
Downloads the video file attached to the transaction id received as the path parameter.
GET /reporter/api/transactions/{id}/video
Parameters
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;
int from = 1;
int to = 1000;
int step = 100;
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();
}
}
fileName = disposition.get(0).split("=")[1];
}
fileName = "/tmp/" + fileName;
saveToFile(response.getBody(), fileName);
Assert.assertTrue(new File(fileName).exists());
}
}
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 /reporter/api/testView
Response
Response Status: 200 OK[
{
"name": "Android OS",
"id": 54,
"createdBy": "admin",
"byKey": "date"
},
{
"name": "Default",
"id": 50,
"byKey": "date",
"showInDashboard": true
},
...
]
POST /reporter/api/testView
JSON parameter
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": [
Response
"date",
"app"
],
"createdBy": "admin"
}
• This API is available for all user roles with permission to access the desired project.
PUT /reporter/api/testView
JSON parameter
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"
}
• This API is available for all user roles with permission to access the desired project.
POST /reporter/api/testView/list
JSON parameter
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"
}
]
}
• This API is available for all user roles with permission to access the desired project.
GET /reporter/api/testView/{id}
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"
}
• This API is available for all user roles with permission to access the desired project.
GET /reporter/api/testView/{id}/summary
Parameters
Response
Response Status: 200 OK{
"data": [
{
"passedCount": 2,
"failedCount": 0,
"incompleteCount": 0,
"skippedCount": 0,
"_count_": 2
}
]
• This API is available for all user roles with permission to access the desired project.
DELETE /reporter/api/testView/{id}
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;
import com.mashape.unirest.http.Unirest;
import static org.junit.Assert.fail;
import com.mashape.unirest.http.HttpResponse;
import java.io.InputStream;
@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" +
} 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)
.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();
}
}
//************************************************************************
****************************************//
@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();
}
}
}
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.
API Calls
Get All Projects
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
}
...
]
PUT /reporter/api/projects/{oldName}/{newName}
Download all the attachments of a given test under a specific project as a zip file.
Note that projectId is the Reporter's project ID, not the Cloud's.
GET /reporter/api/{projectId}/{testId}/attachments
Download all the attachments of a given test under a specific project as a zip file.
GET /reporter/api/{projectName}/{testId}/attachments-name
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>
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;
@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();
}
}
@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();
} 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")
.asBinary();
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Some of the endpoints use URL parameters. Make sure you are familiar with how to use it with Postman.
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.
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,
Response
"filePath": "/attachments/1/2020-01-09/2795/testreportfadfdf1b69bf185a825a5aeb556d1d7876785376898260938183611384077293385164/
index.html",
"captionName": "",
"type": "zip",
"size": 4311336
}
],
"hasReport": true
}]
• 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
• 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
{
"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,
"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,
"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,
"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
}
]
}
]
}
• 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}
POST /reporter/api/tests/list?projectName={projectName}
{projectId} - Project ID
JSON parameter
searchValue String No Return test views which name contains this value,case insensitive
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",
Response
"date": "2019-10-22"
},
...
]
• 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}
{projectId} - Project ID
JSON parameter
pivotBy List No string array which can contain "success" and/or "status".:
• All resulting rows include the column "count" along "pivotBy" columns if any.
Response
Response Status: 200 OK[ {
"count": 1,
"data": [
{
"_count_": 2795
}
]
}]
JSON parameter
• 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}
{projectId} - Project ID
Response
GET /reporter/api/tests/csv?request={TestRequest}
{projectId} - Project ID
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}
{projectId} - Project ID
Body parameter
Download Attachments
Download all the attachments of testId as a zip file.
• This API is available for all user roles with permission to access the desired project.
GET /reporter/api/{testId}/attachments
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;
@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
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 {
} 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 {
} 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)
.header("content-type", "application/json")
.asBinary();
} catch (Exception e) {
e.printStackTrace();
}
}
private void writeToFile(String destination) {
InputStream inputStream = responseInputStream.getRawBody();
try {
FileOutputStream fileOutputStream = new FileOutputStream(destinatio
n);
} catch (IOException e) {
e.printStackTrace();
}
}
• This API is available for all user roles with permission to access the desired project.
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;
@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);
}
class ContentRange {
Long start, end, total;
public ContentRange(String contentRange) {
String[] range = contentRange.split("[ -/]");
this.start = Long.valueOf(range[1]);
this.end = Long.valueOf(range[2]);
this.total = Long.valueOf(range[3]);
}
}
}
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.
GET /reporter/api/keys
Response
Response Status: 200 OK[
{
"id": 13,
"name": "browserName",
"index": 11,
Response
"dataType": "STRING",
"valueCount": 0,
"protected": true
},
...
]
POST /reporter/api/keys
JSON parameter
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}.
DELETE /reporter/api/keys/{id}
Example: /reporter/api/keys/3,4,23
You can retrieve the key ID using the Get Keys Rest API.
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>
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
@Test
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();
}
}
}
Video Report
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.
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().
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:
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.
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.
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.
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
• 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
• 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)
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.
In the generated report you can swap between related tests by clicking the 'Device' field at the top left of the
report.
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;
@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();
}
import java.util.UUID;
@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
@AfterEach
public void afterEach(){
client1.generateReport(false);
client2.generateReport(false);
client1.releaseClient();
client2.releaseClient();
}
}
Once you have expanded the utilities console, click on the Report tab.
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.
To add another action group, click the plus icon. Name your group and continue testing.
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.
Performance Report
A performance report is available when executing a transaction. The report contains the following
measurements:
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.
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.
SeeTestReporter is a report analytics platform that consolidates test report and allows you to analyze test
cases.
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.
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).
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.
• SeeTest Grid
• Appium Grid
• Appium OSS
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.
• Click Add.
• Under Property Name enter attach.crash.log.to.report.
• Under Property Value enter True.
• Click Save ( ).
The device crash log is attached with the other attachment files.
• Android: device_crash.log.
• iOS: deviceCrashLogs.zip.
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