diff --git a/appium/webdriver/extensions/clipboard.py b/appium/webdriver/extensions/clipboard.py index de7f2390c..1400b82f6 100644 --- a/appium/webdriver/extensions/clipboard.py +++ b/appium/webdriver/extensions/clipboard.py @@ -15,7 +15,11 @@ import base64 from typing import TYPE_CHECKING, Optional, cast +from selenium.common.exceptions import UnknownMethodException + from appium.protocols.webdriver.can_execute_commands import CanExecuteCommands +from appium.protocols.webdriver.can_execute_scripts import CanExecuteScripts +from appium.protocols.webdriver.can_remember_extension_presence import CanRememberExtensionPresence from appium.webdriver.clipboard_content_type import ClipboardContentType from ..mobilecommand import MobileCommand as Command @@ -24,7 +28,7 @@ from appium.webdriver.webdriver import WebDriver -class Clipboard(CanExecuteCommands): +class Clipboard(CanExecuteCommands, CanExecuteScripts, CanRememberExtensionPresence): def set_clipboard( self, content: bytes, content_type: str = ClipboardContentType.PLAINTEXT, label: Optional[str] = None ) -> 'WebDriver': @@ -39,13 +43,18 @@ def set_clipboard( Returns: Union['WebDriver', 'Clipboard']: Self instance """ + ext_name = 'mobile: setClipboard' options = { 'content': base64.b64encode(content).decode('UTF-8'), 'contentType': content_type, } if label: options['label'] = label - self.execute(Command.SET_CLIPBOARD, options) + try: + self.assert_extension_exists(ext_name).execute_script(ext_name, options) + except UnknownMethodException: + # TODO: Remove the fallback + self.mark_extension_absence(ext_name).execute(Command.SET_CLIPBOARD, options) return cast('WebDriver', self) def set_clipboard_text(self, text: str, label: Optional[str] = None) -> 'WebDriver': @@ -68,9 +77,15 @@ def get_clipboard(self, content_type: str = ClipboardContentType.PLAINTEXT) -> b is supported on Android Returns: - base64-encoded string: Clipboard content. Or return an empty string if the clipboard is empty + Clipboard content as bytearray. Or empty bytes if the clipboard is empty """ - base64_str = self.execute(Command.GET_CLIPBOARD, {'contentType': content_type})['value'] + ext_name = 'mobile: getClipboard' + options = {'contentType': content_type} + try: + base64_str = self.assert_extension_exists(ext_name).execute_script(ext_name, options) + except UnknownMethodException: + # TODO: Remove the fallback + base64_str = self.mark_extension_absence(ext_name).execute(Command.GET_CLIPBOARD, options)['value'] return base64.b64decode(base64_str) def get_clipboard_text(self) -> str: diff --git a/test/unit/webdriver/device/clipboard_test.py b/test/unit/webdriver/device/clipboard_test.py index 44b346e1f..7e21797a0 100644 --- a/test/unit/webdriver/device/clipboard_test.py +++ b/test/unit/webdriver/device/clipboard_test.py @@ -25,12 +25,17 @@ def test_set_clipboard_with_url(self): httpretty.register_uri( httpretty.POST, appium_command('/session/1234567890/appium/device/set_clipboard'), body='{"value": ""}' ) + httpretty.register_uri( + httpretty.POST, + appium_command('/session/1234567890/execute/sync'), + body='{"value": ""}', + ) driver.set_clipboard(bytes(str('http://appium.io/'), 'UTF-8'), ClipboardContentType.URL, 'label for android') d = get_httpretty_request_body(httpretty.last_request()) - assert d['content'] == 'aHR0cDovL2FwcGl1bS5pby8=' - assert d['contentType'] == 'url' - assert d['label'] == 'label for android' + assert d['args'][0]['content'] == 'aHR0cDovL2FwcGl1bS5pby8=' + assert d['args'][0]['contentType'] == 'url' + assert d['args'][0]['label'] == 'label for android' @httpretty.activate def test_set_clipboard_text(self): @@ -38,8 +43,13 @@ def test_set_clipboard_text(self): httpretty.register_uri( httpretty.POST, appium_command('/session/1234567890/appium/device/set_clipboard'), body='{"value": ""}' ) + httpretty.register_uri( + httpretty.POST, + appium_command('/session/1234567890/execute/sync'), + body='{"value": ""}', + ) driver.set_clipboard_text('hello') d = get_httpretty_request_body(httpretty.last_request()) - assert d['content'] == 'aGVsbG8=' - assert d['contentType'] == 'plaintext' + assert d['args'][0]['content'] == 'aGVsbG8=' + assert d['args'][0]['contentType'] == 'plaintext'