UI Automation Partie 2 en Python

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

Préparation

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()

Essayez de calculer automatiquement avec une calculatrice

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.

Comment vérifier l'élément d'automatisation

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

UI Automation Partie 2 en Python
Automatisation de l'interface utilisateur avec Python
Translocation de fichiers CSV avec Python Partie 1
[Automatisé avec python! ] Partie 1: fichier de configuration
[Automatisé avec python! ] Partie 2: Fonctionnement des fichiers
Quadtree en Python --2
QGIS + Python Partie 2
Python en optimisation
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Création d'interface graphique en python à l'aide de tkinter partie 1
Modulation et démodulation AM avec Python Partie 2
Méta-analyse en Python
Unittest en Python
QGIS + Python Partie 1
Époque en Python
Discord en Python
Dessiner un cœur avec Python Partie 2 (SymPy Edition)
Allemand en Python
DCI en Python
tri rapide en python
N-Gram en Python
Programmation avec Python
Plink en Python
Constante en Python
FizzBuzz en Python
Sqlite en Python
Python: grattage partie 1
Étape AIC en Python
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Quad-tree en Python
Réflexion en Python
Chimie avec Python
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
Python3 commence la partie 1
Python: grattage, partie 2
Aplatir en python
[Automation] Extraire le tableau en PDF avec Python
[Python] Automatisation implémentée pour la copie de fichiers Excel
Utilisez Python dans votre environnement depuis Win Automation
Se débarrasser des images DICOM avec Python Partie 2
Translocation de fichiers CSV en Python Partie 2: Mesure des performances