appium_lib 9.4.5 → 9.4.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|