Skip to content

Commit 0211e1c

Browse files
authored
Merge pull request #678 from AutomationSolutionz/bug-240-appium-3-action-fix
[BUG-240] 3 Appium Actions Fix & Improvement
2 parents a438d9b + 97a568a commit 0211e1c

1 file changed

Lines changed: 143 additions & 49 deletions

File tree

Framework/Built_In_Automation/Mobile/CrossPlatform/Appium/BuiltInFunctions.py

Lines changed: 143 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,13 +1194,55 @@ def teardown_appium(dataset=None):
11941194

11951195
@logger
11961196
def close_application(data_set):
1197-
""" Exit the application """
1197+
"""
1198+
This action **closes (terminates) the current foreground application** on the device using **Appium**.
1199+
1200+
- No element targeting is required — the action terminates the active app automatically.
1201+
- On Android, the current package name is retrieved from the driver.
1202+
- On iOS and macOS, the bundle ID is retrieved from the driver capabilities.
1203+
- The Appium action used is: close.
1204+
1205+
Data Input Fields:
1206+
1207+
| Action | Field Type | Value |
1208+
|---------------------------------------------------------------|---------------|--------|
1209+
| close | appium action | close |
1210+
1211+
Note: Uses `terminate_app()` which is the modern replacement for the deprecated `close_app()`.
1212+
"""
11981213
sModuleInfo = inspect.currentframe().f_code.co_name + " : " + MODULE_NAME
11991214
try:
12001215
CommonUtil.ExecLog(sModuleInfo, "Trying to close the app", 1)
1201-
appium_driver.close_app()
1202-
CommonUtil.ExecLog(sModuleInfo, "Closed the app successfully", 1)
1216+
1217+
device_type = appium_details.get(device_id, {}).get("type", "").lower()
1218+
1219+
if device_type == "android":
1220+
try:
1221+
app_id = appium_driver.current_package
1222+
except Exception:
1223+
app_id = (
1224+
appium_driver.capabilities.get("appPackage")
1225+
or appium_driver.capabilities.get("appium:appPackage", "")
1226+
)
1227+
if not app_id:
1228+
CommonUtil.ExecLog(sModuleInfo, "Could not determine Android package name.", 3)
1229+
return "zeuz_failed"
1230+
elif device_type in ("ios", "macos"):
1231+
app_id = (
1232+
appium_driver.capabilities.get("bundleId")
1233+
or appium_driver.capabilities.get("appium:bundleId", "")
1234+
)
1235+
if not app_id:
1236+
CommonUtil.ExecLog(sModuleInfo, "Could not determine bundle ID from capabilities.", 3)
1237+
return "zeuz_failed"
1238+
else:
1239+
CommonUtil.ExecLog(sModuleInfo, f"Unsupported device type '{device_type}' for close action.", 3)
1240+
return "zeuz_failed"
1241+
1242+
appium_driver.terminate_app(app_id)
1243+
CommonUtil.ExecLog(sModuleInfo, f"Successfully closed app '{app_id}'.", 1)
12031244
return "passed"
1245+
12041246
except Exception:
12051247
errMsg = "Unable to close the application."
12061248
return CommonUtil.Exception_Handler(sys.exc_info(), None, errMsg)
@@ -2868,7 +2910,23 @@ def Seek_Progress_Bar(data_set):
28682910

28692911
@logger
28702912
def Double_Tap_Appium(data_set):
2871-
#!!!not yet tested or used
2913+
"""
2914+
This action performs a **double tap** on a mobile app element using **Appium**.
2915+
2916+
- Locate UI elements using standard properties like 'resource-id', 'tag', 'text', 'content-desc', etc.
2917+
- Supports **partial matching** using `*` before the property name (e.g., *text).
2918+
- You can provide **multiple rows of element properties** for accurate targeting.
2919+
- The Appium action used is: double tap.
2920+
2921+
Data Input Fields:
2922+
2923+
| Action | Field Type | Value |
2924+
|---------------------------------------------------------------|-------------------|--------------------|
2925+
| Enter element's property name to double tap. | element parameter | resource-id value |
2926+
| double tap | appium action | double tap |
2927+
2928+
Note: Uses W3C touch pointer actions for compatibility with both Android and iOS.
2929+
"""
28722930
sModuleInfo = inspect.currentframe().f_code.co_name + " : " + MODULE_NAME
28732931

28742932
skip_or_not = filter_optional_action_and_step_data(data_set, sModuleInfo)
@@ -2877,79 +2935,115 @@ def Double_Tap_Appium(data_set):
28772935

28782936
try:
28792937
Element = LocateElement.Get_Element(data_set, appium_driver)
2880-
if Element == "zeuz_failed":
2881-
CommonUtil.ExecLog(
2882-
sModuleInfo, "Unable to locate your element with given data.", 3
2883-
)
2938+
if Element in failed_tag_list:
2939+
CommonUtil.ExecLog(sModuleInfo, "Unable to locate element with given data.", 3)
28842940
return "zeuz_failed"
2885-
else:
2886-
try:
2887-
if Element.is_enabled():
2888-
action = TouchAction(appium_driver)
28892941

2890-
action.press(Element).wait(100).release().press(Element).wait(
2891-
100
2892-
).release().perform()
2942+
if not Element.is_enabled():
2943+
CommonUtil.ExecLog(sModuleInfo, "Element is not enabled. Cannot double tap.", 3)
2944+
return "zeuz_failed"
28932945

2894-
CommonUtil.ExecLog(
2895-
sModuleInfo, "Double Tapped on element successfully", 1
2896-
)
2897-
return "passed"
2898-
else:
2899-
# CommonUtil.TakeScreenShot(sModuleInfo)
2900-
CommonUtil.ExecLog(
2901-
sModuleInfo, "Element not enabled. Unable to click.", 3
2902-
)
2903-
return "zeuz_failed"
2946+
try:
2947+
finger = PointerInput(interaction.POINTER_TOUCH, "finger")
2948+
builder = ActionBuilder(appium_driver, mouse=finger)
2949+
builder.pointer_action.move_to(Element)
2950+
builder.pointer_action.pointer_down()
2951+
builder.pointer_action.pause(0.1)
2952+
builder.pointer_action.pointer_up()
2953+
builder.pointer_action.pause(0.1)
2954+
builder.pointer_action.pointer_down()
2955+
builder.pointer_action.pause(0.1)
2956+
builder.pointer_action.pointer_up()
2957+
builder.perform()
2958+
CommonUtil.ExecLog(sModuleInfo, "Double tap performed successfully.", 1)
2959+
return "passed"
2960+
except Exception:
2961+
CommonUtil.ExecLog(sModuleInfo, "W3C pointer action failed, trying ActionChains fallback.", 2)
2962+
try:
2963+
actions = ActionChains(appium_driver)
2964+
actions.double_click(Element).perform()
2965+
CommonUtil.ExecLog(sModuleInfo, "Double tap performed via ActionChains fallback.", 1)
2966+
return "passed"
29042967
except Exception:
2905-
errMsg = "Could not select/click your element."
2968+
errMsg = "Double tap failed with both W3C pointer and ActionChains methods."
29062969
return CommonUtil.Exception_Handler(sys.exc_info(), None, errMsg)
29072970

29082971
except Exception:
2909-
errMsg = "Unable to tap."
2972+
errMsg = "Unable to perform double tap."
29102973
return CommonUtil.Exception_Handler(sys.exc_info(), None, errMsg)
29112974

29122975

29132976
@logger
29142977
def Long_Press_Appium(data_set):
2915-
""" Press and hold an element """
2978+
"""
2979+
This action performs a **long press (press and hold)** on a mobile app element using **Appium**.
2980+
2981+
- Locate UI elements using standard properties like 'resource-id', 'tag', 'text', 'content-desc', etc.
2982+
- Supports **partial matching** using `*` before the property name (e.g., *text).
2983+
- You can provide **multiple rows of element properties** for accurate targeting.
2984+
- Optionally specify a **duration** (in milliseconds) for how long to press (default: 1000ms).
2985+
- The Appium action used is: long press.
2986+
2987+
Data Input Fields:
2988+
2989+
| Action | Field Type | Value |
2990+
|---------------------------------------------------------------|-------------------|--------------------|
2991+
| Enter element's property name to long press. | element parameter | value |
2992+
| duration (optional, in milliseconds, default 1000) | optional parameter| 2000 |
2993+
| long press | appium action | long press |
29162994
2995+
Note: Uses W3C touch pointer actions for compatibility with both Android and iOS.
2996+
"""
29172997
sModuleInfo = inspect.currentframe().f_code.co_name + " : " + MODULE_NAME
29182998

29192999
skip_or_not = filter_optional_action_and_step_data(data_set, sModuleInfo)
29203000
if not skip_or_not:
29213001
return "passed"
29223002

29233003
try:
3004+
duration_ms = 1000 # default long press duration in milliseconds
3005+
3006+
for left, mid, right in data_set:
3007+
left = left.strip().lower()
3008+
mid = mid.strip().lower()
3009+
if mid in ("optional parameter", "option") and "duration" in left:
3010+
try:
3011+
duration_ms = int(right.strip())
3012+
except ValueError:
3013+
CommonUtil.ExecLog(sModuleInfo, f"Invalid duration value '{right}', using default 1000ms.", 2)
3014+
29243015
Element = LocateElement.Get_Element(data_set, appium_driver)
2925-
if Element == "zeuz_failed":
2926-
CommonUtil.ExecLog(
2927-
sModuleInfo, "Unable to locate your element with given data.", 3
2928-
)
3016+
if Element in failed_tag_list:
3017+
CommonUtil.ExecLog(sModuleInfo, "Unable to locate element with given data.", 3)
29293018
return "zeuz_failed"
2930-
else:
2931-
try:
2932-
if Element.is_enabled():
2933-
action = TouchAction(appium_driver)
29343019

2935-
action.long_press(Element, 150, 10).release().perform()
3020+
if not Element.is_enabled():
3021+
CommonUtil.ExecLog(sModuleInfo, "Element is not enabled. Cannot long press.", 3)
3022+
return "zeuz_failed"
29363023

2937-
CommonUtil.ExecLog(
2938-
sModuleInfo, "Long Pressed on element successfully", 1
2939-
)
2940-
return "passed"
2941-
else:
2942-
# CommonUtil.TakeScreenShot(sModuleInfo)
2943-
CommonUtil.ExecLog(
2944-
sModuleInfo, "Element not enabled. Unable to click.", 3
2945-
)
2946-
return "zeuz_failed"
3024+
try:
3025+
finger = PointerInput(interaction.POINTER_TOUCH, "finger")
3026+
builder = ActionBuilder(appium_driver, mouse=finger)
3027+
builder.pointer_action.move_to(Element)
3028+
builder.pointer_action.pointer_down()
3029+
builder.pointer_action.pause(duration_ms / 1000)
3030+
builder.pointer_action.pointer_up()
3031+
builder.perform()
3032+
CommonUtil.ExecLog(sModuleInfo, f"Long press performed successfully (duration: {duration_ms}ms).", 1)
3033+
return "passed"
3034+
except Exception:
3035+
CommonUtil.ExecLog(sModuleInfo, "W3C pointer action failed, trying ActionChains fallback.", 2)
3036+
try:
3037+
actions = ActionChains(appium_driver)
3038+
actions.click_and_hold(Element).pause(duration_ms / 1000).release().perform()
3039+
CommonUtil.ExecLog(sModuleInfo, f"Long press performed via ActionChains fallback (duration: {duration_ms}ms).", 1)
3040+
return "passed"
29473041
except Exception:
2948-
errMsg = "Could not select/click your element."
3042+
errMsg = "Long press failed with both W3C pointer and ActionChains methods."
29493043
return CommonUtil.Exception_Handler(sys.exc_info(), None, errMsg)
29503044

29513045
except Exception:
2952-
errMsg = "Unable to tap."
3046+
errMsg = "Unable to perform long press."
29533047
return CommonUtil.Exception_Handler(sys.exc_info(), None, errMsg)
29543048

29553049

0 commit comments

Comments
 (0)