Poursuite de UI Automation with Python Cette fois, je clique sur le bouton.
ControlPattern Les contrôles qui prennent en charge l'automatisation de l'interface utilisateur fournissent une interface fonctionnelle sous la forme d'un modèle de contrôle. Dans le cas des boutons, InvokePattern est pris en charge, donc si vous obtenez ceci et appelez Invoke (), qui est une méthode d'InvokePattern, vous pouvez réaliser un clic sur le bouton. Vous pouvez savoir si un AutomationElement prend en charge InvokePattern en regardant IsInvokePatternAvailable de l'élément.
def click_button(element):
"""IUIAutomationInvokePattern pour l'élément spécifié.Invoke()Cliquez avec
Ne rien faire si la propriété IsInvokePatternAvailable de l'élément spécifié est False
"""
isClickable = element.GetCurrentPropertyValue(UIA_IsInvokePatternAvailablePropertyId)
if isClickable == True:
ptn = element.GetCurrentPattern(UIA_InvokePatternId)
ptn.QueryInterface(IUIAutomationInvokePattern).Invoke()
Les détails sont ci-dessous. UI Automation Control Patterns Overview http://msdn.microsoft.com/en-us/library/ee671194(v=vs.85).aspx#controlpatterninterfaces
La version .NET a une traduction japonaise (bien qu'il s'agisse d'une traduction automatique). Présentation du modèle de contrôle d'automatisation de l'interface utilisateur http://msdn.microsoft.com/ja-jp/library/ms752362(v=vs.110).aspx
Avant de cliquer sur le bouton, assemblez-le, y compris les précédents.
uiauti.py
# -*- coding: utf-8 -*-
"""
uiautil : UI Automation utility
Cela ne fonctionne que sur Windows.
"""
import comtypes
from comtypes import CoCreateInstance
import comtypes.client
from comtypes.gen.UIAutomationClient import *
__uia = None
__root_element = None
def __init():
global __uia, __root_element
__uia = CoCreateInstance(CUIAutomation._reg_clsid_,
interface=IUIAutomation,
clsctx=comtypes.CLSCTX_INPROC_SERVER)
__root_element = __uia.GetRootElement()
def get_window_element(title):
"""Obtient l'AutomationElement de la fenêtre spécifiée dans le titre
Si le titre est dupliqué sur le bureau, renvoyez le premier trouvé
"""
win_element = __root_element.FindFirst(TreeScope_Children,
__uia.CreatePropertyCondition(
UIA_NamePropertyId, title))
return win_element
def find_control(base_element, ctltype):
"""Possède l'ID de type de contrôle spécifié dans le sous-arbre d'élément de base spécifié
Renvoie une séquence d'éléments
"""
condition = __uia.CreatePropertyCondition(UIA_ControlTypePropertyId, ctltype)
ctl_elements = base_element.FindAll(TreeScope_Subtree, condition)
return [ ctl_elements.GetElement(i) for i in range(ctl_elements.Length) ]
def lookup_by_name(elements, name):
"""Éléments avec la propriété Name spécifiée à partir de la séquence d'éléments spécifiée
Renvoie le premier d'entre eux.
Renvoie None s'il n'y a pas de hit
"""
for element in elements:
if element.CurrentName == name:
return element
return None
def lookup_by_automationid(elements, id):
"""Possède la propriété AutomationId spécifiée à partir de la séquence d'éléments spécifiée
Renvoie le premier des éléments.
Renvoie None s'il n'y a pas de hit
"""
for element in elements:
if element.CurrentAutomationId == id:
return element
return None
def click_button(element):
"""IUIAutomationInvokePattern pour l'élément spécifié.Invoke()Cliquez avec
Ne rien faire si la propriété IsInvokePatternAvailable de l'élément spécifié est False
"""
isClickable = element.GetCurrentPropertyValue(UIA_IsInvokePatternAvailablePropertyId)
if isClickable == True:
ptn = element.GetCurrentPattern(UIA_InvokePatternId)
ptn.QueryInterface(IUIAutomationInvokePattern).Invoke()
if __name__ == '__main__':
__init()
Testez en exécutant uiautil.py sur IDLE. Démarrez la calculatrice et décidez de la propriété qui identifie chaque bouton. Cette fois, j'utiliserai AutomationId.
>>>
>>> win = get_window_element('calculatrice')
>>> btns = find_control(win, UIA_ButtonControlTypeId)
>>> for b in btns: print btns.index(b), b.CurrentName, b.CurrentAutomationId
0 Effacer la mémoire 122
1 espace arrière 83
2 7 137
3 4 134
4 1 131
5 0 130
<Omission>
21 soustraction 94
22 ajout 93
23 Soustraction de la mémoire 126
24 racine carrée 110
25% 118
26 Inverse 114
27e année 121
28 Minimiser
29 Agrandir
30 fermer
>>> def one_plus_one():
btn_1 = lookup_by_automationid(btns, "131")
btn_plus = lookup_by_automationid(btns, "93")
btn_equal = lookup_by_automationid(btns, "121")
click_button(btn_1)
click_button(btn_plus)
click_button(btn_1)
click_button(btn_equal)
>>> one_plus_one()
>>>
2 était affiché sur la calculatrice!
Cette fois, j'utilise Windows 8.1 Pro (x64), mais comme indiqué ci-dessous, AutomaionId ne semble pas être garanti entre les versions et les versions, donc AutomaionId peut être différent sur d'autres systèmes d'exploitation tels que Windows 7. En outre, il existe des cas où AutomationId n'est pas affecté comme dans la minimisation et la maximisation.
À partir de la description de UIA_AutomationIdPropertyId dans http://msdn.microsoft.com/en-us/library/ee684017(v=vs.85).aspx.
Although support for AutomationId is always recommended for better automated testing support, this property is not mandatory. Where it is supported, AutomationId is useful for creating a test automation script that runs regardless of the UI language. Clients should make no assumptions regarding the AutomationId values exposed by other applications. AutomationId is not guaranteed to be stable across different releases or builds of an application.
Il semble que la base de la spécification d'AutomationElement dépend de la création de l'application à exploiter. Par conséquent, vous souhaiterez connaître à l'avance les propriétés des éléments d'automatisation de l'application cible de l'opération. Comme dans l'exemple ci-dessus, la méthode pour frapper réellement AutomationElement un par un est gênante, j'ai donc recherché un outil qui pourrait être facilement étudié. Il y avait.
C'est également dans le SDK Windows depuis le début.
Vous pouvez utiliser Inspect.exe et Visual UI Automation Verify inclus dans le SDK Windows pour vérifier les propriétés de chaque élément dans l'arborescence AutomationElement sous le bureau.
Windows Software Development Kit (SDK) for Windows 8.1 http://msdn.microsoft.com/en-us/windows/desktop/bg162891.aspx
Lorsque vous installez le SDK Windows, vous verrez ce qui suit (xxx est x86, x64, arm. La version peut différer selon la version du SDK que vous avez installée). Aucun Visual Studio requis.
%ProgramFiles%\Windows Kits\8.1\bin\xxx
Pour plus de détails sur l'utilisation de l'outil, voir ci-dessous. Inspect http://msdn.microsoft.com/en-us/library/windows/desktop/dd318521(v=vs.85).aspx
Visual UI Automation Verify http://msdn.microsoft.com/en-us/library/windows/desktop/jj160544(v=vs.85).aspx
Recommended Posts