tests/ide_tests/sikuliberemiz.py
author Edouard Tisserant <edouard@beremiz.fr>
Fri, 30 Aug 2024 11:50:23 +0200
changeset 4008 f30573e98600
parent 3853 e1cfb03e6582
permissions -rw-r--r--
IDE: allow structures to be located.
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     1
"Commons definitions for sikuli based beremiz IDE GUI tests"
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     2
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     3
import os
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     4
import sys
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
     5
import subprocess
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
     6
import traceback
3668
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
     7
import signal
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
     8
import re
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
     9
from threading import Thread, Event, Lock
3437
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
    10
from time import time as timesec
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    11
from xml.sax.saxutils import escape as escape_xml
3432
40b8b2ffb3fd Tests: Various enhancements in Makefile and sikuli common python code.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3431
diff changeset
    12
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    13
import sikuli
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    14
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    15
beremiz_path = os.environ["BEREMIZPATH"]
3431
5bcef31e276d Tests: Added BEREMIZPYTHONPATH to point to Python interpreter to use for tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3430
diff changeset
    16
python_bin = os.environ.get("BEREMIZPYTHONPATH", "/usr/bin/python")
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    17
opj = os.path.join
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    18
3696
ea30051326e9 tests: add tesseract training data "tessdata", still trying to enhance OCR reliability in UI tests
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3695
diff changeset
    19
tessdata_path = os.environ["TESSDATAPATH"]
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    20
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    21
ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    22
def escape_ansi(line):
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    23
    return ansi_escape.sub('', line)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    24
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    25
def escape(txt):
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    26
    return escape_xml(escape_ansi(txt))
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    27
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    28
class KBDShortcut:
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    29
    """Send shortut to app by calling corresponding methods.
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    30
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    31
    example:
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    32
        k = KBDShortcut()
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    33
        k.Clean()
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    34
    """
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    35
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    36
    fkeys = {"Stop":     sikuli.Key.F4,
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    37
             "Run":      sikuli.Key.F5,
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    38
             "Transfer": sikuli.Key.F6,
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    39
             "Connect":  sikuli.Key.F7,
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    40
             "Clean":    sikuli.Key.F9,
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    41
             "Build":    sikuli.Key.F11,
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    42
             "Save":     ("s",sikuli.Key.CTRL),
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    43
             "New":      ("n",sikuli.Key.CTRL),
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    44
             "Address":  ("l",sikuli.Key.CTRL)}  # to reach address bar in GTK's file selector
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    45
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    46
    def __init__(self, app):
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
    47
        self.app = app
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    48
    
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    49
    def __getattr__(self, name):
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    50
        fkey = self.fkeys[name]
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    51
        if type(fkey) != tuple:
3432
40b8b2ffb3fd Tests: Various enhancements in Makefile and sikuli common python code.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3431
diff changeset
    52
            fkey = (fkey,)
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    53
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    54
        def PressShortCut():
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
    55
            self.app.sikuliapp.focus()
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    56
            sikuli.type(*fkey)
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
    57
            self.app.ReportText("Sending " + name + " shortcut")
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    58
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    59
        return PressShortCut
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    60
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    61
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    62
class IDEIdleObserver:
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    63
    "Detects when IDE is idle. This is particularly handy when staring an operation and witing for the en of it."
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    64
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    65
    def __init__(self):
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    66
        """
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    67
        Parameters: 
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    68
            app (class BeremizApp)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    69
        """
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    70
        self.r = sikuli.Region(self.sikuliapp.window())
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
    71
        self.targetOffset = self.r.getTopLeft()
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    72
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    73
        self.idechanged = False
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    74
        
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    75
        # 200 was selected because default 50 was still catching cursor blinking in console
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    76
        # FIXME : remove blinking cursor in console
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    77
        self.r.onChange(200,self._OnIDEWindowChange)
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    78
        self.r.observeInBackground()
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    79
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    80
    def __del__(self):
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    81
        self.r.stopObserver()
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    82
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    83
    def _OnIDEWindowChange(self, event):
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    84
        self.idechanged = True
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    85
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    86
    def WaitIdleUI(self, period=1, timeout=15):
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    87
        """
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    88
        Wait for IDE to stop changing
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    89
        Parameters: 
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    90
            period (int): how many seconds with no change to consider idle
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    91
            timeout (int): how long to wait for idle, in seconds
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    92
        """
3437
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
    93
        c = max(timeout/period,1)
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    94
        while c > 0:
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    95
            self.idechanged = False
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
    96
            sikuli.wait(period)
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    97
            if not self.idechanged:
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    98
                break
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
    99
            c = c - 1
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   100
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   101
        self.ReportScreenShot("UI is idle" if c != 0 else "UI is not idle")
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   102
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   103
        if c == 0:
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   104
            raise Exception("Window did not idle before timeout")
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   105
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   106
 
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   107
class stdoutIdleObserver:
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   108
    "Detects when IDE's stdout is idle. Can be more reliable than pixel based version (false changes ?)"
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   109
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   110
    def __init__(self):
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   111
        """
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   112
        Parameters: 
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   113
            app (class BeremizApp)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   114
        """
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   115
        self.stdoutchanged = False
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   116
3437
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   117
        self.event = Event()
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   118
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   119
        self.pattern = None
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   120
        self.success_event = Event()
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   121
3670
cfb2b05b68c4 Tests: UI tests now avoid polling stdout if process didn't start.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3669
diff changeset
   122
        if self.proc is not None:
cfb2b05b68c4 Tests: UI tests now avoid polling stdout if process didn't start.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3669
diff changeset
   123
            self.thread = Thread(target = self._waitStdoutProc).start()
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   124
3528
c269f256a7c4 tests: add (broken) debug_project test, fix edit_project
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3448
diff changeset
   125
    def __del__(self):
c269f256a7c4 tests: add (broken) debug_project test, fix edit_project
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3448
diff changeset
   126
        pass  # self.thread.join() ?
c269f256a7c4 tests: add (broken) debug_project test, fix edit_project
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3448
diff changeset
   127
3432
40b8b2ffb3fd Tests: Various enhancements in Makefile and sikuli common python code.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3431
diff changeset
   128
    def _waitStdoutProc(self):
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   129
        while True:
3437
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   130
            a = self.proc.stdout.readline()
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   131
            if len(a) == 0 or a is None: 
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   132
                break
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   133
            self.ReportOutput(a)
3437
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   134
            self.event.set()
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   135
            if self.pattern is not None and a.find(self.pattern) >= 0:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   136
                sys.stdout.write("found pattern in '" + a +"'")
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   137
                self.success_event.set()
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   138
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   139
    def waitForChangeAndIdleStdout(self, period=2, timeout=15):
3437
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   140
        """
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   141
        Wait for IDE'stdout to start changing
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   142
        Parameters: 
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   143
            timeout (int): how long to wait for change, in seconds
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   144
        """
ce366d67a5b7 Tests: Enhance robustness of stdout driven waiting state in Sikuli based tests.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3432
diff changeset
   145
        start_time = timesec()
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   146
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   147
        wait_result = self.event.wait(timeout)
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   148
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   149
        self.ReportScreenShot("stdout changed" if wait_result else "stdout didn't change")
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   150
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   151
        if wait_result:
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   152
            self.event.clear()
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   153
        else:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   154
            raise Exception("Stdout didn't become active before timeout")
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   155
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   156
        self.waitIdleStdout(period, timeout - (timesec() - start_time))
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   157
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   158
    def waitIdleStdout(self, period=2, timeout=15):
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   159
        """
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   160
        Wait for IDE'stdout to stop changing
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   161
        Parameters: 
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   162
            period (int): how many seconds with no change to consider idle
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   163
            timeout (int): how long to wait for idle, in seconds
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   164
        """
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   165
        end_time = timesec() + timeout
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   166
        self.event.clear()
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   167
        while timesec() < end_time:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   168
            if self.event.wait(period):
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   169
                # no timeout -> got event -> not idle -> loop again
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   170
                self.event.clear()
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   171
            else:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   172
                # timeout -> no event -> idle -> exit
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   173
                self.ReportScreenShot("stdout is idle")
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   174
                return True
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   175
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   176
        self.ReportScreenShot("stdout did not idle")
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   177
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   178
        raise Exception("Stdout did not idle before timeout")
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   179
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   180
    def waitPatternInStdout(self, pattern, timeout, count=1):
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   181
        found = 0
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   182
        self.pattern = pattern
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   183
        end_time = timesec() + timeout
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   184
        while True:
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   185
            remain = end_time - timesec()
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   186
            if remain <= 0 :
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   187
                res = False
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   188
                break
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   189
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   190
            res = self.success_event.wait(remain)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   191
            if res:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   192
                self.success_event.clear()
3424
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   193
                found = found + 1
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   194
                if found >= count:
7db96e011fe7 Tests: added tests/Makefile and a first test in tests/ide_tests. Test requires sikuli and Xvfb or Xnest.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents:
diff changeset
   195
                    break
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   196
        self.pattern = None
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   197
        self.ReportScreenShot("found pattern" if res else "pattern not found")
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   198
        return res
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   199
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   200
class BeremizApp(IDEIdleObserver, stdoutIdleObserver):
3669
ca25c686cd97 Tests: UI tests can now load projects from tests/projects
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3668
diff changeset
   201
    def __init__(self, projectpath=None, exemple=None, testproject=None):
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   202
        """
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   203
        Starts Beremiz IDE, waits for main window to appear, maximize it.
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   204
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   205
            Parameters: 
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   206
                projectpath (str): path to project to open
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   207
                exemple (str): path relative to exemples directory
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   208
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   209
            Returns:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   210
                Sikuli App class instance
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   211
        """
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   212
        self.ocropts = sikuli.OCR.globalOptions()
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   213
        self.ocropts.dataPath(tessdata_path)
3842
3922024076b3 Tests: revert Teseract to less perforant legacy mode, but more repeatable. Compensate with zoom in edit_project and filter noise out of OCR text.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3839
diff changeset
   214
        
3922024076b3 Tests: revert Teseract to less perforant legacy mode, but more repeatable. Compensate with zoom in edit_project and filter noise out of OCR text.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3839
diff changeset
   215
        # 0 use legacy Tesseract (not so good, but repeatable)
3922024076b3 Tests: revert Teseract to less perforant legacy mode, but more repeatable. Compensate with zoom in edit_project and filter noise out of OCR text.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3839
diff changeset
   216
        # 1 use RNN Tesseract (better but non-repeatable)
3922024076b3 Tests: revert Teseract to less perforant legacy mode, but more repeatable. Compensate with zoom in edit_project and filter noise out of OCR text.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3839
diff changeset
   217
        # 2 use both
3922024076b3 Tests: revert Teseract to less perforant legacy mode, but more repeatable. Compensate with zoom in edit_project and filter noise out of OCR text.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3839
diff changeset
   218
        self.ocropts.oem(0)
3853
e1cfb03e6582 Tests: more OCR tuning
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3842
diff changeset
   219
        self.ocropts.psm(12)
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   220
        self.ocropts.smallFont()
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   221
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   222
        self.imgnum = 0
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   223
        self.starttime = timesec()
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   224
        self.screen = sikuli.Screen()
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   225
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   226
        self.report = open("report.xhtml", "w")
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   227
        self.report.write("""\
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   228
<html xmlns="http://www.w3.org/1999/xhtml">
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   229
  <head>
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   230
    <meta charset="utf-8"/>
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   231
    <meta name="color-scheme" content="light dark"/>
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   232
    <title>Test report</title>
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   233
  </head>
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   234
  <body>
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   235
""")
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   236
3839
a466d4468d7a Tests: use SID+KILL for sikuli subprocesses
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3729
diff changeset
   237
        command = ["setsid", python_bin, opj(beremiz_path,"Beremiz.py"), "--log=/dev/stdout"]
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   238
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   239
        if exemple is not None:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   240
            command.append(opj(beremiz_path,"exemples",exemple))
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   241
        elif projectpath is not None:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   242
            command.append(projectpath)
3669
ca25c686cd97 Tests: UI tests can now load projects from tests/projects
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3668
diff changeset
   243
        elif testproject is not None:
ca25c686cd97 Tests: UI tests can now load projects from tests/projects
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3668
diff changeset
   244
            command.append(opj(beremiz_path,"tests","projects",testproject))
ca25c686cd97 Tests: UI tests can now load projects from tests/projects
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3668
diff changeset
   245
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   246
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   247
        # App class is broken in Sikuli 2.0.5: can't start process with arguments.
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   248
        # 
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   249
        # Workaround : - use subprocess module to spawn IDE process,
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   250
        #              - use wmctrl to find IDE window details and maximize it
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   251
        #              - pass exact window title to App class constructor
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   252
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   253
        self.ReportText("Launching " + repr(command))
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   254
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   255
        self.proc = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=0)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   256
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   257
        # Window are macthed against process' PID
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   258
        ppid = self.proc.pid
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   259
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   260
        # Timeout 5s
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   261
        c = 50
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   262
        while c > 0:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   263
            # equiv to "wmctrl -l -p | grep $pid"
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   264
            try:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   265
                wlist = filter(lambda l:(len(l)>2 and l[2]==str(ppid)), map(lambda s:s.split(None,4), subprocess.check_output(["wmctrl", "-l", "-p"]).splitlines()))
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   266
            except subprocess.CalledProcessError:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   267
                wlist = []
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   268
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   269
            # window with no title only has 4 fields do describe it
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   270
            # beremiz splashcreen has no title
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   271
            # wait until main window is visible
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   272
            if len(wlist) == 1 and len(wlist[0]) == 5:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   273
                windowID,_zero,wpid,_XID,wtitle = wlist[0] 
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   274
                break
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   275
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   276
            sikuli.wait(0.1)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   277
            c = c - 1
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   278
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   279
        if c == 0:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   280
            raise Exception("Couldn't find Beremiz window")
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   281
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   282
        # Maximize window x and y
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   283
        subprocess.check_call(["wmctrl", "-i", "-r", windowID, "-b", "add,maximized_vert,maximized_horz"])
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   284
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   285
        # switchApp creates an App object by finding window by title, is not supposed to spawn a process
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   286
        self.sikuliapp = sikuli.switchApp(wtitle)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   287
        self.k = KBDShortcut(self)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   288
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   289
        IDEIdleObserver.__init__(self)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   290
        stdoutIdleObserver.__init__(self)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   291
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   292
        # stubs for common sikuli calls to allow adding hooks later
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   293
        for name, takes_matches in [
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   294
            ("click", True),
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   295
            ("doubleClick", True),
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   296
            ("type", False),
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   297
            ("rightClick", True),
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   298
            ("wait", False)]:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   299
            def makeMyMeth(n,m):
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   300
                def myMeth(*args, **kwargs):
3534
7f62da4362fd tests: nore details, please
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3528
diff changeset
   301
                    self.ReportScreenShot("Begin: " + n + "(" + repr(args) + "," + repr(kwargs) + ")")
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   302
                    if m:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   303
                        args = map(self.handle_PFRML_arg, args)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   304
                        kwargs = dict(map(lambda k,v:(k,self.handle_PFRML_arg(v)), kwargs.items()))
3544
f2dff88db448 tests: IDE: force reporting screenshot even after failing command
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3534
diff changeset
   305
                    try:
f2dff88db448 tests: IDE: force reporting screenshot even after failing command
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3534
diff changeset
   306
                        getattr(sikuli, n)(*args, **kwargs)
f2dff88db448 tests: IDE: force reporting screenshot even after failing command
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3534
diff changeset
   307
                    finally:
f2dff88db448 tests: IDE: force reporting screenshot even after failing command
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3534
diff changeset
   308
                        self.ReportScreenShot("end: " + n + "(" + repr(args) + "," + repr(kwargs) + ")")
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   309
                return myMeth
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   310
            setattr(self, name, makeMyMeth(name,takes_matches))
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   311
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   312
    def handle_PFRML_arg(self, arg):
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   313
        if type(arg)==list:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   314
            return self.findBest(*arg)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   315
        if type(arg)==str and not arg.endswith(".png"):
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   316
            return self.findBest(arg)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   317
        return arg
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   318
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   319
    def findBest(self, *args):
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   320
        #match = self.r.findBest(*args)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   321
        match = None 
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   322
        matches = sikuli.OCR.readWords(self.r) + sikuli.OCR.readLines(self.r)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   323
        for m in matches:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   324
            mText = m.getText().encode('ascii', 'ignore')
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   325
            for arg in args:
3842
3922024076b3 Tests: revert Teseract to less perforant legacy mode, but more repeatable. Compensate with zoom in edit_project and filter noise out of OCR text.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3839
diff changeset
   326
                if arg in mText or arg in mText.translate(None, "\"`'|-. "):
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   327
                    if match is None:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   328
                        match = m
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   329
                    if mText == arg:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   330
                        match = m
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   331
                        break
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   332
        if match is None:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   333
            self.ReportText("Not found: " + repr(args) + " OCR content: ")
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   334
            for m in matches:
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   335
                self.ReportText(repr(m) + ": " + m.getText().encode('ascii', 'ignore'))
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   336
            raise Exception("Not Found: " + repr(args))
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   337
        
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   338
        # translate match to screen ref
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   339
        #match.setTargetOffset(self.targetOffset)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   340
        match.setTopLeft(match.getTopLeft().offset(self.targetOffset))
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   341
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   342
        self.ReportTextImage("Found for " + repr(args) + ": " +
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   343
            " ".join([repr(match), repr(match.getTarget()), repr(match.getTargetOffset())]),
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   344
            self.screen.capture(match))
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   345
        return match.getTarget()
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   346
3671
973a7681f206 Tests: Add 'dragNdrop' for UI tests with slower begining than sikuli's dragDrop
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3670
diff changeset
   347
    def dragNdrop(self, src, dst):
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   348
        self.ReportScreenShot("Drag: (" + repr(src) + ")")
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   349
        sikuli.drag(self.handle_PFRML_arg(src))
3671
973a7681f206 Tests: Add 'dragNdrop' for UI tests with slower begining than sikuli's dragDrop
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3670
diff changeset
   350
        sikuli.mouseMove(5,0)
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   351
        sikuli.dropAt(self.handle_PFRML_arg(dst))
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   352
        self.ReportScreenShot("Drop: (" + repr(dst) + ")")
3671
973a7681f206 Tests: Add 'dragNdrop' for UI tests with slower begining than sikuli's dragDrop
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3670
diff changeset
   353
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   354
    def close(self):
3713
cf7c91183995 Tests: use expedited termination of IDE with SIGTERM instead of normal close
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3710
diff changeset
   355
cf7c91183995 Tests: use expedited termination of IDE with SIGTERM instead of normal close
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3710
diff changeset
   356
        self.ReportScreenShot("Close app")
3839
a466d4468d7a Tests: use SID+KILL for sikuli subprocesses
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3729
diff changeset
   357
        os.kill(self.proc.pid, signal.SIGKILL)
3713
cf7c91183995 Tests: use expedited termination of IDE with SIGTERM instead of normal close
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3710
diff changeset
   358
        #self.sikuliapp.close()
cf7c91183995 Tests: use expedited termination of IDE with SIGTERM instead of normal close
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3710
diff changeset
   359
        #self.sikuliapp = None
cf7c91183995 Tests: use expedited termination of IDE with SIGTERM instead of normal close
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3710
diff changeset
   360
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   361
        self.report.write("""
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   362
  </body>
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   363
</html>""")
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   364
        self.report.close()
3446
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   365
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   366
    def __del__(self):
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   367
        if self.sikuliapp is not None:
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   368
            self.sikuliapp.close()
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   369
        IDEIdleObserver.__del__(self)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   370
        stdoutIdleObserver.__del__(self)
de8cc85b688a Tests: refactored sikuli based test
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3437
diff changeset
   371
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   372
    def ReportScreenShot(self, msg):
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   373
        cap = self.screen.capture(self.r)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   374
        self.ReportTextImage(msg, cap)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   375
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   376
    def ReportTextImage(self, msg, img):
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   377
        elapsed = "%.3fs: "%(timesec() - self.starttime)
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   378
        fname = "capture"+str(self.imgnum)+".png"
3839
a466d4468d7a Tests: use SID+KILL for sikuli subprocesses
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3729
diff changeset
   379
        sys.stdout.write(elapsed + " [" + fname + "] " + msg + "\n")
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   380
        img.save(".", fname)
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   381
        self.imgnum = self.imgnum + 1
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   382
        self.report.write( "<p>" + escape(elapsed + msg) + "<br/><img src=\""+ fname + "\"/>" + "</p>")
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   383
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   384
    def ReportText(self, text):
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   385
        elapsed = "%.3fs: "%(timesec() - self.starttime)
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   386
        #res = u"<p><![CDATA[" + elapsed + text + "]]></p>"
3839
a466d4468d7a Tests: use SID+KILL for sikuli subprocesses
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3729
diff changeset
   387
        sys.stdout.write(elapsed + text + "\n")
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   388
        res = u"<p>" + escape(elapsed + text) + "</p>"
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   389
        self.report.write(res)
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   390
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   391
    def ReportOutput(self, text):
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   392
        elapsed = "%.3fs: "%(timesec() - self.starttime)
3675
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   393
        sys.stdout.write(elapsed + text)
3710
51c2d434e10e tests: IDE: own text matching logic for OCR reliability, enhanced ihtml report
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3696
diff changeset
   394
        self.report.write("<pre>" + escape(elapsed + text) + "</pre>")
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   395
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   396
3675
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   397
class AuxiliaryProcess(stdoutIdleObserver):
3668
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   398
    def __init__(self, beremiz_app, command):
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   399
        self.app = beremiz_app
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   400
        self.app.ReportText("Launching process " + repr(command))
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   401
        self.proc = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=0)
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   402
        self.app.ReportText("Launched process " + repr(command) + " PID: " + str(self.proc.pid))
3675
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   403
        stdoutIdleObserver.__init__(self)
3668
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   404
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   405
    def close(self):
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   406
        if self.proc is not None:
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   407
            proc = self.proc
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   408
            self.proc = None
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   409
            # self.proc.stdout.close()
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   410
            self.app.ReportText("Kill process PID: " + str(proc.pid))
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   411
            try:
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   412
                os.kill(proc.pid, signal.SIGTERM)
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   413
            except OSError:
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   414
                pass
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   415
            proc.wait()
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   416
            # self.thread.join()
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   417
3675
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   418
    def ReportOutput(self, text):
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   419
        self.app.ReportOutput("Aux: "+text)
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   420
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   421
    def ReportScreenShot(self, msg):
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   422
        self.app.ReportOutput("Aux: "+msg)
d331eb981b44 Tests: IDE: add stdout monitoring capabilities to auxiliary process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3671
diff changeset
   423
3668
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   424
    def __del__(self):
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   425
        self.close()
142c268124ab Tests: add command for UI tests to launch and close Auxiliary Process
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3562
diff changeset
   426
3447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   427
def run_test(func, *args, **kwargs):
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   428
    app = BeremizApp(*args, **kwargs)
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   429
    try:
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   430
        success = func(app)
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   431
    except:
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   432
        # sadly, sys.excepthook is broken in sikuli/jython 
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   433
        # purpose of this run_test function is to work around it.
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   434
        # and catch exception cleanly anyhow
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   435
        e_type, e_value, e_traceback = sys.exc_info()
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   436
        err_msg = "\n".join(traceback.format_exception(e_type, e_value, e_traceback))
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   437
        app.ReportOutput(err_msg)
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   438
        success = False
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   439
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   440
    app.close()
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   441
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   442
    if success:
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   443
        sikuli.exit(0)
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   444
    else:
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   445
        sikuli.exit(1)
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   446
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   447
65c5f66e9298 Tests: add HTML report generation and a workaround to bad exception handling in sikuli.
Edouard Tisserant <edouard.tisserant@gmail.com>
parents: 3446
diff changeset
   448