Robot Framework: capture screen and move to a new location

Asked by Peter Kim

Hi.

I have a function called test_teardown which looks like following:

def test_teardown():
    # Save the screen
    print "test_teardown: capturing the screen"
    captured_screen = capture(SCREEN)
    print "test teardown: screen was captured at ", captured_screen
    outfile = os.path.join(getBundlePath(), os.path.basename(captured_screen))
    print "test_teardown: moving capture screen ", captured_screen, " to ", outfile
    shutil.move (captured_screen, outfile)

This code works fine in Sikuli IDE.

If Sikuli is used with Robot Framework, the capture works but the captured temporary file seems to be removed right away and the code fails. Here is the log message from Robot Framework:

- TEARDOWN: LU6200.Test Teardown
Start / End / Elapsed: 20111123 10:25:35.423 / 20111123 10:25:36.104 / 00:00:00.681
10:25:36.071 INFO test_teardown: capturing the screen
test teardown: screen was captured at C:\Users\pd.kim\AppData\Local\Temp\sikuli-scr-7443802522424196690.png
10:25:36.104 FAIL TypeError: len() of unsized object

I commented out the last three lines and confirmed that the captured file was not there any more after the function was completed.

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
RaiMan (raimund-hocke) said :
#1

When running the stuff in RobotFrameWork, you have to take a a real path. getBundlePath() in this case points to the temp directory itself, so source and target are the same in this case.

I do not definitely know when, but the temporary images are purged by Sikuli itself.

If it does not work at all, you might use the Java Robot screen capture yourself.

Revision history for this message
Peter Kim (pd-kim) said :
#2

Hi RaiMan,

Thank you for your prompt answers.

I think that the problem is getBundlePath() when Sikuli is run with Robot Framework.

Here is what my function looks like:

def v_wait_click(image):
    if (v.exists(image,25)):
        v.click(image)
    else:
        print "v_wait_click: capturing the screen"
        captured_screen = capture(SCREEN)
        print "v_wait_click: screen was captured at ", captured_screen
        print "v_wait_click: getBundlePath() = ", getBundlePath()
        print "v_wait_click: os.path.basename(captured_screen) = ", os.path.basename(captured_screen)
        outfile = os.path.join(getBundlePath(), os.path.basename(captured_screen))
        print "v_wait_click: moving capture screen ", captured_screen, " to ", outfile
        shutil.move (captured_screen, outfile)
        v.click(image)

Here is what Sikuli IDE printed out:

v_wait_click: capturing the screen
v_wait_click: screen was captured at C:\Users\pd.kim\AppData\Local\Temp\sikuli-scr-5383166600268765385.png
v_wait_click: getBundlePath() = C:\Sikuli\LU6200.sikuli
v_wait_click: os.path.basename(captured_screen) = sikuli-scr-5383166600268765385.png
v_wait_click: moving capture screen C:\Users\pd.kim\AppData\Local\Temp\sikuli-scr-5383166600268765385.png to C:\Sikuli\LU6200.sikuli\sikuli-scr-5383166600268765385.png

Here is what Sikuli + Robot Framework printed out:

- KEYWORD: LU6200.V Wait Click c:\Sikuli\LU6200.sikuli\SikuliIDE.png
Start / End / Elapsed: 20111124 11:09:41.057 / 20111124 11:10:07.008 / 00:00:25.951
11:10:06.898 INFO v_wait_click: capturing the screen
v_wait_click: screen was captured at C:\Users\pd.kim\AppData\Local\Temp\sikuli-scr-2623127815520719942.png
v_wait_click: getBundlePath() = None
v_wait_click: os.path.basename(captured_screen) = sikuli-scr-2623127815520719942.png
11:10:07.006 FAIL TypeError: len() of unsized object

So the question is why getBundlePath() returns None in Robot Framework.

Revision history for this message
Best RaiMan (raimund-hocke) said :
#3

-- why getBundlePath() returns None in Robot Framework
the bundle path is only set, when the script is run using either the IDE or "java -jar sikuli-script.jar". This is not the case, when your functions are used in RFW. There it is simply a Jython module import, that does not know anything about images and bundles.

So if you want to be able to test your scripts in Sikuli's IDE and use them as modules in RFW too, you have to add some code, that provides the image path, when running in RFW (if not getBundlePath(): # provide image path).

Depending on the overall structure of your stuff, you may decide to store all images in one .sikuli, that is imported in your scripts, which puts them in the image path, so the images will be found automagically. In this case, you have to take care, that your image filenames follow a naming convention, that prevents duplicate filenames.

Revision history for this message
Peter Kim (pd-kim) said :
#4

Thanks RaiMan, that solved my question.

Revision history for this message
RaiMan (raimund-hocke) said :
#5

If you decide to store all images in a few places, you can pre populate the image path with these directories using an environment variable
SIKULI_IMAGE_PATH=path1-to-images:path2-to-images:path3-to-images

So you would not need any extra code in your scripts. They would run as scripts from command line and in RFW.

look: http://sikuli.org/docx/globals.html#getImagePath (the text below)
for more information.