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.ocr() to extract information from the screen, and it provides a
higher-level API in the vocabulary and user-facing concepts of your own
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.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.
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
- Create a class that derives from
- Define a property called
- Define any other properties for information that you want to extract from the screen.
- Make a git snapshot of your code with
- Check the behaviour in the Object Repository on the Stb-tester portal.
- Repeat steps 1-6 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¶
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.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.ocr()— must specify
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
Take a git snapshot of your code¶
./stbt_rig.py snapshot to push a snapshot of your code to the
Stb-tester portal. This will only push files known to git, so if you’ve made
your FrameObject in a new file, use
git add tests/myfile.py first so that
git knows about your file.
./stbt_rig.py is a development tool that shortens the edit/test cycle when
you’re working on your FrameObjects. It pushes a snapshot of your code to a git
branch called “your_username/snapshot”. To install
If your IDE allows it, you can bind
./stbt_rig.py snapshot to your IDE’s
View your Page Object in the Stb-tester Portal¶
Select your branch (your_username/snapshot), and select “Watch for changes
and generate documentation”. Now, whenever you push changes with
snapshot, the portal will show the screenshots you’ve added, do they match
(according to the
is_visible property that you defined), and the values of
the other properties.