Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master'
Browse files Browse the repository at this point in the history
# Conflicts:
#	docs/APILibraryDocumentation.html
#	docs/DesktopLibraryDocumentation.html
#	docs/GUILibraryDocumentation.html
#	docs/MobileLibraryDocumentation.html
#	docs/SOAPLibraryDocumentation.html
  • Loading branch information
Wolfe1 committed Dec 7, 2020
2 parents 3a59d50 + 05e362d commit 1132169
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 1 deletion.
9 changes: 9 additions & 0 deletions samples/Appium-DesktopTests.robot
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,15 @@ Flick Tests
Wait Until Page Contains Element accessibility_id=Standard
Wait For And Click Element accessibility_id=Standard

Screen Recording Keyword Test - See video with logs or in log.html
Start Screen Recording
Wait For And Click Element accessibility_id=num2Button
Wait For And Click Element accessibility_id=num3Button
Wait For And Click Element accessibility_id=num4Button
Wait For And Click Element accessibility_id=num5Button
Wait Until Element Contains accessibility_id=CalculatorResults 2,345
Stop Screen Recording

Switch To Desktop Test
Close Application
Switch Application Desktop
Expand Down
76 changes: 75 additions & 1 deletion src/Zoomba/DesktopLibrary.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from selenium.common.exceptions import NoSuchElementException, InvalidSelectorException
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.touch_actions import TouchActions

from time import sleep, time
from robot import utils
from base64 import b64decode

try:
AppiumCommon = importlib.import_module('Helpers.AppiumCommon', package='Helpers')
Expand Down Expand Up @@ -132,6 +132,7 @@ def get_keyword_names(self):
'drag_and_drop_by_touch_offset', 'wait_for_and_tap', 'wait_for_and_double_tap',
'double_tap', 'flick', 'flick_from_element', 'scroll', 'scroll_from_element',
'wait_for_and_flick_from_element', 'wait_for_and_scroll_from_element',
'start_screen_recording', 'stop_screen_recording',
# External Libraries
'clear_text', 'click_button', 'click_element', 'close_all_applications',
'close_application', 'element_attribute_should_match', 'element_should_be_disabled',
Expand All @@ -149,6 +150,79 @@ def get_keyword_names(self):
'xpath_should_match_x_times', 'tap'
]

# Screen Recorder - adapted from AppiumLibrary
@keyword("Start Screen Recording")
def start_screen_recording(self, time_limit='180s', **options):
"""Starts an asynchronous Screen Recording for the current open application.
``timeLimit`` sets the actual time limit of the recorded video (defaulting to 180 seconds).
`Start Screen Recording` is used hand in hand with `Stop Screen Recording`.
See `Stop Screen Recording` for more details.
Keyword requires Appium to be used.
Example:
| `Start Screen Recording` | | # starts a screen record session |
| .... keyword actions | | |
| `Stop Screen Recording` | filename=output | # saves the recorded session |
"""
options['time_limit'] = utils.timestr_to_secs(time_limit)
self._output_format = '.mp4'
if self._recording is None:
self._recording = self._current_application().start_recording_screen(**options)

@keyword("Stop Screen Recording")
def stop_screen_recording(self, filename=None, **options):
"""Gathers the output from the previously started screen recording \
to a media file, then embeds it to the log.html(Android Only).
Requires an active or exhausted Screen Recording Session.
See `Start Screen Recording` for more details.
=== Optional Args ===
- ``remotePath`` The path to the remote location, where the resulting video should be \
uploaded. The following protocols are supported _http/https_, ftp. Null or empty \
string value (the default setting) means the content of resulting file should \
be encoded as Base64 and passed as the endpoint response value. An \
exception will be thrown if the generated media file is too big to fit \
into the available process memory.
- ``username`` The name of the user for the remote authentication.
- ``password`` The password for the remote authentication.
- ``method`` The http multipart upload method name. The _PUT_ one is used by default.
Keyword requires Appium to be used.
Example:
| `Start Screen Recording` | | # starts a screen record session |
| .... keyword actions | | |
| `Stop Screen Recording` | filename=output | # saves the recorded session |
"""
self._recording = self._current_application().stop_recording_screen(**options)
return self._save_recording(filename, options)

def _save_recording(self, filename, options):
path, link = self._get_screenrecord_paths(options, filename)
decoded = b64decode(self._recording)
with open(path, 'wb') as screenrecording:
screenrecording.write(decoded)
# Embed the Screen Recording to the log file
if not self._is_remotepath_set(options):
self._html('</td></tr><tr><td colspan="3"><a href="{vid}">'
'<video width="800px" controls>'
'<source src="{vid}" type="video/mp4">'
'</video></a>'.format(vid=link)
)
# Empty Screen Record Variable
self._recording = None
return path

# End Screen Recorder Keywords

@keyword("Driver Setup")
def driver_setup(self, path=None):
"""Starts the WinAppDriver.
Expand Down
23 changes: 23 additions & 0 deletions test/Desktop/test_desktop.py
Original file line number Diff line number Diff line change
Expand Up @@ -698,3 +698,26 @@ def test_drag_and_drop_by_touch_offset(self, tap_and_hold):
mock_desk = MagicMock()
DesktopLibrary.drag_and_drop_by_touch_offset(mock_desk, "some_locator", 50, 100)
tap_and_hold.assert_called_with(unittest.mock.ANY, unittest.mock.ANY)

def test_start_screen_recording(self):
mock_desk = MagicMock()
mock_desk._recording = None
DesktopLibrary.start_screen_recording(mock_desk)
self.assertTrue(mock_desk._recording == unittest.mock.ANY)

def test_stop_screen_recording(self):
mock_desk = MagicMock()
mock_desk._recording = None
DesktopLibrary.start_screen_recording(mock_desk)
file = DesktopLibrary.stop_screen_recording(mock_desk)
self.assertTrue(file == unittest.mock.ANY)

def test_save_recording(self):
mock_desk = MagicMock()
mock_desk._recording = b'some data'
mock_desk._is_remotepath_set = MagicMock(return_value=False)
options = ["username=test"]
mock_desk._get_screenrecord_paths = MagicMock(return_value=("path", "link"))
file = DesktopLibrary._save_recording(mock_desk, "filename", options)
self.assertTrue(file == "path")
os.remove("path")

0 comments on commit 1132169

Please sign in to comment.