Simple Java REPL for controlling mobile apps through Appium.

Java REPL on Github

Get Started

Introduction

REPL is a simple interactive language shell that takes single user input in the form of an expression, evaluates them and return the results to user on the same shell. Many languages and interpreters have a similar mechanism, like Python, Ruby, Lisp, Scheme, etc.

Appium REPL is a great place to start experimenting with Appium, there are advantages to using the REPL: it's simple, and should work without any complex installation or configuration.

Actually exists some Appium REPL implementations such as:

Appium Java REPL is built on top of Java-REPL (by Albert Latacz) implementation (you can play with it online).

Try It Out

Download the latest version (requires JDK 1.8 or newer) and install Appium

Don't have a AUT?, don't worry, be happy. There are some pre-compiled test apps available on the Appium Java-client project.

Launching the console

java -jar appium-repl-X-X-X.jar

This will open the Appium Java REPL console.

import static com.mobilebox.repl.Appium.*;
----------------------------
 :::- Appium Java REPL -:::

Type import static com.mobilebox.repl.Appium.*;

Type help() for more options.
-----------------------------

Welcome to JavaREPL version null (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144)
Type expression to evaluate, :help for more options or press tab to auto-complete.
Connected to local instance at http://localhost:45800
java>

Now you can type some Java code and then press Return/Enter. JavaREPL evaluates what you typed and returns the result:

java> System.out.println("Ireneo Funes")
Ireneo Funes
java>

If this doesn't work try to run pointing directly to java executable within JDK, like so:

$[PATH_TO_JDK]/bin/java -jar appium-repl-X-X-X.jar

Console options

All the console options starts with colon : and everything else is considered as Java expression. Type the command :help in order to get the console options. To exit the interactive session, type :quit followed by the return or enter key.

Start sessions

First we'll need to start the Appium server. Open a new terminal a execute:

appium --session-override --command-timeout=1200

Or we can use the Appium GUI. Just click the Launch button in the top right-hand corner of the window. After clicking it, you should see some debug information in the center console. Assuming there are no errors or exceptions, it should be up ready to receive a session.

Console Appium commands

Appium Java REPL comes with some useful commands at the REPL-prompt: such as: find an element, get source, get current activity, etc.

In order to use Appium on the console, we need imports all the static member of Appium class. Type:

import static com.mobilebox.repl.Appium.*;

Now we can start an Appium session from the console or Appium GUI, after it start you can interact with the AUT.

Appium Java REPL come with commands for Android and iOS platforms. You can print all commands available for both platforms through the help() command:

help()
------------------------------------
::-  Available Commands for Appium  -::
------------------------------------

---> Command: user_home
---> Description: Prints the user home directory.
---> Parameters: []
---> Return:

---> Command: my_name
---> Description: Prints my name
---> Parameters: []
---> Return:

---> Command: ios
---> Description: Prints all commands available for iOS.
---> Parameters: []
---> Return:

---> Command: android
---> Description: Prints all commands available especifc for Android.
---> Parameters: []
---> Return:

---> Command: appium
---> Description: Prints all commands available for Android and iOS.
---> Parameters: []
---> Return:

---> Command: android_device
---> Description: Prints all commands available for Android Device.
---> Parameters: []
---> Return:

---> Command: exit
---> Description: Quit Appium REPL
---> Parameters: []
---> Return:

---> Command: help
---> Description: Prints this help.
---> Parameters: []
---> Return:

Android and iOS commands

start

Start an Appium session from appium.txt file. You can specify the necessary configurations of your app through some capabilities by storing them in a file called ${user.home}/appium.txt (this gets resolved by 'user.home' system property, you can use the user_home() to get the user home directory):

android.start()
ios.start

Here's what appium.txt looks like for Android:

platform.name=android
device.name=S5Mini
command.timeout=9000
udid=3204a5a5f0d691efsd
app=/Applications/ApiDemos-debug.apk
appium.server=http://127.0.0.1:4723/wd/hub

Appium Java REPL does support "hot reload" for appium.txt file, this mean that automatically reload the appium.txt file if it is modified on the filesystem.

id

Find element by ID:

android.id("id")
ios.id("id")

Parameters description


id: The element id.
Returns an AndroidElement


ids

Find elements by ID:

android.ids("id")
ios.ids("id")

Parameters description


id: The element id.
Returns a list of AndroidElement. This list is empty when no elements are found.


className

Find element by class name:

android.className("className")
ios.className("className")

Parameters description


id: The element id.
Returns an AndroidElement


classNames

Find elements by class name:

android.classNames("className")
ios.classNames("className")

Parameters description


id: The element id.
Returns a list of AndroidElement. This list is empty when no elements are found.


xpath

Find element by xpath:

android.xpath("xpath")
ios.xpath("xpath")

Parameters description


xpath: A Xpath expression
Returns an AndroidElement


xpaths

Find elements by xpath:

android.xpaths("xpath")
ios.xpaths("xpath")

Parameters description


xpath: A Xpath expression
Returns a list of AndroidElement. This list is empty when no elements are found.


back

Move back:

android.back()
ios.back()

orientation

Prints the current orientation of a mobile devices desktop:

android.orientation()
ios.orientation()

capabilities

Prints the capabilities of the current driver:

android.capabilities()
ios.capabilities()

source

Retrieves a XML view of the current screen:

android.source()
ios.source()

session

Prints the ID of this session:

android.session()
ios.session()

strings

Prints all defined Strings from an app for the default language:

android.strings()
ios.strings()

time

Prints the device date and time for both iOS and Android devices:

android.time()
ios.time()

context

Prints the current context:

android.context()
ios.context()

contextHandles

Prints the available contexts:

android.contextHandles()
ios.contextHandles()

context

Switch to a new context:

android.context("NATIVE_APP")
ios.context("NATIVE_APP")

Parameters description


context: The context name


hideKeyboard

Hides the keyboard if it is showing:

android.hideKeyboard()
ios.hideKeyboard()

Android commands

start

Start an Appium session for an Andorid app:

android.start("device name", "udid", "app path", "appium server url","command timeout")

Parameters description


deviceName: The kind of mobile device or emulator to use

udid: Unique device identifier of the connected physical device

app: The absolute local path or remote http URL to an .apk

server: The Appium server URL

timeout: How long (in seconds) Appium will wait for a new command from the client before assuming the client quit and ending the session.


text

Find element by text:

android.text("My Text")

Parameters description


text: The visible text displayed in a widget (for example, the text label to launch an app).
Returns an AndroidElement


texts

Find elements by text:

android.texts("My Text")

Parameters description


text: The visible text displayed in a widget (for example, the text label to launch an app).
Returns a list of AndroidElement. This list is empty when no elements are found.


textContain

Find element by text that contains a given text:

android.textContain("My Text")

Parameters description


text: The visible text displayed in a widget (for example, the text label to launch an app). The text for the element must match exactly with the string in your input argument. Matching is case-sensitive.
Returns an AndroidElement


textContains

Find elements by text that contains a given text:

android.textContains("My Text")

Parameters description


text: The visible text displayed in a widget (for example, the text label to launch an app). The text for the element must match exactly with the string in your input argument. Matching is case-sensitive.
Returns a list of AndroidElement. This list is empty when no elements are found.


textContains

Find element by an UISelector expression. Chaining the search criteria on 'new UiSelector()':

android.uiSelector("className('android.widget.RelativeLayout').enabled(true).instance(0);")

Parameters description


selector: The UISelector expression. E.g: className('android.widget.RelativeLayout').enabled(true).instance(0);
Returns an AndroidElement


uiSelector

Find element by an UISelector expression. Chaining the search criteria on 'new UiSelector()':

android.uiSelector("className('android.widget.RelativeLayout').enabled(true).instance(0);")

Parameters description


selector: The UISelector expression. E.g: className('android.widget.RelativeLayout').enabled(true).instance(0);
Returns an AndroidElement


uiSelectors

Find elements by an UISelector expression. Chaining the search criteria on 'new UiSelector()':

android.uiSelector("className('android.widget.RelativeLayout').enabled(true).instance(0);")

Parameters description


selector: The UISelector expression. E.g: className('android.widget.RelativeLayout').enabled(true).instance(0);
Returns a list of AndroidElement. This list is empty when no elements are found.


activity

Prints the current activity being run on the mobile device:

android.activity()

openNotifications

Open the notification shade, on Android devices:

android.openNotifications()

closeApp

Close the app which was provided in the capabilities at session creation:

android.closeApp()

launchApp

Launch the app which was provided in the capabilities at session creation:

android.launchApp()

appInfo

Prints detailed information about the app:

android.appInfo()

Android Device commands

Appium Java REPL also provides some commands for control an Android device or emulator from outside of Appium code. With these commands you can takes screenshots, set brightness, retrieves devices properties, etc. For provide these functions Appium Java REPL uses an ADB client implemented in pure Java: JADB

device

You can get an instance of an Andorid device:

device = android.device()

Returns an AndroidDeviceCommands


brightness

Set brightness:

device.brightness(255)

Parameters description


brightness: Value into the range [0,255]


serial

Prints the Android device serial:

device.serial()

call

Sends the KEYCODE_CALL KeyEvent:

device.call()

volumenUp

Sends the KEYCODE_VOLUME_UP KeyEvent:

device.volumenUp()

volumenDown

Sends the KEYCODE_VOLUME_DOWN KeyEvent:

device.volumenDown()

version

Prints the device Android version:

device.version()

vm

Prints device information related to Dalvik VM:

device.vm()

dhcp

Prints device information related to DHCP:

device.dhcp()

gsm

Prints device information related to GSM:

device.gsm()

productInfo

Prints device information related to product:

device.productInfo()

remove

Remove a file:

device.remove("file path")

Parameters description


filePath: The file path to remove


packages

Prints all packages on the device:

device.packages()

battery

Prints battery status:

device.battery()

disk

Prints disk space usage:

device.disk()

shellPrograms

Prints a list of all the available shell programs:

device.shellPrograms()

screenshot

Take and save a device screenshot to file:

device.screenshot("file path")

Parameters description


filePath: Full path to file


shell

Execute a shell command in the emulator/device instance and then exits the remote shell:

device.executeShell("pm", "list", "packages")

Parameters description


command: A shell command

args: Shell commands arguments


prop

Given the name of a system environment variable,returns its value for this device:

device.prop("property")

Parameters description


property: The property name


iOS commands

start

Start an Appium session for an iOS app:

ios.start("device name", "udid", "app path", "appium server url","command timeout")

Parameters description


deviceName: The kind of mobile device or emulator to use

udid: Unique device identifier of the connected physical device

app: The absolute local path or remote http URL to an .ipa (or .app for simulators)

server: The Appium server URL

timeout: How long (in seconds) Appium will wait for a new command from the client before assuming the client quit and ending the session.


Scripting

Since the v1.0.0 version, Appium Java REPL has a few functionalities in which scripts can be used. Appium Java REPL use Nashorn Javascript Engine for scripting.

Appium Java REPL exposes objects that we can use in our scripts. Let's start by briefly looking at what type of information we are allowed to use in our scripts.

Commands available during script execution

During different operations, Appium Java REPL allows us to use different commands in our scripts. To develop a script that fits our use case, we should be familiar with those commands.

Start a session with a custom DesiredCapabilities

Start a new Appium session given Nashorn script file with DesiredCapabilities:

android.start("capabilities.js")
ios.start("capabilities.js")

Parameters description


filePath: The script full path

Here's what capabilities.js looks like for Android:

//The main method providing an entry point for the Appium JAVA REPL.
function main() {
  var DesiredCapabilities = Java.type("org.openqa.selenium.remote.DesiredCapabilities")
  var caps = new DesiredCapabilities();
  caps.setCapability("appiumServer","http://127.0.0.1:4723/wd/hub");
  caps.setCapability("udid", "ID");
  caps.setCapability("deviceName", "NAME");
  caps.setCapability("newCommandTimeout", "900000");
  caps.setCapability("app", "ApiDemos-debug.apk");
  caps.setCapability("platformName","android");
  caps.setCapability("appActivity","io.appium.android.apis.ApiDemos");
  caps.setCapability("appPackage","io.appium.android.apis");
  return caps;
}

Interact with the application under test

You can execute a nashorn script that use some of the Appium JAVA REPL commands:

android.run("script.js")
ios.run("script.js")

Parameters description


filePath: The script full path

Here's what script.js looks like:

//The REPL object.
var $;

//The main method providing an entry point for the Appium JAVA REPL scripting capabilities.
function main(repl){
    $ = repl;
    iteration();
    locators();
    appInfo();
    moreinfo();
    deviceActions();
}

//Access to REPL commands.
function iteration(){
  var elements = $.ids("android:id/text1");
  for each (element in elements) {
    element.click();
    $.back();
  }
}

//Some device actions through JADB.
function deviceActions(){
  var Device = $.device();
  Device.brightness(100);
  Device.call();
  Device.volumenUp();
  Device.volumenDown();

  print(Device.version());
  print(Device.vm());
  print(Device.dhcp());
  print(Device.gsm());
  print(Device.net());
}

function locators(){
  print($.className("android.widget.TextView").getText());
  print($.id("android:id/text1").getText());
  print($.xpath('//*[@text="NFC"]').getText());

  //List
  print($.ids("android:id/text1").size());
  print($.classNames("android.widget.TextView").size());
  print($.xpaths('//*[@text="NFC"]').size());

  //UISelector
  print($.text("App"));
  print($.texts("App").size());
  print($.textContain("Te"));
  print($.textContains("Te").size());
}

//Application under test info through APKInspector.
function appInfo(){
  print($.appInfo());
}

//Some Appium commands.
function moreinfo(){
  print($.activity());
  print($.orientation());
  print($.capabilities());
  print($.session());
  print($.source());
  print($.time());
  print($.context());
  print($.contextHandles());
  print($.sessionDetails());
}

Vanilla mode

Start a custom session

Of course, you can use Appium Java REPL without use the built-in commands that come with it. This example shows you how to setup the driver and launch the app under test:

import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.remote.MobileCapabilityType;
import io.appium.java_client.remote.MobilePlatform;
import io.appium.java_client.android.AndroidDriver;
import java.net.URL;

capabilities = new DesiredCapabilities();
capabilities.setCapability(MobileCapabilityType.PLATFORM_NAME,MobilePlatform.ANDROID);
capabilities.setCapability(MobileCapabilityType.APP, "/Applications/ApiDemos-debug.apk");
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);