1
#############################################################################
3
# Linux Desktop Testing Project http://ldtp.freedesktop.org
6
# M Nagashree <mnagashree@novell.com>
7
# Veerapuram Varadhan <v.varadhan@gmail.com>
8
# Nagappan Alagappan <nagappan@gmail.com>
10
# Copyright 2004 - 2006 Novell, Inc.
11
# Copyright 2007 - 2009 Nagappan Alagappan
13
# This library is free software; you can redistribute it and/or
14
# modify it under the terms of the GNU Library General Public
15
# License as published by the Free Software Foundation; either
16
# version 2 of the License, or (at your option) any later version.
18
# This library is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
# Library General Public License for more details.
23
# You should have received a copy of the GNU Library General Public
24
# License along with this library; if not, write to the
25
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26
# Boston, MA 02110, USA.
28
#############################################################################
42
import xml.dom.minidom
44
# Let us not register our application under at-spi application list
45
os.environ ['GTK_MODULES'] = ''
49
_ldtpDebug = os.getenv('LDTP_DEBUG')
55
statGrabMsg = 'pystatgrab package not installed'
57
def tuplelist2list(lst):
59
for x in range(1, len(lst) + 1):
60
for y in range(1, len(lst[x-1]) + 1):
61
d.append(lst[x-1][y-1])
64
def getFullPath(path):
66
path = os.path.expanduser(path)
68
path = os.path.abspath(path)
72
def imagecompare(imgfile1, imgfile2):
74
import ImageChops, Image
76
ldtp.log('Python-Imaging package not installed', 'error')
77
raise ldtp.LdtpExecutionError('Python-Imaging package not installed')
80
im1 = Image.open(imgfile1)
81
im2 = Image.open(imgfile2)
83
imgcompdiff = ImageChops.difference(im1, im2)
84
diffboundrect = imgcompdiff.getbbox()
85
imgdiffcrop = imgcompdiff.crop(diffboundrect)
87
seq = list(imgdiffcrop.getdata())
88
seq = tuplelist2list(seq)
90
for i in range(0, imgdiffcrop.size[0] * imgdiffcrop.size[1] * 3, 3):
91
if seq[i] != 0 or seq[i+1] != 0 or seq[i+2] != 0:
92
diffcount = diffcount + 1.0
94
diffImgLen = imgcompdiff.size[0] * imgcompdiff.size[1] * 1.0
95
diffpercent = (diffcount * 100) / diffImgLen
96
ldtp.log('length ' + str(diffImgLen))
97
ldtp.log('diffcount ' + str(diffcount))
98
ldtp.log('diff percent ' + str(diffpercent))
101
ldtp.log('Input file does not exist', 'error')
102
raise ldtp.LdtpExecutionError('Input file does not exist')
104
def imagecapture(winName = None, outFile = None, width = None,
105
height = None, x = 0, y = 0):
106
# winname == None, let us capture the entire screen
107
# if output file name is not passed, then a random file name will be generated in
108
# /tmp and it will be returned
114
gobject.threads_init()
118
print 'pygtk package not installed'
126
print 'wnck python package not installed'
133
def getWinId(self, winName):
135
ldtp.log('wnck package not installed, screen capture ' \
136
'disabled based on window name',
140
screen = wnck.screen_get_default()
142
for window in screen.get_windows():
143
if re.search(winName, window.get_name()):
144
winid = window.get_xid()
145
# Activate the window
146
# http://faq.pygtk.org/index.py?req=show&file=faq10.027.htp
147
window.activate(gtk.get_current_event_time())
151
def generateTmpFile(self):
153
fp = tempfile.NamedTemporaryFile()
154
self.tmpFile = fp.name + '.png'
157
self.tmpFile = outFile
159
def capturescreenshot(self):
165
winid = self.getWinId(winName)
172
# Based on http://ubuntuforums.org/showthread.php?t=448160
173
window = gtk.gdk.get_default_root_window()
174
size = window.get_size()
175
pb = gtk.gdk.Pixbuf(gtk.gdk.COLORSPACE_RGB, False, 8,
178
pb = pb.get_from_drawable(window, window.get_colormap(),
182
self.generateTmpFile()
184
pb.save(self.tmpFile, "png")
185
# based on http://faq.pygtk.org/index.py?req=show&file=faq08.004.htp
191
cmd = "import -window %s" % winid
193
cmd = "%s -crop %dx%d+%d+%d" % (cmd, width,
195
cmd = "%s %s" % (cmd, self.tmpFile)
196
status = commands.getstatusoutput(cmd)
198
ldtp.log('Unable to capture screenshot: %s' % status [1], 'error')
203
screenshot = ImageCapture()
205
gobject.idle_add(screenshot.capturescreenshot)
206
#gobject.idle_add(gtk.main_quit)
208
return screenshot.tmpFile
210
def _wnckFunction(wnckFunctionName, windowName = None):
215
gobject.threads_init()
219
print 'pygtk package not installed'
228
print 'wnck python package not installed'
232
def __init__(self, windowName = None):
234
self.windowName = windowName
236
def _operateOnWindow(self, wnckFunctionName):
237
screen = wnck.screen_get_default()
238
windowList = screen.get_windows()
245
_currentWindow = w.get_name()
246
if re.search(fnmatch.translate(windowName), _currentWindow, re.I) or \
247
re.search(fnmatch.translate(windowName),
248
re.sub(" *\t*\n*", "", _currentWindow), re.I):
249
if wnckFunctionName not in dir(w):
251
function = getattr(w, wnckFunctionName)
252
if wnckFunctionName == 'activate':
258
if wnckFunctionName not in dir(w):
260
function = getattr(w, wnckFunctionName)
264
_wnckInst = _wnckInternal(windowName)
265
gobject.idle_add(_wnckInst._operateOnWindow, wnckFunctionName)
266
#gobject.idle_add(gtk.main_quit)
269
def activatewindow(windowName = None):
270
_wnckFunction('activate', windowName)
272
def minimizewindow(windowName = None):
273
_wnckFunction('minimize', windowName)
275
def maximizewindow(windowName = None):
276
_wnckFunction('maximize', windowName)
278
def closewindow(windowName):
279
_wnckFunction('close', windowName)
281
def blackoutregion(infile, outfile, topx, topy, botx, boty):
283
import ImageChops, Image
285
ldtp.log('Python-Imaging package not installed', 'error')
286
raise ldtp.LdtpExecutionError('Python-Imaging package not installed')
287
im = Image.open(infile)
288
box = (topx, topy, botx, boty)
289
region = im.crop(box)
290
region = region.point(lambda i: i * 0)
291
im.paste(region, box)
294
# XML Data file parser
295
class LdtpDataFileParser:
296
def __init__(self, filename = None):
297
self.ldtpdataxml = []
300
dom = xml.dom.minidom.parse(filename)
301
self.ldtpdataxml = dom.getElementsByTagName("data")
302
if self.ldtpdataxml == []:
303
ldtp.log('data xml tag not present')
304
if _ldtpDebug and _ldtpDebug == '2':
305
print 'data xml tag not present'
306
except xml.parsers.expat.ExpatError, msg:
307
ldtp.log('XML Error: ' + str(msg), 'error')
309
ldtp.log('XML \"' + filename + '\" file not found', 'error')
310
def setfilename(self, filename):
311
self.ldtpdataxml = []
314
dom = xml.dom.minidom.parse(filename)
315
self.ldtpdataxml = dom.getElementsByTagName("data")
316
if self.ldtpdataxml == []:
317
ldtp.log('data xml tag not present')
318
if _ldtpDebug and _ldtpDebug == '2':
319
print 'data xml tag not present'
320
except xml.parsers.expat.ExpatError, msg:
321
if _ldtpDebug and _ldtpDebug == '2':
322
print 'XML Error: ' + str(msg)
323
ldtp.log('XML Error: ' + str(msg), 'error')
325
if _ldtpDebug and _ldtpDebug == '2':
326
print 'XML \"' + filename + '\" file not found'
327
ldtp.log('XML \"' + filename + '\" file not found', 'error')
328
def getText(self, nodelist):
330
for node in nodelist:
331
if node.nodeType == node.TEXT_NODE:
334
def gettagvalue(self, tagname):
336
if self.ldtpdataxml == []:
338
for dataelements in self.ldtpdataxml:
339
for data in dataelements.getElementsByTagName(tagname):
340
self.taglist.append(self.getText(data.childNodes))
343
class pstats(threading.Thread):
344
"""Capturing Memory and CPU Utilization statistics for an application and its related processes
346
xstats = pstats('evolution', 2)
347
# Start Logging by calling start
349
# Stop the process statistics gathering thread by calling the stopstats method
352
def __init__(self, appname, inter = 2):
353
if statGrabMsg is not None:
354
ldtp.log(statGrabMsg, 'error')
355
raise ldtp.LdtpExecutionError(statGrabMsg)
356
threading.Thread.__init__(self)
357
self.processname = appname
358
self.interval = inter
361
while self.stop_flag == 0:
362
for i in statgrab.sg_get_process_stats():
363
if self.stop_flag == 1:
365
result = re.search(self.processname, str(i['process_name']))
367
title = str(i['proctitle'])
368
proctitle = re.split("\s", title)
369
procname = re.split("\/", proctitle[0])
370
# Put the stats into ldtp log file
371
ldtp.log(procname[-1] + ' - ' + str(i['proc_resident'] / (1024*1024)) + 'M',
373
ldtp.log(procname[-1] + ' - ' + str(round(i['cpu_percent'], 2)),
375
# Wait for interval seconds before gathering stats again
376
time.sleep(self.interval)
381
############# Application Functions #################
384
status = commands.getstatusoutput(cmd)
386
ldtp.log(status[1], 'error')
387
raise ldtp.LdtpExecutionError(status[1])
390
########### LTFX Functions ###############
392
#Get currently active window title name
393
cmd = "ltfx -e 'get_active_win'"
394
status = commands.getstatusoutput(cmd)
396
ldtp.log(status[1], 'error')
397
raise ldtp.LdtpExecutionError(status[1])
400
def windowexists(window_name):
401
#Check window name exists with the given name
402
cmd = "ltfx -e \'win_exists \"" + window_name + "\"\'"
405
def partialexists(window_name):
406
#Check window name exists with the given partial name
407
cmd = "ltfx -e \'win_exists_partial \"" + window_name + "\"\'"
410
def activatewinpartialname(window_name):
411
# Set active window based on the given partial name"
412
cmd = "ltfx -e \'activate_win_partial \"" + window_name + "\"\'"
415
def activatewin(window_name):
416
#Set active window based on the given name
417
cmd = "ltfx -e \'activate_win \"" + window_name + "\"\'"
420
def activatewinid(window_id):
421
#Set active window based on the given window-id
422
cmd = "ltfx -e \'activate_win_id \"" + window_id + "\"\'"
425
def closewindow(window_name):
426
#Close the window with the given title
429
def waitwinname(window_name):
430
#Wait for window with name to appear
431
cmd = "ltfx -e 'wait_for_win \"" + window_name + "\"\'"
434
def waitwinpartialname(window_name):
435
#Wait for window with partial name to appear
436
cmd = "ltfx -e 'wait_for_win_partial \"" + window_name + "\"\'"
439
def waitwinclose(window_name):
440
#Wait for window to close with the given name
441
cmd = "ltfx -e 'wait_for_close \"" + window_name + "\"\'"
444
def waitwinpartialclose(window_name):
445
#Wait for window to close with the given partial name
446
cmd = "ltfx -e 'wait_for_close_partial \"" + window_name + "\"\'"
449
def typekey(window_name):
450
#Type the given text in the focused window
451
cmd = "ltfx -e 'type \"" + window_name + "\"\'"