tests/ide_tests/sikuliberemiz.py
branchwxPython4
changeset 3710 51c2d434e10e
parent 3696 ea30051326e9
child 3713 cf7c91183995
equal deleted inserted replaced
3705:fcf3dcc8ab3b 3710:51c2d434e10e
     3 import os
     3 import os
     4 import sys
     4 import sys
     5 import subprocess
     5 import subprocess
     6 import traceback
     6 import traceback
     7 import signal
     7 import signal
       
     8 import re
     8 from threading import Thread, Event, Lock
     9 from threading import Thread, Event, Lock
     9 from time import time as timesec
    10 from time import time as timesec
       
    11 from xml.sax.saxutils import escape as escape_xml
    10 
    12 
    11 import sikuli
    13 import sikuli
    12 
    14 
    13 beremiz_path = os.environ["BEREMIZPATH"]
    15 beremiz_path = os.environ["BEREMIZPATH"]
    14 python_bin = os.environ.get("BEREMIZPYTHONPATH", "/usr/bin/python")
    16 python_bin = os.environ.get("BEREMIZPYTHONPATH", "/usr/bin/python")
    15 opj = os.path.join
    17 opj = os.path.join
    16 
    18 
    17 tessdata_path = os.environ["TESSDATAPATH"]
    19 tessdata_path = os.environ["TESSDATAPATH"]
       
    20 
       
    21 ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
       
    22 def escape_ansi(line):
       
    23     return ansi_escape.sub('', line)
       
    24 
       
    25 def escape(txt):
       
    26     return escape_xml(escape_ansi(txt))
    18 
    27 
    19 class KBDShortcut:
    28 class KBDShortcut:
    20     """Send shortut to app by calling corresponding methods.
    29     """Send shortut to app by calling corresponding methods.
    21 
    30 
    22     example:
    31     example:
    57         """
    66         """
    58         Parameters: 
    67         Parameters: 
    59             app (class BeremizApp)
    68             app (class BeremizApp)
    60         """
    69         """
    61         self.r = sikuli.Region(self.sikuliapp.window())
    70         self.r = sikuli.Region(self.sikuliapp.window())
       
    71         self.targetOffset = self.r.getTopLeft()
    62 
    72 
    63         self.idechanged = False
    73         self.idechanged = False
    64         
    74         
    65         # 200 was selected because default 50 was still catching cursor blinking in console
    75         # 200 was selected because default 50 was still catching cursor blinking in console
    66         # FIXME : remove blinking cursor in console
    76         # FIXME : remove blinking cursor in console
   197                 exemple (str): path relative to exemples directory
   207                 exemple (str): path relative to exemples directory
   198 
   208 
   199             Returns:
   209             Returns:
   200                 Sikuli App class instance
   210                 Sikuli App class instance
   201         """
   211         """
   202         sikuli.OCR.Options().dataPath(tessdata_path)
   212         self.ocropts = sikuli.OCR.globalOptions()
   203         sikuli.OCR.Options().oem(0)
   213         self.ocropts.dataPath(tessdata_path)
   204 
   214         self.ocropts.oem(0)
   205         self.screenshotnum = 0
   215         self.ocropts.smallFont()
       
   216 
       
   217         self.imgnum = 0
   206         self.starttime = timesec()
   218         self.starttime = timesec()
   207         self.screen = sikuli.Screen()
   219         self.screen = sikuli.Screen()
   208 
   220 
   209         self.report = open("report.html", "w")
   221         self.report = open("report.xhtml", "w")
   210         self.report.write("""<!doctype html>
   222         self.report.write("""\
   211 <html>
   223 <html xmlns="http://www.w3.org/1999/xhtml">
   212   <head>
   224   <head>
   213     <meta charset="utf-8">
   225     <meta charset="utf-8"/>
   214     <meta name="color-scheme" content="light dark">
   226     <meta name="color-scheme" content="light dark"/>
   215     <title>Test report</title>
   227     <title>Test report</title>
   216   </head>
   228   </head>
   217   <body>
   229   <body>
   218 """)
   230 """)
   219 
   231 
   271 
   283 
   272         IDEIdleObserver.__init__(self)
   284         IDEIdleObserver.__init__(self)
   273         stdoutIdleObserver.__init__(self)
   285         stdoutIdleObserver.__init__(self)
   274 
   286 
   275         # stubs for common sikuli calls to allow adding hooks later
   287         # stubs for common sikuli calls to allow adding hooks later
   276         for name in ["click","doubleClick","type","rightClick","wait"]:
   288         for name, takes_matches in [
   277             def makeMyMeth(n):
   289             ("click", True),
       
   290             ("doubleClick", True),
       
   291             ("type", False),
       
   292             ("rightClick", True),
       
   293             ("wait", False)]:
       
   294             def makeMyMeth(n,m):
   278                 def myMeth(*args, **kwargs):
   295                 def myMeth(*args, **kwargs):
   279                     self.ReportScreenShot("Begin: " + n + "(" + repr(args) + "," + repr(kwargs) + ")")
   296                     self.ReportScreenShot("Begin: " + n + "(" + repr(args) + "," + repr(kwargs) + ")")
       
   297                     if m:
       
   298                         args = map(self.handle_PFRML_arg, args)
       
   299                         kwargs = dict(map(lambda k,v:(k,self.handle_PFRML_arg(v)), kwargs.items()))
   280                     try:
   300                     try:
   281                         getattr(sikuli, n)(*args, **kwargs)
   301                         getattr(sikuli, n)(*args, **kwargs)
   282                     finally:
   302                     finally:
   283                         self.ReportScreenShot("end: " + n + "(" + repr(args) + "," + repr(kwargs) + ")")
   303                         self.ReportScreenShot("end: " + n + "(" + repr(args) + "," + repr(kwargs) + ")")
   284                 return myMeth
   304                 return myMeth
   285             setattr(self, name, makeMyMeth(name))
   305             setattr(self, name, makeMyMeth(name,takes_matches))
       
   306 
       
   307     def handle_PFRML_arg(self, arg):
       
   308         if type(arg)==list:
       
   309             return self.findBest(*arg)
       
   310         if type(arg)==str and not arg.endswith(".png"):
       
   311             return self.findBest(arg)
       
   312         return arg
       
   313 
       
   314     def findBest(self, *args):
       
   315         #match = self.r.findBest(*args)
       
   316         match = None 
       
   317         matches = sikuli.OCR.readWords(self.r) + sikuli.OCR.readLines(self.r)
       
   318         for m in matches:
       
   319             mText = m.getText().encode('ascii', 'ignore')
       
   320             for arg in args:
       
   321                 if arg in mText:
       
   322                     if match is None:
       
   323                         match = m
       
   324                     if mText == arg:
       
   325                         match = m
       
   326                         break
       
   327         if match is None:
       
   328             self.ReportText("Not found: " + repr(args) + " OCR content: ")
       
   329             for m in matches:
       
   330                 self.ReportText(repr(m) + ": " + m.getText().encode('ascii', 'ignore'))
       
   331             raise Exception("Not Found: " + repr(args))
       
   332         
       
   333         # translate match to screen ref
       
   334         #match.setTargetOffset(self.targetOffset)
       
   335         match.setTopLeft(match.getTopLeft().offset(self.targetOffset))
       
   336 
       
   337         self.ReportTextImage("Found for " + repr(args) + ": " +
       
   338             " ".join([repr(match), repr(match.getTarget()), repr(match.getTargetOffset())]),
       
   339             self.screen.capture(match))
       
   340         return match.getTarget()
   286 
   341 
   287     def dragNdrop(self, src, dst):
   342     def dragNdrop(self, src, dst):
   288         sikuli.drag(src)
   343         self.ReportScreenShot("Drag: (" + repr(src) + ")")
       
   344         sikuli.drag(self.handle_PFRML_arg(src))
   289         sikuli.mouseMove(5,0)
   345         sikuli.mouseMove(5,0)
   290         sikuli.dropAt(dst)
   346         sikuli.dropAt(self.handle_PFRML_arg(dst))
       
   347         self.ReportScreenShot("Drop: (" + repr(dst) + ")")
   291 
   348 
   292     def close(self):
   349     def close(self):
   293         self.sikuliapp.close()
   350         self.sikuliapp.close()
   294         self.sikuliapp = None
   351         self.sikuliapp = None
   295         self.report.write("""
   352         self.report.write("""
   302             self.sikuliapp.close()
   359             self.sikuliapp.close()
   303         IDEIdleObserver.__del__(self)
   360         IDEIdleObserver.__del__(self)
   304         stdoutIdleObserver.__del__(self)
   361         stdoutIdleObserver.__del__(self)
   305 
   362 
   306     def ReportScreenShot(self, msg):
   363     def ReportScreenShot(self, msg):
       
   364         cap = self.screen.capture(self.r)
       
   365         self.ReportTextImage(msg, cap)
       
   366 
       
   367     def ReportTextImage(self, msg, img):
   307         elapsed = "%.3fs: "%(timesec() - self.starttime)
   368         elapsed = "%.3fs: "%(timesec() - self.starttime)
   308         fname = "capture"+str(self.screenshotnum)+".png"
   369         fname = "capture"+str(self.imgnum)+".png"
   309         cap = self.screen.capture(self.r)
   370         img.save(".", fname)
   310         cap.save(".", fname)
   371         self.imgnum = self.imgnum + 1
   311         self.screenshotnum = self.screenshotnum + 1
   372         self.report.write( "<p>" + escape(elapsed + msg) + "<br/><img src=\""+ fname + "\"/>" + "</p>")
   312         self.report.write( "<p>" + elapsed + msg + "<br/><img src=\""+ fname + "\">" + "</p>")
       
   313 
   373 
   314     def ReportText(self, text):
   374     def ReportText(self, text):
   315         elapsed = "%.3fs: "%(timesec() - self.starttime)
   375         elapsed = "%.3fs: "%(timesec() - self.starttime)
   316         self.report.write("<p>" + elapsed + text + "</p>")
   376         #res = u"<p><![CDATA[" + elapsed + text + "]]></p>"
       
   377         res = u"<p>" + escape(elapsed + text) + "</p>"
       
   378         self.report.write(res)
   317 
   379 
   318     def ReportOutput(self, text):
   380     def ReportOutput(self, text):
   319         elapsed = "%.3fs: "%(timesec() - self.starttime)
   381         elapsed = "%.3fs: "%(timesec() - self.starttime)
   320         sys.stdout.write(elapsed + text)
   382         sys.stdout.write(elapsed + text)
   321         self.report.write("<pre>" + elapsed + text + "</pre>")
   383         self.report.write("<pre>" + escape(elapsed + text) + "</pre>")
   322 
   384 
   323 
   385 
   324 class AuxiliaryProcess(stdoutIdleObserver):
   386 class AuxiliaryProcess(stdoutIdleObserver):
   325     def __init__(self, beremiz_app, command):
   387     def __init__(self, beremiz_app, command):
   326         self.app = beremiz_app
   388         self.app = beremiz_app