"Commons definitions for sikuli based beremiz IDE GUI tests"
from threading import Thread, Event
home = os.environ["HOME"]
beremiz_path = os.environ["BEREMIZPATH"]
def StartBeremizApp(projectpath=None, exemple=None):
Starts Beremiz IDE, waits for main window to appear, maximize it.
projectpath (str): path to project to open
exemple (str): path relative to exemples directory
Sikuli App class instance
command = ["%s/beremizenv/bin/python"%home, opj(beremiz_path,"Beremiz.py"), "--log=/dev/stdout"]
command.append(opj(beremiz_path,"exemples",exemple))
elif projectpath is not None:
command.append(projectpath)
# App class is broken in Sikuli 2.0.5: can't start process with arguments.
# Workaround : - use subprocess module to spawn IDE process,
# - use wmctrl to find IDE window details and maximize it
# - pass exact window title to App class constructor
proc = subprocess.Popen(command, stdout=subprocess.PIPE, bufsize=0)
# Window are macthed against process' PID
# equiv to "wmctrl -l -p | grep $pid"
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()))
except subprocess.CalledProcessError:
# window with no title only has 4 fields do describe it
# beremiz splashcreen has no title
# we wity until main window is visible
if len(wlist) == 1 and len(wlist[0]) == 5:
windowID,_zero,wpid,_XID,wtitle = wlist[0]
raise Exception("Couldn't find Beremiz window")
# Maximize window x and y
subprocess.check_call(["wmctrl", "-i", "-r", windowID, "-b", "add,maximized_vert,maximized_horz"])
# switchApp creates an App object by finding window by title, is not supposed to spawn a process
return proc, switchApp(wtitle)
"""Send shortut to app by calling corresponding methods:
def __getattr__(self, name):
"Detects when IDE is idle. This is particularly handy when staring an operation and witing for the en of it."
app (class App): Sikuli app given by StartBeremizApp
self.r = Region(app.window())
# 200 was selected because default 50 was still catching cursor blinking in console
# FIXME : remove blinking cursor in console
self.r.onChange(200,self._OnIDEWindowChange)
self.r.observeInBackground()
def _OnIDEWindowChange(self, event):
def Wait(self, period, timeout):
Wait for IDE to stop changing
period (int): how many seconds with no change to consider idle
timeout (int): how long to wait for idle, in seconds
raise Exception("Window did not idle before timeout")
class stdoutIdleObserver:
"Detects when IDE's stdout is idle. Can be more reliable than pixel based version (false changes ?)"
def __init__(self, proc):
proc (subprocess.Popen): Beremiz process, given by StartBeremizApp
self.stdoutchanged = False
self.thread = Thread(target = self._waitStdoutProc).start()
a = self.proc.stdout.read(1)
if len(a) == 0 or a is None:
def Wait(self, period, timeout):
Wait for IDE'stdout to stop changing
period (int): how many seconds with no change to consider idle
timeout (int): how long to wait for idle, in seconds
raise Exception("Stdout did not idle before timeout")
def waitPatternInStdout(proc, pattern, timeout, count=1):
def waitPatternInStdoutProc():
a = proc.stdout.readline()
if len(a) == 0 or a is None:
raise Exception("App finished before producing expected stdout pattern")
Thread(target = waitPatternInStdoutProc).start()
if not success_event.wait(timeout):