From 41e98f0beff0c3b970777865058cfbaa10703402 Mon Sep 17 00:00:00 2001 From: tschmid Date: Tue, 25 Sep 2007 06:31:14 +0000 Subject: [PATCH] initial check in git-svn-id: svn://svn.cy55.de/Zope3/src/loops/trunk@2069 fd906abe-77d9-0310-91a1-e0d9ade77398 --- agent/crawl/watsup/AppControls.py | 152 +++ agent/crawl/watsup/OrderedDict.py | 61 + agent/crawl/watsup/PControl.py | 389 ++++++ agent/crawl/watsup/__init__.py | 0 agent/crawl/watsup/__init__.pyc | Bin 0 -> 135 bytes agent/crawl/watsup/docs/WatsupIE methods.doc | Bin 0 -> 42496 bytes agent/crawl/watsup/docs/html/code/example1.py | 10 + agent/crawl/watsup/docs/html/code/example2.py | 27 + agent/crawl/watsup/docs/html/code/example3.py | 17 + agent/crawl/watsup/docs/html/code/example4.py | 51 + .../crawl/watsup/docs/html/code/example4a.py | 3 + .../crawl/watsup/docs/html/code/example4b.py | 3 + .../watsup/docs/html/images/ShowWindows1.jpg | Bin 0 -> 28696 bytes .../watsup/docs/html/images/ShowWindows2.jpg | Bin 0 -> 60292 bytes .../watsup/docs/html/images/framework1.jpg | Bin 0 -> 46739 bytes .../watsup/docs/html/images/framework2.jpg | Bin 0 -> 57321 bytes .../watsup/docs/html/images/framework3.jpg | Bin 0 -> 127162 bytes agent/crawl/watsup/docs/html/intro.html | 343 +++++ agent/crawl/watsup/docs/images/tizmoi.jpg | Bin 0 -> 6827 bytes agent/crawl/watsup/docs/tac.css | 7 + agent/crawl/watsup/launcher.py | 116 ++ agent/crawl/watsup/performance.py | 181 +++ agent/crawl/watsup/timedunittest.py | 279 ++++ agent/crawl/watsup/tools/ShowWindows.bat | 1 + agent/crawl/watsup/tools/__init__.py | 0 agent/crawl/watsup/tools/buildSuite.py | 96 ++ agent/crawl/watsup/tools/findAppControls.py | 42 + agent/crawl/watsup/tools/fmShowWindows.py | 127 ++ agent/crawl/watsup/tools/runTests.ini | 4 + agent/crawl/watsup/tools/showWindows.py | 34 + agent/crawl/watsup/tools/watsup_framework.bat | 1 + agent/crawl/watsup/tools/watsup_framework.py | 653 +++++++++ agent/crawl/watsup/tools/wxShowWindows.py | 29 + agent/crawl/watsup/utils.py | 37 + agent/crawl/watsup/wie.py | 45 + agent/crawl/watsup/winGuiAuto.py | 1169 +++++++++++++++++ agent/crawl/watsup/winGuiAuto.pyc | Bin 0 -> 38356 bytes 37 files changed, 3877 insertions(+) create mode 100644 agent/crawl/watsup/AppControls.py create mode 100644 agent/crawl/watsup/OrderedDict.py create mode 100644 agent/crawl/watsup/PControl.py create mode 100644 agent/crawl/watsup/__init__.py create mode 100644 agent/crawl/watsup/__init__.pyc create mode 100644 agent/crawl/watsup/docs/WatsupIE methods.doc create mode 100644 agent/crawl/watsup/docs/html/code/example1.py create mode 100644 agent/crawl/watsup/docs/html/code/example2.py create mode 100644 agent/crawl/watsup/docs/html/code/example3.py create mode 100644 agent/crawl/watsup/docs/html/code/example4.py create mode 100644 agent/crawl/watsup/docs/html/code/example4a.py create mode 100644 agent/crawl/watsup/docs/html/code/example4b.py create mode 100644 agent/crawl/watsup/docs/html/images/ShowWindows1.jpg create mode 100644 agent/crawl/watsup/docs/html/images/ShowWindows2.jpg create mode 100644 agent/crawl/watsup/docs/html/images/framework1.jpg create mode 100644 agent/crawl/watsup/docs/html/images/framework2.jpg create mode 100644 agent/crawl/watsup/docs/html/images/framework3.jpg create mode 100644 agent/crawl/watsup/docs/html/intro.html create mode 100644 agent/crawl/watsup/docs/images/tizmoi.jpg create mode 100644 agent/crawl/watsup/docs/tac.css create mode 100644 agent/crawl/watsup/launcher.py create mode 100644 agent/crawl/watsup/performance.py create mode 100644 agent/crawl/watsup/timedunittest.py create mode 100644 agent/crawl/watsup/tools/ShowWindows.bat create mode 100644 agent/crawl/watsup/tools/__init__.py create mode 100644 agent/crawl/watsup/tools/buildSuite.py create mode 100644 agent/crawl/watsup/tools/findAppControls.py create mode 100644 agent/crawl/watsup/tools/fmShowWindows.py create mode 100644 agent/crawl/watsup/tools/runTests.ini create mode 100644 agent/crawl/watsup/tools/showWindows.py create mode 100644 agent/crawl/watsup/tools/watsup_framework.bat create mode 100644 agent/crawl/watsup/tools/watsup_framework.py create mode 100644 agent/crawl/watsup/tools/wxShowWindows.py create mode 100644 agent/crawl/watsup/utils.py create mode 100644 agent/crawl/watsup/wie.py create mode 100644 agent/crawl/watsup/winGuiAuto.py create mode 100644 agent/crawl/watsup/winGuiAuto.pyc diff --git a/agent/crawl/watsup/AppControls.py b/agent/crawl/watsup/AppControls.py new file mode 100644 index 0000000..dee6f64 --- /dev/null +++ b/agent/crawl/watsup/AppControls.py @@ -0,0 +1,152 @@ +""" Class and functions to find the windowText and className for a given executable +""" + +# Author : Tim Couper - tim@2wave.net +# Date : 22 July 2004 +# Version : 1.1 +# Copyright : Copyright TAC Software Ltd, under Python-style licence. +# Provided as-is, with no warranty. +# Notes : Requires Python 2.3, win32all, ctypes & watsup package + +import os.path + +from watsup.winGuiAuto import findTopWindows,findControls,dumpWindow,\ + dumpTopWindows +from watsup.utils import dumpHwnd,tupleHwnd +from watsup.launcher import AppThread,terminateApp +from watsup.OrderedDict import OrderedDict +from time import time,sleep +from types import ListType + +THREAD_TIMEOUT_SECS=2.0 +INDENT=2 + +#wstruct is of the form [hwnd,wclass,wtext] or +# [hwnd,wclass,wtext,[winstruct] + +##def printwstruct(wstruct): +## print 'printFormat had trouble with:\n%s' % str(wstruct[3]) +## import pprint +## print '------' +## pprint.pprint(wstruct) +## print '------' + +def printFormat(wstruct,indent=0): + def printwstruct(wstruct): + print 'printFormat had trouble with:\n%s' % str(wstruct[3]) + import pprint + print '------' + pprint.pprint(wstruct) + print '------' + """wstruct is either a wintuple, or a recursive list of wintuples + """ + + # type 1 + if type(wstruct[1]) is not ListType: + print '%s%s: %s' % (' '*indent,wstruct[2],wstruct[1]) + if len(wstruct)>3 and wstruct[3]<>None: + try: + for item in wstruct[3]: + printFormat(item,indent+INDENT) + except: + print_wstruct(wstruct) + # type 2: + else: + for item in wstruct[1]: + printFormat(item,indent+INDENT) + + +class AppControls(object): + def __init__(self,program,wantedText=None,wantedClass=None,selectionFunction=None,verbose=False): + + self.wantedText=wantedText + self.wantedClass=wantedClass + self.selectionFunction=selectionFunction + + self.verbose=verbose + + topHwnds,unwantedHwnds,self.appThread=findAppTopWindows(program,verbose=verbose) #should only be one, but you never know + + self.topHwnds=[] + self.unwantedHwnds=unwantedHwnds + + def run(self): + while self.appThread.isAlive(): + results=findNewTopWindows(self.unwantedHwnds,self.verbose) + if results: + self.process(results) # update the list of topWindows and unwanted TopWindows + + def process(self,results): + for hwnd in results: + + ctHwnds=findControls(hwnd) + if ctHwnds: + # we only add hwnd if there are controlHwnds + # as there may be a form which exists + # as an hwnd, but has not controls materialised yet + self.unwantedHwnds.append(hwnd) + self.write(hwnd) + for ctHwnd in ctHwnds: + self.unwantedHwnds.append(ctHwnd) + + def write(self,hwnd): + h=tupleHwnd(hwnd) + t=[h[0],h[1],h[2],dumpWindow(hwnd)] + printFormat(t) + +def findNewTopWindows(unwantedHwnds=[],verbose=False): + # returns a list of all top windows' hwnds we haven't + # found yet + htuples=dumpTopWindows() + + if verbose: + print '..%d windows found (%d windows in unwanted)' % (len(htuples),len(unwantedHwnds)) + results=[] + for htuple in htuples: + hwnd=htuple[0] + if hwnd not in unwantedHwnds: + if verbose: + print '..adding %s' % dumpHwnd(hwnd) + results.append(hwnd) + + return results + +def findAppTopWindows(program,verbose=False): + """returns the hwnds for the program, along with the hwnds for the + stuff that are to be ignored + """ + + # first we run findTopWindows before launching the program; store the hwnds found + # (note that it doesn't matter if an instance of the program IS running + # as we'll start another one whose hwnds will be new) + + # run findTopWindows, and remove from the list any which are stored + unwantedHwnds=findNewTopWindows() # list of topWindow hwnds that exist + if verbose: + print '..%d original window(s)' % len(unwantedHwnds) + # run the program + appThread=AppThread(program,verbose) + appThread.start() + # give the thread a chance to get going: + results=[] + t=time() + while not results and ((time()-t)None: + for cp in controlParameters: + hwnd=cp.get('hwnd',None) + wantedClass=cp.get('wantedClass',None) + wantedText=cp.get('wantedTest',None) + selectionFunction=cp.get('selectionFunction',None) + clist=self.findControls(hwnd=hwnd, + wantedText=wantedText, + wantedClass=wantedClass, + selectionFunction=selectionFunction) + + self.controls.extend(clist) + + self._mainMenuHandle=None + + def activateMenuItem(self,menuItem): + menuItem.activateMenuItem() + + def terminate(self): + terminateApp(self.hwnd) + +#------------------------------------------------------------------------------- +#Accessors & properties + +### top menu item +## def getMainMenu(self): +## if self._mainMenuHandle: +## return self._mainMenuHandle +## else: +## return getTopMenu(self.hwnd) +## +## mainMenu=property(getMainMenu) +#------------------------------------------------------------------------------- + +class PControlError(Exception): pass +class PControl(PWinControl): + def __init__(self,parent,hwnd=None,wantedText=None,wantedClass=None,selectionFunction=None): + "Constructor takes either hwnd directly, or others in a controlParameter set" + PWinControl.__init__(self,parent) + if hwnd: + self.hwnd=hwnd + else: + try: + self.hwnd=findControl(parent.hwnd, + wantedText=wantedText, + wantedClass=wantedClass, + selectionFunction=selectionFunction, + maxWait=CONTROL_MAX_WAIT_SECS) + except WinGuiAutoError,e: + raise PControlError,e + + +## def addKnowledge(self,attrName): +## knowledge=getKnowledge() +## knowledge.add(self.className,attrName) + + #------------------------------------------------------------------------------- + # general winctrl actions which, if acted upon by a user, might tell us sth about + # this unknown control + + def getItems(self): + # This PControl of unknown class can get items + # at least the user thinks so + #self.addKnowledge('getItems') + res=getComboboxItems(self.hwnd) + if not res: + res=getListboxItems(self.hwnd) + + return res + + def selectItem(self,item): + # This PControl of unknown class can select items + # at least the user thinks so + #self.addKnowledge('selectItem') + res= selectListboxItem(self.hwnd, item) + if not res: + res=selectComboBoxItem(self.hwnd,item) + return res + + def click(self): + # This PControl of unknown class is clickable + # at least the user thinks so + #self.addKnowledge('click') + clickButton(self.hwnd) + + def getCaption(self): + # This PControl of unknown class has a caption, + # at least the user thinks so + #self.addKnowledge('caption') + return self.getEditText() + + def setCheckBox(self, state=3DTrue): + setCheckBox(self.hwnd, state) + + def getCheckBox(self): + return getCheckBox(self.hwnd) + + #------------------------------------------------------------------------------- + #Accessors and properties + + def getText(self): + # returns a list of strings which make up the text + return getEditText(self.hwnd) + + def setText(self,text,append=False): + setEditText(text,append) + + def getClassName(self): + return win32gui.GetClassName(self.hwnd) + + text=property(getText) + className=property(getClassName) + caption=property(getCaption) + items=property(getItems) + + #------------------------------------------------------------------------------- + +class PEdit(PControl): + def __init__(self,parent,hwnd=None,wantedText=None,wantedClass=None,selectionFunction=None): + PControl.__init__(self,parent,hwnd,wantedText,wantedClass,selectionFunction) + + #------------------------------------------------------------------------------- + #Accessors and properties + + def getText(self): + # returns a simple string - PEdit controls only have one value + p=PControl.getText(self) + if p: + return p[0] + else: + return '' + + text=property(getText) + caption=None #undefine the caption property + + #------------------------------------------------------------------------------- + +class PText(PControl): + # multi-line text control + caption=None + +class PComboBox(PControl): + + def selectItem(self,item): + selectComboboxItem(self.hwnd,item) + + #------------------------------------------------------------------------------- + #Accessors and properties + + def getItems(self): + return getComboboxItems(self.hwnd) + + items=property(getItems) + + + #------------------------------------------------------------------------------- + + +class PDelphiComboBox(PComboBox): + # The Delphi Combo box has a control of class Edit within + # it, which contains the text + def __init__(self,parent,hwnd=None,wantedText=None,wantedClass=None,selectionFunction=None): + PControl.__init__(self,parent,hwnd,wantedText,wantedClass,selectionFunction) + self.editCtrl=self.findPControl(wantedClass='Edit') + #------------------------------------------------------------------------------- + #Accessors and properties + + def getText(self): + # get the content from the control Edit: + + return self.editCtrl.getText() + + text=property(getText) + + + #------------------------------------------------------------------------------- + +class PButton(PControl): + + def click(self): + clickButton(self.hwnd) + + #------------------------------------------------------------------------------- + #Accessors and properties + + caption=property(PControl.getText) + + #------------------------------------------------------------------------------- + +class PListBox(PControl): + + def selectItem(self,item): + return selectListboxItem(self.hwnd, item) + + #------------------------------------------------------------------------------- + #Accessors and properties + + def getItems(self): + return getListboxItems(self.hwnd) + + items=property(getItems) + + + #------------------------------------------------------------------------------- + +class PCheckBox(PControl): + + + #------------------------------------------------------------------------------- + #Accessors and properties + + + caption=property(PControl.getText) + + def getCheckStatus(self): + return self.getCheckBox() + + def isChecked(self): + return self.getCheckStatus()#=3D=3D win32con.BST_INDETERMINATE + + def isIndeterminate(self): + return self.getCheckStatus() #=3D=3D win32con.BST_INDETERMINATE + =20 + + def isNotChecked(self): + return self.getCheckStatus() #=3D=3D win32con.BST_UNCHECKED + =20 + + def setChecked(self): + setCheckBox(hwnd, state = True) + + def setUnChecked(self): + setCheckBox(hwnd, state = False) + + + #------------------------------------------------------------------------------- +KNOWN_CLASSES={'TEdit': PEdit, + 'TComboBox': PDelphiComboBox, + 'ComboBox': PComboBox, + 'TButton': PButton, + 'TListBox': PListBox, + 'ListBox': PListBox, + 'CheckBox': PCheckBox, + 'TCheckBox': PCheckBox, + + } + \ No newline at end of file diff --git a/agent/crawl/watsup/__init__.py b/agent/crawl/watsup/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/agent/crawl/watsup/__init__.pyc b/agent/crawl/watsup/__init__.pyc new file mode 100644 index 0000000000000000000000000000000000000000..68a487e531c7321e7473d8c4329c0b54d8ae9e8e GIT binary patch literal 135 zcmdn|iI?lfV?W1a1}IJ}s>XD6no7RQt)mK2v3#KgyE=4F<|$LkeT7IOeK+2rP@l;)(`fs8H& GVg>;AY#sOj literal 0 HcmV?d00001 diff --git a/agent/crawl/watsup/docs/WatsupIE methods.doc b/agent/crawl/watsup/docs/WatsupIE methods.doc new file mode 100644 index 0000000000000000000000000000000000000000..ae7b75cd8d7de5ab4c4bc8d0f98893b25b8e2600 GIT binary patch literal 42496 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 av+hg1=cT8Z_fGxyi`r{>{<8x?0{;&(mNTOO literal 0 HcmV?d00001 diff --git a/agent/crawl/watsup/docs/html/code/example1.py b/agent/crawl/watsup/docs/html/code/example1.py new file mode 100644 index 0000000..a261280 --- /dev/null +++ b/agent/crawl/watsup/docs/html/code/example1.py @@ -0,0 +1,10 @@ +from watsup.winGuiAuto import findTopWindow,findControl,setEditText +from time import sleep +# Locate notepad's edit area, and enter various bits of text. + +notepadWindow = findTopWindow(wantedClass='Notepad') +editArea = findControl(notepadWindow,wantedClass="Edit") +setEditText(editArea, "Hello, again!") +sleep(0.8) +setEditText(editArea, " You still there?",True) + diff --git a/agent/crawl/watsup/docs/html/code/example2.py b/agent/crawl/watsup/docs/html/code/example2.py new file mode 100644 index 0000000..a6bf70c --- /dev/null +++ b/agent/crawl/watsup/docs/html/code/example2.py @@ -0,0 +1,27 @@ +from watsup.winGuiAuto import findControl,setEditText, findTopWindow,clickButton +import os +import os.path + +FILENAME='atestfile.txt' + +def main(): + # delete any occurrence of this file from the disk + if os.path.exists(FILENAME): + os.remove(FILENAME) + + form=findTopWindow(wantedText='Simple Form') + button=findControl(form,wantedText='Create file') + editbox=findControl(form,wantedClass='TEdit') + + # enter a filename: + setEditText(editbox,[FILENAME]) + clickButton(button) + + # now check that the file is there + if os.path.exists(FILENAME): + print 'file %s is present' %FILENAME + else: + print "file %s isn't there" % FILENAME + +if __name__=='__main__': + main() \ No newline at end of file diff --git a/agent/crawl/watsup/docs/html/code/example3.py b/agent/crawl/watsup/docs/html/code/example3.py new file mode 100644 index 0000000..6f8cb1c --- /dev/null +++ b/agent/crawl/watsup/docs/html/code/example3.py @@ -0,0 +1,17 @@ +from watsup.launcher import launchApp,terminateApp +from watsup.winGuiAuto import findTopWindows +import example2 + +# find an instance of SimpleForm. If one isn't there, launch it +forms=findTopWindows(wantedText='Simple Form') +if forms: + form=forms[0] +else: + form=launchApp('simple.exe',wantedText='Simple Form') + +example2.main() + +# and terminate the form +terminateApp(form) + + diff --git a/agent/crawl/watsup/docs/html/code/example4.py b/agent/crawl/watsup/docs/html/code/example4.py new file mode 100644 index 0000000..8e82bd8 --- /dev/null +++ b/agent/crawl/watsup/docs/html/code/example4.py @@ -0,0 +1,51 @@ +from watsup.launcher import launchApp,terminateApp +from watsup.winGuiAuto import findTopWindows, findControl,getEditText,clickButton +from watsup.performance import PerformanceCheck,PerformanceCheckError +from time import sleep,time + +def main(myExecutable,myWantedText): + # find an instance of SimpleForm. If one isn't there, launch it + forms=findTopWindows(wantedText=myWantedText) + if forms: + form=forms[0] + else: + form=launchApp(myExecutable,wantedText=myWantedText) + + button=findControl(form,wantedText='Click me') + editbox=findControl(form,wantedClass='TEdit') + + #start a performance check instance + p=PerformanceCheck() + + clickButton(button) + + # belts and braces to avoid infinite waiting! + maxWaitTime=2.0 + startTime=time() + + while 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ⅇGQC>g9=_ z{seH(3MsLb4H**vRm`w?;H}}VCjr|TyV#(-bo@<8Z^Unr1cE5*iR7;m#2Xi1e4o#Q z?7+okU*^!=`y=H|A{8VG_Mh)vtnV1eMU^nmH`l^%jhuvF*5^vnQzpZPo|&C9CcXJu zW1GX!7SD1x;bXHBA@)XN<0KH7fHWckc4SJC-H(n)SVpJ zORe|ulttD^`R2PIR}6wwLHg7X^G#TSL|mJtd1}^Jhl^!Ve;;f(k0( zWixh-LB@Js-%@CN@luH?gE?Dc1e>zj5?{UJ>y!YGCaF>U{DN&8p(ym0cZaa)^@=1< z9@ZKRc|N!ji649eJoUpVAd>ooYag)OC-eNCNc-7mILkOt#O}*{xglYwa+<1(_gUd` zV^emd1aOKZPNsYv-L+5rijd5w?4B)P@zQ)1yIX;7BC#FYJkpqv_WN9CWHQ57`9TWW zCymJ&E0x^<60S91nMq}Z4(Q`K!OkVs>EO8Ssep4#wQfeGaPo}l4c^_CxuO;cLU&BJ zl<_%B6+hW%Fl~2+R`!VbOnV~l*6SbDk4Q)-Xf`SucP%E|TI8i{v)17Y5PxP_HKNn| z9yWpquJGfsx#5*BE>Tx_bu4#*(oUP)u&LQ2uZqfU;gqc)o7h;3gL-J=`-hMU;H=sq z-kDpo6W7zV;L_vXTp3elyCbecF@dCa+7@T*PpovSHH7XnlUWxi^)J0&OXP{=>z^UO2^`z{J=JCwSiU!GxIzA5Y43V&%;{Wm!fSjwlVN8(Qd0Eg tHZSzS4*zs#*vd+$Z=ZDs literal 0 HcmV?d00001 diff --git a/agent/crawl/watsup/docs/html/images/framework1.jpg b/agent/crawl/watsup/docs/html/images/framework1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6abc351d2eeb198cc229051f16de53ae2f97ea54 GIT binary patch literal 46739 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 literal 0 HcmV?d00001 diff --git a/agent/crawl/watsup/docs/html/images/framework2.jpg b/agent/crawl/watsup/docs/html/images/framework2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b50497e755da19b0135c6a47deeb426f1fd9f41f GIT binary patch literal 57321 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

DOV4+=DOO59+q^b? zYlivu#VKOr!v>1X*4t7Hzg4LT6Gk>K-Q?a0KOXdG+C$eQU6V}Acgz1G#kCvy+?aCH zRw4-A{XU2Y3&PnOXXaV*t3%9YD(1J{B|ckcSCPxa31m4_)-S%RANa`YE3*mq~kSDUHrQ2nfdW_jUi*N``jb6 z6ozK|CLau)BmY#limI7FuQJ+-+q1vZp7_gH6TWVObgh)|BN)< zG07mmX&Q<3>$6hRnkSv{x^}HtapZ}($1j(!Y&9=i1kEW45^kU5z`_fcYw4--oy(N-sTJiW8d(Uc8Dr(D8K&IW&!UCqS#kYnzDl}J zojs9Ql&hhTft1R)a^&(9di4|s@eH}(=1r^ca9_0^ImU)|3!G{eZSCygW9~%DR@eJ1 z(UDH}nF)=-D3&shB)%M?05~m^@*V$DV+DQ6lO!hwhs+Pg7D`QRr)^BzLTjll1$VW^ zT2o1+E+Wv1g=RFkfwGUmGK2%wbM;NnGF~8ypnikzW|`j(gzsMCuVEoFaX?_Z7N)jd z-X22@yXwvH85Es1Wje)zvaxk`odEHIl{7h;!8T$JD-AlDUZZD9GgyVC?&k;lCa>Cw zpLj$pa;}bJza!IJo&rbM^s~UPD*9|IJ{c@)(b*6IbKw&E|H1LtU%)qL{B>~KnY1$`7 zZgB=Ro6r1VB(P$_{=;WcpXEMXX&A%Eu{^I=+El!jUL!L05PG6W9b@<==5+jC;rq7D zSwWr?BNNh@TqW6e1g$=FvnJWo$AWW0kgNQ3aJ*6c-n%azD?# zt>oHstph}M4;yE``+O{dp`<^li>Z*+Y4&jT#5SYOR4>2k-BG5h+$a z=Z@NahyKD#;xAn%vZS1MO;75a?7|m(0TLesg;lj*waS56a^_wM!$s9{?YoZsd=q=9^FC-eF5Du26pDYNt0I-BjBAge8Xa zP5fCi=KLm^G~n>@o(R{C#T(>oCJ*Z`40jAW!iCRBJP*0kpy87==H&ji&dBx%OdM94 z_BPy?S&@p1bMIaXhMMJc=0exh(lVuSS~OjZ(y>PBJV)64{$w`we0LdRyD%sl0_6^s zqL5D9f!Yck<8>RNnmdV8_P|AriB4?e;`0(C^xccXqB;CO8oa|SAP3o>>w2D^2>Zp0 zdu+&0Q+Ygv$|vPaOEfcc$vcj@V?_lyLk(&Uk%p2D!>jFKS|uK0TP+@0UFC8^g3hmb zX7mj2()vYdc)=gy*+$+xAG}EKxZzJSc#bW8Q`lW3h3WbwRUK3d=N*2}!a7`wUerN` zR!oK4X&bG8=Z*Vg1$J4XDfyqM8KNQv3UQb&6~ngIObUb)Vde2~C6IE9?1XM^ja5+B4L$ zcDqd6N}b%L++l-sgRJ}GX-_YS`W+3wvku7u-589*BRVtUKoPiW)_b}uL=^0Vv*erm z@bcc&1Gc*j#Fr^yNtDwyi-M;lE7k z)RJIBC4;VDdRFvluJ$P>e>FeQ0L`=A!l&QEM|Vh_N;#1BOMZVHpMert6`&y>g&q(W2cDGcwRgEdEKqq!mjgu_-vh3FC zweB9ET;&_zB50ZvhZ&EE)#0M*{Es;#l)Y7NY%e!v#j!r9-)H3T=Pp=Nf#}t#q?`}W z+pP|i$@h9Q5-ES&-*kaj0&FMB>z{k$LGZ3TUKzNt@|qRRe)kA;(2+hsmT_&Ty`5x1 z{@EdjfZQX|C3z`NI4*mZ9LtLW+y0A)(OEtAzHe;QbD6(zRQgTn1qu?7=MNgrd22N^ zi?IKd`_-?4rL7x9?cA5F6ULZmvn+}RT?Er7F#Mxy%WsZu@MpYPR`(yCm*B}|n4N+K zh+HbHOn@(ymxaqxT$nRY?&xIS?7Pw{dVB_hV&DliA#QKd6AK@18yFE>TK{$J@mCj_ zKmI6mA+;lO5U``0yV^z1Z{4$AoB8ai5a*7kqb4XJMl~z}#dJ z)@c$hV%lXS5&4wR7rYsY31Kpgyog8n^ z$FOYsWGK&_(xIbGWtKk^q)W~Yzu^q$-O#6|Ki{U(1$ zeqe5igC_JPh=reeXtZfarpq2(Z^zfbEO4Qm@mS?KRcCGX*o2|Jz)CYs z?&C+isFCnseQBhhLQ!qaj!nk)r|YBfcM*bT344SGdP&gc+}=G)gJmb?!;Dq_v0rJf=2FC++EBpnpr9;9fFwt}eYu-EL4o+~4n4Fw5aP-M7+z0!6o*>}0xaX8LEy2$lb- z_+M2{ccgD55g3vc@3SN{BrfbVvc|x1b-#4`3(!Iiyv9?-0O@$L-=YIHr`P1b;qZtI zR^ILq{pL?anMZV+d3Y4$V-VUEI50Q_xqhvj{hMTZ@M8U&6p|;|CdE_FA419?pX4!w z`gZxCK032Kooc;5o+q5E2599GSUi z{(I)ioBRHm_r1+xRhM+F>gw)V)yp0iA2$K$G7{1f04OK`0P5)v@VEjHeZv0tem|A` z?`e3d{n!h@K!7%edVql<2S8&$!C*i=_5(}mBGMC|_^Bno z@PFq5exk7O&)^UqmjNg+Ph4~u^ryzwGr_5Y9|223S&Yd0<#)x>pP8)WP;Vwn{dK>k z!Tm=NG!-&h8j$jl)>98DHRNOIpMd8BEbmw|-Yb7?g=3ET4?wtTYsi%i2dS|_M(q*c zslhtCoa*PpA|26cc2B_07!+dhT$%_D%W(R*nhzcVT^-P=`hz2?UIET_cp zZR-!@zPLRNjhRv(PY%Yg-4q2+ zXZdb_qviQ(%jDZZsZuC>vp4BqFq-PG3{G>nWSlFwz~eXHfB36&O@1}FeMJFxeEXI; zZ4X$@l+vbeQD9p$V(;}%e29}4i!fIJvPI00?$#%e>K=n%=k?%3QjC@t_eGX3Z(6ye zmXVSsN?L||S~PLyH1talQ;<>f@@M@+0|KZT+JrC2MFt1m(#K4 zs3w+erd6J(CN%QXzVJ53e;nysVNs!LShOuvE!WYhpJi8@iEH92+vfCg=g>LUogcSu zP;t&^z1N6$&tBPGGv)5RozyjJ`pnpeLu*B}zB85&Hu;?!2mutFPZ@ySpm7&{T<|2w@qFfs*Ay<5nFv8r+MYnkQmx=*-$5VOdPxi}J z7SdO?`d=zE|AGBG0*9v`gXdk%TB~PAt7kX+EYYp|ch(;uP2+V*)0|ff=-5i;*#5mh zQq>>WzavoM3;E*f<)bI5Ix-qMZe+Vzj=!`10Ff9w=ooMGP0U)Cm0MRzo&%5l|G@tp zQL;N!@+i9^qMV;jnO_t3qSpPL^9KkWRW0%4#?&RI#^kETBhg{L%|GyeN3iw0IrNU& zJBQus3*DNONu?Kl=ll`=S39ru+OloV%Qx{C=N0@d=RM3*s4Ya?bZQ_;6(_l|&XEVZ zN#&9#(@3gDV*Dq_oY%Tb?1O82Cb92T(^8i7oJX_>FVKb{R+^9^Q6hXdA&(bm`JW&+ zr-q+ZW_izuJnAj(2XP=z$ln4~yYF^wN1JbXxFmC}@#mV{Ta0wW zRZOgRUqAiha#j63U_G}DYazSyDm-)Ak8>ybY7r8P2ifx)iD(&=}L+8UA z8XK#u^LH;2pABw30%Svg&wIL+VI_A1Fz#N8`AK2CNc_)`1HbPSm%`!q=MN^q1qgA& z(7#~uunU`@KDCK8!U{B?hv6;1YRiS!k9m-&hjw0UWlMiS*b6u}K?Y(+0Xfk&K zNrjk!Hoy`&8z1&-(B6@nS4Dwcs@~CcD2hMWu)EXm;onaO#q|m76x?)?m#p2#dslJs zgyk6?x)cGwtoI#2xSziZ+9)nh`uhEAe=mpsZ*vYcReQ-VY+-HC=~Ed~2O-l_STOw% zd0UVAA_%JJmg8h2hvQP{-3#wI$*;wHT{?|h!2TX@3xuv%FlmGqvQv^MD(@g#!wNfk z9`25r#A0p77q7ytk*Q|@4fG_%2?iP z+D;qMMwP`*y@fvSJFcu=_s==+w$_T%&gXBUzpz%@JOUc^?CIyu#~_{JANg(xvi$`4 zv$61}-Q_02=()~Z)~ zL53}H-Wd@J!N{E`!gmV^9`66_rQ_-P=h?LG3)~dzLJ{uqNZBw!;_!3Nd0wNo=(!|YI|Q~h0DLwOnoID ztP>-!x;uWu{bY+6@A+|Dl)9}H9`E>CY(s2phMjXF--*rX%)*1clf##Z{Z@x3=TA{743 zEAXS0wq2sfXFJW;YQLUFnQOJgZI&8Shaxd|0>3a%Hl7-IPR>W(<&d0xgKOhqnj8Fq zs}Xw7WK6$>7vufzJc59dIHCUH>N8DungDlf8 zqSo{aALo~SpFjO z>(nwZO;h~xk!HEt?zrS84(&RJyPE#{vAx6@FS{F94g0(LBOrH0Az^TTV*;bj^vuiF zB4$u4rdWaa_H~BlvTcOG7YD!Z*bsxkwlnlr8drs>voUg;5_d~2lnxciH?`q*OKnUf zjFW4Lw>IYw7;F|hsy(Z~nMKBhz!ibKiEYKV8+2ERRb=LGi|or^9w;X-XWjJZuTVS! zw6E|5FLhYyO@v;heI0OunPR<9a26!j*vzN#N=t4z*(M#;w^*UhQu*NWkjvxhH0AtT zurT;7ScLpZu*kXgbMFhZoUu9O32ORs<{yS1nN)lsBj~)86Ecv%jcBOd@pX#F^z0y6 zg8sZVYLsRmOT@x>$5v=z|7ilRzNTedbff9>oV;s{5oGR)>k1$H>qGJPe2b>?ZDsYo zdO`i!Ir=xhI09e4kQQ`(JV`m_N<6bi7rcaxIASa#`r$ z%}!U%#^lRmHhG&VkX!7_nxGRQJi(?>pt5=G3$;P?*~ zDHPoo)b$(2J|)JI$mo~veJvC-e(*{a1s`Wp+Pcc8GU(0v_zX^mNzOOS>cHoo%cvN{ zOKzySJ*=Ml=`gls?#Ms)uHus%`P|3Ec) zk~87@gX|Tn;4!z$Zg$W`WmB)O{QJf5-=patAZo?e+eg6Da-8jHsSO7W2Lt=G@P>kg z`6&bg3kMJV3N5uIHagXblXjf0Y!^=Xlg@U(=7f`iUk$HnK%>kuQg zJh&2?*hC@eCgk_$@Bmnz0j5@=@|$5K9pPg)QU3~l3@&;Sk`A1A?a$kgAIizN8 zo;sIA443u{#N1UrbbgF{hVKVyQ=QB(3=jtv>Fnczqpd@?HH5n86qD6E*t1ys`T9G0LLxZq z7$|F*fgS>>W@?bU1{$|OmO5@-bus$mw}BrdhggA<$d;8MAcpHSFYA_DPkTCyZs&mK##88FyJIO#G25A@RPy385vpwgOMEy%jrP zSck0wkG2PMxT3H(-P~Duu1T)o6pl8Ni4k1r9g4%qgru3=Ak@a1Uu8tesZGm&<(VgP zsePHLj;^PCM`@2p40`FHebg{KzOMDqr9m5?rcHp{r!BI+I`Z5F2Mt-uNi}O2YbW13 zZ%-L>avf7Uw#XzIw9$&Rl z__ftutymEb4+veUmO8(L-2Fol-7a(JW|1DbW~Jy(ZG)8sTfZ7rLPr57L&^<_PQ(G# zPgWIJH!_84_yw9n3O}W%$0Gm|~SMDfbYADqLx*(MFj#JtE*((hy3rDWT zy{G~kjg}T3)xE>G5mtl@*v6AK5eA@_jI5ERE{j+_`Z{O9yj(`^+21@BVU`OLY6U3o_|itE5>`nwMG|svv{9)#KI}pg@L8 zUdXiBOt`U3Mg*?d9+$6Oyr>Ya!-M#WIBan{xK_e8Ap>YWOzXUe^J6uxZiR`A) zOBDZ-0!BxVbP8XR`Ro+EfsN_$M(XlH?HYFX3pw>$hn3vBp9YyJ&`Or*7#yS?%z%m0 zik zbK2m1w~XrTi+Wjn5*f%QL&+@rI zb45=_`yE}fJrXv0d?1s6@ICjnOGV^iFEI++ek~7`Ji}`WjA4^+<^vjRq=}&!IfRbl zf?%3hK~9Cm=hQ@5=b(L`kCUkl z;w*zF@DFigcntP z?uHB#H{@8Z7y2GdJ?s7MDyHgcG;)k+Wiqi;Vl($OA_DnN|MR|gl6*r|nPlC4Og0pO zrqlhHti&LpB3m^VvO^lHmWyIom8Hb+of*|r|4XNqDI}z#LlHTe^4KZm*4=7Mx7pF@ z_sa5PVYKor%`zYJJiN3)1$De^oCZpVkAMlTwn>FjI!Bwbska5ptX~EpuJiI-G{lVb z8Fg!1JDBmTIvNd(in8h(@J?P0pVsk_>fNY$1*_fOFN9y0s?^NyT{wRo&l?C>QfrTI zV$?H>uTofXSTnI&SXPV0B(_a?Mh018l9~TJRFw|uGmUim&9&a&&wp|8@6hWv{LkRu zEB9yh|7++$jDs#O2|8x{`F;yc!rI&9VPHQ9E~J4o$tpxj{6g zjJQ&9&pM1=mG_?}79CB+sM88sG0*sFPC3RWCe~}2iZX@p*{&f7eUvK_vnGo1d3S8n^Or-DgNSzmw&riJ+ z9{%qFI|j+;aqg5@_GuqEhs!!H@ zd4W2Z8g4JpF6y+mO%%ucKbr}0_RMZOJY@Y;t=IlCgu6}Jl2BH701J-#kP$}K;`V9( z3uRgxKJg<5D4?JomGZsSKSiS&?qwS)h2riD;KdG0+#sX6L(*QtGsCCTsBjA9@ z?tqMzD@kuu-$rHBJJn^*^@sTV2m|lkl z!?MYa2A!lnr*G74P7MEZ2c3wb?)PulFQmV3r)<4(`%~R7I{(QXAWLj&%9{l5eP*!_ z_OHpu_#n@E-FNT>ExWJee6S%C;@RO6rUDarA#jKaEs6==2A7KCAlaYQsPMR}^xF`apXIPF) z|D?4fUk+@%n@T8r2?^Yi*F$9U;2vmcG~xh4u!lEh6_4f(EECuXrOw;<~u;;&xJFMWUaD(8O3ru~Z9M{YpIYD%&hsGi`hyJoQN-Sw14+FVa&+8Bn#}89fx#BTLWY$NB z(OS9RD@8>AvNT!v9!rKyQ(1Q{Kn66Z z-c)b${MhzKSI)0_b0#MbGw1&LE7|$R?X5^C|CB}^zWN#4)eGKMW>zVc(Mwuw$>#d; zZ-rc2Rwc7Kr7*30+b-JcHjUG47~K79Q{#mf3)B{rTw7D)5%YL#-tJVZl`;XK=hU8d zf!(PP8+U&J;`J$bZyVp&h+t|Z%J5F1>MG)|wh@#~DWv<~;k`t_BTG`GZ=z~CSgEO9 zQG_b%zC8E}-Tmx1$D>XExvNyqm2LJhh#IgdW!s){d9S30z~#sKH!@mvL#dSG!WlVKp*kNT+z_Y+KDAY|@8-zhnzo zDn&WVd?dqvwy$iklGHmcuFUVc9$bh>_54Ny&Z?rZu(o|Bl<#Hm?FBKi7dQzZgT+0u<3jemTM1bQo? zlce2<17quQp2_=9QIV2qR|*Wa`G47c%?CvD?_6F{QaO}-`xp(^Be=#-E;#=%# zydt&&<=yF^LKhFJBCWS;%%$lYB<8!iczrazI|`SD(#5i*gw)dm0dVlLy11(ZA|A~? zDJp^9B-&&6?{q9q?|;V8s;jXkiJ_X3rfYJE2qI@Ce>ciPWx_4T9bCI+XCUpi%?H(V zMgp;IU0igTk?o6o+_EXnh#~?!C-U&`h~oL-{VUPlVUjPVI5|XTIcf!#*{rn)VwzhD zqIwgHA)E-N3hRk8awKxm60ve1Rzk6Cd5j=B))7`hZ}Q;zR`te`V1))tiiG_<8fzN{ zqaSuTO;^7ypSX#WyeBPp-_%mk4Y8&fGReB5vG(tdHmIT=VHbgmbxU(?Y}Yz!LtCWB znIcHg>3jwt;VNEiBr94;4ETgPR5mj-r8^}xC}R!whr8HSG^xF5t2(;KECUMGb~R;d z>TE-?Dd{0P9Oam)N0U-?wi(UsOz~8&nAI_-m&^S6TQRC9UWDB=`fW`9woD$~z+zQS zcU3w=#3|5EHUuV`Tc$&sVWc2WG=FyfTtsP44#A+0qN8hRXK1`9UU4c&b#F=~G-G5O zp-mVpr$)3@FDxxY&!5b*?yr%J=`|)!pPkBX( zWa+O^F7oL-!wENWG-EuoQ;cxY=0GqNm)jtpM2kgYyy_{zsMerYg%wm!y>nD zvz-*9$Yif}5ZbEgcW2KkgfdAuOA)0Mnd}KQL_<{>c(x>3d4Ppv6pDH1GfE}x zks=D6k;LJrC?N6>43C5SXB^RE{_{q+T^e~aZERDMp z^zY5gX`9A?hIx$A5F>co9wSCmOd=Vw7C}1cL6j*N4&iZhcCmlFV96DPdcXMm=M|fE z^2`(luSDtG)6XGAJW{WP?k3Tm`jBD5r%?J$?E$8 zI5RGaPFGb8`6Ra_zvy_XD?j7SbL~J2b|-HiGMcq4fP30Yz?ED%km=s*jSWcfQ;G16^iQb(Gz5aojezrWD zW}4WMW2BGK9M$Y`Ca5_WC4pdOH&N~+ejMe3 z!fe?j=S-8XrYl2%pQmg3+=}!Vc?U`fDkI_8_Hf1*jl~j;g*0XUV&xk3zQ=<~! zQE-1I&dJw64yjxWP_MLI9X*gf*J+RsF|xKOugwXY^BBK^Ng-<(r>RIq&aM7KRu-EK zt>lABlr(;JEdhy>V_^giHg)KrQr7#IN4A=cbjQ*4>EiC&n8s!-CCdwRJB(BbgNkE1 zDLr||GY!4@ww}ykl52_!FB~{hr80=N)zCF-+p+uc)feQ**+o)VAp`X)2+`9YT`}nj zYZ#1j(dg}TeSJcUOp8e6yjr*zf?ef*8z-yI^2dVt39p9I%3nf^{970oc?PkPnC29@ zOO(^MlOm=X)y^4Wk@80uxE}$R>E(PLG}}DjBHjj?!b2IgXTwunAGk);%d7F+`%qu= z3KvMiQ!SUV7_DOue$r#HeSv=>{{64i!7WY9?2@Q*G47@O{8d=w(pF+ zS+Q4mtPjP^K9ucEvGpYJc)bQLg<*PlXpIZxVLD}ukOi2J*RZ~&FJ-n9{Uu6eKphb2 z9f12(0FOx3V9VCku%Dpwv_;8TF zPJ~tUZRKe!Qs5&fmRW8EXVsR}2_!5&ttW4Bf4nYnYI3RPU{w5>(5F2m^oEo04Na2> z8d)v7L#P}eFY?e^j&sZ1*wgbN3cEPi7CN(1=(mwydJ8L7F<0TFo(oRv(0v+n^lJpK z5?-I{o=)eB2%txcn<7aKv$Cn- z;!yzEIXIP7Q)akdi>erzIJqR}=GWHEetssbWSW>%P(O`M$s*$B9<=Lh9FRc8B^Fqd z_sfm+rw8SQpyus-7Q|L?hHJAB3X8pREydH*+sSKbf?U$WlAE^=c>-|;@1Q9_?`RB? zIfq0~QFHKj5PXwFN?H0}N5A|OhHe6bqSS^Szu`G%wSZ^9XZ6aq&hNNbSI_6L;I4N3 zdsUW`+f`B0{wViZtJ}cBMEaWyhK<(4za=WUhh;$Zy)t=xD)L<$!)c#qEbXb@RCut% zZhI)NImdBSbrwesmsXeCOchhd^@z`sh3|?&bL;I4?Uh;9tsUR?@rGRSILKqI{z=rA z?MZaQ{ht+0znzi3vdcL0EB}1BfTjP<>Xluc@8p~x3E#HOhCKCnqeIKL>b_!K`L|C^ zZXCZAQv2$998vB2WZ+Wg!BH1lmJ{dslM7b3SAS@1%~Vl!Tu=L~n19bHyXR9re!hoW z7QuN@0n%2!AA>$ZvK<9YOUw0EG)7BsX05(G+h`Nl*+{nd@S1PbjEz;QCgHUL{Tp1M z(@t&hD4PTNF#M|05*uWD3Y5CXtIVR^XWkEv?ETIJj~K@Cl11Fuzdu2K3aBVlWXv(= zFkHR2qr;HFw@`Nzq@J9i9K(4%T&68jY+iz4tT|9L;5|qj9kef@DxT%4qc z7Kcwl9^|I-nw?Qe)IN=K3>m&$pHqE$lCPY+P}7nwLteJ7G-7L{P@}ZLc_@vCf=*A9 zL4^Rb)kc9xX2$!vVqQ?X(#@#AbGPDUnE!y^^(B!g;%lwZ%24Crv2?_>A!- z1jSCR)ZRLaq|j(i%aQ@1dhS@dMp_U_aJ&I2kB@yEZXI8CuC}I z8?_|$y~c$+6HT|9{V(yV^NF8ACyR;5WcZFo!el(xY=?F7jU!DFHD_yZc>#^o}QRIJSq$7?#@rk z%4FV5eu=-NTOO^RL2n&-317_29b$Y!}W7t1m#KK z7?}tg<$0oKQAun(vJu>@H&>?#YHrep>n1g`<45tdXC2;yg)2wukWw{Ejq0yMr?phI zxC-+PwYNl=1?IH^dkn>iRhi;68Qd0BLJE#XWkOCP8t8d=7WB0^lX0Sa%$FG>i_vFh zKL%uv4XDh`VkA-4fKF}aWEB$2YV*c>)LzRfADOX1Ni2Vt8=jGsqw~QkwK|P*UvCJ$ z>`#s&999zzvRqoRw1HGFyY(Nn5i}qX8KEpa{@T)_oOZtJtxaRJ9-s@%{q*n0wd$N#zjEQAO;Urq{9O( zH$g^(-1jNfM)f87gG=%Ijb&vc^|Xhltf09M$|0()!BqY@)NEn%=Ka~C1Qp+kIbX7y z^Magr=_C?VTgY%w3(EAYQz_M$x|bv0!iH3t5YiM?D40;z9!%Nj=gv%6YBnITI3ht^ zkCyj#KF`nN;)v)-lYUx&?AAUfil*e{(Fk$h&rd5O5}UHrGR}+7BP+Jc?P>ghEq|q! zUb8~Sz%M`H+POcYS^-Q(!d2J#mY$(>{g#NXVm3>wk0z16nD3&ZvGh}9I%0K1zFwA| zS;Gy1SySgg@pyst>e#Zc(S5d^6!((bTOQT9##|F|KR5PMbUJJP{pKR_$YG=um~ zUpGApLgzC06tx_CYc)~q(2sB&RpXTjr6t9^S*_WfJ<&wblTPhQ!F!xy1Xk^HF^GT*%nmvROGcAL_w+nvUO3pRQ;-Lnhg>~ zMWvF`is=ke^sh7|!>wEv%sQtOt1Wf7Ox3jJq;d&%YTO6p#pU)9%~fnbg;VOPsw!GI z!npuFy52Oy^dynUQZ;2YNtB=pRl~6{{NhYZ9{B)HzPZu{I&-&VIZtKvqO=4_>~h>J z-!{dhl!_f}7Wxwx{C<#1O8TB?1RCdDn>Ht76BWa@9!q0On#4E(OZv*I-hgz`FoqA) z3rgD7iu2~Ov}LLmWJ)aG?9A(}MivC)A@3zZ2leDdWLe+Trt`EtqOK(eM{6SP>+ZBSwp)vu^V1>#6_6RYX0K@(i)tA5z+N5vaCv_!|>qlmSnYej?t{LbqqNpYT0U0Q3H9ki5`80 z_K|O6M6PLbce5JoCpQThi5v^V5KTWl#$&Yk`wDACO|Fy>E2N;B%sU9cd2u+#djPFj=hm1Fh->CPaK7x8QUHML(g^S2S9HU zz3`hB7r+taFP&}Ngi5ZWjA;iohsuotdE&W23FXUOlo;JyR0N0&O6F5?(yzyi5SP9K zk@m#Q9HsW3VeUkHY;e$c58UppF@YW%p&HExGcd?(!yD&BVC0}0;nKk74tBYs9IaQs z?*5Dug*Qj?>N{Jg#Uk5SCo_&s zG%xY0r9h+DP%{&2TarRC=iB$T4xAsqq4H(UodwjiFNl8PIC9Zwg@;_}J%2w_I-U{K)_hjc-VUS7vxm2CNx;qJJ@-tp8+y+q?G_@3@q_QTcum zz5i2D>A4l?!`9xK{Vn#iD5h8o1SkR{eDPgP2}l2aa7r(P?}$B(8V0} zUf}mKv!L}2lHK$>q|KE6Fvylg8^|7_T{BmbpP+yXEdFq2RO1i8f>5wxM1b2~f8g|U zXzj15ibz{CpK^{KO78?-8^h<`yCM*r3cn9s!AR;zzT^)+oruk#Twl`F3p z2##<@nb;92+KlvxJ~TUvCTCZX$2*Tm_YdeocHXxZD*y%}AsSJ{d-T*V7FNAw+9$%C z!kHvBrP`XtzuQ1j?f-Ts-gQ_%sO0-~&UXrnm(sTn55*vB7^784%-Je7e^BErYUaNy zv}ACVzcd+U#fJqc`RMuJ8p+v%cUz6ksi>$p2EM^lL?A~siNP8+8&kN7nT1h*x;6i5 z8cWRoAzLWa1+kWTrzFkUJgGm42JvNP;a2;gbAbdiZ5kQHx;Q1fpW#}kg$K}kK}^ib zCWC5uE|(WN!q-azJs~ZjSk-%9VB_7BNg^BQ`knrXA|n@WfP& z$)QsuDLkKHpdHs3D5*ruq3CohP`bOjIS#|~eH_N@;27wrmz2rN!=o?|x7d0jjax+K zx?@>NLpn#IudR2KblHL8HK4B0>l#;H`s_UhH#p_4-PA*^}|WHft$sXj`- zBrJF`*RlBRHLO#w1@T+s6OCF^R)la;@<8bDRuB6F2Lv_52%(ap0&1pq$Hgk7&!D18rb3lCfT((MB$GCDq4sTrK5yZ9Iif}_`h zbg&cKWZ0MCr3j+ROR2zP13PVI9D>~S3P5E-@K42Pyf zI#P*nWw;WlM!K^{RU*+zp+~#S%jZmPLGZ}#MPl_~m=%LS+3XDNA z^mhWi#3>SNkhmCr(^hvvM(Y{E0H+Ji|F9r{iW*>0`nRmUPv1a#(s#D{hvxXS+p4# zy5nEc2LjE^fLQnd-*qPFz_ea6#6zFp4){(p!Rc$CUYJ$ob=vXM= zgaH^9T}xB>1y1AqR&sv)y$cEBLjSDE*RSnCYZ$ z*f??4m>{?T!TLiD(n}1Ci11iNOQ+`VS>%$F13ueOG@aiIj87N($M>Kq**py;fctX$ zaNwHokt^Quj#>#Zv0f_d;RLxI24#=21WMIC_AX3iH0|y@5BVO&O>kPju?KOo@S5ZH zpsQRz8~KmVY~6|&-B(Uq#l<^%CrANpHxOp=r$QCg zlc#ZLN0X3c1LGJ@q4raQTe#Ajl)E1_TWeZhS7c8xii&Tu${#lWt^SLr`4-6WTm3hG ztk3^j{e^$8uk=*Eu>7IR>W7)%J6lf=^;cZe-(jsve;isry)V7|PRrnzX2m@Q{FFm|rg4-CjN(cJ9JBn8qMQW9Mt_DDhb&ipS_Nu7e z=%OY$%wul#c(=zQP=`?@U*m%|BMZmwit_Y2Q85?BK%kES<{5;NSeYE3AXDjmNSP8Q zXEHk$4EF#%FNzrC?M}S^`@!o76v*L!WgGrMcc_zy9m9pEC+QF<%*Uq(s`FS|fjx(Y zi8rv`VEHlYALlR34VM(Jlz|F)h%B|S7ZnO~ionv(+)iAU;1Utk?Da9Ixf7V?vKdqIyVa zqHl}O&m(H}ZvB8MlR{&c=D_H4mJt8Ina{aPsscv&CAQ0luL?O?+qbVgT1JZz=I)Sq z7k#MTOkBLp;a}aG3AVluAwGG9Rea#tF`0GdeE6?11hYJ$TNQh^U74-6ekwRT0w~HF z$UT8$O)+jdEMF|&Q8_#omFtATp2!X87rsR3w-0PM4zIyM6*vPX zJEjN`5k#c9u%dwQiRt6}SeQ^aUp^;Aujr(*OkxMLdV=c@TX66Y>~-~ZjkE48BXDA| zD`gG-|7!OC8UNFXdvILF8OU)_z^`v|U-4CR_cJhB>;KBJ6(#Fo*EILcV($yd>YJed$Nrz@ zmN&y|X7YNK8uc6*NtNo63sLvEwRKUX`ylzC*A7#y^oQaX=Esc1O7g%R-Kec{9{Lb7 zA7_cXoBHE-e>?mC zQI{(GdoRB=baih3Z757^Jq?9!F5dt<%^p!Xj(ZAAZJZQLMk*6mm1wyO5Wd4$w(RvB zd?^Q4O-s3y+iNQcsV-9+W2^zBWBT|mgA4TcXnrJd?PT1i?8=mIKVQj!< zw4j#>Rk_&=8dJ$BQ!qHvS+`S;n*6QaeHO)_P(1;+w1K)@0J z&P@2w2Xy9fo3A31m*1FED85~9Aq$Ou>Qs$8o(X>X3J`PNow8810(#wjXVjk5LkG`4 zEVuHB{4o8SRF{vOT7mhQEX3*C3>MzNt=yYW(>5oEn$`BXL?L;~oHP;UW~3u*!$AXV za4r@xuHD_$lpQtH2Eyh$TSzox&~UM{LP_Koqdg6 z)cYFJ56jkw2p#@|VzhR;_F!YVf${*#%rprdWlwD!dECS*b-79{6+8!bELLiqD^GAU zA>=tBSLiGn(;%eiJlMy%v-wk5Ff@okm>}Xg{z4=rc^?}Zg`x@rMMM%g7@;s2c5hAy zme47PxtmV98Y-AbFJ`Vd107i#&9NRfAozV?bYU{kgnkC+;KCH+yibgYBi zxzAqHOxkH#CWRe^gBmlrHCL%fB}s2c{ z&t~{++_pRySbQR3)&z1zH{<~<6$r<=asYHs$PKa~DbAiO6_S()#Vc{!u-vQY_Y2Ag z;wnh+WGVqza(h*ovtBxvSG?bAw)Ra*_WB-tI#O2$>%Et}xxsHP*zfxu0Rta==w%-P zLYET{qb7Z=br(-#BVU&30j6>L88%6WO=YGn9$EQl2`}$9EF&yLx)G5K2DrufI(n`q zI(fgENj*XPLq7_pXblw3)DkjMP_0-r+oc}?p?})%gCjkxln!4S+ZY#y1#10+4@7gn zum_pC(S@8MP8nOAe+qilH{}_XHcrfMr$ zTIq!ZB}>6VZM{Oew?FdxzcbZ{@ z3~GTyLv*q7A)xc+bQ>6%LFBkdMnS|$xSGj@`hHr|m_W(<>2neKFF&?`H+(toEBQ0V ziob#%j2;2oi?47B9|1Xc7Vpe{UvDcFroMw((J*QYJGCA2*c$3t!P`2?>SH^}UhF*0 zsoOi$s$Y*OPkm{gZT@3+L5xQ7I#x_&$RvVCLHr5@1W8`|92cvxKtkJi|31=?0%d@W zQo`6P-a%Vzj{zpIxtwi*e^{=>Z2$pRrAID3iUu(;Q}tsWl!Vl*`UJFcSTz0>oF{(i z(k4(r4AetW4o2_AJH=K)CWz?2&*aFcQQ(QRRx3we=TXN$5Uk|FP&3-0L1feu3%OK; zlQnS3AlJ$pi>wc zQwq-jD>HZ2<{)IvZZ=z?aFL|4f3Urg9c?ap&Ok?*)=N-dR3l@KJ-~ylUM8lUS;4XQ z2IPSvORbuQ$ zfdFs-qG9a|bR;wKTKVSBDQOA%I=Ii+)rYKw)rUwz18OT5HB)Wthq88H4KFlB#pE^L zQ_44kfsExaK@8X@uU07p7P+B|tfQ;+$pf^{-kD&Ouq5{uM*EU4G0+agm^|azJa3Lg zXe^q3Mw>|I?Ph zJ}3tr6bn3(Ps)2KP-Ft4p)WOC;D-t}3v`7`*&-Vnl*4Vvz$IaH4uSDnPW=?AOnWt& zAa-cDMW(c3#OaJqjEj+PJ9){MBD*?okU&*iUNmC*<|oZ37ooC@I1GUV3EGVzV-cz& zNBkW1a7k~MLsu!U8gK8W>Zw7*oD0zfmY7@j<}g^rWYm!4^Y$Uv5_;_@Xl)tDH+8fKZPBPpcT zgcAm~&y>~q(u$`H3l%BCsYR_h4TaM%GL1PzlceiUq5@Y1@-KDE+?0aH;5 zx=bt5Wr{@}Y{U)A5TQ5{yzfOsuoUYsm_gQ#?@pd=>WsM*y(pb#YA-KK>K`az^OoXj2z=17i z+u|7^;duj;7}@Ak5Ofd1`@AV}4~cm+?|7}dCe5FN_}H6q-4wq=855FaU(oPmcu zx`F3&$x#YY%BH{ObiCo0RglG$^WNx2Z!Wm&L7qWx_}oj`W7iFGtKvpa!K>6;_(%V?;` zsw#Wmiy|gEX*fl{Og|nGw@`F!X0yefP^L^&!{M(D!(bv}V-Z(i^CA-aqN0NhA%MnI zW0DuhsMbA@Sx_O8RT5BFQF~t%4wF{Q8-H3Xe#h35(yR$A>!0?wz2Xv|0RILkP zsa2K(`;=iW>25nA*4#*$m`$sGq>D5fvk{hNS2)hck(i=D)LupQUO<-!iWyMWESU30 z`^vB&Cx&scD+xey(FBe?TjZ|I%IiqWQ;Td)p*JEo&5c*xVMvyXUuTtR1I4PzY6CBY7uB%4?!}-b2i^0EM%&pxt?`w3@ zd;DMQy?0d8-?lFrs+53)UKK*`3B9RwDWN2xHz@(6N)-@MIw1yx&;kUchK}^6D7^-h zDn+DMK}8frESKLtd!PIEz5Cqp-Wd1Xckg)buOxHKHP_6y1N%4#$`2$fM;>NS>e1IwIlEX)ng2Gb_*ZNB(jdGgJ#0| zuB+a12tiaaXu`Z=HkkxyVH4AyDeVd~2sIH7Lv#5!AdC!B)nw!&EP~2) zZfm2Yb9dn|0`N1$#1ABwl8YGAny~7fkz^LL0)xI0$>6!6pWTG|+?12WEFiVhzA#ce zAe|m;!=Fe-HsGKK2Z5pYuRw3QKk+UU*T2@AZpcCbOyB)5P)x?8%IzHUJWtr#RN>Wt zPl9N?&@Nr=H?eir=^ohiNWlQZcbxo``p)euRD^|GD>*B3qw?3%B)c`SQcn$=W21x~ zJx-3tz;;mbBVbP6TpWUnr6JCSoUK2`tCWCKhH06A)M%o~1wPAL(8Y*eR|*DKU|(Y; z4Xt>9CWg-9P)wk7hC;|8$OSzzo6p8*>+mIsEqpleu=jqdll}PzFs^xU+M-HXntQ|qS@jecP9XE?$-N$vGzP@? zT?K6kCg?`#U~$Uz*e1!fa$J7~UaVq3Ric*}+(X@ThcG88eNxj_@Eg$P)@5jR$qqR- zny1yH(APmjT-d0MDI<-v$|P6jA<%Q$Nnk(r&U5>$ zRI4hegJPreQe$)4!PiEtyZKKm$3W^UQZJ=%8kxHYg_?`ZGicATM=dN=V~ywD8#kmc zu+JSU=)ON(*4@qsp9t7ykg#gZ9!CW&>9D$%OS_qS3{uxGQ#@iw_USd@Q+Ycs(lOw@ zj>#EGH&Ih788|<;Zfx`H8KPDFaEBWmz)dbScff3QLt{ zo>lV!>iQ*f&?V<(A^ohJ3ntKAk@Pqtaf6tMViO9nIFDh)0F;S0|7GjC6IiE58~rfGT5N1qCKa%RUAHJb zDg=Tvt%ujwHU1JPEqWCi!3w;C|62yv_*VueXg0cCeA9!f{>Scwn(0!T*NK2x$mab@ zfJ?}GA3CF7Q_+bLj6xo+_gdxxs$M33(CmYh)t>A6XSz|dO8I`GN>>72zQno>52v8& zSbUmSIhU8?z2OGPrf67#M-U9Kw-f?F_epvuP|*9y)HmIhB2_WIBQA?Y&rIhyg^TB; zRQemzc$J(~KBB=Gxc=?BVM)I5xzMU!rDi_aGFSEa*+53=mS9sp{VW3cM9>V4lglG& z)|NVL!TKL9dQ4Wc+dJbyL%26`WNH|x79EjzlQ>wph8A|yO0I;gr*T-ME^Mw!Xuv+9 zLp%{6R_AHhB7ty+reaRD5dC5SY-cB-_FxG+M4Qix+A&rQ*#yi|x@gnVfa^|M0Y>U{ z@w0YMMQI&T#AxX_Z=NZJZt32YZtqb=J@&)3OC6I+lIDTpG4a-5Rwm&|oWil$DH&G5C z$J1jaJsLO}VyQP5990nix+pGDF`y$G;3NzjW!)hSTit67)~&-HTfrM)#jRxWX-Og_ zyp7FtmMrEIWu%lxB(yCuS)yR{eN46WcRQJvBhtp7-mT7d25g<@?EF|zkdBzMrHje8 z2UYur(D7Q4OL?WnV*GCymcEmi}eO` zJYy)gJf)Ku!~zKx+S3cKLpLqgeyT1MO~q3u&Rqe|j)V#G>iS(Cxi5L|H6)~_n`4vj z?%eXmFITZng>{w&yPL~&L1hOhxT7F~wyob_u3-PZ|ItO=&A-7^2*S?=&JaZV4#7 zF3bij^wY=*h%qPrvk@mR1R(}e? zS#6C-Y*ZadT78=&+ZgZ-qe;=s|Co&Jc`&9!Q(>O|{za{abg$pVHh+SKx1`mE)QE`I z-Iy!PsS3QT`eI#hImDiH*c=w&=69T&rYCRg>(bvcXOZcQk%A6YGxaI!Ch#+CC<56+ z1FIJTOxi`G6pP{nOInT2YVDlqtQ*!eN~s;>ljxTDJ3$*HpP|~(dZT3m)1I6I(r%DE zIWQfmW%7i<3j@TlEhdLxkF)NRr6|4do+hoIk{VnTiW%~Z&6*l)_5-)|*x5)(99t@6 zLMPiqG2vT5aXt4-Z}|1t)TyMo7i^i8Wlyc7N{|J^QF3oMw3l?y8^4`) zcJv$cvmJk4@*7|jQ@{7dUS&Z>$2!M6D0qOzjuxBY%dAap*ykO`RpZ7bKH=n02X1vi za|$K7l1r90v9n!5C3CuO{ghKAgPN?;eBX`=oKn1uuz=vi2BfH+DY~7{u#FSOvFv8P zJGwWol!;-&N~k(>xED0%(u89Z7{!OWiO;dkc_`;zuSVSn{|xVmL@s>%Q1Q6NLIuCn zR}be5njAKSB!c56CzOGzk3|j{$;a}Dn%PZ+wW&hRT$&cTc{eHxHzIZ$7%1uyB4Zui zmw*#;Wl^Iq;5?@n$}=;+3(apfq;_F4gy5`(s$C4kD7~)Qp~u;Qz-u!T2Jz?&Xg>8m zHd<;yiKP1+@vC^KDLKbtc20r+bDMMZZJM4Lf&+R;S0hkZ_@ipN#PYK z$?UGA`F_eVS|UO*95@YTP1FiQH+7CXhVK(iqu7} z0Q1MikEmUFE%@RIh;SQaY+mLl3Bl*=!3#N7n@kql+wfeU3+;TFH?ZC7-52)!Y0X|h!QX$c9% zi2~8fgFstXClAN1>Ym(a4hx{(&n#f>^8}&Fxs~sy9f{FKQ#nTTh(6O|ygOtZLwzeA zg4?o!un2eEtlAlfA1vm~9=jWJn3Kr|XhpV(JG-}=*vAh8%z z!wg|*aE5Bmf^22}%I!_@B;Cmg4d3q%P-{y;Yg^UTW}JY64=T8<9zfGTBx>aST5^K< zMH#fG@>~pqK5(pgEHT}aRa8b^FU*0?hRjAkXkVgrGLn5>pENaKNQ*djspCTRaBwb5 zxiNlInAq_Xu`%`KWh=UdqvH}ZOp-InCF%;o$tZm{3DK#N*(_YQHN|Q@C*9}1Q{{kY zkPVSSRFHB0p?aW)QEKL=WbI9U3Tj|4w82I$n5~$r-hMGL^G(Y5gPGK?mNAt14FzLq z@gqaytluAl7E*i*Ljwp(U>=aM01FcrGE)$lW47RL6U$ELP$z4bNGxEyg_wE&W>x-$ zr~7v9cH!CA-3JLZoJE5EJHW@0LC2(@rGEg9tLI*`?eACn{s0zcs_wjbneYeDSbOqU@f~WGbS6Mv!A1LOXEe?h*eB3HD`&*{@Z`bL+h7J7-*wJ6Gp?`uM{rx&;)qTB0 zmDfXRuXCKr2}x^l4cN3b`K~YG`UenZ@?^E(51=oKG5^L(C55`N@l<*Z=gfcKT%I*&jfZQsmR_ z39S0q&q67KUfqi^;UxBpO4&>^p`nXu)c5{2+y8DK*?j@_+->2c-P`q7l;}%D2qF>D z*QLB_tmbk&!JUe&>9Fr@e$*H5{a6GP9|f?k+fwL%?X9&3nyXkHHVLmt%%|M4*Lp5e zmFAOAkyuL8KLN~QSVPj;5`*+nP3uV@jrPQ*gHJ$8I|DohT=K4BMPTvsQ?$b^GB)9q z`}6k}_%R9x^*tHjb=Ko2Pvj+h(_uz1-D9wYvoB(-NLYn0yE58xGUutCFIC+m9{obf z!7zQ}TqdJBx^33}*|!TM1pA)9>b+i^9z&oUy`3*D8_>=NTZStMurR#C5|jUVOZN-XlQ|qwB%G&|8`yx;I9Hu>PxI_0$`|u#YF+AoT3ua zYE}o1a0v{>WfqsUObN+rYH3>r-A&KP%AT2Hf}lzpo0?lUX<|fl-9n~?U4!F#|5gKf zQC)h2tRqbH?PTJ5m#7z6C`W-G!!@7knmd>!KJ7}xf{Tfnv8{e35uO>_EVTkX9U`nJ zFm5hqywmh6dIq;EZ#KjdU&@A|mHFji+t!`#*ObV%38DfqE-|{xE&e-C(8i~AXFr!# zO2ZU>YTs(T^J-`Qh^Mn+gZWp@gNI7(w^t@^Fy$QCpPaQm)BoW0J^rQl>XV7OCFNkV z0pWA2pTGV5r=I0K5RhGJ-#ziUoBDPVlH5TQ>L^jM`ngGf_TBi=ew7t=o}TjGjJ`F% za&GnOx6farfAc?CYX5j*e>dgrn`6q~b1xs}{iWJVwCHKw`OoP~}^1v^9`9mEm7abMUjg7rH8!|74c$~RwFqs8r7xIfO91Tm5CD!FU2O_d9+J(Qv z__cN5q#37q9wT;;Fa&V(TRe&gUN&j{1NgGil(TXaXnmMEXEEn6_f^@?ey_mJBEwq0 zPft_q;BHg;AbkKdBAGsJROtD5x?B|FHcx2h1r)dS{E1`O+%UXZ@z~hn*+i?HzlXwr zSEZibW~8Jk;w)1xyI7h7JE%G0th7QOWWO3hXOddm^^vCyEptRDBi^=}&<_?N7L;g} zWb1PVn#!|0e%Chi!9D8mU5`_~ishTgI}6Xh2W{3m%-&ISQn;yOdsojQPoN>WzJzUF zlR|zPTAaByB9b3m*V1Kab~AK!L?O#}#?rE_zD^O|Jlh!R_|1`>De+M`hvuq3K1H

5_ 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

FbJfhC_F9*oR%QXG!fuzUm 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 literal 0 HcmV?d00001 diff --git a/agent/crawl/watsup/docs/html/intro.html b/agent/crawl/watsup/docs/html/intro.html new file mode 100644 index 0000000..be9809e --- /dev/null +++ b/agent/crawl/watsup/docs/html/intro.html @@ -0,0 +1,343 @@ + + + +Windows Application Test System Using Python + + + + + + +

WATSUP - Windows Application Test System Using Python

+ +The WATSUP toolkit is designed to allow the automated test of Windows applications. +The system uses the "object-based" mechanism for identifying and invoking actions +on controls and menu items. +

So much has been written about the scope, robustness, scalability and outstanding + usability of Python that I'll go no further with it here, only to say that if + you haven't yet had a chance to use this comprehensive, open source language, + don't miss out on the opportunity to take a serious look at it!

+ +

The examples in this document assume a basic familiarity with Python.

+ + + +

Functional Tests

+ +Testers/developers write automated functional tests which follow a prescriptive, +possibly branching, possibly dynamic "user workflow". The script can check for +changes in the gui itself, operating system environment, file system, database +table and records, network, internet or extranet urls/pages/web services ... - in +fact anywhere that there could be changes. +

+Examination of the functions in module autoWinGui.py within the watsup package shows the variety of windows control items +that can be checked/modified. These include: +

    +
  • Get and set text in editable controls
  • +
  • Edit and select items from controls supporting lists
  • +
  • Click and double-click controls to invoke their actions
  • +
  • Determine the state of menu items and invoke them
  • +
+

The system also provides tools for finding windows by caption and/or class, + controls by text/caption and/or class, and menu items by text or position. (One + of the aspirations of this project is to continue to extend the list to include + as many controls as possible) .

+ +

Example 1 - automated writing on Notepad

+

Here's a simple example of the control over applications that you can have with watsup. +First, launch notepad from:

Windows Start Menu - All Programs - Accessories - Notepad

+Then run the following script (Example 1) + +
+from watsup.winGuiAuto import findTopWindow,findControl,setEditText
+from time import sleep  
+# Locate notepad's edit area, and enter various bits of text.
+
+notepadWindow = findTopWindow(wantedClass='Notepad')
+editArea = findControl(notepadWindow,wantedClass="Edit") 
+setEditText(editArea, "Hello, again!")  
+sleep(0.8) 
+setEditText(editArea, " You still there?",True) 
+ 
+ Finally, close notepad.

+ +

Example 2 - testing a simple example

+ +In functional tests, the tester wants to ensure that +the cause - invoking a sequence of windows events (button clicks, menu item activation) +has the predicted effect of, for example, a change in a value of a sindows control, +the creation of a file, or the entry of a new database record. +See the directory watsup/examples/simple directory for the executable simple.exe. + +If you run the application, you see a button and a text box. +Enter a valid filename into the box, say xyz, and +click the button; +after the file is created, a message box appears containing a success message, +and investigation of the directory watsup/examples/simple will show a file +called 'xyz.txt' has been created (or overwritten). + +

Now let's script a test to automate this functionality.

+ +First find and launch the application. +Then run the following script (Example 2) +
+from watsup.winGuiAuto import findControl,setEditText, findTopWindow,clickButton
+import os
+import os.path
+
+FILENAME='atestfile.txt'
+
+def main():
+    # delete any occurrence of this file from the disk
+    if os.path.exists(FILENAME):
+        os.remove(FILENAME)
+        
+    form=findTopWindow(wantedText='Simple Form')
+    button=findControl(form,wantedText='Create file')
+    editbox=findControl(form,wantedClass='TEdit')
+    
+    # enter a filename:
+    setEditText(editbox,[FILENAME])
+    print 'clicking button to create file'
+		clickButton(button)
+    
+    # now check that the file is there
+    if os.path.exists(FILENAME):
+        print 'file %s is present' %FILENAME
+    else:
+        print "file %s isn't there" % FILENAME     
+
+if __name__=='__main__':
+    main()    
+
+
+
+
+ + +

Example 3 - automating program launch and termination

+ +

It's a bit tedious having to start and close the application each time. +Example 3 launches the application, +if it isn't already running, and terminates it on +completion of the test

+ +
+from watsup.launcher import launchApp,terminateApp
+from watsup.winGuiAuto import findTopWindows                            
+import example2
+
+# find an instance of SimpleForm. If one isn't there, launch it
+
+forms=findTopWindows(wantedText='Simple Form')
+if forms:
+    form=forms[0]
+else:
+    form=launchApp('simple.exe',wantedText='Simple Form')    
+
+example2.main()
+
+# and terminate the form
+terminateApp(form)    
+
+
+ +launchApp starts the application in a separate thread, +and looks for a window with caption containing "Simple Form", +returning the window handle of the recovered form. + +terminateApp attempts to close the form, by trying to activate menu item File-Exit, or, failing that, +sending Alt + F4. + +

Example 4 - finding windows and controls

+ +

In building scripts, we need to be able to find the class and/or text of the many windows and controls +to be investigated or invoked.

+ +

In the tools directory, there's a tool - ShowWindows.bat - to assist us with this.

+Show Windows 1 + + +

Clicking the "Register" button persists information about +the existing windows running on the system (and it tells you how many, FYI). +Clicking the "Find new" button will report all non-trivial windows and all their +constituent controls which have appeared in the windows environment +since the last "Register" click. + +So to test our program simple.exe, launch ShowWindows, click Register. +Then launch simple.exe and +and click the Find New button. +The associated text box shows n/m, where m is the total number of new windows found, +and n is the number of those which are significant (ie have any controls) and are reported.

+ +Show Windows 2 + + +

Performance Tests

+ +

Performance tests, in this definition, are single-client scripts, +which are similar in operation to the functional tests above, +but for which certain steps of the tests +must either be done within an acceptable timeframe ("CHECKING") +and/or the time taken for those steps +should be recorded for subsequent analysis ("RECORDING").

+ +

WATSUP provides a simple mechanism to add such tests to existing functional tests. +In examples 4a & 4b, we launch almost identical applications, +perform.exe and perform2.exe respectively. + When the button is clicked, the text "Finished" is written +to the edit box. The difference between the programs is that the former is + coded to wait for 1/2 second before "Finished" +appears; in the latter case, the delay is 1.5 seconds.

+ +

In both cases, we are setting a performance test that the process +take no more than 1 second. +Clearly, we should expect example 4a to be ok and example 4b to fail. +

+ + +

So we have Example 4a

+
+from example4 import main
+
+main('perform.exe','Performance Form 1')
+
+
+

and Example 4b

+
+from example4 import main
+
+main('perform2.exe','Performance Form 2')
+
+
+ +

which reference Example 4:

+
+
+from watsup.launcher import launchApp,terminateApp 
+from watsup.winGuiAuto import findTopWindows, findControl,getEditText,clickButton  
+from watsup.performance import PerformanceCheck,PerformanceCheckError  
+from time import sleep,time                      
+
+def main(myExecutable,myWantedText):
+    # find an instance of SimpleForm. If one isn't there, launch it
+    forms=findTopWindows(wantedText=myWantedText)
+    if forms:
+        form=forms[0]
+    else:
+        form=launchApp(myExecutable,wantedText=myWantedText)       
+    
+    button=findControl(form,wantedText='Click me')
+    editbox=findControl(form,wantedClass='TEdit')
+
+    #start a performance check instance
+    p=PerformanceCheck()
+    
+    clickButton(button)    
+    
+    # belts and braces to avoid infinite waiting!
+    maxWaitTime=2.0
+    startTime=time()
+    
+    while time()-startTime<maxWaitTime:
+        t=getEditText(editbox)
+        if t:
+            break
+        else:
+            sleep(0.1)
+    else:
+        raise Exception,'Failed to get value after maxWaitTime of %s secs' % maxWaitTime        
+    
+    try:
+        try:
+           #do the check/recording step, identifying this step with the wantedtext
+            p.check(myWantedText,1.0)    
+        except PerformanceCheckError,e:
+            print '** Failed: %s' % e
+            
+    # and terminate the form
+    finally:
+        terminateApp(form)      
+
+if __name__=='__main__':
+    print ' please run example4a or 4b'
+
+
+ +

Key points in example4.py

+ +

Immediately prior to clicking the button, we establish a PerformanceCheck instance, +which, among other things, establises a timer. +Every time the check() method is called on a PerformanceCheck instance, the following occurs:

+ +

Also if we are CHECKING (the default condition), +that time is checked against the number of seconds added as the +second parameter. +If the elapsed time exceeds the value of the 2nd parameter, an exception is raised.

+ +

So in example4.py, we see that the check method requires a 1 second acceptance. +Hence example4a succeeds and example4b fails. +

+ +

Regression Testing

+ +

Functional and performance scripts such as those above are +immediately useable within a test framework - +the excellent python unit test framework is highly recommended +(unittest.py, which comes along with your python installation). +This then enables the tester to develop complete regression tests +involving any combination of Functional & Performance testing.

+

For an example of the use of functional and performance tests within +the unit test framework, run the program framework.bat in the tools subdirectory. +This will launch a nice user interface from which sets of test cases can be run: +

+ + +

Select the File menu option, and you have the option to load files which +contain testcases, or directories/directory trees. If select the "Load files" +option, and navigate up one directory, and then down through examples and the unittests +directories, you should find, and select, exampleTests.py. +The Framework program examines the selected file(s) and extracts the TestCases, +presents in the top frame

+ + + +

Selecting Menu option Testing - Run Tests (or the long button labelled Run Tests), + will cause each test to be run; success or failure is shown in the lower frame

+ + +

For more information on python's unit test module, refer to the python documentation. +Finally, it is worth noting that this framework will work with any unit tests, not just +those specifically testing windows application, so you can test +elements of the logic that you have written in other applications. + +

Downloads

+ +Download watsup here +

(This package should be unzipped in the site-packages directory in your python installation)

+ +

Dependencies

+ + +

Credits

+ +

The framework test tool was built from parts in unittestgui.py by Chris Liechti. +Much of the core functionality in WATSUP derives from the important work by + Simon Brunning, + who, in his module winGuiAuto.py provided concise, accessible mechanisms to + access and "click" windows controls & menus; Simon's work recognises the huge + contribution that Mark Hammond has made to the python community (and wider) + in providing pywin32, comprehensive win32 API modules for python. +

+ +Dr Tim Couper
+timc@tizmoi.net + + + diff --git a/agent/crawl/watsup/docs/images/tizmoi.jpg b/agent/crawl/watsup/docs/images/tizmoi.jpg new file mode 100644 index 0000000000000000000000000000000000000000..eccd841395c5ff450028960a4685b18248b9447c GIT binary patch literal 6827 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 literal 0 HcmV?d00001 diff --git a/agent/crawl/watsup/docs/tac.css b/agent/crawl/watsup/docs/tac.css new file mode 100644 index 0000000..3ca6dbd --- /dev/null +++ b/agent/crawl/watsup/docs/tac.css @@ -0,0 +1,7 @@ +body {font-family: "Trebuchet MS", Verdana, sans-serif} +code {font: Courier New; size 12} +h1 {color: navy} +h2 {color: navy} +h3 {color: navy} +h4 {color: navy} + diff --git a/agent/crawl/watsup/launcher.py b/agent/crawl/watsup/launcher.py new file mode 100644 index 0000000..e34441e --- /dev/null +++ b/agent/crawl/watsup/launcher.py @@ -0,0 +1,116 @@ +""" launch & terminate a windows application +""" + +# Author : Tim Couper - tim@2wave.net +# Date : 22 July 2004 +# Version : 1.0 +# Copyright : Copyright TAC Software Ltd, under Python-style licence. +# Provided as-is, with no warranty. +# Notes : Requires Python 2.3, win32all, ctypes, SendKeys & winGuiAuto + + +import os.path +import threading +import win32gui +#import win32api +#import win32con +import SendKeys +from watsup.utils import WatsupError +from watsup.winGuiAuto import findTopWindow,findTopWindows, \ + WinGuiAutoError,activateMenuItem + +MENU_TERMINATIONS=[('file', 'exit'),('file', 'quit')] + +def launchApp(program,wantedText=None,wantedClass=None,verbose=False): + global p + p=AppThread(program,verbose) + p.start() + try: + return findTopWindow(wantedText=wantedText,wantedClass=wantedClass) + except WinGuiAutoError,e: + pass + + # find all the Windows that are lurking about, and terminate them + # this I can't do until terminateApp can find a window and bring it to focus + # for now, find one top window and return that; if there are none, + # it should raise an exception + try: + return findTopWindows(wantedText=wantedText,wantedClass=wantedClass)[0] + except IndexError: + raise WatsupError,'Failed to find any windows' + +class AppThread(threading.Thread): + def __init__(self,program,verbose=False): + threading.Thread.__init__(self,name=program) + self.program=program + self.verbose=verbose + + def run(self): + """main control loop""" + #check the given program exists, and is a file: + # if the program has no type, make it .exe: + if os.path.splitext(self.program)[1]=='': + prog='%s.exe' % self.program + else: + prog=self.program + + prog=os.path.abspath(prog) + + if os.path.isfile(prog): + # launch the new application in a separate thread + if self.verbose: + print '..launching "%s"' % prog + os.system('"%s"' % prog) + + else: + print 'AppThread: program not found: "%s"\n' % prog + + if self.verbose: + print '..terminating "%s"' % prog + + +def terminateApp(hwnd=None): + """Terminate the application by: + If there's a file-exit menu, click that + If there's a file-Quit menu, click that + Otherwise, send Alt-F4 to the current active window +** it's the calling program responsibility to get the right active window + """ + if hwnd: + for fileExit in MENU_TERMINATIONS: + try: + activateMenuItem(hwnd, fileExit) + return + except WinGuiAutoError: + pass + + # blast the current window with ALT F4 .. + SendKeys.SendKeys("%{F4}") + #win32gui.PumpWaitingMessages() +## from watsup.winGuiAuto import findControl,findTopWindows +## topHs=findTopWindows(wantedText='MyTestForm') +## for topH in topHs: +## #hwnd=findControl(topH) +## a=win32gui.findWindow(topH) +## print a, topH +## win32gui.SetFocus(topH) +## win32gui.PumpWaitingMessages() +## SendKeys.SendKeys("%{F4}") +## + +## if not hwnd and (wantedText or wantedClass): +## hwnds=findTopWindows(wantedText=wantedText,wantedClass=wantedClass) +## elif hwnd: +## hwnds=[hwnd] +## +## if hwnds: +## for hwnd in hwnds: +## #win32gui.SetFocus(hwnd) +## #win32gui.SetActiveWindow(hwnd) +## # mm the above don;t work, perhaps because the +## # window is actually to be found in another thread +## +## SendKeys.SendKeys("%{F4}") + +if __name__=='__main__': + pass \ No newline at end of file diff --git a/agent/crawl/watsup/performance.py b/agent/crawl/watsup/performance.py new file mode 100644 index 0000000..8417f58 --- /dev/null +++ b/agent/crawl/watsup/performance.py @@ -0,0 +1,181 @@ +# Author : Tim Couper - timc@tizmoi.net +# Date : 22 July 2004 +# Version : 1.0 +# Copyright : Copyright TAC Software Ltd, under Python-style licence. +# Provided as-is, with no warranty. + +from time import time,ctime +import sys +import cPickle + +#------------------------------------------------------------------------------- +# hidden globals + +_PerformanceDataThisRun=None +_PerformanceDataStore=None + +_doPerformanceChecks=True +_recordPerformanceData=False + +#------------------------------------------------------------------------------- +# externals + +def isRecording(): + return _recordPerformanceData + +def isChecking(): + return _doPerformanceChecks + +def doRecording(doIt=True): + global _recordPerformanceData + _recordPerformanceData=doIt + +def doChecking(doIt=True): + global _doPerformanceChecks + _doPerformanceChecks=doIt + +def onOff(bool): + if bool: + return 'On' + else: + return 'Off' + +def getPerformanceDataThisRun(): + "returns the Performance data for this run of the tests" + global _PerformanceDataThisRun + if _PerformanceDataThisRun==None: + # create an instance, and load up what was already there + _PerformanceDataThisRun=PerformanceDataThisRun() + return _PerformanceDataThisRun + +def getPerformanceDataStore(): + "returns the all Performance data for all runs of the tests" + global _PerformanceDataStore + if _PerformanceDataStore==None: + # create an instance, and load up what was already there + _PerformanceDataStore=PerformanceDataStore() + try: + _PerformanceDataStore=cPickle.load(open(_PerformanceDataStore.filename)) + except IOError,EOFError: + pass + return _PerformanceDataStore + +PERFORMANCE_STORE_FILENAME='PerformanceDataStore.dat' + +class PerformanceDataCollectionError(Exception): pass +class PerformanceDataCollection(dict): + def __str__(self): + lines=[] + keys=self.keys() + keys.sort() + for msg in keys: + lines.append(str(msg)) + pdiList=self[msg] + pdiList.sort() + for pdi in pdiList: + lines.append(' %s' % pdi) + return '\n'.join(lines) + +#class PerformanceDataThisRunError(Exception): pass +class PerformanceDataThisRun(PerformanceDataCollection): pass + +class PerformanceDataStoreError(Exception): pass +class PerformanceDataStore(PerformanceDataCollection): + 'performs persistent store of PerformanceDataItems' + def __init__(self, filename=PERFORMANCE_STORE_FILENAME): + self.filename=filename + + def addItem(self,msg,pdi): + 'adds a pdi item to items, in the right place' + # msg must be immutable + if isinstance(pdi,PerformanceDataItem): + if not self.has_key(msg): + self[msg]=[] + self[msg].append(pdi) + else: + e='addItem can only accept PerformanceDataItem instances (%s: %s)' % (msg,str(pdi)) + raise PerformanceDataStoreError,e + +#------------------------------------------------------------------------------- + +class PerformanceCheckError(AssertionError): pass + +class PerformanceCheck(object): + + def __init__(self): + self.reset() + + def reset(self): + self.startTime=time() + + def check(self,msg,maxDelay=None): + res=time()-self.startTime + + # if we're storing the data + if isRecording(): + pdi=PerformanceDataItem(self.startTime,res,maxDelay) + pd=getPerformanceDataThisRun() + if not pd.has_key(msg): + pd[msg]=[] #list of PerformanceData instances, we hope + + # add it to the current data being processed + pd[msg].append(pdi) + + # and add it to the store that we're going to persist + pds=getPerformanceDataStore() + pds.addItem(msg,pdi) + cPickle.dump(pds,open(pds.filename,'w')) + + # if we're acting on performance tests: + if isChecking() and maxDelay<>None and (res>float(maxDelay)): + res=round(res,2) + msg='%s [Delay > %s secs (%s secs)]' % (msg,maxDelay,res) + raise PerformanceCheckError,msg + +class PerformanceDataItem(object): + "holds a result (as elapsed time value in secs) and the time of invocation" + def __init__(self,startTime,elapsedTime,maxDelay=None): + self.startTime=startTime # time of run + self.elapsedTime=round(elapsedTime,2) # elapsed time in secs + self.maxDelay=maxDelay # user defined delay for check + # if None, then there is no upper threshhold + + def __str__(self): + if self.maxDelay==None: + ok='OK' + md='' + else: + if self.elapsedTime<=self.maxDelay: + ok='OK' + else: + ok='Fail' + md= ' (%s)' % self.maxDelay + + return '%s: %s%s %s' % (ctime(self.startTime), self.elapsedTime, md, ok) + + def __cmp__(self,other): + if self.startTimeother.startTime: + return 1 + else: + return 0 + + +def nicePrint(filename=sys.stdout): + def wout(f,text): + f.write('%s\n' % text) + + if filename==sys.stdout: + f=sys.stdout + else: + f=open(filename,'w') + +## from watsup.timedunittest import getPerformanceDataStore,getPerformanceDataThisRun, \ +## isRecording + if isRecording(): + for func in (getPerformanceDataThisRun,getPerformanceDataStore): + fn=func.__name__ + wout(f,'\n%s\n%s\n' % (fn,'-'*len(fn))) + wout(f,str(func())) + diff --git a/agent/crawl/watsup/timedunittest.py b/agent/crawl/watsup/timedunittest.py new file mode 100644 index 0000000..6413fc6 --- /dev/null +++ b/agent/crawl/watsup/timedunittest.py @@ -0,0 +1,279 @@ +# Author : Tim Couper - tim@2wave.net +# Date : 22 July 2004 +# Version : 1.0 +# Copyright : Copyright TAC Software Ltd, under Python-style licence. +# Provided as-is, with no warranty. + +from unittest import TestCase +from time import time,sleep,ctime +import sys + +if sys.platform=='win32': + import win32gui + def pump(): + # clear down any waiting messages (it all helps) + win32gui.PumpWaitingMessages() +else: + pump=None + +###------------------------------------------------------------------------------- +### hidden globals +## +##_PerformanceDataThisRun=None +##_PerformanceDataStore=None +##_doPerformanceChecks=True +##_recordPerformanceData=True +###------------------------------------------------------------------------------- +## +###------------------------------------------------------------------------------- +### externals +## +##def isRecording(): +## return _recordPerformanceData +## +##def isChecking(): +## return _doPerformanceChecks +## +##def doRecording(doIt=True): +## global _recordPerformanceData +## _recordPerformanceData=doIt +## +##def doChecking(doIt=True): +## global _doPerformanceChecks +## _doPerformanceChecks=doIt +## +##def getPerformanceDataThisRun(): +## "returns the Performance data for this run of the tests" +## global _PerformanceDataThisRun +## if _PerformanceDataThisRun==None: +## # create an instance, and load up what was already there +## _PerformanceDataThisRun=PerformanceDataThisRun() +## return _PerformanceDataThisRun +## +##def getPerformanceDataStore(): +## "returns the all Performance data for all runs of the tests" +## global _PerformanceDataStore +## if _PerformanceDataStore==None: +## # create an instance, and load up what was already there +## _PerformanceDataStore=PerformanceDataStore() +## try: +## _PerformanceDataStore=cPickle.load(open(_PerformanceDataStore.filename)) +## except IOError,EOFError: +## pass +## return _PerformanceDataStore +## +##PERFORMANCE_STORE_FILENAME='PerformanceDataStore.dat' +## +##class PerformanceDataCollectionError(Exception): pass +##class PerformanceDataCollection(dict): +## def __str__(self): +## lines=[] +## keys=self.keys() +## keys.sort() +## for msg in keys: +## lines.append(str(msg)) +## pdiList=self[msg] +## pdiList.sort() +## for pdi in pdiList: +## lines.append(' %s' % pdi) +## return '\n'.join(lines) +## +###class PerformanceDataThisRunError(Exception): pass +##class PerformanceDataThisRun(PerformanceDataCollection): pass +## +##class PerformanceDataStoreError(Exception): pass +##class PerformanceDataStore(PerformanceDataCollection): +## 'performs persistent store of PerformanceDataItems' +## def __init__(self, filename=PERFORMANCE_STORE_FILENAME): +## self.filename=filename +## +## def addItem(self,msg,pdi): +## 'adds a pdi item to items, in the right place' +## # msg must be immutable +## if isinstance(pdi,PerformanceDataItem): +## if not self.has_key(msg): +## self[msg]=[] +## self[msg].append(pdi) +## else: +## e='addItem can only accept PerformanceDataItem instances (%s: %s)' % (msg,str(pdi)) +## raise PerformanceDataStoreError,e +## +###------------------------------------------------------------------------------- +## +##class PerformanceCheckError(AssertionError): pass +## +##class PerformanceCheck(object): +## +## def __init__(self): +## self.reset() +## +## def reset(self): +## self.startTime=time() +## +## def check(self,msg,maxDelay=None): +## res=time()-self.startTime +## +## # if we're storing the data +## if isRecording(): +## pdi=PerformanceDataItem(self.startTime,res,maxDelay) +## pd=getPerformanceDataThisRun() +## if not pd.has_key(msg): +## pd[msg]=[] #list of PerformanceData instances, we hope +## +## # add it to the current data being processed +## pd[msg].append(pdi) +## +## # and add it to the store that we're going to persist +## pds=getPerformanceDataStore() +## pds.addItem(msg,pdi) +## cPickle.dump(pds,open(pds.filename,'w')) +## +## # if we're acting on performance tests: +## if isChecking() and maxDelay<>None and (res>float(maxDelay)): +## res=round(res,2) +## msg='%s [Delay > %s secs (%s secs)]' % (msg,maxDelay,res) +## raise PerformanceCheckError,msg +## +##class PerformanceDataItem(object): +## "holds a result (as elapsed time value in secs) and the time of invocation" +## def __init__(self,startTime,elapsedTime,maxDelay=None): +## self.startTime=startTime # time of run +## self.elapsedTime=round(elapsedTime,2) # elapsed time in secs +## self.maxDelay=maxDelay # user defined delay for check +## # if None, then there is no upper threshhold +## +## def __str__(self): +## if self.maxDelay==None: +## ok='OK' +## md='' +## else: +## if self.elapsedTime<=self.maxDelay: +## ok='OK' +## else: +## ok='Fail' +## md= ' (%s)' % self.maxDelay +## +## return '%s: %s%s %s' % (ctime(self.startTime), self.elapsedTime, md, ok) +## +## def __cmp__(self,other): +## if self.startTimeother.startTime: +## return 1 +## else: +## return 0 +## + +maxWaitSecsDefault=3.0 +retrySecsDefault=0.2 + +class TimedOutError(AssertionError): pass + +class TimedTestCase(TestCase): + # extends the functionality of unittest.TestCase to + # allow multiple attempts at assertion, failif, for + # a specific length of time. If the test is not successful by the time + # that Then it fails + + def __init__(self, methodName='runTest',maxWaitSecsDefault=1.0,retrySecsDefault=0.2): + TestCase.__init__(self,methodName) + self.maxWaitSecsDefault=float(maxWaitSecsDefault) + self.retrySecsDefault=float(retrySecsDefault) + + def doTimeTest(self,func,*args): + # remove the last 2 args, as they're out timing values: + maxWaitSecs=args[-2] + retrySecs=args[-1] + args=args[:-2] + + if maxWaitSecs==None: + maxWaitSecs=self.maxWaitSecsDefault + else: + try: + maxWaitSecs=float(maxWaitSecs) + except TypeError,e: + e='%s (maxWaitSecs "%s")' % (e,maxWaitSecs) + raise TypeError,e + + if retrySecs==None: + retrySecs=self.retrySecsDefault + else: + try: + retrySecs=float(retrySecs) + except TypeError,e: + e='%s (retrySecs "%s")' % (e,retrySecs) + raise TypeError,e + retrySecs=max(0,retrySecs-.001) # allow for the pump,etc below + + t=time() + while (time()-t)findAppControls.py example/example1 + +c:>findAppControls.py -v example/example1 + +- this does it in verbose mode +""" + +# Author : Tim Couper - tim@tizmoi.net +# Date : 1 August 2004 +# Copyright : Copyright TAC Software Ltd, under Python-like licence. +# Provided as-is, with no warranty. +# Notes : Requires watsup + + +from optparse import OptionParser +parser = OptionParser() +parser.add_option("-v", "--verbose", + + action="store_true", dest="verbose", default=False, + + help="print verbose messages") + +(options, args) = parser.parse_args() +if len(args)<1: + print 'Usage: findAppControls.py ' + +else: + from watsup.AppControls import AppControls + try: + print 'passing',args[0] + a=AppControls(args[0],verbose=options.verbose) + a.run() + + except: + import sys + print '\n** %s **\n' % sys.exc_info()[1] + import traceback + traceback.print_tb(sys.exc_info()[2]) + diff --git a/agent/crawl/watsup/tools/fmShowWindows.py b/agent/crawl/watsup/tools/fmShowWindows.py new file mode 100644 index 0000000..96b5a8f --- /dev/null +++ b/agent/crawl/watsup/tools/fmShowWindows.py @@ -0,0 +1,127 @@ +#Boa:Frame:ShowWindows + +# Author : Tim Couper - tim@tizmoi.net +# Date : 1 August 2004 +# Copyright : Copyright TAC Software Ltd, under Python-like licence. +# Provided as-is, with no warranty. +# Notes : Requires watsup, wxPython + +from wxPython.wx import * +from wxPython.lib.anchors import LayoutAnchors + +from watsup.tools.showWindows import findAll,findNew,readPickle +from watsup.winGuiAuto import dumpWindow +from watsup.utils import tupleHwnd +import pprint + +def create(parent): + return ShowWindows(parent) + +[wxID_SHOWWINDOWS, wxID_SHOWWINDOWSFINDNEW, wxID_SHOWWINDOWSNEWWINDOWS, + wxID_SHOWWINDOWSPANEL1, wxID_SHOWWINDOWSREGISTER, wxID_SHOWWINDOWSREGISTERED, + wxID_SHOWWINDOWSTEXT, +] = map(lambda _init_ctrls: wxNewId(), range(7)) + +class ShowWindows(wxFrame): + def _init_ctrls(self, prnt): + # generated method, don't edit + wxFrame.__init__(self, id=wxID_SHOWWINDOWS, name='ShowWindows', + parent=prnt, pos=wxPoint(424, 184), size=wxSize(456, 433), + style=wxMINIMIZE_BOX | wxSTATIC_BORDER | wxCAPTION | wxSYSTEM_MENU, + title='ShowWindows 1.0') + self.SetClientSize(wxSize(448, 399)) + self.SetToolTipString('ShowWindow') + self.Center(wxBOTH) + self.Enable(True) + self.SetSizeHints(-1, -1, -1, -1) + self.SetThemeEnabled(False) + + self.panel1 = wxPanel(id=wxID_SHOWWINDOWSPANEL1, name='panel1', + parent=self, pos=wxPoint(0, 350), size=wxSize(450, 50), + style=wxTAB_TRAVERSAL) + self.panel1.SetConstraints(LayoutAnchors(self.panel1, True, True, False, + False)) + + self.Register = wxButton(id=wxID_SHOWWINDOWSREGISTER, label='Register', + name='Register', parent=self.panel1, pos=wxPoint(32, 13), + size=wxSize(75, 23), style=0) + self.Register.SetToolTipString('Register all windows info') + EVT_BUTTON(self.Register, wxID_SHOWWINDOWSREGISTER, + self.OnRegisterButton) + + self.FindNew = wxButton(id=wxID_SHOWWINDOWSFINDNEW, label='Find New', + name='FindNew', parent=self.panel1, pos=wxPoint(304, 13), + size=wxSize(75, 23), style=0) + EVT_BUTTON(self.FindNew, wxID_SHOWWINDOWSFINDNEW, self.OnFindNewButton) + + self.Text = wxTextCtrl(id=wxID_SHOWWINDOWSTEXT, name='Text', + parent=self, pos=wxPoint(0, 0), size=wxSize(450, 350), + style=wxRAISED_BORDER | wxTE_WORDWRAP | wxTE_MULTILINE, value='') + + self.Registered = wxTextCtrl(id=wxID_SHOWWINDOWSREGISTERED, + name='Registered', parent=self.panel1, pos=wxPoint(110, 16), + size=wxSize(40, 16), style=wxTE_CENTER | wxTE_READONLY, value='') + self.Registered.SetToolTipString('No of windows registered on system') + self.Registered.SetBackgroundColour(wxColour(175, 175, 175)) + + self.NewWindows = wxTextCtrl(id=wxID_SHOWWINDOWSNEWWINDOWS, + name='NewWindows', parent=self.panel1, pos=wxPoint(382, 16), + size=wxSize(40, 16), style=wxTE_CENTER | wxTE_READONLY, value='') + self.NewWindows.SetToolTipString('No of new windows found') + self.NewWindows.SetBackgroundColour(wxColour(175, 175, 175)) + + def __init__(self, parent): + self._init_ctrls(parent) + #load up the last value for your info + ws=readPickle() + if ws: + self.Registered.SetValue(str(len(ws))) + + def OnRegisterButton(self, event): + ws=findAll() + self.Registered.SetBackgroundColour(wxColour(255, 255, 255)) + self.Registered.SetValue(str(len(ws))) + + def OnFindNewButton(self, event): + ws=findNew() + self.NewWindows.SetBackgroundColour(wxColour(255, 255, 255)) + # write the details to the text box + withControls=self.writeNewWindows(ws) + self.NewWindows.SetValue('%s/%d' % (withControls,len(ws))) + + def writeNewWindows(self,ws): + noControls=0 + withControls=0 + txt=[] + for w in ws: + + dw=dumpWindow(w) + if not dw: + noControls+=1 + continue + + t=tupleHwnd(w) + # don't bother with ShowWindows application: + + wclass=t[2] + wtext=t[1] + if wclass=='wxWindowClass' and wtext.startswith('ShowWindows'): + noControls+=1 + continue + + if wtext: + wtext="%s" % wtext + else: + wtext='' + + withControls+=1 + # write the heading window + #txt.append('%d. %s %s' % (withControls,wclass,wtext)) + txt.append('%d. %s' % (withControls,str(list(t)))) + txt.append(pprint.pformat(dw)) + txt.append('') + + self.Text.SetValue('\n'.join(txt)) + + return withControls + diff --git a/agent/crawl/watsup/tools/runTests.ini b/agent/crawl/watsup/tools/runTests.ini new file mode 100644 index 0000000..a528579 --- /dev/null +++ b/agent/crawl/watsup/tools/runTests.ini @@ -0,0 +1,4 @@ +[main] +checking = True +current_directory = C:\Python23\Lib\site-packages\watsup\examples\unittests + diff --git a/agent/crawl/watsup/tools/showWindows.py b/agent/crawl/watsup/tools/showWindows.py new file mode 100644 index 0000000..1aafe9d --- /dev/null +++ b/agent/crawl/watsup/tools/showWindows.py @@ -0,0 +1,34 @@ +# logic for wxShowWindows + +# Author : Tim Couper - timc@tizmoi.net +# Date : 1 August 2004 +# Copyright : Copyright TAC Software Ltd, under Python-like licence. +# Provided as-is, with no warranty. +# Notes : Requires watsup + +import cPickle +from watsup.AppControls import findNewTopWindows +from watsup.winGuiAuto import dumpWindow +from watsup.utils import dumpHwnd +import os.path +from types import ListType + +PICKLE_FILE='findall.pkl' + +def readPickle(pickle_file=PICKLE_FILE): + #reads the list in the pickle file if possible + if os.path.exists(pickle_file): + return cPickle.load(open(pickle_file)) + else: + return [] + +def findAll(pickle_file=PICKLE_FILE): + # get all the top windows: + res=findNewTopWindows() + cPickle.dump(res,open(pickle_file,'w')) + return res + +def findNew(pickle_file=PICKLE_FILE): + # get all the top windows, and return any new ones + olds=readPickle(pickle_file) + return findNewTopWindows(olds) diff --git a/agent/crawl/watsup/tools/watsup_framework.bat b/agent/crawl/watsup/tools/watsup_framework.bat new file mode 100644 index 0000000..2ffdf75 --- /dev/null +++ b/agent/crawl/watsup/tools/watsup_framework.bat @@ -0,0 +1 @@ +python watsup_framework.py \ No newline at end of file diff --git a/agent/crawl/watsup/tools/watsup_framework.py b/agent/crawl/watsup/tools/watsup_framework.py new file mode 100644 index 0000000..f6ff39f --- /dev/null +++ b/agent/crawl/watsup/tools/watsup_framework.py @@ -0,0 +1,653 @@ + +# Author : Tim Couper - timc@tizmoi.net +# Date : 1 August 2004 +# Copyright : Copyright TAC Software Ltd, under Python-like licence. +# Provided as-is, with no warranty. +# Notes : Requires wxPython,watsup +# Based heavily on unittestgui.py by Chris Liechti + +import unittest, os, imp, time, traceback,sys + +## import all of the wxPython GUI package +from wxPython.wx import * +from wxPython.grid import * + +from watsup.performance import doChecking,onOff,isChecking +from watsup.tools.buildSuite import buildSuite +from time import ctime + +BASE_TITLE="Watsup Framework" +INI_FILE='./runTests.ini' + +from ConfigParser import ConfigParser,NoOptionError, NoSectionError + +#specify editor, make it return immediately, otherwise the GUI will wait +#until its closed. on win use "start cmd", on un*x "cmd&" +EDITOR = r'start c:\tools\wscite\scite "%(filename)s" -goto:%(lineno)s' +def starteditor(filename, lineno=1): + if os.path.exists(filename): + os.system(EDITOR % {'filename':filename, 'lineno':lineno}) + else: + wxMessageBox("Cannot locate sourcefile:\n%s" % filename, "Can't start editor...", wxOK) + +#---------------------------------------------------------------- + +class GUITestResult(unittest.TestResult): + """A test result class that can print formatted text results to a stream. + """ + separator1 = '=' * 70 + separator2 = '-' * 70 + + def __init__(self, listview, progress, descriptions, verbosity): + unittest.TestResult.__init__(self) + self.listview = listview + self.showAll = verbosity > 1 + self.descriptions = descriptions + self.progress = progress + self.testdescr = None + self.stream = sys.stdout + + def getDescription(self, test): + if self.descriptions: + return test.shortDescription() or str(test) + else: + return str(test) + + def startTest(self, test): + unittest.TestResult.startTest(self, test) + self.testdescr = self.getDescription(test) + if self.showAll: + self.stream.write(self.getDescription(test)) + self.stream.write(" ... ") + + def _correctFilename(self, filename): + if filename[-4:] in ('.pyc', '.pyo'): + return filename[:-1] + return filename + + def addSuccess(self, test): + unittest.TestResult.addSuccess(self, test) + if self.showAll: + self.stream.write("ok\n") + self.listview.Append( ( + 'Ok', + self.testdescr, + '', + None, + None + ) ) + self.progress.tick() + + def addError(self, test, err): + unittest.TestResult.addError(self, test, err) + if self.showAll: + self.stream.write("ERROR\n") + try: + filename = self._correctFilename(err[2].tb_frame.f_globals['__file__']) + except KeyError: + filename = None + lineno = err[2].tb_lineno + self.listview.Append( ( + 'Error', + self.testdescr, + traceback.format_exception(*err)[-1].rstrip(), + self._exc_info_to_string(err), + (filename, lineno) + ) ) + self.progress.tick() + + def addFailure(self, test, err): + unittest.TestResult.addFailure(self, test, err) + if self.showAll: + self.stream.write("FAIL\n") + try: + filename = self._correctFilename(err[2].tb_frame.f_globals['__file__']) + except KeyError: + filename = None + lineno = err[2].tb_lineno + self.listview.Append( ( + 'Fail', + self.testdescr, + traceback.format_exception(*err)[-1].rstrip(), + self._exc_info_to_string(err), + (filename, lineno) + ) ) + self.progress.tick() + + def printErrors(self): + if self.showAll: + self.stream.write("\n") + self.printErrorList('ERROR', self.errors) + self.printErrorList('FAIL', self.failures) + + def printErrorList(self, flavour, errors): + for test, err in errors: + self.stream.write(self.separator1) + self.stream.write("\n%s: %s\n" % (flavour,self.getDescription(test))) + self.stream.write(self.separator2) + self.stream.write("\n%s\n" % err) + +class GUITestRunner: + """A test runner class that displays results in textual form. + + It prints out the names of tests as they are run, errors as they + occur, and a summary of the results at the end of the test run. + """ + def __init__(self, listview, progress, stream=sys.stderr, descriptions=1, verbosity=2): + self.listview = listview + self.progress = progress + self.stream = unittest._WritelnDecorator(stream) + self.descriptions = descriptions + self.verbosity = verbosity + + def _makeResult(self): + return GUITestResult(self.listview, self.progress, self.descriptions, self.verbosity) + + def run(self, test): + "Run the given test case or test suite." + result = self._makeResult() + startTime = time.time() + test(result) + stopTime = time.time() + timeTaken = float(stopTime - startTime) + result.printErrors() + self.stream.writeln(result.separator2) + run = result.testsRun + self.stream.writeln("Ran %d test%s in %.3fs" % + (run, run == 1 and "" or "s", timeTaken)) + self.stream.writeln() + if not result.wasSuccessful(): + self.stream.write("FAILED (") + failed, errored = map(len, (result.failures, result.errors)) + if failed: + self.stream.write("failures=%d" % failed) + if errored: + if failed: self.stream.write(", ") + self.stream.write("errors=%d" % errored) + self.stream.writeln(")") + else: + self.stream.writeln("OK") + + return result + +#---------------------------------------------------------------- + +def lastline(t): + t = t.rstrip() + n = t.rfind('\n') + if n >= 0: + return t[n+1:] + return t + +#---------------------------------------------------------------- + +class ResultView(wxListCtrl): + PM_DETAIL = wxNewId() + PM_LOCATE = wxNewId() + + def __init__(self, parent): + wxListCtrl.__init__(self, parent, -1, + style=wxLC_REPORT|wxSUNKEN_BORDER|wxLC_VIRTUAL|wxLC_VRULES,#|wxLC_HRULES, + size=(500,200)) + + self.InsertColumn(0, '-Ok-') + self.InsertColumn(1, 'Description') + self.InsertColumn(2, 'Details') + + self.SetColumnWidth(0, 40) + w = self.GetSize()[0] - self.GetColumnWidth(0) + self.SetColumnWidth(1, w/2) + self.SetColumnWidth(2, w/2) + + EVT_RIGHT_DOWN(self, self.OnRightClick) + EVT_LIST_ITEM_SELECTED(self, self.GetId(), self.OnItemSelected) + EVT_LIST_ITEM_ACTIVATED(self, self.GetId(), self.OnItemActivated) + + self.red = wxListItemAttr() + self.red.SetBackgroundColour(wxRED) + self.green = wxListItemAttr() + self.green.SetBackgroundColour(wxColour(200,255,200)) #light green + self.orange = wxListItemAttr() + self.orange.SetBackgroundColour(wxColour(255,200,200)) #light red + self.result = [] + self.currentItem = None + + EVT_SIZE(self, self.OnSize) + + #node menu + self.nodemenu = wxMenu() + self.nodemenu.Append(self.PM_DETAIL, "Show Details") + #self.nodemenu.AppendSeparator() + #self.nodemenu.Append(self.PM_LOCATE, "Locate Source") + + EVT_MENU(self, self.PM_DETAIL, self.OnDetail) + #EVT_MENU(self, self.PM_LOCATE, self.OnLocate) + + def OnDetail(self, event=None): + if self.result[self.currentItem][3]: + wxMessageBox(self.result[self.currentItem][3], "Result details", wxOK) + + def OnLocate(self, event=None): + filename, lineno = self.result[self.currentItem][4] + print "locate",filename, lineno + starteditor(filename, lineno) + + def OnSize(self, event): + w = self.GetSize()[0] - self.GetColumnWidth(0) - 30 + if w < 180: w = 180 + self.SetColumnWidth(1, w/2) + self.SetColumnWidth(2, w/2) + + def Append(self, item): + self.result.append(item) + self.SetItemCount(len(self.result)) + #wxYield() + #self.Refresh() + + def DeleteAllItems(self): + self.result = [] + wxListCtrl.DeleteAllItems(self) + + def OnItemSelected(self, event): + self.currentItem = event.m_itemIndex + + def OnItemActivated(self, event): + self.currentItem = event.m_itemIndex + self.OnDetail() + + def OnRightClick(self, event): + pt = event.GetPosition() + item, flags = self.HitTest(pt) + if not flags & wxLIST_HITTEST_NOWHERE: + if self.currentItem is not None: + self.SetItemState(self.currentItem, 0, wxLIST_STATE_SELECTED ) + self.currentItem = item + self.SetItemState(item, wxLIST_STATE_SELECTED, wxLIST_STATE_SELECTED ) + if self.result[self.currentItem][3]: + self.PopupMenu(self.nodemenu, pt) #display popup menu + + def OnCopyAsText(self, all=0): + res = [] + item = -1; + while 1: + if all: + item = self.GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_DONTCARE); + else: + item = self.GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED); + text = '\t'.join(map(str, self.result[item])) + res.append(text) + if item == -1: + break + clip = wxClipboard() + clip.Open() + clip.SetData( wxTextDataObject('\n'.join(res)) ) + clip.Close() + + #--------------------------------------------------- + # These methods are callbacks for implementing the + # "virtualness" of the list... + def OnGetItemText(self, row, col): + #print row, col + try: + return str(self.result[row][col]) + except IndexError: + return '' + + def OnGetItemImage(self, item): + return 0 + + def OnGetItemAttr(self, item): + if self.result[item][0] == 'Error': + return self.red + elif self.result[item][0] == 'Fail': + return self.orange + elif self.result[item][0] == 'Ok': + return self.green + return None + +class TreeView(wxTreeCtrl): + PM_RUNSEL = wxNewId() + PM_LOCATE = wxNewId() + + def __init__(self, *args, **kwargs): + wxTreeCtrl.__init__(self, *args, **kwargs) + EVT_LEFT_DCLICK(self, self.OnLeftDClick) + EVT_RIGHT_DOWN(self, self.OnRightClick) + EVT_RIGHT_UP(self, self.OnRightUp) + EVT_TREE_BEGIN_LABEL_EDIT(self, self.GetId(), self.OnBeginEdit) + EVT_TREE_END_LABEL_EDIT (self, self.GetId(), self.OnEndEdit) + + #node menu +## self.nodemenu = wxMenu() +## self.nodemenu.Append(self.PM_RUNSEL, "Run selected") +## self.nodemenu.AppendSeparator() +## self.nodemenu.Append(self.PM_LOCATE, "Locate Source") +## +## EVT_MENU(self, self.PM_RUNSEL, self.OnRunSel) +## EVT_MENU(self, self.PM_LOCATE, self.OnLocate) + + #don't allow editing of node names + def OnBeginEdit(self, event): event.Veto() + def OnEndEdit(self, event): event.Veto() + + def OnLeftDClick(self, event): +## pt = event.GetPosition(); +## item, flags = self.HitTest(pt) +## #print("OnLeftDClick: %s" % self.GetItemText(item)) +## parent = self.GetItemParent(item) +## #self.SortChildren(parent) + event.Skip() + + def OnRightClick(self, event): + pt = event.GetPosition() + item, flags = self.HitTest(pt) + if not flags & wxTREE_HITTEST_NOWHERE: + self.SelectItem(item) + #self.PopupMenu(self.nodemenu, pt) #display node menu + + def OnRightUp(self, event): + pt = event.GetPosition(); + item, flags = self.HitTest(pt) + #self.tree.EditLabel(item) + + def OnCompareItems(self, item1, item2): + t1 = self.GetItemText(item1) + t2 = self.GetItemText(item2) + #print('compare: ' + t1 + ' <> ' + t2) + return cmp(t1,t2) + + def OnRunSel(self, event): + pass + def OnLocate(self, event): + pass + +#---------------------------------------------------------------- + +class ProgressBar(wxGauge): + def __init__(self, *args, **kwargs): + wxGauge.__init__(self, *args, **kwargs) + self.SetBezelFace(5) + self.SetShadowWidth(5) + self.increment = 1 + + def tick(self): + self.SetValue(self.GetValue() + self.increment) + +#---------------------------------------------------------------- + +class Frame(wxFrame): + ID_BUTTON = wxNewId() + #M_NEW = wxNewId() + M_OPENFILES = wxNewId() + M_OPENDIR = wxNewId() + M_OPENTREE = wxNewId() + M_EXIT = wxNewId() + M_COPYALL = wxNewId() + M_COPYSEL = wxNewId() + M_RUN = wxNewId() + M_CHECKING = wxNewId() + + + def __init__(self, parent, id, title = BASE_TITLE): + + # First, call the base class' __init__ method to create the frame + wxFrame.__init__(self, parent, id, title, wxPoint(100, 100), wxSize(100, 100)) + #variables + self.suite = None + + self.loadConfig() + + #menu + menuBar = wxMenuBar() + menu = wxMenu() + #menu.Append(self.M_NEW, "&New") + menu.Append(self.M_OPENFILES, "&Load Test File(s)") + menu.Append(self.M_OPENDIR, "&Load Test Directory") + menu.Append(self.M_OPENTREE, "&Load Test Directory Tree") + menu.AppendSeparator() + menu.Append(self.M_EXIT, "E&xit") + #EVT_MENU(self, self.M_NEW, self.OnNew) + EVT_MENU(self, self.M_OPENFILES, self.OnMenuOpenFiles) + EVT_MENU(self, self.M_OPENDIR, self.OnMenuOpenDir) + EVT_MENU(self, self.M_OPENTREE, self.OnMenuOpenTree) + EVT_MENU(self, self.M_EXIT, self.OnCloseWindow) + menuBar.Append(menu, "&File"); + + menu = wxMenu() + menu.Append(self.M_COPYALL, "&Copy all results") + menu.Append(self.M_COPYSEL, "&Copy selected results") + EVT_MENU(self, self.M_COPYALL, self.OnCopyAll) + EVT_MENU(self, self.M_COPYSEL, self.OnCopySelection) + menuBar.Append(menu, "&Edit"); + + menu = wxMenu() + menu.Append(self.M_RUN, "&Run all") + menu.AppendSeparator() + menu.AppendCheckItem(self.M_CHECKING,"&Checking") + menu.Check(self.M_CHECKING,isChecking()) + EVT_MENU(self, self.M_RUN, self.OnRun) + EVT_MENU(self, self.M_CHECKING, self.OnChecking) + self.testing_menu=menu + menuBar.Append(menu, "&Testing") + + self.SetMenuBar(menuBar) + + #GUI + panel = wxPanel(self, 0) + + button = wxButton(panel, self.ID_BUTTON, "Run Tests" ) + button.SetDefault() + EVT_BUTTON(panel, self.ID_BUTTON, self.OnRun ) + + self.tree = TreeView(panel, -1, size=(300,250), style=wxTR_HAS_BUTTONS | wxTR_EDIT_LABELS)# | wxTR_MULTIPLE + + self.progress = ProgressBar(panel, -1, 100, style=wxGA_HORIZONTAL|wxGA_SMOOTH) + + self.list = ResultView(panel) + + sizer = wxBoxSizer(wxVERTICAL) + sizer.Add(self.tree, 1, wxEXPAND) + sizer.Add(button, 0, wxEXPAND) + sizer.Add(self.progress, 0, wxEXPAND) + sizer.Add(self.list, 1, wxEXPAND) + + panel.SetAutoLayout(1) + panel.SetSizer(sizer) + sizer.Fit(panel) + + basesizer = wxBoxSizer(wxVERTICAL) + basesizer.Add(panel, 1, wxEXPAND) + self.SetAutoLayout(1) + self.SetSizer(basesizer) + self.Fit() + + #create a statusbar + sb = self.CreateStatusBar(1) + sb.SetStatusWidths([-1]) + self.SetStatusText('Please load file(s), a directory or tree',0) + #update controls + self.OnNew() + + def __del__(self): + # persist any values in .ini file + + cfg=ConfigParser() + cfg.add_section('main') + cfg.set('main','current_directory',self.getCurrentDirectory()) + cfg.set('main','checking',isChecking()) + cfg.write(open(INI_FILE,'w')) + + def loadConfig(self): + # load settings from the config file + + cfg=ConfigParser() + cfg.read(INI_FILE) + + self._currentDirectory='.' + try: + self.setCurrentDirectory(cfg.get('main','current_directory')) + except NoSectionError: # none of the other options will be available + return + except NoOptionError: + pass + + try: + doChecking(cfg.getboolean('main','checking')) + except (NoOptionError, NoSectionError): + doChecking(True) + + + def UpdateTree(self, root=None, testlist=None): + if root is None: + root = self.root + if testlist is None and self.suite: + testlist = self.suite._tests #grmpf accessing a _ member, oh well + + if root and testlist: + for testcase in testlist: + if isinstance(testcase, unittest.TestSuite): + + testname=testcase._tests[0] + #str(testname): atestcasename (module.class) + # we want module.class here, with no brackets + # this should do it + label= str(testname).split('(')[1] + label=label[:-1] + + child = self.tree.AppendItem(root, "%s (%d)" % (label,len(testcase._tests))) + self.tree.SetPyData(child, None) + self.UpdateTree(child, testcase._tests) + self.tree.SortChildren(child) + self.tree.Collapse(child) + else: + + label="%s" % testcase + label=label.split('(')[0] + + child = self.tree.AppendItem(root,label) + self.tree.SetPyData(child, None) + ##self.tree.SetItemImage(child, idx2, wxTreeItemIcon_Expanded) + ##self.tree.SetItemSelectedImage(child, idx3) + + self.tree.Expand(root) + + def OnRun(self, event=None): + """ """ + if self.suite: + runner = GUITestRunner(self.list, self.progress) + self.SetStatusText('Running tests...',0) + ln = self.suite.countTestCases() + self.progress.SetValue(0) + self.progress.SetRange(ln) + self.list.DeleteAllItems() + + result = runner.run(self.suite) + + self.SetStatusText('Ran %d tests, %d errors, %d failures' % (ln, len(result.errors), len(result.failures)), 0) + + else: + self.SetStatusText('No tests found', 0) + + + def OnMenuOpenFiles(self, event=None): + """ """ + + dlg = wxFileDialog(self, "Choose one or more modules", + self.getCurrentDirectory(),"", + 'Python files (*.py)|*.py|All files (*.*)|*.*', + wxOPEN|wxMULTIPLE) + + if dlg.ShowModal() == wxID_OK: +## for path in dlg.GetPaths(): +## log.WriteText('You selected: %s\n' % path) + self.OnNew() + filenames = dlg.GetPaths() #dlg.GetPath() + self.setCurrentDirectory(dlg.GetDirectory()) + self.suite=buildSuite(filenames) + + #print self.suite + dlg.Destroy() + self.UpdateTree() + + def OnMenuOpenDir(self,event=None): + self.loadDirectory('Choose the test directory') + + def OnMenuOpenTree(self,event=None): + self.loadDirectory('Choose the top test directory',True) + + def loadDirectory(self,msg,tree=False): + dlg=wxDirDialog(self,msg, self.getCurrentDirectory()) + if dlg.ShowModal() == wxID_OK: + self.OnNew() + dir = dlg.GetPath() + self.setCurrentDirectory(dir) + self.suite=buildSuite(dir,tree) + #print self.suite + dlg.Destroy() + self.UpdateTree() + + def OnNew(self, event=None): + self.list.DeleteAllItems() + self.tree.DeleteAllItems() + self.root = self.tree.AddRoot("Watsup Tests:") + self.tree.SetPyData(self.root, None) + self.progress.SetValue(0) + self.suite = None + #self.filename = None + + def OnCopySelection(self,event=None): + self.list.OnCopyAsText() + + def OnCopyAll(self,event=None): + self.list.OnCopyAsText(all=1) + + def OnCloseWindow(self, event=None): + self.Destroy() + + + def OnChecking(self,event=None): + # toggle self._checking: + bool=not isChecking() + self.testing_menu.Check(self.M_CHECKING,bool) + doChecking(bool) + self.SetStatusText('Checking %s' % onOff(bool),0) + + def getCurrentDirectory(self): + if os.path.isdir(self._currentDirectory): + return self._currentDirectory + else: + return '.' + + def setCurrentDirectory(self,value): + if self._currentDirectory<>value: + if os.path.isdir(value): + self._currentDirectory=value + # update the title + if value=='.': + text='' + else: + text='(%s)' % value + + self.SetTitle('%s %s'.strip() % (BASE_TITLE,text)) + else: + self._currentDirectory='.' + + +#--------------------------------------------------------------------------- +# Every wxWindows application must have a class derived from wxApp +class App(wxApp): + # wxWindows calls this method to initialize the application + def OnInit(self): + # Create an instance of our customized Frame class + frame = Frame(NULL, -1) + frame.Show(true) + # Tell wxWindows that this is our main window + self.SetTopWindow(frame) + # Return a success flag + return true + +#--------------------------------------------------------------------------- +if __name__ == "__main__": + app = App(0) # Create an instance of the application class + app.MainLoop() # Tell it to start processing events + diff --git a/agent/crawl/watsup/tools/wxShowWindows.py b/agent/crawl/watsup/tools/wxShowWindows.py new file mode 100644 index 0000000..2ec2110 --- /dev/null +++ b/agent/crawl/watsup/tools/wxShowWindows.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +#Boa:App:BoaApp + +# Author : Tim Couper - tim@tizmoi.net +# Date : 1 August 2004 +# Copyright : Copyright TAC Software Ltd, under Python-like licence. +# Provided as-is, with no warranty. +# Notes : Requires watsup,wxPython + +from wxPython.wx import * + +import fmShowWindows + +modules ={'fmShowWindows': [1, 'Main frame of Application', 'fmShowWindows.py']} + +class BoaApp(wxApp): + def OnInit(self): + wxInitAllImageHandlers() + self.main = fmShowWindows.create(None) + self.main.Show() + self.SetTopWindow(self.main) + return True + +def main(): + application = BoaApp(0) + application.MainLoop() + +if __name__ == '__main__': + main() diff --git a/agent/crawl/watsup/utils.py b/agent/crawl/watsup/utils.py new file mode 100644 index 0000000..79c502a --- /dev/null +++ b/agent/crawl/watsup/utils.py @@ -0,0 +1,37 @@ +""" watsup system utilities +""" + +# Author : Tim Couper - timc@tizmoi.net +# Date : 22 July 2004 +# Version : 1.0 +# Copyright : Copyright TAC Software Ltd, under Python-style licence. +# Provided as-is, with no warranty. +# Notes : Requires win32all + +import win32gui +import win32api +import sys + +class WatsupError(Exception): pass + +##def kill(pid): + +## """kill function for Win32""" + +## handle = win32api.OpenProcess(1, 0, pid) + +## return (0 != win32api.TerminateProcess(handle, 0)) + +def dumpHwnd(hwnd): + t=list(tupleHwnd(hwnd)) + t.reverse() + return '%s:"%s" (%d)' % tuple(t) #(win32gui.GetClassName(hwnd),win32gui.GetWindowText(hwnd),hwnd) + +def tupleHwnd(hwnd): + return (hwnd,win32gui.GetWindowText(hwnd),win32gui.GetClassName(hwnd)) + +def pump(): + win32gui.PumpWaitingMessages() + +if __name__=='__main__': + pass \ No newline at end of file diff --git a/agent/crawl/watsup/wie.py b/agent/crawl/watsup/wie.py new file mode 100644 index 0000000..8f5cf37 --- /dev/null +++ b/agent/crawl/watsup/wie.py @@ -0,0 +1,45 @@ +# provides a testing interface to web applications via the PAMIE module + +# Author : Tim Couper - timc@tizmoi.net +# Date : 22 July 2004 +# Version : 1.0 +# Copyright : Copyright TAC Software Ltd, under Python-style licence. +# Provided as-is, with no warranty. + +from cPAMIE import PAMIE + +def findRunningIE(): + from win32com.client import Dispatch + from win32gui import GetClassName + + ShellWindowsCLSID = '{9BA05972-F6A8-11CF-A442-00A0C90A8F39}' + ShellWindows = Dispatch ( ShellWindowsCLSID ) + + # try to get an ie instance from the window + for shellwindow in ShellWindows : + if GetClassName ( shellwindow.HWND ) == 'IEFrame' : + return shellwindow + +class WatsupIE(PAMIE): + def __init__(self,url=None, timeOut=1000, useExistingIfPossible=False): + + self._ie=None + + if useExistingIfPossible: + self._ie=findRunningIE() + + if self._ie: + # this case can only arise if we've located a running IE; + + # the code below should be everything else in PAMIE.__init__, + # apart from instantiation of the new ie instance: + if url: + self._ie.Navigate(url) + else: + self._ie.Navigate('about:blank') + self._timeOut = timeOut + self._ie.Visible = 1 + else: + PAMIE.__init__(self,url,timeOut) + + \ No newline at end of file diff --git a/agent/crawl/watsup/winGuiAuto.py b/agent/crawl/watsup/winGuiAuto.py new file mode 100644 index 0000000..9ae3f4c --- /dev/null +++ b/agent/crawl/watsup/winGuiAuto.py @@ -0,0 +1,1169 @@ +# Module : winGuiAuto.py +# Synopsis : Windows GUI automation utilities +# Programmer : Simon Brunning - simon@brunningonline.net +# Date : 25 June 2003 +# Version : 1.0 +# Copyright : Released to the public domain. Provided as-is, with no warranty. +# Notes : Requires Python 2.3, win32all and ctypes + +# Modifications by Tim Couper - tim@tizmoi.net +# 22 Jul 2004 +# findControls: deduplicates the list to be returned +# findControl: handles win32gui.error from initial call to findControls +# getMenuInfo: improved algorithm for calculating no. of items in a menu +# activateMenuItem: improved algorithm for calculating no. of items in a menu +# +# GLOBALLY corrected spelling: seperator -> separator +# : descendent -> descendant +# added findMenuItem + +'''Windows GUI automation utilities. + +TODO - Until I get around to writing some docs and examples, the tests at the +foot of this module should serve to get you started. + +The standard pattern of usage of winGuiAuto is in three stages; identify a +window, identify a control in the window, trigger an action on the control. + +The end result is always that you wish to have an effect upon some Windows GUI +control. + +The first stage is to identify the window within which the control can be +found. To do this, you can use either findTopWindow or findTopWindows. The +findTopWindow function returns a reference to single window, or throws an +exception if multiple windows or no windows matching the supplied selection +criteria are found. If no matching window is found, immediately, the +findTopWindow function may keep trying to find a match, depending upon suppled +retry aguments. The findTopWindows function returns a list of references to all +windows matching the supplied selection criteria; this list may be empty. The +findTopWindows function will return immediately. + +Usually, specifying caption text, the window's class, or both, will be +sufficient to identify the required window. (Note that the window's class is a +Windows API concept; it has nothing to do with Python classes. See http://msdn.microsoft.com/library/en-us/winui/WinUI/WindowsUserInterface/Windowing/Window_89WindowClasse.asp +for an overview.) Caption text will match if the specified text is *contained* +in the windows' captions; this match is case unsensitive. Window class names +must match identically; the full class name must be matched, and the test is +case sensitive. + +This matching behavior is usually the most useful - but not always. If other +selection behavior is required, a selection function can be passed to the find +functions. + +These returned references are in the form of 'Windows Handles'. All windows and +controls are accessed via a Windows Handle (or hwnd). See +http://msdn.microsoft.com/library/en-us/winui/winui/windowsuserinterface/windowing/windows/aboutwindows.asp +for Microsoft's info-deluge on all things Windows window. + +Having identified the window, the next stage is to identify the control. To do +this, you can use either of the findControl and findControls functions. These +work in almost exactly the same way as the findTopWindow and findTopWindows +functions; they take the hwnd of the top level window within which the required +control should be found, and otherwise take the same arguments as the +findTopWindow and findTopWindows functions, and work in the same ways. + +Having now identified your control, you can now query its state, and send +actions (in the form of Windows messages) to it. It's at this point that you +are most likely to end up having to extend winGuiAuto in some way; the +developer of the GUI that you are trying to drive is free to develop controls +which respond to different messages in different ways. Still, if standard MFC +controls have been used, you may find that winGuiAuto's functions may provide +much or all of what you need - or at least provide a useful template. These +functions (clickButton, clickStatic, doubleClickStatic, getComboboxItems, +getEditText, getListboxItems, selectComboboxItem, selectListboxItem and +setEditText) should be fairly self evident. + +Selection of menu items is a slightly different process: but don't fret; it's +pretty simple. You'll need to identify the hwnd of the top level window that +you want to control using either of the findTopWindow and findTopWindows +functions. You can then call the activateMenuItem function, passing in the top +level window's hwnd and the path to the menu option that you wish to activate. +This path should consist of a list specifiying the path to the required menu +option - see activateMenuItem's docstring for details. + +TODO getMenuInfo + +TODO: dumpTopWindows, dumpWindow, Spy++ and Winspector (http://www.windows-spy.com) +Two if the main difficulties you'll come across while using winGuiAuto will be discovering + the classes of the windows that you want, and where the provided +''' + +import array +import ctypes +import os +import struct +import sys +import time +import win32api +import win32con +import win32gui + +def findTopWindow(wantedText=None, + wantedClass=None, + selectionFunction=None, + maxWait=1, + retryInterval=0.1): + '''Find the hwnd of a top level window. + + You can identify windows using captions, classes, a custom selection + function, or any combination of these. (Multiple selection criteria are + ANDed. If this isn't what's wanted, use a selection function.) + + If no window matching the specified selection criteria is found + immediately, further attempts will be made. The retry interval and maximum + time to wait for a matching window can be specified. + + Arguments: + + wantedText Text which the required window's caption must + *contain*. (Case insensitive match.) + wantedClass Class to which the required window must belong. + selectionFunction Window selection function. Reference to a function + should be passed here. The function should take hwnd + as an argument, and should return True when passed the + hwnd of a desired window. + maxWait The maximum time to wait for a matching window, in + seconds. + retryInterval How frequently to look for a matching window, in + seconds + + Raises: + WinGuiAutoError When no window or multiple windows found. + + Usage examples: # Caption contains "Options" + optDialog = findTopWindow(wantedText="Options") + # Caption *equals* "Notepad" + saveDialog = findTopWindow(selectionFunction=lambda hwnd: + win32gui.GetWindowText(hwnd)=='Notepad') + ''' + topWindows = findTopWindows(wantedText, wantedClass, selectionFunction) + if len(topWindows) > 1: + raise WinGuiAutoError("Multiple top level windows found for wantedText=" + + repr(wantedText) + + ", wantedClass=" + + repr(wantedClass) + + ", selectionFunction=" + + repr(selectionFunction) + + ", maxWait=" + + repr(maxWait) + + ", retryInterval=" + + str(retryInterval)) + elif topWindows: + return topWindows[0] + elif (maxWait-retryInterval) >= 0: + time.sleep(retryInterval) + try: + return findTopWindow(wantedText=wantedText, + wantedClass=wantedClass, + selectionFunction=selectionFunction, + maxWait=maxWait-retryInterval, + retryInterval=retryInterval) + except WinGuiAutoError: + raise WinGuiAutoError("No top level window found for wantedText=" + + repr(wantedText) + + ", wantedClass=" + + repr(wantedClass) + + ", selectionFunction=" + + repr(selectionFunction) + + ", maxWait=" + + repr(maxWait) + + ", retryInterval=" + + str(retryInterval)) + else: + raise WinGuiAutoError("No top level window found for wantedText=" + + repr(wantedText) + + ", wantedClass=" + + repr(wantedClass) + + ", selectionFunction=" + + repr(selectionFunction) + + ", maxWait=" + + repr(maxWait) + + ", retryInterval=" + + str(retryInterval)) + +def findTopWindows(wantedText=None, wantedClass=None, selectionFunction=None): + '''Find the hwnd of top level windows. + + You can identify windows using captions, classes, a custom selection + function, or any combination of these. (Multiple selection criteria are + ANDed. If this isn't what's wanted, use a selection function.) + + Arguments: + wantedText Text which required windows' captions must contain. + wantedClass Class to which required windows must belong. + selectionFunction Window selection function. Reference to a function + should be passed here. The function should take hwnd as + an argument, and should return True when passed the + hwnd of a desired window. + + Returns: A list containing the window handles of all top level + windows matching the supplied selection criteria. + + Usage example: optDialogs = findTopWindows(wantedText="Options") + ''' + results = [] + topWindows = [] + win32gui.EnumWindows(_windowEnumerationHandler, topWindows) + for hwnd, windowText, windowClass in topWindows: + if wantedText and \ + not _normaliseText(wantedText) in _normaliseText(windowText): + continue + if wantedClass and not windowClass == wantedClass: + continue + if selectionFunction and not selectionFunction(hwnd): + continue + results.append(hwnd) + return results + +def dumpTopWindows(): + '''TODO''' + topWindows = [] + win32gui.EnumWindows(_windowEnumerationHandler, topWindows) + return topWindows + +def dumpWindow(hwnd): + '''Dump all controls from a window into a nested list + + Useful during development, allowing to you discover the structure of the + contents of a window, showing the text and class of all contained controls. + + Think of it as a poor man's Spy++. ;-) + + Arguments: The window handle of the top level window to dump. + + Returns A nested list of controls. Each entry consists of the + control's hwnd, its text, its class, and its sub-controls, + if any. + + Usage example: replaceDialog = findTopWindow(wantedText='Replace') + pprint.pprint(dumpWindow(replaceDialog)) + ''' + windows = [] + try: + win32gui.EnumChildWindows(hwnd, _windowEnumerationHandler, windows) + except win32gui.error: + # No child windows + return + windows = [list(window) for window in windows] + for window in windows: + childHwnd, windowText, windowClass = window + window_content = dumpWindow(childHwnd) + if window_content: + window.append(window_content) + + def dedup(thelist): + '''De-duplicate deeply nested windows list.''' + def listContainsSublists(thelist): + return bool([sublist + for sublist in thelist + if isinstance(sublist, list)]) + found=[] + def dodedup(thelist): + todel = [] + for index, thing in enumerate(thelist): + if isinstance(thing, list) and listContainsSublists(thing): + dodedup(thing) + else: + if thing in found: + todel.append(index) + else: + found.append(thing) + todel.reverse() + for todel in todel: + del thelist[todel] + dodedup(thelist) + dedup(windows) + + return windows + +def findControl(topHwnd, + wantedText=None, + wantedClass=None, + selectionFunction=None, + maxWait=1, + retryInterval=0.1): + '''Find a control. + + You can identify a control within a top level window, using caption, class, + a custom selection function, or any combination of these. (Multiple + selection criteria are ANDed. If this isn't what's wanted, use a selection + function.) + + If no control matching the specified selection criteria is found + immediately, further attempts will be made. The retry interval and maximum + time to wait for a matching control can be specified. + + Arguments: + topHwnd The window handle of the top level window in which the + required controls reside. + wantedText Text which the required control's captions must contain. + wantedClass Class to which the required control must belong. + selectionFunction Control selection function. Reference to a function + should be passed here. The function should take hwnd as + an argument, and should return True when passed the + hwnd of the desired control. + maxWait The maximum time to wait for a matching control, in + seconds. + retryInterval How frequently to look for a matching control, in + seconds + + Returns: The window handle of the first control matching the + supplied selection criteria. + + Raises: + WinGuiAutoError When no control or multiple controls found. + + Usage example: optDialog = findTopWindow(wantedText="Options") + okButton = findControl(optDialog, + wantedClass="Button", + wantedText="OK") + ''' + controls = findControls(topHwnd, + wantedText=wantedText, + wantedClass=wantedClass, + selectionFunction=selectionFunction) + # check for None returned: Tim 6 Jul 2004 + if controls==None: + raise WinGuiAutoError("EnumChildWindows failed with win32gui.error " + + repr(topHwnd) + + ", wantedText=" + + repr(wantedText) + + ", wantedClass=" + + repr(wantedClass) + + ", selectionFunction=" + + repr(selectionFunction) + + ", maxWait=" + + repr(maxWait) + + ", retryInterval=" + + str(retryInterval) + ) + + if len(controls) > 1: + raise WinGuiAutoError("Multiple controls found for topHwnd=" + + repr(topHwnd) + + ", wantedText=" + + repr(wantedText) + + ", wantedClass=" + + repr(wantedClass) + + ", selectionFunction=" + + repr(selectionFunction) + + ", maxWait=" + + repr(maxWait) + + ", retryInterval=" + + str(retryInterval)) + elif controls: + return controls[0] + elif (maxWait-retryInterval) >= 0: + time.sleep(retryInterval) + try: + return findControl(topHwnd=topHwnd, + wantedText=wantedText, + wantedClass=wantedClass, + selectionFunction=selectionFunction, + maxWait=maxWait-retryInterval, + retryInterval=retryInterval) + except WinGuiAutoError: + raise WinGuiAutoError("No control found for topHwnd=" + + repr(topHwnd) + + ", wantedText=" + + repr(wantedText) + + ", wantedClass=" + + repr(wantedClass) + + ", selectionFunction=" + + repr(selectionFunction) + + ", maxWait=" + + repr(maxWait) + + ", retryInterval=" + + str(retryInterval)) + else: + raise WinGuiAutoError("No control found for topHwnd=" + + repr(topHwnd) + + ", wantedText=" + + repr(wantedText) + + ", wantedClass=" + + repr(wantedClass) + + ", selectionFunction=" + + repr(selectionFunction) + + ", maxWait=" + + repr(maxWait) + + ", retryInterval=" + + str(retryInterval)) + +def findControls(topHwnd, + wantedText=None, + wantedClass=None, + selectionFunction=None): + '''Find controls. + + You can identify controls using captions, classes, a custom selection + function, or any combination of these. (Multiple selection criteria are + ANDed. If this isn't what's wanted, use a selection function.) + + Arguments: + topHwnd The window handle of the top level window in which the + required controls reside. + wantedText Text which the required controls' captions must contain. + wantedClass Class to which the required controls must belong. + selectionFunction Control selection function. Reference to a function + should be passed here. The function should take hwnd as + an argument, and should return True when passed the + hwnd of a desired control. + + Returns: The window handles of the controls matching the + supplied selection criteria. + + Usage example: optDialog = findTopWindow(wantedText="Options") + def findButtons(hwnd, windowText, windowClass): + return windowClass == "Button" + buttons = findControl(optDialog, wantedText="Button") + ''' + def searchChildWindows(currentHwnd): + results = [] + childWindows = [] + try: + win32gui.EnumChildWindows(currentHwnd, + _windowEnumerationHandler, + childWindows) + except win32gui.error: + # This seems to mean that the control *cannot* have child windows, + # i.e. is not a container. + return + + for childHwnd, windowText, windowClass in childWindows: + descendantMatchingHwnds = searchChildWindows(childHwnd) + if descendantMatchingHwnds: + results += descendantMatchingHwnds + + if wantedText and \ + not _normaliseText(wantedText) in _normaliseText(windowText): + continue + if wantedClass and \ + not windowClass == wantedClass: + continue + if selectionFunction and \ + not selectionFunction(childHwnd): + continue + results.append(childHwnd) + return results + + # deduplicate the returned windows: Tim 6 Jul 2004 + #return searchChildWindows(topHwnd) + + hlist=searchChildWindows(topHwnd) + + if hlist: + # deduplicate the list: + hdict={} + for h in hlist: + hdict[h]='' + return hdict.keys() + else: + return hlist + +def getTopMenu(hWnd): + '''Get a window's main, top level menu. + + Arguments: + hWnd The window handle of the top level window for which the top + level menu is required. + + Returns: The menu handle of the window's main, top level menu. + + Usage example: hMenu = getTopMenu(hWnd) + ''' + return ctypes.windll.user32.GetMenu(ctypes.c_long(hWnd)) + +def activateMenuItem(hWnd, menuItemPath): + '''Activate a menu item + + Arguments: + hWnd The window handle of the top level window whose menu you + wish to activate. + menuItemPath The path to the required menu item. This should be a + sequence specifying the path through the menu to the + required item. Each item in this path can be specified + either as an index, or as a menu name. + + Raises: + WinGuiAutoError When the requested menu option isn't found. + + Usage example: activateMenuItem(notepadWindow, ('file', 'open')) + + Which is exactly equivalent to... + + activateMenuItem(notepadWindow, (0, 1)) + ''' + # By Axel Kowald (kowald@molgen.mpg.de) + # Modified by S Brunning to accept strings in addition to indicies. + + # Top level menu + hMenu = getTopMenu(hWnd) + + # Get top level menu's item count. Is there a better way to do this? + # Yes .. Tim Couper 22 Jul 2004 + + hMenuItemCount=win32gui.GetMenuItemCount(hMenu) + +## for hMenuItemCount in xrange(256): +## try: +## _getMenuInfo(hMenu, hMenuItemCount) +## except WinGuiAutoError: +## break +## hMenuItemCount -= 1 + + # Walk down submenus + for submenu in menuItemPath[:-1]: + try: # submenu is an index + 0 + submenu + submenuInfo = _getMenuInfo(hMenu, submenu) + hMenu, hMenuItemCount = submenuInfo.submenu, submenuInfo.itemCount + except TypeError: # Hopefully, submenu is a menu name + try: + dump, hMenu, hMenuItemCount = _findNamedSubmenu(hMenu, + hMenuItemCount, + submenu) + except WinGuiAutoError: + raise WinGuiAutoError("Menu path " + + repr(menuItemPath) + + " cannot be found.") + + # Get required menu item's ID. (the one at the end). + menuItem = menuItemPath[-1] + try: # menuItem is an index + 0 + menuItem + menuItemID = ctypes.windll.user32.GetMenuItemID(hMenu, + menuItem) + except TypeError: # Hopefully, menuItem is a menu name + try: + subMenuIndex, dump, dump = _findNamedSubmenu(hMenu, + hMenuItemCount, + menuItem) + except WinGuiAutoError: + raise WinGuiAutoError("Menu path " + + repr(menuItemPath) + + " cannot be found.") + menuItemID = ctypes.windll.user32.GetMenuItemID(hMenu, subMenuIndex) + + # Activate + win32gui.PostMessage(hWnd, win32con.WM_COMMAND, menuItemID, 0) + +##def findMenuItems(hWnd,wantedText): +## """Finds menu items whose captions contain the text""" +## hMenu = getTopMenu(hWnd) +## hMenuItemCount=win32gui.GetMenuItemCount(hMenu) +## +## for topItem in xrange(hMenuItemCount): +## + +def getMenuInfo(hWnd, menuItemPath): + '''TODO''' + + # Top level menu + hMenu = getTopMenu(hWnd) + + # Get top level menu's item count. Is there a better way to do this? + # Yes .. Tim Couper 22 Jul 2004 + hMenuItemCount=win32gui.GetMenuItemCount(hMenu) + +## for hMenuItemCount in xrange(256): +## try: +## _getMenuInfo(hMenu, hMenuItemCount) +## except WinGuiAutoError: +## break +## hMenuItemCount -= 1 + submenuInfo=None + + # Walk down submenus + for submenu in menuItemPath: + try: # submenu is an index + 0 + submenu + submenuInfo = _getMenuInfo(hMenu, submenu) + hMenu, hMenuItemCount = submenuInfo.submenu, submenuInfo.itemCount + except TypeError: # Hopefully, submenu is a menu name + try: + submenuIndex, new_hMenu, hMenuItemCount = _findNamedSubmenu(hMenu, + hMenuItemCount, + submenu) + submenuInfo = _getMenuInfo(hMenu, submenuIndex) + hMenu = new_hMenu + except WinGuiAutoError: + raise WinGuiAutoError("Menu path " + + repr(menuItemPath) + + " cannot be found.") + if submenuInfo==None: + raise WinGuiAutoError("Menu path " + + repr(menuItemPath) + + " cannot be found. (Null menu path?)") + + + return submenuInfo + +def _getMenuInfo(hMenu, uIDItem): + '''Get various info about a menu item. + + Arguments: + hMenu The menu in which the item is to be found. + uIDItem The item's index + + Returns: Menu item information object. This object is basically + a 'bunch' + (see http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52308). + It will have useful attributes: name, itemCount, + submenu, isChecked, isDisabled, isGreyed, and + isSeparator + + Raises: + WinGuiAutoError When the requested menu option isn't found. + + Usage example: submenuInfo = _getMenuInfo(hMenu, submenu) + hMenu, hMenuItemCount = submenuInfo.submenu, submenuInfo.itemCount + ''' + # An object to hold the menu info + class MenuInfo(Bunch): + pass + menuInfo = MenuInfo() + + # Menu state + menuState = ctypes.windll.user32.GetMenuState(hMenu, + uIDItem, + win32con.MF_BYPOSITION) + if menuState == -1: + raise WinGuiAutoError("No such menu item, hMenu=" + + str(hMenu) + + " uIDItem=" + + str(uIDItem)) + + # Menu name + menuName = ctypes.c_buffer("\000" * 32) + ctypes.windll.user32.GetMenuStringA(ctypes.c_int(hMenu), + ctypes.c_int(uIDItem), + menuName, ctypes.c_int(len(menuName)), + win32con.MF_BYPOSITION) + menuInfo.name = menuName.value + + # Sub menu info + menuInfo.itemCount = menuState >> 8 + if bool(menuState & win32con.MF_POPUP): + menuInfo.submenu = ctypes.windll.user32.GetSubMenu(hMenu, uIDItem) + else: + menuInfo.submenu = None + + menuInfo.isChecked = bool(menuState & win32con.MF_CHECKED) + menuInfo.isDisabled = bool(menuState & win32con.MF_DISABLED) + menuInfo.isGreyed = bool(menuState & win32con.MF_GRAYED) + menuInfo.isSeparator = bool(menuState & win32con.MF_SEPARATOR) + # ... there are more, but these are the ones I'm interested in thus far. + + return menuInfo + +def clickButton(hwnd): + '''Simulates a single mouse click on a button + + Arguments: + hwnd Window handle of the required button. + + Usage example: okButton = findControl(fontDialog, + wantedClass="Button", + wantedText="OK") + clickButton(okButton) + ''' + _sendNotifyMessage(hwnd, win32con.BN_CLICKED) + +def clickStatic(hwnd): + '''Simulates a single mouse click on a static + + Arguments: + hwnd Window handle of the required static. + + Usage example: TODO + ''' + _sendNotifyMessage(hwnd, win32con.STN_CLICKED) + +def doubleClickStatic(hwnd): + '''Simulates a double mouse click on a static + + Arguments: + hwnd Window handle of the required static. + + Usage example: TODO + ''' + _sendNotifyMessage(hwnd, win32con.STN_DBLCLK) + +def getComboboxItems(hwnd): + '''Returns the items in a combo box control. + + Arguments: + hwnd Window handle for the combo box. + + Returns: Combo box items. + + Usage example: fontCombo = findControl(fontDialog, wantedClass="ComboBox") + fontComboItems = getComboboxItems(fontCombo) + ''' + + return _getMultipleWindowValues(hwnd, + getCountMessage=win32con.CB_GETCOUNT, + getValueMessage=win32con.CB_GETLBTEXT) + +def selectComboboxItem(hwnd, item): + '''Selects a specified item in a Combo box control. + + Arguments: + hwnd Window handle of the required combo box. + item The reqired item. Either an index, of the text of the + required item. + + Usage example: fontComboItems = getComboboxItems(fontCombo) + selectComboboxItem(fontCombo, + random.choice(fontComboItems)) + ''' + try: # item is an index Use this to select + 0 + item + win32gui.SendMessage(hwnd, win32con.CB_SETCURSEL, item, 0) + _sendNotifyMessage(hwnd, win32con.CBN_SELCHANGE) + except TypeError: # Item is a string - find the index, and use that + items = getComboboxItems(hwnd) + itemIndex = items.index(item) + selectComboboxItem(hwnd, itemIndex) + +def getListboxItems(hwnd): + '''Returns the items in a list box control. + + Arguments: + hwnd Window handle for the list box. + + Returns: List box items. + + Usage example: docType = findControl(newDialog, wantedClass="ListBox") + typeListBox = getListboxItems(docType) + ''' + + return _getMultipleWindowValues(hwnd, + getCountMessage=win32con.LB_GETCOUNT, + getValueMessage=win32con.LB_GETTEXT) + +def selectListboxItem(hwnd, item): + '''Selects a specified item in a list box control. + + Arguments: + hwnd Window handle of the required list box. + item The reqired item. Either an index, of the text of the + required item. + + Usage example: docType = findControl(newDialog, wantedClass="ListBox") + typeListBox = getListboxItems(docType) + + # Select a type at random + selectListboxItem(docType, + random.randint(0, len(typeListBox)-1)) + ''' + try: # item is an index Use this to select + 0 + item + win32gui.SendMessage(hwnd, win32con.LB_SETCURSEL, item, 0) + _sendNotifyMessage(hwnd, win32con.LBN_SELCHANGE) + except TypeError: # Item is a string - find the index, and use that + items = getListboxItems(hwnd) + itemIndex = items.index(item) + selectListboxItem(hwnd, itemIndex) + +def getEditText(hwnd): + '''Returns the text in an edit control. + + Arguments: + hwnd Window handle for the edit control. + + Returns Edit control text lines. + + Usage example: pprint.pprint(getEditText(editArea)) + ''' + return _getMultipleWindowValues(hwnd, + getCountMessage=win32con.EM_GETLINECOUNT, + getValueMessage=win32con.EM_GETLINE) + +def setEditText(hwnd, text, append=False): + '''Set an edit control's text. + + Arguments: + hwnd The edit control's hwnd. + text The text to send to the control. This can be a single + string, or a sequence of strings. If the latter, each will + be become a a separate line in the control. + append Should the new text be appended to the existing text? + Defaults to False, meaning that any existing text will be + replaced. If True, the new text will be appended to the end + of the existing text. + Note that the first line of the new text will be directly + appended to the end of the last line of the existing text. + If appending lines of text, you may wish to pass in an + empty string as the 1st element of the 'text' argument. + + Usage example: print "Enter various bits of text." + setEditText(editArea, "Hello, again!") + setEditText(editArea, "You still there?") + setEditText(editArea, ["Here come", "two lines!"]) + + print "Add some..." + setEditText(editArea, ["", "And a 3rd one!"], append=True) + ''' + + # Ensure that text is a list + try: + text + '' + text = [text] + except TypeError: + pass + + # Set the current selection range, depending on append flag + if append: + win32gui.SendMessage(hwnd, + win32con.EM_SETSEL, + -1, + 0) + else: + win32gui.SendMessage(hwnd, + win32con.EM_SETSEL, + 0, + -1) + + # Send the text + win32gui.SendMessage(hwnd, + win32con.EM_REPLACESEL, + True, + os.linesep.join(text)) + +def setCheckBox(hwnd, state = True): + """ + Activates a CheckBox button. + + Inputs - + hwnd - Handle of GUI element + state - Boolean + True - Activate the Checkbox + False - Clear the CheckBox + + Outputs - + Integer -- Result of the Win32gui.SendMessage Command + + Note: There is a 3rd state to a CheckBox. Since it is not + common has been split to another function + setCheckBox_Indeterminate. + """ + win32gui.SendMessage( hwnd, + win32con.BM_SETCHECK, + win32con.BST_CHECKED, + 0 ) + + +def setCheckBox_Indeterminate(hwnd): + """ + Activates a CheckBox button. + + Inputs - + hwnd - Handle of GUI element + + Outputs - + Integer -- Result of the Win32gui.SendMessage Command + + """ + win32gui.SendMessage( hwnd, + win32con.BM_SETCHECK, + win32con.BST_INDETERMINATE, + 0 ) + +def getCheckBox(hwnd): + """ + Returns the status from a CheckBox button. + + Inputs - + hwnd - Handle of GUI element + + Outputs - + 0 - win32Gui send message error + win32con.BST_CHECKED- The Checkbox is checked + win32con.BST_INDETERMINATE - The Checkbox is checked and = + greyed out. + win32con.BST_UNCHECKED- The checkbox is not checked + =20 + """ + value = win32gui.SendMessage( hwnd, + win32con.BM_GETCHECK, + 0, + 0 ) + return value + +def _getMultipleWindowValues(hwnd, getCountMessage, getValueMessage): + ''' + + A common pattern in the Win32 API is that in order to retrieve a + series of values, you use one message to get a count of available + items, and another to retrieve them. This internal utility function + performs the common processing for this pattern. + + Arguments: + hwnd Window handle for the window for which items should be + retrieved. + getCountMessage Item count message. + getValueMessage Value retrieval message. + + Returns: Retrieved items. + ''' + result = [] + + MAX_VALUE_LENGTH = 256 + bufferlength = struct.pack('i', MAX_VALUE_LENGTH) # This is a C style int. + + valuecount = win32gui.SendMessage(hwnd, getCountMessage, 0, 0) + for itemIndex in range(valuecount): + valuebuffer = array.array('c', + bufferlength + + ' ' * (MAX_VALUE_LENGTH - len(bufferlength))) + valueLength = win32gui.SendMessage(hwnd, + getValueMessage, + itemIndex, + valuebuffer) + result.append(valuebuffer.tostring()[:valueLength]) + return result + +def _windowEnumerationHandler(hwnd, resultList): + '''win32gui.EnumWindows() callback. + + Pass to win32gui.EnumWindows() or win32gui.EnumChildWindows() to + generate a list of window handle, window text, window class tuples. + ''' + resultList.append((hwnd, + win32gui.GetWindowText(hwnd), + win32gui.GetClassName(hwnd))) + +def _buildWinLong(high, low): + '''Build a windows long parameter from high and low words. + + See http://support.microsoft.com/support/kb/articles/q189/1/70.asp + ''' + # return ((high << 16) | low) + return int(struct.unpack('>L', + struct.pack('>2H', + high, + low)) [0]) + +def _sendNotifyMessage(hwnd, notifyMessage): + '''Send a notify message to a control.''' + win32gui.SendMessage(win32gui.GetParent(hwnd), + win32con.WM_COMMAND, + _buildWinLong(notifyMessage, + win32api.GetWindowLong(hwnd, + win32con.GWL_ID)), + hwnd) + +def _normaliseText(controlText): + '''Remove '&' characters, and lower case. + + Useful for matching control text.''' + return controlText.lower().replace('&', '') + +def _findNamedSubmenu(hMenu, hMenuItemCount, submenuName): + '''Find the index number of a menu's submenu with a specific name.''' + for submenuIndex in range(hMenuItemCount): + submenuInfo = _getMenuInfo(hMenu, submenuIndex) + if _normaliseText(submenuInfo.name).startswith(_normaliseText(submenuName)): + return submenuIndex, submenuInfo.submenu, submenuInfo.itemCount + raise WinGuiAutoError("No submenu found for hMenu=" + + repr(hMenu) + + ", hMenuItemCount=" + + repr(hMenuItemCount) + + ", submenuName=" + + repr(submenuName)) + +def _dedup(thelist): + '''De-duplicate deeply nested list.''' + found=[] + def dodedup(thelist): + for index, thing in enumerate(thelist): + if isinstance(thing, list): + dodedup(thing) + else: + if thing in found: + del thelist[index] + else: + found.append(thing) + + +class Bunch(object): + '''See http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52308''' + + def __init__(self, **kwds): + self.__dict__.update(kwds) + + def __str__(self): + state = ["%s=%r" % (attribute, value) + for (attribute, value) + in self.__dict__.items()] + return '\n'.join(state) + +class WinGuiAutoError(Exception): + pass + +def self_test(): + '''Self test - drives Notepad and WordPad.''' + # I'd like to use unittest here, but I've no idea how to automate these + # tests. As it is, you just have to *watch* the test! ;-) + import pprint, random + + # NT/2K/XP versions of Notepad have a different menu stuctures. + WIN_VERSION_DECODE = {(1, 4, 0): "95", + (1, 4, 10): "98", + (1, 4, 90): "ME", + (2, 4, 0): "NT", + (2, 5, 0): "2K", + (2, 5, 1): "XP"} + win_version = os.sys.getwindowsversion() + win_version = WIN_VERSION_DECODE[win_version[3], win_version[0], win_version[1]] + print "win_version=", win_version + x=raw_input('->') + print "Let's see what top windows we have at the 'mo:" + pprint.pprint(dumpTopWindows()) + x=raw_input('->') + print "Open and locate Notepad" + os.startfile('notepad') + notepadWindow = findTopWindow(wantedClass='Notepad') + x=raw_input('->') + print "Look at some menu item info" + + print 'File menu' + print getMenuInfo(notepadWindow, ('file',)) + print "file|exit" + print getMenuInfo(notepadWindow, ('file', 'exit')) + x=raw_input('->') + print "Open and locate the 'replace' dialogue" + if win_version in ["NT"]: + activateMenuItem(notepadWindow, ['search', 'replace']) + elif win_version in ["2K", "XP"]: + activateMenuItem(notepadWindow, ['edit', 'replace']) + else: + raise Exception("Tests not written for this OS yet. Feel free!") + replaceDialog = findTopWindow(wantedText='Replace', wantedClass="#32770") + x=raw_input('->') + print "Locate the 'find' edit box" + findValue = findControls(replaceDialog, wantedClass="Edit")[0] + x=raw_input('->') + print "Enter some text - and wait long enough for it to be seen" + setEditText(findValue, "Hello, mate!") + time.sleep(.5) + x=raw_input('->') + + print "Locate the 'cancel' button, and click it." + cancelButton = findControl(replaceDialog, + wantedClass="Button", + wantedText="Cancel") + clickButton(cancelButton) + x=raw_input('->') + print "Open and locate the 'font' dialogue" + if win_version in ["NT"]: + activateMenuItem(notepadWindow, ['edit', 'set font']) + elif win_version in ["2K", "XP"]: + activateMenuItem(notepadWindow, ['format', 'font']) + print findTopWindows(wantedText='Font', wantedClass="#32770") + x=raw_input('->') + fontDialog = findTopWindow(wantedText='Font', wantedClass="#32770") + + print "Let's see if dumping works. Dump the 'font' dialogue contents:" + pprint.pprint(dumpWindow(fontDialog)) + x=raw_input('->') + + print "Change the font" + fontCombos = findControls(fontDialog, wantedClass="ComboBox") + print "Find the font selection combo" + for fontCombo in fontCombos: + fontComboItems = getComboboxItems(fontCombo) + if 'Arial' in fontComboItems: + break + x=raw_input('->') + print "Select at random" + selectComboboxItem(fontCombo, random.choice(fontComboItems)) + time.sleep(.5) + + okButton = findControl(fontDialog, wantedClass="Button", wantedText="OK") + clickButton(okButton) + x=raw_input('->') + + print "Locate notepad's edit area, and enter various bits of text." + editArea = findControl(notepadWindow,wantedClass="Edit") + setEditText(editArea, "Hello, again!") + time.sleep(.5) + setEditText(editArea, "You still there?") + time.sleep(.5) + setEditText(editArea, ["Here come", "two lines!"]) + time.sleep(.5) + x=raw_input('->') + + print "Add some..." + setEditText(editArea, ["", "And a 3rd one!"], append=True) + time.sleep(.5) + + print "See what's there now:" + pprint.pprint(getEditText(editArea)) + x=raw_input('->') + + print "Exit notepad" + activateMenuItem(notepadWindow, ('file', 'exit')) + time.sleep(.5) + + print "Don't save." + saveDialog = findTopWindow(selectionFunction=lambda hwnd: + win32gui.GetWindowText(hwnd)=='Notepad') + noButton = findControl(saveDialog,wantedClass="Button", wantedText="no") + clickButton(noButton) + x=raw_input('->') + + print "Check you get an exception for non-existent top window" + try: + findTopWindow(wantedText="Banana") + raise Exception("Test failed") + except WinGuiAutoError, winGuiAutoError: + print "Yup, got: ", str(winGuiAutoError) + x=raw_input('->') + print "OK, now we'll have a go with WordPad." + os.startfile('wordpad') + wordpadWindow = findTopWindow(wantedText='WordPad') + x=raw_input('->') + print "Open and locate the 'new document' dialog." + activateMenuItem(wordpadWindow, [0, 0]) + newDialog = findTopWindow(wantedText='New', wantedClass="#32770") + x=raw_input('->') + print "Check you get an exception for non-existent control" + try: + findControl(newDialog, wantedClass="Banana") + raise Exception("Test failed") + except WinGuiAutoError, winGuiAutoError: + print "Yup, got: ", str(winGuiAutoError) + x=raw_input('->') + print "Locate the 'document type' list box" + docType = findControl(newDialog, wantedClass="ListBox") + typeListBox = getListboxItems(docType) + print "getListboxItems(docType)=", typeListBox + x=raw_input('->') + print "Select a type at random" + selectListboxItem(docType, random.randint(0, len(typeListBox)-1)) + time.sleep(.5) + clickButton(findControl(newDialog, wantedClass="Button", wantedText="OK")) + x=raw_input('->') + print "Check you get an exception for non-existent menu path" + try: + activateMenuItem(wordpadWindow, ('not', 'there')) + raise Exception("Test failed") + except WinGuiAutoError, winGuiAutoError: + print "Yup, got: ", str(winGuiAutoError) + x=raw_input('->') + print "Check you get an exception for non-existent menu item" + try: + activateMenuItem(wordpadWindow, ('file', 'missing')) + raise Exception("Test failed") + except WinGuiAutoError, winGuiAutoError: + print "Yup, got: ", str(winGuiAutoError) + x=raw_input('->') + print "Exit wordpad" + activateMenuItem(wordpadWindow, ('file', 'exit')) + x=raw_input('->') + print "Err, that's it." + +if __name__ == '__main__': + self_test() \ No newline at end of file diff --git a/agent/crawl/watsup/winGuiAuto.pyc b/agent/crawl/watsup/winGuiAuto.pyc new file mode 100644 index 0000000000000000000000000000000000000000..758b1c8ae54f0fead5c80868250cc3651da85f12 GIT binary patch literal 38356 zcmeHw`)^!Ve%~3AqQuerEv;YI@`IFDq-=Q|+p=kgB58>=MQJao<=Sh78P2^V#~RL1 zb7xF4v4U;wX1%*u^pT?Iwm}m#n-u8}?GFvMDbNSdG$`61nxHKLq$q+E2+$^JfVO`? z+Rx|nJ@?L?A*q!`Z5~Bs&*i=6p6B;`U+4S%o^${4|2|l3{rc~`Q+EE}Vf_73{E|N| zI2SqhKCT59^|(6)_dagyzQ?`aliv5b_j}X(KKFiKdcViLzbC!#cklP7_j}#@d(-=U z?)`n~{eXLafDQToQ75X}<32?_`_n|c?RTG|#RD$d>pn&I4!UTcZVu)0SlI!UJ)BD~ zs_YRL?N^bbE;^u_V=g+Vo8vAzq?;2iI;@+ME;^!{Q!YBHo6{~jrkgV^IdDcwBo;wM~m+IJ?Y}7Ty#eFfs4*6!_zMMf^N>a=rP?qntEFb8 zUJF{yO109g#K}mpICo>>Mlc-Qsv#|y3YOz$P-@g$wJ2!TgY^co)s};#z8VKny_^Ik zyofhSt83Lbxezp0;-DEPO{6#ZP+Y3ln?ZdE_mw1Atw*hD93(6CRy7KexbYEk*VV*k zy%i+QQllA1>;tO7Q!OerqF}AmY{rcmYiT8=<(N0?mD<%-Weg(-P;aG%`WvyzEXTN;Ic{J?L8&aT05Tkq&+q#cW5A6# zX;qtSx>Q{+Z6?Tu@p267m1KouS}9>{s3~4rip$NQwT8L`wA>67J1btQG?FHVjUl3D z4lNx9dtu$gAAqtJtglqcXsF%0pp4cQ32;o+NHAB&^x%C3lfr)SZ7Yd`7{xKhC5(Bl zzGj^X>Rky5%5&~IGA*@g29-wKY&B{aI>4|LH{x1ZvzP!cFu5r-Q77hvxK^qa zCXiN^f>nU70(9|N6ESKwO9rU#*In|SQ!U? zv{Os0AuH)Y1t97@CVzD`jw+>QT-_9o?liR3(q?ccj@N=_V^dwI3sM-W>b?*}@fzlz zuWUxyy*MfYBn=?ja%&ZMXVB{eF?zBUeANo(8_1l2QIlS(Rz1@GKv)DREZ)#e2da=` zSj0rHt~EEena5mD)+^O28s}{0Ap|_Xm9)?ez$#gb%b+6;xLmRsY{nZ+BXk4vU=oz8 zr383}d0ebFS1w>GQ892aX)P^P$`!z53pO|6yRAwC6Kj=>1Vc0RCh&-K)W-I-Zc$os z-ebtv%_-6(Q3|Bq1g#~Qev$={MtDym32tsSS3q^@95`Dr3kI>$Y_46tcyTp}Y9p(a za-*KqmzpEx`s&4MWwB9eY+j6O!>!~Zdey32M1!}ccqPxg1%5SE1L`f6%CS#Gi~erm zwbw1*IAIZwl#(@&qL@kjBQUy3ygqV17|+4bpd`EsKouOcL7V7KAal?!kVTX#wK#gA zC@z;#&0snqV0Xq`NjEH0E`iQlwIr@3VAdbSBZ2kIAQ99`t8r3XZ2|Xu-W5p#DGVyVP4`BWt0ZY!Sv?sUS& zy|kvHL5bv_+kDLUZ4wvP>y0~{v{F@=1+ApqtZu5J1V|r1QU_oaX~k{%msXvnByB7a zNuZL_9dajd5X>2|f%nb&T2PHYic=&2APBgea89u_#f((<0X2Ei#I}X!&>T=>+Kf6} zYIup_yWJ(Wwst$ie?XOQQ;4v$DF}%7ej01__54&qPiUmdPJ33E>252Ae5*jM!^}2g zs~iL$6-`r0f}t*AnfFuyUPGNNIWGy&1X(wMaboh|25WU7EPm1IlFzpx3N0y_&3I#3`w-LCx{=L~S>1M5Ngk?@ z6;9!h6iw5D#s?KnoFuA1r-Rx9{^AAp}uFeXc_DSZXV>*WVdW@gOk;aWRgi zmVu{INu%f{id$#fLj=S!uBA+CjrvERL2z-fd`cOREXKN?YN53l+-z8Hn!wN!_^dAi zM&vne6BnW=OlsNUUs8*I&$P3!D1bC1=UzXg7>b1cpQ9ugCU{YMeZ4+%& zxULxq-mA9;0b+p_IMSh)-x!J(^^z$;o&jPKh|gXd_h{OwZ*QgU_7tf{(&<6j zP;rc9Q{+J4V@|JQ{G5yoZ7xU>ignwX2CS=?XI(%s4TP+2&RMXG?q z$=W8B#q-6vbzp%BfmNty!mCP|3!6A0DHB_ekzI$5nNT8N!DEx&rfYC9PE#t@R)Y752F^c>WMC{~lW1 z<0}2WXkl~MHDPSp$1X$zY&t5k&oBU`1rI2%+cP_V_uGX&^!dZ0tKV`3{Nn%)x<@qt zRA2aN?S{eS(NznB)$9^ zEAWU#t+@=fzP{>tFIU#AEtLXV&6R4K#Nx$D&CEo`r?9#ShOVcJ__lVQE=DO~RoB?e z1gtq!54uv*%vthQEFU9$q(h9p=o zVg0FfUb|xkdQAsNJ6qF1MiIbcsZMvfJwO8n8|l)pTCXh|HfA&VPHOK6(&cCN zDnqi7Ak15kO4*AY$Kxdn;ObX)n2qMN)Sg$-nO9jCTOH?u?U)3&j{w0Y`&?9`Le2bCbOhapMn5Rf^#>dpd{zE?HEfzrI@Ics`cey zw9_~@)TY1DtQzA#YOU+iZu|v+vs6u92+q-XwN{FDZajfKc!$&rnep>6^DpP0MY$7pgwNm~b*6!pT>#b|Owj~%ExT0xp?GGn`u=KkzaEi{kfc}w+B z7M$~SHxJ^zqvGT|Qf6Qu?~w#N`jn!yIMyiBMs;#_>yj372K(?)B>0N5v9&1jUQGUymzn ze8Rhl+dt_(keYd~-`(3wZLS_bkxErd-t<#f{BWOa>|Y+i@^fE@#V^*1g3kmnq#|$?cHYzI&PYO}gc8avuRa zL}u9}r$JXF!o>e4YpvCJTa-7?;^l&Ml*w^Jixo4{H^j9UYB1rK;2n#J$W8Lt(i$Ck zV(eY)R+7UUyh%vOA;wKfX@V$|o+gO&D4gCsJLXt_6~E+hT-*sV-Xn#*?l9Q#S^Q4= z-_b&u@5#oUneA7ZJH;w+@#3MqNT6gAvk4?`gD zG`IX`w2%<&u7^V^v+D!?r|$nVJh1x(w|Ux+0R5))fQ_No73OPSaD5zEuU7R4alk)> zu)uQQ3SULZzI)0$ar-z$5QG6n3uX^Va_sJ;`>7sQy)nk>CT_p3EWHv$eKdJM7C|VR zk%B@AvgarO2jKzx!(LWWxVxg?Ji;jul5r1q2>dVm2ZhtDK$?69;(7vhB@q`X5K#uS zEMt{jN=Xn)$~vBEaGk+MOOLIHPnTQf3yWGZY0%R-? zJl2u*Gng#F9*#j{>5fDiA2qBLBv}>y#ur52N#0oXAUlC#cY=zo3g!7|Ee@wGT@Wz3 ztAjxh7Ly%VAXLFB9LGDX0op=$bTG7>UK#IhWNnSkz7hK~)V5*{bu@6^H2E1(TFNMn zgUF;Qf^dMu-z<>izUkaIdfYc~Ex09wTlKh~Mq-cq4D=*xUjf#>*&*tAQaC5#;i!d} zj55s3Sm>g!o9TSmpNg=he!lb|fuUN*N9GeK__zV^~>@%98R z4Ccc7U1`tF6R3bSjr%p|tW}(lGaI*q-dr?pNBEJwYYu)6Hvj`!(i%ZxfS$O$=sp0W z!vDPj3a$o}$6SHaA$C>=SUy7$JrwR97oYkJT5-QItpa%@;3uYqw|K>bEc-mb3!V5A z$d8Sa#t#p&C+Gv-jNbj0n~ze7F=Nt~oEi=VN!B=|qzND60mlD2B z%3W$K<8Tf{^QO&67^`?pgNXnwJa1FF;6B7j35kK40Z)426HFk*SwfS!5KUE$u7SaY zC-D@XVipR2%d$Y829_BPBFW%@n};2E_yWrQF3UfOi#ytn7366EexNWYz#qnX5{gXE zz{z4ynf)X*2#0a}lGh+VjU2$CfQ?{Az+~_rp>Hq5G!};l-ei>HkDK`&3r)QCZVB&t z@NNmZ9#T>`4Yz`xLT__$T(AV-ImVXv~ zC}~f97}pPQqCkNpf9p_{9$eeZ2kdOC*RkHrOyPT$ASHpfEpO+Ll_cwgp0@Fv_zKz{ z9IUPxV8?V=vhx*cS(#O6Pusg=Qh51Lz5DxP#*H$z^Sb?sIAs2$ttVV#q%Ii`D1-8D zd@{bG2XU2HV;u%)KdBGql=&P@*~)7>yU>pGU}5LJjSkkZBQb1^%FZ~KjWxqrf1{cn z)Gw5FCGQyWY2NLy!xD>)WmcwcBh!6sOx?XzJwE=)S2J!TGn7@o{R(iqntWQ$6gqm& zVyn(QWF_P*a8$i}&K7xH_AA-)yVc5I3Gp#l(kn0;ik~@yq+$jMja;eIMs+`OHx3o; zQ(BN9;ij#xovWqL5WD%EdXr0dmf3I8WqsI8tovZzO z3f8G#bcGcxQ1`fvGv>BALL(XVap}Zw-hBWNM<8IU2|}AwKa`gdIoa+57);K3S#7dbR!wqM{$$JhL)3MYOjq z-CMA`LfH|Eno6in7gOd)XXDCh4)e5W<1;%BP3?BOzE>ED4wi|S^tt*PABH$oV<%=` zrw&?fZmz*4$Xm8jt?HIryI#H|3on4n!b&bLaDm@OFji>Tg5nQrx|Nl=-OJw~j*!sY z{xbhiN2ZD_ocK0gnxPgLU@jaWhj|^~yx90fS#Jw2n7I92a5d2#SEvuNDkup0 zC6!2E6Rvw)kGVeP?>-M-Z@(P9Uy*@w^C?=nQ9YOuOPcEz0Yq|@%-{W&$iGkdpEiRg zETTYEg^8nsrz13szcA|}YvHS?Ul%eoXuxOT^4)w^9fXm%060|kyUGDqfl(Dr!vBkA z_PP1mPh{PyZS5AaS+@qLDdYe7+VBH+OH!b_;Q`;Uy#zCcF&AJz>?%j-eTFjrNgww2 z?*R!CZIY89*)hKX1av6;WC*+D|AS!0oKs{Z|g=8=3qJQ zP`Sx{CjKAW&hI-(iL^ZwM*4z!+fl%!9h*%Q>WZ!DW;^WKa)O=dt!3LkuMxni*1S(> zZ`KpSbHv=tyyeC(#kQ;4-Nwot`{uX(So|@lJ>D>TF&*ma4)^Hp){=tph|O7`fvSb| zf~P%LApVXqww?>78+)$%nHs|8T*kPX(7q514KBf?FnA#t#8$i7p!YcMIOchAXiQ$Z zEfe#Dy-JLpgp3#&xzBJ@{K)_PfxUb2LhzFBlXk;ksR|k)7vq2o&k|}YFzwg4?>OC( zIWjXOC5DWy?WgnXmnb`q$k(Qnm<6y)fd?Cn#H8U`CZOeZBYs#`8XD%n-W39^aMcCc z7-lfZ5q!ohkuyt-vfa0Mc^emnh~^rfnvhO)6I-XR+wQ}5a1__k9N_%*h4CBLufu;Z zB+JGX)u$ zikQ87xkUG1_jLakN+*uXojI`QaB)Ahm)^p@!eKZY5vB@#t+#MWcLxh+dW-(u!7c9& z7oO;qblZoT_~WD}1NWD1;J6TJ8{aqQ`9GwUgz^olIsA_WD&deC@XkSMNFk>Z-N#U( zOuh|4FkqV#wkO>&LGmR!@w|LP$xOcORVaYfh_G0z5s5u+{_by~l7YO?)0sP%4oEc# zJ#5nQLhrXI?}qF$kG^08bfG>8uUvPbOj0WB7B(GI^{J9SI0YroAo~`&!VwQVSb(@9 z@_YOI%n(s5%qT6K;NwfYO!7i346pKXjh882xU7)<&SLk71K|uWH+Z?p%a?f(276=_ zdMXBiq*#mB7liJ+M@@D=#{)*7C`m7OeFypu@9XcSR^5%4$AG296gL%O4ZJigq!{P; zgoT^HLLe2?ES?0Uu(MBa5)kGdh=Mx{5;2|J6mm>Fs2Yd{1Txfv7Q~6h)C1q31rf_~ zzVbALE${P&o&lVIt#7Y80rUZKV>RMiDe4|O?o z)$11IkcRvHZ9W`!h=Bk;ve!r5kD^rlDReb!?-*NR1Je8!j=NeB3J=sels%p+ds1bY zdMcNCI!is1OFf&Vej%6oSeE)YYo8V4OkU}=Ma@U0My1}egAxKArx4`ytNW~J$OZFK z3-?rVL;`uYqxLFu!y5FEOb$tuwx%Y?l{+e76_hSmh)8+Z+3BP9nH3qaOoHE+^1r_L zA-1@BUCJKV_F^ePR2NPG*-?g>>slGyF~<-vqeI0B_MBE}6Bgd5GVmGI)& z?9G{r^zw_Zo!?#&AONPYdypITa2Nph((2q0Y~gEE zV9&vZBOO-4&^<4AclNG$p@zK4_)1*9!;OfQWTKLku(@6LR~zxBKj~!0u~w2<=tGD$ zt~a*Lqr?YtdOet`=5b(W3tdiDW5JnMPKLzq5dCS|hAlojaLPaUe4W|=D$7+pl0h$@ zm_c2mmWDv&qux*kN7FwrG)I1|c&Hdhz7xiiA%%q=p+vVV_>rJ9dC4)^B)qe5^Ty3vHw91BHEXJwiB?Kly+Ciq zuT74>J2_#hYf2VU0r7HTYIf|(G~QC5Y*UId^;0BL@J4qj`Tphnw`8k7LLu` z2vt>%WK6H1(3a-xAsljsR1s%FS|`E62LUj9Mdewjpv%MJ1GS9zhz~OJojlbu(0dpH z`vAos5J87hU_x;yz$zq5Y^QAK^c@~Z0qeApdH0GPHc(Qkt--p&sIx_?Rj`AT zyuQ6-dkJd?i%s5{ZEnLbcJ0;91wOYu+T9K1&LbI0`)@qVM+DQBxxn*iu#pkRmHCyC zQ5#YA%FM#}^c3-1Ml;1t?izc9(YdbuOv+ebG5egT@on_+K~RHov{K#$YFGt3pa%Db zht}F`n|B_mo{oSim-44a?wUjn~0^#EP~x!Z)B!)M4Iq`7MS<7sI=uR zlq*|Ta*>Pmp1CI>O=SxQrg{YZWr|dt9U_66MY0l23{TsrzxfBog&}y);F%lBk>UB_%$)`@%JcE?FXGuK zj?5brwhi;1-pahc#bRRK)L*xbAmiQPUuMpq=H(l>?0VrAeh0Pue#WT}KN?Q`+w7l3 z?n$X_Qnpi9#v$-H4f9dx$=lSEwwU4+58h0hvJKu67MU{-Uo%SfzRPS&}yIJT>HPoUsR6NQWLz~e!e#u|M zWmDT+p^Bbn{M<5p8U+Mr9ES$#Zg|>9mGESS;$0Y<#UquF{veSHU1>d@wuhZzqPx!xe&a zlRWn^NZo#mJpO@WBVBHP#9QvD;*51(2+m!Lacl>UkXS}2w2dG?h9zQ9 z92oPVf3$?itBKW>_a%%J2Z{qzwY3)Tc(^#A{RhM8hX{b!JRjYYOL2ha(HMt^U%?3* z;CsaZLKM$w{UR_mfc02$Kr9lk$C25rd1>Qp^hT?hwmJox;^%dShq1|2pU?5^0){W! zj+V0p1X#u6RGEl%kda-cNj@y#!Zp4;E*xS15xZ3Xu&VUBv+qz$zTx{6L6~ zT2F9riM~Zr!fRBR?bpVzVYj0%7*JcFK>!S3mFM0f4sW1>xq!yYx#>npDkN8gl5(I4 z39ih}rS3F&ehk|r^a+HvFXvEz|Ip8ei!{! zOdX*LCri+q>GwC$41ILe1&oJEReiz z#GI=26lO$q1fTe0q|!-$7}D;Tj2A()>m)s#2Wh(Css$7V+7?)gxjr; zUV72fsab)vH>E8(JekszPCs{>EW-#;e>4QW zdP+;sWsJH7St|mc!6|9imRt}o5BPy5poWxByr?%Kuv+ly1`gG(;QJc*EE{!Hezyjm zaEJkgFkr(c1Ig(PhpqsnTVD=gIY2g`%L#F}%w75jo0%D^qgrH=gjzvG!*lg~Q=lLi z;1xCw)ec?7iOBZ3JA7-ypHZ!P@VyX*NSOkej?O+3K_%6ERTz~Yu~#5}fWM2w1Wejz zFZz12lh9bL9TK5&v_sp~Cl>GimjcnR@Z_`sV7w7sxu;;%_TchRv?T)a=KWC0tAuoB z0Gq6UI^g+GwlRi9kfvFT%pYh~R~QMQ@R*92wQkG02DT+zSk&Y}b<)LnFl}3y$|?`z z6M9IQRcbU!n~HFeZlB*U^ zbJyfLv!EK7wU!b6OcRB$PFN+ol4Q5ieE1EShMuQYX4hOIq-px6zz6Jbq$B;1q}Z4yW~cxpYBJ(P6@VG~Eo(ON}3n=wvK<=o=%c}~IA{Q1?IR-|a>ry_y~F;llV z!G;mEitc{y=+yZ+&K>dC^$)6!@HoYhPL`wS_w zL~N~^2>2KAEMY2|W*=cP!>M@n^<6_;>pMik+1Y5*0Ld?-YSVN34~SH<3D}1=$MH+J zZ^Gm#uYx-%L}om27SIoRPhp2_NQAuW;s1D)aV{g9XHXB9BLPn8R7g?E7fBryMP@Fu z((%+`g{g_QdZKLB1JB@h z4Ocl-f29||qP5=j9MkSr;WJoxXFwaziUVwb2%q38g%!vQfO-G>m+?M~SMlkZVDNdI z1ib>BEdymC$|;Y520-6(3118mn(A`P0(U9+vU8|BJk7!aqQP0@A*}+2T9gQ?N(*{# zQImErmhB7AVI{wN;LsKE&j}oI64xiKjqQ`_$MH-4IxZXU5y{M`J8}En^t?tSiNLAL z0jK&bn1*Y1J_2r7xg*5=G~(g4k1^XA0i6Jqx-=ZZzPy7c zRp!I?q4ar^GB*tA)D12hz;fe_09<+zb3m;LC|qm7I_$%C!ELbhu9SYDq^$7ik%T8Z zDjHV%l5z*)`*>Ia$Op$#%}}h%s6Q~q*Gx`4>Ph35kli+OuwWSDBH4>YO{1Bx3%Ok$ z}7 zL23V{ouh)i8Q|x3hzh79ql*Ap?{iQp#o|brXwEwO@Y7KOT#9Vm7HTOLX5#h@9SE9k zvBj(dkwAUv8KA-fVhvBf|IE$+#nH$nY(|-mMCt}v#(A`n?%`*$x z;pJIej3YhA$LINo-^1=R*14Mhkr3w^&FOs3BRZdRf6w;ka!RPP*|-tXMxG?|opqd@fP`Jm zoNupEtDwFAN+7Z!XH-IpWf#WrORnMqD(SOxWg$K=hEG5ex1VUAaEmd4a)6p(hM=NT z$L^lsVZUIWpd*TI9nNV$o=I5!bIIs)jf7KFG#vdk+?rqbZ{p7EbHC0sMdc6RF54cW zb$YLw|CEbPBX@zentbLn$Q+$z30PO~qD-!hq{rGxktKB$ zdjhZ7=UAsXLr;LHWbr3m^psl`>o3$^lKK!Wb>#{2dBFK0Goz>3QJi`J!i~6GpJT_cbr1XgFsA2Gu0Y6{VW|y-L1x27J^*2e{V!neaOJRz&Toa+3(Sh$ zeOBWa)qxAh)MJ}!dGJ?rk_kl+*U z%BwVf%Neq7hT?_dVBN6j&I&{(P#?iohSb-HfvSA z?V=xLfoRM%K`Z#sV@I**3bJ~TO-93CEB6`i z?4tz%K>d7zV`)C=kPn5hSUCfv-ip^pbN$buHi~p&^jA1o%##7?L#t`GBYm%<(mRi) z(ytK=*3GKbm%<^n z{@5lwDmgysa4Lwm0+eYD z^kb1u1d9fb6460cO7JhW`kdx>2~itk4zy;Kof+%drMh-wzQa%HaxE*(mWPlinKvIJ zF2>Buyh)zlrW;%u4|*HIAU>nQ4+0`$fI3{FgT%srfm>D0sH$WbPji?Qd6a|o2I|MS zGH<|**c zT56TCZ3&GZ7K9=wFiHVfL7R%cI4T2ST+!b7BTryqiJx9(kDUA6 zxAob(eDh^~H={b}eTinY(T+CMI3k$X>36yvS7x2<&^@;{78u3a5S5`0E>nOCr=<|Q z=qS2llg2b+?K`-U(XNeP_=*Y-8KKXGpRY$C*#tkSvrQ8+!@7 z1Gzi|JraX16n+PjU&$bdF2UroZS;`N+U# zF+C=OWg2WF*Ga--^|(Cs-`xdt5Jpj}uU{6LOoB{k;UqPx-U)pPonNaQ(Z>hNWH9`Z zbl&ilv=$utl&9J5^T9C8#7!l)$pIdK#KQgCJXxS zwbm{K%k}2vAbAdr+<5l_VHm8({Lr_tKfE@RTFR)!*l4K-Y<2HnBrmXrF77DwW=I|u zi!H{jrIa)xgZfOop1k}yN9XOLBG^39r!6S1e9(L}WIkA(Ir>USE{t~o{P>7hH1s8D zMEUtqvGlN7YzXD+%LQ+j#EhLd*hZF)4Nq;?M!zd|N%5#u5k+cFUT4WtT3lg&hd zIKUgP8+c7Z8?73pbsSrOV6gBE3k={Q8!*SM?~sP?Au0Sy`f@TQ+weuE|1DlP13ITW zyu`bYcp-T8)tT_?y!#Xv_0D#pg+If@zsd{I+s^#{7Vo};i_pYxd62hx=oDZ5Aus=f z?~ma!KQ*)PmC0}x=QJ!#Ai#ZMQs(HKrX+{OM(U~|E1j3WQz>56usu*3Hf6rN?s8w6 z2=-!@1Eg^Bxzk5UG25@kw|c}X%JS+-6e{+Z?vK|41=ASh64X$DJNpE&-qq^9QOZt? z#(x&p4kp`U8Z_geET58uF(@yi(!y_D+=akQRuy6qR7@9M{qa9RQIk8_4 zdGYSJavZ}Op5ep;A*`)ag@f?eqYUyKL#q9E9DkW|7H`wCc*8td?q1|Mg8$e;)?2h= zJ?quG^zAX^vG$%psmE2KvwY_hS}$l)abgNWjd5Ozi00n`YT@7KWt10Esyw*iAMuVj z5&kMK)4WJvzr;KG1&yvqszzKQI8{2%G?J+i>?H3*i5tB830}U=3n?-D7B3_<(V$qn z0!EFVMVvp&w||$HpXY@!5_X>O_j%XkMXsYM-u)|FMBa96k&O4@|Kb~w_dei>?3!&P z)ZIhs8`5Flv@>YlB6~_c#HAnT)b(FaFJgK5-+>#)&JFYryp}z$Ds^Ju;6OO=#evKC p%aGP111Ir2GjQm@%Lh*D>1m|y9~eN{g9C?79XQoH@CyeE{}(zc4mtn; literal 0 HcmV?d00001