Module: ILessPainfulClient::Cucumber::Operations

Defined in:
lib/ilesspainfulclient-cucumber/operations.rb

Constant Summary collapse

DATA_PATH =
File.expand_path(File.dirname(__FILE__))

Instance Method Summary collapse

Instance Method Details

#background(secs) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 96

def background(secs)
  raise "Not implemented yet"
  IO.popen("/Users/krukow/Projects/iOS/libimobiledevice/tools/idevicedebugserver -u #{ENV['UUID']} dk.tk-solutions.Background", "w+") do |pipe|
    puts "sleep"
    sleep(secs)
    puts "wake"
    pipe.puts "kill"
    pipe.close_write
    sleep(5)
  end
  system("/Users/krukow/Projects/iOS/libimobiledevice/tools/idevicedebugserver --dont-kill -u #{ENV['UUID']} #{ENV['BUNDLE_ID']} &")

end

#cell_swipe(options = {}) ⇒ Object



40
41
42
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 40

def cell_swipe(options={})
  playback("cell_swipe",options)
end

#check_element_does_not_exist(query) ⇒ Object



129
130
131
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 129

def check_element_does_not_exist( query )
  element_exists( query ).should be_false
end

#check_element_exists(query) ⇒ Object



125
126
127
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 125

def check_element_exists( query )
  element_exists( query ).should be_true
end

#check_view_with_mark_exists(expected_mark) ⇒ Object



133
134
135
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 133

def check_view_with_mark_exists(expected_mark)
  check_element_exists( "view marked:'#{expected_mark}'" )
end

#doneObject



44
45
46
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 44

def done
  map(nil,:touchDone,load_playback_data("touch_done"))
end

#element_exists(uiquery) ⇒ Object

def swipe( uiquery, direction )

  views_touched = frankly_map( uiquery, "swipe:", direction)
  raise "could not find anything matching [#{uiquery}] to swipe" if views_touched.empty?
  #TODO raise warning if views_touched.count > 1
end


117
118
119
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 117

def element_exists(uiquery)
  !query(uiquery).empty?
end

#element_is_not_hidden(uiquery) ⇒ Object

a better name would be element_exists_and_is_not_hidden



138
139
140
141
142
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 138

def element_is_not_hidden(uiquery)
   matches = query(uiquery, 'isHidden')
   matches.delete(true)
   !matches.empty?
end

#http(options, data = nil) ⇒ Object



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 254

def http(options, data=nil)
  url = url_for(options[:path])
  if options[:method] == :post
    req = Net::HTTP::Post.new url.path
    if options[:raw]
      req.body=data
    else
      req.body = data.to_json
    end

  else
    req = Net::HTTP::Get.new url.path
  end
  make_http_request( url, req )
end

#load_playback_data(recording, options = {}) ⇒ Object



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 145

def load_playback_data(recording,options={})
  os = options["OS"] || ENV["OS"]
  device = options["DEVICE"] || ENV["DEVICE"]

  rec_dir = ENV['PLAYBACK_DIR'] || "#{Dir.pwd}/playback"
  if !recording.end_with?".base64"
     recording = "#{recording}_#{os}_#{device}.base64"
  end
  data = nil
  if (File.exists?(recording))
    data = File.read(recording)
    puts "found #{recording}"
  elsif (File.exists?("#{rec_dir}/#{recording}"))
    data = File.read("#{rec_dir}/#{recording}")
    puts "#{rec_dir}/#{recording}"
  elsif (File.exists?("#{DATA_PATH}/resources/#{recording}"))
    data = File.read("#{DATA_PATH}/resources/#{recording}")
    puts "#{DATA_PATH}/resources/#{recording}"
  else
    raise "Playback not found: #{recording} (searched for #{recording} in #{Dir.pwd}, #{rec_dir}, #{DATA_PATH}/resources"
  end
  data
end

#make_http_request(url, req) ⇒ Object



277
278
279
280
281
282
283
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 277

def make_http_request( url, req )
  @http = @http || Net::HTTP.new(url.host, url.port)
  res = @http.start do |sess|
    sess.request req
  end
  res.body
end

#map(query, method_name, *method_args) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 239

def 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'
    raise "map #{query}, #{method_name} failed because: #{res['reason']}\n#{res['details']}"
  end

  res['results']
end

#okObject



25
26
27
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 25

def ok
  touch("view marked:'ok'")
end

#pinch(in_out, options = {}) ⇒ Object



60
61
62
63
64
65
66
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 60

def pinch(in_out,options={})
  file = "pinch_in"
  if in_out.to_sym==:out
    file = "pinch_out"
  end
  playback(file, options)
end

#playback(recording, options = {}) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 168

def playback(recording, options={})
  data = load_playback_data(recording)

  post_data = %Q|{"events":"#{data}"|
  post_data<< %Q|,"query":"#{options[:query]}"| if options[:query]
  post_data<< %Q|,"offset":#{options[:offset].to_json}| if options[:offset]
  post_data<< %Q|,"reverse":#{options[:reverse]}| if options[:reverse]
  post_data<< %Q|,"prototype":"#{options[:prototype]}"| if options[:prototype]
  post_data << "}"

  res = http({:method=>:post, :raw=>true, :path=>'play'}, post_data)

  res = JSON.parse( res )
  if res['outcome'] != 'SUCCESS'
    raise "playback failed because: #{res['reason']}\n#{res['details']}"
  end
  res['results']
end

#query(uiquery, *args) ⇒ Object



10
11
12
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 10

def query(uiquery, *args)
  map(uiquery, :query, *args)
end

#record_beginObject



187
188
189
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 187

def record_begin
  http({:method=>:post, :path=>'record'}, {:action => :start})
end

#record_end(file_name) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 191

def record_end(file_name)
  res = http({:method=>:post, :path=>'record'}, {:action => :stop})
  File.open("_recording.plist",'wb') do |f|
      f.write res
  end
  file_name = "#{file_name}_#{ENV['OS']}_#{ENV['DEVICE']}.base64"
  system("plutil -i _recording.plist -o _recording_binary.plist -convert binary1")
  system("openssl base64 -in _recording_binary.plist -out #{file_name}")
  system("rm _recording.plist _recording_binary.plist")
  file_name
end

#rotate(dir) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 68

def rotate(dir)
  @current_rotation = @current_rotation || :down
  rotate_cmd = nil
  case dir
    when :left then
      if @current_rotation == :down
        @current_rotation = :right
        rotate_cmd = "down_to_right"
      elsif @current_rotation == :left
        @current_rotation = :down
        rotate_cmd = "left_to_down"
      end
    when :right then
      if @current_rotation == :down
        @current_rotation = :left
        rotate_cmd = "down_to_left"
      elsif @current_rotation == :right
        @current_rotation = :down
        rotate_cmd = "right_to_down"
      end
  end

  if rotate_cmd.nil?
    throw "Does not support rotating #{dir} when home button is pointing #{@current_rotation}"
  end
  playback("rotate_home_#{rotate_cmd}")
end

#screencast_beginObject



203
204
205
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 203

def screencast_begin
   http({:method=>:post, :path=>'screencast'}, {:action => :start})
end

#screencast_end(file_name) ⇒ Object



207
208
209
210
211
212
213
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 207

def screencast_end(file_name)
  res = http({:method=>:post, :path=>'screencast'}, {:action => :stop})
  File.open(file_name,'wb') do |f|
      f.write res
  end
  file_name
end

#screenshotObject



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 215

def screenshot
  if !/localhost/.match(ENV['DEVICE_ENDPOINT'])
    f = %x[idevicescreenshot -u #{ENV['UUID']}]
    line=f.strip().split("\n").last
    filename=line.split(" ").last
    outfile = "#{ENV['SCREENSHOT_PATH_PREFIX']}_#{Step_line}.png"
    if File.exist?filename
      puts "converting screenshot: #{filename} to 1.png"
      system("convert #{filename} to #{outfile}")
    else
      raise "Error. Unable to screenshot for device #{ENV['UUID']}."
    end
  else
    res = http({:method =>:get, :path => 'screenshot'})
    @sc_count = @sc_count || 0
    path = "screenshot_#{@sc_count}.png"
    @sc_count += 1
    File.open(path,'wb') do |f|
      f.write res
    end
    system("open #{path}")
  end
end

#scroll(uiquery, direction) ⇒ Object



48
49
50
51
52
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 48

def scroll(uiquery,direction)
  views_touched=map(uiquery, :scroll, direction)
  raise "could not find view to scroll: '#{uiquery}', args: #{direction}" if views_touched.empty?
  views_touched
end

#scroll_to_row(uiquery, number) ⇒ Object



54
55
56
57
58
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 54

def scroll_to_row(uiquery,number)
  views_touched=map(uiquery, :scrollToRow, number)
  raise "could not find view to scroll: '#{uiquery}', args: #{number}" if views_touched.empty?
  views_touched
end

#set_text(uiquery, txt) ⇒ Object



29
30
31
32
33
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 29

def set_text(uiquery, txt)
  text_fields_modified = map(uiquery, :setText, txt)
  raise "could not find text field #{uiquery}" if text_fields_modified.empty?
  text_fields_modified
end

#simple_touch(label, *args) ⇒ Object



21
22
23
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 21

def simple_touch(label,*args)
  touch("view marked:'#{label}'", *args)
end

#swipe(dir, options = {}) ⇒ Object



36
37
38
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 36

def swipe(dir,options={})
  playback("swipe_#{dir}}",options)
end

#touch(uiquery, options = {}) ⇒ Object



14
15
16
17
18
19
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 14

def touch(uiquery,options={})
  options[:query] = uiquery
  views_touched = playback("touch",options)
  raise "could not find view to touch: '#{uiquery}', args: #{args}" if views_touched.empty?
  views_touched
end

#url_for(verb) ⇒ Object



271
272
273
274
275
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 271

def url_for( verb )
  url = URI.parse (ENV['DEVICE_ENDPOINT']|| "http://localhost:37265/")
  url.path = '/'+verb
  url
end

#view_with_mark_exists(expected_mark) ⇒ Object



121
122
123
# File 'lib/ilesspainfulclient-cucumber/operations.rb', line 121

def view_with_mark_exists(expected_mark)
  element_exists( "view marked:'#{expected_mark}'" )
end