#!/usr/bin/env python
#############################################################################
#
#
# The Author of this File is:
# Prashanth Mohan <prashmohan@gmail.com>
#
# The Modifiers of this File are:
# Venkateswaran S <wenkat.s@gmail.com>
# Nagappan <nagappan@gmail.com>
#
# For more information on the Linux Desktop Testing Project (LDTP) visit
# http://ldtp.freedesktop.org
#
#############################################################################
import socket, os, types, sys, string, re
from xml.dom.minidom import *
class LdtpExecutionError (Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
class ConnectionLost (Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
try:
client = socket.socket (socket.AF_UNIX, socket.SOCK_STREAM)
except socket.error,msg:
print "ERROR WHILE CREATING SOCKET",msg
raise LdtpExecutionError
socketpath = os.environ.get ("LDTP_AUTH_SOCK")
if socketpath == '':
print "Serever Not Running"
raise ConnectionLost (0)
try:
client.connect (socketpath)
except socket.error,msg:
print "COULD NOT ESTABLISH CONNECTION",msg
raise ConnectionLost (0)
def socksend (sendmsg):
"""This Function will send a LDTP packet to the server
INPUT: sendmsg --> LDTP Packet in string format
OUTPUT: returns the Error Code/appropriate value as string"""
try:
client.send (sendmsg)
xmlcontent = ''
data = client.recv (4)
print data
while True:
data = client.recv (512)
print data
xmlcontent += data
# FXIME: Read based on size
if string.find (data, '</xml>') != -1:
break
data = unparse (xmlcontent)
except socket.error, msg:
print "ERROR WHILE SENDING/RECEIVING PACKET " + str (msg)
raise ConnectionLost (0)
return data
def unparse (xml):
"""Returns the value obtained from the server's return LDTP packet"""
try:
length=int (xml[:xml.find('\n')])
xml=xml[xml.find('\n')+1:] #removes the length
if length != len (xml)+1: # +1 for the removed starting '\n'
#enter code here for request for resending xml
pass
try:
dom = parseString(xml)
response = dom.getElementsByTagName ('response')[0]
status = response.getElementsByTageName ('status')[0]
data = response.getElementsByTagName ('data')[0]
code = int(status.getAttribute ('code'))
msg = status.getAttribute ('msg')
length_of_data = int(data.getAttribute ('length'))
ret_msg = data.getAttribute ('value')
if length_of_data != len (ret_msg):
#again code for msg rereuest
pass
except:
log ('Internal Error during Server-Client communication','cause')
raise LdtpExecutionError (0)
if isError(code):
errmsg = 'Error Code No: '+str(codeno)
errmsg += '\n' + msg
log (errmsg,'cause')
raise LdtpExecutionError (0)
except:
#log ('Unable to get information from Server\'s code packet','cause')
raise LdtpExecutionError (0)
return ret_msg
def isError(codeno):
"""Determines whether the obtained codeno is an error or not"""
#code here for checking error code
pass
def parsexml (name,*args):
"""This Function will parse some information into an LDTP packet
INPUT: name --> function_name
args --> [,window_name[,object_name[,args...]]]
OUTPUT: returns a string in the LDTP packet (XML lib2) format"""
try:
line='<?xml version=\"2.0\"?>' ## should this header be there in the packets?
line+='<request>'
line=line+'\n<action name=\"'+name+'\"/>'
if len(args)>=1:
window=args[0]
line=line+'\n<window name=\"'+window+'\"/>'
if len(args)>=2:
object=args[1]
line=line+'\n<object value=\"'+object+'\"/>'
if len(args)>=3:
for index in range (2,len(args)):
arg=args[index]
line=line+'\n<arg value=\"'+arg+'\"/>'
line+='</request>'
line+='</xml>'
except:
print "ERROR WHILE PARSING XML STRING"
return 'ERROR' #replace with exception
line=str (len (line))+line
return line
# Calendar View Functions
def selectevent (windowname, Calendar_view_name, calendar_event_name):
"""Selects the row from the table of calendar events based on the calendar event name specified
INPUT: selectevent ('<window name>', '<Calendar_view name>', '<calendar event name>')
OUTPUT: Returns 1 on success and 0 on error."""
if not (type (windowname) == type (Calendar_view_name) == type (calendar_event_name) == types.StringType):
raise SyntaxError
xml=parsexml('selectevent',windowname,Calendar_view_name,calendar_event_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def selecteventindex (windowname, component_name, event_number):
"""Select an event from a calendar table using its index. Index for a calendar event starts from 1.
INPUT: selecteventindex ('<window name>', '<component name>', <event number>)
OUTPUT: Returns 1 on success and 0 on error."""
if not ((type (windowname) == type (component_name) == types.StringType) and (type (event_number) == types.IntType)):
raise SyntaxError
xml=parsexml('selecteventindex',windowname, component_name, event_number)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def verifyeventexist (windowname, component_name):
"""verifies whether any events are present in a calendar table
INPUT: verifyeventexist ('<window name>', '<component name>')
OUTPUT: Returns 1 on success and 0 on no events."""
if not (type (windowname) == type (component_name) == types.StringType):
raise SyntaxError
xml=parsexml('verifyeventexist',windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
# Checkbox Functions
def check (windowname, component_name):
"""Check (tick) the check box state.
INPUT: check ('<window name>', '<component name>')
OUTPUT: Returns 1 if state is checked, else 0."""
if not (type (windowname) == type (component_name) == types.StringType):
raise SyntaxError
xml=parsexml('check',windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def uncheck (windowname, component_name):
"""Uncheck (un-tick) the check state.
INPUT: uncheck ('<window name>', '<component name>')
OUTPUT: Returns 1 if state is unchecked, else 0."""
if not (type (windowname) == type (component_name) == types.StringType):
raise SyntaxError
xml=parsexml('uncheck',windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def click (windowname, component_name):
"""click on radio button / check box / push button/ combo box/ radio menu item/ toggle button/ radio button.
INPUT: click ('<window name>', '<component name>')
OUTPUT: Clicks the component_name."""
if not (type (windowname) == type (component_name) == types.StringType):
raise SyntaxError
xml=parsexml('click',windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def verifycheck (windowname, component_name):
"""Checks the state of check box.
INPUT: verifycheck ('<window name>', '<component name>')
OUTPUT: If check box state is checked, then returns 1, else 0."""
if not (type (windowname) == type (component_name) == types.StringType):
raise SyntaxError
xml=parsexml('verifycheck',windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def verifyuncheck (windowname, component_name):
"""Checks the state of check box.
INPUT: verifyuncheck ('<window name>', '<component name>')
OUTPUT: If check box state is un-checked, then returns 1, else 0."""
if not (type (windowname) == type (component_name) == types.StringType):
raise SyntaxError
xml=parsexml('verifyuncheck',windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
# CheckMenuItem Functions
def selectmenuitem (windowname, menu_hierarchy):
"""Selects the menu item specified.
INPUT: selectmenuitem ('<window name>', '<menu hierarchy>')
OUTPUT: TODO."""
if not (type (windowname) == type (menu_hierarchy) == types.StringType):
raise SyntaxError
xml=parsexml('selectmenuitem',windowname, menu_hierarchy)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
#TODO
#def verifymenucheck (windowname, menu_hierarchy):
# """
# INPUT:
#
# OUTPUT: """
# if not (type (windowname) == type (menu_hierarchy) == types.StringType):
# raise SyntaxError
#
# xml=parsexml('verifymenucheck',windowname, menu_hierarchy)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
# Combobox Functions
#TODO
#def capturetofile ():
# """
# INPUT:
#
# OUTPUT: """
# if not (type () == type () == types.StringType):
# raise SyntaxError
#
# xml=parsexml('capturetofile',,)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
def hidelist (dlgName, cmbName):
""" Hides combo box drop down list in the current dialog.
Suppose in previous operation one testcase has clicked on combo box,
its drop down list will be displayed. If further no any operation has
been done on that combo box then to close that drop down list 'HideList'
action is required.
INPUT: hidelist ('dlgName', 'cmbName')
OUTPUT: TODO"""
if not (type (dlgName) == type (cmbName) == types.StringType):
raise SyntaxError
xml=parsexml('hidelist',dlgName,cmbName)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def select (dlgName, cmbName, Select_argument):
""" Select action will select an value given in argument from the combo box.
INPUT: select ('dlgName', 'cmbName', '<Select argument>')
OUTPUT: TODO"""
# Verify Types.
# if not (type (dlgName) == type (cmbName) == type(Select_argument) == types.StringType):
# raise SyntaxError
xml=parsexml('select',dlgName,cmbName,Select_argument)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def selectindex (dlgName, cmbName, index):
""" SelectIndex action will select an item from combo box where value of index is pointing to its position in list/menu.
INPUT: selectindex ('dlgName', 'cmbName', <index>)
OUTPUT: TODO"""
# Verify Types.
# if not (type (dlgName) == type (cmbName) == type(index) == types.StringType):
# raise SyntaxError
xml=parsexml('selectindex', dlgname, cmbName, index)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
#TODO
#def selectpartialmatch ():
# """
# INPUT:
#
# OUTPUT: """
# if not (type () == type () == types.StringType):
# raise SyntaxError
#
# xml=parsexml('selectpartialmatch',,)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
def settextvalue (windowname,component_name,text):
"""puts the text into the component given by the component name
INPUT: settextvalue ('<window name>', '<component name>', '<text>')
OUTPUT: returns 1 on success and 0 otherwise"""
if not (type (windowname) == type (component_name) == type (text) == types.StringType):
raise SyntaxError
xml=parsexml('settextvalue',windowname,component_name,text)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def showlist (dlgName, cmbName):
""" Displays combo box drop down list in the current dialog.
INPUT: showlist ('dlgName', 'cmbName')
OUTPUT: TODO"""
# Verify Types.
# if not (type (dlgName) == type (cmbName) == types.StringType):
# raise SyntaxError
xml=parsexml('showlist', windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
#TODO
#def verifiydropdown ():
# """
# INPUT:
#
# OUTPUT: """
# if not (type () == type () == types.StringType):
# raise SyntaxError
#
# xml=parsexml('verifydropdown',,)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
def verfyhidelist (dlgName, cmbName):
""" Verifies if combo box drop down list in the current dialog is not visible.
INPUT: verfyhidelist ('dlgName', 'cmbName')
OUTPUT: TODO"""
if not (type (dlgname) == type (cmbName) == types.StringType):
raise SyntaxError
xml=parsexml('verifyhidelist', windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def verifyselect (dlgName, cmbName, argument):
""" VerfySelect action will verify if combo box is set to value given in argument.
INPUT: verifyselect ('dlgName', 'cmbName', '<argument>')
OUTPUT: VerifySelect function will try to find if text box associated with combo box
is set to value specified in the argument."""
# Verify Types.
# if not (type (dlgName) == type (cmbName) == type(argument) == types.StringType):
# raise SyntaxError
xml=parsexml('verifyselect', windowname, component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def verifysettext (windowname, component_name, text):
""" checks if the text is inserted into the component given by the component name
INPUT: verifysettext ('<window name>', '<component name>', '<text>')
OUTPUT: returns 1 if the text is inserted into the specified component else returns 0 """
if not (type (windowname) == type (component_name) == type(text) == types.StringType):
raise SyntaxError
xml=parsexml('verifysettext',windowname,component_name,text)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def verifyshowlist (dlgName, cmbName):
""" Verifies if combo box drop down list in the current dialog is visible.
INPUT: verifyshowlist ('dlgName', 'cmbName')
OUTPUT: Combo box will generally have a list as its child or a menu as its child.
So this function gets object handle of list or menu object, checks if list or
menu items of combo box is visible, if yes then return zero else minus one."""
# Verify Types.
# if not (type (dlgName) == type (cmbName) == types.StringType):
# raise SyntaxError
xml=parsexml('verifyshowlist',dlgName,cmbName)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def comboselect (windowname, component_name, menu_item_name):
""" Select a menu item or list item in a combo box
INPUT: comboselect ('<window name>', '<component name>', '<menu item name>')
OUTPUT: """
if not (type (windowname) == type (component_name) == type(menu_iten_name) == types.StringType):
raise SyntaxError
xml=parsexml('comboselect',windowname,component_name,menu_item_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
# ComboEditBox Functions
# TODO
# ComboListBox Functions
# TODO
# General Functions
def waittillguiexist (windowname):
""" If the given window name exist, this function returns 1. If window doesnot exist,
then this function returns 0. Difference between guiexist and waitguiexist is,
waitguiexist waits for maximum 30 seconds. Still the window doesn't appear,
then 0 is returned. We can set the environment variable 'GUI_TIMEOUT' to change
the default waiting time.
INPUT: waittillguiexist ('<window name>')
OUTPUT: returns 1 on success and 0 on no existing window """
if not (type (windowname) == types.StringType):
raise SyntaxError
xml=parsexml('waittillguiexist',windowname)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def waittillguinotexist (windowname):
""" If the given window name does not exist, this function returns 1. If window exist,
then this function returns 0. Difference between guiexist and waitguinotexist is,
waitguinotexist waits for maximum 30 seconds. Still the window does not disappear,
then 0 is returned. We can set the environment variable 'GUI_TIMEOUT' to change the
default waiting time.
INPUT: waittillguinotexist ('<window name>')
OUTPUT: returns 1 on success and 0 on no existing window """
if not (type (windowname) == types.StringType):
raise SyntaxError
xml=parsexml('waittillguinotexist',windowname)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def guiexist (windowname):
""" If the given window name exist, this function returns 1. If window doesnot exist,
then this function returns 0.
INPUT: guiexist ('<window name>')
OUTPUT: returns 1 on success and 0 on no existing window """
if not (type (windowname) == types.StringType):
raise SyntaxError
xml=parsexml('guiexist',windowname)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def initappmap (application_map_name):
""" Application map will be loaded
INPUT: initappmap ('<application map name>')
OUTPUT: TODO"""
if not (type (appilication_map_name) == types.StringType):
raise SyntaxError
xml=parsexml('initappmap',appilication_map_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def setappmap (new_application_map_name):
""" A new application map will be loaded. Existing appmap will be unloaded.
INPUT: setappmap ('<new application map name>')
OUTPUT: TODO """
if not (type (new_appilication_map_name) == types.StringType):
raise SyntaxError
xml=parsexml('setappmap',new_appilication_map_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
# TODO
#def reinitldtp():
# """
# INPUT:
#
# OUTPUT: """
# if not (type () == type () == types.StringType):
# raise SyntaxError
#
# xml=parsexml('reinitldtp',,)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
def LdtpDataFileParser (XML_Filename):
""" XML parser to parse data files.
INPUT: LdtpDataFileParser ('[XML Filename]')
OUTPUT: LdtpDataFileParser class takes Data XML filename as an optional argument.
This class also provides 2 functions.
1. setfilename ('[XML Filename]'). If the class does not takes an argument,
then this function should be used
2. gettagvalue ('tag name'). Get the value of the given tag. """
if not (type (XML_Filename) == types.StringType):
raise SyntaxError
xml=parsexml('LdtpDataFileParser',XML_Filename)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def doubleclick (dlgName, component_name):
""" Performs 'double click' mouse event on the given componenet.
INPUT: doubleclick ('dlgName', 'component name')
OUTPUT: It calculates the given object's boundary and fires a mouse event at the
center of the obtained boundary """
# Verify Types.
# if not (type (dlgName) == type (component_name) == types.StringType):
# raise SyntaxError
xml=parsexml('doubleclick',dlgName,component_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def remap (applicationname, dialog_name):
""" We can handle dynamically created widgets (meaning widgets created at run time) using
this remap function. Calling remap will generate appmap for the given dialog at run
time and update the hash table. Then we can access the new widgets. But please make
sure to call undoremap() once the required functions are performed so that the hash
table will be reverted back to its original state. The reason for having undoremap()
is that subsequent calls to remap() might corrupt the hash table containg the appmap
entries.
Please not that the <application-name> should be same as the one given as the commmand-line
argument for appmap generation.
INPUT: remap ('<application-name>', '<dialog name>')
OUTPUT: It uses the same logic that appmap module uses to generate appmap."""
if not (type (appilicationname) == type (dialog_name) == types.StringType):
raise SyntaxError
xml=parsexml('remap',appilcationname,dialog_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
# Imaging Functions
def imagecapture (windowname, output_file, *args):
#(opt)resolution_x, (opt)resolution_y, (opt)startx, (opt)starty):
""" Capture snap-shot of the window. Where startx & starty are offset
INPUT: imagecapture (<window name>, <output file>, (opt)<resolution-x>, (opt)<resolution-y>, (opt)startx, (opt)starty):
OUTPUT: TODO """
# This has optional arguments.
if not (type (windowname) == type (output_file) == types.StringType):
raise SyntaxError
xml=parsexml('imagecapture',windowname,output_file,args)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def imagecompare (imgfile1, imgfile2):
""" Compares two images and returns difference of them in percentage
INPUT: imagecompare (imgfile1, imgfile2)
OUTPUT: TODO """
if not (type (imgfile1) == type (imgfile2) == types.StringType):
raise SyntaxError
xml=parsexml('imagecompare',imgfile1,imgfile2)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def blackoutregion (infile,outfile,topx,topy,botx,boty):
""" Blacks out the region in the image given by top-coords - topx,topy bottom-coords - botx,boty
of the region
INPUT: blackoutregion (infile,outfile,topx,topy,botx,boty)
OUTPUT: TODO """
if not ((type (infile) == type (outfile) == types.StringType) and (type(topx) == type(topy) == type(botx) == type(boty) == types.IntType)):
raise SyntaxError
xml=parsexml('blackoutregion',infile,outfile,topx,topy,botx,boty)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
# Label Functions
#TODO
#def getlabel ():
# """
# INPUT:
#
# OUTPUT: """
# if not (type () == type () == types.StringType):
# raise SyntaxError
#
# xml=parsexml('getlabel',,)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
# LayeredPane Functions
#TODO
#def selectitem ():
# """
# INPUT:
#
# OUTPUT: """
# if not (type () == type () == types.StringType):
# raise SyntaxError
#
# xml=parsexml('selectitem',,)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
#TODO
#def rightclick ():
# """
# INPUT:
#
# OUTPUT: """
# if not (type () == type () == types.StringType):
# raise SyntaxError
#
# xml=parsexml('rightclick',,)
#
# try:
# data=socksend(xml)
# except ConnectionLost:
# raise ConnectionLost (0)
#
# return data
# Log Function
def startlog (log_file_name, bool_value):
""" Start logging on the specified file. second arugment is optional and 0 is default value
0 - Append log to an existing file
1 - Write log to a new file. If file already exist,
then erase existing file content and start log
INPUT: startlog ('<log file name>', [0 or 1])
OUTPUT: Log file will be created if log file is not present in any case. If second argument is 1,
then existing file content will be erased. If second argument is 0, then new logs will be
append to existing log.
It returns 1 on Success and 0 on error """
if not (type (log_file_name) == types.StringType and type (bool_value) == types.IntType):
raise SyntaxError
xml=parsexml('startlog',log_file_name,bool_name)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def log(Message,tag):
""" Logs the message in the log.xml with the tag which can be viewed after the execution of scripts
INPUT: log('<Message to be logged>','<tag>')
OUTPUT: The required message will be logged into the log.xml on execution of scripts
It returns 1 on Success and 0 on error """
if not (type (Message) == type (tag) == types.StringType):
raise SyntaxError
xml=parsexml('log',Message,tag)
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
def stoplog():
""" Stop logging.
INPUT: stoplog()
OUTPUT: If a log file has been previously opened for logging, that file pointer will be closed.
So that the new logging will not be appened to the log file. """
xml=parsexml('stoplog')
try:
data=socksend(xml)
except ConnectionLost:
raise ConnectionLost (0)
return data
# MenuItem Functions