You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ORPA-pyOpenRPA/Sources/pyOpenRPA/Robot/UIWeb.py

211 lines
8.6 KiB

from selenium import *
from selenium import webdriver, common
import os
import sys
from pyOpenRPA.Tools import CrossOS
import time
# XPATH CSS CHEAT CHEET: https://devhints.io/xpath
UIO_WAIT_SEC_FLOAT = 60
UIO_WAIT_INTERVAL_SEC_FLOAT = 1.0
gBrowser:webdriver.Chrome = None
def BrowserChromeStart(inDriverExePathStr:str = None, inChromeExePathStr:str = None, inExtensionPathList:list = None, inProfilePathStr:str=None) -> webdriver.Chrome:
global gBrowser
lResourcePathStr = os.path.abspath(os.path.join(sys.executable, "..","..", ".."))
# Путь по умолчанию к портативному браузеру и драйверу (если скачивался репозиторий pyOpenRPA
if inDriverExePathStr == None: inDriverExePathStr = os.path.join(lResourcePathStr, "SeleniumWebDrivers", "Chrome", "chromedriver_win32 v84.0.4147.30", "chromedriver.exe")
if inChromeExePathStr == None: inChromeExePathStr = os.path.join(lResourcePathStr, "WChrome64-840414730", "App", "Chrome-bin", "chrome.exe")
if inExtensionPathList == None: inExtensionPathList = []
# Set full path to exe of the chrome
lWebDriverChromeOptionsInstance = webdriver.ChromeOptions()
lWebDriverChromeOptionsInstance.binary_location = inChromeExePathStr
#lWebDriverChromeOptionsInstance2 = webdriver.ChromeOptions()
if inProfilePathStr is not None:
inProfilePathStr = os.path.abspath(inProfilePathStr)
lWebDriverChromeOptionsInstance.add_argument(f"user-data-dir={os.path.abspath(inProfilePathStr)}")
# Add extensions
for lExtensionItemFullPath in inExtensionPathList:
lWebDriverChromeOptionsInstance.add_extension (os.path.abspath(lExtensionItemFullPath))
#if inDriverExePathStr == "built-in":
# Run with specified web driver path
gBrowser = webdriver.Chrome(executable_path = inDriverExePathStr, options=lWebDriverChromeOptionsInstance)
#else:
# lWebDriverInstance = webdriver.Chrome(options = lWebDriverChromeOptionsInstance)
return gBrowser
def BrowserChange(inBrowser):
global gBrowser
gBrowser = inBrowser
def PageOpen(inURLStr):
global gBrowser
if gBrowser is not None: gBrowser.get(inURLStr)
def PageScrollTo(inVerticalPxInt=0, inHorizontalPxInt=0):
PageJSExecute(inJSStr=f"scroll({inHorizontalPxInt},{inVerticalPxInt})")
def PageJSExecute(inJSStr, *inArgList):
# arguments[0], arguments[1] etc
global gBrowser
if gBrowser is not None: return gBrowser.execute_script(inJSStr, *inArgList)
def BrowserClose():
global gBrowser
if gBrowser is not None: gBrowser.quit()
def UIOSelectorList(inUIOSelectorStr, inUIO=None) -> list:
lResultList = []
if inUIO is None:
global gBrowser
if gBrowser is not None:
if UIOSelectorDetect(inUIOSelectorStr=inUIOSelectorStr) == "CSS":
lResultList = gBrowser.find_elements_by_css_selector(css_selector=inUIOSelectorStr)
else:
lResultList = gBrowser.find_elements_by_xpath(xpath=inUIOSelectorStr)
else:
if UIOSelectorDetect(inUIOSelectorStr=inUIOSelectorStr) == "CSS":
lResultList = inUIO.find_elements_by_css_selector(css_selector=inUIOSelectorStr)
else:
lResultList = gBrowser.find_elements_by_xpath(xpath=inUIOSelectorStr)
return lResultList
def UIOSelectorFirst(inUIOSelectorStr, inUIO=None) -> list:
lResult = None
lUIOList = UIOSelectorList(inUIOSelectorStr=inUIOSelectorStr, inUIO=inUIO)
if len(lUIOList) > 0: lResult = lUIOList[0]
return lResult
def UIOTextGet(inUIO) -> str:
return inUIO.text
def UIOAttributeGet(inUIO, inAttributeStr) -> str:
return inUIO.get_attribute(inAttributeStr)
def UIOAttributeStyleGet(inUIO, inAttributeStr) -> str:
return inUIO.value_of_css_property(inAttributeStr)
def UIOAttributeSet(inUIO, inAttributeStr, inValue):
lJSStr = \
f"arguments[0].setAttribute(arguments[1], arguments[2]);"
gBrowser.execute_script(lJSStr,inUIO, inAttributeStr, inValue)
def UIOAttributeRemove(inUIO, inAttributeStr):
lJSStr = \
f"arguments[0].removeAttribute(arguments[1]);"
gBrowser.execute_script(lJSStr,inUIO, inAttributeStr)
def UIOAttributeStyleSet(inUIO, inAttributeStr, inValue):
lJSStr = \
f"arguments[0].style[arguments[1]]=arguments[2];"
gBrowser.execute_script(lJSStr,inUIO, inAttributeStr, inValue)
def UIOAttributeStyleRemove(inUIO, inAttributeStr):
lJSStr = \
f"arguments[0].style[arguments[1]]=\"\";"
gBrowser.execute_script(lJSStr,inUIO, inAttributeStr)
def UIOClick(inUIO):
inUIO.click()
def UIOSelectorHighlight(inUIOSelectorStr: str, inIsFirst:bool=False, inDurationSecFloat:float=3.0, inColorStr:str="green"):
global gBrowser
if inIsFirst == True:
lUIOList = [UIOSelectorFirst(inUIOSelectorStr=inUIOSelectorStr)]
lJSStr = \
f"var lElementList = arguments[0];" \
f"if (lElementList.length>0) {{ lElementList=[lElementList[0]]; }}" \
f"for (var lIndexInt=0; lIndexInt<lElementList.length;lIndexInt++) {{" \
f" lElement=lElementList[lIndexInt];" \
f" lElement.ORPABackupStyleOutline = lElement.style[\"outline\"];" \
f" lElement.style[\"outline\"]=\"2px solid {inColorStr}\";" \
f"}}" \
f"window.ORPAOutlineList = lElementList;"
PageJSExecute(lJSStr, lUIOList)
else:
lUIOList = UIOSelectorList(inUIOSelectorStr=inUIOSelectorStr)
lJSStr = \
f"var lElementList = arguments[0];" \
f"for (var lIndexInt=0; lIndexInt<lElementList.length;lIndexInt++) {{" \
f" lElement=lElementList[lIndexInt];" \
f" lElement.ORPABackupStyleOutline = lElement.style[\"outline\"];" \
f" lElement.style[\"outline\"]=\"2px solid {inColorStr}\";" \
f"}}" \
f"window.ORPAOutlineList = lElementList;"
PageJSExecute(lJSStr, lUIOList)
time.sleep(inDurationSecFloat)
lJSStr = \
f"var lElementList = window.ORPAOutlineList;" \
f"for (var lIndexInt=0; lIndexInt<lElementList.length;lIndexInt++) {{" \
f" lElement=lElementList[lIndexInt];" \
f" lElement.style[\"outline\"]=lElement.ORPABackupStyleOutline;" \
f"}}" \
f"delete window.ORPAOutlineList;"
PageJSExecute(inJSStr=lJSStr)
def UIOSelectorClick(inUIOSelectorStr: str):
PageJSExecute(inJSStr=f"document.querySelector('{inUIOSelectorStr}').click()")
def UIOSelectorWaitAppear(inUIOSelectorStr:str, inWaitSecFloat:float=UIO_WAIT_SEC_FLOAT, inWaitIntervalSecFloat:float = UIO_WAIT_INTERVAL_SEC_FLOAT):
lStartSecFloat = time.time()
lResultList=[]
while time.time() - lStartSecFloat < inWaitSecFloat:
lResultList = UIOSelectorList(inUIOSelectorStr=inUIOSelectorStr)
if len(lResultList)>0: break
time.sleep(inWaitIntervalSecFloat)
if time.time() - lStartSecFloat > inWaitSecFloat: raise Exception(f"Wait time is over. No element has been appear")
return lResultList
def UIOSelectorWaitDisappear(inUIOSelectorStr:str, inWaitSecFloat:float=UIO_WAIT_SEC_FLOAT, inWaitIntervalSecFloat:float = UIO_WAIT_INTERVAL_SEC_FLOAT):
lStartSecFloat = time.time()
while time.time() - lStartSecFloat < inWaitSecFloat:
lResultList = UIOSelectorList(inUIOSelectorStr=inUIOSelectorStr)
if len(lResultList)==0: break
time.sleep(inWaitIntervalSecFloat)
if time.time() - lStartSecFloat > inWaitSecFloat: raise Exception(f"Wait time is over. No element has been disappear")
from lxml import etree
from io import StringIO
gXML = etree.parse(StringIO('<foo><bar></bar></foo>'))
def UIOSelectorDetect(inUIOSelectorStr:str) -> str:
"""Идентифицировать стиль селектора (CSS или XPATH)
:param inUIOSelectorStr: _description_
:type inUIOSelectorStr: str
:return: "CSS" или "XPATH"
:rtype: str
"""
global gXML
lResultStr = "CSS"
try:
gXML.xpath(inUIOSelectorStr)
lResultStr = "XPATH"
except etree.XPathEvalError as e:
lResultStr = "CSS"
return lResultStr
def UIOMouseSearchInit():
lJSStr = """
document.ORPASearch = function(e){
document.ORPAMouseXInt = e.clientX;
document.ORPAMouseYInt = e.clientY;
}
document.addEventListener('mousemove', document.ORPASearch, {
passive: true})
"""
PageJSExecute(lJSStr)
def UIOMouseSearchReturn():
lJSStr = """
document.removeEventListener('mousemove', document.ORPASearch);
return document.elementFromPoint(document.ORPAMouseXInt,document.ORPAMouseYInt);
"""
return PageJSExecute(lJSStr)