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.
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,50 @@
1
+ =begin
2
+ Skip:
3
+ status # status patches are already tested in driver.rb
4
+ raw_execute # debug output for Pry
5
+ =end
6
+ # rake ios[common/patch]
7
+ describe 'common/patch.rb' do
8
+ def before_first
9
+ screen.must_equal catalog
10
+ end
11
+
12
+ t 'before_first' do
13
+ before_first
14
+ end
15
+
16
+ # Attributes are busted in Android.
17
+ # Blocked on https://github.com/appium/appium/issues/628
18
+ describe 'Selenium::WebDriver::Element methods' do
19
+ # todo: t 'value' do; end
20
+
21
+ t 'name' do
22
+ first_s_text.name.must_equal 'UICatalog'
23
+ end
24
+
25
+ # t 'tag_name' do; end # Doesn't work on Android
26
+
27
+ t 'location_rel' do
28
+ loc = first_s_text.location_rel
29
+ loc.x.class.must_equal String
30
+ loc.y.class.must_equal String
31
+ end
32
+ end
33
+
34
+ describe 'common patch' do
35
+ # By default, the webdriver gem will return message instead of origValue
36
+ # {"message":"An unknown server-side error occurred while processing the command.","origValue":"Strategy id is not valid."}
37
+ t 'error_message' do
38
+ value = ''
39
+ begin
40
+ set_wait 0
41
+ find_element(:css, 'ok')
42
+ rescue Exception => e;
43
+ value = e.message
44
+ ensure
45
+ set_wait
46
+ end
47
+ value.must_equal "Invalid locator strategy: css selector"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,17 @@
1
+ describe 'version.rb' do
2
+ def before_first
3
+ screen.must_equal catalog
4
+ end
5
+
6
+ t 'before_first' do
7
+ before_first
8
+ end
9
+
10
+ t '::Appium::VERSION' do
11
+ ::Appium::VERSION.must_match /(\d+)\.(\d+).(\d+)/
12
+ end
13
+
14
+ t '::Appium::DATE' do
15
+ ::Appium::DATE.must_match /(\d+)\-(\d+)\-(\d+)/
16
+ end
17
+ end
@@ -0,0 +1,82 @@
1
+ describe 'device/device' do
2
+ def before_first
3
+ screen.must_equal catalog
4
+ end
5
+
6
+ t 'before_first' do
7
+ before_first
8
+ end
9
+
10
+ t 'lock' do
11
+ lock 5
12
+ tag('UIAButton').name.must_equal 'SlideToUnlock'
13
+
14
+ # It appears that lockForDuration doesn't.
15
+ close_app
16
+ launch
17
+ end
18
+
19
+ t 'background_app' do
20
+ background_app 5
21
+ screen.must_equal catalog
22
+ end
23
+
24
+ t 'is_installed' do
25
+ installed = is_installed? "Derrp"
26
+ installed.must_equal false
27
+ end
28
+
29
+ t 'shake' do
30
+ shake
31
+ end
32
+
33
+ t 'close and launch' do
34
+ close_app
35
+ launch
36
+ tag('UIANavigationBar').name.must_equal 'UICatalog'
37
+ end
38
+
39
+ t 'reset' do
40
+ reset
41
+ end
42
+
43
+ t 'available_contexts' do
44
+ available_contexts.must_equal ["NATIVE_APP"]
45
+ end
46
+
47
+ t 'current_context' do
48
+ current_context.must_equal nil
49
+ end
50
+
51
+ t 'switch_to_default_context' do
52
+ switch_to_default_context
53
+ current_context.must_equal nil
54
+ end
55
+
56
+ t 'app_strings' do
57
+ app_strings.must_include "SearchBarExplain"
58
+ end
59
+
60
+ t 'action_chain' do
61
+ ac = Appium::TouchAction.new
62
+ e = find_element(:name, 'Buttons, Various uses of UIButton')
63
+ ac.press element: e, x: 10, y: 10
64
+ ac.perform
65
+ back
66
+ end
67
+
68
+ t 'swipe' do
69
+ swipe start_x: 75, start_y: 500, end_x: 75, end_y: 0, duration: 0.8
70
+ end
71
+
72
+ t 'pinch & zoom' do
73
+ s_text('Images, Use of UIImageView').click
74
+ zoom 200
75
+ pinch 75
76
+ end
77
+
78
+ t 'file movement' do
79
+ read_file = pull_file 'Library/AddressBook/AddressBook.sqlitedb'
80
+ read_file.start_with?('SQLite format').must_equal true
81
+ end
82
+ end
@@ -0,0 +1,12 @@
1
+ describe 'device/multi_touch' do
2
+ t { } # place holder test
3
+ end
4
+
5
+ # todo: write tests
6
+ =begin
7
+ pinch
8
+ zoom
9
+ initialize
10
+ add
11
+ perform
12
+ =end
@@ -0,0 +1,15 @@
1
+ describe 'device/touch_actions' do
2
+ t { } # place holder test
3
+ end
4
+ # todo: write tests
5
+ =begin
6
+ move_to
7
+ press_for_duration
8
+ press
9
+ release
10
+ tap
11
+ wait
12
+ swipe
13
+ perform
14
+ cancel
15
+ =end
@@ -0,0 +1,203 @@
1
+ # rake ios[driver]
2
+ describe 'driver' 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
+ def is_sauce
12
+ ENV['UPLOAD_FILE'] && ENV['SAUCE_USERNAME']
13
+ end
14
+
15
+ t 'load_appium_txt' do
16
+ # skip this test if we're using Sauce
17
+ # the storage API doesn't have an on disk file
18
+ skip if is_sauce
19
+ # __FILE__ is '(eval)' so use env var set by the Rakefile
20
+ path = ENV['APPIUM_TXT']
21
+ opts = Appium.load_appium_txt file: path, verbose: true
22
+
23
+ actual = ''
24
+ actual = File.basename opts[:caps][:app] if opts && opts[:caps]
25
+ expected = 'UICatalog.app'
26
+ assert_equal expected, actual
27
+ end
28
+
29
+ describe 'Appium::Driver attributes' do
30
+ t 'verify all attributes' do
31
+ 2.times { set_wait 30 } # must set twice to validate last_waits
32
+ actual = driver_attributes
33
+ actual[:caps][:app] = File.basename actual[:caps][:app]
34
+ expected = { caps: { platformName: 'ios',
35
+ app: 'UICatalog.app' },
36
+ custom_url: false,
37
+ export_session: false,
38
+ default_wait: 30,
39
+ last_waits: [30, 30],
40
+ sauce_username: nil,
41
+ sauce_access_key: nil,
42
+ port: 4723,
43
+ device: :ios,
44
+ debug: true }
45
+
46
+ if actual != expected
47
+ diff = HashDiff.diff expected, actual
48
+ diff = "diff (expected, actual):\n#{diff}"
49
+ # example:
50
+ # change :ios in expected to match 'ios' in actual
51
+ # [["~", "caps.platformName", :ios, "ios"]]
52
+ message = "\n\nactual:\n\n: #{actual.ai}expected:\n\n#{expected.ai}\n\n#{diff}"
53
+ fail message
54
+ end
55
+ end
56
+
57
+ t 'verify attributes are immutable' do
58
+ driver_attributes[:caps][:app] = 'fake'
59
+ actual = File.basename driver_attributes[:caps][:app]
60
+ expected = 'UICatalog.app'
61
+ actual.must_equal expected
62
+ end
63
+
64
+ t 'no_wait' do
65
+ no_wait
66
+ default_wait.must_equal 0
67
+ set_wait 30
68
+ end
69
+
70
+ t 'default_wait attr' do
71
+ set_wait 31 # set wait and no_wait update default_wait
72
+ default_wait.must_equal 31
73
+ set_wait 30
74
+ end
75
+
76
+ t 'app_path attr' do
77
+ apk_name = File.basename driver_attributes[:caps][:app]
78
+
79
+ if is_sauce
80
+ apk_name.must_equal 'sauce-storage:UICatalog6.1.app.zip'
81
+ else
82
+ apk_name.must_equal 'UICatalog.app'
83
+ end
84
+ end
85
+
86
+ # Only used for Sauce Labs
87
+ t 'app_name attr' do
88
+ name_attr = driver_attributes[:caps][:name]
89
+ if is_sauce
90
+ name_attr.must_equal 'appium_lib_ios'
91
+ else
92
+ name_attr.must_be_nil
93
+ end
94
+ end
95
+
96
+ t 'sauce_username attr' do
97
+ sauce_username = driver_attributes[:sauce_username]
98
+ if is_sauce
99
+ sauce_username.must_equal 'appiumci'
100
+ else
101
+ sauce_username.must_be_nil
102
+ end
103
+ end
104
+
105
+ t 'sauce_access_key attr' do
106
+ sauce_access_key = driver_attributes[:sauce_access_key]
107
+ if is_sauce
108
+ sauce_access_key.must_match /\h{8}-\h{4}-\h{4}-\h{4}-\h{12}/
109
+ else
110
+ sauce_access_key.must_be_nil
111
+ end
112
+ end
113
+ end
114
+
115
+ describe 'Appium::Driver' do
116
+ t '@@loaded' do
117
+ loaded = $driver.class.class_variable_get :@@loaded
118
+ loaded.must_equal true
119
+ end
120
+
121
+ t '$driver.class' do
122
+ $driver.class.must_equal Appium::Driver
123
+ end
124
+ end
125
+
126
+ describe 'methods' do
127
+ t 'status' do
128
+ appium_server_version['build'].keys.sort.must_equal %w(revision version)
129
+ end
130
+
131
+ t 'server_version' do
132
+ server_version = appium_server_version['build']['version']
133
+ if is_sauce
134
+ server_version.must_match 'Sauce OnDemand'
135
+ else
136
+ server_version.must_match /(\d+)\.(\d+).(\d+)/
137
+ end
138
+ end
139
+
140
+ t 'restart' do
141
+ restart
142
+ s_text 'buttons'
143
+ end
144
+
145
+ t 'driver' do
146
+ driver.browser.must_equal :iOS
147
+ end
148
+
149
+ =begin
150
+ Skip:
151
+ screenshot # this is slow and already tested by Appium
152
+ driver_quit # tested by restart
153
+ start_driver # tested by restart
154
+ =end
155
+ t 'set_wait' do
156
+ # fill the @last_waits array with: [30, 30]
157
+ set_wait(30).must_equal(30)
158
+ set_wait(30).must_equal(30)
159
+
160
+ # verify set_wait with no args works correctly
161
+ set_wait.must_equal(30)
162
+ set_wait(30).must_equal(30)
163
+ set_wait.must_equal(30)
164
+
165
+ set_wait(2).must_equal(2)
166
+ set_wait.must_equal(30)
167
+ set_wait(3).must_equal(3)
168
+ set_wait.must_equal(2)
169
+
170
+ set_wait(2).must_equal(2)
171
+ set_wait(3).must_equal(3)
172
+ set_wait.must_equal(2)
173
+ end
174
+
175
+ t 'default_wait' do
176
+ set_wait 30
177
+ default_wait.must_equal 30 # set in run.rb
178
+ end
179
+
180
+ # returns true unless an error is raised
181
+ t 'exists' do
182
+ exists(0, 0) { true }.must_equal true
183
+ exists(0, 0) { raise 'error' }.must_equal false
184
+ end
185
+
186
+ # any script
187
+ t 'execute_script' do
188
+ execute_script %q(au.mainApp().getFirstWithPredicate("name contains[c] 'button'");)
189
+ end
190
+
191
+ # any elements
192
+ t 'find_elements' do
193
+ find_elements(:class, 'UIAStaticText').length.must_equal 13
194
+ end
195
+
196
+ # any element
197
+ t 'find_element' do
198
+ find_element(:class, 'UIAStaticText').class.must_equal Selenium::WebDriver::Element
199
+ end
200
+
201
+ # Skip: x # x is only used in Pry
202
+ end
203
+ end
@@ -0,0 +1,48 @@
1
+ # rake ios[ios/element/alert]
2
+ describe 'ios/element/alert' do
3
+ def nav_once
4
+ screen.must_equal catalog
5
+ wait_true { s_text('alerts').click; tag('UIANavigationBar').name == 'Alerts' } # wait for true
6
+ tag('UIANavigationBar').name.must_equal 'Alerts'
7
+
8
+ # redefine method as no-op after it's invoked once
9
+ self.class.send :define_method, :nav_once, proc {}
10
+ end
11
+
12
+ def after_last
13
+ alert_accept if exists { s_text('UIActionSheet <title>') }
14
+ back_click
15
+ screen.must_equal catalog
16
+ sleep 1
17
+ end
18
+
19
+ before do
20
+ nav_once
21
+ open_alert
22
+ end
23
+
24
+ def open_alert
25
+ wait_true do
26
+ return true if exists { s_text('UIActionSheet <title>') }
27
+ s_text('Show OK-Cancel').click
28
+ s_text('UIActionSheet <title>').displayed?
29
+ end
30
+ end
31
+
32
+ # iOS 7 is not using the alert methods. alert is nil.
33
+ def ios7_alert_detected
34
+ execute_script 'UIATarget.localTarget().frontMostApp().alert().isNil()'
35
+ end
36
+
37
+ t 'alert_accept' do
38
+ alert_accept
39
+ end
40
+
41
+ t 'alert_dismiss' do
42
+ alert_dismiss
43
+ end
44
+
45
+ t 'after_last' do
46
+ after_last
47
+ end
48
+ end
@@ -0,0 +1,58 @@
1
+ # rake ios['ios/element/button']
2
+ describe 'ios/element/button' do
3
+ def before_first
4
+ screen.must_equal catalog
5
+ # nav to buttons activity
6
+ wait { s_text('buttons').click }
7
+ end
8
+
9
+ def after_last
10
+ # nav back to start
11
+ back_click
12
+ end
13
+
14
+ t 'before_first' do
15
+ before_first
16
+ end
17
+
18
+ def gray
19
+ 'Gray'
20
+ end
21
+
22
+ t 'button' do
23
+ # by index
24
+ button(2).name.must_equal gray
25
+
26
+ # by name contains
27
+ button('ray').name.must_equal gray
28
+ end
29
+
30
+ t 'buttons' do
31
+ exp = ['Back', 'Gray', 'Right pointing arrow']
32
+ buttons('a').map { |e| e.name }.must_equal exp
33
+ end
34
+
35
+ t 'first_button' do
36
+ first_button.name.must_equal 'Back'
37
+ end
38
+
39
+ t 'last_button' do
40
+ last_button.name.must_equal 'Rounded'
41
+ end
42
+
43
+ t 'button_exact' do
44
+ button_exact(gray).name.must_equal gray
45
+ end
46
+
47
+ t 'buttons_exact' do
48
+ buttons_exact(gray).first.name.must_equal gray
49
+ end
50
+
51
+ t 'e_buttons' do
52
+ e_buttons.length.must_equal 4
53
+ end
54
+
55
+ t 'after_last' do
56
+ after_last
57
+ end
58
+ end