def navigate_to(self, target, page, verify_every_keypress=False): """Move the selection to the specified key. This won't press *KEY_OK* on the target; it only moves the selection there. :param target: This can be a Key object returned from `find_key`, or it can be a dict that contains one or more of "name", "text", "region", and "mode" (as many as are needed to identify the key using `find_keys`). If more than one key matches the given parameters, ``navigate_to`` will navigate to the closest one. For convenience, a single string is treated as "name". :param stbt.FrameObject page: See `enter_text`. :param bool verify_every_keypress: See `enter_text`. :returns: A new FrameObject instance of the same type as ``page``, reflecting the device-under-test's new state after the navigation completed. """ import stbt_core as stbt targets = self._find_keys(target) if not targets: raise ValueError("'%s' isn't in the keyboard" % (target, )) if self.G_ is None: # Re-calculate graph without any shift transitions that type text self.G_ = _strip_shift_transitions(self.G) assert page, "%s page isn't visible" % type(page).__name__ deadline = time.time() + self.navigate_timeout current = page.selection while current not in targets: assert time.time() < deadline, ( "Keyboard.navigate_to: Didn't reach %r after %s seconds" % (target, self.navigate_timeout)) keys = list(_keys_to_press(self.G_, current, targets)) log.debug("Keyboard: navigating from %r to %r by pressing %r", current, target, [k for k, _ in keys]) if not verify_every_keypress: for k, _ in keys[:-1]: stbt.press(k) keys = keys[-1:] # only verify the last one for key, possible_targets in keys: assert self.press_and_wait(key, stable_secs=0.5) page = page.refresh() assert page, "%s page isn't visible" % type(page).__name__ current = page.selection assert current in possible_targets, \ "Expected to see %s after pressing %s, but saw %r" % ( _join_with_commas( [repr(x) for x in sorted(possible_targets)], last_one=" or "), key, current) return page
def navigate_to(self, target, page, verify_every_keypress=False): """Move the selection to the specified character. Note that this won't press KEY_OK on the target, it only moves the selection there. :param str target: The key or button to navigate to, for example "A", " ", or "CLEAR". :param stbt.FrameObject page: See ``enter_text``. :param bool verify_every_keypress: See ``enter_text``. :returns: A new FrameObject instance of the same type as ``page``, reflecting the device-under-test's new state after the navigation completed. """ import stbt_core as stbt if target not in self.G: raise ValueError("'%s' isn't in the keyboard" % (target, )) assert page, "%s page isn't visible" % type(page).__name__ deadline = time.time() + self.navigate_timeout current = _selection_to_text(page.selection) while current != target: assert time.time() < deadline, ( "Keyboard.navigate_to: Didn't reach %r after %s seconds" % (target, self.navigate_timeout)) keys = list(_keys_to_press(self.G, current, target)) log.info("Keyboard: navigating from %s to %s by pressing %r", current, target, keys) if not verify_every_keypress: for k, _ in keys[:-1]: stbt.press(k) keys = keys[-1:] # only verify the last one for key, possible_targets in keys: assert stbt.press_and_wait(key, mask=self.mask, stable_secs=0.5) page = page.refresh() assert page, "%s page isn't visible" % type(page).__name__ current = _selection_to_text(page.selection) assert current in possible_targets, \ "Expected to see %s after pressing %s, but saw %r" % ( _join_with_commas( [repr(x) for x in sorted(possible_targets)], last_one=" or "), key, current) return page
def test_that_image_is_rotated_by_arrows(): press("KEY_LEFT") wait_for_match('stb-tester-left.png') press("KEY_RIGHT") wait_for_match('stb-tester-right.png') press("KEY_UP") wait_for_match('stb-tester-up.png') press("KEY_DOWN") wait_for_match('stb-tester-down.png')
def test_that_custom_key_is_recognised(): press("KEY_CUSTOM") wait_for_match('stb-tester-up.png', timeout_secs=1)
def test_that_image_returns_to_normal_on_OK(): press("KEY_OK") wait_for_match('stb-tester-350px.png')
def enter_text(self, text, page, verify_every_keypress=False): """Enter the specified text using the on-screen keyboard. :param str text: The text to enter. If your keyboard only supports a single case then you need to convert the text to uppercase or lowercase, as appropriate, before passing it to this method. :param stbt.FrameObject page: An instance of a `stbt.FrameObject` sub-class that describes the appearance of the on-screen keyboard. It must implement the following: * ``selection`` (*str* or `Keyboard.Selection`) — property that returns the name of the currently selected character (for example "A" or " ") or button (for example "CLEAR" or "SEARCH"). This property can return a string, or an object with a ``text`` attribute that is a string. For grid-shaped keyboards, you can implement this property using `stbt.Grid` to map from the region of the selection (highlight) to the corresponding letter; see the example below. The ``page`` instance that you provide must represent the current state of the device-under-test. :param bool verify_every_keypress: If True, we will read the selected key after every keypress and assert that it matches the model (``graph``). If False (the default) we will only verify the selected key corresponding to each of the characters in ``text``. For example: to get from Q to D on a qwerty keyboard you need to press KEY_DOWN, KEY_RIGHT, KEY_RIGHT. The default behaviour will only verify that the selected key is D after pressing KEY_RIGHT the last time. This is faster, and closer to the way a human uses the on-screen keyboard. Set this to True to help debug your model if ``enter_text`` is behaving incorrectly. Typically your FrameObject will provide its own ``enter_text`` method, so your test scripts won't call this ``Keyboard`` class directly. For example:: class YouTubeSearch(stbt.FrameObject): _kb = stbt.Keyboard(''' A B KEY_RIGHT ...etc... ''') letters = stbt.Grid(region=..., data=["ABCDEFG", "HIJKLMN", "OPQRSTU", "VWXYZ-'"]) space_row = stbt.Grid(region=..., data=[[" ", "CLEAR", "SEARCH"]]) @property def is_visible(self): ... # implementation not shown @property def selection(self): m = stbt.match("keyboard-selection.png", frame=self._frame) if not m: return stbt.Keyboard.Selection(None, None) try: text = self.letters.get(region=m.region).data except IndexError: text = self.space_row.get(region=m.region).data return stbt.Keyboard.Selection(text, m.region) def enter_text(self, text): page = self page = self._kb.enter_text(text.upper(), page) self._kb.navigate_to("SEARCH", page) stbt.press("KEY_OK") def navigate_to(self, target): return self._kb.navigate_to(target, page=self) """ import stbt_core as stbt for letter in text: if letter not in self.G: raise ValueError("'%s' isn't in the keyboard" % (letter, )) prev = None for letter in text: page = self.navigate_to(letter, page, verify_every_keypress) if letter == prev: stbt.press("KEY_OK", interpress_delay_secs=1) else: stbt.press("KEY_OK") prev = letter return page