Small UI automation library for Android built on top of ADB calls. It provides API to write readable and dynamic tests on Clojure that could be run inside REPL or from command line.
pico-automator is inspired by maestro and allows to write UI tests on Clojure. The choice of Clojure allows to use a lightweight IDE (VS Code, Emacs, Vim and etc.) and REPL when writing tests.
- Create file
example.clj
with the code below:
(start-flow
"Sample Flow"
(fn [automator]
(-> automator
(launch "org.wikipedia")
(tap-on {:text "Search Wikipedia"})
(assert-visible {:text "Recent searches:"})
(input-text "Monad")
(assert-visible {:text "Monad (functional programming)"}))))
- Download
pico-automator.jar
from Release page and run the test (in order to work, pico-automator requires Java 11 and ADB binary accessible from the PATH variable)
java -jar pico-automator.jar example.clj
There are 2 ways to run tests with pico-automator:
- With standalone CLI application
pico-automator.jar
- With Clojure REPL
The usage of CLI application is described in Quickstart section.
The Functional API for pico-automator is provided by pico-automator-clojure project, that can be used as a dependency inside deps.edn
file. pico-automator-clojure is available in JitPack maven repository here.
- Setup
deps.edn
file in the directory:
{:paths ["."]
:mvn/repos
{"jitpack" {:url "https://jitpack.io/"}}
:deps
{com.github.aivanovski/pico-automator-clojure {:mvn/version "X.X.X"}}
:aliases
{:repl-server {:extra-deps {nrepl/nrepl {:mvn/version "1.0.0"}
cider/cider-nrepl {:mvn/version "0.37.0"}}
:main-opts ["--main" "nrepl.cmdline"
"--middleware" "[cider.nrepl/cider-middleware]"]}}}
- Start the REPL server:
clojure -M:repl-server
- Create file with the test:
(ns wikipedia-search
(:require [picoautomator.core :refer :all]))
(defn -main
[& args]
(start-flow
"Search Wikipedia"
(fn [automator]
(-> automator
(launch "org.wikipedia")
... ; Implement your test steps here
))))
- Connect to the REPL and run it.
The example could be found here
The api namespace is picoautomator.core
.
Function start-flow
starts the test:
(start-flow
"Test Flow"
(fn [automator]
(-> automator
(launch "org.wikipedia"))))
The application could be launched with launch
function:
(-> automator
(launch "org.wikipedia")) ;; specify your application id
Functions that interact with views (for example tap-on
, assert-visible
, input-text
and etc.) require the view paramaters to be specified as follows.
By view id:
{:id "viewId"} ;; corresponds to R.id.viewId in android application
By exact text:
{:text "Search Wikipedia"}
By content description:
{:content-desc "search-wikipedia"}
By patricular text matching:
{:contains-text "Wikipedia"}
To assert whether an element is visbile or not visible following function could be used:
(-> automator
(assert-visible {:id "viewId"})
(assert-not-visible {:id "viewId"}))
In order to click/tap on view:
(-> automator
(tap-on {:id "viewId"})
(long-tap-on {:id "viewId"}))
(-> automator
;; Inputs text regardless of whether any text field is currently focused or not
(input-text "Text")
;; Taps on view specified by view-parameters and then inputs text
(input-text "Text" {:id "inputField"}))
In order to finish test successfully or with a failure depend on some extenal condition, functions complete
and fail
could be used:
(-> automator
;; Finishes test successfully and prints the message
(complete "The test is finished successfully")
;; Finishes test with an error and prints the message
(fail "The test is failed"))
(-> automator
;; Checks if view is visible and returns true of false
(visible? {:id "viewId"})
;; Stops test execution for 5 seconds
(sleep {:seconds 5})
;; Wait until view became visible on the screen for 15 seconds and checks every second
(wait-until {:text "viewId"} {:seconds 15} {:seconds 1})
;; Returns object that represents view tree on the screen
(ui-tree))
More examples could be found here