appium_lib 8.2.1 → 9.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/android_tests/lib/android/specs/common/device_touchaction.rb +2 -2
  3. data/appium_lib.gemspec +2 -2
  4. data/docs/android_docs.md +245 -212
  5. data/docs/docs.md +17 -15
  6. data/docs/index_paths.md +2 -2
  7. data/docs/ios_docs.md +422 -240
  8. data/docs/ios_xcuitest.md +25 -0
  9. data/ios_tests/Gemfile +2 -0
  10. data/ios_tests/appium.txt +2 -1
  11. data/ios_tests/lib/common.rb +98 -4
  12. data/ios_tests/lib/ios/specs/common/helper.rb +24 -28
  13. data/ios_tests/lib/ios/specs/common/patch.rb +1 -1
  14. data/ios_tests/lib/ios/specs/device/device.rb +17 -11
  15. data/ios_tests/lib/ios/specs/device/multi_touch.rb +22 -1
  16. data/ios_tests/lib/ios/specs/device/touch_actions.rb +14 -5
  17. data/ios_tests/lib/ios/specs/driver.rb +13 -9
  18. data/ios_tests/lib/ios/specs/ios/element/alert.rb +12 -8
  19. data/ios_tests/lib/ios/specs/ios/element/button.rb +6 -3
  20. data/ios_tests/lib/ios/specs/ios/element/text.rb +5 -3
  21. data/ios_tests/lib/ios/specs/ios/element/textfield.rb +12 -8
  22. data/ios_tests/lib/ios/specs/ios/helper.rb +9 -3
  23. data/ios_tests/lib/ios/specs/ios/patch.rb +9 -1
  24. data/ios_tests/readme.md +3 -2
  25. data/lib/appium_lib/common/error.rb +5 -0
  26. data/lib/appium_lib/common/version.rb +2 -2
  27. data/lib/appium_lib/device/device.rb +7 -1
  28. data/lib/appium_lib/device/multi_touch.rb +27 -9
  29. data/lib/appium_lib/device/touch_actions.rb +12 -5
  30. data/lib/appium_lib/driver.rb +29 -1
  31. data/lib/appium_lib/ios/element/button.rb +50 -24
  32. data/lib/appium_lib/ios/element/generic.rb +20 -4
  33. data/lib/appium_lib/ios/element/text.rb +48 -24
  34. data/lib/appium_lib/ios/element/textfield.rb +80 -40
  35. data/lib/appium_lib/ios/helper.rb +107 -33
  36. data/lib/appium_lib/ios/mobile_methods.rb +1 -0
  37. data/lib/appium_lib/ios/patch.rb +5 -2
  38. data/readme.md +1 -0
  39. data/release_notes.md +10 -0
  40. metadata +16 -2
@@ -0,0 +1,25 @@
1
+ ## XCUITest
2
+ - Over Appium1.6.0 provides `XCUITest` automation name based on WebDriverAgent.
3
+ - [appium-xcuitest-driver](https://github.com/appium/appium-xcuitest-driver)
4
+ - [WebDriverAgent](https://github.com/facebook/WebDriverAgent)
5
+ - How to migrate XCUITest from UIAutomation
6
+ - [Migrating your iOS tests from UIAutomation](https://github.com/appium/appium/blob/v1.6.2/docs/en/advanced-concepts/migrating-to-xcuitest.md)
7
+
8
+
9
+ ### Elements
10
+ - supported elements by find_element is:
11
+ - [appium-xcuitest-driver](https://github.com/appium/appium-xcuitest-driver/blob/master/lib/commands/find.js#L17)
12
+ - [WebDriverAgent](https://github.com/facebook/WebDriverAgent/blob/8346199212bffceab24192e81bc0118d65132466/WebDriverAgentLib/Commands/FBFindElementCommands.m#L111)
13
+ - Mapping
14
+ - https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBElementTypeTransformer.m#L19
15
+
16
+ ### XPath
17
+ - It is better to avoid XPath strategy.
18
+ - https://github.com/appium/appium/blob/v1.6.2/docs/en/advanced-concepts/migrating-to-xcuitest.md#xpath-locator-strategy
19
+ > Try not to use XPath locators unless there is absolutely no other alternatives. In general, xpath locators might be times slower, than other types of locators like accessibility id, class name and predicate (up to 100 times slower in some special cases). They are so slow, because xpath location is not natively supported by Apple's XCTest framework.
20
+ - Improved performance a bit
21
+ - https://github.com/appium/appium/issues/6842
22
+ - https://github.com/facebook/WebDriverAgent/issues/306
23
+ - XPath in WebDriverAgent
24
+ - https://github.com/facebook/WebDriverAgent/blob/2158a8d0f305549532f1338fe1e4628cfbd53cd9/WebDriverAgentLib/Categories/XCElementSnapshot%2BFBHelpers.m#L57
25
+
@@ -1,2 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec path: File.expand_path('../../', __FILE__) # __dir__ fails on 1.9
3
+
4
+ gem 'appium_console'
@@ -1,7 +1,8 @@
1
1
  [caps]
2
2
  platformName = "ios"
3
- platformVersion = "9.3"
3
+ platformVersion = "10.1"
4
4
  deviceName ="iPhone Simulator"
5
+ automationName = 'XCUITest'
5
6
  app = "./UICatalog.app"
6
7
 
7
8
  [appium_lib]
@@ -18,17 +18,111 @@ end
18
18
  def go_to_textfields
19
19
  screen.must_equal catalog
20
20
  wait_true do
21
- text('textfield').click
21
+ UI::Inventory.xcuitest? ? find_element(:name, 'TextFields').click : text('textfield').click
22
22
  screen == 'TextFields' # wait for screen transition
23
23
  end
24
-
25
- screen.must_equal 'TextFields'
26
24
  end
27
25
 
28
26
  def screen
29
- $driver.find_element(:class, 'UIANavigationBar').name
27
+ $driver.find_element(:class, UI::Inventory.navbar).name
30
28
  end
31
29
 
32
30
  def catalog
33
31
  'UICatalog'
34
32
  end
33
+
34
+ module UI
35
+ module Inventory
36
+ def self.xcuitest?
37
+ $driver.automation_name_is_xcuitest?
38
+ end
39
+
40
+ def self.navbar
41
+ if xcuitest?
42
+ 'XCUIElementTypeNavigationBar'
43
+ else
44
+ 'UIANavigationBar'
45
+ end
46
+ end
47
+
48
+ def self.button
49
+ if xcuitest?
50
+ 'XCUIElementTypeButton'
51
+ else
52
+ 'UIAButton'
53
+ end
54
+ end
55
+
56
+ def self.static_text
57
+ if xcuitest?
58
+ 'XCUIElementTypeStaticText'
59
+ else
60
+ 'UIAStaticText'
61
+ end
62
+ end
63
+
64
+ def self.text_field
65
+ if xcuitest?
66
+ 'XCUIElementTypeTextField'
67
+ else
68
+ 'UIATextField'
69
+ end
70
+ end
71
+
72
+ def self.secure_text_field
73
+ if xcuitest?
74
+ 'XCUIElementTypeSecureTextField'
75
+ else
76
+ 'UIASecureTextField'
77
+ end
78
+ end
79
+
80
+ def self.picker
81
+ if xcuitest?
82
+ 'XCUIElementTypePicker'
83
+ else
84
+ 'UIAPicker'
85
+ end
86
+ end
87
+
88
+ def self.action_sheet
89
+ if xcuitest?
90
+ 'XCUIElementTypeActionSheet'
91
+ else
92
+ 'UIActionSheet'
93
+ end
94
+ end
95
+
96
+ def self.table
97
+ if xcuitest?
98
+ 'XCUIElementTypeTable'
99
+ else
100
+ 'UIATable'
101
+ end
102
+ end
103
+
104
+ def self.table_cell
105
+ if xcuitest?
106
+ 'XCUIElementTypeCell'
107
+ else
108
+ 'UIATableCell'
109
+ end
110
+ end
111
+
112
+ def self.other
113
+ if xcuitest?
114
+ 'XCUIElementTypeOther'
115
+ else
116
+ fail 'unknown UIA element: other'
117
+ end
118
+ end
119
+
120
+ def self.status_bar
121
+ if xcuitest?
122
+ 'XCUIElementTypeStatusBar'
123
+ else
124
+ 'UIAStatusBar'
125
+ end
126
+ end
127
+ end
128
+ end
@@ -70,18 +70,18 @@ describe 'common/helper.rb' do
70
70
 
71
71
  t 'back' do
72
72
  # start page
73
- tag('UIANavigationBar').name.must_equal 'UICatalog'
73
+ tag(UI::Inventory.navbar).name.must_equal 'UICatalog'
74
74
  # nav to new page.
75
75
  wait_true do
76
76
  text('buttons').click
77
- tag('UIANavigationBar').name == 'Buttons'
77
+ tag(UI::Inventory.navbar).name == 'Buttons'
78
78
  end
79
79
 
80
- tag('UIANavigationBar').name.must_equal 'Buttons'
80
+ tag(UI::Inventory.navbar).name.must_equal 'Buttons'
81
81
  # go back
82
82
  back_click
83
83
  # start page
84
- tag('UIANavigationBar').name.must_equal 'UICatalog'
84
+ tag(UI::Inventory.navbar).name.must_equal 'UICatalog'
85
85
  end
86
86
 
87
87
  t 'session_id' do
@@ -90,11 +90,11 @@ describe 'common/helper.rb' do
90
90
  end
91
91
 
92
92
  t 'xpath' do
93
- xpath('//UIAStaticText').name.must_equal 'UICatalog'
93
+ xpath("//#{UI::Inventory.static_text}").name.must_equal 'UICatalog'
94
94
  end
95
95
 
96
96
  t 'xpaths' do
97
- xpaths('//UIAStaticText').length.must_equal 25
97
+ xpaths("//#{UI::Inventory.static_text}").length.must_equal 25
98
98
  end
99
99
 
100
100
  def uibutton_text
@@ -102,13 +102,13 @@ describe 'common/helper.rb' do
102
102
  end
103
103
 
104
104
  t 'ele_index' do
105
- ele_index('UIAStaticText', 2).name.must_equal uibutton_text
105
+ ele_index(UI::Inventory.static_text, 2).name.must_equal uibutton_text
106
106
  end
107
107
 
108
108
  # TODO: 'string_attr_exact'
109
109
 
110
110
  t 'find_ele_by_attr' do
111
- el_id = find_ele_by_attr('UIAStaticText', 'name', uibutton_text).instance_variable_get :@id
111
+ el_id = find_ele_by_attr(UI::Inventory.static_text, 'name', uibutton_text).instance_variable_get :@id
112
112
  el_id.must_match(/\d+/)
113
113
  end
114
114
 
@@ -117,10 +117,10 @@ describe 'common/helper.rb' do
117
117
  # no space after the !
118
118
  set_wait 1
119
119
  # empty array returned when no match
120
- found = !find_eles_by_attr('UIAStaticText', 'name', uibutton_text).empty?
120
+ found = !find_eles_by_attr(UI::Inventory.static_text, 'name', uibutton_text).empty?
121
121
  found.must_equal true
122
122
 
123
- found = !find_eles_by_attr('UIAStaticText', 'name', 'zz').empty?
123
+ found = !find_eles_by_attr(UI::Inventory.static_text, 'name', 'zz').empty?
124
124
  found.must_equal false
125
125
  set_wait
126
126
  end
@@ -128,26 +128,29 @@ describe 'common/helper.rb' do
128
128
  # TODO: 'string_attr_include'
129
129
 
130
130
  t 'find_ele_by_attr_include' do
131
- el_text = find_ele_by_attr_include('UIAStaticText', :name, 'button').text
131
+ el_text = find_ele_by_attr_include(UI::Inventory.static_text, :name, 'button').text
132
132
  el_text.must_equal uibutton_text
133
133
 
134
- el_name = find_ele_by_attr_include('UIAStaticText', :name, 'button').name
134
+ el_name = find_ele_by_attr_include(UI::Inventory.static_text, :name, 'button').name
135
135
  el_name.must_equal uibutton_text
136
136
  end
137
137
 
138
138
  t 'find_eles_by_attr_include' do
139
- ele_count = find_eles_by_attr_include('UIAStaticText', :name, 'e').length
140
- ele_count.must_equal 19
139
+ ele_count = find_eles_by_attr_include(UI::Inventory.static_text, :name, 'e').length
140
+ expected = UI::Inventory.xcuitest? ? 20 : 19
141
+ ele_count.must_equal expected
141
142
  end
142
143
 
143
144
  t 'first_ele' do
144
- first_ele('UIAStaticText').name.must_equal 'UICatalog'
145
+ first_ele(UI::Inventory.static_text).name.must_equal 'UICatalog'
145
146
  end
146
147
 
147
148
  t 'last_ele' do
148
- el = last_ele('UIAStaticText')
149
- el.text.must_equal 'Transitions'
150
- el.name.must_equal 'Transitions'
149
+ expected = UI::Inventory.xcuitest? ? 'Shows UIViewAnimationTransitions' : 'Transitions'
150
+
151
+ el = last_ele(UI::Inventory.static_text)
152
+ el.text.must_equal expected
153
+ el.name.must_equal expected
151
154
  end
152
155
 
153
156
  # t 'source' do # tested by get_source
@@ -156,10 +159,6 @@ describe 'common/helper.rb' do
156
159
  get_source.class.must_equal String
157
160
  end
158
161
 
159
- t 'id' do
160
- id 'ButtonsExplain' # 'Various uses of UIButton'
161
- end
162
-
163
162
  t 'invalid id should error' do
164
163
  proc { id 'does not exist' }.must_raise Selenium::WebDriver::Error::NoSuchElementError
165
164
 
@@ -168,15 +167,15 @@ describe 'common/helper.rb' do
168
167
  end
169
168
 
170
169
  t 'tag' do
171
- tag('UIATableCell').name.must_equal uibutton_text
170
+ tag(UI::Inventory.navbar).name.must_equal 'UICatalog'
172
171
  end
173
172
 
174
173
  t 'tags' do
175
- tags('UIATableCell').length.must_equal 12
174
+ tags(UI::Inventory.table_cell).length.must_equal 12
176
175
  end
177
176
 
178
177
  t 'find_eles_by_attr_include' do
179
- find_eles_by_attr_include('UIAStaticText', 'name', 'Use').length.must_equal 7
178
+ find_eles_by_attr_include(UI::Inventory.static_text, 'name', 'Use').length.must_equal 7
180
179
  end
181
180
 
182
181
  t 'get_page_class' do
@@ -185,10 +184,7 @@ describe 'common/helper.rb' do
185
184
  end
186
185
 
187
186
  # TODO: write tests
188
- # get_page_class
189
187
  # page_class
190
- # tag
191
- # tags
192
188
  # px_to_window_rel
193
189
  # lazy_load_strings
194
190
  # xml_keys
@@ -48,7 +48,7 @@ describe 'common/patch.rb' do
48
48
  ensure
49
49
  set_wait
50
50
  end
51
- value.must_equal 'Invalid locator strategy: css selector'
51
+ value.must_equal "Locator Strategy 'css selector' is not supported for this session"
52
52
  end
53
53
  end
54
54
  end
@@ -18,8 +18,10 @@ describe 'device/device' do
18
18
  end
19
19
 
20
20
  t 'lock' do
21
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
22
+
21
23
  lock 5
22
- tag('UIAButton').name.must_equal 'SlideToUnlock'
24
+ tag(UI::Inventory.button).name.must_equal 'SlideToUnlock'
23
25
 
24
26
  # It appears that lockForDuration doesn't.
25
27
  close_app
@@ -32,18 +34,22 @@ describe 'device/device' do
32
34
  end
33
35
 
34
36
  t 'app_installed' do
37
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
38
+
35
39
  installed = app_installed? 'Derrp'
36
40
  installed.must_equal false
37
41
  end
38
42
 
39
43
  t 'shake' do
44
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
45
+
40
46
  shake
41
47
  end
42
48
 
43
49
  t 'close and launch' do
44
50
  close_app
45
51
  launch_app
46
- tag('UIANavigationBar').name.must_equal 'UICatalog'
52
+ tag(UI::Inventory.navbar).name.must_equal 'UICatalog'
47
53
  end
48
54
 
49
55
  t 'reset' do
@@ -75,23 +81,23 @@ describe 'device/device' do
75
81
  end
76
82
 
77
83
  t 'swipe' do
78
- swipe start_x: 75, start_y: 500, delta_x: 75, delta_y: 0, duration: 800
79
- end
80
-
81
- t 'pinch & zoom' do
82
- wait { id('ImagesExplain').click }
83
- # both of these appear to do nothing on iOS 8
84
- zoom 200
85
- pinch 75
86
- go_back
84
+ swipe start_x: 75, start_y: 500, delta_x: 0, delta_y: -500, duration: 800
87
85
  end
88
86
 
89
87
  t 'pull_file' do
88
+ # Selenium::WebDriver::Error::UnknownError: An unknown server-side error occurred while processing the command.
89
+ # Original error: Cannot read property 'getDir' of undefined
90
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
91
+
90
92
  read_file = pull_file 'Library/AddressBook/AddressBook.sqlitedb'
91
93
  read_file.start_with?('SQLite format').must_equal true
92
94
  end
93
95
 
94
96
  t 'pull_folder' do
97
+ # Selenium::WebDriver::Error::UnknownError: An unknown server-side error occurred while processing the command.
98
+ # Original error: Cannot read property 'getDir' of undefined
99
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
100
+
95
101
  data = pull_folder 'Library/AddressBook'
96
102
  data.length.must_be :>, 1
97
103
  end
@@ -1,5 +1,26 @@
1
+ # rake ios[device/multi_touch]
1
2
  describe 'device/multi_touch' do
2
- t {} # place holder test
3
+ def before_first
4
+ screen.must_equal catalog
5
+ end
6
+
7
+ # go back to the main page
8
+ def go_back
9
+ back
10
+ wait { !exists { id 'ArrowButton' } } # successfully transitioned back
11
+ end
12
+
13
+ t 'before_first' do
14
+ before_first
15
+ end
16
+
17
+ t 'pinch & zoom' do
18
+ wait { id('Images').click }
19
+ # both of these appear to do nothing on iOS 8
20
+ zoom 200
21
+ pinch 75
22
+ go_back
23
+ end
3
24
  end
4
25
 
5
26
  # TODO: write tests
@@ -1,18 +1,27 @@
1
+ # rake ios[device/touch_actions]
1
2
  describe 'device/touch_actions' do
3
+ def after_last
4
+ back_click
5
+ end
6
+
2
7
  t 'swipe_default_duration' do
3
8
  wait_true do
4
- text('pickers').click
9
+ wait { UI::Inventory.xcuitest? ? find_element(:name, 'Pickers').click : text('pickers').click }
5
10
  screen == 'Pickers'
6
11
  end
7
12
 
8
- ele_index('UIAStaticText', 2).text.must_equal 'John Appleseed - 0'
9
- picker = ele_index('UIAPicker', 1)
13
+ ele_index(UI::Inventory.static_text, 2).text.must_equal 'John Appleseed - 0'
14
+ picker = ele_index(UI::Inventory.picker, 1)
10
15
  loc = picker.location.to_h
11
16
  size = picker.size.to_h
12
17
  start_x = loc[:x] + size[:width] / 2
13
18
  start_y = loc[:y] + size[:height] / 2
14
- swipe start_x: start_x, start_y: start_y, delta_x: start_x, delta_y: - 50
15
- ele_index('UIAStaticText', 2).text.must_equal 'Chris Armstrong - 0'
19
+ swipe start_x: start_x, start_y: start_y, delta_x: 0, delta_y: - 50
20
+ ele_index(UI::Inventory.static_text, 2).text.must_equal 'Chris Armstrong - 0'
21
+ end
22
+
23
+ t 'after_last' do
24
+ after_last
16
25
  end
17
26
  end
18
27
 
@@ -36,7 +36,8 @@ describe 'driver' do
36
36
  actual = driver_attributes
37
37
  actual[:caps][:app] = File.basename actual[:caps][:app]
38
38
  expected = { caps: { platformName: 'ios',
39
- platformVersion: '9.3',
39
+ platformVersion: '10.1',
40
+ automationName: 'XCUITest',
40
41
  deviceName: 'iPhone Simulator',
41
42
  app: 'UICatalog.app' },
42
43
  custom_url: false,
@@ -145,7 +146,11 @@ describe 'driver' do
145
146
  end
146
147
 
147
148
  t 'driver' do
148
- driver.browser.must_equal :iOS
149
+ driver.browser.must_be_empty
150
+ end
151
+
152
+ t 'automation_name_is_xcuitest?' do
153
+ automation_name_is_xcuitest?.must_equal UI::Inventory.xcuitest?
149
154
  end
150
155
 
151
156
  #
@@ -188,30 +193,29 @@ describe 'driver' do
188
193
 
189
194
  # simple integration sanity test to check for unexpected exceptions
190
195
  t 'set_location' do
196
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
191
197
  set_location latitude: 55, longitude: -72, altitude: 33
192
198
  end
193
199
 
194
- # any script
195
- t 'execute_script' do
196
- execute_script %q(au.mainApp().getFirstWithPredicate("name contains[c] 'button'");)
197
- end
198
-
199
200
  # any elements
200
201
  t 'find_elements' do
201
- find_elements(:class, 'UIATableCell').length.must_equal 12
202
+ find_elements(:class, UI::Inventory.table_cell).length.must_equal 12
202
203
  end
203
204
 
204
205
  # any element
205
206
  t 'find_element' do
206
- find_element(:class, 'UIAStaticText').class.must_equal Selenium::WebDriver::Element
207
+ find_element(:class, UI::Inventory.static_text).class.must_equal Selenium::WebDriver::Element
207
208
  end
208
209
 
209
210
  # settings
210
211
  t 'get settings' do
212
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
211
213
  get_settings.wont_be_nil
212
214
  end
213
215
 
214
216
  t 'update settings' do
217
+ fail NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
218
+
215
219
  update_settings cyberdelia: 'open'
216
220
  get_settings['cyberdelia'].must_equal 'open'
217
221
  end