Monday 7 May 2012

Sikuli - Presentation of Script Results

There are three methods for Sikuli Scripts to present results to the user: pop-up, print, and file io.

Pop-up

Pop-up alerts are the highest priority/highest visibility method of interacting with the user, but have the lowest data persistence. Typically, a pop-up is combined as a part of a try block or if statement. This presents the user with one or more lines of text, and halts the Sikuli script. The halting of the script allows users to inspect the current screen, modify graphical elements and mouse positions, and resume operation. Pop-ups can be used like a breakpoint within the script. The only downside is that there is no permanent record of the pop-up. Typically they need to be removed or commented out of a completed script.

def Alert():
    AlertL1 = "Sikuli Alert:"
    AlertL2 = "    - Displays 1+ lines of text"
    AlertL3 = "    - Halts the Sikuli script:"
    AlertL4 = "        - Allows inspection/modification of the screen/mouse"
    AlertL5 = "        - Allows user-controlled resumption of script"
    AlertL6 = "    - Used like a breakpoint or a try-catch statement"
    AlertL7 = "    - No permanent record of the alert."
    Str = AlertL1 + "\n" + AlertL2 + "\n" + AlertL3 + "\n" + AlertL4 + "\n" + AlertL5 + "\n" + AlertL6 + "\n" + AlertL7  
    popup( Str )
Alert()

Print

The python print command is used to print strings to stdout and does not interrupt the flow of the Sikuli script. When running Sikuli in the IDE, the stdout is captured and displayed in the Message window. The data is only moderately permanent and can be difficult to read. Because the window buffer is limited, for scripts with a large amount of print scripts there is the possibility of losing print data and the data is lost when a script is re-executed.

This is rectified by running the script from the command line and piping stdout to file. Unfortunately this file can be difficult to interpret because the stdout stream is also used for the internal Sikuli Logging messages (which uses the Jython Logging ilbrary). This means that the print data can become lost in a number of other messages.


def Print():
    print "Python Print:"
    print "    - Prints 1+ lines of text to stdio"
    print "    - In Sikuli IDE, text is displayed in the Message window."
    print "    - On the command line, text can be piped to file."
    print "    - Print command can be used without interrupting the flow of the Sikuli script."
    print "    - Data is lost the script is re-executed."
    print "    - stdio is used elsewhere, so print may be difficult to interpret"
Print()


File IO

Logging in Jython is normally accomplished through the Logging library. This library is in use by Sikuli, and its use has the same drawback as Print; an output file with multiple interleaved data streams that is difficult to read. A better alternative is to log to a separate user file using standard file IO. File IO allows the output strings to be encapsulated and if the logfile is opened in append mode, the data is also persistent across multiple executions of the Sikuli script. The file is by default located in the Sikuli base directory.

def Log():
    f = open("myLogfile.txt", 'a')
    f.write("Log to File:")
    f.write("    - Logs are persistent and encapsulated.")
    f.write("    - Logs do not interfere with Sikuli execution")
    f.write("    - Appended Logs 'a' allow for data persistence")
    f.close()

Log()

Building a Better Logger


Note that myLOG_CNT is a global variable. Globals must be defined as part of the Settings class and cannot overload an of the exsisting variable names. This logger includes a timestamp and message number to each entry. The file can also be located anywhere on the user's system.

import time

def LogMessage( FileName, msg ):
    """Though Python has logging capability, Sikuli already uses this to log its own stream of information. This 
       information includes mouse movements and keyboard entries and is exhaustive.  Using file IO allows the output 
       strings to be encapsulated and if the logfile is opened in append mode, the data is also persistent across 
       multiple executions of the Sikuli script.            
    """ 
    Settings.myLOG_CNT += 1
    dts = time.strftime('%Y-%m-%d %H:%M:%S')
    f = open(FileName, 'a')
    f.write('%s: msg# %d: %s\n' % (dts, Settings.myLOG_CNT, msg))
    f.close()



Further Reading:
05-07-2012 Sikuli X-1.0rc3 (r905)

2 comments: