0

I try to avoid the sleep() command so I want to replace it with smarter functions like wait_for_element_exists() but they seems to not work under iOS. Example:

touch("button marked:'button_in_the_first_view'")
wait_for_element_exists("button marked:'button_in_the_second_view'")
touch("button marked:'button_in_the_third_view'")

Calabash doesn't wait for the second button to be displayed on the screen, goes to line 3 without any delay and fails the test

If I try to determine the properties of the second button it is immediately available, still enabled and not hidden despite the fact that navigation view controller hasn't finished the push animation from the first view:

touch("button marked:'button_in_the_first_view'")
query("button marked:'button_in_the_second_view'").count # => 1
query("button marked:'button_in_the_second_view'", :isEnabled).first # => 1
query("button marked:'button_in_the_second_view'", :isHidden).first # => 0

Thanks in advance for your help,

Michał

Kaktusiarz
  • 415
  • 7
  • 22
  • I know this is not the answer you are looking for. But I have faced similar issues and in some cases found the need to combine a sleep() and a wait_for because wait_for was firing before the UI component could be used. – Lasse Mar 17 '15 at 14:34

1 Answers1

1

wait_for_elements_exist() works. You need to find out where it wrongly triggers. As Lasse says sometimes you need to use least sleep(0.3) for match the animation speed. There are options on wait_for_elements_exist method like

    wait_for_elements_exist(elements_arr, 
    {
     :timeout => 10, #maximum number of seconds to wait
     :retry_frequency => 0.2, #wait this long before retrying the block
     :post_timeout => 0.1, #wait this long after the block returns true
     :timeout_message => "Timed out waiting...", #error message in case options[:timeout] is exceeded
     :screenshot_on_error => true # take a screenshot in case of error
    }
)

Try use these options, element_exists() function and some UI query to find out what actually happen on the screen ? What are the both buttons state and what happen at the next second?

Further more you can check button state before touch it like this.

Then /^I should see "([^\"]*)" button isEnabled$/ do |text|
    state = query("button marked:'#{text}'", :isEnabled)[0]
    state = state.to_i
    if state!=1
      screenshot_and_raise "Current state is not enabled for button: #{text}"
    end
    sleep(STEP_PAUSE)
end



Then /^I touch the "([^\"]*)" button after it appears$/ do |name|
      element = "button marked:'#{name}'"
      if element_does_not_exist(element)
        wait_for_elements_exist( [element], :timeout => 10)
        sleep(STEP_PAUSE)
        touch(element)
        sleep(0.3)
      elsif element_exists(element)
        touch(element)
        sleep(0.3)
      else
        screenshot_and_raise "'#{name}' Button isnt exsist."
      end
    end

Here I add some advance wait functions on calabash. Check if you can find a solution there.

  • Unfortunatelly it doesn't work. The first if clause (`if element_does_not_exist(element)`) is never visited (I tried many examples). Furthermore If I simply invoke `wait_for_elements_exist( [element], :timeout => 10, :post_timeout => 0.5)` but displaying of the element in the view lasts longer than 0.5 it always fails. – Kaktusiarz Mar 18 '15 at 12:33
  • May be your button element is already exist and it is not active. you may need to use wait_for_animations_to_finish() "Sometimes you do need sleep (to wait for animations to complete)" Read here under waiting https://github.com/calabash/calabash-android/blob/master/documentation/ruby_api.md – Chathura Palihakkara Mar 18 '15 at 19:39