diff --git a/Framework/Built_In_Automation/Database/BuiltInFunctions.py b/Framework/Built_In_Automation/Database/BuiltInFunctions.py index 4f756456..2b9cbd7e 100755 --- a/Framework/Built_In_Automation/Database/BuiltInFunctions.py +++ b/Framework/Built_In_Automation/Database/BuiltInFunctions.py @@ -451,7 +451,7 @@ def select_from_db(data_set): if "table" in left.lower(): # Get the and query, and remove any whitespaces table_name= right.strip() - if left.lower()=="where": + if left.strip().lower()=="where": where=right.strip() if "action" in mid.lower(): variable_name = right.strip() diff --git a/Framework/Built_In_Automation/Mobile/CrossPlatform/Appium/BuiltInFunctions.py b/Framework/Built_In_Automation/Mobile/CrossPlatform/Appium/BuiltInFunctions.py index 74a3442f..19b05ec1 100755 --- a/Framework/Built_In_Automation/Mobile/CrossPlatform/Appium/BuiltInFunctions.py +++ b/Framework/Built_In_Automation/Mobile/CrossPlatform/Appium/BuiltInFunctions.py @@ -2,7 +2,7 @@ # -*- coding: cp1252 -*- """ Name: Built In Functions - Appium - Description: Contains all Sequential Actions related to automating Android and IOS using Appium + Description: Contains all Sequential Actions related to automating Android, IOS and MacOS using Appium """ ######################### @@ -14,6 +14,7 @@ from appium import webdriver from appium.options.android import UiAutomator2Options from appium.options.ios import XCUITestOptions +from appium.options.mac import Mac2Options import traceback import socket import os, sys, datetime, time, inspect, subprocess, re, signal, _thread, requests, copy @@ -341,7 +342,7 @@ def find_correct_device_on_first_run(serial_or_name, device_info): @logger def unlock_android_device(data_set): - """ Unlocks an androi device with adb commands""" + """ Unlocks an android device with adb commands""" sModuleInfo = inspect.currentframe().f_code.co_name + " : " + MODULE_NAME @@ -460,10 +461,6 @@ def launch_application(data_set): # Parse data set try: - desiredcaps = {} - desiredcaps['unicodeKeyboard'] = False - desiredcaps['resetKeyboard'] = False - browserstack_run = False aws_run = False @@ -494,6 +491,7 @@ def launch_application(data_set): platform_version = "" device_name = "" ios = "" + macos = "" no_reset = False work_profile = False @@ -506,6 +504,8 @@ def launch_application(data_set): activity_name = right elif left in ("ios", "ios simulator") and mid == "element parameter": ios = right + elif "macos" in left.lower().strip(): + macos = right.strip() elif left == "work profile" and right.strip().lower() in ("yes", "true"): work_profile = True elif left in ("no reset", "no_reset", "noreset") and mid == "element parameter": @@ -521,9 +521,12 @@ def launch_application(data_set): desiredcaps['unicodeKeyboard'] = False desiredcaps['resetKeyboard'] = False # Set the global variable for the preferred connected device - if find_correct_device_on_first_run(serial, device_info) in failed_tag_list: + if find_correct_device_on_first_run(serial, device_info) in failed_tag_list and macos == "": return "zeuz_failed" - + elif macos != "": + device_id = "device 1" + appium_details[device_id] = {"driver":None, "server":None, "serial":"", "type":"macos", "iemi":"", "platform_version":"", "device_name":""} + device_type = appium_details[device_id]["type"].lower().strip() for left, mid, right in data_set: @@ -593,6 +596,7 @@ def launch_application(data_set): platform_version=platform_version, device_name=device_name, ios=ios, + macos = macos, no_reset=no_reset, work_profile=work_profile, desiredcaps=desiredcaps, @@ -600,7 +604,7 @@ def launch_application(data_set): if result == "zeuz_failed": return "zeuz_failed" - if launch_app: # if ios simulator then no need to launch app again + if launch_app and macos == "": # if ios simulator then no need to launch app again appium_driver.activate_app(package_name) # Launch program configured in the Appium capabilities CommonUtil.ExecLog(sModuleInfo, "Launched the application successfully.", 1) return "passed" @@ -761,6 +765,7 @@ def start_appium_driver( platform_version="", device_name="", ios="", + macos="", no_reset=False, work_profile=False, desiredcaps=None, @@ -916,6 +921,13 @@ def start_appium_driver( desired_caps["deviceName"] = "iPhone" # Read model (only needs to be unique if using more than one) desired_caps["bundleId"] = ios desired_caps["udid"] = appium_details[device_id]["serial"] # Device unique identifier - use auto if using only one phone + elif str(appium_details[device_id]["type"]).lower() == "macos": + CommonUtil.ExecLog(sModuleInfo, "Setting up with MacOS", 1) + desired_caps["platformName"] = "mac" + desired_caps["automationName"] = "mac2" + desired_caps["wdaLocalPort"] = wdaLocalPort + desired_caps["bundleId"] = macos + desired_caps["newCommandTimeout"] = 6000 else: CommonUtil.ExecLog(sModuleInfo, "Invalid device type: %s" % str(appium_details[device_id]["type"]), 3) return "zeuz_failed", launch_app @@ -942,6 +954,8 @@ def start_appium_driver( if appium_driver: # Make sure we get the instance appium_details[device_id]["driver"] = appium_driver + if appium_details[device_id]["type"] == "macos": + Shared_Resources.Set_Shared_Variables("screen_capture", "desktop") Shared_Resources.Set_Shared_Variables("appium_details", appium_details) CommonUtil.set_screenshot_vars(Shared_Resources.Shared_Variable_Export()) CommonUtil.ExecLog(sModuleInfo, "Appium driver created successfully.", 1) diff --git a/Framework/Built_In_Automation/Sequential_Actions/action_declarations/common.py b/Framework/Built_In_Automation/Sequential_Actions/action_declarations/common.py index e1a7e184..6c7e8fdf 100644 --- a/Framework/Built_In_Automation/Sequential_Actions/action_declarations/common.py +++ b/Framework/Built_In_Automation/Sequential_Actions/action_declarations/common.py @@ -125,6 +125,9 @@ {"name": "connect to bigquery client", "function": "connect_to_bigquery_client", "screenshot": "none" }, {"name": "execute bigquery query", "function": "execute_bigquery_query", "screenshot": "none" }, + + {"name": "connect to google service client", "function": "connect_to_google_service_account", "screenshot": "none" }, + {"name": "upload to google storage bucket", "function": "upload_to_google_storage_bucket", "screenshot": "none" }, ) # yapf: disable diff --git a/Framework/Built_In_Automation/Sequential_Actions/common_functions.py b/Framework/Built_In_Automation/Sequential_Actions/common_functions.py index b11e6c6b..627912ed 100755 --- a/Framework/Built_In_Automation/Sequential_Actions/common_functions.py +++ b/Framework/Built_In_Automation/Sequential_Actions/common_functions.py @@ -6505,6 +6505,70 @@ def execute_bigquery_query(data_set): except: return CommonUtil.Exception_Handler(sys.exc_info()) +@logger +def connect_to_google_service_account(data_set): + """ + data_set: + credentials path | input parameter | path to credentails json file + connect to google service client | common action | client variable name + """ + + sModuleInfo = inspect.currentframe().f_code.co_name + " : " + MODULE_NAME + CommonUtil.ExecLog(sModuleInfo, "Actions involving the Google service account may not function correctly without a virtual environment.", 2) + cred_path = None + client_var_name = None + for left, _, right in data_set: + if left.strip().lower() == 'credentials path': + cred_path = right.strip() + if left.strip().lower() == 'connect to google service client': + client_var_name = right.strip() + + try: + from google.cloud import storage + client = storage.Client.from_service_account_json(json_credentials_path=cred_path) + sr.Set_Shared_Variables(client_var_name, client) + return "passed" + except: + CommonUtil.ExecLog(sModuleInfo, "Incorrect Credentails", 3) + return "zeuz_failed" + +@logger +def upload_to_google_storage_bucket(data_set): + """ + data_set: + filepath | input parameter | filepath + bucket | input parameter | bucket name + upload to google storage bucket | common action | client variable name + """ + + sModuleInfo = inspect.currentframe().f_code.co_name + " : " + MODULE_NAME + CommonUtil.ExecLog(sModuleInfo, "Actions involving the Google service account may not function correctly without a virtual environment.", 2) + filepath = None + client_var_name = None + bucket = None + + for left, _, right in data_set: + if left.strip().lower() == 'filepath': + filepath = right.strip() + if left.strip().lower() == 'upload to google storage bucket': + client_var_name = right.strip() + if left.strip().lower() == 'bucket': + bucket = right.strip() + + if None in (filepath,client_var_name,bucket): + CommonUtil.ExecLog(sModuleInfo, "Incorrect Dataset", 3) + return "zeuz_failed" + + try: + client = sr.Get_Shared_Variables(client_var_name) + bucket = client.get_bucket(bucket) + blob = bucket.blob(os.path.basename(filepath)) + blob.upload_from_filename(filepath) + CommonUtil.ExecLog(sModuleInfo, f'File {filepath} uploaded to {bucket}.') + return "passed" + except: + return CommonUtil.Exception_Handler(sys.exc_info()) + @logger def text_to_speech(data_set): """ diff --git a/requirements-linux.txt b/requirements-linux.txt index 474ed070..d12fdcc3 100644 --- a/requirements-linux.txt +++ b/requirements-linux.txt @@ -57,4 +57,5 @@ pandas pyperclip thefuzz backports-datetime-fromisoformat; python_version < '3.11' -genson \ No newline at end of file +genson +google-cloud-storage \ No newline at end of file diff --git a/requirements-mac.txt b/requirements-mac.txt index 09116e15..81308218 100644 --- a/requirements-mac.txt +++ b/requirements-mac.txt @@ -61,4 +61,5 @@ pandas pyperclip backports-datetime-fromisoformat; python_version < '3.11' thefuzz -genson \ No newline at end of file +genson +google-cloud-storage \ No newline at end of file diff --git a/requirements-win.txt b/requirements-win.txt index f2e6f8b1..06f990db 100644 --- a/requirements-win.txt +++ b/requirements-win.txt @@ -72,3 +72,4 @@ pyperclip backports-datetime-fromisoformat; python_version < '3.11' thefuzz genson +google-cloud-storage \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index d6823b45..9b1a167a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -52,4 +52,5 @@ boto3 pandas pyperclip backports-datetime-fromisoformat; python_version < '3.11' -genson \ No newline at end of file +genson +google-cloud-storage \ No newline at end of file