Skip to content

Latest commit

 

History

History
287 lines (211 loc) · 9.79 KB

File metadata and controls

287 lines (211 loc) · 9.79 KB

Documentation

  • find_elements returns an empty array [] when no elements are found.
  • button(int), textfield(int) use xpath so 1 is the first button, 2 the second etc. 0 is invalid.

--

Example use of Appium's mobile gesture.

@driver.execute_script 'mobile: tap', :x => 0, :y => 500

console.rb uses some code from simple_test.rb and is released under the same license as Appium. The Accessibility Inspector is helpful for discovering button names and textfield values.

Long click on an ImageView in Android.

last_image = find_elements(:tag_name, :ImageView).last
mobile(:longClick, element: last_image.ref)

Rotate examples.

driver.rotate :landscape
driver.rotate :portrait
  • status["value"]["build"]["revision"] Discover the Appium rev running on the server.
  • driver.keyboard.send_keys "msg" Sends keys to currently active element

generic

  • source Prints a JSON view of the current page.
  • page Prints the content descriptions and text values on the current page.
  • page_class Prints the classes found on the current page.
  • (Element) find(value) Returns the first element that contains value.
  • (Element) finds(value) Returns all elements containing value (iOS only for now).
  • (Element) name(name) Returns the first element containing name. Android name is the content description. iOS uses accessibility label with a fallback to text.
  • (Array<Element>) names(name) Returns all elements containing name.
  • (Element) text(text) Returns the first element containing text.
  • (Array<Element>) texts(text) Returns all elements containing text.
  • current_app Returns information about the current app. Android only.

--

alert

  1. (void) alert_accept Accept the alert.
  2. (String) alert_accept_text Get the text of the alert's accept button.
  3. (void) alert_click(value) iOS only Tap the alert button identified by value.
  4. (void) alert_dismiss Dismiss the alert.
  5. (String) alert_dismiss_text Get the text of the alert's dismiss button.
  6. (String) alert_text Get the alert message text.

button

  1. (Button) button(index) Find a button by index.
  2. (Button) button(text, number = 0) Find a button by text and optionally number.
  3. (Button) button_include(text) Get the first button that includes text.
  4. (Array<String>, Array<Buttons>) buttons(text = nil) Get an array of button texts or button elements if text is provided.
  5. (Array<Button>) buttons_include(text) Get all buttons that include text.
  6. (Button) first_button Get the first button element.
  7. (Button) last_button Get the last button element.

textfield

  1. (Textfield) textfield(index) Find a textfield by index.
  2. (Array<Textfield>) e_textfields Get an array of textfield elements.
  3. (Textfield) first_textfield Get the first textfield element.
  4. (Textfield) last_textfield Get the last textfield element.
  5. (Textfield) textfield(text) Get the first textfield that matches text.
  6. (Textfield) textfield_include(text) Get the first textfield that includes text.
  7. (Array<String>) textfields Get an array of textfield texts.

text

The Static Text methods have been prefixed with s_ to avoid conflicting with the generic text methods.

  1. (Text) s_text(index) Find a text by index.
  2. (Array<Text>) s_e_texts Get an array of text elements.
  3. (Text) first_s_text Get the first text element.
  4. (Text) last_s_text Get the last text element.
  5. (Text) s_text(text) Get the first element that matches text.
  6. (Text) s_text_include(text) Get the first textfield that includes text.
  7. (Array<String>) s_texts Get an array of text texts.

window

  1. (Object) window_size Get the window's size.

--

e.name # button, text
e.value # secure, textfield
e.type 'some text' # type text into textfield
e.clear # clear textfield
e.tag_name # calls .type (patch.rb)
e.text
e.size
e.location
e.rel_location
e.click
e.send_keys 'keys to send'
e.set_value 'value to set' # ruby_console specific
e.displayed? # true or false depending if the element is visible
e.selected? # is the tab selected?
e.attribute('checked') # is the checkbox checked?


# alert example without helper methods
alert = $driver.switch_to.alert
alert.text
alert.accept
alert.dismiss

# Secure textfield example.
#
# Find using default value
s = textfield 'Password'
# Enter password
s.send_keys 'hello'
# Check value
s.value == ios_password('hello'.length)

routing.js lists not yet implemented end points.

--

Driver

start_driver will restart the driver.

x will quit the driver and exit Pry.

execute_script calls $driver.execute_script

find_element calls $driver.find_element

find_elements calls $driver.find_elements

mobile :swipe, endX: 100, endY: 100, duration: 0.01 calls $driver.execute_script 'mobile: swipe', endX: 100, endY: 100, duration: 0.01

no_wait will set implicit wait to 0. $driver.manage.timeouts.implicit_wait = 0

set_wait will set implicit wait to default 30 seconds. $driver.manage.timeouts.implicit_wait = 30

set_wait(timeout_seconds) will set implicit wait to desired timeout. $driver.manage.timeouts.implicit_wait = timeout

.click to tap an element. .send_keys to type on an element.

Raw UIAutomation

execute_script "au.lookup('button')[0].tap()" is the same as execute_script 'UIATarget.localTarget().frontMostApp().buttons()[0].tap()'

See app.js for more au methods. Note that raw UIAutomation commands are not officially supported.

Advanced au.

In this example we lookup two tags, combine the results, wrap with $, and then return the elements.

s = %(
var t = au.lookup('textfield');
var s = au.lookup('secure');
var r = $(t.concat(s));
au._returnElems(r);
)

execute_script s

XPath

See #194 for details.

find_element  :xpath, 'button'
find_elements :xpath, 'button'

find_element  :xpath, 'button[@name="Sign In"]'
find_elements :xpath, 'button[@name="Sign In"]'

find_element  :xpath, 'button[contains(@name, "Sign In")]'
find_elements :xpath, 'button[contains(@name, "Sign")]'

find_element :xpath, 'textfield[@value="Email"]'
find_element :xpath, 'textfield[contains(@value, "Email")]'

find_element  :xpath, 'text[contains(@name, "Reset")]'
find_elements :xpath, 'text[contains(@name, "agree")]'

Cucumber Sauce Integration

Reset after each test and when done report the result to Sauce after quiting the driver.

require 'rest_client' # https://github.com/archiloque/rest-client
require 'json' # for .to_json
require 'sauce_whisk'

After do |scenario|
  # end the test session, ignoring any exceptions.
  ignore { $driver.driver_quit }
  
  user   = ENV['SAUCE_USERNAME']
  key    = ENV['SAUCE_ACCESS_KEY']
  if user && !user.empty? && key && !key.empty?
    passed = ! scenario.failed?
    SauceWhisk::Jobs.change_status $driver.driver.session_id, passed
  end
end

Set iOS version

# git clone
export V=`git rev-parse --verify HEAD`

# Delete all old DerivedData
rm -rf "/Users/`whoami`/Library/Developer/Xcode/DerivedData/ProjectName*"
# xcode build
cd "/Users/`whoami`/Library/Developer/Xcode/DerivedData/ProjectName*/Build/Products/Debug-iphonesimulator/ProjectName.app"

# set version
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $V" Info.plist
/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $V" Info.plist
/usr/bin/plutil -convert binary1 Info.plist

# zip app
cd ..
zip -r -X "$WORKSPACE/ProjectName.zip" ProjectName.app

Set Android version

# Save as set_version.rb and pass version as first arg.
# android:versionCode must be an int
Dir.glob('./**/AndroidManifest.xml') do |xml|
  data = File.read xml
  data.scan(/android:versionName="[^"]*"/).each { |m| data.gsub!(m, m.sub(/"[^"]*"/, '"' + ARGV.first + '"')) }
  File.open(xml, 'w') { |f| f.write data }
end

Android notes

list all ids on API 18

get_source.to_s.scan(/id\/([^\"]*)\"/)

iOS notes

mobile gestures on iOS are known to be crashy. Fix by adding pre/post event sleep.

sleep 3
mobile :tap, x: 10, y: 100, duration: 0.5
sleep 1

Accept an alert if it exists.

alert_accept if exists { alert_text }