diff --git a/.github/workflows/functional-test.yml b/.github/workflows/functional-test.yml index 5f3f7597..b77088fb 100644 --- a/.github/workflows/functional-test.yml +++ b/.github/workflows/functional-test.yml @@ -99,13 +99,11 @@ jobs: name: func_test_android3 - target: test/functional/android/finger_print_tests.py test/functional/android/screen_record_tests.py test/functional/android/settings_tests.py test/functional/android/chrome_tests.py name: func_test_android4 - - target: test/functional/android/context_switching_tests.py test/functional/android/remote_fs_tests.py + - target: test/functional/android/remote_fs_tests.py name: func_test_android5 - target: test/functional/android/common_tests.py test/functional/android/webelement_tests.py name: func_test_android6 - - target: test/functional/android/applications_tests.py - name: func_test_android7 - - target: test/functional/android/network_connection_tests.py test/functional/android/log_event_tests.py test/functional/android/activities_tests.py test/functional/android/hw_actions_tests.py + - target: test/functional/android/network_connection_tests.py test/functional/android/log_event_tests.py test/functional/android/hw_actions_tests.py name: func_test_android8 runs-on: ubuntu-latest diff --git a/test/functional/android/activities_tests.py b/test/functional/android/activities_tests.py deleted file mode 100644 index d8d7585e..00000000 --- a/test/functional/android/activities_tests.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from .helper.test_helper import APIDEMO_PKG_NAME, BaseTestCase - - -class TestActivities(BaseTestCase): - def test_current_activity(self) -> None: - activity = self.driver.current_activity - assert '.ApiDemos' == activity - - def test_start_activity_this_app(self) -> None: - self.driver.execute_script( - 'mobile: startActivity', - { - 'component': f'{APIDEMO_PKG_NAME}/.ApiDemos', - }, - ) - self._assert_activity_contains('Demos') - - self.driver.execute_script( - 'mobile: startActivity', - { - 'component': f'{APIDEMO_PKG_NAME}/.accessibility.AccessibilityNodeProviderActivity', - }, - ) - self._assert_activity_contains('Node') - - def test_start_activity_other_app(self) -> None: - self.driver.execute_script( - 'mobile: startActivity', - { - 'component': f'{APIDEMO_PKG_NAME}/.ApiDemos', - }, - ) - self._assert_activity_contains('Demos') - - self.driver.execute_script( - 'mobile: startActivity', - { - 'component': 'com.google.android.deskclock/com.android.deskclock.DeskClock', - }, - ) - self._assert_activity_contains('Clock') - - def _assert_activity_contains(self, activity: str) -> None: - current = self.driver.current_activity - assert activity in current diff --git a/test/functional/android/applications_tests.py b/test/functional/android/applications_tests.py deleted file mode 100644 index 9035c04e..00000000 --- a/test/functional/android/applications_tests.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os - -from appium.webdriver.applicationstate import ApplicationState - -from .helper.desired_capabilities import PATH -from .helper.test_helper import APIDEMO_PKG_NAME, BaseTestCase - - -class TestApplications(BaseTestCase): - def test_background_app(self) -> None: - self.driver.background_app(1) - - def test_is_app_installed(self) -> None: - assert not self.driver.is_app_installed('sdfsdf') - assert self.driver.is_app_installed(APIDEMO_PKG_NAME) - - def test_install_app(self) -> None: - self.driver.remove_app(APIDEMO_PKG_NAME) - assert not self.driver.is_app_installed(APIDEMO_PKG_NAME) - self.driver.install_app(PATH(os.path.join('../..', 'apps', 'ApiDemos-debug.apk.zip'))) - assert self.driver.is_app_installed(APIDEMO_PKG_NAME) - - def test_remove_app(self) -> None: - assert self.driver.is_app_installed(APIDEMO_PKG_NAME) - self.driver.remove_app(APIDEMO_PKG_NAME) - assert not self.driver.is_app_installed(APIDEMO_PKG_NAME) - - def test_app_management(self) -> None: - app_id = self.driver.current_package - assert self.driver.query_app_state(app_id) == ApplicationState.RUNNING_IN_FOREGROUND - self.driver.background_app(-1) - assert self.driver.query_app_state(app_id) < ApplicationState.RUNNING_IN_FOREGROUND - self.driver.activate_app(app_id) - assert self.driver.query_app_state(app_id) == ApplicationState.RUNNING_IN_FOREGROUND - - def test_app_strings(self) -> None: - strings = self.driver.app_strings() - assert u'You can\'t wipe my data, you are a monkey!' == strings[u'monkey_wipe_data'] - - def test_app_strings_with_language(self) -> None: - strings = self.driver.app_strings('en') - assert u'You can\'t wipe my data, you are a monkey!' == strings[u'monkey_wipe_data'] - - def test_app_strings_with_language_and_file(self) -> None: - strings = self.driver.app_strings('en', 'some_file') - assert u'You can\'t wipe my data, you are a monkey!' == strings[u'monkey_wipe_data'] diff --git a/test/functional/android/context_switching_tests.py b/test/functional/android/context_switching_tests.py deleted file mode 100644 index 8151fcca..00000000 --- a/test/functional/android/context_switching_tests.py +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env python - -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pytest -from selenium.webdriver import ActionChains -from selenium.webdriver.common.actions import interaction -from selenium.webdriver.common.actions.action_builder import ActionBuilder -from selenium.webdriver.common.actions.pointer_input import PointerInput - -from appium import webdriver -from appium.common.exceptions import NoSuchContextException -from appium.options.common import AppiumOptions -from appium.webdriver.common.appiumby import AppiumBy -from test.helpers.constants import SERVER_URL_BASE - -from .helper import desired_capabilities - - -class TestContextSwitching(object): - def setup_method(self) -> None: - caps = desired_capabilities.get_desired_capabilities('ApiDemos-debug.apk.zip') - self.driver = webdriver.Remote(SERVER_URL_BASE, options=AppiumOptions().load_capabilities(caps)) - - def teardown_method(self) -> None: - self.driver.quit() - - def test_contexts_list(self) -> None: - self._enter_webview() - contexts = self.driver.contexts - assert 2 == len(contexts) - - def test_move_to_correct_context(self) -> None: - self._enter_webview() - assert 'WEBVIEW_io.appium.android.apis' == self.driver.current_context - - def test_actually_in_webview(self) -> None: - self._enter_webview() - el = self.driver.find_element(by=AppiumBy.XPATH, value='//a[@id="i am a link"]') - assert el is not None - - def test_move_back_to_native_context(self) -> None: - self._enter_webview() - self.driver.switch_to.context(None) - assert 'NATIVE_APP' == self.driver.current_context - - def test_set_invalid_context(self) -> None: - with pytest.raises(NoSuchContextException): - self.driver.switch_to.context('invalid name') - - def _enter_webview(self) -> None: - btn = self.driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='Views') - btn.click() - self._scroll_to_webview() - self._scroll_to_webview() - btn_web_view = self.driver.find_element(by=AppiumBy.ACCESSIBILITY_ID, value='WebView') - btn_web_view.click() - self.driver.switch_to.context('WEBVIEW') - - def _scroll_to_webview(self) -> None: - actions = ActionChains(self.driver) - actions.w3c_actions = ActionBuilder(self.driver, mouse=PointerInput(interaction.POINTER_TOUCH, "touch")) - actions.w3c_actions.pointer_action.move_to_location(393, 1915) - actions.w3c_actions.pointer_action.pointer_down() - actions.w3c_actions.pointer_action.move_to_location(462, 355) - actions.w3c_actions.pointer_action.release() - actions.perform() diff --git a/test/unit/webdriver/app_test.py b/test/unit/webdriver/app_test.py index 7cb7b6b3..45367141 100644 --- a/test/unit/webdriver/app_test.py +++ b/test/unit/webdriver/app_test.py @@ -23,84 +23,130 @@ class TestWebDriverApp(object): @httpretty.activate def test_install_app(self): driver = android_w3c_driver() - httpretty.register_uri( - httpretty.POST, appium_command('/session/1234567890/appium/device/install_app'), body='{"value": ""}' - ) httpretty.register_uri(httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": ""}') result = driver.install_app('path/to/app') - assert {'app': 'path/to/app'}, get_httpretty_request_body(httpretty.last_request()) + assert { + 'args': [{'app': 'path/to/app', 'appPath': 'path/to/app'}], + 'script': 'mobile: installApp', + } == get_httpretty_request_body(httpretty.last_request()) assert isinstance(result, WebDriver) @httpretty.activate def test_remove_app(self): driver = android_w3c_driver() - httpretty.register_uri( - httpretty.POST, appium_command('/session/1234567890/appium/device/remove_app'), body='{"value": ""}' - ) httpretty.register_uri(httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": ""}') result = driver.remove_app('com.app.id') - assert {'app': 'com.app.id'}, get_httpretty_request_body(httpretty.last_request()) + assert { + 'args': [{'appId': 'com.app.id', 'bundleId': 'com.app.id'}], + 'script': 'mobile: removeApp', + } == get_httpretty_request_body(httpretty.last_request()) assert isinstance(result, WebDriver) @httpretty.activate def test_app_installed(self): driver = android_w3c_driver() - httpretty.register_uri( - httpretty.POST, appium_command('/session/1234567890/appium/device/app_installed'), body='{"value": true}' - ) httpretty.register_uri( httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": true}' ) result = driver.is_app_installed("com.app.id") - assert {'app': "com.app.id"}, get_httpretty_request_body(httpretty.last_request()) + + assert { + 'args': [{'appId': 'com.app.id', 'bundleId': 'com.app.id'}], + 'script': 'mobile: isAppInstalled', + } == get_httpretty_request_body(httpretty.last_request()) assert result is True @httpretty.activate def test_terminate_app(self): driver = android_w3c_driver() - httpretty.register_uri( - httpretty.POST, appium_command('/session/1234567890/appium/device/terminate_app'), body='{"value": true}' - ) httpretty.register_uri( httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": true}' ) result = driver.terminate_app("com.app.id") - assert {'app': "com.app.id"}, get_httpretty_request_body(httpretty.last_request()) + + assert { + 'args': [{'appId': 'com.app.id', 'bundleId': 'com.app.id'}], + 'script': 'mobile: terminateApp', + } == get_httpretty_request_body(httpretty.last_request()) assert result is True @httpretty.activate def test_activate_app(self): driver = android_w3c_driver() - httpretty.register_uri( - httpretty.POST, appium_command('/session/1234567890/appium/device/activate_app'), body='{"value": ""}' - ) httpretty.register_uri(httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": ""}') result = driver.activate_app("com.app.id") - assert {'app': 'com.app.id'}, get_httpretty_request_body(httpretty.last_request()) + assert { + 'args': [{'appId': 'com.app.id', 'bundleId': 'com.app.id'}], + 'script': 'mobile: activateApp', + } == get_httpretty_request_body(httpretty.last_request()) assert isinstance(result, WebDriver) @httpretty.activate def test_background_app(self): driver = android_w3c_driver() - httpretty.register_uri( - httpretty.POST, appium_command('/session/1234567890/appium/app/background'), body='{"value": ""}' - ) httpretty.register_uri(httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": ""}') result = driver.background_app(0) - assert {'app': 0}, get_httpretty_request_body(httpretty.last_request()) + + assert {'args': [{'seconds': 0}], 'script': 'mobile: backgroundApp'} == get_httpretty_request_body( + httpretty.last_request() + ) assert isinstance(result, WebDriver) @httpretty.activate def test_query_app_state(self): driver = android_w3c_driver() - httpretty.register_uri( - httpretty.POST, appium_command('/session/1234567890/appium/device/app_state'), body='{"value": 3 }' - ) httpretty.register_uri(httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": 3}') result = driver.query_app_state('com.app.id') - assert {'app': 3}, get_httpretty_request_body(httpretty.last_request()) + assert { + 'args': [{'appId': 'com.app.id', 'bundleId': 'com.app.id'}], + 'script': 'mobile: queryAppState', + } == get_httpretty_request_body(httpretty.last_request()) assert result is ApplicationState.RUNNING_IN_BACKGROUND + + @httpretty.activate + def test_app_strings(self): + driver = android_w3c_driver() + httpretty.register_uri( + httpretty.POST, + appium_command('/session/1234567890/execute/sync'), + body='{"value": {"monkey_wipe_data": "You can\'t wipe my data, you are a monkey!"} }', + ) + result = driver.app_strings() + + assert {'args': [{}], 'script': 'mobile: getAppStrings'} == get_httpretty_request_body(httpretty.last_request()) + assert 'You can\'t wipe my data, you are a monkey!' == result['monkey_wipe_data'], result + + @httpretty.activate + def test_app_strings_with_lang(self): + driver = android_w3c_driver() + httpretty.register_uri( + httpretty.POST, + appium_command('/session/1234567890/execute/sync'), + body='{"value": {"monkey_wipe_data": "You can\'t wipe my data, you are a monkey!"} }', + ) + result = driver.app_strings('en') + + assert {'args': [{'language': 'en'}], 'script': 'mobile: getAppStrings'} == get_httpretty_request_body( + httpretty.last_request() + ) + assert 'You can\'t wipe my data, you are a monkey!' == result['monkey_wipe_data'], result + + @httpretty.activate + def test_app_strings_with_lang_and_file(self): + driver = android_w3c_driver() + httpretty.register_uri( + httpretty.POST, + appium_command('/session/1234567890/execute/sync'), + body='{"value": {"monkey_wipe_data": "You can\'t wipe my data, you are a monkey!"} }', + ) + result = driver.app_strings('en', 'some_file') + + assert { + 'args': [{'language': 'en', 'stringFile': 'some_file'}], + 'script': 'mobile: getAppStrings', + } == get_httpretty_request_body(httpretty.last_request()) + assert 'You can\'t wipe my data, you are a monkey!' == result['monkey_wipe_data'], result diff --git a/test/unit/webdriver/context_test.py b/test/unit/webdriver/context_test.py index 16ab9dc1..5352dee3 100644 --- a/test/unit/webdriver/context_test.py +++ b/test/unit/webdriver/context_test.py @@ -14,12 +14,41 @@ import httpretty -from test.unit.helper.test_helper import android_w3c_driver, appium_command +from test.unit.helper.test_helper import android_w3c_driver, appium_command, get_httpretty_request_body class TestWebDriverContext(object): + @httpretty.activate + def test_current_contexts(self): + driver = android_w3c_driver() + httpretty.register_uri( + httpretty.GET, appium_command('/session/1234567890/context'), body='{"value": "NATIVE_APP"}' + ) + assert driver.current_context == 'NATIVE_APP' + @httpretty.activate def test_get_contexts(self): driver = android_w3c_driver() - httpretty.register_uri(httpretty.GET, appium_command('/session/1234567890/context'), body='{"value": "NATIVE"}') - assert driver.current_context == 'NATIVE' + httpretty.register_uri( + httpretty.GET, appium_command('/session/1234567890/contexts'), body='{"value": ["NATIVE_APP", "CHROMIUM"]}' + ) + + assert ['NATIVE_APP', 'CHROMIUM'] == driver.contexts + + @httpretty.activate + def test_switch_to_context(self): + driver = android_w3c_driver() + httpretty.register_uri(httpretty.POST, appium_command('/session/1234567890/context'), body='{"value": null}') + + driver.switch_to.context(None) + + assert {'name': None} == get_httpretty_request_body(httpretty.last_request()) + + @httpretty.activate + def test_switch_to_context_native_app(self): + driver = android_w3c_driver() + httpretty.register_uri(httpretty.POST, appium_command('/session/1234567890/context'), body='{"value": null}') + + driver.switch_to.context('NATIVE_APP') + + assert {'name': 'NATIVE_APP'} == get_httpretty_request_body(httpretty.last_request()) diff --git a/test/unit/webdriver/webdriver_test.py b/test/unit/webdriver/webdriver_test.py index 39792dcc..f7fa3091 100644 --- a/test/unit/webdriver/webdriver_test.py +++ b/test/unit/webdriver/webdriver_test.py @@ -368,6 +368,24 @@ class CustomAppiumConnection(AppiumConnection): assert isinstance(driver.command_executor, CustomAppiumConnection) + @httpretty.activate + def test_extention_command_check(self): + driver = android_w3c_driver() + httpretty.register_uri( + httpretty.POST, appium_command('/session/1234567890/execute/sync'), body='{"value": true}' + ) + assert ( + driver.execute_script( + 'mobile: startActivity', + {'component': 'io.appium.android.apis/.accessibility.AccessibilityNodeProviderActivity'}, + ) + is True + ) + assert { + 'args': [{'component': 'io.appium.android.apis/.accessibility.AccessibilityNodeProviderActivity'}], + 'script': 'mobile: startActivity', + } == get_httpretty_request_body(httpretty.last_request()) + class SubWebDriver(WebDriver): def __init__(self, command_executor, direct_connection=False, options=None):