Module: Calabash::Cucumber::WaitHelpers

Includes:
Core, Logging, TestsHelpers
Included in:
Operations
Defined in:
lib/calabash-cucumber/wait_helpers.rb

Overview

A collection of methods that help you wait for things.

Defined Under Namespace

Classes: WaitError

Constant Summary collapse

CALABASH_CONDITIONS =

Currently two conditions that can be waited for using ‘wait_for_condition`: `:none_animating` no UIKit object is animating and `:no_network_indicator` status bar network indicator not showing.

{:none_animating => 'NONE_ANIMATING',
:no_network_indicator => 'NO_NETWORK_INDICATOR'}
DEFAULT_OPTS =

The default options used in the “wait*” methods

{
      # default upper limit on how long to wait
      :timeout => 30,
      # default polling frequency for waiting
      :retry_frequency => 0.3,
      # default extra wait after the condition becomes true
      :post_timeout => 0,
      # default message if timeout occurs
      :timeout_message => 'Timed out waiting...',
      # Calabash will generate a screenshot by default if waiting times out
      :screenshot_on_error => true
}

Instance Method Summary collapse

Methods included from TestsHelpers

#check_element_does_not_exist, #check_element_exists, #check_view_with_mark_exists, #classes, #each_cell, #element_does_not_exist, #element_exists, #view_with_mark_exists

Methods included from FailureHelpers

#fail, #screenshot, #screenshot_and_raise, #screenshot_embed

Methods included from Core

#await_page, #backdoor, #calabash_exit, #clear_text, #client_version, #console_attach, #double_tap, #flash, #flick, #html, #identifier, #label, #location_for_place, #page, #pan, #pinch, #query, #query_all, #scroll, #scroll_to_cell, #scroll_to_collection_view_item, #scroll_to_collection_view_item_with_mark, #scroll_to_row, #scroll_to_row_with_mark, #send_app_to_background, #server_log_level, #server_version, #set_location, #set_server_log_level, #set_text, #set_user_pref, #start_test_server_in_background, #swipe, #tap, #tap_mark, #tap_point, #touch, #touch_hold, #two_finger_tap, #user_pref, #wait_tap

Methods included from PlaybackHelpers

#interpolate, #playback, #record_begin, #record_end

Methods included from Logging

#calabash_info, #calabash_warn

Methods included from RotationHelpers

#rotate, #rotate_home_button_to

Methods included from StatusBarHelpers

#device_orientation, #landscape?, #portrait?, #status_bar_orientation

Methods included from UIA

#uia, #uia_call, #uia_call_windows, #uia_names, #uia_query, #uia_query_windows

Methods included from QueryHelpers

#escape_quotes

Methods included from EnvironmentHelpers

#default_device, #device_family_iphone?, #ios5?, #ios6?, #ios7?, #ios8?, #ipad?, #iphone?, #iphone_4in?, #iphone_5?, #iphone_app_emulated_on_ipad?, #ipod?, #simulator?, #uia_available?, #uia_not_available?, #xamarin_test_cloud?

Instance Method Details

#touch_transition(touch_q, done_queries, check_options = {}, animation_options = {}) ⇒ Object

Combines touching an element and ‘wait_for_transition`

Parameters:

  • touch_q (String)

    the Calabash query to touch

  • done_queries (Array)

    passed to ‘wait_for_transition`

  • check_options (Hash) (defaults to: {})

    ({}) passed to ‘wait_for_transition`

  • animation_options (Hash) (defaults to: {})

    ({}) passed to ‘wait_for_transition`

See Also:



332
333
334
335
# File 'lib/calabash-cucumber/wait_helpers.rb', line 332

def touch_transition(touch_q, done_queries,check_options={},animation_options={})
  touch(touch_q)
  wait_for_transition(done_queries,check_options,animation_options)
end

#until_element_does_not_exist(uiquery, opts = {}) ⇒ Object

Performs a lambda action until the element (a query string) disappears. The default action is to do nothing.

Raises an error if no uiquery is specified.

Examples:

until_element_does_not_exist("button", :action => lambda { swipe("up") })

Parameters:

  • uiquery (String)

    the Calabash query to wait for disappearing.

  • opts (Hash) (defaults to: {})

    options for controlling the details of the wait. The same options as DEFAULT_OPTS apply.

See Also:



368
369
370
371
372
373
374
375
# File 'lib/calabash-cucumber/wait_helpers.rb', line 368

def until_element_does_not_exist(uiquery, opts = {})
  condition = lambda {element_does_not_exist(uiquery)}
  extra_opts = { :until => condition, :action => lambda {} }
  opts = DEFAULT_OPTS.merge(extra_opts).merge(opts)
  wait_poll(opts) do
    opts[:action].call
  end
end

#until_element_exists(uiquery, opts = {}) ⇒ Object

Performs a lambda action until the element (a query string) appears. The default action is to do nothing. Similar to ‘wait_poll`.

Raises an error if no uiquery is specified.

Examples:

until_element_exists("button", :action => lambda { swipe("up") })

Parameters:

  • uiquery (String)

    the Calabash query to wait for

  • opts (Hash) (defaults to: {})

    options for controlling the details of the wait. The same options as DEFAULT_OPTS apply.

See Also:



349
350
351
352
353
354
355
# File 'lib/calabash-cucumber/wait_helpers.rb', line 349

def until_element_exists(uiquery, opts = {})
  extra_opts = { :until_exists => uiquery, :action => lambda {} }
  opts = DEFAULT_OPTS.merge(extra_opts).merge(opts)
  wait_poll(opts) do
    opts[:action].call
  end
end

#wait_error(msg) ⇒ WaitError, Object

if msg is a String, a new WaitError is returned. Otherwise msg itself is returned.

Parameters:

  • msg (String, Object)

    a message to raise

Returns:

  • (WaitError)

    if msg is a String, returns a new WaitError

  • (Object)

    if msg is anything else, returns msg



435
436
437
# File 'lib/calabash-cucumber/wait_helpers.rb', line 435

def wait_error(msg)
  (msg.is_a?(String) ? WaitError.new(msg) : msg)
end

#wait_for(options_or_timeout = DEFAULT_OPTS, &block) ⇒ nil

Waits for a condition to be true. The condition is specified by a given block that is called repeatedly. If the block returns a ‘trueish’ value the condition is considered true and ‘wait_for` immediately returns. There is a `:timeout` option that specifies a maximum number of seconds to wait. If the given block doesn’t return a ‘trueish’ value before the ‘:timeout` seconds has elapsed, the waiting fails and raises a WaitError error.

The ‘options` hash controls the details of waiting (see `options_or_timeout` below). DEFAULT_OPTS specifies the default waiting options.

‘wait_for` is a low-level building-block for waiting and often there are higher-level waiting methods what use `wait_for` in their implementation (e.g. `wait_for_element_exists`).

Examples:

Waiting for an element (see also ‘wait_for_element_exists`)

wait_for(timeout: 60,
         timeout_message: "Could not find 'Sign in' button") do
  element_exists("button marked:'Sign in'")
end

Parameters:

  • options_or_timeout (Hash) (defaults to: DEFAULT_OPTS)

    options for controlling the details of the wait. Note for backwards compatibility with old Calabash versions can also be a number which is then interpreted as a timeout.

Options Hash (options_or_timeout):

  • :timeout (Numeric) — default: 30

    upper limit on how long to wait (in seconds)

  • :retry_frequency (Numeric) — default: 0.3

    how often to poll (i.e., call the given block)

  • :post_timeout (Numeric) — default: 0

    if positive, an extra wait is made after the condition is satisfied

  • :timeout_message (String)

    the error message to use if condition is not satisfied in time

  • :screenshot_on_error (Boolean)

    generate a screenshot on error

Returns:

  • (nil)

    when the condition is satisfied

Raises:

See Also:



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/calabash-cucumber/wait_helpers.rb', line 83

def wait_for(options_or_timeout=DEFAULT_OPTS, &block)
  #note Hash is preferred, number acceptable for backwards compat
  default_timeout = 30
  timeout = options_or_timeout || default_timeout
  post_timeout=0
  retry_frequency=0.3
  timeout_message = nil
  screenshot_on_error = true

  if options_or_timeout.is_a?(Hash)
    timeout = options_or_timeout[:timeout] || default_timeout
    retry_frequency = options_or_timeout[:retry_frequency] || retry_frequency
    post_timeout = options_or_timeout[:post_timeout] || post_timeout
    timeout_message = options_or_timeout[:timeout_message]
    if options_or_timeout.key?(:screenshot_on_error)
      screenshot_on_error = options_or_timeout[:screenshot_on_error]
    end
  end

  begin
    Timeout::timeout(timeout, WaitError) do
      sleep(retry_frequency) until yield
    end
    sleep(post_timeout) if post_timeout > 0
  rescue WaitError => e
    msg = timeout_message || e
    if screenshot_on_error
      sleep(retry_frequency)
      return screenshot_and_retry(msg, &block)
    else
      raise wait_error(msg)
    end
  rescue Exception => e
    handle_error_with_options(e, nil, screenshot_on_error)
  end
end

#wait_for_element_does_not_exists(element_query, options = {}) ⇒ nil

Waits for a Calabash query to return an empty result (typically a UI element to disappear). Uses ‘wait_for`.

Parameters:

  • element_query (String)

    a Calabash query to be empty (i.e. ‘element_does_not_exist(element_query)`)

  • options (Hash) (defaults to: {})

    options for controlling the details of the wait. The same options as DEFAULT_OPTS apply.

Returns:

  • (nil)

    when the condition is satisfied

Raises:

See Also:



215
216
217
218
# File 'lib/calabash-cucumber/wait_helpers.rb', line 215

def wait_for_element_does_not_exists(element_query, options={})
  options[:timeout_message] = options[:timeout_message] || "Timeout waiting for element to not exist: #{element_query}"
  wait_for(options) { element_does_not_exist(element_query) }
end

#wait_for_element_exists(element_query, options = {}) ⇒ nil

Waits for a Calabash query to return a non-empty result (typically a UI element to be visible). Uses ‘wait_for`.

Examples:

Waiting for an element to be visible

wait_for_element_exists("button marked:'foo'", timeout: 60)

Parameters:

  • element_query (String)

    a Calabash query to wait for (i.e. ‘element_exists(element_query)`)

  • options (Hash) (defaults to: {})

    options for controlling the details of the wait. The same options as DEFAULT_OPTS apply.

Returns:

  • (nil)

    when the condition is satisfied

Raises:

See Also:



178
179
180
181
# File 'lib/calabash-cucumber/wait_helpers.rb', line 178

def wait_for_element_exists(element_query, options={})
  options[:timeout_message] = options[:timeout_message] || "Timeout waiting for element: #{element_query}"
  wait_for(options) { element_exists(element_query) }
end

#wait_for_elements_do_not_exist(elements_arr, options = {}) ⇒ nil

Waits for one or more Calabash queries to all return empty results (typically a UI elements to disappear). Uses ‘wait_for`.

Parameters:

  • elements_arr (Array<String>)

    an Array of Calabash queries to be empty (i.e. ‘element_does_not_exist(element_query)`)

  • options (Hash) (defaults to: {})

    options for controlling the details of the wait. The same options as DEFAULT_OPTS apply.

Returns:

  • (nil)

    when the condition is satisfied

Raises:

See Also:



232
233
234
235
236
237
238
239
240
# File 'lib/calabash-cucumber/wait_helpers.rb', line 232

def wait_for_elements_do_not_exist(elements_arr, options={})
  if elements_arr.is_a?(String)
    elements_arr = [elements_arr]
  end
  options[:timeout_message] = options[:timeout_message] || "Timeout waiting for no elements matching: #{elements_arr.join(",")}"
  wait_for(options) do
    elements_arr.none? { |q| element_exists(q) }
  end
end

#wait_for_elements_exist(elements_arr, options = {}) ⇒ nil

Waits for one or more Calabash queries to all return non-empty results (typically a UI elements to be visible). Uses ‘wait_for`.

Parameters:

  • elements_arr (Array<String>)

    an Array of Calabash queries to wait for (i.e. ‘element_exists(element_query)`)

  • options (Hash) (defaults to: {})

    options for controlling the details of the wait. The same options as DEFAULT_OPTS apply.

Returns:

  • (nil)

    when the condition is satisfied

Raises:

See Also:



194
195
196
197
198
199
200
201
202
# File 'lib/calabash-cucumber/wait_helpers.rb', line 194

def wait_for_elements_exist(elements_arr, options={})
  if elements_arr.is_a?(String)
    elements_arr = [elements_arr]
  end
  options[:timeout_message] = options[:timeout_message] || "Timeout waiting for elements: #{elements_arr.join(',')}"
  wait_for(options) do
    elements_arr.all? { |q| element_exists(q) }
  end
end

#wait_for_no_network_indicator(options = {}) ⇒ nil

Waits for the status-bar network indicator to stop animating (network activity done).

Parameters:

  • options (Hash) (defaults to: {})

    options for controlling the details of the wait.

Options Hash (options):

  • :timeout (Numeric) — default: 30

    maximum time to wait

Returns:

  • (nil)

    when the condition is satisfied

Raises:



311
312
313
314
# File 'lib/calabash-cucumber/wait_helpers.rb', line 311

def wait_for_no_network_indicator(options = {})
  options[:condition] = CALABASH_CONDITIONS[:no_network_indicator]
  wait_for_condition(options)
end

#wait_for_none_animating(options = {}) ⇒ nil

Waits for all elements to stop animating (EXPERIMENTAL).

Parameters:

  • options (Hash) (defaults to: {})

    options for controlling the details of the wait.

Options Hash (options):

  • :timeout (Numeric) — default: 30

    maximum time to wait

Returns:

  • (nil)

    when the condition is satisfied

Raises:



301
302
303
304
# File 'lib/calabash-cucumber/wait_helpers.rb', line 301

def wait_for_none_animating(options = {})
  options[:condition] = CALABASH_CONDITIONS[:none_animating]
  wait_for_condition(options)
end

#wait_for_transition(done_queries, check_options = {}, animation_options = {}) ⇒ Object

Combines waiting for elements and waiting for animations.

Parameters:

  • done_queries (Array)

    Calabash queries to wait for (one or more).

  • check_options (Hash) (defaults to: {})

    ({}) options used for ‘wait_for_elements_exists(done_queries, check_options)`

  • animation_options (Hash) (defaults to: {})

    ({}) options used for ‘wait_for_none_animating(animation_options)`



320
321
322
323
324
# File 'lib/calabash-cucumber/wait_helpers.rb', line 320

def wait_for_transition(done_queries, check_options={},animation_options={})
  done_queries = [*done_queries]
  wait_for_elements_exist(done_queries,check_options)
  wait_for_none_animating(animation_options)
end

#wait_poll(opts, &block) ⇒ nil

Repeatedly runs an action (for side-effects) until a condition is satisfied. Similar to ‘wait_for` but specifies both a condition to wait for and an action to repeatedly perform to make the condition true (e.g. scrolling). The return value of the action is ignored.

The block represents the action and options :until or :until_exists specify the condition to wait for. Same options as ‘wait_for` can be provided.

Examples:

Scrolling until we find an element

wait_poll(timeout: 10,
          timeout_message: 'Unable to find "Example"',
          until_exists: "* marked:'Example'") do
  scroll("tableView", :down)
end

Win the battle

wait_poll(timeout: 60,
          timeout_message: 'Defeat!',
          until: lambda { enemy_defeated? }) do
  launch_the_missiles!
end

Parameters:

  • opts (Hash)

    options for controlling the details of the wait in addition to the options specified below, all options in DEFAULT_OPTS also apply and can be overridden.

Options Hash (opts):

  • :until (Proc)

    if specified this lambda/Proc becomes the condition to wait for.

  • :until_exists (String)

    if specified, a calabash query to wait for. Exactly one of ‘:until` and `:until_exists` must be specified

Returns:

  • (nil)

    when the condition is satisfied

Raises:

See Also:



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/calabash-cucumber/wait_helpers.rb', line 149

def wait_poll(opts, &block)
  test = opts[:until]
  if test.nil?
    cond = opts[:until_exists]
    raise 'Must provide :until or :until_exists' unless cond
    test = lambda { element_exists(cond) }
  end
  wait_for(opts) do
    if test.call()
      true
    else
      yield
      false
    end
  end
end

#when_element_exists(uiquery, opts = {}) ⇒ Object

Performs a lambda action once the element exists. The default behavior is to touch the specified element.

Raises an error if no uiquery is specified.

Examples:

when_element_exists("button", :timeout => 10)

Parameters:

  • uiquery (String)

    the Calabash query to wait for.

  • opts (Hash) (defaults to: {})

    options for controlling the details of the wait. The same options as DEFAULT_OPTS apply.

See Also:



388
389
390
391
392
# File 'lib/calabash-cucumber/wait_helpers.rb', line 388

def when_element_exists(uiquery, opts = {})
  action = opts[:action] || lambda { touch(uiquery) }
  wait_for_element_exists(uiquery, opts)
  action.call
end