appium_lib 0.24.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +17 -8
  3. data/android_tests/Gemfile +1 -0
  4. data/android_tests/LICENSE-2.0.txt +202 -0
  5. data/android_tests/Rakefile +61 -0
  6. data/android_tests/api.apk +0 -0
  7. data/android_tests/appium.txt +3 -0
  8. data/android_tests/flaky.txt +1 -0
  9. data/android_tests/lib/android/specs/android/dynamic.rb +5 -0
  10. data/android_tests/lib/android/specs/android/element/alert.rb +41 -0
  11. data/android_tests/lib/android/specs/android/element/button.rb +55 -0
  12. data/android_tests/lib/android/specs/android/element/generic.rb +48 -0
  13. data/android_tests/lib/android/specs/android/element/text.rb +39 -0
  14. data/android_tests/lib/android/specs/android/element/textfield.rb +60 -0
  15. data/android_tests/lib/android/specs/android/helper.rb +80 -0
  16. data/android_tests/lib/android/specs/android/patch.rb +14 -0
  17. data/android_tests/lib/android/specs/common/device.rb +117 -0
  18. data/android_tests/lib/android/specs/common/element/window.rb +9 -0
  19. data/android_tests/lib/android/specs/common/helper.rb +112 -0
  20. data/android_tests/lib/android/specs/common/patch.rb +69 -0
  21. data/android_tests/lib/android/specs/common/version.rb +9 -0
  22. data/android_tests/lib/android/specs/driver.rb +174 -0
  23. data/android_tests/lib/format.rb +49 -0
  24. data/android_tests/lib/run.rb +72 -0
  25. data/android_tests/readme.md +27 -0
  26. data/appium_lib.gemspec +8 -5
  27. data/docs/android_docs.md +1052 -716
  28. data/docs/ios_docs.md +657 -834
  29. data/docs_gen/make_docs.rb +1 -3
  30. data/ios_tests/Gemfile +1 -0
  31. data/ios_tests/LICENSE-2.0.txt +202 -0
  32. data/ios_tests/Rakefile +47 -0
  33. data/ios_tests/UICatalog.app.zip +0 -0
  34. data/ios_tests/UICatalog.app/12-6AM.png +0 -0
  35. data/ios_tests/UICatalog.app/12-6PM.png +0 -0
  36. data/ios_tests/UICatalog.app/6-12AM.png +0 -0
  37. data/ios_tests/UICatalog.app/6-12PM.png +0 -0
  38. data/ios_tests/UICatalog.app/Default-568h@2x.png +0 -0
  39. data/ios_tests/UICatalog.app/Default@2x.png +0 -0
  40. data/ios_tests/UICatalog.app/Info.plist +0 -0
  41. data/ios_tests/UICatalog.app/PkgInfo +1 -0
  42. data/ios_tests/UICatalog.app/UIButton_custom.png +0 -0
  43. data/ios_tests/UICatalog.app/UICatalog +0 -0
  44. data/ios_tests/UICatalog.app/blueButton.png +0 -0
  45. data/ios_tests/UICatalog.app/bookmarkImage.png +0 -0
  46. data/ios_tests/UICatalog.app/bookmarkImageHighlighted.png +0 -0
  47. data/ios_tests/UICatalog.app/divider.png +0 -0
  48. data/ios_tests/UICatalog.app/en.lproj/AlertsViewController.nib +0 -0
  49. data/ios_tests/UICatalog.app/en.lproj/ButtonsViewController.nib +0 -0
  50. data/ios_tests/UICatalog.app/en.lproj/ControlsViewController.nib +0 -0
  51. data/ios_tests/UICatalog.app/en.lproj/ImagesViewController.nib +0 -0
  52. data/ios_tests/UICatalog.app/en.lproj/Localizable.strings +0 -0
  53. data/ios_tests/UICatalog.app/en.lproj/MainWindow.nib +0 -0
  54. data/ios_tests/UICatalog.app/en.lproj/PickerViewController.nib +0 -0
  55. data/ios_tests/UICatalog.app/en.lproj/SearchBarController.nib +0 -0
  56. data/ios_tests/UICatalog.app/en.lproj/SegmentViewController.nib +0 -0
  57. data/ios_tests/UICatalog.app/en.lproj/TextFieldController.nib +0 -0
  58. data/ios_tests/UICatalog.app/en.lproj/TextViewController.nib +0 -0
  59. data/ios_tests/UICatalog.app/en.lproj/ToolbarViewController.nib +0 -0
  60. data/ios_tests/UICatalog.app/en.lproj/TransitionViewController.nib +0 -0
  61. data/ios_tests/UICatalog.app/en.lproj/WebViewController.nib +0 -0
  62. data/ios_tests/UICatalog.app/orangeslide.png +0 -0
  63. data/ios_tests/UICatalog.app/scene1.jpg +0 -0
  64. data/ios_tests/UICatalog.app/scene2.jpg +0 -0
  65. data/ios_tests/UICatalog.app/scene3.jpg +0 -0
  66. data/ios_tests/UICatalog.app/scene4.jpg +0 -0
  67. data/ios_tests/UICatalog.app/scene5.jpg +0 -0
  68. data/ios_tests/UICatalog.app/searchBarBackground.png +0 -0
  69. data/ios_tests/UICatalog.app/segment_check.png +0 -0
  70. data/ios_tests/UICatalog.app/segment_search.png +0 -0
  71. data/ios_tests/UICatalog.app/segment_tools.png +0 -0
  72. data/ios_tests/UICatalog.app/segmentedBackground.png +0 -0
  73. data/ios_tests/UICatalog.app/slider_ball.png +0 -0
  74. data/ios_tests/UICatalog.app/toolbarBackground.png +0 -0
  75. data/ios_tests/UICatalog.app/whiteButton.png +0 -0
  76. data/ios_tests/UICatalog.app/yellowslide.png +0 -0
  77. data/ios_tests/appium.txt +3 -0
  78. data/ios_tests/flaky.txt +1 -0
  79. data/ios_tests/lib/format.rb +25 -0
  80. data/ios_tests/lib/ios/specs/common/element/window.rb +15 -0
  81. data/ios_tests/lib/ios/specs/common/helper.rb +204 -0
  82. data/ios_tests/lib/ios/specs/common/patch.rb +50 -0
  83. data/ios_tests/lib/ios/specs/common/version.rb +17 -0
  84. data/ios_tests/lib/ios/specs/device/device.rb +82 -0
  85. data/ios_tests/lib/ios/specs/device/multi_touch.rb +12 -0
  86. data/ios_tests/lib/ios/specs/device/touch_actions.rb +15 -0
  87. data/ios_tests/lib/ios/specs/driver.rb +203 -0
  88. data/ios_tests/lib/ios/specs/ios/element/alert.rb +48 -0
  89. data/ios_tests/lib/ios/specs/ios/element/button.rb +58 -0
  90. data/ios_tests/lib/ios/specs/ios/element/generic.rb +35 -0
  91. data/ios_tests/lib/ios/specs/ios/element/text.rb +54 -0
  92. data/ios_tests/lib/ios/specs/ios/element/textfield.rb +123 -0
  93. data/ios_tests/lib/ios/specs/ios/helper.rb +27 -0
  94. data/ios_tests/lib/ios/specs/ios/patch.rb +30 -0
  95. data/ios_tests/lib/run.rb +106 -0
  96. data/ios_tests/readme.md +30 -0
  97. data/ios_tests/upload/sauce_storage.rb +64 -0
  98. data/ios_tests/upload/upload.rb +6 -0
  99. data/lib/appium_lib.rb +4 -14
  100. data/lib/appium_lib/android/dynamic.rb +30 -32
  101. data/lib/appium_lib/android/element/alert.rb +34 -33
  102. data/lib/appium_lib/android/element/button.rb +91 -0
  103. data/lib/appium_lib/android/element/generic.rb +51 -146
  104. data/lib/appium_lib/android/element/text.rb +54 -0
  105. data/lib/appium_lib/android/element/textfield.rb +46 -41
  106. data/lib/appium_lib/android/helper.rb +248 -417
  107. data/lib/appium_lib/android/mobile_methods.rb +17 -0
  108. data/lib/appium_lib/android/patch.rb +9 -8
  109. data/lib/appium_lib/awesome_print/ostruct.rb +33 -0
  110. data/lib/appium_lib/common/element/window.rb +9 -8
  111. data/lib/appium_lib/common/helper.rb +182 -243
  112. data/lib/appium_lib/common/patch.rb +65 -79
  113. data/lib/appium_lib/common/version.rb +2 -3
  114. data/lib/appium_lib/device/device.rb +339 -0
  115. data/lib/appium_lib/device/multi_touch.rb +94 -0
  116. data/lib/appium_lib/device/touch_actions.rb +142 -0
  117. data/lib/appium_lib/driver.rb +217 -306
  118. data/lib/appium_lib/ios/element/alert.rb +16 -92
  119. data/lib/appium_lib/ios/element/button.rb +55 -0
  120. data/lib/appium_lib/ios/element/generic.rb +27 -160
  121. data/lib/appium_lib/ios/element/text.rb +54 -0
  122. data/lib/appium_lib/ios/element/textfield.rb +78 -65
  123. data/lib/appium_lib/ios/helper.rb +300 -190
  124. data/lib/appium_lib/ios/mobile_methods.rb +17 -0
  125. data/lib/appium_lib/ios/patch.rb +55 -41
  126. data/lib/appium_lib/logger.rb +13 -0
  127. data/lib/appium_lib/rails/duplicable.rb +116 -0
  128. data/readme.md +6 -1
  129. data/release_notes.md +118 -0
  130. metadata +170 -12
  131. data/lib/appium_lib/common/element/button.rb +0 -83
  132. data/lib/appium_lib/common/element/text.rb +0 -61
@@ -0,0 +1,35 @@
1
+ # rake ios['ios/element/generic']
2
+ describe 'ios/element/generic' do
3
+ def before_first
4
+ screen.must_equal catalog
5
+ end
6
+
7
+ def uibutton_text
8
+ 'Buttons, Various uses of UIButton'
9
+ end
10
+
11
+ def verify element
12
+ element = element.first if element.is_a? Array
13
+ element.name.must_equal uibutton_text
14
+ end
15
+
16
+ t 'before_first' do
17
+ before_first
18
+ end
19
+
20
+ t 'find' do
21
+ verify find 'tons'
22
+ end
23
+
24
+ t 'finds' do
25
+ verify finds 'tons'
26
+ end
27
+
28
+ t 'find_exact' do
29
+ verify find_exact uibutton_text
30
+ end
31
+
32
+ t 'finds_exact' do
33
+ verify finds_exact uibutton_text
34
+ end
35
+ end
@@ -0,0 +1,54 @@
1
+ # rake ios['ios/element/text']
2
+ describe 'ios/element/text' do
3
+ def ui_catalog
4
+ 'UICatalog'
5
+ end
6
+
7
+ def before_first
8
+ screen.must_equal catalog
9
+ end
10
+
11
+ t 'before_first' do
12
+ before_first
13
+ end
14
+
15
+ t 'e_s_texts' do
16
+ e_s_texts.length.must_equal 13
17
+ end
18
+
19
+ t 'first_s_text' do
20
+ first_s_text.text.must_equal ui_catalog
21
+ end
22
+
23
+ t 'last_s_text' do
24
+ last_s_text.text.must_equal ''
25
+ last_s_text.name.must_equal 'Transitions, Shows UIViewAnimationTransitions'
26
+ end
27
+
28
+ t 's_text' do
29
+ s_text('mat').text.must_equal ''
30
+ s_text(1).text.must_equal ui_catalog
31
+ s_text('mat').name.must_equal 'Transitions, Shows UIViewAnimationTransitions'
32
+ end
33
+
34
+ t 's_texts' do
35
+ exp = ['Controls, Various uses of UIControl', 'Segments, Various uses of UISegmentedControl']
36
+ s_texts('trol').map { |e| e.name }.must_equal exp
37
+ s_texts('uses').length.must_equal 7
38
+ end
39
+
40
+ t 's_text_exact' do
41
+ # should fail
42
+ set_wait 0
43
+ act = begin; s_text_exact 'mos'; rescue; end
44
+ act.must_be_nil
45
+ set_wait
46
+
47
+ # should pass
48
+ s_text_exact(ui_catalog).text.must_equal ui_catalog
49
+ end
50
+
51
+ t 's_texts_exact' do
52
+ s_texts_exact('UICatalog').length.must_equal 1
53
+ end
54
+ end
@@ -0,0 +1,123 @@
1
+ # rake ios[ios/element/textfield]
2
+ describe 'ios/element/textfield' do
3
+ def enter_text
4
+ '<enter text>'
5
+ end
6
+
7
+ def enter_password
8
+ '<enter password>'
9
+ end
10
+
11
+ def before_first
12
+ go_to_textfields
13
+ end
14
+
15
+ def after_last
16
+ set_wait 30
17
+ end
18
+
19
+ t 'before_first' do
20
+ before_first
21
+ end
22
+
23
+ t 'textfield' do
24
+ textfield(1).text.must_equal(enter_text)
25
+ textfield(enter_text).text.must_equal(enter_text)
26
+ textfield('word').text.must_equal enter_password
27
+ end
28
+
29
+ t 'textfields' do
30
+ values = textfields('enter').map { |e| e.value }
31
+ values.include?('<enter text>').must_equal true
32
+ values.include?('<enter password>').must_equal true
33
+ end
34
+
35
+ t 'first_textfield' do
36
+ first_textfield.text.must_equal enter_text
37
+ end
38
+
39
+ t 'last_textfield' do
40
+ last_textfield.text.must_equal enter_password
41
+ end
42
+
43
+ t 'textfield_exact' do
44
+ textfield_exact(enter_password).text.must_equal enter_password
45
+ end
46
+
47
+ t 'textfields_exact' do
48
+ textfields_exact(enter_password).first.text.must_equal enter_password
49
+ end
50
+
51
+ t 'e_textfields' do
52
+ e_textfields.length.must_equal 4
53
+ end
54
+
55
+ def keyboard_exists?
56
+ !!ignore { wait_true(3) { execute_script 'au.mainApp().keyboard().type() !== "UIAElementNil"' } }
57
+ end
58
+
59
+ def keyboard_must_not_exist
60
+ keyboard_exists?.must_equal false
61
+ end
62
+
63
+ def keyboard_must_exist
64
+ keyboard_exists?.must_equal true
65
+ end
66
+
67
+ t 'textfield type' do
68
+ # Regular send keys triggers the keyboard and doesn't dismiss
69
+ keyboard_must_not_exist
70
+ textfield(1).send_keys 'ok'
71
+ keyboard_must_exist
72
+
73
+ # type will dismiss the keyboard
74
+ message = 'type test type'
75
+ textfield(1).type message
76
+ keyboard_must_not_exist
77
+ textfield(1).text.must_equal message
78
+ end
79
+
80
+ def must_raise_no_element &block
81
+ proc { block.call }.must_raise Selenium::WebDriver::Error::NoSuchElementError
82
+ end
83
+
84
+ # test textfield methods with no textfields
85
+
86
+ t 'leave textfields' do
87
+ set_wait 1
88
+ leave_textfields
89
+ end
90
+
91
+ t 'no textfield' do
92
+ must_raise_no_element { textfield(1) }
93
+ must_raise_no_element { textfield('does not exist') }
94
+ end
95
+
96
+ t 'no textfields' do
97
+ textfields('does not exist').length.must_equal 0
98
+ end
99
+
100
+ t 'no first_textfield' do
101
+ must_raise_no_element { first_textfield }
102
+ end
103
+
104
+ t 'no last_textfield' do
105
+ must_raise_no_element { last_textfield }
106
+ end
107
+
108
+ t 'no textfield_exact' do
109
+ must_raise_no_element { textfield_exact('does not exist') }
110
+ end
111
+
112
+ t 'no textfields_exact' do
113
+ textfields_exact('does not exist').length.must_equal 0
114
+ end
115
+
116
+ t 'no e_textfields' do
117
+ e_textfields.length.must_equal 0
118
+ end
119
+
120
+ t 'after_last' do
121
+ after_last
122
+ end
123
+ end
@@ -0,0 +1,27 @@
1
+ # rake ios[ios/helper]
2
+ describe 'ios/helper' do
3
+ def before_first
4
+ screen.must_equal catalog
5
+ end
6
+
7
+ t 'before_first' do
8
+ before_first
9
+ end
10
+
11
+ t 'ios_password' do
12
+ ios_password.must_equal '•'
13
+ ios_password(2).must_equal '•' * 2
14
+ end
15
+
16
+ # todo: t 'get_page' do
17
+
18
+ # t 'page' do # writes to std out
19
+
20
+ t 'source_window' do
21
+ source_window.length.must_equal 11
22
+ end
23
+
24
+ # todo: t 'page_window' do
25
+ # todo: t 'id' do
26
+ # todo: t 'ios_version' do
27
+ end
@@ -0,0 +1,30 @@
1
+ # rake ios[ios/patch]
2
+ describe 'ios/patch' do
3
+ def before_first
4
+ screen.must_equal catalog
5
+ go_to_textfields
6
+ end
7
+
8
+ def after_last
9
+ leave_textfields
10
+ end
11
+
12
+ t 'before_first' do
13
+ before_first
14
+ end
15
+
16
+ # todo: test 'label'
17
+
18
+ t 'type' do
19
+ # nav to textfield
20
+ s_text('textfields').click
21
+
22
+ ele = first_textfield
23
+ ele.type 'ok'
24
+ ele.text.must_equal 'ok'
25
+ end
26
+
27
+ t 'after_last' do
28
+ after_last
29
+ end
30
+ end
@@ -0,0 +1,106 @@
1
+ require 'rubygems'
2
+ require 'spec'
3
+ require 'hashdiff'
4
+
5
+ require_relative '../../lib/appium_lib'
6
+
7
+ =begin
8
+ Run all Android tests:
9
+ ruby run.rb android
10
+
11
+ Run only the view album test:
12
+ ruby run.rb ios view_album
13
+ =end
14
+
15
+ # Sanity check
16
+ a = OpenStruct.new x: 'ok'
17
+ raise 'x issue' unless a.x == 'ok'
18
+
19
+ # common methods
20
+ def back_click(opts={})
21
+ opts ||= {}
22
+ search_wait = opts.fetch(:wait, 60 * 1.7)
23
+ # iOS may have multiple 'back' buttons
24
+ # select the first displayed? back button.
25
+ wait(search_wait) do
26
+ button_exact('Back').click
27
+ end
28
+ end
29
+
30
+ def leave_textfields
31
+ back_click
32
+ screen.must_equal catalog
33
+ end
34
+
35
+ def go_to_textfields
36
+ screen.must_equal catalog
37
+ wait_true { s_text('textfield').click; screen == 'TextFields' } # wait for screen transition
38
+ screen.must_equal 'TextFields'
39
+ end
40
+
41
+ def screen
42
+ $driver.find_element(:class, 'UIANavigationBar').name
43
+ end
44
+
45
+ def catalog
46
+ 'UICatalog'
47
+ end
48
+
49
+ ##
50
+
51
+ caps = Appium.load_appium_txt file: File.expand_path('..', __FILE__), verbose: true
52
+ caps = caps.merge({ appium_lib: { debug: true, wait: 30 } })
53
+
54
+ dir = File.expand_path '..', __FILE__
55
+ device = ARGV[0].downcase.strip
56
+ devices = %w[ android selendroid ios ]
57
+ raise 'Expected android, selendroid or ios as first argument' unless devices.include? device
58
+
59
+ one_test = ARGV[1]
60
+ test_dir = "/#{device}/"
61
+
62
+ caps[:app] = ENV['SAUCE_PATH'] if ENV['SAUCE_USERNAME'] && ENV['SAUCE_ACCESS_KEY']
63
+
64
+ trace_files = []
65
+
66
+ if one_test
67
+ unless File.exists? one_test
68
+ # ensure ext is .rb
69
+ one_test = File.join(File.dirname(one_test),
70
+ File.basename(one_test, '.*') + '.rb')
71
+ one_test = File.join(dir, test_dir + 'specs/', one_test)
72
+ else
73
+ one_test = File.expand_path one_test
74
+ end
75
+ raise "\nTest #{one_test} does not exist.\n" unless File.exists?(one_test)
76
+ Appium::Driver.new(caps).start_driver
77
+ # require support (common.rb)
78
+ Dir.glob(File.join dir, test_dir + '/*.rb') do |test|
79
+ require test
80
+ trace_files << test
81
+ end
82
+ puts "Loading one test: #{one_test}"
83
+ require one_test
84
+ trace_files << one_test
85
+ else
86
+ # require all
87
+ Dir.glob(File.join dir, test_dir + '**/*.rb') do |test|
88
+ # load all tests
89
+ trace_files << test
90
+ puts " #{File.basename(test, '.*')}"
91
+ require test
92
+ end
93
+ Appium::Driver.new(caps).start_driver
94
+ end
95
+
96
+ trace_files.map! do |f|
97
+ f = File.expand_path f
98
+ # ensure all traced files end in .rb
99
+ f = File.join(File.dirname(f), File.basename(f, '.*') + '.rb')
100
+ f
101
+ end
102
+
103
+ # Exit after tests.
104
+ Minitest.after_run { $driver.x if $driver }
105
+ # Run Minitest. Provide test file array for tracing.
106
+ Minitest.run_specs({ :trace => trace_files })
@@ -0,0 +1,30 @@
1
+ ruby_lib_ios
2
+ =====================
3
+
4
+ ruby_lib's iOS tests. Requires `Ruby 1.9.3` or better.
5
+
6
+ - `rake install` Install gems required to run the tests.
7
+ - `rake ios` Run all tests.
8
+ - `rake` Run all the test. Same as `rake ios`
9
+ - `rake ios['ios/element/generic']` Run a single test.
10
+ - `arc` Opens the Appium Ruby Console (arc). Enables interactive testing.
11
+ - `gem install appium_console` if it's not installed already.
12
+
13
+ `UICatalog6.1` is from [appium/appium](https://github.com/appium/appium/blob/master/assets/UICatalog6.1.app.zip)
14
+
15
+ The tests are now run against `iPhone Simulator 7.0.3 (11B508)`
16
+
17
+ #### Documentation
18
+
19
+ - [Installing Appium on OS X](https://github.com/appium/ruby_console/blob/master/osx.md)
20
+ - [Overview](https://github.com/appium/ruby_lib/blob/master/docs/docs.md)
21
+ - [iOS methods](https://github.com/appium/ruby_lib/blob/master/docs/ios_docs.md)
22
+ - [Minitest Expectations](http://ruby-doc.org/stdlib-1.9.3/libdoc/minitest/spec/rdoc/MiniTest/Expectations.html)
23
+
24
+ --
25
+
26
+ ```java
27
+ Finished in 1 min 49 secs
28
+
29
+ 101 runs, 130 assertions, 0 failures, 0 errors, 0 skips
30
+ ```
@@ -0,0 +1,64 @@
1
+ =begin
2
+ See docs @ http://saucelabs.com/docs/rest#storage
3
+
4
+ s = SauceStorage.new username: 'my_user_name', key: '00', debug: true
5
+
6
+ # or if you have SAUCE_USERNAME and SAUCE_ACCESS_KEY in env already
7
+
8
+ s = SauceStorage.new debug: true
9
+
10
+ # list all files
11
+ s.files
12
+
13
+ # upload a file
14
+ s.upload '/tmp/sauce/test.zip'
15
+
16
+ > s.files
17
+ => [{"size"=>8,
18
+ "mtime"=>1367700857.1011374,
19
+ "name"=>"test.zip",
20
+ "md5"=>"d8064dccc0b399d37c73ffa9661a79b6"}]
21
+ > s.upload '/tmp/sauce/test.zip'
22
+ Uploaded /tmp/sauce/test.zip
23
+ local_md5: 764efa883dda1e11db47671c4a3bbd9e
24
+ remote_md5: 764efa883dda1e11db47671c4a3bbd9e
25
+ =end
26
+ require 'rubygems'
27
+ require 'restclient'
28
+ require 'json'
29
+
30
+ class SauceStorage
31
+ attr_reader :username, :key, :url, :debug
32
+ def initialize opts
33
+ @username = opts.fetch :username, ENV['SAUCE_USERNAME']
34
+ @key = opts.fetch :key, ENV['SAUCE_ACCESS_KEY']
35
+ @url = "https://#{@username}:#{@key}@saucelabs.com/rest/v1/storage/#{@username}"
36
+ @debug = opts.fetch :debug, false
37
+ end
38
+
39
+ def upload file_path
40
+ file_name = File.basename file_path
41
+ file = File.new file_path
42
+ local_md5 = Digest::MD5.hexdigest File.read file_path
43
+
44
+ self.files.each do |file|
45
+ if file['md5'] == local_md5
46
+ puts 'File already uploaded' if @debug
47
+ return true
48
+ end
49
+ end
50
+
51
+ url = "#{@url}/#{file_name}?overwrite=plz"
52
+ remote_md5 = JSON.parse( RestClient.post url, file, content_type: 'application/octet-stream' )['md5']
53
+ if @debug
54
+ puts "Uploaded #{file_path}"
55
+ puts " local_md5: #{local_md5}"
56
+ puts "remote_md5: #{remote_md5}"
57
+ end
58
+ local_md5 == remote_md5
59
+ end
60
+
61
+ def files
62
+ JSON.parse( RestClient.get @url )['files']
63
+ end
64
+ end