#!/usr/bin/python
# encoding=utf-8

"""
@Author  :  Lijiawei
@Date    :  11/02/2021 3:36 PM
@Desc    :  proxy line
"""

from selenium.webdriver import Chrome, ActionChains, Firefox, Remote
from selenium.webdriver.remote.webelement import WebElement
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.chrome.options import Options
from airtest.core.settings import Settings as ST
from airtest.core.helper import logwrap
from airtest import aircv
from airtest.core.cv import Template
from utx.selenium.utils.airtest_api import loop_find
from utx.selenium.exceptions import IsNotTemplateError
from airtest.aircv import get_resolution
from pynput.mouse import Controller, Button
from airtest.core.error import TargetNotFoundError

import os
import time
import sys

from utx.core.utils.tools import plat


class WebChrome(Chrome):
    chrome_options = Options()
    chrome_options.add_experimental_option("debuggerAddress", "127.0.0.1:9222")
    if plat() == 'Windows':
        driver_name = 'chromedriver.exe'
    else:
        driver_name = 'chromedriver'
    driver_path = os.path.join(ST.PROJECT_ROOT, 'driver', '{}'.format(driver_name))

    def __init__(self, executable_path=driver_path, port=0,
                 options=chrome_options, service_args=None,
                 desired_capabilities=None, service_log_path=None,
                 chrome_options=None):

        # todo 适配selenium 4.0.0
        # def __init__(self, executable_path="chromedriver", port=0,
        #              options: Options = chrome_options, service_args=None,
        #              desired_capabilities=None, service_log_path=None,
        #              chrome_options=None, service=Service(executable_path=driver_path), keep_alive=None):

        if "darwin" in sys.platform:
            os.environ['PATH'] += ":/Applications/AirtestIDE.app/Contents/Resources/selenium_plugin"
        super(WebChrome, self).__init__(chrome_options=chrome_options, executable_path=executable_path,
                                        port=port, options=options, service_args=service_args,
                                        service_log_path=service_log_path, desired_capabilities=desired_capabilities)
        self.father_number = {0: 0}
        self.action_chains = ActionChains(self)
        self.number = 0
        self.mouse = Controller()
        self.operation_to_func = {"elementsD": self.find_any_element, "xpath": self.find_element_by_xpath,
                                  "id": self.find_element_by_id,
                                  "name": self.find_element_by_name, "css": self.find_element_by_css_selector}

    def loop_find_element(self, func, text, timeout=10, interval=0.5):
        """
        Loop to find the target web element by func.

        Args:
            func: function to find element
            text: param of function
            timeout: time to find the element
            interval: interval between operation
        Returns:
            element that been found
        """
        start_time = time.time()
        while True:
            try:
                element = func(text)
            except NoSuchElementException:
                print("Element not found!")
                # 超时则raise，未超时则进行下次循环:
                if (time.time() - start_time) > timeout:
                    # try_log_screen(screen)
                    raise NoSuchElementException(
                        'Element %s not found in screen' % text)
                else:
                    time.sleep(interval)
            else:
                return element

    def loop_find_element_noExc(self, func, text, timeout=3, interval=0.5):
        """
        Loop to find the target web element by func.

        Args:
            func: function to find element
            text: param of function
            timeout: time to find the element
            interval: interval between operation
        Returns:
            element that been found
        """
        start_time = time.time()
        while True:
            try:
                element = func(text)
            except NoSuchElementException:
                print("Element not found!")
                # 超时则raise，未超时则进行下次循环:
                if (time.time() - start_time) > timeout:
                    # try_log_screen(screen)
                    return None
                else:
                    time.sleep(interval)
            else:
                print('element found')
                return element

    @logwrap
    def find_any_element(self, elementsD):
        """
        Find the web element by the indicated parameters.

        Args:
            elementsD: a dictionary with keys = by's, values=value
        Returns:
            Web element of current page.
        """
        web_element = None
        for key in elementsD:
            value = elementsD[key]
            print(value)
            if key.upper() == 'ID':
                web_element = self.loop_find_element_noExc(super().find_element_by_id, value)
            elif key.upper() == 'XPATH':
                web_element = self.loop_find_element_noExc(super().find_element_by_xpath, value)
            elif key.upper() == 'CSS':
                web_element = self.loop_find_element_noExc(super().find_element_by_css_selector, value)
            elif key.upper() == 'NAME':
                web_element = self.loop_find_element_noExc(super().find_element_by_name, value)
            elif key.upper() == 'LINKTEXT':
                web_element = self.loop_find_element_noExc(super().find_element_by_link_text, value)
            elif key.upper() == 'CLASSNAME':
                web_element = self.loop_find_element_noExc(super().find_element_by_class_name, value)
            elif key.upper() == 'PARTIALLINKTEXT':
                web_element = self.loop_find_element_noExc(super().find_element_by_partial_link_text, value)
            elif key.upper() == 'TAGNAME':
                web_element = self.loop_find_element_noExc(super().find_element_by_tag_name, value)
                # check by position/ picture / visual testing
            if web_element is not None:
                break
        if web_element is not None:
            log_res = self._gen_screen_log(web_element)
            return Element(web_element, log_res)
        raise NoSuchElementException('Element not found in screen')

    @logwrap
    def find_element_by_xpath(self, xpath):
        """
        Find the web element by xpath.

        Args:
            xpath: find the element by xpath.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebChrome, self).find_element_by_xpath, xpath)
        # web_element = super(WebChrome, self).find_element_by_xpath(xpath)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_id(self, id):
        """
        Find the web element by id.

        Args:
            id: find the element by attribute id.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebChrome, self).find_element_by_id, id)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_css_selector(self, css_selector):
        """
        Find the web element by css_selector.

        Args:
            css_selector: find the element by attribute css_selector.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebChrome, self).find_element_by_css_selector, css_selector)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_name(self, name):
        """
        Find the web element by name.

        Args:
            name: find the element by attribute name.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebChrome, self).find_element_by_name, name)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def switch_to_new_tab(self):
        """
        Switch to the new tab.
        """
        _father = self.number
        self.number = len(self.window_handles) - 1
        self.father_number[self.number] = _father
        self.switch_to.window(self.window_handles[self.number])
        self._gen_screen_log()
        time.sleep(0.5)

    @logwrap
    def switch_to_previous_tab(self):
        """
        Switch to the previous tab(which to open current tab).
        """
        self.number = self.father_number[self.number]
        self.switch_to.window(self.window_handles[self.number])
        self._gen_screen_log()
        time.sleep(0.5)

    @logwrap
    def airtest_touch(self, v):
        """
        Perform the touch action on the current page by image identification.

        Args:
            v: target to touch, either a Template instance or absolute coordinates (x, y)
        Returns:
            Finial position to be clicked.
        """
        # 调用airtest opencv 图像识别能力
        if isinstance(v, Template):
            _pos = loop_find(v, timeout=ST.FIND_TIMEOUT, driver=self)
        else:
            _pos = v
        x, y = _pos
        # self.action_chains.move_to_element_with_offset(root_element, x, y)
        # self.action_chains.click()
        pos = self._get_left_up_offset()
        pos = (pos[0] + x, pos[1] + y)
        self._move_to_pos(pos)
        self._click_current_pos()
        time.sleep(1)
        return _pos

    @logwrap
    def assert_template(self, v, msg=""):
        """
        Assert target exists on the current page.

        Args:
            v: target to touch, either a Template instance
        Raise:
            AssertionError - if target not found.
        Returns:
            Position of the template.
        """
        if isinstance(v, Template):
            try:
                pos = loop_find(v, timeout=ST.FIND_TIMEOUT, driver=self)
            except TargetNotFoundError:
                raise AssertionError("Target template not found on screen.")
            else:
                return pos
        else:
            raise IsNotTemplateError("args is not a template")

    @logwrap
    def assert_exist(self, param, operation, msg=""):
        """
        Assert element exist.

        Args:
            operation: the method that to find the element.
            param: the param of method.
        Raise:
            AssertionError - if assertion failed.
        """
        try:
            func = self.operation_to_func[operation]
        except Exception:
            raise AssertionError("There was no operation: %s" % operation)
        try:
            func(param)
        except Exception as e:
            raise AssertionError("Target element not find.")

    @logwrap
    def get(self, address):
        """
        Access the web address.

        Args:
            address: the address that to accesss
        """
        super(WebChrome, self).get(address)
        time.sleep(2)

    @logwrap
    def back(self):
        """
        Back to last page.
        """
        super(WebChrome, self).back()
        self._gen_screen_log()
        time.sleep(1)

    @logwrap
    def forward(self):
        """
        Forward to next page.
        """
        super(WebChrome, self).forward()
        self._gen_screen_log()
        time.sleep(1)

    @logwrap
    def snapshot(self, filename=None):
        self._gen_screen_log(filename=filename)

    @logwrap
    def _gen_screen_log(self, element=None, filename=None, ):
        if ST.LOG_DIR is None:
            return None
        if filename:
            self.screenshot(filename)

        # 忽略警告 .jpg
        jpg_file_name = str(int(time.time())) + '.png'
        # 适配utx报告路径
        jpg_path = os.path.join(ST.LOG_DIR, jpg_file_name)
        print("this is jpg path:", jpg_path)
        self.screenshot(jpg_path)
        saved = {"screen": jpg_path}
        if element:
            size = element.size
            location = element.location
            x = size['width'] / 2 + location['x']
            y = size['height'] / 2 + location['y']
            if "darwin" in sys.platform:
                x, y = x * 2, y * 2
            saved.update({"pos": [[x, y]]})
        return saved

    def screenshot(self, file_path=None):
        if file_path:
            self.save_screenshot(file_path)
        else:
            if not ST.LOG_DIR:
                file_path = "temp.png"
            else:
                file_path = os.path.join(ST.LOG_DIR, "temp.png")
            self.save_screenshot(file_path)
            screen = aircv.imread(file_path)
            return screen

    def _get_left_up_offset(self):
        window_pos = self.get_window_position()
        window_size = self.get_window_size()
        mouse = Controller()
        screen = self.screenshot()
        screen_size = get_resolution(screen)
        offset = window_size["width"] - \
                 screen_size[0], window_size["height"] - screen_size[1]
        pos = (int(offset[0] / 2 + window_pos['x']),
               int(offset[1] + window_pos['y'] - offset[0] / 2))
        return pos

    def _move_to_pos(self, pos):
        self.mouse.position = pos

    def _click_current_pos(self):
        self.mouse.click(Button.left, 1)

    def to_json(self):
        # add this method for json encoder in logwrap
        return repr(self)


class WebRemote(Remote):

    def __init__(self, command_executor='http://127.0.0.1:4444/wd/hub',
                 desired_capabilities=None, browser_profile=None, proxy=None,
                 keep_alive=False, file_detector=None, options=None):
        super(WebRemote, self).__init__(command_executor=command_executor,
                                        desired_capabilities=desired_capabilities, browser_profile=browser_profile,
                                        proxy=proxy,
                                        keep_alive=keep_alive, file_detector=file_detector, options=options)

        self.father_number = {0: 0}
        self.action_chains = ActionChains(self)
        self.number = 0
        self.mouse = Controller()
        self.operation_to_func = {"xpath": self.find_element_by_xpath, "id": self.find_element_by_id,
                                  "name": self.find_element_by_name, "css": self.find_element_by_css_selector}

    def loop_find_element(self, func, text, timeout=10, interval=0.5):
        """
        Loop to find the target web element by func.

        Args:
            func: function to find element
            text: param of function
            timeout: time to find the element
            interval: interval between operation
        Returns:
            element that been found
        """
        start_time = time.time()
        while True:
            try:
                element = func(text)
            except NoSuchElementException:
                print("Element not found!")
                # 超时则raise，未超时则进行下次循环:
                if (time.time() - start_time) > timeout:
                    # try_log_screen(screen)
                    raise NoSuchElementException('Element %s not found in screen' % text)
                else:
                    time.sleep(interval)
            else:
                return element

    @logwrap
    def find_element_by_xpath(self, xpath):
        """
        Find the web element by xpath.

        Args:
            xpath: find the element by xpath.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebRemote, self).find_element_by_xpath, xpath)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_id(self, id):
        """
        Find the web element by id.

        Args:
            id: find the element by attribute id.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebRemote, self).find_element_by_id, id)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_css_selector(self, css_selector):
        """
        Find the web element by css_selector.

        Args:
            css_selector: find the element by attribute css_selector.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebRemote, self).find_element_by_css_selector, css_selector)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_name(self, name):
        """
        Find the web element by name.

        Args:
            name: find the element by attribute name.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(WebRemote, self).find_element_by_name, name)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def switch_to_new_tab(self):
        """
        Switch to the new tab.
        """
        _father = self.number
        self.number = len(self.window_handles) - 1
        self.father_number[self.number] = _father
        self.switch_to.window(self.window_handles[self.number])
        self._gen_screen_log()
        time.sleep(0.5)

    @logwrap
    def switch_to_previous_tab(self):
        """
        Switch to the previous tab(which to open current tab).
        """
        self.number = self.father_number[self.number]
        self.switch_to.window(self.window_handles[self.number])
        self._gen_screen_log()
        time.sleep(0.5)

    @logwrap
    def airtest_touch(self, v):
        """
        Perform the touch action on the current page by image identification.

        Args:
            v: target to touch, either a Template instance or absolute coordinates (x, y)
        Returns:
            Finial position to be clicked.
        """
        if isinstance(v, Template):
            _pos = loop_find(v, timeout=ST.FIND_TIMEOUT, driver=self)
        else:
            _pos = v
        x, y = _pos
        # self.action_chains.move_to_element_with_offset(root_element, x, y)
        # self.action_chains.click()
        pos = self._get_left_up_offset()
        pos = (pos[0] + x, pos[1] + y)
        self._move_to_pos(pos)
        self._click_current_pos()
        time.sleep(1)
        return _pos

    @logwrap
    def assert_template(self, v, msg=""):
        """
        Assert target exists on the current page.

        Args:
            v: target to touch, either a Template instance
        Raise:
            AssertionError - if target not found.
        Returns:
            Position of the template.
        """
        if isinstance(v, Template):
            try:
                pos = loop_find(v, timeout=ST.FIND_TIMEOUT, driver=self)
            except TargetNotFoundError:
                raise AssertionError("Target template not found on screen.")
            else:
                return pos
        else:
            raise IsNotTemplateError("args is not a template")

    @logwrap
    def assert_exist(self, param, operation, msg=""):
        """
        Assert element exist.

        Args:
            operation: the method that to find the element.
            param: the param of method.
        Raise:
            AssertionError - if assertion failed.
        """
        try:
            func = self.operation_to_func[operation]
        except Exception:
            raise AssertionError("There was no operation: %s" % operation)
        try:
            func(param)
        except Exception as e:
            raise AssertionError("Target element not find.")

    @logwrap
    def get(self, address):
        """
        Access the web address.

        Args:
            address: the address that to accesss
        """
        super(WebRemote, self).get(address)
        time.sleep(2)

    @logwrap
    def back(self):
        """
        Back to last page.
        """
        super(WebRemote, self).back()
        self._gen_screen_log()
        time.sleep(1)

    @logwrap
    def forward(self):
        """
        Forward to next page.
        """
        super(WebRemote, self).forward()
        self._gen_screen_log()
        time.sleep(1)

    @logwrap
    def snapshot(self, filename=None):
        self._gen_screen_log(filename=filename)

    @logwrap
    def _gen_screen_log(self, element=None, filename=None, ):
        if ST.LOG_DIR is None:
            return None
        if filename:
            self.screenshot(filename)
        jpg_file_name = str(int(time.time())) + '.png'
        jpg_path = os.path.join(ST.LOG_DIR, jpg_file_name)
        print("this is jpg path:", jpg_path)
        self.screenshot(jpg_path)
        saved = {"screen": jpg_path}
        if element:
            size = element.size
            location = element.location
            x = size['width'] / 2 + location['x']
            y = size['height'] / 2 + location['y']
            if "darwin" in sys.platform:
                x, y = x * 2, y * 2
            saved.update({"pos": [[x, y]]})
        return saved

    def screenshot(self, file_path=None):
        if file_path:
            self.save_screenshot(file_path)
        else:
            if not ST.LOG_DIR:
                file_path = "temp.png"
            else:
                file_path = os.path.join(ST.LOG_DIR, "temp.png")
            self.save_screenshot(file_path)
            screen = aircv.imread(file_path)
            return screen

    def _get_left_up_offset(self):
        window_pos = self.get_window_position()
        window_size = self.get_window_size()
        mouse = Controller()
        screen = self.screenshot()
        screen_size = get_resolution(screen)
        offset = window_size["width"] - \
                 screen_size[0], window_size["height"] - screen_size[1]
        pos = (int(offset[0] / 2 + window_pos['x']),
               int(offset[1] + window_pos['y'] - offset[0] / 2))
        return pos

    def _move_to_pos(self, pos):
        self.mouse.position = pos

    def _click_current_pos(self):
        self.mouse.click(Button.left, 1)

    def to_json(self):
        # add this method for json encoder in logwrap
        return repr(self)


class WebFirefox(Firefox):

    def __init__(self, firefox_profile=None, firefox_binary=None,
                 timeout=30, capabilities=None, proxy=None,
                 executable_path="geckodriver", options=None, firefox_options=None,
                 service_args=None, desired_capabilities=None, log_path=None):
        print("Please make sure your geckodriver is in your path before proceeding using this driver")
        super(WebFirefox, self).__init__(firefox_profile=firefox_profile, firefox_binary=firefox_binary,
                                         timeout=timeout, capabilities=capabilities, proxy=proxy,
                                         executable_path=executable_path, options=options,
                                         firefox_options=firefox_options,
                                         service_args=service_args, desired_capabilities=desired_capabilities,
                                         log_path=log_path)
        self.father_number = {0: 0}
        self.action_chains = ActionChains(self)
        self.number = 0
        self.mouse = Controller()
        self.operation_to_func = {"xpath": self.find_element_by_xpath, "id": self.find_element_by_id,
                                  "name": self.find_element_by_name, "css": self.find_element_by_css_selector}

    def loop_find_element(self, func, text, timeout=10, interval=0.5):
        """
        Loop to find the target web element by func.

        Args:
            func: function to find element
            text: param of function
            timeout: time to find the element
            interval: interval between operation
        Returns:
            element that been found
        """
        start_time = time.time()
        while True:
            try:
                element = func(text)
            except NoSuchElementException:
                print("Element not found!")
                # 超时则raise，未超时则进行下次循环:
                if (time.time() - start_time) > timeout:
                    # try_log_screen(screen)
                    raise NoSuchElementException('Element %s not found in screen' % text)
                else:
                    time.sleep(interval)
            else:
                return element

    @logwrap
    def find_element_by_xpath(self, xpath):
        """
        Find the web element by xpath.

        Args:
            xpath: find the element by xpath.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(Firefox, self).find_element_by_xpath, xpath)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_id(self, id):
        """
        Find the web element by id.

        Args:
            id: find the element by attribute id.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(Firefox, self).find_element_by_id, id)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_css_selector(self, css_selector):
        """
        Find the web element by css_selector.

        Args:
            css_selector: find the element by attribute css_selector.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(Firefox, self).find_element_by_css_selector, css_selector)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def find_element_by_name(self, name):
        """
        Find the web element by name.

        Args:
            name: find the element by attribute name.
        Returns:
            Web element of current page.
        """
        web_element = self.loop_find_element(super(Firefox, self).find_element_by_name, name)
        log_res = self._gen_screen_log(web_element)
        return Element(web_element, log_res)

    @logwrap
    def switch_to_new_tab(self):
        """
        Switch to the new tab.
        """
        _father = self.number
        self.number = len(self.window_handles) - 1
        self.father_number[self.number] = _father
        self.switch_to.window(self.window_handles[self.number])
        self._gen_screen_log()
        time.sleep(0.5)

    @logwrap
    def switch_to_previous_tab(self):
        """
        Switch to the previous tab(which to open current tab).
        """
        self.number = self.father_number[self.number]
        self.switch_to.window(self.window_handles[self.number])
        self._gen_screen_log()
        time.sleep(0.5)

    @logwrap
    def airtest_touch(self, v):
        """
        Perform the touch action on the current page by image identification.

        Args:
            v: target to touch, either a Template instance or absolute coordinates (x, y)
        Returns:
            Finial position to be clicked.
        """
        if isinstance(v, Template):
            _pos = loop_find(v, timeout=ST.FIND_TIMEOUT, driver=self)
        else:
            _pos = v
        x, y = _pos
        # self.action_chains.move_to_element_with_offset(root_element, x, y)
        # self.action_chains.click()
        pos = self._get_left_up_offset()
        pos = (pos[0] + x, pos[1] + y)
        self._move_to_pos(pos)
        self._click_current_pos()
        time.sleep(1)
        return _pos

    @logwrap
    def assert_template(self, v, msg=""):
        """
        Assert target exists on the current page.

        Args:
            v: target to touch, either a Template instance
        Raise:
            AssertionError - if target not found.
        Returns:
            Position of the template.
        """
        if isinstance(v, Template):
            try:
                pos = loop_find(v, timeout=ST.FIND_TIMEOUT, driver=self)
            except TargetNotFoundError:
                raise AssertionError("Target template not found on screen.")
            else:
                return pos
        else:
            raise IsNotTemplateError("args is not a template")

    @logwrap
    def assert_exist(self, param, operation, msg=""):
        """
        Assert element exist.

        Args:
            operation: the method that to find the element.
            param: the param of method.
        Raise:
            AssertionError - if assertion failed.
        """
        try:
            func = self.operation_to_func[operation]
        except Exception:
            raise AssertionError("There was no operation: %s" % operation)
        try:
            func(param)
        except Exception as e:
            raise AssertionError("Target element not find.")

    @logwrap
    def get(self, address):
        """
        Access the web address.

        Args:
            address: the address that to accesss
        """
        super(WebFirefox, self).get(address)
        time.sleep(2)

    @logwrap
    def back(self):
        """
        Back to last page.
        """
        super(WebFirefox, self).back()
        self._gen_screen_log()
        time.sleep(1)

    @logwrap
    def forward(self):
        """
        Forward to next page.
        """
        super(WebFirefox, self).forward()
        self._gen_screen_log()
        time.sleep(1)

    @logwrap
    def snapshot(self, filename=None):
        self._gen_screen_log(filename=filename)

    @logwrap
    def _gen_screen_log(self, element=None, filename=None, ):
        if ST.LOG_DIR is None:
            return None
        if filename:
            self.screenshot(filename)
        jpg_file_name = str(int(time.time())) + '.png'
        jpg_path = os.path.join(ST.LOG_DIR, jpg_file_name)
        print("this is jpg path:", jpg_path)
        self.screenshot(jpg_path)
        saved = {"screen": jpg_path}
        if element:
            size = element.size
            location = element.location
            x = size['width'] / 2 + location['x']
            y = size['height'] / 2 + location['y']
            if "darwin" in sys.platform:
                x, y = x * 2, y * 2
            saved.update({"pos": [[x, y]]})
        return saved

    def screenshot(self, file_path=None):
        if file_path:
            self.save_screenshot(file_path)
        else:
            if not ST.LOG_DIR:
                file_path = "temp.png"
            else:
                file_path = os.path.join(ST.LOG_DIR, "temp.png")
            self.save_screenshot(file_path)
            screen = aircv.imread(file_path)
            return screen

    def _get_left_up_offset(self):
        window_pos = self.get_window_position()
        window_size = self.get_window_size()
        mouse = Controller()
        screen = self.screenshot()
        screen_size = get_resolution(screen)
        offset = window_size["width"] - \
                 screen_size[0], window_size["height"] - screen_size[1]
        pos = (int(offset[0] / 2 + window_pos['x']),
               int(offset[1] + window_pos['y'] - offset[0] / 2))
        return pos

    def _move_to_pos(self, pos):
        self.mouse.position = pos

    def _click_current_pos(self):
        self.mouse.click(Button.left, 1)

    def to_json(self):
        # add this method for json encoder in logwrap
        return repr(self)


class Element(WebElement):

    def __init__(self, _obj, log):
        super(Element, self).__init__(
            parent=_obj._parent, id_=_obj._id, w3c=_obj._w3c)
        self.res_log = log

    def click(self):
        super(Element, self).click()
        time.sleep(0.5)
        return self.res_log

    def send_keys(self, text, keyborad=None):
        if keyborad:
            super(Element, self).send_keys(text, keyborad)
        else:
            super(Element, self).send_keys(text)
        time.sleep(0.5)
        return self.res_log
