require 'json' module Calabash module Cucumber module Map #=> Connection # returns an array of views matched by the +query+ or the result of # performing the Objective-C sequence defined by the +method_name+ and # +method_args+ on all the views matched by the +query+ # # the query language is documented here: https://github.com/calabash/calabash-ios/wiki # # returns a JSON representation of each view that is matched # # when the +method_name+ is a calabash operation, returns an array that # contains the result of calling the objc selector +description+ on each # matched view. these are examples of calabash operations: +:flash+, # +:scrollToRowWithMark+, +:changeDatePickerDate+. def map(query, method_name, *method_args) #todo calabash operations should return 'views touched' in JSON format raw_map(query, method_name, *method_args)['results'] end # returns a JSON object the represents the result of performing an http # query against the calabash server. # # gem users should _not_ call this method directly; call +map+ instead. # # raises an error and takes a screenshot if the value of the +outcome+ key # is _not_ 'SUCCESS' # # the JSON object contains the following keys: # # +outcome+ => indicates the success or failure of the query # # +status_bar_orientation+ => the orientation of the status bar # # +results+ => views matched by the +query+ or the result of # performing the Objective-C selector sequence defined by # the +method_name+ with arguments defined in # +method_args+ on all views matched by the +query+ # # the query language is documented here: https://github.com/calabash/calabash-ios/wiki # # here are some examples that clarify how the +method_name+ and +method_args+ # influence the value of the +results+ key # # simple examples: # # raw_map('label')['result'] #=> [ all visible UILabels ] # raw_map('label', :text) #=> [ the 'text' of all visible UILabels ] # # example of calling a selector with arguments: # # raw_map("tableView marked:'cheeses'", {'numberOfRowsInSection' => 0})) => # [ the number of rows in the first section of the 'cheeses' table ] # # example of calling a selector on view to return an object and then calling # another selector on the returned object: # # raw_map("pickerView marked:'cheeses'", :delegate, [{pickerView:nil},{titleForRow:1},{forComponent:0}]) => # objc call: [[pickerView delegate] pickerView:nil titleForRow:1 forComponent:0] => # ['French'] def raw_map(query, method_name, *method_args) operation_map = { :method_name => method_name, :arguments => method_args } res = http({:method => :post, :path => 'map'}, {:query => query, :operation => operation_map}) res = JSON.parse(res) if res['outcome'] != 'SUCCESS' screenshot_and_raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}" end res end # asserts the result of a calabash +map+ call and raises an error with # +msg+ if no valid results are found. # # casual gem users should never need to call this method; this is a # convenience method for gem maintainers. # # raises an error if +map_results+: # # is an empty list #=> [] # contains a '' string #=> [ "" ] # contains '*****' string #=> [ "*****" ] # contains a single nil #=> [ nil ] # # when evaluating whether a +map+ call is successful it is important to # note that sometimes a [ nil ] or [nil, , nil] is # a valid result. # # consider a controller with 3 labels: # # label @ index 0 has text "foo" # label @ index 1 has text nil (the [label text] => nil) # label @ index 2 has text "bar" # # map('label', :text) => ['foo', nil, 'bar'] # map('label index:1', :text) => [nil] # # in other cases, [ nil ] should be treated as an invalid result # # # invalid # > mark = 'mark does not exist' # > map('tableView', :scrollToRowWithMark, mark, args) => [ nil ] # # here a [ nil ] should be considered invalid because the # the operation could not be performed because there is not row that # matches +mark+ def assert_map_results(map_results, msg) compact = map_results.compact if compact.empty? or compact.member? '' or compact.member? '*****' screenshot_and_raise msg end end end end end