def test_load_invalid(self): database = LocatorsDatabase(to_stream(ERRORS)) database.load() assert database.error is None assert len(database.locators) == 1 assert len(database._invalid) == 2
def test_migrate_screenshot(self): content = copy.deepcopy(CURRENT) content["RobotSpareBin.Username"]["screenshot"] = "not-exist.png" content["RobotSpareBin.Password"]["screenshot"] = ( "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAA" "AACklEQVR42mMAAQAABQABoIJXOQAAAABJRU5ErkJggg==" ) with temp_cwd() as cwd: images = Path(cwd) / ".images" screenshot_username = images / "robotsparebin-username-screenshot.png" screenshot_password = images / "robotsparebin-password-screenshot.png" database = LocatorsDatabase(to_stream(content)) database.load() assert database.error is None assert len(database.locators) == 4 assert images.is_dir() assert not (screenshot_username).is_file() assert (screenshot_password).is_file() username = database.locators["RobotSpareBin.Username"] assert username.screenshot == "not-exist.png" password = database.locators["RobotSpareBin.Password"] assert password.screenshot == str(screenshot_password.relative_to(cwd))
def test_load_by_name_invalid_name(self): with temp_cwd() as cwd: path = Path(cwd) / "locators.json" with open(path, "w") as fd: fd.write(json.dumps(CURRENT)) with pytest.raises(ValueError): LocatorsDatabase.load_by_name("RobotSpareBin.Paswerd")
def test_legacy_missing_name(self): content = copy.deepcopy(LEGACY) del content[1]["name"] database = LocatorsDatabase(to_stream(content)) database.load() assert database.error is None assert len(database.locators) == 2
def test_load_malformed(self): stream = io.StringIO("not-a-json{]}\\''") database = LocatorsDatabase(stream) database.load() assert database.error is not None assert len(database.error) == 2 assert len(database.locators) == 0
def parse(locator: LocatorType) -> Locator: """Parse locator string literal into a ``Locator`` instance. For example: "image:path/to/image.png" -> ImageLocator(path="path/to/image-png") """ if isinstance(locator, Locator): return locator try: typename, _, value = str(locator).partition(":") except ValueError as err: raise ValueError(f"Invalid locator format: {locator}") from err if not value: typename, value = "alias", typename typename = typename.strip().lower() if typename == "alias": return LocatorsDatabase.load_by_name(_unquote(value)) else: klass = TYPES.get(typename) if not klass: raise ValueError(f"Unknown locator type: {typename}") args = [_unquote(arg) for arg in value.split(",")] return klass(*args)
def _load_by_alias(self, criteria: str) -> str: try: locator = LocatorsDatabase.load_by_name(criteria, self._locators_path) if isinstance(locator, WindowsLocator): return locator.value except ValueError: pass return criteria
def test_load_by_name(self): with temp_cwd() as cwd: path = Path(cwd) / "locators.json" with open(path, "w") as fd: fd.write(json.dumps(CURRENT)) locator = LocatorsDatabase.load_by_name("RobotSpareBin.Password") assert isinstance(locator, BrowserLocator) assert locator.strategy == "id" assert locator.value == "password"
def _find_by_alias(self, parent, criteria, tag, constraints): """Custom 'alias' locator that uses locators database.""" del constraints locator = LocatorsDatabase.load_by_name(criteria, self.locators_path) if not isinstance(locator, BrowserDOM): raise ValueError(f"Not a browser locator: {criteria}") selector = "{strategy}:{value}".format(strategy=locator.strategy, value=locator.value) return self._element_finder.find(selector, tag, parent)
def test_reset_error(self): database = LocatorsDatabase() database.path = io.StringIO("some-error") database.load() assert database.error is not None assert len(database.locators) == 0 database.path = to_stream(CURRENT) database.load() assert database.error is None assert len(database.locators) == 4
def test_resolve_paths(self): database = LocatorsDatabase(to_stream(CURRENT)) database.load() database.path = "/example/root/path/locators.json" locator = database.resolve("RobotSpareBin.Logo") assert isinstance(locator, ImageLocator) assert Path(locator.path) == Path( "/example/root/path/relative/locator/path.png") assert Path(locator.source) == Path("/absolute/locator/path.png")
def test_save(self): stream = to_stream(CURRENT) database = LocatorsDatabase(stream) database.load() stream.truncate(0) stream.seek(0) database.locators["RobotSpareBin.Password"].value = "paswerd" database.save() data = stream.getvalue() content = json.loads(data) assert content["RobotSpareBin.Password"]["value"] == "paswerd"
def test_load_by_name_invalid_path(self): with pytest.raises(ValueError): LocatorsDatabase.load_by_name("RobotSpareBin.Password", "no-exist.json")
def legacy_database(self): database = LocatorsDatabase(to_stream(LEGACY)) database.load() return database
def current_database(self): database = LocatorsDatabase(to_stream(CURRENT)) database.load() return database
def test_load_missing(self): database = LocatorsDatabase("not/a/valid/path") database.load() assert database.error is None assert len(database.locators) == 0
def test_load_legacy_empty(self): database = LocatorsDatabase(to_stream({})) database.load() assert database.error is None assert len(database.locators) == 0