robotframework-appiumwindows 0.1.0__tar.gz

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 (28) hide show
  1. robotframework_appiumwindows-0.1.0/AppiumLibrary/__init__.py +106 -0
  2. robotframework_appiumwindows-0.1.0/AppiumLibrary/appium_path.py +10 -0
  3. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/__init__.py +21 -0
  4. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_applicationmanagement.py +515 -0
  5. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_element.py +1282 -0
  6. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_logging.py +63 -0
  7. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_powershell.py +553 -0
  8. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_runonfailure.py +74 -0
  9. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_screenrecord.py +138 -0
  10. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_screenshot.py +109 -0
  11. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_waiting.py +163 -0
  12. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/_windows.py +215 -0
  13. robotframework_appiumwindows-0.1.0/AppiumLibrary/keywords/keywordgroup.py +70 -0
  14. robotframework_appiumwindows-0.1.0/AppiumLibrary/locators/__init__.py +7 -0
  15. robotframework_appiumwindows-0.1.0/AppiumLibrary/locators/elementfinder.py +264 -0
  16. robotframework_appiumwindows-0.1.0/AppiumLibrary/utils/__init__.py +50 -0
  17. robotframework_appiumwindows-0.1.0/AppiumLibrary/utils/applicationcache.py +48 -0
  18. robotframework_appiumwindows-0.1.0/AppiumLibrary/version.py +2 -0
  19. robotframework_appiumwindows-0.1.0/LICENSE +21 -0
  20. robotframework_appiumwindows-0.1.0/PKG-INFO +148 -0
  21. robotframework_appiumwindows-0.1.0/README.md +119 -0
  22. robotframework_appiumwindows-0.1.0/pyproject.toml +38 -0
  23. robotframework_appiumwindows-0.1.0/robotframework_appiumwindows.egg-info/PKG-INFO +148 -0
  24. robotframework_appiumwindows-0.1.0/robotframework_appiumwindows.egg-info/SOURCES.txt +26 -0
  25. robotframework_appiumwindows-0.1.0/robotframework_appiumwindows.egg-info/dependency_links.txt +1 -0
  26. robotframework_appiumwindows-0.1.0/robotframework_appiumwindows.egg-info/requires.txt +2 -0
  27. robotframework_appiumwindows-0.1.0/robotframework_appiumwindows.egg-info/top_level.txt +1 -0
  28. robotframework_appiumwindows-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,106 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ import os
4
+ from AppiumLibrary.keywords import *
5
+ from AppiumLibrary.version import VERSION
6
+
7
+ __version__ = VERSION
8
+
9
+
10
+ class AppiumLibrary(
11
+ _LoggingKeywords,
12
+ _RunOnFailureKeywords,
13
+ _ElementKeywords,
14
+ _WindowsKeywords,
15
+ _PowershellKeywords,
16
+ _ScreenshotKeywords,
17
+ _ApplicationManagementKeywords,
18
+ _WaitingKeywords,
19
+ _ScreenrecordKeywords
20
+ ):
21
+ """AppiumLibrary is a Mobile App testing library for Robot Framework.
22
+
23
+ = Locating or specifying elements =
24
+
25
+ All keywords in AppiumLibrary that need to find an element on the page
26
+ take an argument, either a ``locator`` or a ``webelement``. ``locator``
27
+ is a string that describes how to locate an element using a syntax
28
+ specifying different location strategies. ``webelement`` is a variable that
29
+ holds a WebElement instance, which is a representation of the element.
30
+
31
+ == Using locators ==
32
+
33
+ By default, when a locator is provided, it is matched against the key attributes
34
+ of the particular element type. For iOS and Android, key attribute is ``id`` for
35
+ all elements and locating elements is easy using just the ``id``. For example:
36
+
37
+ | Click Element id=my_element
38
+
39
+ New in AppiumLibrary 1.4, ``id`` and ``xpath`` are not required to be specified,
40
+ however ``xpath`` should start with ``//`` else just use ``xpath`` locator as explained below.
41
+
42
+ For example:
43
+
44
+ | Click Element my_element
45
+ | Wait Until Page Contains Element //*[@type="android.widget.EditText"]
46
+
47
+
48
+ Appium additionally supports some of the [https://w3c.github.io/webdriver/webdriver-spec.html|Mobile JSON Wire Protocol] locator strategies.
49
+ It is also possible to specify the approach AppiumLibrary should take
50
+ to find an element by specifying a lookup strategy with a locator
51
+ prefix. Supported strategies are:
52
+
53
+ | *Strategy* | *Example* | *Description* | *Note* |
54
+ | identifier | Click Element `|` identifier=my_element | Matches by @id attribute | |
55
+ | id | Click Element `|` id=my_element | Matches by @resource-id attribute | |
56
+ | accessibility_id | Click Element `|` accessibility_id=button3 | Accessibility options utilize. | |
57
+ | xpath | Click Element `|` xpath=//UIATableView/UIATableCell/UIAButton | Matches with arbitrary XPath | |
58
+ | class | Click Element `|` class=UIAPickerWheel | Matches by class | |
59
+ | android | Click Element `|` android=UiSelector().description('Apps') | Matches by Android UI Automator | |
60
+ | ios | Click Element `|` ios=.buttons().withName('Apps') | Matches by iOS UI Automation | |
61
+ | predicate | Click Element `|` predicate=name=="login" | Matches by iOS Predicate | Check PR: #196 |
62
+ | chain | Click Element `|` chain=XCUIElementTypeWindow[1]/* | Matches by iOS Class Chain | |
63
+ | css | Click Element `|` css=.green_button | Matches by css in webview | |
64
+ | name | Click Element `|` name=my_element | Matches by @name attribute | *Only valid* for Selendroid |
65
+
66
+ == Using webelements ==
67
+
68
+ Starting with version 1.4 of the AppiumLibrary, one can pass an argument
69
+ that contains a WebElement instead of a string locator. To get a WebElement,
70
+ use the new `Get WebElements` or `Get WebElement` keyword.
71
+
72
+ For example:
73
+ | @{elements} Get Webelements class=UIAButton
74
+ | Click Element @{elements}[2]
75
+
76
+ """
77
+
78
+ ROBOT_LIBRARY_SCOPE = 'GLOBAL'
79
+ ROBOT_LIBRARY_VERSION = VERSION
80
+
81
+ def __init__(self, timeout=5, run_on_failure='Appium Capture Page Screenshot', sleep_between_wait_loop=0.2):
82
+ """AppiumLibrary can be imported with optional arguments.
83
+
84
+ ``timeout`` is the default timeout used to wait for all waiting actions.
85
+ It can be later set with `Set Appium Timeout`.
86
+
87
+ ``run_on_failure`` specifies the name of a keyword (from any available
88
+ libraries) to execute when a AppiumLibrary keyword fails.
89
+
90
+ By default `Capture Page Screenshot` will be used to take a screenshot of the current page.
91
+ Using the value `No Operation` will disable this feature altogether. See
92
+ `Register Keyword To Run On Failure` keyword for more information about this
93
+ functionality.
94
+
95
+ ``sleep_between_wait_loop`` is the default sleep used to wait between loop in all wait until keywords
96
+
97
+ Examples:
98
+ | Library | AppiumLibrary | 10 | # Sets default timeout to 10 seconds |
99
+ | Library | AppiumLibrary | timeout=10 | run_on_failure=No Operation | # Sets default timeout to 10 seconds and does nothing on failure |
100
+ | Library | AppiumLibrary | timeout=10 | sleep_between_wait_loop=0.3 | # Sets default timeout to 10 seconds and sleep 300 ms between wait loop |
101
+ """
102
+ for base in AppiumLibrary.__bases__:
103
+ base.__init__(self)
104
+ self.set_appium_timeout(timeout)
105
+ self.register_keyword_to_run_on_failure(run_on_failure)
106
+ self.set_sleep_between_wait_loop(sleep_between_wait_loop)
@@ -0,0 +1,10 @@
1
+ import os
2
+ import sys
3
+
4
+ PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
5
+ if PROJECT_ROOT not in sys.path:
6
+ sys.path.append(PROJECT_ROOT)
7
+
8
+ def get_version():
9
+ from AppiumLibrary.version import VERSION
10
+ return VERSION
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ from ._applicationmanagement import _ApplicationManagementKeywords
4
+ from ._element import _ElementKeywords
5
+ from ._logging import _LoggingKeywords
6
+ from ._powershell import _PowershellKeywords
7
+ from ._runonfailure import _RunOnFailureKeywords
8
+ from ._screenrecord import _ScreenrecordKeywords
9
+ from ._screenshot import _ScreenshotKeywords
10
+ from ._waiting import _WaitingKeywords
11
+ from ._windows import _WindowsKeywords
12
+
13
+ __all__ = ["_LoggingKeywords",
14
+ "_RunOnFailureKeywords",
15
+ "_ElementKeywords",
16
+ "_PowershellKeywords",
17
+ "_WindowsKeywords",
18
+ "_ScreenshotKeywords",
19
+ "_ApplicationManagementKeywords",
20
+ "_WaitingKeywords",
21
+ "_ScreenrecordKeywords"]
@@ -0,0 +1,515 @@
1
+ # -*- coding: utf-8 -*-
2
+ import inspect
3
+ import os
4
+
5
+ import robot
6
+ from appium import webdriver
7
+ from appium.options.common import AppiumOptions
8
+
9
+ from AppiumLibrary.utils import ApplicationCache
10
+ from .keywordgroup import KeywordGroup
11
+
12
+ ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
13
+
14
+
15
+ class _ApplicationManagementKeywords(KeywordGroup):
16
+ def __init__(self):
17
+ self._cache = ApplicationCache()
18
+ self._timeout_in_secs = float(5)
19
+
20
+ # Public, open and close
21
+ def appium_get_current_application(self):
22
+ current = self._cache.current
23
+ if current is self._cache._no_current:
24
+ return None
25
+ return current
26
+
27
+ def appium_get_session_index(self):
28
+ current_index = self._cache.current_index
29
+ return current_index
30
+
31
+ def appium_close_application(self, ignore_fail=False, quit_app=True):
32
+ self._cache.close(ignore_fail, quit_app)
33
+
34
+ def appium_close_all_applications(self, ignore_fail=True, quit_app=True):
35
+ self._cache.close_all(ignore_fail, quit_app)
36
+
37
+ def appium_save_source(self, file_path='file_source.txt'):
38
+ page_source = self._invoke_original("get_source")
39
+ with open(file_path, 'w', encoding='utf-8') as file:
40
+ file.write(page_source)
41
+
42
+ def close_application(self):
43
+ """Closes the current application and also close webdriver session."""
44
+ self._info('Closing application with session id %s' % self._current_application().session_id)
45
+ self._cache.close()
46
+
47
+ def close_all_applications(self, ignore_fail=True):
48
+ """Closes all open applications.
49
+
50
+ This keyword is meant to be used in test or suite teardown to
51
+ make sure all the applications are closed before the test execution
52
+ finishes.
53
+
54
+ After this keyword, the application indices returned by `Open Application`
55
+ are reset and start from `1`.
56
+ """
57
+
58
+ self._info('Closing all applications')
59
+ self._cache.close_all(ignore_fail)
60
+
61
+ def open_application(self, remote_url, alias=None, **kwargs):
62
+ """Opens a new application to given Appium server.
63
+ Capabilities of appium server, Android and iOS,
64
+ Please check https://appium.io/docs/en/2.1/cli/args/
65
+ | *Option* | *Man.* | *Description* |
66
+ | remote_url | Yes | Appium server url |
67
+ | alias | no | alias |
68
+ | strict_ssl | No | allows you to send commands to an invalid certificate host like a self-signed one. |
69
+
70
+ Examples:
71
+ | Open Application | http://localhost:4723/wd/hub | alias=Myapp1 | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | app=your.app |
72
+ | Open Application | http://localhost:4723/wd/hub | alias=Myapp1 | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | app=your.app | strict_ssl=False |
73
+ | Open Application | http://localhost:4723/wd/hub | platformName=Android | platformVersion=4.2.2 | deviceName=192.168.56.101:5555 | app=${CURDIR}/demoapp/OrangeDemoApp.apk | appPackage=com.netease.qa.orangedemo | appActivity=MainActivity |
74
+ """
75
+
76
+ desired_caps = AppiumOptions().load_capabilities(caps=kwargs)
77
+ application = webdriver.Remote(str(remote_url), options=desired_caps)
78
+
79
+ self._info('Opened application with session id %s' % application.session_id)
80
+
81
+ if hasattr(self, "clear_search_context"):
82
+ self._invoke_original("clear_search_context")
83
+
84
+ return self._cache.register(application, alias)
85
+
86
+ def switch_application(self, index_or_alias):
87
+ """Switches the active application by index or alias.
88
+
89
+ `index_or_alias` is either application index (an integer) or alias
90
+ (a string). Index is got as the return value of `Open Application`.
91
+
92
+ This keyword returns the index of the previous active application,
93
+ which can be used to switch back to that application later.
94
+
95
+ Example:
96
+ | ${appium1}= | Open Application | http://localhost:4723/wd/hub | alias=MyApp1 | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | app=your.app |
97
+ | ${appium2}= | Open Application | http://localhost:4755/wd/hub | alias=MyApp2 | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | app=your.app |
98
+ | Click Element | sendHello | # Executed on appium running at localhost:4755 |
99
+ | Switch Application | ${appium1} | # Switch using index |
100
+ | Click Element | ackHello | # Executed on appium running at localhost:4723 |
101
+ | Switch Application | MyApp2 | # Switch using alias |
102
+ | Page Should Contain Text | ackHello Received | # Executed on appium running at localhost:4755 |
103
+
104
+ """
105
+ old_index = self._cache.current_index
106
+ if index_or_alias is None:
107
+ self._cache.close()
108
+ else:
109
+ self._cache.switch(index_or_alias)
110
+ return old_index
111
+
112
+ def launch_application(self):
113
+ """*DEPRECATED!!* in selenium v4, use `Activate Application` keyword.
114
+
115
+ Launch application. Application can be launched while Appium session running.
116
+ This keyword can be used to launch application during test case or between test cases.
117
+
118
+ This keyword works while `Open Application` has a test running. This is good practice to `Launch Application`
119
+ and `Quit Application` between test cases. As Suite Setup is `Open Application`, `Test Setup` can be used to `Launch Application`
120
+
121
+ Example (syntax is just a representation, refer to RF Guide for usage of Setup/Teardown):
122
+ | [Setup Suite] |
123
+ | | Open Application | http://localhost:4723/wd/hub | platformName=Android | deviceName=192.168.56.101:5555 | app=${CURDIR}/demoapp/OrangeDemoApp.apk |
124
+ | [Test Setup] |
125
+ | | Launch Application |
126
+ | | | <<<test execution>>> |
127
+ | | | <<<test execution>>> |
128
+ | [Test Teardown] |
129
+ | | Quit Application |
130
+ | [Suite Teardown] |
131
+ | | Close Application |
132
+
133
+ See `Quit Application` for quiting application but keeping Appium sesion running.
134
+ """
135
+ driver = self._current_application()
136
+ driver.launch_app()
137
+
138
+ def quit_application(self):
139
+ """*DEPRECATED!!* in selenium v4, check `Close Application` keyword.
140
+
141
+ Close application. Application can be quit while Appium session is kept alive.
142
+ This keyword can be used to close application during test case or between test cases.
143
+
144
+ See `Launch Application` for an explanation.
145
+
146
+ """
147
+ driver = self._current_application()
148
+ driver.close_app()
149
+
150
+ def reset_application(self):
151
+ """*DEPRECATED!!* in selenium v4, check `Terminate Application` keyword.
152
+
153
+ Reset application. Open Application can be reset while Appium session is kept alive.
154
+ """
155
+ driver = self._current_application()
156
+ driver.reset()
157
+
158
+ def remove_application(self, application_id):
159
+ """ Removes the application that is identified with an application id
160
+
161
+ Example:
162
+ | Remove Application | com.netease.qa.orangedemo |
163
+
164
+ """
165
+ driver = self._current_application()
166
+ driver.remove_app(application_id)
167
+
168
+ def get_appium_timeout(self):
169
+ """Gets the timeout in seconds that is used by various keywords.
170
+
171
+ See `Set Appium Timeout` for an explanation."""
172
+ return robot.utils.secs_to_timestr(self._timeout_in_secs)
173
+
174
+ def set_appium_timeout(self, seconds):
175
+ """Sets the timeout in seconds used by various keywords.
176
+
177
+ There are several `Wait ...` keywords that take timeout as an
178
+ argument. All of these timeout arguments are optional. The timeout
179
+ used by all of them can be set globally using this keyword.
180
+
181
+ The previous timeout value is returned by this keyword and can
182
+ be used to set the old value back later. The default timeout
183
+ is 5 seconds, but it can be altered in `importing`.
184
+
185
+ Example:
186
+ | ${orig timeout} = | Set Appium Timeout | 15 seconds |
187
+ | Open page that loads slowly |
188
+ | Set Appium Timeout | ${orig timeout} |
189
+ """
190
+ old_timeout = self._invoke_original("get_appium_timeout")
191
+ self._timeout_in_secs = robot.utils.timestr_to_secs(seconds)
192
+ return old_timeout
193
+
194
+ def get_appium_sessionId(self):
195
+ """Returns the current session ID as a reference"""
196
+ self._info("Appium Session ID: " + self._current_application().session_id)
197
+ return self._current_application().session_id
198
+
199
+ def get_source(self):
200
+ """Returns the entire source of the current page."""
201
+ return self._current_application().page_source
202
+
203
+ def log_source(self, loglevel='INFO'):
204
+ """Logs and returns the entire html source of the current page or frame.
205
+
206
+ The `loglevel` argument defines the used log level. Valid log levels are
207
+ `WARN`, `INFO` (default), `DEBUG`, `TRACE` and `NONE` (no logging).
208
+ """
209
+ ll = loglevel.upper()
210
+ if ll == 'NONE':
211
+ return ''
212
+ else:
213
+ if "run_keyword_and_ignore_error" not in [check_error_ignored[3] for check_error_ignored in
214
+ inspect.stack()]:
215
+ source = self._current_application().page_source
216
+ self._log(source, ll)
217
+ return source
218
+ else:
219
+ return ''
220
+
221
+ def execute_script(self, script, **kwargs):
222
+ """
223
+ Execute a variety of native, mobile commands that aren't associated
224
+ with a specific endpoint. See [https://appium.io/docs/en/commands/mobile-command/|Appium Mobile Command]
225
+ for more details.
226
+
227
+ Example:
228
+ | &{scrollGesture} | create dictionary | left=${50} | top=${150} | width=${50} | height=${200} | direction=down | percent=${100} |
229
+ | Sleep | 1 |
230
+ | Execute Script | mobile: scrollGesture | &{scrollGesture} |
231
+
232
+ Updated in AppiumLibrary 2
233
+ """
234
+ if kwargs:
235
+ self._info(f"Provided dictionary: {kwargs}")
236
+
237
+ return self._current_application().execute_script(script, kwargs)
238
+
239
+ def execute_async_script(self, script, **kwargs):
240
+ """
241
+ Inject a snippet of Async-JavaScript into the page for execution in the
242
+ context of the currently selected frame (Web context only).
243
+
244
+ The executed script is assumed to be asynchronous and must signal that is done by
245
+ invoking the provided callback, which is always provided as the final argument to the
246
+ function.
247
+
248
+ The value to this callback will be returned to the client.
249
+
250
+ Check `Execute Script` for example kwargs usage
251
+
252
+ Updated in AppiumLibrary 2
253
+ """
254
+ if kwargs:
255
+ self._info(f"Provided dictionary: {kwargs}")
256
+
257
+ return self._current_application().execute_async_script(script, kwargs)
258
+
259
+ def execute_adb_shell(self, command, *args):
260
+ """
261
+ Execute ADB shell commands
262
+
263
+ Android only.
264
+
265
+ - _command_ - The ABD shell command
266
+ - _args_ - Arguments to send to command
267
+
268
+ Returns the exit code of ADB shell.
269
+
270
+ Requires server flag --relaxed-security to be set on Appium server.
271
+ """
272
+ return self._current_application().execute_script('mobile: shell', {
273
+ 'command': command,
274
+ 'args': list(args)
275
+ })
276
+
277
+ def execute_adb_shell_timeout(self, command, timeout, *args):
278
+ """
279
+ Execute ADB shell commands
280
+
281
+ Android only.
282
+
283
+ - _command_ - The ABD shell command
284
+ - _timeout_ - Timeout to be applied to command
285
+ - _args_ - Arguments to send to command
286
+
287
+ Returns the exit code of ADB shell.
288
+
289
+ Requires server flag --relaxed-security to be set on Appium server.
290
+ """
291
+ return self._current_application().execute_script('mobile: shell', {
292
+ 'command': command,
293
+ 'args': list(args),
294
+ 'timeout': timeout
295
+ })
296
+
297
+ def go_back(self):
298
+ """Goes one step backward in the browser history."""
299
+ self._current_application().back()
300
+
301
+ def lock(self, seconds=5):
302
+ """
303
+ Lock the device for a certain period of time. iOS only.
304
+ """
305
+ self._current_application().lock(robot.utils.timestr_to_secs(seconds))
306
+
307
+ def background_app(self, seconds=5):
308
+ """*DEPRECATED!!* use `Background Application` instead.
309
+ Puts the application in the background on the device for a certain
310
+ duration.
311
+ """
312
+ self._current_application().background_app(seconds)
313
+
314
+ def background_application(self, seconds=5):
315
+ """
316
+ Puts the application in the background on the device for a certain
317
+ duration.
318
+ """
319
+ self._current_application().background_app(seconds)
320
+
321
+ def activate_application(self, app_id):
322
+ """
323
+ Activates the application if it is not running or is running in the background.
324
+ Args:
325
+ - app_id - BundleId for iOS. Package name for Android.
326
+
327
+ New in AppiumLibrary v2
328
+ """
329
+ self._current_application().activate_app(app_id)
330
+
331
+ def terminate_application(self, app_id):
332
+ """
333
+ Terminate the given app on the device
334
+
335
+ Args:
336
+ - app_id - BundleId for iOS. Package name for Android.
337
+
338
+ New in AppiumLibrary v2
339
+ """
340
+ return self._current_application().terminate_app(app_id)
341
+
342
+ def stop_application(self, app_id, timeout=5000, include_stderr=True):
343
+ """
344
+ Stop the given app on the device
345
+
346
+ Android only. New in AppiumLibrary v2
347
+ """
348
+ self._current_application().execute_script('mobile: shell', {
349
+ 'command': 'am force-stop',
350
+ 'args': [app_id],
351
+ 'includeStderr': include_stderr,
352
+ 'timeout': timeout
353
+ })
354
+
355
+ def touch_id(self, match=True):
356
+ """
357
+ Simulate Touch ID on iOS Simulator
358
+
359
+ `match` (boolean) whether the simulated fingerprint is valid (default true)
360
+
361
+ New in AppiumLibrary 1.5
362
+ """
363
+ self._current_application().touch_id(match)
364
+
365
+ def toggle_touch_id_enrollment(self):
366
+ """
367
+ Toggle Touch ID enrolled state on iOS Simulator
368
+
369
+ New in AppiumLibrary 1.5
370
+ """
371
+ self._current_application().toggle_touch_id_enrollment()
372
+
373
+ def shake(self):
374
+ """
375
+ Shake the device
376
+ """
377
+ self._current_application().shake()
378
+
379
+ def portrait(self):
380
+ """
381
+ Set the device orientation to PORTRAIT
382
+ """
383
+ self._rotate('PORTRAIT')
384
+
385
+ def landscape(self):
386
+ """
387
+ Set the device orientation to LANDSCAPE
388
+ """
389
+ self._rotate('LANDSCAPE')
390
+
391
+ def get_current_context(self):
392
+ """Get current context."""
393
+ return self._current_application().current_context
394
+
395
+ def get_contexts(self):
396
+ """Get available contexts."""
397
+ print(self._current_application().contexts)
398
+ return self._current_application().contexts
399
+
400
+ def get_window_height(self):
401
+ """Get current device height.
402
+
403
+ Example:
404
+ | ${width} | Get Window Width |
405
+ | ${height} | Get Window Height |
406
+ | Click A Point | ${width} | ${height} |
407
+
408
+ New in AppiumLibrary 1.4.5
409
+ """
410
+ return self._current_application().get_window_size()['height']
411
+
412
+ def get_window_width(self):
413
+ """Get current device width.
414
+
415
+ Example:
416
+ | ${width} | Get Window Width |
417
+ | ${height} | Get Window Height |
418
+ | Click A Point | ${width} | ${height} |
419
+
420
+ New in AppiumLibrary 1.4.5
421
+ """
422
+ return self._current_application().get_window_size()['width']
423
+
424
+ def switch_to_context(self, context_name):
425
+ """Switch to a new context"""
426
+ self._current_application().switch_to.context(context_name)
427
+
428
+ def switch_to_frame(self, frame):
429
+ """
430
+ Switches focus to the specified frame, by index, name, or webelement.
431
+
432
+ Example:
433
+ | Go To Url | http://www.xxx.com |
434
+ | Switch To Frame | iframe_name|
435
+ | Click Element | xpath=//*[@id="online-btn"] |
436
+ """
437
+ self._current_application().switch_to.frame(frame)
438
+
439
+ def switch_to_parent_frame(self):
440
+ """
441
+ Switches focus to the parent context. If the current context is the top
442
+ level browsing context, the context remains unchanged.
443
+ """
444
+ self._current_application().switch_to.parent_frame()
445
+
446
+ def switch_to_window(self, window_name):
447
+ """
448
+ Switch to a new webview window if the application contains multiple webviews
449
+ """
450
+ self._current_application().switch_to.window(window_name)
451
+
452
+ def go_to_url(self, url):
453
+ """
454
+ Opens URL in default web browser.
455
+
456
+ Example:
457
+ | Open Application | http://localhost:4755/wd/hub | platformName=iOS | platformVersion=7.0 | deviceName='iPhone Simulator' | browserName=Safari |
458
+ | Go To URL | http://m.webapp.com |
459
+ """
460
+ self._current_application().get(url)
461
+
462
+ def get_capability(self, capability_name=None):
463
+ """
464
+ Return the desired capability value by desired capability name
465
+ """
466
+ try:
467
+ capabilities = self._current_application().capabilities
468
+ capability = capabilities[capability_name] if capability_name else capabilities
469
+ except Exception as e:
470
+ raise e
471
+ return capability
472
+
473
+ def get_window_title(self):
474
+ """Get the current Webview window title."""
475
+ return self._current_application().title
476
+
477
+ def get_window_url(self):
478
+ """Get the current Webview window URL."""
479
+ return self._current_application().current_url
480
+
481
+ def get_windows(self):
482
+ """Get available Webview windows."""
483
+ print(self._current_application().window_handles)
484
+ return self._current_application().window_handles
485
+
486
+ # Private
487
+
488
+ def _current_application(self):
489
+ if not self._cache.current:
490
+ raise RuntimeError('No application is open')
491
+ return self._cache.current
492
+
493
+ def _get_platform(self):
494
+ try:
495
+ platform_name = self._current_application().capabilities['platformName']
496
+ except Exception as e:
497
+ raise e
498
+ return platform_name.lower()
499
+
500
+ def _is_platform(self, platform):
501
+ platform_name = self._get_platform()
502
+ return platform.lower() == platform_name
503
+
504
+ def _is_ios(self):
505
+ return self._is_platform('ios')
506
+
507
+ def _is_android(self):
508
+ return self._is_platform('android')
509
+
510
+ def _is_window(self):
511
+ return self._is_platform('windows')
512
+
513
+ def _rotate(self, orientation):
514
+ driver = self._current_application()
515
+ driver.orientation = orientation