appium_lib 9.4.5 → 9.4.6
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/appium_lib.gemspec +1 -1
- data/docs/android_docs.md +224 -224
- data/docs/ios_docs.md +250 -250
- data/lib/appium_lib/common/version.rb +1 -1
- data/release_notes.md +13 -0
- metadata +1 -109
- data/android_tests/Gemfile +0 -2
- data/android_tests/LICENSE-2.0.txt +0 -202
- data/android_tests/Rakefile +0 -68
- data/android_tests/api.apk +0 -0
- data/android_tests/appium.txt +0 -11
- data/android_tests/flaky.txt +0 -1
- data/android_tests/lib/android/specs/android/element/alert.rb +0 -48
- data/android_tests/lib/android/specs/android/element/button.rb +0 -52
- data/android_tests/lib/android/specs/android/element/generic.rb +0 -58
- data/android_tests/lib/android/specs/android/element/text.rb +0 -35
- data/android_tests/lib/android/specs/android/element/textfield.rb +0 -62
- data/android_tests/lib/android/specs/android/helper.rb +0 -111
- data/android_tests/lib/android/specs/android/patch.rb +0 -27
- data/android_tests/lib/android/specs/common/command.rb +0 -52
- data/android_tests/lib/android/specs/common/device.rb +0 -159
- data/android_tests/lib/android/specs/common/device_touchaction.rb +0 -34
- data/android_tests/lib/android/specs/common/element/window.rb +0 -11
- data/android_tests/lib/android/specs/common/helper.rb +0 -112
- data/android_tests/lib/android/specs/common/patch.rb +0 -78
- data/android_tests/lib/android/specs/common/version.rb +0 -9
- data/android_tests/lib/android/specs/common/web_context.rb +0 -60
- data/android_tests/lib/android/specs/device/touch_actions.rb +0 -71
- data/android_tests/lib/android/specs/driver.rb +0 -280
- data/android_tests/lib/android/specs/install.rb +0 -26
- data/android_tests/lib/format.rb +0 -47
- data/android_tests/lib/run.rb +0 -91
- data/android_tests/readme.md +0 -30
- data/grid/README.md +0 -21
- data/grid/appium.txt.ios.example +0 -15
- data/grid/config.json +0 -25
- data/grid/hub_config.json +0 -14
- data/grid/selenium-server-standalone-2.53.1.jar +0 -0
- data/grid/selenium-server-standalone-3.2.0.jar +0 -0
- data/ios_tests/Gemfile +0 -4
- data/ios_tests/LICENSE-2.0.txt +0 -202
- data/ios_tests/Rakefile +0 -54
- 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 +0 -1
- 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 +0 -15
- data/ios_tests/data/unicode.txt +0 -1
- data/ios_tests/flaky.txt +0 -1
- data/ios_tests/lib/common.rb +0 -84
- data/ios_tests/lib/format.rb +0 -23
- data/ios_tests/lib/ios/specs/common/command.rb +0 -45
- data/ios_tests/lib/ios/specs/common/element/window.rb +0 -17
- data/ios_tests/lib/ios/specs/common/helper.rb +0 -228
- data/ios_tests/lib/ios/specs/common/patch.rb +0 -54
- data/ios_tests/lib/ios/specs/common/version.rb +0 -17
- data/ios_tests/lib/ios/specs/common/web_context.rb +0 -15
- data/ios_tests/lib/ios/specs/device/device.rb +0 -130
- data/ios_tests/lib/ios/specs/device/multi_touch.rb +0 -31
- data/ios_tests/lib/ios/specs/device/touch_actions.rb +0 -90
- data/ios_tests/lib/ios/specs/driver.rb +0 -308
- data/ios_tests/lib/ios/specs/ios/element/alert.rb +0 -51
- data/ios_tests/lib/ios/specs/ios/element/button.rb +0 -58
- data/ios_tests/lib/ios/specs/ios/element/generic.rb +0 -37
- data/ios_tests/lib/ios/specs/ios/element/text.rb +0 -63
- data/ios_tests/lib/ios/specs/ios/element/textfield.rb +0 -135
- data/ios_tests/lib/ios/specs/ios/helper.rb +0 -59
- data/ios_tests/lib/ios/specs/ios/mobile_methods.rb +0 -20
- data/ios_tests/lib/ios/specs/ios/patch.rb +0 -34
- data/ios_tests/lib/ios/specs/ios/xcuitest_gestures.rb +0 -110
- data/ios_tests/lib/run.rb +0 -4
- data/ios_tests/readme.md +0 -31
- data/ios_tests/upload/sauce_storage.rb +0 -67
- data/ios_tests/upload/upload.rb +0 -6
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# rake android[common/device_touchaction]
|
|
2
|
-
describe 'common/device_touchaction' do
|
|
3
|
-
t 'action_chain' do
|
|
4
|
-
wait do
|
|
5
|
-
e = text('Accessibility')
|
|
6
|
-
touch_action = Appium::TouchAction.new.press(element: e, x: 0.5, y: 0.5).release(element: e)
|
|
7
|
-
touch_action.perform
|
|
8
|
-
touch_action.actions.must_equal []
|
|
9
|
-
end
|
|
10
|
-
wait { text('Custom View') }
|
|
11
|
-
back
|
|
12
|
-
wait { text_exact 'NFC' }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
t 'swipe' do
|
|
16
|
-
wait { Appium::TouchAction.new.swipe(start_x: 0.75, start_y: 0.25, end_x: 0.75, end_y: 50).perform }
|
|
17
|
-
wait { !exists { text_exact 'NFC' } }
|
|
18
|
-
wait { text_exact 'Bouncing Balls' }
|
|
19
|
-
back
|
|
20
|
-
wait { text_exact 'NFC' }
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
t 'pinch & zoom' do
|
|
24
|
-
wait { text_exact 'NFC' }
|
|
25
|
-
wait { text_exact('Graphics').click }
|
|
26
|
-
wait { text('BitmapMesh').click }
|
|
27
|
-
wait do
|
|
28
|
-
zoom 200
|
|
29
|
-
pinch 75
|
|
30
|
-
end
|
|
31
|
-
2.times { back }
|
|
32
|
-
wait { text_exact 'NFC' }
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# rake android[common/element/window]
|
|
2
|
-
describe 'common/element/window' do
|
|
3
|
-
# rubocop:disable Lint/UnifiedInteger
|
|
4
|
-
t 'window_size' do
|
|
5
|
-
wait do
|
|
6
|
-
size = window_size
|
|
7
|
-
size.width.class.must_equal Fixnum
|
|
8
|
-
size.height.class.must_equal Fixnum
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
end
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
describe 'common/helper' do
|
|
2
|
-
wait_opts = { timeout: 0.2, interval: 0.2 } # max_wait, interval
|
|
3
|
-
|
|
4
|
-
# There's no `must_not_raise` as the opposite of must_raise
|
|
5
|
-
|
|
6
|
-
# By default code is expected to not raise exceptions.
|
|
7
|
-
# must_not_raise is a no-op.
|
|
8
|
-
|
|
9
|
-
# wait is a success unless an error is raised
|
|
10
|
-
# max_wait=0 is infinity to use 0.1
|
|
11
|
-
t 'wait' do
|
|
12
|
-
# successful wait should not raise error
|
|
13
|
-
wait(wait_opts) { true }
|
|
14
|
-
wait(wait_opts) { false }
|
|
15
|
-
wait(wait_opts) { nil }
|
|
16
|
-
|
|
17
|
-
# failed wait should error
|
|
18
|
-
proc { wait(wait_opts) { raise } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
19
|
-
|
|
20
|
-
# regular rescue will not handle exceptions outside of StandardError hierarchy
|
|
21
|
-
# must rescue Exception explicitly to rescue everything
|
|
22
|
-
proc { wait(wait_opts) { raise NoMemoryError } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
23
|
-
proc { wait(timeout: 0.2, interval: 0.0) { raise NoMemoryError } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
24
|
-
|
|
25
|
-
# invalid keys are rejected
|
|
26
|
-
proc { wait(invalidkey: 2) { true } }.must_raise RuntimeError
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
t 'ignore' do
|
|
30
|
-
# ignore should rescue all exceptions
|
|
31
|
-
ignore { true }
|
|
32
|
-
ignore { false }
|
|
33
|
-
ignore { nil }
|
|
34
|
-
ignore { raise }
|
|
35
|
-
ignore { raise NoMemoryError }
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# wait_true is a success unless the value is not true
|
|
39
|
-
t 'wait_true' do
|
|
40
|
-
# successful wait should not error
|
|
41
|
-
wait_true(wait_opts) { true }
|
|
42
|
-
|
|
43
|
-
# failed wait should error
|
|
44
|
-
proc { wait_true(wait_opts) { false } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
45
|
-
proc { wait_true(wait_opts) { nil } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
46
|
-
|
|
47
|
-
# raise should error
|
|
48
|
-
proc { wait_true(wait_opts) { raise } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
49
|
-
|
|
50
|
-
# regular rescue will not handle exceptions outside of StandardError hierarchy
|
|
51
|
-
# must rescue Exception explicitly to rescue everything
|
|
52
|
-
proc { wait_true(wait_opts) { raise NoMemoryError } }.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
53
|
-
proc { wait_true(timeout: 0.2, interval: 0.0) { raise NoMemoryError } }
|
|
54
|
-
.must_raise Selenium::WebDriver::Error::TimeOutError
|
|
55
|
-
|
|
56
|
-
# invalid keys are rejected
|
|
57
|
-
proc { wait_true(invalidkey: 2) { true } }.must_raise RuntimeError
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
t 'back' do
|
|
61
|
-
# start page
|
|
62
|
-
wait { texts.length.must_equal 13 }
|
|
63
|
-
# nav to new page.
|
|
64
|
-
# ele 0 is the title and can't be clicked.
|
|
65
|
-
wait { text(2).click }
|
|
66
|
-
wait { texts.length.must_equal 5 }
|
|
67
|
-
# go back
|
|
68
|
-
back
|
|
69
|
-
# start page
|
|
70
|
-
wait { find 'NFC' }
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
t 'session_id' do
|
|
74
|
-
wait { session_id.must_match(/\h{8}-\h{4}-\h{4}-\h{4}-\h{12}/) }
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
t 'xpath' do
|
|
78
|
-
wait { xpath('//android.widget.TextView').name.must_equal 'API Demos' }
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
t 'xpaths' do
|
|
82
|
-
wait { xpaths('//android.widget.TextView').length.must_equal 13 }
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
t 'ele_index' do
|
|
86
|
-
wait { ele_index('android.widget.TextView', 3).name.must_equal 'Accessibility' }
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
t 'tags' do
|
|
90
|
-
wait { tags('android.widget.TextView').length.must_equal 13 }
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
t 'first_ele' do
|
|
94
|
-
wait do
|
|
95
|
-
first_ele('android.widget.TextView').text.must_equal 'API Demos'
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
t 'last_ele' do
|
|
100
|
-
wait do
|
|
101
|
-
last_ele('android.widget.TextView').text.must_equal 'Views'
|
|
102
|
-
end
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# t 'source' do # tested by get_source
|
|
106
|
-
|
|
107
|
-
t 'get_source' do
|
|
108
|
-
wait do
|
|
109
|
-
get_source.class.must_equal String
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# rubocop:disable Lint/RescueException
|
|
2
|
-
# rubocop:disable Metrics/LineLength
|
|
3
|
-
|
|
4
|
-
# Skip:
|
|
5
|
-
# status # status patches are already tested in driver.rb
|
|
6
|
-
# raw_execute # debug output for Pry
|
|
7
|
-
|
|
8
|
-
describe 'common/patch' do
|
|
9
|
-
# Attributes are busted in Android.
|
|
10
|
-
# Blocked on https://github.com/appium/appium/issues/628
|
|
11
|
-
describe 'Selenium::WebDriver::Element methods' do
|
|
12
|
-
# Android supports exactly two string Attributes
|
|
13
|
-
# .name and .text
|
|
14
|
-
# https://github.com/appium/appium/blob/ea3450e7f78d1794bab42fa396a387e7b86fd3b3/android/bootstrap/src/io/appium/android/bootstrap/handler/GetAttribute.java#L43
|
|
15
|
-
# t 'value' do; end # Doesn't work on Android
|
|
16
|
-
|
|
17
|
-
t 'name' do
|
|
18
|
-
wait { first_text.name.must_equal 'API Demos' }
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
# t 'tag_name' do; end # Doesn't work on Android
|
|
22
|
-
|
|
23
|
-
t 'location_rel' do
|
|
24
|
-
wait do
|
|
25
|
-
loc = first_text.location_rel
|
|
26
|
-
loc.x.class.must_equal String
|
|
27
|
-
loc.y.class.must_equal String
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
describe 'common patch' do
|
|
33
|
-
# By default, the webdriver gem will return message instead of origValue
|
|
34
|
-
# {"message":"An unknown server-side error occurred while processing the command.","origValue":"Strategy id is not valid."}
|
|
35
|
-
t 'id error_message' do
|
|
36
|
-
value = ''
|
|
37
|
-
begin
|
|
38
|
-
set_wait 0
|
|
39
|
-
find_element(:id, 'ok')
|
|
40
|
-
rescue Exception => e
|
|
41
|
-
value = e.message
|
|
42
|
-
ensure
|
|
43
|
-
set_wait 30
|
|
44
|
-
end
|
|
45
|
-
value = value.split("\n").first.strip
|
|
46
|
-
exp = 'An element could not be located on the page using the given search parameters.'
|
|
47
|
-
value.must_equal exp
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
t 'id success' do
|
|
51
|
-
if !automation_name_is_uiautomator2?
|
|
52
|
-
wait do
|
|
53
|
-
el = id 'autocomplete_3_button_7' # <string name="autocomplete_3_button_7">Text</string>
|
|
54
|
-
el.name.must_equal 'Text'
|
|
55
|
-
end
|
|
56
|
-
else
|
|
57
|
-
wait do
|
|
58
|
-
el = text 'text' # <string name="autocomplete_3_button_7">Text</string>
|
|
59
|
-
el.name.must_equal 'Text'
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
t 'find many elements by resource id' do
|
|
65
|
-
wait do
|
|
66
|
-
value = find_elements(:id, 'android:id/text1').length
|
|
67
|
-
value.must_equal 12
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
t 'find single element by resource id' do
|
|
72
|
-
wait do
|
|
73
|
-
value = id('android:id/text1').text
|
|
74
|
-
value.must_equal "Access'ibility"
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# Tests specifically for areas where the web_context differs in behaviour
|
|
2
|
-
# rake android[common/web_context]
|
|
3
|
-
describe 'the web context' do
|
|
4
|
-
# appium's context support is broken on android
|
|
5
|
-
|
|
6
|
-
t 'available_contexts' do
|
|
7
|
-
wait_true { available_contexts.include? 'NATIVE_APP' }
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
t 'current_context' do
|
|
11
|
-
wait { current_context.must_equal 'NATIVE_APP' }
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
t 'set_context' do
|
|
15
|
-
wait { scroll_to('Views').click }
|
|
16
|
-
wait { scroll_to('WebView').click }
|
|
17
|
-
|
|
18
|
-
def undo_setcontext_nav
|
|
19
|
-
back
|
|
20
|
-
wait { find('WebView') }
|
|
21
|
-
back
|
|
22
|
-
wait { find 'Views' }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
contexts = available_contexts
|
|
26
|
-
webview_context = contexts.detect { |e| e.start_with?('WEBVIEW') }
|
|
27
|
-
|
|
28
|
-
if webview_context.nil?
|
|
29
|
-
undo_setcontext_nav
|
|
30
|
-
raise "No webview context found. contexts are: #{contexts}"
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
wait { set_context webview_context }
|
|
34
|
-
wait { current_context.must_equal webview_context }
|
|
35
|
-
|
|
36
|
-
# verify inspect within webview works
|
|
37
|
-
get_android_inspect.split("\n").length.must_be :>=, 3
|
|
38
|
-
|
|
39
|
-
wait { set_context 'NATIVE_APP' }
|
|
40
|
-
wait { current_context.must_equal 'NATIVE_APP' }
|
|
41
|
-
|
|
42
|
-
undo_setcontext_nav
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
t 'within_context' do
|
|
46
|
-
$driver.within_context 'NATIVE_APP' do
|
|
47
|
-
wait { current_context.must_equal 'NATIVE_APP' }
|
|
48
|
-
end
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
t 'switch_to_default_context' do
|
|
52
|
-
wait do
|
|
53
|
-
switch_to_default_context
|
|
54
|
-
current_context.must_equal 'NATIVE_APP'
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
wait { set_context 'NATIVE_APP' }
|
|
58
|
-
wait { current_context.must_equal 'NATIVE_APP' }
|
|
59
|
-
end
|
|
60
|
-
end
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# rake android[device/touch_actions]
|
|
2
|
-
describe 'device/touch_actions' do
|
|
3
|
-
def swipe_till_text_visible(seen_text)
|
|
4
|
-
start_x = window_size[:width] / 2
|
|
5
|
-
start_y = window_size[:height] / 2
|
|
6
|
-
wait(60) do
|
|
7
|
-
# rubocop:disable Metrics/LineLength
|
|
8
|
-
# Example for Android's log
|
|
9
|
-
# [0] pry(#<device/touch_actions>)> swipe start_x: start_x, start_y: start_y, end_x: start_y, end_y: start_y - 100
|
|
10
|
-
# [HTTP] --> POST /wd/hub/session/9baa18bf-a19b-4654-be4a-d0db0334bbc0/touch/perform {"actions":[{"action":"press","options":{"x":600,"y":919}},{"action":"wait","options":{"ms":200}},{"action":"moveTo","options":{"x":600,"y":819}},{"action":"release"}]}
|
|
11
|
-
# [debug] [MJSONWP] Calling AppiumDriver.performTouch() with args: [[{"action":"press","options":{"x":600,"y":919}},{"action":"wait","options":{"ms":200}},{"action":"moveTo","options":{"x":600,"y":819}},{"action":"release"}],"9baa18bf-a19b-4654-be4a-d0db0334bbc0"]
|
|
12
|
-
# [debug] [AndroidBootstrap] Sending command to android: {"cmd":"action","action":"swipe","params":{"startX":600,"startY":919,"endX":600,"endY":819,"steps":6}}
|
|
13
|
-
# [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got data from client: {"cmd":"action","action":"swipe","params":{"startX":600,"startY":919,"endX":600,"endY":819,"steps":6}}
|
|
14
|
-
# [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command of type ACTION
|
|
15
|
-
# [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Got command action: swipe
|
|
16
|
-
# [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Display bounds: [0,0][1200,1838]
|
|
17
|
-
# [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Display bounds: [0,0][1200,1838]
|
|
18
|
-
# [AndroidBootstrap] [BOOTSTRAP LOG] [debug] Swiping from [x=600.0, y=919.0] to [x=600.0, y=819.0] with steps: 6
|
|
19
|
-
# [debug] [AndroidBootstrap] Received command result from bootstrap
|
|
20
|
-
# rubocop:enable Metrics/LineLength
|
|
21
|
-
swipe start_x: start_x, start_y: start_y, end_x: start_x, end_y: start_y - 100
|
|
22
|
-
text(seen_text).displayed?
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
t 'swipe_coordinates_end_x_end_y' do
|
|
27
|
-
s = Appium::TouchAction.new.swipe_coordinates(end_x: 1, end_y: 2)
|
|
28
|
-
s[:offset_x].must_equal 1
|
|
29
|
-
s[:offset_y].must_equal 2
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
t 'swipe_coordinates_end_x' do
|
|
33
|
-
s = Appium::TouchAction.new.swipe_coordinates(end_x: 1)
|
|
34
|
-
s[:offset_x].must_equal 1
|
|
35
|
-
s[:offset_y].must_equal 0
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
t 'swipe_coordinates_end_y' do
|
|
39
|
-
s = Appium::TouchAction.new.swipe_coordinates(end_y: 1)
|
|
40
|
-
s[:offset_x].must_equal 0
|
|
41
|
-
s[:offset_y].must_equal 1
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
t 'swipe_coordinates_offset' do
|
|
45
|
-
s = Appium::TouchAction.new.swipe_coordinates
|
|
46
|
-
s[:offset_x].must_equal 0
|
|
47
|
-
s[:offset_y].must_equal 0
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
t 'swipe_default_duration' do
|
|
51
|
-
swipe_till_text_visible('views')
|
|
52
|
-
text('views').click
|
|
53
|
-
wait_true do
|
|
54
|
-
text('animation').displayed?
|
|
55
|
-
end
|
|
56
|
-
text('animation').text.must_equal 'Animation'
|
|
57
|
-
swipe_till_text_visible('lists')
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# TODO: write tests
|
|
62
|
-
#
|
|
63
|
-
# move_to
|
|
64
|
-
# long_press
|
|
65
|
-
# press
|
|
66
|
-
# release
|
|
67
|
-
# tap
|
|
68
|
-
# wait
|
|
69
|
-
# swipe
|
|
70
|
-
# perform
|
|
71
|
-
# cancel
|
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
# rubocop:disable Lint/RescueException
|
|
2
|
-
|
|
3
|
-
# rake android[driver]
|
|
4
|
-
describe 'driver' do
|
|
5
|
-
def sauce?
|
|
6
|
-
ENV['UPLOAD_FILE'] && ENV['SAUCE_USERNAME']
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
t 'load_settings' do
|
|
10
|
-
appium_txt = File.join(Dir.pwd, 'appium.txt')
|
|
11
|
-
parsed = Appium.load_settings file: appium_txt, verbose: true
|
|
12
|
-
apk_name = File.basename parsed[:caps][:app]
|
|
13
|
-
assert_equal apk_name, 'api.apk'
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
describe 'Appium::Driver attributes' do
|
|
17
|
-
t 'no_wait' do
|
|
18
|
-
no_wait
|
|
19
|
-
proc { button('zz') }.must_raise Selenium::WebDriver::Error::NoSuchElementError
|
|
20
|
-
set_wait
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
# attr_reader :default_wait, :app_path, :app_name, :selendroid,
|
|
24
|
-
# :app_package, :app_activity, :app_wait_activity,
|
|
25
|
-
# :sauce_username, :sauce_access_key, :port, :os, :debug
|
|
26
|
-
t 'default_wait attr' do
|
|
27
|
-
set_wait 1
|
|
28
|
-
default_wait.must_equal 1
|
|
29
|
-
set_wait # restore default
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
t 'app_path attr' do
|
|
33
|
-
apk_name = File.basename driver_attributes[:caps][:app]
|
|
34
|
-
apk_name.must_equal 'api.apk'
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
t 'verify Appium::Driver::Capabilities.init_caps_for_appium' do
|
|
38
|
-
expected_app = File.absolute_path('api.apk')
|
|
39
|
-
caps = ::Appium::Driver::Capabilities.init_caps_for_appium(platformName: 'Android',
|
|
40
|
-
app: expected_app,
|
|
41
|
-
appPackage: 'io.appium.android.apis',
|
|
42
|
-
appActivity: '.ApiDemos',
|
|
43
|
-
deviceName: 'Nexus 7',
|
|
44
|
-
some_capability: 'some_capability')
|
|
45
|
-
caps_with_json = JSON.parse(caps.to_json)
|
|
46
|
-
caps_with_json['platformName'].must_equal 'Android'
|
|
47
|
-
caps_with_json['app'].must_equal expected_app
|
|
48
|
-
caps_with_json['appPackage'].must_equal 'io.appium.android.apis'
|
|
49
|
-
caps_with_json['appActivity'].must_equal '.ApiDemos'
|
|
50
|
-
caps_with_json['deviceName'].must_equal 'Nexus 7'
|
|
51
|
-
caps_with_json['someCapability'].must_equal 'some_capability'
|
|
52
|
-
|
|
53
|
-
caps[:platformName].must_equal 'Android'
|
|
54
|
-
caps[:app].must_equal expected_app
|
|
55
|
-
caps[:appPackage].must_equal 'io.appium.android.apis'
|
|
56
|
-
caps[:appActivity].must_equal '.ApiDemos'
|
|
57
|
-
caps[:deviceName].must_equal 'Nexus 7'
|
|
58
|
-
caps[:some_capability].must_equal 'some_capability'
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
t 'verify all attributes' do
|
|
62
|
-
actual = driver_attributes
|
|
63
|
-
caps_app_for_teardown = actual[:caps][:app]
|
|
64
|
-
expected_app = File.absolute_path('api.apk')
|
|
65
|
-
|
|
66
|
-
expected = { automation_name: nil,
|
|
67
|
-
custom_url: false,
|
|
68
|
-
export_session: false,
|
|
69
|
-
default_wait: 1,
|
|
70
|
-
sauce_username: nil,
|
|
71
|
-
sauce_access_key: nil,
|
|
72
|
-
sauce_endpoint: 'ondemand.saucelabs.com:443/wd/hub',
|
|
73
|
-
port: 4723,
|
|
74
|
-
device: :android,
|
|
75
|
-
debug: true,
|
|
76
|
-
listener: nil,
|
|
77
|
-
wait_timeout: 30, # default
|
|
78
|
-
wait_interval: 0.5 } # default
|
|
79
|
-
|
|
80
|
-
# actual[:caps].to_json send to Appium server
|
|
81
|
-
caps_with_json = JSON.parse(actual[:caps].to_json)
|
|
82
|
-
caps_with_json['platformName'].must_equal 'android'
|
|
83
|
-
caps_with_json['app'].must_equal expected_app
|
|
84
|
-
caps_with_json['appPackage'].must_equal 'io.appium.android.apis'
|
|
85
|
-
caps_with_json['appActivity'].must_equal '.ApiDemos'
|
|
86
|
-
caps_with_json['deviceName'].must_equal 'Nexus 7'
|
|
87
|
-
caps_with_json['someCapability'].must_equal 'some_capability'
|
|
88
|
-
|
|
89
|
-
actual[:caps][:platformName].must_equal 'android'
|
|
90
|
-
actual[:caps][:app].must_equal expected_app
|
|
91
|
-
actual[:caps][:appPackage].must_equal 'io.appium.android.apis'
|
|
92
|
-
actual[:caps][:appActivity].must_equal '.ApiDemos'
|
|
93
|
-
actual[:caps][:deviceName].must_equal 'Nexus 7'
|
|
94
|
-
actual[:caps][:some_capability].must_equal 'some_capability'
|
|
95
|
-
|
|
96
|
-
dup_actual = actual.dup
|
|
97
|
-
dup_actual.delete(:caps)
|
|
98
|
-
|
|
99
|
-
if dup_actual != expected
|
|
100
|
-
diff = HashDiff.diff expected, actual
|
|
101
|
-
diff = "diff (expected, actual):\n#{diff}"
|
|
102
|
-
|
|
103
|
-
actual[:caps][:app] = caps_app_for_teardown
|
|
104
|
-
# example:
|
|
105
|
-
# change :ios in expected to match 'ios' in actual
|
|
106
|
-
# [["~", "caps.platformName", :ios, "ios"]]
|
|
107
|
-
message = "\n\nactual:\n\n: #{actual.ai}expected:\n\n#{expected.ai}\n\n#{diff}"
|
|
108
|
-
raise message
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
t 'default timeout for http client' do
|
|
113
|
-
http_client.open_timeout.must_equal 999_999
|
|
114
|
-
http_client.read_timeout.must_equal 999_999
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
describe 'Appium::Driver' do
|
|
119
|
-
t '$driver.class' do
|
|
120
|
-
$driver.class.must_equal Appium::Driver
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
t 'absolute_app_path' do
|
|
124
|
-
def absolute_app_path(path)
|
|
125
|
-
$driver.class.absolute_app_path(caps: { app: path })
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def validate_path(path)
|
|
129
|
-
absolute_app_path(path).must_equal path
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
validate_path 'sauce-storage:some_storage_suffix'
|
|
133
|
-
validate_path 'http://www.saucelabs.com'
|
|
134
|
-
|
|
135
|
-
# fake real paths for osx/windows.
|
|
136
|
-
FakeFS.activate!
|
|
137
|
-
|
|
138
|
-
osx_existing_path = '/Users/user/myapp.app'
|
|
139
|
-
FileUtils.mkdir_p osx_existing_path
|
|
140
|
-
validate_path osx_existing_path
|
|
141
|
-
|
|
142
|
-
# TODO: FakeFS fails on Windows paths due to the drive letters.
|
|
143
|
-
# Look into how opscode/chef tests this.
|
|
144
|
-
# windows_existing_path = "C:\\Program Files\\myapp.apk"
|
|
145
|
-
# FileUtils.mkdir_p windows_existing_path
|
|
146
|
-
# validate_path windows_existing_path
|
|
147
|
-
|
|
148
|
-
FakeFS.deactivate!
|
|
149
|
-
|
|
150
|
-
# bundle id test
|
|
151
|
-
validate_path 'my.bundle.id'
|
|
152
|
-
|
|
153
|
-
# relative path test
|
|
154
|
-
relative_path = File.join __FILE__, ('..' + File::SEPARATOR) * 4, 'api.apk'
|
|
155
|
-
expected_path = File.expand_path relative_path
|
|
156
|
-
|
|
157
|
-
absolute_app_path(relative_path).must_equal expected_path
|
|
158
|
-
|
|
159
|
-
# invalid path test
|
|
160
|
-
invalid_path_errors = false
|
|
161
|
-
begin
|
|
162
|
-
absolute_app_path('../../does_not_exist.apk')
|
|
163
|
-
rescue Exception
|
|
164
|
-
invalid_path_errors = true
|
|
165
|
-
ensure
|
|
166
|
-
invalid_path_errors.must_equal true
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
describe 'methods' do
|
|
172
|
-
t 'status' do
|
|
173
|
-
appium_server_version['build'].keys.sort.must_equal %w(revision version)
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
t 'server_version' do
|
|
177
|
-
server_version = appium_server_version['build']['version']
|
|
178
|
-
if sauce?
|
|
179
|
-
server_version.must_match 'Sauce OnDemand'
|
|
180
|
-
else
|
|
181
|
-
server_version.must_match(/(\d+)\.(\d+).(\d+)/)
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
t 'client_version' do
|
|
186
|
-
client_version = appium_client_version
|
|
187
|
-
expected = { version: ::Appium::VERSION }
|
|
188
|
-
client_version.must_equal expected
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
# Skip:
|
|
192
|
-
# ios_capabilities # save for iOS tests
|
|
193
|
-
# absolute_app_path # tested already by starting the driver for this test
|
|
194
|
-
# server_url # sauce labs only
|
|
195
|
-
|
|
196
|
-
t 'set_immediate_value' do
|
|
197
|
-
wait { find('app').click }
|
|
198
|
-
wait { find('activity').click }
|
|
199
|
-
wait { find('custom title').click }
|
|
200
|
-
|
|
201
|
-
message = 'hello'
|
|
202
|
-
|
|
203
|
-
wait do
|
|
204
|
-
elem = textfield(1)
|
|
205
|
-
elem.clear
|
|
206
|
-
set_immediate_value(elem, message)
|
|
207
|
-
elem.text.must_equal message
|
|
208
|
-
end
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
t 'restart' do
|
|
212
|
-
set_wait 1 # ensure wait is 1 before we restart.
|
|
213
|
-
restart
|
|
214
|
-
current_activity.must_equal '.ApiDemos'
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
t 'driver' do
|
|
218
|
-
driver.browser.must_be_empty
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
# Skip:
|
|
222
|
-
# screenshot # this is slow and already tested by Appium
|
|
223
|
-
# driver_quit # tested by restart
|
|
224
|
-
# start_driver # tested by restart
|
|
225
|
-
# no_wait # posts value to server, it's not stored locally
|
|
226
|
-
# set_wait # posts value to server, it's not stored locally
|
|
227
|
-
# execute_script # 'mobile: ' is deprecated and plain execute_script unsupported
|
|
228
|
-
|
|
229
|
-
t 'default_wait' do
|
|
230
|
-
set_wait 1
|
|
231
|
-
default_wait.must_equal 1
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
# returns true unless an error is raised
|
|
235
|
-
t 'exists' do
|
|
236
|
-
exists(0, 0) { true }.must_equal true
|
|
237
|
-
exists(0, 0) { raise 'error' }.must_equal false
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
# any elements
|
|
241
|
-
t 'find_elements' do
|
|
242
|
-
wait do
|
|
243
|
-
find_elements(:class_name, 'android.widget.TextView').length.must_equal 13
|
|
244
|
-
end
|
|
245
|
-
end
|
|
246
|
-
|
|
247
|
-
# any element
|
|
248
|
-
t 'find_element' do
|
|
249
|
-
wait do
|
|
250
|
-
find_element(:class_name, 'android.widget.TextView').class.must_equal Selenium::WebDriver::Element
|
|
251
|
-
end
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
# simple integration sanity test to check for unexpected exceptions
|
|
255
|
-
t 'set_location' do
|
|
256
|
-
begin
|
|
257
|
-
set_location latitude: 55, longitude: -72, altitude: 33
|
|
258
|
-
rescue Selenium::WebDriver::Error::UnknownError => e
|
|
259
|
-
# on android this method is expected to raise with this message when running
|
|
260
|
-
# on a regular device, or on genymotion.
|
|
261
|
-
# error could be many messages, including:
|
|
262
|
-
# ERROR running Appium command: port should be a number or string
|
|
263
|
-
# ERROR running Appium command: port should be > 0 and < 65536
|
|
264
|
-
raise unless e.message.include?('ERROR running Appium command: port should be')
|
|
265
|
-
end
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
# settings
|
|
269
|
-
t 'get settings' do
|
|
270
|
-
get_settings.wont_be_nil
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
t 'update settings' do
|
|
274
|
-
update_settings cyberdelia: 'open'
|
|
275
|
-
get_settings['cyberdelia'].must_equal 'open'
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
# Skip: x # x is only used in Pry
|
|
279
|
-
end
|
|
280
|
-
end
|