appium_lib 0.24.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +17 -8
- data/android_tests/Gemfile +1 -0
- data/android_tests/LICENSE-2.0.txt +202 -0
- data/android_tests/Rakefile +61 -0
- data/android_tests/api.apk +0 -0
- data/android_tests/appium.txt +3 -0
- data/android_tests/flaky.txt +1 -0
- data/android_tests/lib/android/specs/android/dynamic.rb +5 -0
- data/android_tests/lib/android/specs/android/element/alert.rb +41 -0
- data/android_tests/lib/android/specs/android/element/button.rb +55 -0
- data/android_tests/lib/android/specs/android/element/generic.rb +48 -0
- data/android_tests/lib/android/specs/android/element/text.rb +39 -0
- data/android_tests/lib/android/specs/android/element/textfield.rb +60 -0
- data/android_tests/lib/android/specs/android/helper.rb +80 -0
- data/android_tests/lib/android/specs/android/patch.rb +14 -0
- data/android_tests/lib/android/specs/common/device.rb +117 -0
- data/android_tests/lib/android/specs/common/element/window.rb +9 -0
- data/android_tests/lib/android/specs/common/helper.rb +112 -0
- data/android_tests/lib/android/specs/common/patch.rb +69 -0
- data/android_tests/lib/android/specs/common/version.rb +9 -0
- data/android_tests/lib/android/specs/driver.rb +174 -0
- data/android_tests/lib/format.rb +49 -0
- data/android_tests/lib/run.rb +72 -0
- data/android_tests/readme.md +27 -0
- data/appium_lib.gemspec +8 -5
- data/docs/android_docs.md +1052 -716
- data/docs/ios_docs.md +657 -834
- data/docs_gen/make_docs.rb +1 -3
- data/ios_tests/Gemfile +1 -0
- data/ios_tests/LICENSE-2.0.txt +202 -0
- data/ios_tests/Rakefile +47 -0
- data/ios_tests/UICatalog.app.zip +0 -0
- data/ios_tests/UICatalog.app/12-6AM.png +0 -0
- data/ios_tests/UICatalog.app/12-6PM.png +0 -0
- data/ios_tests/UICatalog.app/6-12AM.png +0 -0
- data/ios_tests/UICatalog.app/6-12PM.png +0 -0
- data/ios_tests/UICatalog.app/Default-568h@2x.png +0 -0
- data/ios_tests/UICatalog.app/Default@2x.png +0 -0
- data/ios_tests/UICatalog.app/Info.plist +0 -0
- data/ios_tests/UICatalog.app/PkgInfo +1 -0
- data/ios_tests/UICatalog.app/UIButton_custom.png +0 -0
- data/ios_tests/UICatalog.app/UICatalog +0 -0
- data/ios_tests/UICatalog.app/blueButton.png +0 -0
- data/ios_tests/UICatalog.app/bookmarkImage.png +0 -0
- data/ios_tests/UICatalog.app/bookmarkImageHighlighted.png +0 -0
- data/ios_tests/UICatalog.app/divider.png +0 -0
- data/ios_tests/UICatalog.app/en.lproj/AlertsViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ButtonsViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ControlsViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ImagesViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/Localizable.strings +0 -0
- data/ios_tests/UICatalog.app/en.lproj/MainWindow.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/PickerViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/SearchBarController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/SegmentViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/TextFieldController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/TextViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/ToolbarViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/TransitionViewController.nib +0 -0
- data/ios_tests/UICatalog.app/en.lproj/WebViewController.nib +0 -0
- data/ios_tests/UICatalog.app/orangeslide.png +0 -0
- data/ios_tests/UICatalog.app/scene1.jpg +0 -0
- data/ios_tests/UICatalog.app/scene2.jpg +0 -0
- data/ios_tests/UICatalog.app/scene3.jpg +0 -0
- data/ios_tests/UICatalog.app/scene4.jpg +0 -0
- data/ios_tests/UICatalog.app/scene5.jpg +0 -0
- data/ios_tests/UICatalog.app/searchBarBackground.png +0 -0
- data/ios_tests/UICatalog.app/segment_check.png +0 -0
- data/ios_tests/UICatalog.app/segment_search.png +0 -0
- data/ios_tests/UICatalog.app/segment_tools.png +0 -0
- data/ios_tests/UICatalog.app/segmentedBackground.png +0 -0
- data/ios_tests/UICatalog.app/slider_ball.png +0 -0
- data/ios_tests/UICatalog.app/toolbarBackground.png +0 -0
- data/ios_tests/UICatalog.app/whiteButton.png +0 -0
- data/ios_tests/UICatalog.app/yellowslide.png +0 -0
- data/ios_tests/appium.txt +3 -0
- data/ios_tests/flaky.txt +1 -0
- data/ios_tests/lib/format.rb +25 -0
- data/ios_tests/lib/ios/specs/common/element/window.rb +15 -0
- data/ios_tests/lib/ios/specs/common/helper.rb +204 -0
- data/ios_tests/lib/ios/specs/common/patch.rb +50 -0
- data/ios_tests/lib/ios/specs/common/version.rb +17 -0
- data/ios_tests/lib/ios/specs/device/device.rb +82 -0
- data/ios_tests/lib/ios/specs/device/multi_touch.rb +12 -0
- data/ios_tests/lib/ios/specs/device/touch_actions.rb +15 -0
- data/ios_tests/lib/ios/specs/driver.rb +203 -0
- data/ios_tests/lib/ios/specs/ios/element/alert.rb +48 -0
- data/ios_tests/lib/ios/specs/ios/element/button.rb +58 -0
- data/ios_tests/lib/ios/specs/ios/element/generic.rb +35 -0
- data/ios_tests/lib/ios/specs/ios/element/text.rb +54 -0
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +123 -0
- data/ios_tests/lib/ios/specs/ios/helper.rb +27 -0
- data/ios_tests/lib/ios/specs/ios/patch.rb +30 -0
- data/ios_tests/lib/run.rb +106 -0
- data/ios_tests/readme.md +30 -0
- data/ios_tests/upload/sauce_storage.rb +64 -0
- data/ios_tests/upload/upload.rb +6 -0
- data/lib/appium_lib.rb +4 -14
- data/lib/appium_lib/android/dynamic.rb +30 -32
- data/lib/appium_lib/android/element/alert.rb +34 -33
- data/lib/appium_lib/android/element/button.rb +91 -0
- data/lib/appium_lib/android/element/generic.rb +51 -146
- data/lib/appium_lib/android/element/text.rb +54 -0
- data/lib/appium_lib/android/element/textfield.rb +46 -41
- data/lib/appium_lib/android/helper.rb +248 -417
- data/lib/appium_lib/android/mobile_methods.rb +17 -0
- data/lib/appium_lib/android/patch.rb +9 -8
- data/lib/appium_lib/awesome_print/ostruct.rb +33 -0
- data/lib/appium_lib/common/element/window.rb +9 -8
- data/lib/appium_lib/common/helper.rb +182 -243
- data/lib/appium_lib/common/patch.rb +65 -79
- data/lib/appium_lib/common/version.rb +2 -3
- data/lib/appium_lib/device/device.rb +339 -0
- data/lib/appium_lib/device/multi_touch.rb +94 -0
- data/lib/appium_lib/device/touch_actions.rb +142 -0
- data/lib/appium_lib/driver.rb +217 -306
- data/lib/appium_lib/ios/element/alert.rb +16 -92
- data/lib/appium_lib/ios/element/button.rb +55 -0
- data/lib/appium_lib/ios/element/generic.rb +27 -160
- data/lib/appium_lib/ios/element/text.rb +54 -0
- data/lib/appium_lib/ios/element/textfield.rb +78 -65
- data/lib/appium_lib/ios/helper.rb +300 -190
- data/lib/appium_lib/ios/mobile_methods.rb +17 -0
- data/lib/appium_lib/ios/patch.rb +55 -41
- data/lib/appium_lib/logger.rb +13 -0
- data/lib/appium_lib/rails/duplicable.rb +116 -0
- data/readme.md +6 -1
- data/release_notes.md +118 -0
- metadata +170 -12
- data/lib/appium_lib/common/element/button.rb +0 -83
- 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 })
|
data/ios_tests/readme.md
ADDED
@@ -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
|