Taking screenshots at arbitrary points of test execution

Long story, hope I make myself clear.

I want to take screenshots of the full page at any scenario where i have test failing. Browser has ability to take screenshots but that works only for Browser’s own keywords. Ok, builtin library has Run Keyword If Test Failed and i thought i could use it in tear done phase but apparently not.

Initially my setup was:

  • testsuite files with tests defined as templates →
  • resource file that has the implemented templates as keywords and each template had its own [teardown]

Ofcourse this did not work because teardown in the keywword (even thought the keyword is a test template) didn’t work. TEST STATUS variable was not defined and Run Keyword If Test Failed was complaining that it should be only executed in test teardown.

Ok, i got that sorted out by moving the [teardown] from the template into actual suite. And re-run.

Didn’t work. However the faillure changed:

Also teardown failed:
Error: Tried to take screenshot, but no page was open.

Ok, maybe this is due to auto closing context’s and what not, so i added import time argument:

 auto_closing_level=MANUAL

And rely only on my own setup which creates browser, context and page … and teardown that closes then and runs a Take Screenshot before closing anything but the result is still the same: No Page Open :frowning: Is this a bug in Browser or am i doing something i should not ?

Any suggestions ?

What i would like to do is to Browser.Take Screenshot with full page on for every failing keyword even when its not directly from browser library and not to litter the testcode with extra keywords / exception handling to archive that.

PS. Im about to start writing a listener that does what i need but feels like this sort of scenario should be possible to accomplish with just RF and Browser’s own keywords ?

Browser library doesn’t see outside of the library own keywords, if the test failed or not. There are some plans to make it aware of such things, but nothing concrete yet. Basically automatically clearing video and trace files on successful tests. But also in library case we are planning to use listener interface, so I think listener is the easy way out also for your case

Yes Tatu. Thats why i dont use automatic screenshot feature from the browser lib and moved the screenshoting into teardown but as i tried to convey, that didnt work because “No open page” even thought i’ve completely disabled the auto context closing. Which is why i said, “feels like a bug”.

Auto closing should do the trick, but usually this doesn’t work as expected because of Robot Framework library import mechanism if you have multiple imports of the library. If you have multiple imports of Browser library you should change the import setting in all library imports. This is because it’s impossible to know which of the library imports is valid during the test execution. Usually it’s better to import library only one time.

$ git grep "Library "|grep Browser
resources/keywords.resource:Library         Browser   jsextension=${CURDIR}/../lib/mockUrl.js,${CURDIR}/../lib/consoleListener.js,${CURDIR}/../lib/axe-core-extension.js   enable_presenter_mode=False   run_on_failure=${None}   auto_closing_level=MANUAL

Only single Library import for Browser …

I made a barebones listener that implements only end_keyword:

from robot.libraries.BuiltIn import BuiltIn
from pathlib import Path
import json
import sys


class ScreenshotListener():
    ROBOT_LISTENER_API_VERSION = 3
    def end_keyword(self, data, result):
        if result.status == "FAIL":
            try:
                b = BuiltIn().get_library_instance("Browser")
                suite_name = BuiltIn().get_variable_value("\${SUITE NAME}")
                test_name = BuiltIn().get_variable_value("\${TEST NAME}")
                ss_index = BuiltIn().get_variable_value("\${index}", "0")

                ssfile = f"NAME: {suite_name}_{test_name}_FAILURE_{ss_index}"
                b.take_screenshot(ssfile, log_screenshot=True, fullPage=True)
                print(f"NAME: {ssfile}", file=sys.stderr)
            except Exception as e:
                print(f"FAIL: {e}", file=sys.stderr)

And this triggers following to the console;

FAIL: Error: Tried to take screenshot, but no page was open.

This feels like something is not working in browser side ← OK: This is not the case. On cases where this happened where API responses where errors but they where expected errors … Eg, when polling for some value to change and api responses to frontend returned error 500’s… I guess i can hack around these …

Darn, then it wasn’t that one, hmmm. Indeed it sounds like a bug.We have simple tests which verify that it should work, but they don’t cover all situations. Would it be possible you to submit an issue with simple example which demonstrates the problem?

1 Like

i’ll try write a small repro that highlights the issue - also to just rule out that its not issue somewhere else besides my own codebase… Might take few days

1 Like

@aaltat – I think i found the reason for this while writing a repro for the other issue i asked about in gh issues. I had teardown being called twice and thus, the page wasn’t open. And for same reason, i wasn’t able to call js extension because keyword teardown was already executed…