Primarily, Squish is a tool to automate GUI tests. However, given the ability to automatically interact with an application, there is a whole lot more we can do with Squish. For example keeping documentation screenshots in the user’s manual up to date has proven to be an annoying and tedious task. Incidentally, Squish can also take screenshots. So why not go ahead and automate that burden away?
For the sake of this article, we are going to tackle a small task: Produce screenshots for a tutorial. The tutorial shall be about adding a contact in Squish’s address book example application. Let’s start off with a textual description of what actions need to be taken in the address book application:
Feature: Address Book Tutorial This is a demo feature that creates screenshots which could be used in the documentation or tutorial for Squish's address book example application. Scenario: Adding a Contact Given the address book application is running Then I create a new address book Then I open the new contact dialog Then I enter new contact data Then I confirm the new contact dialog
That probably looks familiar: it is a Gherkin feature file as used with Behavior-Driven Development (BDD). Usually, a Gherkin feature follows a Given/When/Then pattern. That works well for test cases with pre- and post-conditions, but in our screenshots project there are no conditions to check. We still get a clear description of what is supposed to happen though. In comparison to recorded script code, it is also a lot easier to read and understand.
Now is a good time to record the necessary steps without having to bother about screenshots at all. Afterwards we can then continue by inserting a step for screen-shooting where needed:
Feature: Address Book Tutorial This is a demo feature that creates screenshots which could be used in the documentation or tutorial for Squishs address book example application. Scenario: Adding a Contact Given the address book application is running Then I create a new address book Then I shoot the main window with file name "main_window_empty" Then I open the new contact dialog Then I shoot the new contact dialog with file name "new_contact_dialog_empty" Then I enter new contact data Then I shoot the new contact dialog with file name "new_contact_dialog_filled" Then I confirm the new contact dialog Then I shoot the main window with file name "main_window_one_contact"
As you can see, there is a screen-shooting step after each action. This could of course look completely different for your own application. If you already have a library of step implementations, you can reuse many of those and thus save lots of time.
So much for the plain English part. Now it is time to get our hands dirty and implement the screenshot step! Looking at the feature file, it becomes clear that the steps follow a “shoot [object] with file name [name]” pattern. This pattern translates well to a parametrized step implementation:
@Then("I shoot the |any| with file name "|any|"") def step(context, identifier, fileName): pass
The “identifier” parameter describes the object to screen-shoot. We need to find the object in the application by, for example, mapping the term “main window” from the Gherkin feature to a Squish object name. Just like in normal Squish tests, we use waitForObject() to acquire the actual object reference. The reference is then passed to the grabWidget() function.
grabWidget() creates a screenshot of the object in memory. Finally, write the image it returned to a suitable location on disk. This is the resulting step implementation:
@Then("I shoot the |any| with file name "|any|"") def step(context, identifier, fileName): object = None if identifier == "main window": object = waitForObject(names.address_Book_MainWindow) elif identifier == "new contact dialog": object = waitForObject(names.address_Book_Add_Dialog) shot = grabWidget(object) filePath = os.path.join(squishinfo.testCase, fileName + ".png") shot.save(filePath, "png")
In case you stumbled upon the “names.address_Book_MainWindow” part: This is a symbolic name from the Scripted Object Map that has been released with Squish 6.4.
Please note that if you follow along this article, it may be necessary to adapt the object names passed to
waitForObject() – they need to match symbolic names that actually exist in your object map. Once that is done, run the feature, and create the desired documentation screenshots in the process. In this example, the images will be saved to the test case directory in PNG format.
Creating documentation screenshots is one way to use Squish beyond pure testing applications. As already mentioned, writing tests takes less work when you have a library of existing functions to reuse. Creating new “tests” for this kind of job is just as quick and can spare you of tons of tedious work updating your documentation. In addition, outlining the screenshot contents in a Gherkin file is a good way to track changes to otherwise opaque binary files in version control.
Also note that with
grabWidget(), you can shoot arbitrary widgets, not just a whole window. Finally, with the power of your favorite scripting language at hand, post-processing images via command-line utilities is just a few lines of code away.