Что нового

UIAutomate - автоматизация нестандартных элементов GUI

rivega

Новичок
Сообщения
45
Репутация
1
У меня на стационарном ПК все получилось, на ноутбуке нет-скрипт(с бесконечным ожиданием) просто ждет загрузки страницы(хотя она уже загрузилась)
Windows и там и там 7, Сhrome на ПК 39.0.2171.95 dev-m, а на ноуте 40.0.2214.91 m.
Может от этого зависеть?
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
rivega [?]
Может от этого зависеть?
Сложно сказать... Я проверяю на стационаре Win7 x86, Chrome 40.0.2214.91 m. Проблем с кнопкой не наблюдаю.
Попробуйте подождать чего-нибудь другого - там много разных элементов (телефон, кнопка счёта, поле документа)
Код:
Send("iqoption.ru{enter}")
; ожидание загрузки
$UIA_DefaultWaitTime = 0
_UIA_WaitControlTypeElement($oParent, "UIA_TextControlTypeId", "8 800 333 47 55")
;~ _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Открыть счет", Default, True)
;~ _UIA_WaitControlTypeElement($oParent, "UIA_DocumentControlTypeId", "Брокер бинарных опционов", Default, True)
; нажатие кнопки "Вход"
_UIA_ElementDoDefaulAction(_UIA_GetControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Войти", Default, True))
 

rivega

Новичок
Сообщения
45
Репутация
1
Хорошо, спасибо. Буду разбираться.


Добавлено:
Сообщение автоматически объединено:

Есть наблюдение что на ноутбуке у меня хром был запущен и работал(открыто несколько вкладок)....если запускаю скрипт то вероятно хром открывается не в режиме "--force-renderer-accessibility"

Если закрываю хром полностью и запускаю скрипт все срабатывает как надо.


Вопрос- пароль и логин вводятся как будто их по букве с клавиатуры вводят(медленно) и между вводом пароля и логина заметная пауза. Это нормальная работа или можно ускорить?(или от ПК зависит)
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
rivega [?]
по букве с клавиатуры вводят(медленно)
Chrome не поддерживает прямую установку текста в эти поля. Поэтому варианта два:
1. Ускорить нажатия клавиш в Send()
Код:
Opt("SendKeyDownDelay", 0)
Opt("SendKeyDelay", 0)
2. Использовать буфер обмена
Код:
; регистрация
_UIA_WaitControlTypeElement($oParent, "UIA_TextControlTypeId", "Авторизация")
_UIA_ElementSetFocus(_UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "E-mail"))
;~ Send("[email protected]")
ClipPut("[email protected]")
Send("+{ins}")
_UIA_ElementSetFocus(_UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "Пароль"))
;~ Send("password")
ClipPut("password")
Send("+{ins}")
_UIA_ElementDoDefaulAction(_UIA_GetControlTypeElement($oParent, "UIA_CheckBoxControlTypeId", " Запомнить меня"))
_UIA_ElementDoDefaulAction(_UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Войти"))
 

rivega

Новичок
Сообщения
45
Репутация
1
InnI сказал(а):
Обновление до версии 1.1:
- добавлена функция _UIA_ElementGetPreviousNext() для поиска предыдущего и следующего элементов того же уровня
- добавлена возможность вывода ошибок в консоль: глобальный переключатель $UIA_ConsoleWriteError (включён по умолчанию)
- в CUIAutomation2.au3 добавлены директивы #Au3Stripper_Off и #Au3Stripper_On для идентификаторов свойств и типов

Есть ли возможность сделать не большой пример по функции _UIA_ElementGetPreviousNext()?



Код:
$oPreviosnext=_UIA_ElementGetPreviousNext($i)																 $Previos=_UIA_ElementGetPropertyValue($oPreviosnext[0],"Name")
MsgBox("","", $Previos)


что я не правильно делаю?
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
rivega [?]
что я не правильно делаю?
Если $i - это элемент (объект), то всё правильно. В противном случае в консоле SciTE должна быть ошибка: _UIA_ElementGetPreviousNext : параметр не является объектом.

пример по функции _UIA_ElementGetPreviousNext()
Предыдущий/следующий элемент для пункта меню "Вид" всплывающего меню рабочего стола Windows 7
Код:
#include "UIAutomate.au3"

WinMinimizeAll()
MouseClick("right", 0, 0, 1, 0)

$oParent = _UIA_GetElementFromHandle(WinWait("[class:#32768]"))
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_MenuItemControlTypeId", "Вид")
If Not IsObj($oElement) Then Exit

$oPreviousNext = _UIA_ElementGetPreviousNext($oElement)

If IsObj($oPreviousNext[0]) Then
  ConsoleWrite(_UIA_ElementGetPropertyValue($oPreviousNext[0], "Name") & @CRLF)
Else
  ConsoleWrite("= Предыдущий элемент отсутствует =" & @CRLF)
EndIf

If IsObj($oPreviousNext[1]) Then
  ConsoleWrite(_UIA_ElementGetPropertyValue($oPreviousNext[1], "Name") & @CRLF)
Else
  ConsoleWrite("= Следующий элемент отсутствует =" & @CRLF)
EndIf

WinMinimizeAllUndo()
 

rivega

Новичок
Сообщения
45
Репутация
1
На главной странице сайта все получается))

а вот в всплывающем окне нет....
Обратится к элементу могу, обьект получаю, действие выполняется....а предыдущий и следующий обьекты не находит....
Код:
#include "UIAutomate.au3"

WinMinimizeAll()
Opt("WinTitleMatchMode", 2)
Run(@ProgramFilesDir & "\Google\Chrome\Application\chrome.exe --force-renderer-accessibility")
$hWnd = WinWait(" - Google Chrome", "", 5)
If Not $hWnd Then Exit

$oParent = _UIA_GetElementFromHandle($hWnd)
$oElement = _UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", "Адресная строка и строка поиска")
_UIA_ElementMouseClick($oElement)
Send("iqoption.ru{enter}")
$oElement = _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Войти", Default, True, 0) ; ожидание загрузки
_UIA_ElementDoDefaulAction($oElement)
Sleep(2000)
$oElement1=_UIA_GetControlTypeElement($oParent, "UIA_CheckBoxControlTypeId", " Запомнить меня")

If  IsObj($oElement1) Then
   MsgBox("","","нашли обьект-запомнить меня")
endif
$oPreviousNext = _UIA_ElementGetPreviousNext($oElement1)

If IsObj($oPreviousNext[0]) Then
  ConsoleWrite(_UIA_ElementGetPropertyValue($oPreviousNext[0], "Name") & @CRLF)
Else
  ConsoleWrite("= Предыдущий элемент отсутствует =" & @CRLF)
EndIf

If IsObj($oPreviousNext[1]) Then
  ConsoleWrite(_UIA_ElementGetPropertyValue($oPreviousNext[1], "Name") & @CRLF)
Else
  ConsoleWrite("= Следующий элемент отсутствует =" & @CRLF)
EndIf

WinMinimizeAllUndo()


дальше на сайте появляется всплывающее окно(по типу окна регистрации) и из него требуется считывать цифры, на прямую обратится не могу, тк не знаю name(как раз те цифры которые нужно считать........)(до него есть TextcontroltypeID, после него ButtoncontroltypeID)
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
rivega [?]
предыдущий и следующий обьекты не находит
Потому что их нет. В данной функции предыдущий/следующий - это элементы одного уровня вложенности. Например (см. вложение). Для поля "Пароль" предыдущим будет поле "E-mail", а следующим - пустой элемент. Этот пустой элемент является родительским по отношению к флажку "Запомнить меня", а следующим для него будет пустой элемент, который является родителем для кнопки "Войти". Но ни у флажка ни у кнопки нет предыдущего/следующего - они единственные в своём уровне вложенности.

цифры которые нужно считать
Если Inspect ни в одном свойстве эти цифры не отображает, то считать их не получится.

Не обязательно искать элемент по имени. Можно искать почти по любому другому свойству, которые отображает Inspect. Например, поле для ввода пароля можно найти так
Код:
_UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", True, "IsPassword")
Попробуйте найти такое свойство, которое отличает нужный вам элемент от других.

Неблагодарное это дело - Chrome автоматизировать :stars:
 

Вложения

  • scr.jpg
    scr.jpg
    188.6 КБ · Просмотры: 170

rivega

Новичок
Сообщения
45
Репутация
1
Проблема в том что кроме имени ничем не отличается((((


Если не Chrome...то в какую сторону смотреть?
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
rivega [?]
кроме имени ничем не отличается
Уверен, что размером и/или положением точно отличается. К тому же в имени может быть уникальный символ, например %, которого нет у других элементов. Можно ещё найти все элементы с одинаковым свойством-значением и по индексу полученного массива обратиться к нужному (если они всегда создаются в определённом порядке).

в какую сторону смотреть
В сторону Internet Explorer. Либо самостоятельно разбирать POST и GET запросы. Примеров на форуме много.
 

rivega

Новичок
Сообщения
45
Репутация
1
Положением да, отличается, но обращаться по положению....мне кажется не очень правильно(размер окна изменился и уже не обратимся)
Что ищу: запись вида "$0.00" (так оно отображается на сайте во всплывающем окне), инспект распознает символ $ как прямоугольник.
На основной странице сайта прокатывает поиск по части имени ".", во всплывающем окне, если ищу по ".", то возвращает имя с основной страницы((.
Поиск всех сейчас попробую...
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
rivega [?]
во всплывающем окне
Если это такое же окно, как и регистрация, то оно только выглядит, как всплывающее. На самом деле оно находится в общем дереве объектов страницы, но, вероятно, ниже. А так как поиск производится до первого совпадения, то вы получаете объект самой страницы, а не этого "окна".


Добавлено:
Сообщение автоматически объединено:

Посмотрите хороший пример в этой теме: Ответ #13. Там coolpunk "выпрямляет" дерево в одномерный массив. Затем, перебирая элементы, находит нужный и от него отсчитывает необходимый "предыдущий/следующий".
На примере вашего окна регистрации таким образом можно найти элементы относительно флажка "Запомнить меня": поле пароля [$i - 2] и кнопку входа [$i + 2]
Код:
#include "UIAutomate.au3"
Opt("WinTitleMatchMode", 2)

Run(@ProgramFilesDir & "\Google\Chrome\Application\chrome.exe www.iqoption.ru --force-renderer-accessibility")
$hWnd = WinWait(" - Google Chrome", "", 5)
If Not $hWnd Then Exit

$oParent = _UIA_GetElementFromHandle($hWnd)
$oElement = _UIA_WaitControlTypeElement($oParent, "UIA_ButtonControlTypeId", "Войти", Default, True, 20)
_UIA_ElementDoDefaulAction($oElement)
_UIA_WaitControlTypeElement($oParent, "UIA_TextControlTypeId", "Авторизация")

$aAllElements = _UIA_FindAllElements($oParent)
For $i = 1 To $aAllElements[0]
  If _UIA_ElementGetPropertyValue($aAllElements[$i], "Name") = " Запомнить меня" Then
    ConsoleWrite(_UIA_ElementGetPropertyValue($aAllElements[$i - 2], "Name") & @CRLF)
    ConsoleWrite(_UIA_ElementGetPropertyValue($aAllElements[$i + 2], "Name") & @CRLF)
    ExitLoop
  EndIf
Next
 

rivega

Новичок
Сообщения
45
Репутация
1
Не обязательно искать элемент по имени. Можно искать почти по любому другому свойству, которые отображает Inspect. Например, поле для ввода пароля можно найти так
Код: AutoIt [Выделить]
_UIA_GetControlTypeElement($oParent, "UIA_EditControlTypeId", True, "IsPassword")

Попробуйте найти такое свойство, которое отличает нужный вам элемент от других.

Вот вопрос возник....эта функция найдет первое подходящее под условие? можно сразу по нескольким свойствам искать?
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
rivega [?]
сразу по нескольким свойствам
Интерфейс такое предусматривает, но в UDF данный функционал не реализован. В качестве аналога сделана функция _UIA_FindElementsInArray(). Другими словами, сначала вы ищете элементы с использованием _UIA_FindAllElements(), которая предполагает одну пару свойство-значение. Затем фильтруете полученный массив через _UIA_FindElementsInArray(), которая тоже ищет одну пару свойство-значение, но уже с возможностью частичного совпадения значения. После этого, при необходимости, опять фильтруете уже частично отсеянный массив через _UIA_FindElementsInArray() и так до тех пор, пока не останутся только нужные элементы.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
InnI
А чего бы вам не реализовать PropertyCondition, это же не сложно. И в функции поиска тогда можно передавать указатель на условия поиска.
Как то так
Код:
Func _UIA_PropertyCondition($PropertyId, $PropertyValue)
	Local $pCondition
	$objUIAutomation.CreatePropertyCondition($PropertyId, $PropertyValue, $pCondition)
	If Not $pCondition Then Return SetError(1, @error, 0)
	Return SetError(0, 0, $pCondition)
EndFunc
Func _UIA_AndCondition(ByRef $pCondition_1, ByRef $pCondition_2)
	If Not ($pCondition_1 Or $pCondition_2) Then Return SetError(1, 0, 0)
	Local $pCondition
	$objUIAutomation.CreateAndCondition($pCondition_1, $pCondition_2, $pCondition)
	If Not $pCondition Then Return SetError(2, @error, 0)
	Return SetError(0, 0, $pCondition)
EndFunc   ;==>_UIA_AndCondition
Func _UIA_FirstElement_ByCondition(ByRef $oUIElement, $pCondition)
	If Not (IsObj($oUIElement) Or $pCondition) Then Return SetError(1, 0, 0)
	Local $pUIElement
	$oUIElement.FindFirst($TreeScope_Subtree, $pCondition, $pUIElement)
	If Not $pUIElement Then Return SetError(2, @error, 0)
	Local $oUIElementOut = ObjCreateInterface($pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement)
	If Not IsObj($oUIElementOut) Then Return SetError(3, 0, 0)
	Return SetError(0, 0, $oUIElementOut)
EndFunc   ;==>_UIA_GetFirstElement_ByCondition



Добавлено:
Сообщение автоматически объединено:

К примеру, найти кнопку с именем закрыть можно будет так:
Код:
Local $p1 = _UIA_PropertyCondition($UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId)
	Local $p2 = _UIA_PropertyCondition($UIA_NamePropertyId, 'Закрыть')
	Local $p = _UIA_AndCondition($p1, $p2)
	Local $close_button = _UIA_FirstElement_ByCondition($oElement, $p)
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
inververs [?]
чего бы вам не реализовать
Не было необходимости. _UIA_FindElementsInArray() прекрасно заменяет данный функционал. Возможно, проигрывает в скорости, зато проще в понимании.

это же не сложно
Реализовать не сложно. Сложно объяснить пользователю, что такое Condition и как им пользоваться. А если делать, то нужно и OR и NOT добавлять. К тому же данные должны быть строго типизированы, что непривычно для AutoIt. Нет поддержки частичного совпадения (а для имён очень часто это необходимо). И вот осознав всё это я сделал простенькую фильтрацию через _UIA_FindElementsInArray().

Но, раз возник такой интерес, то подумаю над добавлением данного функционала.
 

inververs

AutoIT Гуру
Сообщения
2,135
Репутация
465
InnI понятно, дело конечно ваше, если будет желание можете реализовать, вдруг кому то понадобится.
 
Автор
I

InnI

AutoIT Гуру
Сообщения
4,958
Репутация
1,448
inververs [?]
если будет желание
Не то, чтобы нет желания... Скорее нет понимания необходимости дублирования функционала. Тем более дублирования с усложнением для пользователя. Потом могут быть вопросы вроде "Если это можно сделать при помощи одной этой функции, зачем нужны вот эти три?" :scratch:
 
Верх