Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,5 @@
rev: 'v0.761'
hooks:
- id: mypy
files: ^appium/
entry: mypy appium/
entry: mypy appium/ test/
pass_filenames: false
2 changes: 1 addition & 1 deletion appium/webdriver/extensions/action_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def drag_and_drop(self, origin_el: WebElement, destination_el: WebElement) -> T:
action.long_press(origin_el).move_to(destination_el).release().perform()
return self

def tap(self, positions: List[Tuple], duration: Optional[int] = None) -> T:
def tap(self, positions: List[Tuple[int, int]], duration: Optional[int] = None) -> T:
"""Taps on an particular place with up to five fingers, holding for a
certain time

Expand Down
5 changes: 4 additions & 1 deletion appium/webdriver/extensions/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,16 @@ class for more details.
}
return self.execute(Command.QUERY_APP_STATE, data)['value']

def app_strings(self, language: str = None, string_file: str = None) -> str:
def app_strings(self, language: str = None, string_file: str = None) -> Dict[str, str]:
"""Returns the application strings from the device for the specified
language.

Args:
language (str): strings language code
string_file (str): the name of the string file to query

Returns:
Dict[str, str]: The key is string id and the value is the content.
"""
data = {}
if language is not None:
Expand Down
2 changes: 1 addition & 1 deletion ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ if [[ $? -ne 0 ]] ; then
fi

(
python -m mypy appium
python -m mypy appium test
)
if [[ $? -ne 0 ]] ; then
EXIT_STATUS=1
Expand Down
8 changes: 4 additions & 4 deletions test/functional/android/activities_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,25 +19,25 @@


class ActivitiesTests(BaseTestCase):
def test_current_activity(self):
def test_current_activity(self) -> None:
activity = self.driver.current_activity
self.assertEqual('.ApiDemos', activity)

def test_start_activity_this_app(self):
def test_start_activity_this_app(self) -> None:
self.driver.start_activity(APIDEMO_PKG_NAME, ".ApiDemos")
self._assert_activity_contains('Demos')

self.driver.start_activity(APIDEMO_PKG_NAME, ".accessibility.AccessibilityNodeProviderActivity")
self._assert_activity_contains('Node')

def test_start_activity_other_app(self):
def test_start_activity_other_app(self) -> None:
self.driver.start_activity(APIDEMO_PKG_NAME, ".ApiDemos")
self._assert_activity_contains('Demos')

self.driver.start_activity("com.android.calculator2", ".Calculator")
self._assert_activity_contains('Calculator')

def _assert_activity_contains(self, activity):
def _assert_activity_contains(self, activity: str) -> None:
current = self.driver.current_activity
self.assertTrue(activity in current)

Expand Down
20 changes: 10 additions & 10 deletions test/functional/android/applications_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,33 @@

class ApplicationsTests(BaseTestCase):

def test_background_app(self):
def test_background_app(self) -> None:
self.driver.background_app(1)
sleep(3)
self.driver.launch_app()

def test_is_app_installed(self):
def test_is_app_installed(self) -> None:
self.assertFalse(self.driver.is_app_installed('sdfsdf'))
self.assertTrue(self.driver.is_app_installed(APIDEMO_PKG_NAME))

def test_install_app(self):
def test_install_app(self) -> None:
self.skipTest('This causes the server to crash. no idea why')
self.assertFalse(self.driver.is_app_installed('io.selendroid.testapp'))
self.driver.install_app('/Users/isaac/code/python-client/test/apps/selendroid-test-app.apk')
self.assertTrue(self.driver.is_app_installed('io.selendroid.testapp'))

def test_remove_app(self):
def test_remove_app(self) -> None:
self.assertTrue(self.driver.is_app_installed(APIDEMO_PKG_NAME))
self.driver.remove_app(APIDEMO_PKG_NAME)
self.assertFalse(self.driver.is_app_installed(APIDEMO_PKG_NAME))

def test_close_and_launch_app(self):
def test_close_and_launch_app(self) -> None:
self.driver.close_app()
self.driver.launch_app()
activity = self.driver.current_activity
self.assertEqual('.ApiDemos', activity)

def test_app_management(self):
def test_app_management(self) -> None:
app_id = self.driver.current_package
self.assertEqual(self.driver.query_app_state(app_id),
ApplicationState.RUNNING_IN_FOREGROUND)
Expand All @@ -60,19 +60,19 @@ def test_app_management(self):
self.assertEqual(self.driver.query_app_state(app_id),
ApplicationState.RUNNING_IN_FOREGROUND)

def test_app_strings(self):
def test_app_strings(self) -> None:
strings = self.driver.app_strings()
self.assertEqual(u'You can\'t wipe my data, you are a monkey!', strings[u'monkey_wipe_data'])

def test_app_strings_with_language(self):
def test_app_strings_with_language(self) -> None:
strings = self.driver.app_strings('en')
self.assertEqual(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):
def test_app_strings_with_language_and_file(self) -> None:
strings = self.driver.app_strings('en', 'some_file')
self.assertEqual(u'You can\'t wipe my data, you are a monkey!', strings[u'monkey_wipe_data'])

def test_reset(self):
def test_reset(self) -> None:
self.driver.reset()
self.assertTrue(self.driver.is_app_installed(APIDEMO_PKG_NAME))

Expand Down
6 changes: 3 additions & 3 deletions test/functional/android/chrome_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@


class ChromeTests(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
caps = get_desired_capabilities()
caps['browserName'] = 'Chrome'
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', caps)

def tearDown(self):
def tearDown(self) -> None:
self.driver.quit()

def test_find_single_element(self):
def test_find_single_element(self) -> None:
self.driver.get('http://10.0.2.2:4723/test/guinea-pig')
self.driver.find_element_by_link_text('i am a link').click()

Expand Down
6 changes: 3 additions & 3 deletions test/functional/android/common_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@

class CommonTests(BaseTestCase):

def test_current_package(self):
def test_current_package(self) -> None:
self.assertEqual(APIDEMO_PKG_NAME, self.driver.current_package)

def test_end_test_coverage(self):
def test_end_test_coverage(self) -> None:
self.skipTest('Not sure how to set this up to run')
self.driver.end_test_coverage(intent='android.intent.action.MAIN', path='')
sleep(5)

def test_open_notifications(self):
def test_open_notifications(self) -> None:
if is_ci():
# TODO Due to unexpected dialog, "System UI isn't responding"
self.skipTest('Need to fix flaky test during running on CI.')
Expand Down
20 changes: 10 additions & 10 deletions test/functional/android/context_switching_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,37 @@

@pytest.mark.skip(reason="Need to fix broken test")
class ContextSwitchingTests(unittest.TestCase):
def setUp(self):
def setUp(self) -> None:
desired_caps = desired_capabilities.get_desired_capabilities('selendroid-test-app.apk')
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)

def test_contexts_list(self):
def tearDown(self) -> None:
self.driver.quit()

def test_contexts_list(self) -> None:
self._enter_webview()
contexts = self.driver.contexts
self.assertEqual(2, len(contexts))

def test_move_to_correct_context(self):
def test_move_to_correct_context(self) -> None:
self._enter_webview()
self.assertEqual('WEBVIEW_io.selendroid.testapp', self.driver.current_context)

def test_actually_in_webview(self):
def test_actually_in_webview(self) -> None:
self._enter_webview()
self.driver.find_element_by_css_selector('input[type=submit]').click()
el = self.driver.find_element_by_xpath("//h1[contains(., 'This is my way')]")
self.assertIsNot(None, el)

def test_move_back_to_native_context(self):
def test_move_back_to_native_context(self) -> None:
self._enter_webview()
self.driver.switch_to.context(None)
self.assertEqual('NATIVE_APP', self.driver.current_context)

def test_set_invalid_context(self):
def test_set_invalid_context(self) -> None:
self.assertRaises(NoSuchContextException, self.driver.switch_to.context, 'invalid name')

def tearDown(self):
self.driver.quit()

def _enter_webview(self):
def _enter_webview(self) -> None:
btn = self.driver.find_element_by_name('buttonStartWebviewCD')
btn.click()
self.driver.switch_to.context('WEBVIEW')
Expand Down
2 changes: 1 addition & 1 deletion test/functional/android/device_time_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


class DeviceTimeTests(BaseTestCase):
def test_device_time(self):
def test_device_time(self) -> None:
date_time = self.driver.device_time
# convert to date ought to work
parse(date_time)
Expand Down
2 changes: 1 addition & 1 deletion test/functional/android/finger_print_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


class FingerPrintTests(BaseTestCase):
def test_finger_print(self):
def test_finger_print(self) -> None:
result = self.driver.finger_print(1)
self.assertEqual(None, result)

Expand Down
10 changes: 6 additions & 4 deletions test/functional/android/helper/desired_capabilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,19 @@
# limitations under the License.

import os

from typing import Any, Dict, Optional

# Returns abs path relative to this file and not cwd
def PATH(p):


def PATH(p: str) -> str:
return os.path.abspath(
os.path.join(os.path.dirname(__file__), '..', p)
)


def get_desired_capabilities(app=None):
desired_caps = {
def get_desired_capabilities(app: Optional[str] = None) -> Dict[str, Any]:
desired_caps: Dict[str, Any] = {
'platformName': 'Android',
'deviceName': 'Android Emulator',
'newCommandTimeout': 240,
Expand Down
11 changes: 8 additions & 3 deletions test/functional/android/helper/test_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import base64
import os
import unittest
from typing import TYPE_CHECKING

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
Expand All @@ -25,14 +26,18 @@

from . import desired_capabilities

if TYPE_CHECKING:
from appium.webdriver.webelement import WebElement
from appium.webdriver.webdriver import WebDriver

# the emulator is sometimes slow and needs time to think
SLEEPY_TIME = 10

# The package name of ApiDemos-debug.apk.zip
APIDEMO_PKG_NAME = 'io.appium.android.apis'


def wait_for_element(driver, locator, value, timeout=SLEEPY_TIME):
def wait_for_element(driver: 'WebDriver', locator: str, value: str, timeout: int = SLEEPY_TIME) -> 'WebElement':
"""Wait until the element located

Args:
Expand All @@ -55,13 +60,13 @@ def wait_for_element(driver, locator, value, timeout=SLEEPY_TIME):

class BaseTestCase(unittest.TestCase):

def setUp(self):
def setUp(self) -> None:
desired_caps = desired_capabilities.get_desired_capabilities('ApiDemos-debug.apk.zip')
self.driver = webdriver.Remote('http://localhost:4723/wd/hub', desired_caps)
if is_ci():
self.driver.start_recording_screen()

def tearDown(self):
def tearDown(self) -> None:
if is_ci():
payload = self.driver.stop_recording_screen()
video_path = os.path.join(os.getcwd(), self._testMethodName + '.mp4')
Expand Down
2 changes: 1 addition & 1 deletion test/functional/android/hw_actions_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


class HwActionsTests(BaseTestCase):
def test_lock(self):
def test_lock(self) -> None:
self.driver.lock(-1)
sleep(10)
try:
Expand Down
10 changes: 5 additions & 5 deletions test/functional/android/ime_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,25 @@


class IMETests(BaseTestCase):
def test_available_ime_engines(self):
def test_available_ime_engines(self) -> None:
engines = self.driver.available_ime_engines
self.assertIsInstance(engines, list)
self.assertTrue(ANDROID_LATIN in engines or GOOGLE_LATIN in engines)

def test_is_ime_active(self):
def test_is_ime_active(self) -> None:
self.assertTrue(self.driver.is_ime_active())

def test_active_ime_engine(self):
def test_active_ime_engine(self) -> None:
engines = self.driver.available_ime_engines
self.assertTrue(self.driver.active_ime_engine in engines)

def test_activate_ime_engine(self):
def test_activate_ime_engine(self) -> None:
engines = self.driver.available_ime_engines

self.driver.activate_ime_engine(engines[-1])
self.assertEqual(self.driver.active_ime_engine, engines[-1])

def test_deactivate_ime_engine(self):
def test_deactivate_ime_engine(self) -> None:
engines = self.driver.available_ime_engines
self.driver.activate_ime_engine(engines[-1])

Expand Down
8 changes: 4 additions & 4 deletions test/functional/android/keyboard_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@


class KeyboardTests(BaseTestCase):
def test_press_keycode(self):
# not sure how to test this.
def test_press_keycode(self) -> None:
# TODO not sure how to test this.
self.driver.press_keycode(176)

def test_long_press_keycode(self):
# not sure how to test this.
def test_long_press_keycode(self) -> None:
# TODO not sure how to test this.
self.driver.long_press_keycode(176)


Expand Down
4 changes: 2 additions & 2 deletions test/functional/android/location_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@


class LocationTests(BaseTestCase):
def test_toggle_location_services(self):
self.driver.toggle_location_services()
def test_toggle_location_services(self) -> None:
self.driver.toggle_location_services() # TODO Add assert


if __name__ == '__main__':
Expand Down
2 changes: 1 addition & 1 deletion test/functional/android/log_event_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


class LogEventTests(BaseTestCase):
def test_log_event(self):
def test_log_event(self) -> None:
vendor = 'appium'
event = 'funEvent'
self.driver.log_event(vendor, event)
Expand Down
Loading