Sitelet https://github.com/appium/python-client/pull/859/files
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
29 changes: 22 additions & 7 deletions appium/webdriver/extensions/android/activities.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,26 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import TypeVar
import warnings
from typing import TYPE_CHECKING, cast

from selenium.common.exceptions import TimeoutException
from selenium.common.exceptions import TimeoutException, UnknownMethodException
from selenium.webdriver.support.ui import WebDriverWait

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.mobilecommand import MobileCommand as Command

T = TypeVar('T', bound=CanExecuteCommands)
if TYPE_CHECKING:
from appium.webdriver.webdriver import WebDriver


class Activities(CanExecuteCommands):
def start_activity(self: T, app_package: str, app_activity: str, **opts: str) -> T:
class Activities(CanExecuteCommands, CanExecuteScripts, CanRememberExtensionPresence):
def start_activity(self, app_package: str, app_activity: str, **opts: str) -> 'WebDriver':
"""Opens an arbitrary activity during a test. If the activity belongs to
another application, that application is started and the activity is opened.
deprecated:: 2.9.0

This is an Android-only method.

Expand All @@ -43,6 +48,11 @@ def start_activity(self: T, app_package: str, app_activity: str, **opts: str) ->
optional_intent_arguments (str): Optional arguments to the intent.
dont_stop_app_on_reset (str): Should the app be stopped on reset?
"""
warnings.warn(
'The "session" API is deprecated. Use "mobile: startActivity" extension instead.',
DeprecationWarning,
)

data = {'appPackage': app_package, 'appActivity': app_activity}
arguments = {
'app_wait_package': 'appWaitPackage',
Expand All @@ -57,7 +67,7 @@ def start_activity(self: T, app_package: str, app_activity: str, **opts: str) ->
if key in opts:
data[value] = opts[key]
self.execute(Command.START_ACTIVITY, data)
return self
return cast('WebDriver', self)

@property
def current_activity(self) -> str:
Expand All @@ -66,7 +76,12 @@ def current_activity(self) -> str:
Returns:
str: The current activity name running on the device
"""
return self.execute(Command.GET_CURRENT_ACTIVITY)['value']
ext_name = 'mobile: getCurrentActivity'
try:
return self.assert_extension_exists(ext_name).execute_script(ext_name)
except UnknownMethodException:
# TODO: Remove the fallback
return self.mark_extension_absence(ext_name).execute(Command.GET_CURRENT_ACTIVITY)['value']

def wait_activity(self, activity: str, timeout: int, interval: int = 1) -> bool:
"""Wait for an activity: block until target activity presents or time out.
Expand Down
48 changes: 35 additions & 13 deletions appium/webdriver/extensions/android/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,24 @@
# 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 warnings
from typing import TYPE_CHECKING, Any, cast

from typing import Any, TypeVar
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.mobilecommand import MobileCommand as Command

T = TypeVar('T', bound=CanExecuteCommands)
if TYPE_CHECKING:
from appium.webdriver.webdriver import WebDriver


class Common(CanExecuteCommands):
def end_test_coverage(self, intent: str, path: str) -> Any: # TODO Check return type
class Common(CanExecuteCommands, CanExecuteScripts, CanRememberExtensionPresence):
def end_test_coverage(self, intent: str, path: str) -> Any:
"""Ends the coverage collection and pull the coverage.ec file from the device.
deprecated:: 2.9.0

Android only.
See https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/android/android-coverage.md
Expand All @@ -34,25 +40,41 @@ def end_test_coverage(self, intent: str, path: str) -> Any: # TODO Check return
Returns:
TODO
"""
data = {
'intent': intent,
'path': path,
}
return self.execute(Command.END_TEST_COVERAGE, data)['value']
warnings.warn(
'This API is deprecated and will be removed in future versions',
DeprecationWarning,
)
return self.execute(
Command.END_TEST_COVERAGE,
{
'intent': intent,
'path': path,
},
)['value']

def open_notifications(self: T) -> T:
def open_notifications(self) -> 'WebDriver':
"""Open notification shade in Android (API Level 18 and above)

Returns:
Union['WebDriver', 'Common']: Self instance
"""
self.execute(Command.OPEN_NOTIFICATIONS, {})
return self
ext_name = 'mobile: openNotifications'
try:
self.assert_extension_exists(ext_name).execute_script(ext_name)
except UnknownMethodException:
# TODO: Remove the fallback
self.mark_extension_absence(ext_name).execute(Command.OPEN_NOTIFICATIONS, {})
return cast('WebDriver', self)

@property
def current_package(self) -> str:
"""Retrieves the current package running on the device."""
return self.execute(Command.GET_CURRENT_PACKAGE)['value']
ext_name = 'mobile: getCurrentPackage'
try:
return self.assert_extension_exists(ext_name).execute_script(ext_name)
except UnknownMethodException:
# TODO: Remove the fallback
return self.mark_extension_absence(ext_name).execute(Command.GET_CURRENT_PACKAGE)['value']

def _add_commands(self) -> None:
# noinspection PyProtectedMember,PyUnresolvedReferences
Expand Down
13 changes: 11 additions & 2 deletions appium/webdriver/extensions/android/display.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.

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.mobilecommand import MobileCommand as Command


class Display(CanExecuteCommands):
class Display(CanExecuteCommands, CanExecuteScripts, CanRememberExtensionPresence):
def get_display_density(self) -> int:
"""Get the display density, Android only

Expand All @@ -29,7 +33,12 @@ def get_display_density(self) -> int:
Return:
int: The display density
"""
return self.execute(Command.GET_DISPLAY_DENSITY)['value']
ext_name = 'mobile: getDisplayDensity'
try:
return self.assert_extension_exists(ext_name).execute_script(ext_name)
except UnknownMethodException:
# TODO: Remove the fallback
return self.mark_extension_absence(ext_name).execute(Command.GET_DISPLAY_DENSITY)['value']

def _add_commands(self) -> None:
# noinspection PyProtectedMember,PyUnresolvedReferences
Expand Down
50 changes: 37 additions & 13 deletions appium/webdriver/extensions/android/gsm.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from typing import TypeVar
from typing import TYPE_CHECKING, cast

from selenium.common.exceptions import UnknownMethodException

from appium.common.helper import extract_const_attributes
from appium.common.logger import logger
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.mobilecommand import MobileCommand as Command

T = TypeVar('T', bound=CanExecuteCommands)
if TYPE_CHECKING:
from appium.webdriver.webdriver import WebDriver


class GsmCallActions:
Expand Down Expand Up @@ -47,8 +52,8 @@ class GsmVoiceState:
ON = 'on'


class Gsm(CanExecuteCommands):
def make_gsm_call(self: T, phone_number: str, action: str) -> T:
class Gsm(CanExecuteCommands, CanExecuteScripts, CanRememberExtensionPresence):
def make_gsm_call(self, phone_number: str, action: str) -> 'WebDriver':
"""Make GSM call (Emulator only)

Android only.
Expand All @@ -64,16 +69,22 @@ def make_gsm_call(self: T, phone_number: str, action: str) -> T:
Returns:
Union['WebDriver', 'Gsm']: Self instance
"""
ext_name = 'mobile: gsmCall'
constants = extract_const_attributes(GsmCallActions)
if action not in constants.values():
logger.warning(
f'{action} is unknown. Consider using one of {list(constants.keys())} constants. '
f'(e.g. {GsmCallActions.__name__}.CALL)'
)
self.execute(Command.MAKE_GSM_CALL, {'phoneNumber': phone_number, 'action': action})
return self

def set_gsm_signal(self: T, strength: int) -> T:
args = {'phoneNumber': phone_number, 'action': action}
try:
self.assert_extension_exists(ext_name).execute_script(ext_name, args)
except UnknownMethodException:
# TODO: Remove the fallback
self.mark_extension_absence(ext_name).execute(Command.MAKE_GSM_CALL, args)
return cast('WebDriver', self)

def set_gsm_signal(self, strength: int) -> 'WebDriver':
"""Set GSM signal strength (Emulator only)

Android only.
Expand All @@ -88,16 +99,23 @@ def set_gsm_signal(self: T, strength: int) -> T:
Returns:
Union['WebDriver', 'Gsm']: Self instance
"""
ext_name = 'mobile: gsmSignal'
constants = extract_const_attributes(GsmSignalStrength)
if strength not in constants.values():
logger.warning(
f'{strength} is out of range. Consider using one of {list(constants.keys())} constants. '
f'(e.g. {GsmSignalStrength.__name__}.GOOD)'
)
self.execute(Command.SET_GSM_SIGNAL, {'signalStrength': strength, 'signalStrengh': strength})
return self
try:
self.assert_extension_exists(ext_name).execute_script(ext_name, {'strength': strength})
except UnknownMethodException:
# TODO: Remove the fallback
self.mark_extension_absence(ext_name).execute(
Command.SET_GSM_SIGNAL, {'signalStrength': strength, 'signalStrengh': strength}
)
return cast('WebDriver', self)

def set_gsm_voice(self: T, state: str) -> T:
def set_gsm_voice(self, state: str) -> 'WebDriver':
"""Set GSM voice state (Emulator only)

Android only.
Expand All @@ -112,14 +130,20 @@ def set_gsm_voice(self: T, state: str) -> T:
Returns:
Union['WebDriver', 'Gsm']: Self instance
"""
ext_name = 'mobile: gmsVoice'
constants = extract_const_attributes(GsmVoiceState)
if state not in constants.values():
logger.warning(
f'{state} is unknown. Consider using one of {list(constants.keys())} constants. '
f'(e.g. {GsmVoiceState.__name__}.HOME)'
)
self.execute(Command.SET_GSM_VOICE, {'state': state})
return self
args = {'state': state}
try:
self.assert_extension_exists(ext_name).execute_script(ext_name, args)
except UnknownMethodException:
# TODO: Remove the fallback
self.mark_extension_absence(ext_name).execute(Command.SET_GSM_VOICE, args)
return cast('WebDriver', self)

def _add_commands(self) -> None:
# noinspection PyProtectedMember,PyUnresolvedReferences
Expand Down
Loading