Object Repository#
The Object Repository contains all of the Page Objects that you have defined in your test-pack.
The Object Repository serves two purposes:
Documentation when you are writing test scripts: It shows the Page Objects that you can use in your test, and their available properties and methods.
Debugging tool when you are writing new Page Objects.
What is a Page Object?#
A Page Object is a Python class that uses Stb-tester APIs like stbt.match()
and stbt.ocr()
to extract information from the screen, and it provides a
higher-level API in the vocabulary and user-facing concepts of your own
application.
Once you have defined the appropriate Page Objects, your testcases can talk about user-facing concepts like “guide”, “menu”, and “programme title”. All the low-level details like image-matching, OCR, and regions, should be encapsulated inside Page Objects. This is a well-known pattern used in web-testing frameworks like Selenium.
If your testcase is calling
stbt.match()
orstbt.ocr()
directly, you are Doing It Wrong!—Paraphrasing Simon Stewart, from the Selenium project.
There are many advantages to using Page Objects:
Maintenance is easier and cheaper. If your GUI changes in appearance, you only need to update your test-pack in one place (the Page Objects), not in hundreds of different testcases.
Stb-tester provides special tooling that makes it easier to adapt your Page Objects when the GUI-under-test changes; you’ll see more about this below.
Clarity: Your testcases are shorter, and the intent of each testcase is clearer.
Documentation and code re-use: Stb-tester’s Object Repository shows you the relevant Page Objects for any particular screen. This makes it easier to use Page Objects written by other team members.
What is a Frame Object?#
stbt.FrameObject
is Stb-tester’s implementation of the Page Object pattern.
It is a base class for the Page Objects that you define.
Stb-tester uses a separate instance of your class for each frame of video that is captured from the device-under-test (hence the name “Frame Object”). Each instance represents information about a specific frame of video — in other words, an instance of a FrameObject represents the state of the device-under-test at a specific point in time.
See stbt.FrameObject
in Stb-tester’s Python API documentation for details
about the special behaviour that FrameObject adds to your classes.
Creating new Page Objects#
Here is the recommended workflow for developing your Page Objects:
Save screenshots of the relevant screens under
selftest/screenshots/
.Create a class that derives from
stbt.FrameObject
.Define a property called
is_visible
.Define any other properties for information that you want to extract from the screen.
Check the behaviour in the Object Repository on the Stb-tester Portal.
Repeat steps 1-5 until it’s working as desired.
Make a git commit and open a pull request to share your changes with your team!
Save a screenshot#
The first step is to save a screenshot of the relevant screen into
selftest/screenshots/
in your test-pack. Give the file a descriptive name,
not just “screenshot.png”. You can create subdirectories to organise your
screenshots as you like.
By saving a screenshot, you will be able to develop and test your Page Object without actually running a test. This is much more efficient because running a test is relatively slow. These screenshots will be visible in the Object Repository on the Stb-tester Portal.
Remember to run git add
to tell git to track the new screenshot.
Create a class that derives from stbt.FrameObject#
For example:
class Menu(stbt.FrameObject):
"""Write some documentation about your class here.
You might want to mention implementation details that others
should be aware of if they're modifying this class, or
details about the relevant business requirements, etc.
"""
Define a property called is_visible#
is_visible
should return True if the particular page or screen is present.
For example, to identify the Roku’s main menu (shown here) we could look for the Roku logo in the top corner and the white selection in the left half of the screen.
class Menu(stbt.FrameObject):
"""The Roku's main menu."""
@property
def is_visible(self):
ignore_text = stbt.MatchParameters(confirm_method="none")
logo = stbt.match("images/roku-logo.png",
frame=self._frame)
selection = stbt.match("images/menu-selection.png",
frame=self._frame,
match_parameters=ignore_text)
return logo and selection
Note that every image-processing operation —such as stbt.match()
or
stbt.ocr()
— must specify frame=self._frame
. Otherwise the result will
depend on the current live video; it won’t correspond to the FrameObject
instance. Stb-tester’s static analysis will warn you if
you’ve forgotten to specify frame
inside a FrameObject property.
Inside a FrameObject property, every image-processing operation — such as
stbt.match()
orstbt.ocr()
— must specifyframe=self._frame
Define properties to extract information from the frame#
Using the same Roku menu as an example, here’s a property that reads the text of the menu selection (“Home”, “My Feed”, “Settings”, etc):
class Menu(stbt.FrameObject):
"""The Roku's main menu."""
@property
def is_visible(self):
... # implementation not shown
@property
def selection(self):
return stbt.ocr(
frame=self._frame,
mode=stbt.OcrMode.SINGLE_LINE,
# Fixed focus menu: The selection is always in the same position
region=stbt.Region(x=116, y=160, right=477, bottom=205))
Once again: It’s important that we specify frame=self._frame
when we call
stbt.ocr()
.
View your Page Object in the Stb-tester Portal#
If you have followed the instructions in IDE Setup, pressing “Save” in your IDE will sync your local changes to the Portal, to a branch called “@YOUR_USERNAME’s snapshot”.
Select your branch, then select “Watch for changes and generate documentation”. Now, whenever you press “Save”, the Portal will run your Page Object code against the screenshots you saved in the first step. Here you can see the return value of each property, and view detailed debug information for any OCR and image-processing operations.