Biblioteka Python — është një projekt open source për automatizimin e aplikacioneve GUI desktop në Windows. Gjatë dy viteve të fundit, ajo ka sjellë karakteristika të reja të mëdha:
- Mbështetje për teknologjinë MS UI Automation. Ndërfaqja është e njëjtë, dhe tani mbështeten: WinForms, WPF, Qt5, Windows Store (UWP) etj. — pothuajse gjithçka që është në Windows.
- Sistemi i backend-ëve/plug-in-eve (aktualisht ka dy nën kapak: defaul
"win32"dhe të riun"uia"). Më pas lëvizim me qetësi drejt multiplatformës. - Huket Win32 për miun dhe tastierën (të nxehta në stilin e pyHook).
Po ashtu, do të bëjmë një shqyrtim të vogël të asaj që ekziston në open source për automatizimin desktop (pa pretendime për krahasim të rëndësishëm).
Ky artikull është pjesërisht një përkthim i ligjëratës në konferencën SQA Days 20 në Minsku ( dhe ), pjesërisht versioni shqiptar i për pywinauto.
- Qasjet kryesore
- Teknologjitë kryesore të aksesueshmërisë për desktop
Të fillojmë me një përmbledhje të shkurtër të open source në këtë fushë. Për aplikacionet GUI desktop, gjithçka është pak më e komplikuar se për webin, që ka Selenium. Ja qasjet kryesore:
Metoda e koordinatave
Hardkodojmë pikët e klikimeve, duke shpresuar në goditje të suksesshme.
[+] Multiplatformë, e lehtë për t'u realizuar.
[+] E lehtë për të bërë regjistrimin e provave "record-replay".
[-] Më i paqëndrueshëm ndaj ndryshimeve të cilësisë së ekranit, temave, shkrimtarëve, madhësive të dritareve etj.
[-] Kërkon përpjekje të mëdha për mbështetje, shpesh më e thjeshtë të rikrijohen provat nga fillimi ose të testohen manualisht.
[-] Automatizon vetëm veprimet, për verifikimin dhe nxjerrjen e të dhënave ka metoda të tjera.
Instrumente (multiplatformë): , , dhe shumë të tjera. Në përgjithësi, instrumentet më të avancuara përfshijnë këtë funksionalitet (jo gjithmonë në mënyrë multiplatformë).
Në të vërtetë, metoda e koordinatave mund të plotësojë qasjet e tjera. Për shembull, për grafikën e personalizuar mund të klikoni në koordinata relative (nga këndi i sipërm majtë të dritares/elementit dhe jo të gjithë ekranit) — zakonisht kjo është mjaft e besueshme, veçanërisht nëse merrni parasysh gjatësi/gjerësi të gjithë elementit (atëherë edhe ndryshimi i cilësisë së ekranit nuk do ta pengojë).
Një opsion tjetër: të ndahen për testime vetëm një makinë me konfigurime të qëndrueshme (nuk është ndër-platformë, por në disa raste është e përshtatshme).
Njohja e imazheve referuese
[+] Ndër-platformë
[+-] Relativisht i besueshëm (më i mirë se metoda koordinatore), por ende kërkon truqe.
[-+] Relativisht i ngadaltë, pasi kërkon burime CPU për algoritmet e njohjes.
[-] Për njohjen e tekstit (OCR), si rregull nuk bëhet fjale => nuk mund të nxirren të dhëna tekstuale. Sa më duket, zgjidhjet ekzistuese OCR nuk janë shumë të besueshme për këtë lloj detyrash dhe nuk kanë përdorim të gjerë (mirëpritje në komente, nëse kjo tashmë nuk është e vërtetë).
Mjetet: , (përdorues i Sikuli, në Python të pastër), .
Teknologji të aksesueshmërisë
[+] Metoda më e besueshme, pasi lejon kërkimin sipas tekstit, pavarësisht se si është vizatuar nga sistemi ose framework-u.
[+] Lejon nxjerrjen e të dhënave tekstuale => më e thjeshtë për të verifikuar rezultatet e testeve.
[+] Si rregull, më e shpejtë, pasi pothuajse nuk konsumon burime CPU.
[-] E vështirë për të krijuar një mjet ndër-platformë: të gjitha bibliotekat open-source mbështesin një ose dy teknologji accessible. Askush nuk mbështet plotësisht Windows/Linux/MacOS, përveç atyre të paguara si TestComplete, UFT ose Squish.
[-] Jo gjithmonë një teknologji e tillë është në dispozicion. Për shembull, testimi i ekranit ngarkues brenda VirtualBox-it — këtu nuk është e mundur pa njohjen e imazheve. Por në shumë raste klasike, megjithatë, qasja accessible është e aplikueshme. Për këtë do të flasim më vonë.
Mjetet: në C#, në C# (përdorues i Selenium), në C# (përdorues i Appium), , (i përshtatshëm me LDTP), , në Ruby, (Projekti i Testimit të Desktop-it Linux) dhe versioni i tij për Windows .
LDTP — ndoshta është mjeti i vetëm open-source ndër-platformë (në fakt një familje bibliotekash) bazuar në teknologjitë accessible. Megjithatë, ai nuk është shumë i popullarizuar. Unë vetë nuk e kam përdorur, por sipas komenteve, ndërfaqja e tij nuk është më e përshtatshme. Nëse ka komente pozitive, ju lutem ndani ato në komente.
Backdoor për testim (a.k.a. biçikleta e brendshme)
Për aplikacionet ndër-platformë, vetë zhvilluesit shpesh krijojnë një mekanizëm të brendshëm për të siguruar testueshmërinë. Për shembull, ata krijojnë një server TCP shërbimi në aplikacion, testet lidhen me të dhe dërgojnë komanda tekstuale: çfarë të klikojnë, nga ku të marrin të dhëna etj. E besueshme, por jo universale.
Teknologjitë kryesore të aksesueshmërisë për desktop
I njohuri Win32 API
Shumica e aplikacioneve Windows, të shkruara para shpërthimit të WPF dhe më pas Windows Store, janë ndërtuar në njëfarë mënyre mbi Win32 API. Në veçanti, MFC, WTL, C++ Builder, Delphi, VB6 — të gjitha këto mjete përdorin Win32 API. Edhe Windows Forms — në masë të madhe është në përputhje me Win32 API.
Mjetet: (ngjason me VB) dhe Python mbështetje , (gjuhë e vet, ka ndërfaqen IDispatch COM), (Python), (Ruby), (Ruby).
Microsoft UI Automation
Avantazhi kryesor: teknologjia MS UI Automation mbështet shumicën dërrmuese të aplikacioneve GUI në Windows me përjashtime të rralla. Problemi: nuk është shumë më e lehtë për t'u mësuar sesa Win32 API. Përndryshe, askush nuk do të krijonte mbështetje për të.
Faktikisht, ky është një set i ndërfaqeve COM të personalizuara (në masë të madhe, UIAutomationCore.dll), si dhe ka një mbështetje .NET në formën e namespace System.Windows.Automation. Ajo, për fat të keq, ka një defekt të ngjashëm, për shkak të të cilit disa elementë UI mund të kalojnë. Prandaj, është më mirë të përdorni drejtpërdrejt UIAutomationCore.dll (nëse keni dëgjuar për UiaComWrapper në C#, kjo është ajo).
Lloje të ndërfaqeve COM:
(1) IUknown bazik — "burimi i të gjitha të këqijave". Më i ulët, aspak miqësor për përdoruesin.
(2) IDispatch dhe pasardhësit (për shembull, Excel.Application), të cilat mund të përdoren në Python përmes paketës win32com.client (pjesë e pyWin32). Variant më i përshtatshëm dhe më tërheqës.
(3) Ndërfaqet e personalizuara, me të cilat punon paketa e jashtme Python .
Mjetet: në C#, 0.6.0+, në C#, (ata kanë kodin burimor të mbështjelljeve C rreth UIAutomationCore.dll të paçmuar), në Ruby.
AT-SPI
Megjithëse pothuajse të gjitha sistemet operative të familjes Linux janë ndërtuar mbi X Window System (në Fedora 25 "x" u zëvendësuan nga Wayland), "x" lejon vetëm operimin me dritaret e nivelit të lartë dhe miun / tastierën. Për analizë të hollësishme të butonave, kutive të listës dhe etj. — ekziston teknologjia AT-SPI. Menaxherët më të njohur të dritareve kanë një demon regjistrimi AT-SPI, i cili siguron një GUI të automatizuar për aplikacionet (të paktën mbështeten Qt dhe GTK).
Mjetet: .
pyatspi2, sipas mendimit tim, ka shumë varësi si PyGObject. Teknologjia vetë është e disponueshme në formën e një biblioteke dinamike të zakonshme libatspi.so. Ajo ka . Për bibliotekën pywinauto, planifikohet të realizojmë mbështetje AT-SPI në këtë mënyrë: përmes ngarkimit të libatspi.so dhe modulit ctypes. Ka një problem të vogël vetëm në përdorimin e versionit të duhur, sepse për aplikacionet GTK+ dhe Qt ato janë pak të ndryshme. Pritet lëshimi i pywinauto 0.7.0 me mbështetje të plotë për Linux në gjysmën e parë të vitit 2018.
Apple Accessibility API
Në MacOS ka një gjuhë automatizimi të Apple, AppleScript. Për të realizuar diçka të ngjashme në Python, padyshim, duhet të përdoren funksione nga ObjectiveC. Duke filluar, duket, që nga MacOS 10.6, në Python e parainstaluar përfshihet paketa pyobjc. Kjo gjithashtu do të lehtësojë listën e varësive për mbështetje të ardhshme në pywinauto.
Mjetet: Përveç gjuhës AppleScript, vlen të përmendet , e njohur gjithashtu si pyatom. Ai është në përputhje me ndërfaqen e LDTP, por gjithashtu është një bibliotekë e pavarur. Ka një , shkruar nga studenti im. Ka një problem të njohur: funksionet me kohë të ndjeshme (metodat waitFor*) nuk funksionojnë. Por, në përgjithësi, është një gjë e mirë.
Si të filloni të punoni me pywinauto
Së pari, është e rëndësishme të armatosni me një inspektor të objekteve GUI (atë që e quajnë Spy tool). Ai do të ndihmojë për të studiuar aplikacionin nga brenda: si është struktura e hierarkisë së elementeve, cilat prona janë të disponueshme. Inspektorët më të njohur të objekteve janë:
- Spy++ — përfshihet në paketimin e Visual Studio, përfshirë Edicioni Express ose Community. Përdor API-në Win32. Njëkloni i njohur i tij është AutoIt Window Info.
- Inspect.exe — përfshihet në Windows SDK. Nëse e keni instaluar, atëherë në Windows 64-bit mund ta gjeni në dosjen
C:Program Files (x86)Windows Kitsbinx64. Në vetë inspektorin, duhet të zgjidhni modin UI Automation në vend të MS AA (Active Accessibility, paraardhës i UI Automation).
Pas inspektimit të aplikacionit nga brenda, zgjidhni backend-in që do të përdorni. Mjafton të tregoni emrin e backend-it kur krijoni objektin Application.
- backend=»win32″ — për momentin përdoret si parazgjedhje, punon mirë me MFC, WTL, VB6 dhe aplikacione të tjera legacy.
- backend=»uia» — një backend i ri për MS UI Automation: punon në mënyrë perfekte me WPF dhe WinForms; gjithashtu i mirë për aplikacionet Delphi dhe Windows Store; punon me Qt5 dhe disa aplikacione Java. Në përgjithësi, nëse Inspect.exe sheh elementet dhe pronat e tyre, atëherë ky backend është i përshtatshëm. Në parim, shumica e shfletuesve gjithashtu mbështesin UI Automation (Mozilla si parazgjedhje, ndëlidhjes së Chrome-t gjatë nisjes duhet t'i jepet çelësi i komandës
--force-renderer-accessibility, për të parë elementet në faqet në Inspect.exe). Sigurisht, konkurrenca me Selenium në këtë fushë vështirë se është e mundshme. Thjesht një tjetër mënyrë për të punuar me shfletuesin (mund të jetë e dobishme për skenarët ndërprodukt).
Pikat e hyrjes për automatizimin
Aplikacioni është mjaft studiuar. Koha për të krijuar objektin Application dhe për ta nisur atë ose për t'u lidhur me atë që është tashmë në funksion. Nuk është thjesht një kopje e klasës standarde subprocess.Popen, veçanërisht objekti hyrës që kufizon gjitha veprimet tuaja brenda kufijve të procesit. Kjo është shumë e dobishme nëse janë aktive disa instance të aplikacionit dhe nuk dëshiron të prekësh të tjerët.
from pywinauto.application import Application
app = Application(backend="uia").start('notepad.exe')
# Përcaktojmë dritaren që duam të gjejmë në procesin Notepad.exe
dlg_spec = app.UntitledNotepad
# presim që dritarja të duket vërtet
actionable_dlg = dlg_spec.wait('visible')Nëse dëshiron të menaxhosh disa aplikacione menjëherë, klasa do të të ndihmojë. Desktop. Për shembull, në kalkulatorin e Win10, hierarkia e elementeve shtrihet në disa procese (jo vetëm calc.exe). Pra, pa objektin Desktop nuk është e mundur.
from subprocess import Popen
from pywinauto import Desktop
Popen('calc.exe', shell=True)
dlg = Desktop(backend="uia").Calculator
dlg.wait('visible')Objekti rrënjor (Aplikacioni ose Desktop)— është vendi i vetëm ku duhet të shënohet b backend. Çdo gjë tjetër është e qartë në konceptin "specifikim->wrapper", për të cilin do flasim më pas.
Specifikimet e dritareve/elementeve
Kjo është koncepti kryesor mbi të cilin ndërtohet ndërfaqja e pywinauto. Mund të përshkruash dritaren/elementin afërsisht ose më në detaje, madje edhe nëse ajo ende nuk ekziston ose është mbyllur. Specifikimi i dritares (objekti WindowSpecification) ruan kriteret sipas të cilave duhet të kërkohet dritarja ose elementi real.
Shembulli i një specifikimi të detajuar të dritares:
>>> dlg_spec = app.window(title='Untitled - Notepad')
>>> dlg_spec
>>> dlg_spec.wrapper_object()Kërkimi i dritares ndodh përmes thirrjes së metodës .wrapper_object(). Kjo kthen një "wrapper" për dritaren/elementin real, ose hedh ElementNotFoundError (ndonjëherë ElementAmbiguousError, nëse gjenden disa elemente, dmth kërkohet sqarimi i kriterit të kërkimit). Ky "wrapper" tashmë di të bëjë disa veprime me elementin ose të marrë të dhëna prej tij.
Python mund ta fshehë thirrjen .wrapper_object(), kështu që kodi përfundimtar bëhet më i shkurtër. Rekomandojmë ta përdorni vetëm për debugging. Këto dy rreshta bëjnë saktësisht të njëjtën gjë:
dlg_spec.wrapper_object().minimize() # debugging
dlg_spec.minimize() # productionKa shumë kritere kërkimi për specifikimin e dritares. Këtu janë disa shembuj:
# могут иметь несколько уровней
app.window(title_re='.* - Notepad$').window(class_name='Edit')
# можно комбинировать критерии (как AND) и не ограничиваться одним процессом приложения
dlg = Desktop(backend="uia").Calculator
dlg.window(auto_id='num8Button', control_type='Button')Lista e të gjitha kritereve të mundshme është në dokumentacionin e funksionit .
Magjia e aksesit sipas atributit dhe çelësit
Python e thjeshton krijimin e specifikimeve të dritares dhe njeh atributet e objektit dinamikisht (brenda është ri-përcaktuar metoda __getattribute__). Sigurisht, emri i atributit ka të njëjtat kufizime si emri i çdo variabli (nuk lejohet të futen hapësira, presje dhe simbole të tjera speciale). Me fat, pywinauto përdor një algoritëm të quajtur «best match» për kërkimin, i cili është i qëndrueshëm ndaj gabimeve të shtypura dhe variacioneve të vogla.
app.UntitledNotepad
# e njëjtë si
app.window(best_match='UntitledNotepad')Nëse për fat të keq nevojiten vargje Unicode (për shembull, për gjuhën ruse), hapësirat etj., mund të bëni qasje me çelës (siç do të ishte një fjalor i zakonshëm):
app['Untitled - Notepad']
# e njëjtë si
app.window(best_match='Untitled - Notepad')Pesë rregulla për emrat magjikë
Si të mësoni emrat magjikë referencialë? Ata, të cilët i jepen elementit para kërkimit. Nëse keni specifikuar një emër, mjaft të ngjashëm me referencën, atëherë elementi do të gjendet.
- Pas titullit (teksti, emri):
app.Properties.OK.click() - Pas tekstit dhe llojit të elementit:
app.Properties.OKButton.click() - Pas llojit dhe numrit:
app.Properties.Button3.click()(emratButton0dheButton1janë të lidhura me elementin e parë të gjetur,Button2— me të dytin, dhe më pas sipas rendit — kështu është historikisht e përcaktuar) - Pas tekstit statik (në të majtë ose në të sipërme) dhe llojit:
app.OpenDialog.FileNameEdit.set_text("")(e dobishme për elementet me tekst dinamik) - Pas llojit dhe tekstit brenda:
app.Properties.TabControlSharing.select("General")
Zakonisht aplikohen dy-tre rregulla njëkohësisht, rrallë më shumë. Për të verifikuar se cilat emra konkretë janë të disponueshëm për çdo element, mund të përdorni metodën print_control_identifiers(). Ai mund të printojë pemën e elementeve si në ekran, ashtu edhe në një skedar. Për çdo element printohen emrat e tij magjikë referencialë. Gjithashtu mund të kopjoni nga aty specifikimet më të detajuara të elementeve të nënpëmasë. Rezultati në skenar do të duket kështu:
app.Properties.child_window(title="Contains:", auto_id="13087", control_type="Edit")Pema e elementeve vetë — zakonisht është një tekst i gjatë mjaft i madh.
>>> app.Properties.print_control_identifiers()
Identifikuesit e Kontrollit:
Dialogu - 'Windows NT Properties' (L688, T518, R1065, B1006)
[u'Windows NT PropertiesDialog', u'Dialog', u'Windows NT Properties']
child_window(title="Windows NT Properties", control_type="Window")
|
| Imazh - '' (L717, T589, R749, B622)
| [u'', u'0', u'Image1', u'Image0', 'Image', u'1']
| child_window(auto_id="13057", control_type="Image")
|
| Imazh - '' (L717, T630, R1035, B632)
| ['Image2', u'2']
| child_window(auto_id="13095", control_type="Image")
|
| Redakto - 'Emri i folderit:' (L790, T596, R1036, B619)
| [u'3', 'Edit', u'Edit1', u'Edit0']
| child_window(title="Emri i folderit:", auto_id="13156", control_type="Edit")
|
| Statik - 'Tipi:' (L717, T643, R780, B658)
| [u'Tipi:Statik', u'Statik', u'Statik1', u'Statik0', u'Tipi:']
| child_window(title="Tipi:", auto_id="13080", control_type="Text")
|
| Redakto - 'Tipi:' (L790, T643, R1036, B666)
| [u'4', 'Edit2', u'Tipi:Redakto']
| child_window(title="Tipi:", auto_id="13059", control_type="Edit")
|
| Statik - 'Lokacioni:' (L717, T669, R780, B684)
| [u'Lokacioni:Statik', u'Lokacioni:', u'Statik2']
| child_window(title="Lokacioni:", auto_id="13089", control_type="Text")
|
| Redakto - 'Lokacioni:' (L790, T669, R1036, B692)
| ['Edit3', u'Lokacioni:Redakto', u'5']
| child_window(title="Lokacioni:", auto_id="13065", control_type="Edit")
|
| Statik - 'Madhësia:' (L717, T695, R780, B710)
| [u'Madhësia:Statik', u'Madhësia:', u'Statik3']
| child_window(title="Madhësia:", auto_id="13081", control_type="Text")
|
| Redakto - 'Madhësia:' (L790, T695, R1036, B718)
| ['Edit4', u'6', u'Madhësia:Redakto']
| child_window(title="Madhësia:", auto_id="13064", control_type="Edit")
|
| Statik - 'Madhësia në disk:' (L717, T721, R780, B736)
| [u'Madhësia në disk:', u'Madhësia në disk:Statik', u'Statik4']
| child_window(title="Madhësia në disk:", auto_id="13107", control_type="Text")
|
| Redakto - 'Madhësia në disk:' (L790, T721, R1036, B744)
| ['Edit5', u'7', u'Madhësia në disk:Redakto']
| child_window(title="Madhësia në disk:", auto_id="13106", control_type="Edit")
|
| Statik - 'Përfshin:' (L717, T747, R780, B762)
| [u'Përfshin:1', u'Përfshin:0', u'Përfshin:Statik', u'Statik5', u'Përfshin:']
| child_window(title="Përfshin:", auto_id="13088", control_type="Text")
|
| Redakto - 'Përfshin:' (L790, T747, R1036, B770)
| [u'8', 'Edit6', u'Përfshin:Redakto']
| child_window(title="Përfshin:", auto_id="13087", control_type="Edit")
|
| Imazh - 'Përfshin:' (L717, T773, R1035, B775)
| [u'Përfshin:Image', 'Image3', u'Përfshin:2']
| child_window(title="Përfshin:", auto_id="13096", control_type="Image")
|
| Statik - 'Krijuar:' (L717, T786, R780, B801)
| [u'Krijuar:', u'Krijuar:Statik', u'Statik6', u'Krijuar:1', u'Krijuar:0']
| child_window(title="Krijuar:", auto_id="13092", control_type="Text")
|
| Redakto - 'Krijuar:' (L790, T786, R1036, B809)
| [u'Krijuar:Redakto', 'Edit7', u'9']
| child_window(title="Krijuar:", auto_id="13072", control_type="Edit")
|
| Imazh - 'Krijuar:' (L717, T812, R1035, B814)
| [u'Krijuar:Image', 'Image4', u'Krijuar:2']
| child_window(title="Krijuar:", auto_id="13097", control_type="Image")
|
| Statik - 'Atributet:' (L717, T825, R780, B840)
| [u'Atributet:Statik', u'Statik7', u'Atributet:']
| child_window(title="Atributet:", auto_id="13091", control_type="Text")
|
| CheckBox - 'I vetëm për lexim (Zbaton vetëm për skedarët në folder)' (L790, T825, R1035, B841)
| [u'CheckBox0', u'CheckBox1', 'CheckBox', u'I vetëm për lexim (Zbaton vetëm për skedarët në folder)CheckBox', u'I vetëm për lexim (Zbaton vetëm për skedarët në folder)']
| child_window(title="I vetëm për lexim (Zbaton vetëm për skedarët në folder)", auto_id="13075", control_type="CheckBox")
|
| CheckBox - 'I fshehtë' (L790, T848, R865, B864)
| ['CheckBox2', u'I FshehtëCheckBox', u'I Fshehtë']
| child_window(title="I fshehtë", auto_id="13076", control_type="CheckBox")
|
| Butoni - 'Avancuar...' (L930, T845, R1035, B868)
| [u'Avancuar...', u'Avancuar...Butoni', 'Butoni', u'Butoni1', u'Butoni0']
| child_window(title="Avancuar...", auto_id="13154", control_type="Button")
|
| Butoni - 'OK' (L814, T968, R889, B991)
| ['Butoni2', u'OK', u'OKButoni']
| child_window(title="OK", auto_id="1", control_type="Button")
|
| Butoni - 'Anulo' (L895, T968, R970, B991)
| ['Butoni3', u'AnuloButoni', u'Anulo']
| child_window(title="Anulo", auto_id="2", control_type="Button")
|
| Butoni - 'Apliko' (L976, T968, R1051, B991)
| ['Butoni4', u'AplikoButoni', u'Apliko']
| child_window(title="Apliko", auto_id="12321", control_type="Button")
|
| TabControl - '' (L702, T556, R1051, B962)
| [u'10', u'TabControlSharing', u'TabControlVersions e Mëparshme', u'TabControlSiguria', u'TabControl', u'TabControlPersonalizo']
| child_window(auto_id="12320", control_type="Tab")
| |
| | TabItem - 'Gjenerale' (L704, T558, R753, B576)
| | [u'TabiGjenerale', 'TabItem', u'Gjenerale', u'TabItem0', u'TabItem1']
| | child_window(title="Gjenerale", control_type="TabItem")
| |
| | TabItem - 'Bashkëpunimi' (L753, T558, R801, B576)
| | [u'Bashkëpunimi', u'TabBashkëpunimi', 'TabItem2']
| | child_window(title="Bashkëpunimi", control_type="TabItem")
| |
| | TabItem - 'Siguria' (L801, T558, R851, B576)
| | [u'Siguria', 'TabItem3', u'TabSiguria']
| | child_window(title="Siguria", control_type="TabItem")
| |
| | TabItem - 'Versionet e mëparshme' (L851, T558, R947, B576)
| | [u'TabItemVersionet e Mëparshme', u'Versionet e mëparshme', 'TabItem4']
| | child_window(title="Versionet e mëparshme", control_type="TabItem")
| |
| | TabItem - 'Personalizo' (L947, T558, R1007, B576)
| | [u'TabItemPersonalizo', 'TabItem5', u'Personalizo']
| | child_window(title="Personalizo", control_type="TabItem")
|
| Bara e Titullit - 'Asnjë' (L712, T521, R1057, B549)
| ['BaraETitullit', u'11']
| |
| | Menu - 'Sistemi' (L696, T526, R718, B548)
| | [u'Sistemi0', u'Sistemi', u'Sistemi1', u'Menu', u'MenuSistemi']
| | child_window(title="Sistemi", auto_id="MenuBar", control_type="MenuBar")
| | |
| | | Item Menu - 'Sistemi' (L696, T526, R718, B548)
| | | [u'Sistemi2', u'MenuItem', u'MenuItemSistemi']
| | | child_window(title="Sistemi", control_type="MenuItem")
| |
| | Butoni - 'Mbylle' (L1024, T519, R1058, B549)
| | [u'MbylleButoni', u'Mbylle', 'Butoni5']
| | child_window(title="Mbylle", control_type="Button")Në disa raste, printimi i gjithë pemës mund të ngadalësohet (për shembull, në iTunes në një skedë ka deri në tri mijë elemente!), por mund të përdorni parametrin depth (thellësia): depth=1 — elementi vetë, depth=2 — vetëm fëmijët e drejtpërdrejtë, dhe kështu me radhë. Ai mund të specifikohet gjithashtu në specifikimet gjatë krijimit të child_window.
Shembuj
Ne vazhdojmë të shtojmë . Nga të rejat, vlen të përmendet automatizimi i analizatorit të rrjetit WireShark (kjo është një shembull i mirë i aplikacionit Qt5; megjithëse ky problem mund të zgjidhet edhe pa GUI, pasi ka scapy.Sniffer nga paketi python ). Gjithashtu ka një shembull të automatizimit të MS Paint me shiritin e tij Ribbon.
Një tjetër shembull i shkëlqyer, shkruar nga studenti im: (ai do të kalojë në depo kryesore pak më vonë).
Dhe, natyrisht, një shembull i abonimit në ngjarjet e tastierës (çelësat e nxehtë) dhe të mausit:
.
Faleminderit
Një falënderim të veçantë — për ata që ndihmojnë vazhdimisht në zhvillimin e projektit. Për mua dhe kjo është një hobij i vazhdueshëm. Dy studentët e mi nga NNUG së fundmi përfunduan diplomat e tyre bachelor në këtë temë. ka kontribuar shumë në mbështetje të MS UI Automation dhe së fundmi ka nisur të zhvillojë një gjenerator automatik të kodit sipas parimit "regjistrim-riprodhim" mbi bazën e pronësive tekstuale (kjo është karakteristika më e komplikuar), për momentin vetëm për backend-in "uia". po zhvillon një backend të ri për Linux mbi bazën e AT-SPI (modulet mouse dhe keyboard bazuar në — tashmë në lëshimet 0.6.x).
Duke qenë se kam lexuar një kurs specializimi për automatizim në Python për një kohë të gjatë, disa studentë masteri kryejnë detyra shtëpie duke realizuar karakteristika të vogla ose shembuj automatizimi. Disa gjëra kyçe në fazën e kërkimeve gjithashtu janë zbuluar nga studentët. Megjithatë, ndonjëherë duhet të monitorojmë me përkushtim cilësinë e kodit. Këtu ndihmojnë shumë analizatorët statikë (QuantifiedCode, Codacy dhe Landscape) dhe testet automatike në re (shërbimi AppVeyor) me mbulim të kodit rreth 95%.
Gjithashtu falënderime për të gjithë ata që lënë opinione, krijojnë gabime dhe dërgojnë kërkesat për bashkim!
Burime të tjera
Ne ndjekim pyetjet përmes (recently a tag appeared ) dhe . Ka .
Çdo muaj përditësojmë Numri i yjeve në GitHub rritet më shpejt vetëm për Autohotkey (ata kanë një komunitet të madh dhe një histori të gjatë) dhe PyAutoGUI (në shumë mënyra falë popullaritetit të librave të autorit të saj Al Sweigart: «Automate the Boring Stuff with Python» dhe të tjerëve).
Burimi: habr.com
