appium_lib 9.0.0 → 9.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +21 -0
- data/android_tests/lib/android/specs/android/helper.rb +3 -5
- data/android_tests/lib/android/specs/common/command.rb +47 -0
- data/android_tests/lib/android/specs/common/helper.rb +8 -8
- data/android_tests/lib/android/specs/common/web_context.rb +1 -1
- data/android_tests/lib/android/specs/driver.rb +19 -11
- data/android_tests/lib/format.rb +3 -3
- data/android_tests/lib/run.rb +7 -5
- data/android_tests/readme.md +1 -1
- data/appium_lib.gemspec +6 -7
- data/contributing.md +10 -0
- data/docs/android_docs.md +252 -217
- data/docs/ios_docs.md +257 -222
- data/docs/ios_xcuitest.md +32 -4
- data/ios_tests/lib/common.rb +11 -55
- data/ios_tests/lib/ios/specs/common/command.rb +44 -0
- data/ios_tests/lib/ios/specs/common/helper.rb +8 -8
- data/ios_tests/lib/ios/specs/device/device.rb +5 -5
- data/ios_tests/lib/ios/specs/driver.rb +34 -15
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +1 -1
- data/ios_tests/readme.md +1 -1
- data/ios_tests/upload/sauce_storage.rb +10 -8
- data/lib/appium_lib/android/element/button.rb +3 -3
- data/lib/appium_lib/android/element/text.rb +1 -1
- data/lib/appium_lib/android/element/textfield.rb +1 -1
- data/lib/appium_lib/android/helper.rb +12 -12
- data/lib/appium_lib/android/mobile_methods.rb +1 -3
- data/lib/appium_lib/common/command.rb +55 -0
- data/lib/appium_lib/common/helper.rb +7 -7
- data/lib/appium_lib/common/patch.rb +21 -8
- data/lib/appium_lib/common/search_context.rb +10 -0
- data/lib/appium_lib/common/version.rb +2 -2
- data/lib/appium_lib/common/wait.rb +8 -14
- data/lib/appium_lib/device/device.rb +65 -83
- data/lib/appium_lib/device/multi_touch.rb +2 -2
- data/lib/appium_lib/device/touch_actions.rb +4 -7
- data/lib/appium_lib/driver.rb +66 -38
- data/lib/appium_lib/ios/element/alert.rb +4 -4
- data/lib/appium_lib/ios/element/textfield.rb +3 -3
- data/lib/appium_lib/ios/errors.rb +6 -0
- data/lib/appium_lib/ios/helper.rb +25 -25
- data/lib/appium_lib/ios/mobile_methods.rb +2 -4
- data/readme.md +3 -1
- data/release_notes.md +13 -0
- metadata +23 -12
data/docs/ios_xcuitest.md
CHANGED
@@ -5,21 +5,49 @@
|
|
5
5
|
- How to migrate XCUITest from UIAutomation
|
6
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
7
|
|
8
|
-
|
9
|
-
### Elements
|
8
|
+
## find elements
|
10
9
|
- supported elements by find_element is:
|
11
10
|
- [appium-xcuitest-driver](https://github.com/appium/appium-xcuitest-driver/blob/master/lib/commands/find.js#L17)
|
12
11
|
- [WebDriverAgent](https://github.com/facebook/WebDriverAgent/blob/8346199212bffceab24192e81bc0118d65132466/WebDriverAgentLib/Commands/FBFindElementCommands.m#L111)
|
13
12
|
- Mapping
|
14
13
|
- https://github.com/facebook/WebDriverAgent/blob/master/WebDriverAgentLib/Utilities/FBElementTypeTransformer.m#L19
|
15
14
|
|
16
|
-
### XPath
|
15
|
+
### with except for XPath
|
16
|
+
#### examples
|
17
|
+
- [button_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/button.rb#L8), [static_text_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/text.rb#L8), [text_field_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/textfield.rb#L10) and [secure_text_field_class](https://github.com/appium/ruby_lib/blob/master/lib/appium_lib/ios/element/textfield.rb#L15) provide class name.
|
18
|
+
- If `automationName` is `Appium`, then they provide `UIAxxxx`
|
19
|
+
- If `automationName` is `XCUITest`, then they provide `XCUIElementTypexxx`
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
find_element(:class, button_class) # Return a element of XCUIElementTypeButton for XCUITest
|
23
|
+
```
|
24
|
+
|
25
|
+
- [tag/s](https://github.com/appium/ruby_lib/blob/ac03116756a72fbd624fa32ea886123b955d7089/lib/appium_lib/android/helper.rb#L238) is alias of `find_element :class, element`
|
26
|
+
|
27
|
+
- `accessibility_id`
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
find_element(:accessibility_id, element) # Return a element which has accessibilityIdentifier, `element`.
|
31
|
+
```
|
32
|
+
|
33
|
+
### with XPath
|
17
34
|
- It is better to avoid XPath strategy.
|
18
35
|
- https://github.com/appium/appium/blob/v1.6.2/docs/en/advanced-concepts/migrating-to-xcuitest.md#xpath-locator-strategy
|
19
|
-
|
36
|
+
- > 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
37
|
- Improved performance a bit
|
21
38
|
- https://github.com/appium/appium/issues/6842
|
22
39
|
- https://github.com/facebook/WebDriverAgent/issues/306
|
23
40
|
- XPath in WebDriverAgent
|
24
41
|
- https://github.com/facebook/WebDriverAgent/blob/2158a8d0f305549532f1338fe1e4628cfbd53cd9/WebDriverAgentLib/Categories/XCElementSnapshot%2BFBHelpers.m#L57
|
25
42
|
|
43
|
+
#### examples
|
44
|
+
- `button/s(value)`, `textfield/s(value)`, `text/s(value)` uses XPath in their method. So, these methods are slower than other find_element directly.
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
button(value) # Return a XCUIElementTypeButton element which has `value` text.
|
48
|
+
textfield(value) # Return a XCUIElementTypeSecureTextField or XCUIElementTypeTextField element which has `value` text.
|
49
|
+
text(value) # Return a XCUIElementTypeStaticText element which has `value` text.
|
50
|
+
```
|
51
|
+
|
52
|
+
## Other actions
|
53
|
+
Basically, other actions such as `type` is compatible with `automationName = Appium`.
|
data/ios_tests/lib/common.rb
CHANGED
@@ -38,91 +38,47 @@ module UI
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def self.navbar
|
41
|
-
|
42
|
-
'XCUIElementTypeNavigationBar'
|
43
|
-
else
|
44
|
-
'UIANavigationBar'
|
45
|
-
end
|
41
|
+
xcuitest? ? 'XCUIElementTypeNavigationBar' : 'UIANavigationBar'
|
46
42
|
end
|
47
43
|
|
48
44
|
def self.button
|
49
|
-
|
50
|
-
'XCUIElementTypeButton'
|
51
|
-
else
|
52
|
-
'UIAButton'
|
53
|
-
end
|
45
|
+
xcuitest? ? 'XCUIElementTypeButton' : 'UIAButton'
|
54
46
|
end
|
55
47
|
|
56
48
|
def self.static_text
|
57
|
-
|
58
|
-
'XCUIElementTypeStaticText'
|
59
|
-
else
|
60
|
-
'UIAStaticText'
|
61
|
-
end
|
49
|
+
xcuitest? ? 'XCUIElementTypeStaticText' : 'UIAStaticText'
|
62
50
|
end
|
63
51
|
|
64
52
|
def self.text_field
|
65
|
-
|
66
|
-
'XCUIElementTypeTextField'
|
67
|
-
else
|
68
|
-
'UIATextField'
|
69
|
-
end
|
53
|
+
xcuitest? ? 'XCUIElementTypeTextField' : 'UIATextField'
|
70
54
|
end
|
71
55
|
|
72
56
|
def self.secure_text_field
|
73
|
-
|
74
|
-
'XCUIElementTypeSecureTextField'
|
75
|
-
else
|
76
|
-
'UIASecureTextField'
|
77
|
-
end
|
57
|
+
xcuitest? ? 'XCUIElementTypeSecureTextField' : 'UIASecureTextField'
|
78
58
|
end
|
79
59
|
|
80
60
|
def self.picker
|
81
|
-
|
82
|
-
'XCUIElementTypePicker'
|
83
|
-
else
|
84
|
-
'UIAPicker'
|
85
|
-
end
|
61
|
+
xcuitest? ? 'XCUIElementTypePicker' : 'UIAPicker'
|
86
62
|
end
|
87
63
|
|
88
64
|
def self.action_sheet
|
89
|
-
|
90
|
-
'XCUIElementTypeActionSheet'
|
91
|
-
else
|
92
|
-
'UIActionSheet'
|
93
|
-
end
|
65
|
+
xcuitest? ? 'XCUIElementTypeActionSheet' : 'UIActionSheet'
|
94
66
|
end
|
95
67
|
|
96
68
|
def self.table
|
97
|
-
|
98
|
-
'XCUIElementTypeTable'
|
99
|
-
else
|
100
|
-
'UIATable'
|
101
|
-
end
|
69
|
+
xcuitest? ? 'XCUIElementTypeTable' : 'UIATable'
|
102
70
|
end
|
103
71
|
|
104
72
|
def self.table_cell
|
105
|
-
|
106
|
-
'XCUIElementTypeCell'
|
107
|
-
else
|
108
|
-
'UIATableCell'
|
109
|
-
end
|
73
|
+
xcuitest? ? 'XCUIElementTypeCell' : 'UIATableCell'
|
110
74
|
end
|
111
75
|
|
112
76
|
def self.other
|
113
|
-
|
114
|
-
'XCUIElementTypeOther'
|
115
|
-
else
|
116
|
-
fail 'unknown UIA element: other'
|
117
|
-
end
|
77
|
+
xcuitest? ? 'XCUIElementTypeOther' : raise('unknown UIA element: other')
|
118
78
|
end
|
119
79
|
|
120
80
|
def self.status_bar
|
121
|
-
|
122
|
-
'XCUIElementTypeStatusBar'
|
123
|
-
else
|
124
|
-
'UIAStatusBar'
|
125
|
-
end
|
81
|
+
xcuitest? ? 'XCUIElementTypeStatusBar' : 'UIAStatusBar'
|
126
82
|
end
|
127
83
|
end
|
128
84
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# rake ios[common/command]
|
2
|
+
describe 'common/command.rb' 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 'check all command no arg' do
|
12
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:shake).must_equal true
|
13
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:launch_app).must_equal true
|
14
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:close_app).must_equal true
|
15
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:reset).must_equal true
|
16
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:device_locked?).must_equal true
|
17
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:device_time).must_equal true
|
18
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:current_context).must_equal true
|
19
|
+
end
|
20
|
+
|
21
|
+
t 'check all command with arg' do
|
22
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:available_contexts).must_equal true
|
23
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:app_strings).must_equal true
|
24
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:lock).must_equal true
|
25
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:install_app).must_equal true
|
26
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:remove_app).must_equal true
|
27
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:app_installed?).must_equal true
|
28
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:background_app).must_equal true
|
29
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:start_activity).must_equal true
|
30
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:set_context).must_equal true
|
31
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:hide_keyboard).must_equal true
|
32
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:press_keycode).must_equal true
|
33
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:long_press_keycode).must_equal true
|
34
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:set_immediate_value).must_equal true
|
35
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:push_file).must_equal true
|
36
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:pull_file).must_equal true
|
37
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:pull_folder).must_equal true
|
38
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:touch_id).must_equal true
|
39
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:get_settings).must_equal true
|
40
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:update_settings).must_equal true
|
41
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:touch_actions).must_equal true
|
42
|
+
Selenium::WebDriver::Remote::Bridge.method_defined?(:multi_touch).must_equal true
|
43
|
+
end
|
44
|
+
end
|
@@ -24,12 +24,12 @@ describe 'common/helper.rb' do
|
|
24
24
|
wait(wait_opts) { nil }
|
25
25
|
|
26
26
|
# failed wait should error
|
27
|
-
proc { wait(wait_opts) {
|
27
|
+
proc { wait(wait_opts) { raise } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
28
28
|
|
29
29
|
# regular rescue will not handle exceptions outside of StandardError hierarchy
|
30
30
|
# must rescue Exception explicitly to rescue everything
|
31
|
-
proc { wait(wait_opts) {
|
32
|
-
proc { wait(timeout: 0.2, interval: 0.0) {
|
31
|
+
proc { wait(wait_opts) { raise NoMemoryError } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
32
|
+
proc { wait(timeout: 0.2, interval: 0.0) { raise NoMemoryError } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
33
33
|
|
34
34
|
# invalid keys are rejected
|
35
35
|
proc { wait(invalidkey: 2) { true } }.must_raise RuntimeError
|
@@ -40,8 +40,8 @@ describe 'common/helper.rb' do
|
|
40
40
|
ignore { true }
|
41
41
|
ignore { false }
|
42
42
|
ignore { nil }
|
43
|
-
ignore {
|
44
|
-
ignore {
|
43
|
+
ignore { raise }
|
44
|
+
ignore { raise NoMemoryError }
|
45
45
|
end
|
46
46
|
|
47
47
|
# wait_true is a success unless the value is not true
|
@@ -54,12 +54,12 @@ describe 'common/helper.rb' do
|
|
54
54
|
proc { wait_true(wait_opts) { nil } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
55
55
|
|
56
56
|
# raise should error
|
57
|
-
proc { wait_true(wait_opts) {
|
57
|
+
proc { wait_true(wait_opts) { raise } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
58
58
|
|
59
59
|
# regular rescue will not handle exceptions outside of StandardError hierarchy
|
60
60
|
# must rescue Exception explicitly to rescue everything
|
61
|
-
proc { wait_true(wait_opts) {
|
62
|
-
proc { wait_true(timeout: 0.2, interval: 0.0) {
|
61
|
+
proc { wait_true(wait_opts) { raise NoMemoryError } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
62
|
+
proc { wait_true(timeout: 0.2, interval: 0.0) { raise NoMemoryError } }
|
63
63
|
.must_raise Selenium::WebDriver::Error::TimeOutError
|
64
64
|
|
65
65
|
# invalid keys are rejected
|
@@ -18,7 +18,7 @@ describe 'device/device' do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
t 'lock' do
|
21
|
-
|
21
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
22
22
|
|
23
23
|
lock 5
|
24
24
|
tag(UI::Inventory.button).name.must_equal 'SlideToUnlock'
|
@@ -34,14 +34,14 @@ describe 'device/device' do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
t 'app_installed' do
|
37
|
-
|
37
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
38
38
|
|
39
39
|
installed = app_installed? 'Derrp'
|
40
40
|
installed.must_equal false
|
41
41
|
end
|
42
42
|
|
43
43
|
t 'shake' do
|
44
|
-
|
44
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
45
45
|
|
46
46
|
shake
|
47
47
|
end
|
@@ -87,7 +87,7 @@ describe 'device/device' do
|
|
87
87
|
t 'pull_file' do
|
88
88
|
# Selenium::WebDriver::Error::UnknownError: An unknown server-side error occurred while processing the command.
|
89
89
|
# Original error: Cannot read property 'getDir' of undefined
|
90
|
-
|
90
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
91
91
|
|
92
92
|
read_file = pull_file 'Library/AddressBook/AddressBook.sqlitedb'
|
93
93
|
read_file.start_with?('SQLite format').must_equal true
|
@@ -96,7 +96,7 @@ describe 'device/device' do
|
|
96
96
|
t 'pull_folder' do
|
97
97
|
# Selenium::WebDriver::Error::UnknownError: An unknown server-side error occurred while processing the command.
|
98
98
|
# Original error: Cannot read property 'getDir' of undefined
|
99
|
-
|
99
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
100
100
|
|
101
101
|
data = pull_folder 'Library/AddressBook'
|
102
102
|
data.length.must_be :>, 1
|
@@ -33,13 +33,16 @@ describe 'driver' do
|
|
33
33
|
describe 'Appium::Driver attributes' do
|
34
34
|
t 'verify all attributes' do
|
35
35
|
2.times { set_wait 30 } # must set twice to validate last_waits
|
36
|
-
actual
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
36
|
+
actual = driver_attributes
|
37
|
+
caps_app_for_teardown = actual[:caps][:app]
|
38
|
+
actual[:caps][:app] = File.basename actual[:caps][:app]
|
39
|
+
|
40
|
+
expected_caps = ::Appium::Driver::Capabilities.init_caps_for_appium(platformName: 'ios',
|
41
|
+
platformVersion: '10.1',
|
42
|
+
automationName: 'XCUITest',
|
43
|
+
deviceName: 'iPhone Simulator',
|
44
|
+
app: 'UICatalog.app')
|
45
|
+
expected = { caps: expected_caps,
|
43
46
|
custom_url: false,
|
44
47
|
export_session: false,
|
45
48
|
default_wait: 30,
|
@@ -54,19 +57,35 @@ describe 'driver' do
|
|
54
57
|
if actual != expected
|
55
58
|
diff = HashDiff.diff expected, actual
|
56
59
|
diff = "diff (expected, actual):\n#{diff}"
|
60
|
+
|
61
|
+
actual[:caps][:app] = caps_app_for_teardown
|
57
62
|
# example:
|
58
63
|
# change :ios in expected to match 'ios' in actual
|
59
64
|
# [["~", "caps.platformName", :ios, "ios"]]
|
60
65
|
message = "\n\nactual:\n\n: #{actual.ai}expected:\n\n#{expected.ai}\n\n#{diff}"
|
61
|
-
|
66
|
+
raise message
|
62
67
|
end
|
68
|
+
|
69
|
+
actual_selenium_caps = actual[:caps][:automationName]
|
70
|
+
actual_selenium_caps.must_equal 'XCUITest'
|
71
|
+
actual[:caps][:app] = caps_app_for_teardown
|
63
72
|
end
|
64
73
|
|
65
74
|
t 'verify attributes are immutable' do
|
75
|
+
driver_attributes[:custom_url] = true
|
76
|
+
expected = false
|
77
|
+
driver_attributes[:custom_url].must_equal expected
|
78
|
+
end
|
79
|
+
|
80
|
+
t 'verify attribute of :caps are not immutable becuse it depends on Selenium' do
|
81
|
+
# immutability depends on Selenium
|
82
|
+
for_clean_up = driver_attributes[:caps][:app].dup
|
66
83
|
driver_attributes[:caps][:app] = 'fake'
|
67
|
-
|
68
|
-
expected
|
69
|
-
|
84
|
+
expected = 'fake'
|
85
|
+
driver_attributes[:caps][:app].must_equal expected
|
86
|
+
|
87
|
+
# clean up
|
88
|
+
driver_attributes[:caps][:app] = for_clean_up
|
70
89
|
end
|
71
90
|
|
72
91
|
t 'no_wait' do
|
@@ -188,12 +207,12 @@ describe 'driver' do
|
|
188
207
|
# returns true unless an error is raised
|
189
208
|
t 'exists' do
|
190
209
|
exists(0, 0) { true }.must_equal true
|
191
|
-
exists(0, 0) {
|
210
|
+
exists(0, 0) { raise 'error' }.must_equal false
|
192
211
|
end
|
193
212
|
|
194
213
|
# simple integration sanity test to check for unexpected exceptions
|
195
214
|
t 'set_location' do
|
196
|
-
|
215
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
197
216
|
set_location latitude: 55, longitude: -72, altitude: 33
|
198
217
|
end
|
199
218
|
|
@@ -209,12 +228,12 @@ describe 'driver' do
|
|
209
228
|
|
210
229
|
# settings
|
211
230
|
t 'get settings' do
|
212
|
-
|
231
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
213
232
|
get_settings.wont_be_nil
|
214
233
|
end
|
215
234
|
|
216
235
|
t 'update settings' do
|
217
|
-
|
236
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support yet" if UI::Inventory.xcuitest?
|
218
237
|
|
219
238
|
update_settings cyberdelia: 'open'
|
220
239
|
get_settings['cyberdelia'].must_equal 'open'
|
@@ -34,7 +34,7 @@ describe 'ios/element/textfield' do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
t 'predicate textfields' do
|
37
|
-
|
37
|
+
raise NotImplementedError, "XCUITest(Appium1.6.2) doesn't support UIAutomation script" if UI::Inventory.xcuitest?
|
38
38
|
|
39
39
|
textfield_count = execute_script(%(au.mainApp().getAllWithPredicate("type contains[c] 'textfield'", true))).length
|
40
40
|
textfield_count.must_equal 4
|
data/ios_tests/readme.md
CHANGED
@@ -38,9 +38,9 @@ class SauceStorage
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def upload(file_path)
|
41
|
-
file_name
|
42
|
-
file
|
43
|
-
|
41
|
+
file_name = File.basename file_path
|
42
|
+
file = File.new file_path
|
43
|
+
local_md_5 = Digest::MD5.hexdigest File.read file_path
|
44
44
|
|
45
45
|
files.each do |f|
|
46
46
|
if f['md5'] == local_md5
|
@@ -50,16 +50,18 @@ class SauceStorage
|
|
50
50
|
end
|
51
51
|
|
52
52
|
url = "#{@url}/#{file_name}?overwrite=plz"
|
53
|
-
|
53
|
+
json = RestClient.post(url, file, content_type: 'application/octet-stream')
|
54
|
+
remote_md_5 = JSON.parse(json)['md5']
|
54
55
|
if @debug
|
55
56
|
puts "Uploaded #{file_path}"
|
56
|
-
puts " local_md5: #{
|
57
|
-
puts "remote_md5: #{
|
57
|
+
puts " local_md5: #{local_md_5}"
|
58
|
+
puts "remote_md5: #{remote_md_5}"
|
58
59
|
end
|
59
|
-
|
60
|
+
local_md_5 == remote_md_5
|
60
61
|
end
|
61
62
|
|
62
63
|
def files
|
63
|
-
|
64
|
+
get = RestClient.get @url
|
65
|
+
JSON.parse(get)['files']
|
64
66
|
end
|
65
67
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# UIAButton methods
|
2
2
|
module Appium
|
3
3
|
module Android
|
4
|
-
Button = 'android.widget.Button'
|
5
|
-
ImageButton = 'android.widget.ImageButton'
|
4
|
+
Button = 'android.widget.Button'.freeze
|
5
|
+
ImageButton = 'android.widget.ImageButton'.freeze
|
6
6
|
|
7
7
|
private
|
8
8
|
|
@@ -45,7 +45,7 @@ module Appium
|
|
45
45
|
# Android needs to combine button and image button to match iOS.
|
46
46
|
if value.is_a? Numeric
|
47
47
|
index = value
|
48
|
-
|
48
|
+
raise "#{index} is not a valid index. Must be >= 1" if index <= 0
|
49
49
|
|
50
50
|
return find_element :uiautomator, _button_visible_selectors(index: index)
|
51
51
|
end
|