#Resource_add_notepad++64_32_PythonSpaceSupport #Robot_GUI_Logging #RobotFixing_NeedToTest_MouseSearch

dev-linux
Ivan Maslov 6 years ago
parent cd5a4684bc
commit f7aba97dbb

@ -15,6 +15,14 @@ import traceback
import ProcessCommunicator import ProcessCommunicator
import JSONNormalize import JSONNormalize
from threading import Timer from threading import Timer
import datetime
import logging
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRobotGUIRun_"+datetime.datetime.now().strftime("%Y_%m_%d__%H_%M_%S")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
#################################### ####################################
#Info: GUI module of the Robot app (OpenRPA - Robot) #Info: GUI module of the Robot app (OpenRPA - Robot)
@ -197,11 +205,13 @@ def UIOSelector_Get_UIO (inSpecificationList,inElement=None):
def PWASpecification_Get_UIO(inControlSpecificationArray): def PWASpecification_Get_UIO(inControlSpecificationArray):
#Определение backend #Определение backend
lBackend=mDefaultPywinautoBackend lBackend=mDefaultPywinautoBackend
#pdb.set_trace()
if "backend" in inControlSpecificationArray[0]: if "backend" in inControlSpecificationArray[0]:
lBackend=inControlSpecificationArray[0]["backend"] lBackend=inControlSpecificationArray[0]["backend"]
inControlSpecificationArray[0].pop("backend") inControlSpecificationArray[0].pop("backend")
#Подготовка входного массива #Подготовка входного массива
inControlSpecificationArray=UIOSelector_SearchNormalize_UIOSelector(inControlSpecificationArray) inControlSpecificationOriginArray=inControlSpecificationArray
inControlSpecificationArray=UIOSelector_SearchProcessNormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив #Выполнить идентификацию объектов, если передан массив
lResultList=[]; lResultList=[];
lTempObject=None lTempObject=None
@ -222,7 +232,7 @@ def PWASpecification_Get_UIO(inControlSpecificationArray):
#Скорректировано из-за недопонимания структуры #Скорректировано из-за недопонимания структуры
lTempObject=lRPAApplication lTempObject=lRPAApplication
#Нормализация массива для целей выборки объекта (удаление конфликтующих ключей) #Нормализация массива для целей выборки объекта (удаление конфликтующих ключей)
inControlSpecificationArray=UIOSelector_SearchNormalize_UIOSelector(inControlSpecificationArray) inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationOriginArray)
#Циклическое прохождение к недрам объекта #Циклическое прохождение к недрам объекта
for lWindowSpecification in inControlSpecificationArray[0:]: for lWindowSpecification in inControlSpecificationArray[0:]:
lTempObject=lTempObject.window(**lWindowSpecification) lTempObject=lTempObject.window(**lWindowSpecification)
@ -240,6 +250,8 @@ def UIOSelector_SearchChildByMouse_UIO(inElementSpecification):
#Ветка поиска в режиме реального времени #Ветка поиска в режиме реального времени
#Сбросить нажатие Ctrl, если оно было #Сбросить нажатие Ctrl, если оно было
bool(win32api.GetAsyncKeyState(17)) bool(win32api.GetAsyncKeyState(17))
#Оптимизация - получить объект для опроса единажды
lUIORoot=UIOSelector_Get_UIO(inElementSpecification)
lFlagLoop = True lFlagLoop = True
while lFlagLoop: while lFlagLoop:
#Проверить, нажата ли клавиша Ctrl (код 17) #Проверить, нажата ли клавиша Ctrl (код 17)
@ -251,7 +263,7 @@ def UIOSelector_SearchChildByMouse_UIO(inElementSpecification):
lElementFounded={} lElementFounded={}
#Создать карту пикселей и элементов #Создать карту пикселей и элементов
#####Внимание! Функция UIOXY_SearchChild_ListDict не написана #####Внимание! Функция UIOXY_SearchChild_ListDict не написана
lElementFoundedList=UIOXY_SearchChild_ListDict(UIOSelector_Get_UIO(inElementSpecification),lX,lY) lElementFoundedList=UIOXY_SearchChild_ListDict(lUIORoot,lX,lY)
#print(lElementFoundedList) #print(lElementFoundedList)
lElementFounded=lElementFoundedList[-1]["element"] lElementFounded=lElementFoundedList[-1]["element"]
#Подсветить объект, если он мышь раньше стояла на другом объекте #Подсветить объект, если он мышь раньше стояла на другом объекте
@ -274,7 +286,7 @@ def UIOSelector_SearchChildByMouse_UIO(inElementSpecification):
def UIOSelector_SearchChildByMouse_UIOTree(inElementSpecification): def UIOSelector_SearchChildByMouse_UIOTree(inElementSpecification):
lItemInfo = [] lItemInfo = []
#Запустить функцию поиска элемента по мыши #Запустить функцию поиска элемента по мыши
lElementList = UIOSelector_SearchChildByMouse_UIO(inElementSpecification,inFlagIsSearchOnline) lElementList = UIOSelector_SearchChildByMouse_UIO(inElementSpecification)
lElement = lElementList[-1]['element'] lElement = lElementList[-1]['element']
#Detect backend of the elements #Detect backend of the elements
lFlagIsBackendWin32 = True lFlagIsBackendWin32 = True
@ -311,6 +323,8 @@ def UIOSelector_SearchChildByMouse_UIOTree(inElementSpecification):
#Переход на родительский объект #Переход на родительский объект
#lElement = lElement.parent() #lElement = lElement.parent()
lListIterator=lListIterator+1 lListIterator=lListIterator+1
#Добавить информацию о Backend в первый объект
lItemInfo[0]["backend"]=lElement.backend.name
#Вернуть результат #Вернуть результат
return lItemInfo return lItemInfo
#################################################################################################### ####################################################################################################
@ -387,7 +401,7 @@ def UIOSelector_TryRestore_Dict(inSpecificationList):
lResult={} lResult={}
try: try:
#Подготовка взодного массива #Подготовка взодного массива
inControlSpecificationArray=UIOSelector_SearchNormalize_UIOSelector(inSpecificationList) inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inSpecificationList)
#Выполнить подключение к объекту. Восстановление необходимо только в бэке win32, #Выполнить подключение к объекту. Восстановление необходимо только в бэке win32,
#так как в uia свернутое окно не распознается #так как в uia свернутое окно не распознается
lRPAApplication = pywinauto.Application(backend="win32") lRPAApplication = pywinauto.Application(backend="win32")
@ -451,7 +465,7 @@ def UIOSelectorUIOActivity_Run_Dict(inControlSpecificationArray,inActionName,inA
#old name - ElementGetInfo #old name - ElementGetInfo
def UIOSelector_Get_UIOInfo(inControlSpecificationArray): def UIOSelector_Get_UIOInfo(inControlSpecificationArray):
#Подготовка входного массива #Подготовка входного массива
inControlSpecificationArray=UIOSelector_SearchNormalize_UIOSelector(inControlSpecificationArray) inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив #Выполнить идентификацию объектов, если передан массив
lResultList=[]; lResultList=[];
if len(inControlSpecificationArray) > 0: if len(inControlSpecificationArray) > 0:
@ -559,7 +573,7 @@ def UIOXY_SearchChild_ListDict(inRootElement,inX,inY,inHierarchyList=[]):
#old name - ElementGetChildElementList #old name - ElementGetChildElementList
def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[],inBackend=mDefaultPywinautoBackend): def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[],inBackend=mDefaultPywinautoBackend):
#Подготовка входного массива #Подготовка входного массива
inControlSpecificationArray=UIOSelector_SearchNormalize_UIOSelector(inControlSpecificationArray) inControlSpecificationArray=UIOSelector_SearchUIONormalize_UIOSelector(inControlSpecificationArray)
#Выполнить идентификацию объектов, если передан массив #Выполнить идентификацию объектов, если передан массив
lResultList=[]; lResultList=[];
#ctypes.windll.user32.MessageBoxW(0, str(inControlSpecificationArray), "Your title", 1) #ctypes.windll.user32.MessageBoxW(0, str(inControlSpecificationArray), "Your title", 1)
@ -581,6 +595,9 @@ def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[],inBackend=mD
lIterator=lIterator+1 lIterator=lIterator+1
else: else:
lResultList=BackendStr_GetTopLevelList_UIOInfo(inBackend) lResultList=BackendStr_GetTopLevelList_UIOInfo(inBackend)
#Установка бэк-енда на первый элемент
for lItem in lResultList:
lItem["backend"]=inBackend
return lResultList return lResultList
#################################################################################################### ####################################################################################################
@ -588,7 +605,7 @@ def UIOSelector_GetChildList_UIOList(inControlSpecificationArray=[],inBackend=mD
#inControlSpecificationArray - UIOSelector (can be dirty) #inControlSpecificationArray - UIOSelector (can be dirty)
#old name 1 - ElementSpecificationArraySearchPrepare #old name 1 - ElementSpecificationArraySearchPrepare
#old name 2 - ElementSpecificationListNormalize #old name 2 - ElementSpecificationListNormalize
def UIOSelector_SearchNormalize_UIOSelector (inControlSpecificationArray): def UIOSelector_SearchUIONormalize_UIOSelector (inControlSpecificationArray):
lResult=[] lResult=[]
#Циклический обход #Циклический обход
for lSpecificationItem in inControlSpecificationArray: for lSpecificationItem in inControlSpecificationArray:
@ -641,11 +658,99 @@ def UIOSelector_SearchNormalize_UIOSelector (inControlSpecificationArray):
lSpecificationItemNew.pop("control_id") lSpecificationItemNew.pop("control_id")
if "control_type" in lSpecificationItemNew: if "control_type" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_type") lSpecificationItemNew.pop("control_type")
#Проверить наличие handle - если он есть, то удалить process, control_id и control_type из-за того, что они мешают друг другу
if 'handle' in lSpecificationItemNew:
if "control_id" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_id")
if "control_type" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_type")
if "process" in lSpecificationItemNew:
lSpecificationItemNew.pop("process")
#Иначе Проверить наличие process - если он есть, то удалить тк он нужен только при подключении к процессу
if 'process' in lSpecificationItemNew:
lSpecificationItemNew.pop("process")
#Добавить строку в результирующий массив #Добавить строку в результирующий массив
lResult.append(lSpecificationItemNew) lResult.append(lSpecificationItemNew)
#Вернуть результат #Вернуть результат
return lResult return lResult
####################################################################################################
#Подготовить массив для обращшения к поиску процесса (отличается от поиска элемента, тк данная функция нужна для нормализации спецификации для подключения к процессу с окнами)
#inControlSpecificationArray - UIOSelector (can be dirty)
#old name 1 - ElementSpecificationArraySearchPrepare
#old name 2 - ElementSpecificationListNormalize
def UIOSelector_SearchProcessNormalize_UIOSelector (inControlSpecificationArray):
lResult=[]
#Циклический обход
for lSpecificationItem in inControlSpecificationArray:
lSpecificationItemNew=lSpecificationItem.copy()
#Перебор всех элементов
for lItemKey,lItemValue in lSpecificationItem.items():
#Флаг удаления атрибута
lFlagRemoveAttribute=False
#############################
#Если является вложенным словарем - удалить
if type(lItemValue) is dict:
lFlagRemoveAttribute=True
#Является типом None
if lItemValue is None:
lFlagRemoveAttribute=True
#Проверка допустимого ключевого слова
if (
lItemKey == "class_name" or
lItemKey == "class_name_re" or
lItemKey == "parent" or
lItemKey == "process" or
lItemKey == "title" or
lItemKey == "title_re" or
lItemKey == "top_level_only" or
lItemKey == "visible_only" or
lItemKey == "enabled_only" or
lItemKey == "best_match" or
lItemKey == "handle" or
lItemKey == "ctrl_index" or
lItemKey == "found_index" or
lItemKey == "predicate_func" or
lItemKey == "active_only" or
lItemKey == "control_id" or
lItemKey == "control_type" or
lItemKey == "auto_id" or
lItemKey == "framework_id" or
lItemKey == "backend"):
True == True
else:
lFlagRemoveAttribute=True
#############################
#Конструкция по удалению ключа из словаря
if lFlagRemoveAttribute:
lSpecificationItemNew.pop(lItemKey)
#Проверит наличие ctrl_index - если он есть, то удалить control_id и control_type из-за того, что они мешают друг другу
if 'ctrl_index' in lSpecificationItemNew:
if "control_id" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_id")
if "control_type" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_type")
#Проверить наличие handle - если он есть, то удалить process, control_id и control_type из-за того, что они мешают друг другу
if 'handle' in lSpecificationItemNew:
if "control_id" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_id")
if "control_type" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_type")
if "process" in lSpecificationItemNew:
lSpecificationItemNew.pop("process")
#Иначе Проверить наличие process - если он есть, то удалить title, control_id и control_type из-за того, что они мешают друг другу
elif 'process' in lSpecificationItemNew:
if "control_id" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_id")
if "control_type" in lSpecificationItemNew:
lSpecificationItemNew.pop("control_type")
if "title" in lSpecificationItemNew:
lSpecificationItemNew.pop("title")
#Добавить строку в результирующий массив
lResult.append(lSpecificationItemNew)
#Вернуть результат
return lResult
#################################################################################################### ####################################################################################################
#Transfer UI object element info (pywinauto) to UIOInfo (dict of attributes) #Transfer UI object element info (pywinauto) to UIOInfo (dict of attributes)
#inElementInfo - UIOEI #inElementInfo - UIOEI
@ -806,13 +911,24 @@ def UIO_FocusHighlight(lWrapperObject,colour='green',thickness=2,fill=win32defin
#Определить разрядность процесса
lProcessBitnessStr = str(struct.calcsize("P") * 8)
############################ ############################
#Старая версия #Старая версия
# Определять флаг Debug, если как второй входной параметр не поступил ключ RELEASE
############################ ############################
mFlagIsDebug=True mFlagIsDebug=True
if (len(sys.argv)>=2):
#run() if (sys.argv[1].upper()=="RELEASE"):
lText = "Bitness:" + str(struct.calcsize("P") * 8) mFlagIsDebug=False
#Оповещение о выбранном режиме
if mFlagIsDebug:
logging.info("Robot/GUI: Debug mode, x"+lProcessBitnessStr)
print ("Robot/GUI: Debug mode, x"+lProcessBitnessStr)
else:
logging.info("Robot/GUI: Release mode, x"+lProcessBitnessStr)
#Нельзя делать print в release mode тк print делает вывод в PIPE поток, что нарушает последовательность взаимодействия с родительским процессом
#print ("Robot/GUI: Release mode, x"+lProcessBitnessStr)
#for line in sys.stdin: #for line in sys.stdin:
# lText=lText+line; # lText=lText+line;
#ctypes.windll.user32.MessageBoxW(0, lText, "Your title", 1) #ctypes.windll.user32.MessageBoxW(0, lText, "Your title", 1)
@ -820,11 +936,6 @@ lText = "Bitness:" + str(struct.calcsize("P") * 8)
buffer = "" buffer = ""
lJSONInputString="" lJSONInputString=""
#Алгоритм включения debug режима (если передано ключевое слово debug как параметр)
#Если есть хотя бы один параметр (sys.argv[1+])
if len(sys.argv) > 1:
if sys.argv[1] == "debug":
mFlagIsDebug=True
#Выполнить чтение буфера, если не отладка библиотеки #Выполнить чтение буфера, если не отладка библиотеки
if not mFlagIsDebug: if not mFlagIsDebug:
while True: while True:

@ -6,6 +6,14 @@ import os
import ProcessCommunicator import ProcessCommunicator
import importlib import importlib
import traceback import traceback
import logging
import sys
import datetime
#Создать файл логирования
# add filemode="w" to overwrite
if not os.path.exists("Reports"):
os.makedirs("Reports")
logging.basicConfig(filename="Reports\ReportRobotRun_"+datetime.datetime.now().strftime("%Y_%m_%d__%H_%M_%S")+".log", level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s")
#################################### ####################################
#Info: Main module of the Robot app (OpenRPA - Robot) #Info: Main module of the Robot app (OpenRPA - Robot)
@ -51,7 +59,7 @@ import traceback
#Section: Module initialization #Section: Module initialization
#################### ####################
#Start childprocess - GUI Module 32 bit #Start childprocess - GUI Module 32 bit
mProcessGUI_x32 = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe','..\\Robot\\GUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) mProcessGUI_x32 = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe','..\\Robot\\GUI.py','release'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#Start childprocess - GUI Module 64 bit - uncomment after WPy64 installation #Start childprocess - GUI Module 64 bit - uncomment after WPy64 installation
#mProcessGUI_x64 = subprocess.Popen(['..\\Resources\\WPy64-3720\\python-3.7.2\\python.exe','GUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) #mProcessGUI_x64 = subprocess.Popen(['..\\Resources\\WPy64-3720\\python-3.7.2\\python.exe','GUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)

@ -0,0 +1,4 @@
cd %~dp0
copy /Y ..\Resources\WPy32-3720\python-3.7.2\python.exe ..\Resources\WPy32-3720\python-3.7.2\OpenRPARobot.exe
.\..\Resources\WPy32-3720\python-3.7.2\OpenRPARobot.exe Robot.py "release"
pause >nul

@ -71,6 +71,15 @@ class testHTTPServer_RequestHandler(BaseHTTPRequestHandler):
def do_POST(self): def do_POST(self):
#Restart studio #Restart studio
if self.path == '/RestartStudio': if self.path == '/RestartStudio':
#self.shutdown()
# Send response status code
self.send_response(200)
# Send headers
self.send_header('Content-type','application/json')
self.end_headers()
message = json.dumps({"Result":"Restart is in progress!"})
# Write content as utf-8 data
self.wfile.write(bytes(message, "utf8"))
os.execl(sys.executable,os.path.abspath(__file__),*sys.argv) os.execl(sys.executable,os.path.abspath(__file__),*sys.argv)
sys.exit(0) sys.exit(0)
#Action ObjectInspector GetObjectList #Action ObjectInspector GetObjectList
@ -158,9 +167,11 @@ def run():
httpd = HTTPServer(server_address, testHTTPServer_RequestHandler) httpd = HTTPServer(server_address, testHTTPServer_RequestHandler)
print('running server...') print('running server...')
httpd.serve_forever() httpd.serve_forever()
#Запуск адреса в браузере
os.system("explorer http://127.0.0.1:8081")
#Start childprocess 32 bit #Start childprocess 32 bit
p = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe','winGUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE) #p = subprocess.Popen(['..\\Resources\\WPy32-3720\\python-3.7.2\\python.exe','winGUI.py'],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
#print(ChildProcessReadWaitString(p)) #print(ChildProcessReadWaitString(p))
run() run()

@ -32,7 +32,22 @@
document.execCommand('copy'); document.execCommand('copy');
document.body.removeChild(el); document.body.removeChild(el);
}; };
///Функция перезапуска студии
mGlobal.Actions.fRestartStudioServer= function()
{
///Загрузка данных
$.ajax({
type: "POST",
url: 'RestartStudio',
data: '',
success:
function(lData,l2,l3)
{
var lResponseJSON=JSON.parse(lData);
},
dataType: "text"
});
}
///Функция клонирования объекта ///Функция клонирования объекта
mGlobal.iSysClone=function(obj,lIsCloneSubProperty,lSubItemCallback) { mGlobal.iSysClone=function(obj,lIsCloneSubProperty,lSubItemCallback) {
///Выполнить инициализацию переменной, если она не была передана ///Выполнить инициализацию переменной, если она не была передана
@ -74,13 +89,13 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'GUIAction', url: 'GUIAction',
data: '{"functionName":"AutomationSearchMouseElementHierarchy","argsArray":['+JSON.stringify(lSpecificationArray)+']}', data: '{"ModuleName":"GUI", "ActivityName":"UIOSelector_SearchChildByMouse_UIOTree","ArgumentList":['+JSON.stringify(lSpecificationArray)+']}',
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
var lResponseJSON=JSON.parse(lData); var lResponseJSON=JSON.parse(lData);
///Подготовить структуру рендеринга, если у текущего объекта имееется родитель ///Подготовить структуру рендеринга, если у текущего объекта имееется родитель
var lStructureToRender=lResponseJSON.outputObject; var lStructureToRender=lResponseJSON.Result;
if (lSpecificationArray.length>1) { if (lSpecificationArray.length>1) {
var lStructureToRenderParent=[] var lStructureToRenderParent=[]
var lStructureToRenderLocal=lStructureToRenderParent; var lStructureToRenderLocal=lStructureToRenderParent;
@ -99,12 +114,15 @@
} }
} }
} }
///Отображение ошибки
if (lResponseJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback);
} else {
///Очистить дерево ///Очистить дерево
mGlobal.ElementTree.fClear(); mGlobal.ElementTree.fClear();
///Прогрузить новое дерево ///Прогрузить новое дерево
mGlobal.ElementTree.fRender(lStructureToRender); mGlobal.ElementTree.fRender(lStructureToRender);
if (lResponseJSON.hasOwnProperty("Error")) {
mGlobal.ShowModal("GUI Error",lResponseJSON.Error);
} }
}, },
dataType: "text" dataType: "text"
@ -154,7 +172,7 @@
///Генерация кода HTML ///Генерация кода HTML
var lResultString=""; var lResultString="";
var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" ' var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" '
var lSubItemActionOnRightClick=' oncontextmenu="mGlobal.ElementHighlightNew(\''+lElementId+'\');" ' var lSubItemActionOnRightClick=' onclick="mGlobal.ElementHighlightNew(\''+lElementId+'\');" '
var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" ' var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" '
var lIconTestOnClick=' onclick="mGlobal.Test(\''+lElementId+'\');" ' var lIconTestOnClick=' onclick="mGlobal.Test(\''+lElementId+'\');" '
var lIconUpOnClick=' onclick="mGlobal.Actions.fAutomationSearchMouseElementHierarchyRun(\''+lElementId+'\');" ' var lIconUpOnClick=' onclick="mGlobal.Actions.fAutomationSearchMouseElementHierarchyRun(\''+lElementId+'\');" '
@ -175,14 +193,14 @@
} }
///Генерация кода текущего элемента ///Генерация кода текущего элемента
lResultString+='\ lResultString+='\
<div class="item" id="'+lElementId+'">\ <div class="item" id="'+lElementId+'" style="padding:5px;">\
<i class="folder icon"></i>\ <i class="angle double right icon"></i>\
<i class="angle double right icon" '+lIconSelectOnClick+'></i>\
<i class="angle double right icon" '+lIconTestOnClick+'></i>\
<i class="angle double up icon" '+lIconUpOnClick+'></i>\
<div class="content">\ <div class="content">\
<div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+inItem.title+'</div>\ <div class="header" '+lIconSelectOnClick+'>'+inItem.title+'</div>\
<div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>process_id:'+inItem.process_id+'; handle:'+inItem.handle+'; class_name: '+inItem.class_name+'; RECT:L'+inItem.rectangle.left+' T'+inItem.rectangle.top+' R'+inItem.rectangle.right+' B'+inItem.rectangle.bottom+'</div>\ <div class="description" '+lIconSelectOnClick+'>process_id:'+inItem.process_id+'; handle:'+inItem.handle+'; class_name: '+inItem.class_name+'; RECT:L'+inItem.rectangle.left+' T'+inItem.rectangle.top+' R'+inItem.rectangle.right+' B'+inItem.rectangle.bottom+'</div>\
<a class="ui tag label teal mini" '+lSubItemActionOnRightClick+'>Highlight</a>\
<a class="ui tag label teal mini" '+lSubItemActionOnClick+'>Expand</a>\
<a class="ui tag label teal mini" '+lIconUpOnClick+'>Mouse search</a>\
'+lSubListHTML+'\ '+lSubListHTML+'\
</div>\ </div>\
</div>' </div>'
@ -196,15 +214,15 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'GUIAction', url: 'GUIAction',
data: '{"functionName":"ElementGetChildElementList","argsArray":['+JSON.stringify(lSpecificationArray)+']}', data: '{"ModuleName":"GUI", "ActivityName":"UIOSelector_GetChildList_UIOList","ArgumentList":['+JSON.stringify(lSpecificationArray)+']}',
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
var lHTMLTree='<div class="ui list">' var lHTMLTree='<div class="ui list">'
var lResponseJSON=JSON.parse(lData) var lResponseJSON=JSON.parse(lData)
for (i=0;i<lResponseJSON.outputObject.length;i++) { for (i=0;i<lResponseJSON.Result.length;i++) {
var lElementId = mGlobal.GenerateUniqueID() var lElementId = mGlobal.GenerateUniqueID()
var lSubItemHandleId=lResponseJSON.outputObject[i].handle; var lSubItemHandleId=lResponseJSON.Result[i].handle;
var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" ' var lSubItemActionOnClick=' onclick="mGlobal.TreeLoadSubTree(\''+lElementId+'\');" '
var lSubItemActionOnRightClick=' oncontextmenu="mGlobal.ElementHighlightNew(\''+lElementId+'\');" ' var lSubItemActionOnRightClick=' oncontextmenu="mGlobal.ElementHighlightNew(\''+lElementId+'\');" '
var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" ' var lIconSelectOnClick=' onclick="mGlobal.TreeObjectInfoLoad(\''+lElementId+'\');" '
@ -218,21 +236,22 @@
<i class="angle double right icon" '+lIconTestOnClick+'></i>\ <i class="angle double right icon" '+lIconTestOnClick+'></i>\
<i class="angle double up icon" '+lIconUpOnClick+'></i>\ <i class="angle double up icon" '+lIconUpOnClick+'></i>\
<div class="content">\ <div class="content">\
<div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+lResponseJSON.outputObject[i].title+'</div>\ <div class="header" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>'+lResponseJSON.Result[i].title+'</div>\
<div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>process_id:'+lResponseJSON.outputObject[i].process_id+'; handle:'+lSubItemHandleId+'; class_name: '+lResponseJSON.outputObject[i].class_name+'; RECT:L'+lResponseJSON.outputObject[i].rectangle.left+' T'+lResponseJSON.outputObject[i].rectangle.top+' R'+lResponseJSON.outputObject[i].rectangle.right+' B'+lResponseJSON.outputObject[i].rectangle.bottom+'</div>\ <div class="description" '+lSubItemActionOnClick+lSubItemActionOnRightClick+'>process_id:'+lResponseJSON.Result[i].process_id+'; handle:'+lSubItemHandleId+'; class_name: '+lResponseJSON.Result[i].class_name+'; RECT:L'+lResponseJSON.Result[i].rectangle.left+' T'+lResponseJSON.Result[i].rectangle.top+' R'+lResponseJSON.Result[i].rectangle.right+' B'+lResponseJSON.Result[i].rectangle.bottom+'</div>\
</div>\ </div>\
</div>' </div>'
//Добавить информацию об элементе в словарь JS //Добавить информацию об элементе в словарь JS
mGlobal.GUIElement[lElementId]={}; mGlobal.GUIElement[lElementId]={};
mGlobal.GUIElement[lElementId]['GUISelectorLocal']=lResponseJSON.outputObject[i] mGlobal.GUIElement[lElementId]['GUISelectorLocal']=lResponseJSON.Result[i]
mGlobal.GUIElement[lElementId]['GUISelectorFull']=Array.from(lSpecificationArray); mGlobal.GUIElement[lElementId]['GUISelectorFull']=Array.from(lSpecificationArray);
mGlobal.GUIElement[lElementId]['GUISelectorFull'].push(lResponseJSON.outputObject[i]) mGlobal.GUIElement[lElementId]['GUISelectorFull'].push(lResponseJSON.Result[i])
} }
lHTMLTree+='</div>' lHTMLTree+='</div>'
$("#"+inElementId+" .content").append(lHTMLTree) $("#"+inElementId+" .content").append(lHTMLTree)
///Отображение ошибки ///Отображение ошибки
if (lResponseJSON.hasOwnProperty("Error")) { if (lResponseJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lResponseJSON.Error); mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -260,7 +279,7 @@
lHTMLList+='</div>' lHTMLList+='</div>'
$(".rpa-hierarchy").html(lHTMLList) $(".rpa-hierarchy").html(lHTMLList)
$(".rpa-object-tree .item").css("background-color",""); $(".rpa-object-tree .item").css("background-color","");
$("#"+inElementId).css("background-color","RGB(128,128,128)"); $("#"+inElementId).css("background-color","RGB(210,210,210)");
///Создать урезанную версию селектора ///Создать урезанную версию селектора
lTextAreaSpecificationArray=mGlobal.iSysClone(lSpecificationArray,true); lTextAreaSpecificationArray=mGlobal.iSysClone(lSpecificationArray,true);
for (var i = 0; i< lTextAreaSpecificationArray.length; i++) { for (var i = 0; i< lTextAreaSpecificationArray.length; i++) {
@ -290,17 +309,18 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'GUIAction', url: 'GUIAction',
data: '{"functionName":"ElementRunAction","argsArray":['+JSON.stringify(lSpecificationArray)+',"get_properties"]}', data: '{"ModuleName":"GUI", "ActivityName":"UIOSelectorUIOActivity_Run_Dict","ArgumentList":['+JSON.stringify(lSpecificationArray)+',"get_properties"]}',
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
var lHTMLList='<div class="ui relaxed divided list">' var lHTMLList='<div class="ui relaxed divided list" style="height:350px;overflow:scroll;">'
var lResponseJSON = JSON.parse(lData) var lResponseJSON = JSON.parse(lData)
///Ошибка ///Ошибка
if (lResponseJSON.hasOwnProperty("Error")) { if (lResponseJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lResponseJSON.Error); mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback);
} else { } else {
var lJSONData = JSON.parse(lData).outputObject var lJSONData = JSON.parse(lData).Result
var lSpecificationArray=Object.keys(lJSONData) var lSpecificationArray=Object.keys(lJSONData)
for (i=0;i<lSpecificationArray.length;i++) { for (i=0;i<lSpecificationArray.length;i++) {
var lItemKey = lSpecificationArray[i] var lItemKey = lSpecificationArray[i]
@ -332,7 +352,8 @@
var lResponseJSON = JSON.parse(lData) var lResponseJSON = JSON.parse(lData)
///Ошибка ///Ошибка
if (lResponseJSON["ErrorFlag"]==true) { if (lResponseJSON["ErrorFlag"]==true) {
mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage); mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -352,7 +373,7 @@
lDataJSON=JSON.parse(lData); lDataJSON=JSON.parse(lData);
///Показать ошибку, если таковая возникла ///Показать ошибку, если таковая возникла
if (lDataJSON["ErrorFlag"]==true) { if (lDataJSON["ErrorFlag"]==true) {
mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage); mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -365,13 +386,13 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'GUIAction', url: 'GUIAction',
data: '{"functionName":"ElementDrawOutlineNewFocus","argsArray":['+lSpecificationArray+']}', data: '{"ModuleName":"GUI","ActivityName":"UIOSelector_FocusHighlight","ArgumentList":['+lSpecificationArray+']}',
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
lDataJSON=JSON.parse(lData); lDataJSON=JSON.parse(lData);
if (lDataJSON.hasOwnProperty("Error")) { if (lDataJSON["ErrorFlag"]==true) {
mGlobal.ShowModal("GUI Error",lDataJSON.Error); mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -384,56 +405,22 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'GUIAction', url: 'GUIAction',
data: '{"functionName":"PywinautoExtElementsGetInfo","argsArray":['+lSpecificationArray+']}', data: '{"ModuleName":"GUI","ActivityName":"UIOSelector_Get_UIOInfoList","ArgumentList":['+lSpecificationArray+']}',
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
lDataJSON=JSON.parse(lData); lDataJSON=JSON.parse(lData);
if (Array.isArray(lDataJSON.outputObject)) { if (Array.isArray(lDataJSON.Result)) {
lHTMLData="" lHTMLData=""
for (i=0;i<lDataJSON.outputObject.length;i++) { for (i=0;i<lDataJSON.Result.length;i++) {
lHTMLData+='<p>'+ lHTMLData+='<p>'+
JSON.stringify(lDataJSON.outputObject[i])+ JSON.stringify(lDataJSON.Result[i])+
'</p>' '</p>'
} }
$(".openrpa-validate-result").html(lHTMLData) $(".openrpa-validate-result").html(lHTMLData)
} }
if (lDataJSON.hasOwnProperty("Error")) { if (lDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.Error); mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
}
},
dataType: "text"
});
}
mGlobal.Test = function (inElementId) {
//Подгрузка массива спецификаций
lSpecificationArray = mGlobal.GUIElement[inElementId].GUISelectorFull
///Загрузка данных
$.ajax({
type: "POST",
url: 'GUIAction',
data: '{"functionName":"ElementActionGetList","argsArray":['+JSON.stringify(lSpecificationArray)+']}',
success:
function(lData,l2,l3)
{
//lDataJSON=JSON.parse(lData.outputObject);
var lDataJSON=JSON.parse(lData)
var lDataKeyList=lDataJSON.outputObject
var lValueList=[]
for (var i = 0; i< lDataKeyList.length;i++) {
if (lDataKeyList[i].length>0)
if (lDataKeyList[i][0]!="_")
lValueList.push({'name':lDataKeyList[i],'value':lDataKeyList[i]})
}
///Установка значений в dropdown
$('.ui.dropdown.gui-action')
.dropdown({
values: lValueList
})
;
///Показать ошибку, если таковая возникла
if (lDataJSON.hasOwnProperty("Error")) {
mGlobal.ShowModal("GUI Error",lDataJSON.Error);
} }
}, },
dataType: "text" dataType: "text"
@ -446,13 +433,13 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'GUIAction', url: 'GUIAction',
data: '{"functionName":"ElementActionGetList","argsArray":['+lActionElementSpecification+']}', data: '{"ModuleName":"GUI","ActivityName":"UIOSelector_Get_UIOActivityList","ArgumentList":['+lActionElementSpecification+']}',
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
//lDataJSON=JSON.parse(lData.outputObject); //lDataJSON=JSON.parse(lData.outputObject);
lDataJSON=JSON.parse(lData) lDataJSON=JSON.parse(lData)
var lDataKeyList=lDataJSON.outputObject var lDataKeyList=lDataJSON.Result
var lValueList=[] var lValueList=[]
for (var i = 0; i< lDataKeyList.length;i++) { for (var i = 0; i< lDataKeyList.length;i++) {
if (lDataKeyList[i].length>0) if (lDataKeyList[i].length>0)
@ -466,8 +453,8 @@
}) })
; ;
///Показать ошибку, если таковая возникла ///Показать ошибку, если таковая возникла
if (lDataJSON.hasOwnProperty("Error")) { if (lDataJSONlDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.Error); mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -525,8 +512,8 @@
var lDataJSON=JSON.parse(lData) var lDataJSON=JSON.parse(lData)
$(".gui-code-list-run-result").html(lDataJSON.outputObject) $(".gui-code-list-run-result").html(lDataJSON.outputObject)
///Показать ошибку, если таковая возникла ///Показать ошибку, если таковая возникла
if (lDataJSON.hasOwnProperty("Error")) { if (lDataJSONlDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.Error); mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -562,15 +549,15 @@
$.ajax({ $.ajax({
type: "POST", type: "POST",
url: 'GUIAction', url: 'GUIAction',
data: '{"functionName":"ElementRunAction","argsArray":['+lActionElementSpecification+',"'+lActionName+'",'+lActionArgumentList+']}', data: '{"ModuleName":"GUI","ActivityName":"UIOSelectorUIOActivity_Run_Dict","ArgumentList":['+lActionElementSpecification+',"'+lActionName+'",'+lActionArgumentList+']}',
success: success:
function(lData,l2,l3) function(lData,l2,l3)
{ {
var lDataJSON=JSON.parse(lData) var lDataJSON=JSON.parse(lData)
$(".gui-result").html(lDataJSON.outputObject) $(".gui-result").html(lDataJSON.Result)
///Показать ошибку, если таковая возникла ///Показать ошибку, если таковая возникла
if (lDataJSON.hasOwnProperty("Error")) { if (lDataJSONlDataJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lDataJSON.Error); mGlobal.ShowModal("GUI Error",lDataJSON.ErrorMessage+" \nTraceback: "+lDataJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -613,8 +600,8 @@
///Прогрузить новое дерево ///Прогрузить новое дерево
mGlobal.ElementTree.fRender(lResponseJSON.Result); mGlobal.ElementTree.fRender(lResponseJSON.Result);
///Показать ошибку, если таковая возникла ///Показать ошибку, если таковая возникла
if (lResponseJSON.hasOwnProperty("Error")) { if (lResponseJSON["ErrorFlag"]) {
mGlobal.ShowModal("GUI Error",lResponseJSON.Error); mGlobal.ShowModal("GUI Error",lResponseJSON.ErrorMessage+" \nTraceback: "+lResponseJSON.ErrorTraceback);
} }
}, },
dataType: "text" dataType: "text"
@ -688,10 +675,10 @@
</div> </div>
<div class="eleven wide column"> <div class="eleven wide column">
<div class="ui input"> <div class="ui input">
<input class="openrpa-value-backend" type="text" placeholder="Backend" value="win32"> <input class="openrpa-value-backend" type="text" placeholder="Backend win32 | uia" value="win32">
</div> </div>
<button class="ui labeled icon button red" onclick=""> <button class="ui labeled icon button red" onclick="mGlobal.Actions.fRestartStudioServer();">
<i class="down icon"></i> <i class="icon redo alternate"></i>
Restart Studio Restart Studio
</button> </button>
</div> </div>
@ -706,30 +693,20 @@
</div> </div>
<div class="six wide column rpa-hierarchy" > <div class="six wide column rpa-hierarchy" >
<p>This example shows how to use lazy loaded images, a sticky menu, and a simple text container</p> <p>Select element in the tree to see hierarchy list</p>
</div> </div>
<div class="four wide column rpa-property-list" > <div class="four wide column rpa-property-list" >
</div> </div>
</div> </div>
<div class="row black"> <div class="row black">
<div class="two wide column"> <div class="three wide column">
<button class="ui button grey labeled icon mini" onclick="mGlobal.GUIRefreshTree()"> <button class="ui button grey labeled icon mini" onclick="mGlobal.GUIRefreshTree()">
<i class="up refresh icon"></i> <i class="up refresh icon"></i>
Refresh tree Refresh tree
</button> </button>
</div> </div>
<div class="two wide column"> <div class="three wide column">
<button class="ui button grey labeled icon mini">
<i class="up arrow icon"></i>
From
</button>
</div>
<div class="two wide column">
<button class="ui button grey labeled icon mini">
<i class="down arrow icon"></i>
To
</button>
</div> </div>
<div class="ten wide column"> <div class="ten wide column">
</div> </div>

Loading…
Cancel
Save