appium_lib 0.24.1 → 1.0.0

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.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +17 -8
  3. data/android_tests/Gemfile +1 -0
  4. data/android_tests/LICENSE-2.0.txt +202 -0
  5. data/android_tests/Rakefile +61 -0
  6. data/android_tests/api.apk +0 -0
  7. data/android_tests/appium.txt +3 -0
  8. data/android_tests/flaky.txt +1 -0
  9. data/android_tests/lib/android/specs/android/dynamic.rb +5 -0
  10. data/android_tests/lib/android/specs/android/element/alert.rb +41 -0
  11. data/android_tests/lib/android/specs/android/element/button.rb +55 -0
  12. data/android_tests/lib/android/specs/android/element/generic.rb +48 -0
  13. data/android_tests/lib/android/specs/android/element/text.rb +39 -0
  14. data/android_tests/lib/android/specs/android/element/textfield.rb +60 -0
  15. data/android_tests/lib/android/specs/android/helper.rb +80 -0
  16. data/android_tests/lib/android/specs/android/patch.rb +14 -0
  17. data/android_tests/lib/android/specs/common/device.rb +117 -0
  18. data/android_tests/lib/android/specs/common/element/window.rb +9 -0
  19. data/android_tests/lib/android/specs/common/helper.rb +112 -0
  20. data/android_tests/lib/android/specs/common/patch.rb +69 -0
  21. data/android_tests/lib/android/specs/common/version.rb +9 -0
  22. data/android_tests/lib/android/specs/driver.rb +174 -0
  23. data/android_tests/lib/format.rb +49 -0
  24. data/android_tests/lib/run.rb +72 -0
  25. data/android_tests/readme.md +27 -0
  26. data/appium_lib.gemspec +8 -5
  27. data/docs/android_docs.md +1052 -716
  28. data/docs/ios_docs.md +657 -834
  29. data/docs_gen/make_docs.rb +1 -3
  30. data/ios_tests/Gemfile +1 -0
  31. data/ios_tests/LICENSE-2.0.txt +202 -0
  32. data/ios_tests/Rakefile +47 -0
  33. data/ios_tests/UICatalog.app.zip +0 -0
  34. data/ios_tests/UICatalog.app/12-6AM.png +0 -0
  35. data/ios_tests/UICatalog.app/12-6PM.png +0 -0
  36. data/ios_tests/UICatalog.app/6-12AM.png +0 -0
  37. data/ios_tests/UICatalog.app/6-12PM.png +0 -0
  38. data/ios_tests/UICatalog.app/Default-568h@2x.png +0 -0
  39. data/ios_tests/UICatalog.app/Default@2x.png +0 -0
  40. data/ios_tests/UICatalog.app/Info.plist +0 -0
  41. data/ios_tests/UICatalog.app/PkgInfo +1 -0
  42. data/ios_tests/UICatalog.app/UIButton_custom.png +0 -0
  43. data/ios_tests/UICatalog.app/UICatalog +0 -0
  44. data/ios_tests/UICatalog.app/blueButton.png +0 -0
  45. data/ios_tests/UICatalog.app/bookmarkImage.png +0 -0
  46. data/ios_tests/UICatalog.app/bookmarkImageHighlighted.png +0 -0
  47. data/ios_tests/UICatalog.app/divider.png +0 -0
  48. data/ios_tests/UICatalog.app/en.lproj/AlertsViewController.nib +0 -0
  49. data/ios_tests/UICatalog.app/en.lproj/ButtonsViewController.nib +0 -0
  50. data/ios_tests/UICatalog.app/en.lproj/ControlsViewController.nib +0 -0
  51. data/ios_tests/UICatalog.app/en.lproj/ImagesViewController.nib +0 -0
  52. data/ios_tests/UICatalog.app/en.lproj/Localizable.strings +0 -0
  53. data/ios_tests/UICatalog.app/en.lproj/MainWindow.nib +0 -0
  54. data/ios_tests/UICatalog.app/en.lproj/PickerViewController.nib +0 -0
  55. data/ios_tests/UICatalog.app/en.lproj/SearchBarController.nib +0 -0
  56. data/ios_tests/UICatalog.app/en.lproj/SegmentViewController.nib +0 -0
  57. data/ios_tests/UICatalog.app/en.lproj/TextFieldController.nib +0 -0
  58. data/ios_tests/UICatalog.app/en.lproj/TextViewController.nib +0 -0
  59. data/ios_tests/UICatalog.app/en.lproj/ToolbarViewController.nib +0 -0
  60. data/ios_tests/UICatalog.app/en.lproj/TransitionViewController.nib +0 -0
  61. data/ios_tests/UICatalog.app/en.lproj/WebViewController.nib +0 -0
  62. data/ios_tests/UICatalog.app/orangeslide.png +0 -0
  63. data/ios_tests/UICatalog.app/scene1.jpg +0 -0
  64. data/ios_tests/UICatalog.app/scene2.jpg +0 -0
  65. data/ios_tests/UICatalog.app/scene3.jpg +0 -0
  66. data/ios_tests/UICatalog.app/scene4.jpg +0 -0
  67. data/ios_tests/UICatalog.app/scene5.jpg +0 -0
  68. data/ios_tests/UICatalog.app/searchBarBackground.png +0 -0
  69. data/ios_tests/UICatalog.app/segment_check.png +0 -0
  70. data/ios_tests/UICatalog.app/segment_search.png +0 -0
  71. data/ios_tests/UICatalog.app/segment_tools.png +0 -0
  72. data/ios_tests/UICatalog.app/segmentedBackground.png +0 -0
  73. data/ios_tests/UICatalog.app/slider_ball.png +0 -0
  74. data/ios_tests/UICatalog.app/toolbarBackground.png +0 -0
  75. data/ios_tests/UICatalog.app/whiteButton.png +0 -0
  76. data/ios_tests/UICatalog.app/yellowslide.png +0 -0
  77. data/ios_tests/appium.txt +3 -0
  78. data/ios_tests/flaky.txt +1 -0
  79. data/ios_tests/lib/format.rb +25 -0
  80. data/ios_tests/lib/ios/specs/common/element/window.rb +15 -0
  81. data/ios_tests/lib/ios/specs/common/helper.rb +204 -0
  82. data/ios_tests/lib/ios/specs/common/patch.rb +50 -0
  83. data/ios_tests/lib/ios/specs/common/version.rb +17 -0
  84. data/ios_tests/lib/ios/specs/device/device.rb +82 -0
  85. data/ios_tests/lib/ios/specs/device/multi_touch.rb +12 -0
  86. data/ios_tests/lib/ios/specs/device/touch_actions.rb +15 -0
  87. data/ios_tests/lib/ios/specs/driver.rb +203 -0
  88. data/ios_tests/lib/ios/specs/ios/element/alert.rb +48 -0
  89. data/ios_tests/lib/ios/specs/ios/element/button.rb +58 -0
  90. data/ios_tests/lib/ios/specs/ios/element/generic.rb +35 -0
  91. data/ios_tests/lib/ios/specs/ios/element/text.rb +54 -0
  92. data/ios_tests/lib/ios/specs/ios/element/textfield.rb +123 -0
  93. data/ios_tests/lib/ios/specs/ios/helper.rb +27 -0
  94. data/ios_tests/lib/ios/specs/ios/patch.rb +30 -0
  95. data/ios_tests/lib/run.rb +106 -0
  96. data/ios_tests/readme.md +30 -0
  97. data/ios_tests/upload/sauce_storage.rb +64 -0
  98. data/ios_tests/upload/upload.rb +6 -0
  99. data/lib/appium_lib.rb +4 -14
  100. data/lib/appium_lib/android/dynamic.rb +30 -32
  101. data/lib/appium_lib/android/element/alert.rb +34 -33
  102. data/lib/appium_lib/android/element/button.rb +91 -0
  103. data/lib/appium_lib/android/element/generic.rb +51 -146
  104. data/lib/appium_lib/android/element/text.rb +54 -0
  105. data/lib/appium_lib/android/element/textfield.rb +46 -41
  106. data/lib/appium_lib/android/helper.rb +248 -417
  107. data/lib/appium_lib/android/mobile_methods.rb +17 -0
  108. data/lib/appium_lib/android/patch.rb +9 -8
  109. data/lib/appium_lib/awesome_print/ostruct.rb +33 -0
  110. data/lib/appium_lib/common/element/window.rb +9 -8
  111. data/lib/appium_lib/common/helper.rb +182 -243
  112. data/lib/appium_lib/common/patch.rb +65 -79
  113. data/lib/appium_lib/common/version.rb +2 -3
  114. data/lib/appium_lib/device/device.rb +339 -0
  115. data/lib/appium_lib/device/multi_touch.rb +94 -0
  116. data/lib/appium_lib/device/touch_actions.rb +142 -0
  117. data/lib/appium_lib/driver.rb +217 -306
  118. data/lib/appium_lib/ios/element/alert.rb +16 -92
  119. data/lib/appium_lib/ios/element/button.rb +55 -0
  120. data/lib/appium_lib/ios/element/generic.rb +27 -160
  121. data/lib/appium_lib/ios/element/text.rb +54 -0
  122. data/lib/appium_lib/ios/element/textfield.rb +78 -65
  123. data/lib/appium_lib/ios/helper.rb +300 -190
  124. data/lib/appium_lib/ios/mobile_methods.rb +17 -0
  125. data/lib/appium_lib/ios/patch.rb +55 -41
  126. data/lib/appium_lib/logger.rb +13 -0
  127. data/lib/appium_lib/rails/duplicable.rb +116 -0
  128. data/readme.md +6 -1
  129. data/release_notes.md +118 -0
  130. metadata +170 -12
  131. data/lib/appium_lib/common/element/button.rb +0 -83
  132. data/lib/appium_lib/common/element/text.rb +0 -61
@@ -0,0 +1,48 @@
1
+ # rake android['android/element/generic']
2
+ describe 'android/element/generic' do
3
+
4
+ def content
5
+ 'Content'
6
+ end
7
+
8
+ def partial
9
+ 'tent'
10
+ end
11
+
12
+ t 'find works before and after get_source' do
13
+ wait { find(partial).text.must_equal content }
14
+ wait { get_source.class.must_equal String }
15
+ wait { find(partial).text.must_equal content }
16
+ end
17
+
18
+ t 'find' do
19
+ wait { find(partial).text.must_equal content }
20
+ end
21
+
22
+ t 'finds' do
23
+ wait { finds(partial).first.text.must_equal content }
24
+ end
25
+
26
+ t 'find_exact' do
27
+ wait { find_exact(content).text.must_equal content }
28
+ end
29
+
30
+ t 'finds_exact' do
31
+ wait { finds_exact(content).first.text.must_equal content }
32
+ end
33
+
34
+ # scroll_to is broken
35
+ t 'scroll_to' do
36
+ wait { find('Views').click }
37
+ wait { scroll_to('rotating button').text.must_equal 'Rotating Button' }
38
+ # back to start activity
39
+ back
40
+ end
41
+
42
+ t 'scroll_to_exact' do
43
+ wait { find('Views').click }
44
+ wait { scroll_to_exact('Rotating Button').text.must_equal 'Rotating Button' }
45
+ # back to start activity
46
+ back
47
+ end
48
+ end
@@ -0,0 +1,39 @@
1
+ # rake android['android/element/text']
2
+ describe 'android/element/text' do
3
+
4
+ def must_raise_no_element &block
5
+ proc { block.call }.must_raise Selenium::WebDriver::Error::NoSuchElementError
6
+ end
7
+
8
+ t 's_text' do
9
+ wait { s_text(1).text.must_equal 'API Demos' }
10
+ wait { s_text('mos').text.must_equal 'API Demos' }
11
+ end
12
+
13
+ t 's_texts' do
14
+ wait { s_texts('i').length.must_equal 7 }
15
+ end
16
+
17
+ t 'first_s_text' do
18
+ wait { first_s_text.text.must_equal 'API Demos' }
19
+ end
20
+
21
+ t 'last_s_text' do
22
+ wait { last_s_text.text.must_equal 'Views' }
23
+ end
24
+
25
+ t 's_text_exact' do
26
+ must_raise_no_element { s_text_exact 'mos' }
27
+
28
+ # should pass
29
+ wait { s_text_exact('API Demos').text.must_equal 'API Demos' }
30
+ end
31
+
32
+ t 's_texts_exact' do
33
+ wait { s_texts_exact('API Demos').length.must_equal 1 }
34
+ end
35
+
36
+ t 'e_s_texts' do
37
+ wait { e_s_texts.length.must_equal 14 }
38
+ end
39
+ end
@@ -0,0 +1,60 @@
1
+ describe 'android/element/textfield' do
2
+ def must_raise_no_element &block
3
+ proc { block.call }.must_raise Selenium::WebDriver::Error::NoSuchElementError
4
+ end
5
+
6
+ def left
7
+ 'Left is best'
8
+ end
9
+
10
+ def right
11
+ 'Right is always right'
12
+ end
13
+
14
+ def before_first
15
+ # nav to activity
16
+ wait { find('app').click }
17
+ wait { find('activity').click }
18
+ wait { find('custom title').click }
19
+ end
20
+
21
+ def after_last
22
+ # back to start
23
+ 3.times { back }
24
+ end
25
+
26
+ t { before_first }
27
+
28
+ t 'textfield' do
29
+ wait { textfield(1).text.must_equal left }
30
+ wait { textfield('right').text.must_equal right }
31
+ end
32
+
33
+ t 'textfields' do
34
+ wait { textfields('right').first.text.must_equal right }
35
+ end
36
+
37
+ t 'first_textfield' do
38
+ wait { first_textfield.text.must_equal left }
39
+ end
40
+
41
+ t 'last_textfield' do
42
+ wait { last_textfield.text.must_equal right }
43
+ end
44
+
45
+ t 'textfield_exact' do
46
+ must_raise_no_element { textfield_exact 'zz' }
47
+ wait { textfield_exact(left).text.must_equal left }
48
+ end
49
+
50
+ t 'textfields_exact' do
51
+ wait { textfields_exact('zz').must_equal [] }
52
+ wait { textfields_exact(left).first.text.must_equal left }
53
+ end
54
+
55
+ t 'e_textfields' do
56
+ wait { e_textfields.length.must_equal 2 }
57
+ end
58
+
59
+ t { after_last }
60
+ end
@@ -0,0 +1,80 @@
1
+ # rake android[android/helper]
2
+ describe 'android/helper' do
3
+ t 'tags' do
4
+ wait { tags('android.widget.TextView').length.must_equal 14 }
5
+ end
6
+
7
+ def page_class_data
8
+ (<<-TXT).strip
9
+ 12x android.widget.TextView
10
+ 4x android.widget.FrameLayout
11
+ 2x android.widget.LinearLayout
12
+ 2x android.view.View
13
+ 1x android.widget.ListView
14
+ 1x android.widget.ImageView
15
+ 1x hierarchy
16
+ TXT
17
+ end
18
+
19
+ # t 'get_selendroid_inspect' # only works on selendroid
20
+ t 'get_page_class' do
21
+ # digit values change based on screen size
22
+ # larger screens have more elements
23
+ wait do
24
+ exp = page_class_data.gsub(/\d+/, '')
25
+ act = get_page_class.gsub(/\d+/, '')
26
+ act.must_equal exp
27
+ end
28
+ end
29
+
30
+ # t 'page_class' do # tested by get_page_class
31
+
32
+ t 'get_android_inspect' do
33
+ # line count changes based on screen size
34
+ wait { get_android_inspect.split("\n").length.must_be :>=, 40 }
35
+ end
36
+
37
+ # t 'get_inspect' do # tested by get_android_inspect
38
+ # t 'page' do # tested by get_android_inspect
39
+
40
+ def id_key
41
+ 'animation_2_instructions'
42
+ end
43
+
44
+ def id_value
45
+ 'Select an animation:'
46
+ end
47
+
48
+ t 'xml_keys' do
49
+ wait do
50
+ id_pair = xml_keys id_key
51
+ id_pair = id_pair.to_a[0]
52
+ id_pair.length.must_equal 2
53
+ id_pair.first.must_equal id_key
54
+ id_pair.last.must_equal id_value
55
+ end
56
+ end
57
+
58
+ t 'resolve_id' do
59
+ wait do
60
+ str = resolve_id id_key
61
+ str.must_equal id_value
62
+ end
63
+ end
64
+
65
+ t 'xml_values' do
66
+ wait do
67
+ value = xml_values(id_value).first.last
68
+ value.must_equal id_value
69
+ end
70
+ end
71
+
72
+ t 'find by id' do
73
+ wait do
74
+ find('accessibility').click
75
+ find('accessibility node provider').click
76
+ id 'accessibility_node_provider' # Accessibility/Accessibility Node Provider
77
+ 2.times { back }
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,14 @@
1
+ describe 'android/patch.rb' do
2
+ t 'type' do
3
+ # nav to textfield
4
+ wait { find('app').click }
5
+ wait { find('search').click }
6
+ wait { find('invoke').click }
7
+
8
+ wait { first_textfield.type 'ok' }
9
+ wait { first_textfield.text.must_equal 'ok' }
10
+
11
+ # nav to start activity
12
+ 3.times { back }
13
+ end
14
+ end
@@ -0,0 +1,117 @@
1
+ describe 'common/device' do
2
+ # Not yet implemented
3
+ t 'shake' do
4
+ # todo: write test
5
+ end
6
+
7
+ t 'remove & install' do
8
+ # todo: write test
9
+ #remove 'com.example.android.apis'
10
+ #install ENV['APP_PATH']
11
+ end
12
+
13
+ t 'background_app' do
14
+ wait { background_app 5 }
15
+ end
16
+
17
+ t 'is_installed' do
18
+ wait { is_installed?('fake_app').must_equal false }
19
+ end
20
+
21
+ t 'reset' do
22
+ reset
23
+ wait { s_text(1).text.must_equal 'API Demos' }
24
+ end
25
+
26
+ t 'close & launch' do
27
+ close_app
28
+ launch
29
+ end
30
+
31
+ t 'current_activity' do
32
+ wait { current_activity.must_equal '.ApiDemos' }
33
+ end
34
+
35
+ t 'available_contexts' do
36
+ wait { available_contexts.must_equal ['NATIVE_APP'] }
37
+ end
38
+
39
+ t 'current_context' do
40
+ wait { current_context.must_equal 'NATIVE_APP' }
41
+ end
42
+
43
+ t 'current_context=' do
44
+ wait do
45
+ current_context= 'WEBVIEW'
46
+ current_context.must_equal 'WEBVIEW'
47
+ end
48
+ end
49
+
50
+ t 'within_context' do
51
+ $driver.within_context 'NATIVE_APP' do
52
+ wait { current_context.must_equal 'NATIVE_APP' }
53
+ end
54
+ end
55
+
56
+ t 'switch_to_default_context' do
57
+ wait do
58
+ switch_to_default_context
59
+ current_context.must_equal 'NATIVE_APP'
60
+ end
61
+ end
62
+
63
+ t 'app_strings' do
64
+ wait do
65
+ strs = app_strings
66
+ strs.has_key?('activity_save_restore').must_equal true
67
+ end
68
+ end
69
+
70
+ def must_return_element element
71
+ element.class.must_equal Selenium::WebDriver::Element
72
+ end
73
+
74
+ t 'complex_find' do
75
+ wait { find('Views').click }
76
+ wait { must_return_element complex_find(mode: 'scroll', selectors: [[[3, 'tabs']]]) }
77
+ wait { must_return_element complex_find(mode: 'all', selectors: [[[3, 'i']]]).first }
78
+ wait { must_return_element complex_find(selectors: [[[3, 'tabs']]]) }
79
+ back
80
+ end
81
+
82
+ t 'key_event' do
83
+ key_event 176
84
+ end
85
+
86
+ t 'action_chain' do
87
+ wait do
88
+ e = find_element(:name, 'Accessibility')
89
+ Appium::TouchAction.new.press(:element => e, x: 0.5, y: 0.5).release(:element => e).perform
90
+ end
91
+ wait { find_element(:name, 'Custom View') }
92
+ back
93
+ end
94
+
95
+ t 'swipe' do
96
+ wait { Appium::TouchAction.new.swipe(start_x: 0.75, start_y: 0.25, end_x: 0.75, end_y: 0.5, duration: 1.5).perform }
97
+ end
98
+
99
+ t 'pinch & zoom' do
100
+ wait do
101
+ s_text('Graphics').click
102
+ s_text('BitmapMesh').click
103
+ zoom 200
104
+ pinch 75
105
+ end
106
+ end
107
+
108
+ t 'push and pull file' do
109
+ wait do
110
+ file = "A Fine Day"
111
+ path = "/data/local/tmp/remote.txt"
112
+ push_file path, file
113
+ read_file = pull_file path
114
+ read_file.must_equal file
115
+ end
116
+ end
117
+ end
@@ -0,0 +1,9 @@
1
+ describe 'common/element/window' do
2
+ t 'window_size' do
3
+ wait do
4
+ size = window_size
5
+ size.width.class.must_equal Fixnum
6
+ size.height.class.must_equal Fixnum
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,112 @@
1
+ describe 'common/helper' do
2
+ wait_time = [0.2, 0.2] # max_wait, interval
3
+
4
+ # wait is a success unless an error is raised
5
+ # max_wait=0 is infinity to use 0.1
6
+ t 'wait' do
7
+ # successful wait should not raise error
8
+ wait(*wait_time) { true }
9
+ wait(*wait_time) { false }
10
+ wait(*wait_time) { nil }
11
+
12
+ # failed wait should error
13
+ proc { wait(*wait_time) { raise } }.must_raise Timeout::Error
14
+
15
+ # regular rescue will not handle exceptions outside of StandardError hierarchy
16
+ # must rescue Exception explicitly to rescue everything
17
+ proc { wait(*wait_time) { raise NoMemoryError } }.must_raise Timeout::Error
18
+ end
19
+
20
+ t 'ignore' do
21
+ # ignore should rescue all exceptions
22
+ ignore { true }
23
+ ignore { false }
24
+ ignore { nil }
25
+ ignore { raise }
26
+ ignore { raise NoMemoryError }
27
+ end
28
+
29
+ # wait_true is a success unless the value is not true
30
+ t 'wait_true' do
31
+ # successful wait should not error
32
+ wait_true(*wait_time) { true }
33
+
34
+ # failed wait should error
35
+ proc { wait_true(*wait_time) { false } }.must_raise Timeout::Error
36
+ proc { wait_true(*wait_time) { nil } }.must_raise Timeout::Error
37
+
38
+ # raise should error
39
+ proc { wait_true(*wait_time) { raise } }.must_raise Timeout::Error
40
+
41
+ # regular rescue will not handle exceptions outside of StandardError hierarchy
42
+ # must rescue Exception explicitly to rescue everything
43
+ proc { wait(*wait_time) { raise NoMemoryError } }.must_raise Timeout::Error
44
+ end
45
+
46
+ t 'back' do
47
+ # start page
48
+ wait { e_s_texts.length.must_equal 14 }
49
+ # nav to new page.
50
+ # ele 0 is the title and can't be clicked.
51
+ wait { s_text(2).click }
52
+ wait { e_s_texts.length.must_equal 8 }
53
+ # go back
54
+ back
55
+ # start page
56
+ wait { find 'NFC' }
57
+ end
58
+
59
+ t 'session_id' do
60
+ wait { session_id.must_match /\h{8}-\h{4}-\h{4}-\h{4}-\h{12}/ }
61
+ end
62
+
63
+ t 'xpath' do
64
+ wait { xpath('//android.widget.TextView').name.must_equal 'API Demos' }
65
+ end
66
+
67
+ t 'xpaths' do
68
+ wait { xpaths('//android.widget.TextView').length.must_equal 14 }
69
+ end
70
+
71
+ t 'ele_index' do
72
+ wait { ele_index('android.widget.TextView', 2).name.must_equal 'Accessibility' }
73
+ end
74
+
75
+ t 'tags' do
76
+ wait { tags('android.widget.TextView').length.must_equal 14 }
77
+ end
78
+
79
+ t 'find_ele_by_attr_include' do
80
+ wait do
81
+ el_text = find_ele_by_attr_include('android.widget.TextView', :text, 'acc').text
82
+ el_text.must_equal 'Accessibility'
83
+ end
84
+ end
85
+
86
+ t 'find_eles_by_attr_include' do
87
+ wait do
88
+ ele_count = find_eles_by_attr_include('android.widget.TextView', :text, 'e').length
89
+ ele_count.must_equal 9
90
+ end
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