testa_appium_driver 0.1.11 → 0.1.12

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -15
  3. data/.idea/deployment.xml +21 -21
  4. data/.idea/inspectionProfiles/Project_Default.xml +8 -8
  5. data/.idea/misc.xml +5 -5
  6. data/.idea/modules.xml +7 -7
  7. data/.idea/runConfigurations/Android_Test.xml +41 -41
  8. data/.idea/runConfigurations.xml +9 -9
  9. data/.idea/sshConfigs.xml +12 -12
  10. data/.idea/vcs.xml +5 -5
  11. data/.idea/webServers.xml +20 -20
  12. data/.rspec +3 -3
  13. data/.rubocop.yml +13 -13
  14. data/CHANGELOG.md +5 -5
  15. data/CODE_OF_CONDUCT.md +102 -102
  16. data/Gemfile +12 -12
  17. data/LICENSE.txt +21 -21
  18. data/README.md +378 -378
  19. data/Rakefile +12 -12
  20. data/bin/console +17 -17
  21. data/bin/setup +8 -8
  22. data/lib/testa_appium_driver/android/class_selectors.rb +437 -437
  23. data/lib/testa_appium_driver/android/driver.rb +69 -69
  24. data/lib/testa_appium_driver/android/locator/attributes.rb +113 -113
  25. data/lib/testa_appium_driver/android/locator.rb +141 -141
  26. data/lib/testa_appium_driver/android/scroll_actions/uiautomator_scroll_actions.rb +61 -61
  27. data/lib/testa_appium_driver/android/selenium_element.rb +7 -7
  28. data/lib/testa_appium_driver/common/bounds.rb +149 -149
  29. data/lib/testa_appium_driver/common/constants.rb +36 -36
  30. data/lib/testa_appium_driver/common/exceptions/strategy_mix_exception.rb +11 -11
  31. data/lib/testa_appium_driver/common/helpers.rb +270 -270
  32. data/lib/testa_appium_driver/common/locator/scroll_actions.rb +397 -397
  33. data/lib/testa_appium_driver/common/locator.rb +610 -610
  34. data/lib/testa_appium_driver/common/scroll_actions/json_wire_scroll_actions.rb +3 -3
  35. data/lib/testa_appium_driver/common/scroll_actions/w3c_scroll_actions.rb +237 -237
  36. data/lib/testa_appium_driver/common/scroll_actions.rb +246 -246
  37. data/lib/testa_appium_driver/common/selenium_element.rb +19 -19
  38. data/lib/testa_appium_driver/driver.rb +312 -312
  39. data/lib/testa_appium_driver/ios/driver.rb +48 -48
  40. data/lib/testa_appium_driver/ios/locator/attributes.rb +80 -80
  41. data/lib/testa_appium_driver/ios/locator.rb +70 -70
  42. data/lib/testa_appium_driver/ios/selenium_element.rb +6 -6
  43. data/lib/testa_appium_driver/ios/type_selectors.rb +187 -187
  44. data/lib/testa_appium_driver/version.rb +5 -5
  45. data/lib/testa_appium_driver.rb +6 -6
  46. data/testa_appium_driver.gemspec +41 -41
  47. data/testa_appium_driver.iml +27 -78
  48. metadata +3 -3
data/README.md CHANGED
@@ -1,378 +1,378 @@
1
- # Testa Appium Driver
2
-
3
- Testa appium driver is a wrapper around the `ruby_lib_core` driver for appium.
4
- It leverages all driver features and makes them simple and easy to use.
5
-
6
- There are two key concepts in the testa driver
7
- #### 1. Elements are fetched only when needed
8
- It allows you to chain all the selectors and use the adjacent selectors without finding each element in the chain.
9
- For example `driver.linear_layout.list_view.view_group.button` will not execute any find element commands
10
- because element command is not given. If `click`, `send_keys` or any attribute method is added to the end of chain
11
- it will execute find_element before triggering the given element command.
12
-
13
- This concept allows you to store the selectors and reuse them later on. For example
14
- ```ruby
15
- # element is not fetched yet
16
- my_fancy_progress_bar = driver.linear_layout.progress_bar
17
-
18
- puts my_fancy_progress_bar.text # will fetch the element and print the text (output: "You are on the first page")
19
- driver.button(text: "next page").click # go to the next page that has the same progress bar locator
20
-
21
- # will fetch the element again and print the text (output: "You are on the second page")
22
- # without TestaAppiumDriver, a Stale Object Exception would be thronw
23
- puts my_fancy_progress_bar.text
24
- ```
25
-
26
-
27
- #### 2. The Best element find / scroll strategy is automatically determined
28
- When given an element locator such as the progress_bar in the first concept, testa appium driver automatically determines
29
- the best find element strategy. The only thing to keep in mind is that you cannot mix strategy specific selectors.
30
- Strategy specific selectors are `from_parent` for uiautomator or `parent`, `siblings` or `children` for xpath strategy.
31
-
32
- There are also multiple scroll strategies. Android supports both `uiautomator` and `w3c`, while iOS only supports `w3c`
33
- scroll strategy. Uiautomator scroll strategy is more fluent and faster but it cannot be limited with single direction
34
- element finding, and it does not have sufficient deadzone support.
35
-
36
-
37
-
38
-
39
- ## Installation
40
-
41
- Add this line to your application's Gemfile:
42
-
43
- ```ruby
44
- gem 'testa_appium_driver'
45
- ```
46
-
47
- And then execute:
48
-
49
- $ bundle install
50
-
51
- Or install it yourself as:
52
-
53
- $ gem install testa_appium_driver
54
-
55
-
56
- For the android platform, make sure you are using the latest version of uiautomator server. Versions older than 4.21.2 have breaking issues.
57
- To get the latest server version execute:
58
- ```shell script
59
- npm install appium-uiautomator2-server
60
- ```
61
- And apks will be located in `./node_modules/appium-uiautomator2-server/apks`. Install both apks on the target device
62
- and make sure you have the `skipServerInstallation: true` capability when starting the driver.
63
- ## Usage
64
-
65
- ### Initialization
66
- ```ruby
67
- opts = {
68
- caps: {
69
- platformName: "Android",
70
- deviceName: "MyPhone",
71
- app: "/path/to/your/apk",
72
- udid: "your_phone_udid",
73
- automationName: "uiautomator2",
74
- skipServerInstallation: true, # if uiautomator server is manually installed
75
- enableMultiWindows: true, # enables appium to see some otherwise "hidden" elements
76
- }
77
- }
78
- driver = TestaAppiumDriver::Driver.new(opts)
79
- ```
80
-
81
- #### Example 1
82
- ```ruby
83
- driver.linear_layout.button(id: "com.package.name:id/myElementId").click
84
- ```
85
- Looks for the first linear layout and a button within the linear layout that has the provided id.
86
- Only 1 find element is executed with the resolved strategy (xpath or uiautomator):<br>
87
- underlying selectors:<br>
88
- xpath: `//android.widget.LinearLayout[1]//android.widget.Button[@resource-id="com.package.name:id/myElementId"]` <br>
89
- uiautomator: `new UiSelector().className("android.widget.LinearLayout").instance(0).childSelector(new UiSelector.className("android.widget.Button").resourceId("com.package.name:id/myElementId")));`<br>
90
-
91
- #### Example 2
92
- ```ruby
93
- driver.linear_layout(id: "myShortIdExample").parent.text_view.wait_until_exists(10).text
94
- ```
95
- Testa driver converts shorthand ids(that dont have :id/) to full ids
96
- by reading the current package under test and prepending it to the shorthand id. If you don't want to prepend the package
97
- name to the id, use = sign before the id, for example `id: "=idWithoutAPackageName"`.
98
-
99
- After adding the `parent` and `text_view` selectors and before retrieving the text value `wait_until_exists(10)` is used to
100
- wait up to 10 seconds for the element to appear in the page before exception is thrown.
101
-
102
- underlying selectors:<br>
103
- xpath: `//android.widget.LinearLayout[@resource-id="com.package.name:id/myShortIdExample"][1]/../android.widget.TextView[1]` <br>
104
- uiautomator: `exception: parent selector cannot be used with uiautomator strategy`
105
-
106
- #### Example 3
107
- ```ruby
108
- driver.list_view(top: 200).edit_text(text: "Looking for this text").scroll_to.align!(:bottom).enabled?
109
- ```
110
- If the element cannot be found in the current view, `scroll_to` action will scroll to start of the scrollable container,
111
- and start scrolling to the end until the element is found or end is reached. Once found the `align!(:bottom)` command
112
- will align the element to the bottom of the scrollable container.
113
- Finally, once the element is scrolled into view and aligned, it will check if the edit_text is enabled.
114
-
115
- The scrollable container is resolved by looking the chain of selectors.
116
- Selector can be a scrollable container if `scrollable: true` or is one of the scrollable classes:
117
- - android.widget.ListView
118
- - android.widget.ScrollView
119
- - android.widget.HorizontalScrollView
120
- - androidx.recyclerview.widget.RecyclerView
121
- - XCUIElementTypeScrollView
122
-
123
- If the selector chain does not contain a scrollable container, a `driver.scrollabe` command will be executed to
124
- retrieve the first scrollable element in page.
125
-
126
- Scrollable selectors can accept the `top`, `right`, `bottom` and `left` parameters as deadzone to prevent that edge of the
127
- container be used as scrollable surface.
128
- Custom views can also be used as scrollable containers with `as_scrollable` command.
129
- The command marks the last selector as scrollable container.
130
- `driver.view(id: "myCustomScrollableView").as_scrollable(top: 200).page_down`
131
-
132
-
133
-
134
-
135
-
136
- #### Example 4
137
- ```ruby
138
- driver.buttons.each do |element|
139
- puts element.text
140
- end
141
- ```
142
- The `each` method is one of the scrollable actions. It will start from the beginning of the scrollable container,
143
- in this case `driver.scrollable`, and find every button in the screen. It will scroll the page until the end of scrollable
144
- container is reached and all buttons are found.
145
-
146
-
147
-
148
- #### Example 5 (Invalid combination)
149
- ```ruby
150
- driver.frame_layout.from_parent.button(text: "My Cool text").siblings
151
- ```
152
- This example demonstrates a invalid selector because it cannot be resolved with xpath nor uiautomator strategy.
153
- It will raise StrategyMixException because from_parent selector can only be used with uiautomator strategy and
154
- siblings selector can only be used with xpath strategy.
155
-
156
-
157
- # Methods
158
-
159
- ## Android
160
- ### Class Selectors
161
- - element
162
- - elements
163
- - scrollable
164
- - scrollables
165
- - image_view
166
- - image_views
167
- - frame_layout
168
- - frame_layouts
169
- - linear_layout
170
- - linear_layouts
171
- - view
172
- - views
173
- - edit_text
174
- - edit_texts
175
- - view_group
176
- - view_groups
177
- - relative_layout
178
- - relative_layouts
179
- - recycler_view
180
- - recycler_views
181
- - button
182
- - buttons
183
- - image_button
184
- - image_buttons
185
- - horizontal_scroll_view
186
- - horizontal_scroll_views
187
- - scroll_view
188
- - scroll_views
189
- - view_pager
190
- - view_pagers
191
- - check_box
192
- - check_boxes
193
- - list_view
194
- - list_views
195
- - progress_bar
196
- - progress_bars
197
- - radio_button
198
- - radio_buttons
199
- - radio_group
200
- - radio_groups
201
- - search_view
202
- - search_views
203
- - spinner
204
- - spinners
205
- - switch
206
- - switches
207
- - toast
208
- - toasts
209
- - toolbar
210
- - toolbars
211
- - text_view
212
- - text_views
213
- - web_view
214
- - web_views
215
- - card_view
216
- - card_views
217
-
218
- Adjacent selectors
219
- - from_parent
220
- - parent
221
- - child
222
- - children
223
- - siblings
224
- - preceding_sibling
225
- - preceding_siblings
226
- - following_sibling
227
- - following_siblings
228
-
229
-
230
- Class Selector arguments
231
- - id
232
- - long_clickable
233
- - desc
234
- - class
235
- - text
236
- - package
237
- - checkable
238
- - checked
239
- - clickable
240
- - enabled
241
- - focusable
242
- - focused
243
- - index
244
- - selected
245
- - scrollable
246
-
247
- ### Attributes
248
- - text
249
- - package
250
- - class_name
251
- - checkable?
252
- - checked?
253
- - clickable?
254
- - desc
255
- - enabled?
256
- - focusable?
257
- - focused?
258
- - long_clickable?
259
- - password?
260
- - id
261
- - scrollable?
262
- - selected?
263
- - displayed?
264
- - selection_start
265
- - selection_end
266
- - bounds
267
- - index
268
-
269
- # iOS
270
- ## Type Selectors
271
- - element
272
- - elements
273
- - window
274
- - windows
275
- - other
276
- - others
277
- - navigation_bar
278
- - navigation_bars
279
- - button
280
- - buttons
281
- - image
282
- - images
283
- - static_text
284
- - static_texts
285
- - scrollable
286
- - scrollables
287
- - scroll_view
288
- - scroll_views
289
- - table
290
- - tables
291
- - cell
292
- - cells
293
-
294
- Adjacent selectors
295
- - parent
296
- - child
297
- - children
298
- - siblings
299
- - preceding_sibling
300
- - preceding_siblings
301
- - following_sibling
302
- - following_siblings
303
-
304
- Type Selector arguments
305
- - enabled
306
- - type, class
307
- - label
308
- - width
309
- - height
310
- - visible
311
- - name, id
312
- - value
313
-
314
-
315
- ## Attributes
316
- - accessibility_container
317
- - accessible?
318
- - class_name
319
- - enabled?
320
- - frame
321
- - index
322
- - label, text
323
- - name
324
- - rect, bounds
325
- - selected?
326
- - type
327
- - value
328
- - visible?
329
-
330
- # Scroll actions
331
- - each
332
- - each_down
333
- - each_up
334
- - each_left
335
- - each_right
336
- - align! (if does not exist, will scroll to find)
337
- - align_top! (if does not exist, will scroll to find)
338
- - align_bottom! (if does not exist, will scroll to find)
339
- - align_left! (if does not exist, will scroll to find)
340
- - align_right! (if does not exist, will scroll to find)
341
- - align
342
- - align_top
343
- - align_bottom
344
- - align_left
345
- - align_right
346
- - scroll_to
347
- - scroll_down_to
348
- - scroll_up_to
349
- - scroll_right_to
350
- - scroll_left_to
351
- - scroll_to_start
352
- - scroll_to_end
353
- - page_down
354
- - page_up
355
- - page_left
356
- - page_right
357
- - fling_down
358
- - fling_up
359
- - fling_left
360
- - fling_right
361
- - drag_to
362
- - drag_by
363
-
364
- # Helpers
365
- - as_scrollable
366
- - wait_until_exists
367
- - wait_while_exists
368
- - wait_until
369
- - wait_while
370
- - when_exists
371
- - exists?
372
- - long_tap
373
-
374
- ## License
375
-
376
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
377
-
378
-
1
+ # Testa Appium Driver
2
+
3
+ Testa appium driver is a wrapper around the `ruby_lib_core` driver for appium.
4
+ It leverages all driver features and makes them simple and easy to use.
5
+
6
+ There are two key concepts in the testa driver
7
+ #### 1. Elements are fetched only when needed
8
+ It allows you to chain all the selectors and use the adjacent selectors without finding each element in the chain.
9
+ For example `driver.linear_layout.list_view.view_group.button` will not execute any find element commands
10
+ because element command is not given. If `click`, `send_keys` or any attribute method is added to the end of chain
11
+ it will execute find_element before triggering the given element command.
12
+
13
+ This concept allows you to store the selectors and reuse them later on. For example
14
+ ```ruby
15
+ # element is not fetched yet
16
+ my_fancy_progress_bar = driver.linear_layout.progress_bar
17
+
18
+ puts my_fancy_progress_bar.text # will fetch the element and print the text (output: "You are on the first page")
19
+ driver.button(text: "next page").click # go to the next page that has the same progress bar locator
20
+
21
+ # will fetch the element again and print the text (output: "You are on the second page")
22
+ # without TestaAppiumDriver, a Stale Object Exception would be thronw
23
+ puts my_fancy_progress_bar.text
24
+ ```
25
+
26
+
27
+ #### 2. The Best element find / scroll strategy is automatically determined
28
+ When given an element locator such as the progress_bar in the first concept, testa appium driver automatically determines
29
+ the best find element strategy. The only thing to keep in mind is that you cannot mix strategy specific selectors.
30
+ Strategy specific selectors are `from_parent` for uiautomator or `parent`, `siblings` or `children` for xpath strategy.
31
+
32
+ There are also multiple scroll strategies. Android supports both `uiautomator` and `w3c`, while iOS only supports `w3c`
33
+ scroll strategy. Uiautomator scroll strategy is more fluent and faster but it cannot be limited with single direction
34
+ element finding, and it does not have sufficient deadzone support.
35
+
36
+
37
+
38
+
39
+ ## Installation
40
+
41
+ Add this line to your application's Gemfile:
42
+
43
+ ```ruby
44
+ gem 'testa_appium_driver'
45
+ ```
46
+
47
+ And then execute:
48
+
49
+ $ bundle install
50
+
51
+ Or install it yourself as:
52
+
53
+ $ gem install testa_appium_driver
54
+
55
+
56
+ For the android platform, make sure you are using the latest version of uiautomator server. Versions older than 4.21.2 have breaking issues.
57
+ To get the latest server version execute:
58
+ ```shell script
59
+ npm install appium-uiautomator2-server
60
+ ```
61
+ And apks will be located in `./node_modules/appium-uiautomator2-server/apks`. Install both apks on the target device
62
+ and make sure you have the `skipServerInstallation: true` capability when starting the driver.
63
+ ## Usage
64
+
65
+ ### Initialization
66
+ ```ruby
67
+ opts = {
68
+ caps: {
69
+ platformName: "Android",
70
+ deviceName: "MyPhone",
71
+ app: "/path/to/your/apk",
72
+ udid: "your_phone_udid",
73
+ automationName: "uiautomator2",
74
+ skipServerInstallation: true, # if uiautomator server is manually installed
75
+ enableMultiWindows: true, # enables appium to see some otherwise "hidden" elements
76
+ }
77
+ }
78
+ driver = TestaAppiumDriver::Driver.new(opts)
79
+ ```
80
+
81
+ #### Example 1
82
+ ```ruby
83
+ driver.linear_layout.button(id: "com.package.name:id/myElementId").click
84
+ ```
85
+ Looks for the first linear layout and a button within the linear layout that has the provided id.
86
+ Only 1 find element is executed with the resolved strategy (xpath or uiautomator):<br>
87
+ underlying selectors:<br>
88
+ xpath: `//android.widget.LinearLayout[1]//android.widget.Button[@resource-id="com.package.name:id/myElementId"]` <br>
89
+ uiautomator: `new UiSelector().className("android.widget.LinearLayout").instance(0).childSelector(new UiSelector.className("android.widget.Button").resourceId("com.package.name:id/myElementId")));`<br>
90
+
91
+ #### Example 2
92
+ ```ruby
93
+ driver.linear_layout(id: "myShortIdExample").parent.text_view.wait_until_exists(10).text
94
+ ```
95
+ Testa driver converts shorthand ids(that dont have :id/) to full ids
96
+ by reading the current package under test and prepending it to the shorthand id. If you don't want to prepend the package
97
+ name to the id, use = sign before the id, for example `id: "=idWithoutAPackageName"`.
98
+
99
+ After adding the `parent` and `text_view` selectors and before retrieving the text value `wait_until_exists(10)` is used to
100
+ wait up to 10 seconds for the element to appear in the page before exception is thrown.
101
+
102
+ underlying selectors:<br>
103
+ xpath: `//android.widget.LinearLayout[@resource-id="com.package.name:id/myShortIdExample"][1]/../android.widget.TextView[1]` <br>
104
+ uiautomator: `exception: parent selector cannot be used with uiautomator strategy`
105
+
106
+ #### Example 3
107
+ ```ruby
108
+ driver.list_view(top: 200).edit_text(text: "Looking for this text").scroll_to.align!(:bottom).enabled?
109
+ ```
110
+ If the element cannot be found in the current view, `scroll_to` action will scroll to start of the scrollable container,
111
+ and start scrolling to the end until the element is found or end is reached. Once found the `align!(:bottom)` command
112
+ will align the element to the bottom of the scrollable container.
113
+ Finally, once the element is scrolled into view and aligned, it will check if the edit_text is enabled.
114
+
115
+ The scrollable container is resolved by looking the chain of selectors.
116
+ Selector can be a scrollable container if `scrollable: true` or is one of the scrollable classes:
117
+ - android.widget.ListView
118
+ - android.widget.ScrollView
119
+ - android.widget.HorizontalScrollView
120
+ - androidx.recyclerview.widget.RecyclerView
121
+ - XCUIElementTypeScrollView
122
+
123
+ If the selector chain does not contain a scrollable container, a `driver.scrollabe` command will be executed to
124
+ retrieve the first scrollable element in page.
125
+
126
+ Scrollable selectors can accept the `top`, `right`, `bottom` and `left` parameters as deadzone to prevent that edge of the
127
+ container be used as scrollable surface.
128
+ Custom views can also be used as scrollable containers with `as_scrollable` command.
129
+ The command marks the last selector as scrollable container.
130
+ `driver.view(id: "myCustomScrollableView").as_scrollable(top: 200).page_down`
131
+
132
+
133
+
134
+
135
+
136
+ #### Example 4
137
+ ```ruby
138
+ driver.buttons.each do |element|
139
+ puts element.text
140
+ end
141
+ ```
142
+ The `each` method is one of the scrollable actions. It will start from the beginning of the scrollable container,
143
+ in this case `driver.scrollable`, and find every button in the screen. It will scroll the page until the end of scrollable
144
+ container is reached and all buttons are found.
145
+
146
+
147
+
148
+ #### Example 5 (Invalid combination)
149
+ ```ruby
150
+ driver.frame_layout.from_parent.button(text: "My Cool text").siblings
151
+ ```
152
+ This example demonstrates a invalid selector because it cannot be resolved with xpath nor uiautomator strategy.
153
+ It will raise StrategyMixException because from_parent selector can only be used with uiautomator strategy and
154
+ siblings selector can only be used with xpath strategy.
155
+
156
+
157
+ # Methods
158
+
159
+ ## Android
160
+ ### Class Selectors
161
+ - element
162
+ - elements
163
+ - scrollable
164
+ - scrollables
165
+ - image_view
166
+ - image_views
167
+ - frame_layout
168
+ - frame_layouts
169
+ - linear_layout
170
+ - linear_layouts
171
+ - view
172
+ - views
173
+ - edit_text
174
+ - edit_texts
175
+ - view_group
176
+ - view_groups
177
+ - relative_layout
178
+ - relative_layouts
179
+ - recycler_view
180
+ - recycler_views
181
+ - button
182
+ - buttons
183
+ - image_button
184
+ - image_buttons
185
+ - horizontal_scroll_view
186
+ - horizontal_scroll_views
187
+ - scroll_view
188
+ - scroll_views
189
+ - view_pager
190
+ - view_pagers
191
+ - check_box
192
+ - check_boxes
193
+ - list_view
194
+ - list_views
195
+ - progress_bar
196
+ - progress_bars
197
+ - radio_button
198
+ - radio_buttons
199
+ - radio_group
200
+ - radio_groups
201
+ - search_view
202
+ - search_views
203
+ - spinner
204
+ - spinners
205
+ - switch
206
+ - switches
207
+ - toast
208
+ - toasts
209
+ - toolbar
210
+ - toolbars
211
+ - text_view
212
+ - text_views
213
+ - web_view
214
+ - web_views
215
+ - card_view
216
+ - card_views
217
+
218
+ Adjacent selectors
219
+ - from_parent
220
+ - parent
221
+ - child
222
+ - children
223
+ - siblings
224
+ - preceding_sibling
225
+ - preceding_siblings
226
+ - following_sibling
227
+ - following_siblings
228
+
229
+
230
+ Class Selector arguments
231
+ - id
232
+ - long_clickable
233
+ - desc
234
+ - class
235
+ - text
236
+ - package
237
+ - checkable
238
+ - checked
239
+ - clickable
240
+ - enabled
241
+ - focusable
242
+ - focused
243
+ - index
244
+ - selected
245
+ - scrollable
246
+
247
+ ### Attributes
248
+ - text
249
+ - package
250
+ - class_name
251
+ - checkable?
252
+ - checked?
253
+ - clickable?
254
+ - desc
255
+ - enabled?
256
+ - focusable?
257
+ - focused?
258
+ - long_clickable?
259
+ - password?
260
+ - id
261
+ - scrollable?
262
+ - selected?
263
+ - displayed?
264
+ - selection_start
265
+ - selection_end
266
+ - bounds
267
+ - index
268
+
269
+ # iOS
270
+ ## Type Selectors
271
+ - element
272
+ - elements
273
+ - window
274
+ - windows
275
+ - other
276
+ - others
277
+ - navigation_bar
278
+ - navigation_bars
279
+ - button
280
+ - buttons
281
+ - image
282
+ - images
283
+ - static_text
284
+ - static_texts
285
+ - scrollable
286
+ - scrollables
287
+ - scroll_view
288
+ - scroll_views
289
+ - table
290
+ - tables
291
+ - cell
292
+ - cells
293
+
294
+ Adjacent selectors
295
+ - parent
296
+ - child
297
+ - children
298
+ - siblings
299
+ - preceding_sibling
300
+ - preceding_siblings
301
+ - following_sibling
302
+ - following_siblings
303
+
304
+ Type Selector arguments
305
+ - enabled
306
+ - type, class
307
+ - label
308
+ - width
309
+ - height
310
+ - visible
311
+ - name, id
312
+ - value
313
+
314
+
315
+ ## Attributes
316
+ - accessibility_container
317
+ - accessible?
318
+ - class_name
319
+ - enabled?
320
+ - frame
321
+ - index
322
+ - label, text
323
+ - name
324
+ - rect, bounds
325
+ - selected?
326
+ - type
327
+ - value
328
+ - visible?
329
+
330
+ # Scroll actions
331
+ - each
332
+ - each_down
333
+ - each_up
334
+ - each_left
335
+ - each_right
336
+ - align! (if does not exist, will scroll to find)
337
+ - align_top! (if does not exist, will scroll to find)
338
+ - align_bottom! (if does not exist, will scroll to find)
339
+ - align_left! (if does not exist, will scroll to find)
340
+ - align_right! (if does not exist, will scroll to find)
341
+ - align
342
+ - align_top
343
+ - align_bottom
344
+ - align_left
345
+ - align_right
346
+ - scroll_to
347
+ - scroll_down_to
348
+ - scroll_up_to
349
+ - scroll_right_to
350
+ - scroll_left_to
351
+ - scroll_to_start
352
+ - scroll_to_end
353
+ - page_down
354
+ - page_up
355
+ - page_left
356
+ - page_right
357
+ - fling_down
358
+ - fling_up
359
+ - fling_left
360
+ - fling_right
361
+ - drag_to
362
+ - drag_by
363
+
364
+ # Helpers
365
+ - as_scrollable
366
+ - wait_until_exists
367
+ - wait_while_exists
368
+ - wait_until
369
+ - wait_while
370
+ - when_exists
371
+ - exists?
372
+ - long_tap
373
+
374
+ ## License
375
+
376
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
377
+
378
+