text: import time
  import logging
  from src import Operations, ActionChains, webdriver, WebDriverWait, EC, By
  from selenium.common.exceptions import (
      ElementNotInteractableException,
      ElementNotVisibleException,
      TimeoutException,
  )
  from selenium.webdriver.common.keys import Keys
  
  
  class Actions(Operations):
      def __init__(self, global_conf):
          self.global_conf = global_conf
          self.browser_init()
  
      def logger_decorator(function):
          def logger_wrapper(*args):
              self = args[0]
              test_data = args[1]
  
              # If no name key in step then add none to avoid execption
              if "name" not in test_data.keys():
                  test_data["name"] = None
  
              logging.info(
                  "TestCase:{0} - Step:{1} - {2}".format(
                      test_data["testcase_no"], test_data["step_no"], test_data["name"]
                  )
              )
  
              # If sleep key mentioned in steps
              if "sleep" in test_data.keys():
                  logging.info(
                      "Sleep for {0} seconds before {1} ".format(
                          test_data["sleep"], test_data["action"]
                      )
                  )
                  time.sleep(test_data["sleep"])
  
              # If wait before action mentioned in steps
              elif "wait before action" in test_data.keys():
                  logging.info("waiting before action")
                  self.wait(test_data["wait before action"])
  
              # method call
              test_result_data = function(*args)
  
              # If wait before action mentioned in steps
              if "wait after action" in test_data.keys():
                  logging.info("waiting after action")
                  self.wait(test_data["wait after action"])
  
              # screenshot after every action
              screenshot_file_name = None
              if "screenshot_name" not in test_data.keys():
                  screenshot_file_name = "{0}_{1}_{2}_{3}".format(
                      test_data["testcase_no"],
                      test_data["step_no"],
                      self.global_conf["locale"],
                      str(int(round(time.time() * 1000))),
                  )
              else:
                  screenshot_file_name = "{0}_{1}".format(
                      self.global_conf["locale"], test_data["screenshot_name"]
                  )
              self.full_page_screenshot(screenshot_file_name)
  
              return test_result_data
  
          return logger_wrapper
  
      def browser_init(self):
          """
          init all selenium browser session and create driver object
          """
          if (
              not self.global_conf["webdriver_path"]
              and self.global_conf["browser"].lower() == "firefox"
          ):
              self.global_conf["webdriver_path"] = "./selenium_drivers/geckodriver"
          elif (
              not self.global_conf["webdriver_path"]
              and self.global_conf["browser"].lower() == "chrome"
          ):
              self.global_conf["webdriver_path"] = "./selenium_drivers/chromedriver"
  
          if self.global_conf["browser"].lower() == "firefox":
              profile = webdriver.FirefoxProfile()
              profile.set_preference("intl.accept_languages", self.global_conf["locale"])
              profile.accept_untrusted_certs = True
              self.driver = webdriver.Firefox(
                  firefox_profile=profile,
                  executable_path=self.global_conf["webdriver_path"],
              )
          elif self.global_conf["browser"].lower() == "chrome":
              options = webdriver.ChromeOptions()
              options.add_experimental_option(
                  "prefs",
                  {"intl.accept_languages": "{0}".format(self.global_conf["locale"])},
              )
              self.driver = webdriver.Chrome(
                  executable_path=self.global_conf["webdriver_path"],
                  chrome_options=options,
              )
  
          self.driver.maximize_window()
  
      @logger_decorator
      def alertmessage(self, test_data):
          """
          This function will handle all alert messages
          """
          try:
              WebDriverWait(self.driver, 10).until(
                  EC.alert_is_present(), "Waiting for alert timed out"
              )
              alert = self.driver.switch_to.alert
              if test_data["value"] == "ok":
                  alert.accept()
              elif test_data["value"] == "cancel":
                  alert.dismiss()
              else:
                  alert.accept()
          except TimeoutException:
              test_data["error"] = True
          return test_data
  
      @logger_decorator
      def scroll(self, test_data):
          """
          This function will scroll given page as per given params
          specify target or x,y 
          default it will do page down
          """
          try:
  
              if "target" in test_data.keys():
                  test_data = self.get_element(test_data)
                  self.driver.execute_script(
                      "arguments[0].scrollIntoView();", test_data["element_obj"]
                  )
              elif "x" in test_data.keys() or "y" in test_data.keys():
                  if "x" not in test_data.keys():
                      test_data["x"] = 0
                  elif "y" not in test_data.keys():
                      test_data["y"] = 0
                  self.driver.execute_script(
                      "window.scrollTo(arguments[0], arguments[1]);",
                      test_data["x"],
                      test_data["y"],
                  )
              else:
                  test_data["values"] = "Keys.PAGE_DOWN"
                  test_data = self.sendkeys(test_data)
  
          except Exception as e:
              logging.error(e)
              test_data["error"] = True
          return test_data
  
      @logger_decorator
      def sendkeys(self, test_data):
          """
          https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html
          """
          try:
              print(test_data)
              if "values" in test_data.keys():
                  actions = ActionChains(self.driver)
  
                  if "Keys" in test_data["values"]:
                      actions.send_keys(getattr(Keys, test_data["values"].split(".")[1]))
                  else:
                      actions.send_keys(test_data["values"])
                  actions.perform()
  
              else:
                  logging.error("values attribute not specified/invalid")
                  test_data["error"] = True
          except Exception as e:
              logging.error(e)
              test_data["error"] = True
          return test_data
  
      @logger_decorator
      def goto(self, test_data):
          """
          This function will visit the URL specified
          :param test_data:
          :return: None
          """
          try:
              if test_data["target"]:
                  if self.check_url(test_data["target"]):
                      self.driver.get(test_data["target"])
                  else:
                      logging.error("Target URL not specified/invalid")
              else:
                  logging.error("Target URL not specified/invalid")
                  test_data["error"] = True
          except Exception as e:
              logging.error(e)
              test_data["error"] = True
          return test_data
  
      @logger_decorator
      def click(self, test_data):
          try:
              test_data = self.get_element(test_data)
              test_data["element_obj"].click()
              # self.driver.switch_to_default_content()
          except (ElementNotVisibleException, ElementNotInteractableException):
              click_obj = None
              for locator in test_data["targets"]:
                  if not click_obj:
                      test_data["target"] = locator
                      logging.info(
                          "finding element for actionchain click using locator: {0} ".format(
                              locator
                          )
                      )
                      try:
                          click_obj = WebDriverWait(self.driver, 10).until(
                              EC.visibility_of_element_located(
                                  (By.XPATH, test_data["target"])
                              )
                          )
                      except Exception:
                          click_obj = None
                  else:
                      break
              if click_obj:
                  ActionChains(self.driver).move_to_element(click_obj).perform()
              else:
                  logging.exception("error")
                  test_data["error"] = True
          except:
              logging.exception("error")
              test_data["error"] = True
  
          return test_data
  
      @logger_decorator
      def hover(self, test_data):
          try:
              test_data = self.get_element(test_data)
              ActionChains(self.driver).move_to_element(
                  test_data["element_obj"]
              ).perform()
          except Exception as e:
              logging.exception(e)
              test_data["error"] = True
  
          return test_data
  
      @logger_decorator
      def input(self, test_data):
          try:
              test_data = self.get_element(test_data)
              test_data["element_obj"].send_keys(test_data["value"])
          except Exception as e:
              logging.exception(e)
              test_data["error"] = True
  
          return test_data
  
      @logger_decorator
      def screenshot(self, test_data):
          try:
              screenshot_file_name = None
              if "screenshot_name" not in test_data.keys():
                  screenshot_file_name = "{0}_{1}_{2}_{3}".format(
                      test_data["testcase_no"],
                      test_data["step_no"],
                      self.global_conf["locale"],
                      str(int(round(time.time() * 1000))),
                  )
              else:
                  screenshot_file_name = "{0}_{1}".format(
                      self.global_conf["locale"], test_data["screenshot_name"]
                  )
  
              self.full_page_screenshot(screenshot_file_name)
          except Exception as e:
              logging.exception(e)
              test_data["error"] = True
  
          return test_data
  
      @logger_decorator
      def sleep(self, test_data):
          try:
              time.sleep(test_data["value"])
          except Exception as e:
              logging.exception(e)
              test_data["error"] = True
          return test_data
  
      @logger_decorator
      def validate(self, test_data):
  
          xpath_denoter = ("//", "/html", "/")
  
          if test_data["target"].startswith(xpath_denoter):
              try:
                  WebDriverWait(self.driver, 20).until(
                      EC.presence_of_element_located((By.XPATH, test_data["target"]))
                  )
              except:
                  logging.error("Element not found")
                  test_data["error"] = True
          else:
              try:
                  WebDriverWait(self.driver, 20).until(
                      EC.presence_of_element_located(
                          (
                              By.XPATH,
                              "//*[contains(text(), '{0}')]".format(test_data["target"]),
                          )
                      )
                  )
              except:
                  logging.error("Element not found")
                  test_data["error"] = True
  
          return test_data
  
      @logger_decorator
      def function(self, test_data):
          print("yet to implement")
          return test_data
  
      def closebrowser(self, test_data):
          try:
              logging.info("Closing browser...")
              self.driver.close()
          except Exception as e:
              logging.exception(e)
          return test_data
  