def test_ios_device_info(): idi = IosDeviceInfo(IosDeviceName.iPhone_11_Pro) assert idi.device_name == IosDeviceName.iPhone_11_Pro assert idi.screen_orientation == ScreenOrientation.PORTRAIT assert idi.ios_version is None assert idi.baseline_env_name is None assert {"name": "iPhone 11 Pro", "screenOrientation": "portrait"} == json.loads( json_utils.to_json(idi) ) idi = IosDeviceInfo( IosDeviceName.iPhone_11_Pro, ScreenOrientation.LANDSCAPE, IosVersion.LATEST, "Baseline env", ) assert idi.device_name == IosDeviceName.iPhone_11_Pro assert idi.screen_orientation == ScreenOrientation.LANDSCAPE assert idi.ios_version == IosVersion.LATEST assert idi.baseline_env_name == "Baseline env" assert { "name": "iPhone 11 Pro", "screenOrientation": "landscape", "iosVersion": "latest", } == json.loads(json_utils.to_json(idi)) idi = IosDeviceInfo("iPhone 11 Pro", "landscape", "latest-1") assert idi.device_name == IosDeviceName.iPhone_11_Pro assert idi.screen_orientation == ScreenOrientation.LANDSCAPE assert idi.ios_version == IosVersion.ONE_VERSION_BACK assert { "name": "iPhone 11 Pro", "screenOrientation": "landscape", "iosVersion": "latest-1", } == json.loads(json_utils.to_json(idi))
def test_image_match_settings_serialization(use_dom, enable_patterns, ignore_displacements, match_level, eyes, screenshot): settings = (Target.window().fully().use_dom(use_dom).enable_patterns( enable_patterns).ignore_displacements( ignore_displacements).match_level(match_level)) exact_match_settings = ExactMatchSettings() exact_match_settings.match_threshold = 0.5 eyes.configure.default_match_settings = ImageMatchSettings( match_level=MatchLevel.EXACT, exact=exact_match_settings, use_dom=use_dom) image_match_settings = MatchWindowTask.create_image_match_settings( settings, eyes) assert image_match_settings.match_level == match_level assert image_match_settings.use_dom == use_dom assert image_match_settings.enable_patterns == enable_patterns assert image_match_settings.ignore_displacements == ignore_displacements assert (image_match_settings.exact.match_threshold == exact_match_settings.match_threshold) serialized_img = json.loads(json_utils.to_json(image_match_settings)) assert serialized_img["matchLevel"] == match_level.value assert serialized_img["useDom"] == use_dom assert serialized_img["enablePatterns"] == enable_patterns assert serialized_img["ignoreDisplacements"] == ignore_displacements assert (serialized_img["exact"]["minDiffIntensity"] == exact_match_settings.min_diff_intensity) assert (serialized_img["exact"]["minDiffWidth"] == exact_match_settings.min_diff_width) assert (serialized_img["exact"]["minDiffHeight"] == exact_match_settings.min_diff_height) assert (serialized_img["exact"]["matchThreshold"] == exact_match_settings.match_threshold)
def create_message_from_log( agent_id, # type: Text test_id, # type: Text stage, # type: Stage data, # type: Dict[Text, Any] type=None, # type: Optional[Text] methods_back=3, # type: int ): # type: (...) -> Text d = { "agentId": agent_id, "testId": test_id, "stage": stage, "threadId": threading.current_thread().name, "stackTrace": [inspect.stack()[i][3] for i in range(2, methods_back + 1)], "pythonVersion": "{} {}".format( platform.python_implementation(), platform.python_version(), ), "platformName": platform.platform(), } if type: d["type"] = type d.update(data) return json_utils.to_json(d)
def prepare_match_data(match_data): # type: (MatchWindowData) -> bytes match_data_json = json_utils.to_json(match_data) logger.debug("MatchWindowData {}".format(match_data_json)) match_data_json_bytes = match_data_json.encode("utf-8") # type: bytes match_data_size_bytes = pack(">L", len(match_data_json_bytes)) # type: bytes return match_data_size_bytes + match_data_json_bytes
def test_fluent_info_api_serialization(use_dom, enable_patterns, ignore_displacements, match_level, eyes, screenshot): settings = (Target.window().fully().use_dom(use_dom).enable_patterns( enable_patterns).ignore_displacements( ignore_displacements).match_level(match_level)) image_match_settings = MatchWindowTask.create_image_match_settings( settings, eyes) assert image_match_settings.match_level == match_level assert image_match_settings.use_dom == use_dom assert image_match_settings.enable_patterns == enable_patterns assert image_match_settings.ignore_displacements == ignore_displacements assert image_match_settings.ignore_regions == [] assert image_match_settings.strict_regions == [] # assert image_match_settings.accessibility == [] assert image_match_settings.layout_regions == [] assert image_match_settings.content_regions == [] assert image_match_settings.floating_match_settings == [] serialized_img = json.loads(json_utils.to_json(image_match_settings)) assert serialized_img["matchLevel"] == match_level.value assert serialized_img["useDom"] == use_dom assert serialized_img["enablePatterns"] == enable_patterns assert serialized_img["ignoreDisplacements"] == ignore_displacements assert serialized_img["Ignore"] == [] assert serialized_img["Layout"] == [] assert serialized_img["Strict"] == [] assert serialized_img["Content"] == [] assert serialized_img["Floating"] == []
def test_render_request_serialize(browser_type): request_resources = {"url": VGResource.EMPTY("some-url.com")} dom_url = "dom-url.com" r_info = RenderInfo( width=500, height=600, size_mode="full-page", selector=None, region=None, emulation_info=None, ) dom = RGridDom( url=dom_url, dom_nodes=[{}], resources=request_resources, ) requests = [ RenderRequest( webhook="some-webhook.com", agent_id="my-agent-id", url=dom_url, dom=dom, resources=request_resources, render_info=r_info, browser_name=browser_type, platform="linux", script_hooks=dict(), selectors_to_find_regions_for=[], send_dom=False, ) ] RESULT_PATTERN = '[{"agentId": "my-agent-id", "browser": {"name": "%s", "platform": "linux"}, "dom": {"hash": "a67486a8bc9ba45f878e5b0d8ff9bc68ec6ed9db0382709751327d1793898e16", "hashFormat": "sha256"}, "renderId": null, "renderInfo": {"height": 600, "sizeMode": "full-page", "width": 500}, "resources": {"url": {"contentType": "application/empty-response", "hash": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", "hashFormat": "sha256"}}, "scriptHooks": {}, "selectorsToFindRegionsFor": [], "sendDom": false, "url": "dom-url.com", "webhook": "some-webhook.com"}]' assert RESULT_PATTERN % (browser_type.value) == json_utils.to_json( requests)
def send_logs(self, *client_events): # type: (*ClientEvent) -> None # try once try: events = json_utils.to_json(LogSessionsClientEvents(client_events)) self._com.request("post", self.API_SESSIONS_LOG, data=events) except Exception: logger.exception("send_logs failed")
def post_locators(self, visual_locators_data): # type: (VisualLocatorsData) -> LOCATORS_TYPE data = json_utils.to_json(visual_locators_data) response = self._com.long_request("post", "api/locators/locate", data=data) response.raise_for_status() return { locator_id: json_utils.attr_from_dict(regions, Region) for locator_id, regions in iteritems(response.json()) }
def test_serialization_of_batch_info(): bi = BatchInfo(name="Name", batch_sequence_name="BatchName").with_batch_id("custom-id") res = json.loads(json_utils.to_json(bi)) print(res) assert res["name"] == "Name" assert res["batchSequenceName"] == "BatchName" assert res["notifyOnCompletion"] == False assert res["id"] == "custom-id"
def _send_runner_started_log_message(self, server_connector): # type: (ServerConnector) -> None message = { "type": "runnerStarted", self._concurrency.kind.value: self._concurrency.value, # ... other properties like node version, os, architecture, etc. } server_connector.send_logs( logger.ClientEvent(logger.TraceLevel.Notice, json_utils.to_json(message)) )
def test_running_session_serialization_and_deserialization(): rs = RunningSession( id="some-id", session_id="session-id", batch_id="batch-id", baseline_id="baseline_id", url="url", is_new_session=True, ) rs_json = json_utils.to_json(rs) assert '"isNew": true' in rs_json assert rs == json_utils.attr_from_json(rs_json, RunningSession)
def job_info(self, render_requests): # type: (List[RenderRequest]) -> List[JobInfo] resp = self._ufg_request("post", self.RENDERER_INFO, data=json_utils.to_json(render_requests)) resp.raise_for_status() # TODO: improve parser to skip parsing of inner structures if required return [ JobInfo(renderer=d.get("renderer"), eyes_environment=d.get("eyesEnvironment")) for d in resp.json() ]
def test_batch_info_serializing(eyes, driver_mock): date = datetime.datetime.strptime("2019-06-04T10:27:15Z", "%Y-%m-%dT%H:%M:%SZ") eyes.batch = BatchInfo("Batch Info", date) eyes.batch.sequence_name = "Sequence" if not eyes._visual_grid_eyes: session_info = open_and_get_start_session_info(eyes, driver_mock) info_json = json_utils.to_json(session_info) batch_info = json.loads(info_json)["startInfo"]["batchInfo"] assert batch_info["name"] == "Batch Info" assert batch_info["batchSequenceName"] == "Sequence" assert batch_info["startedAt"] == "2019-06-04T10:27:15Z"
def _start_session(self, session_start_info): # type: (SessionStartInfo) -> RunningSession logger.debug("start_session called.") data = json_utils.to_json(session_start_info) response = self._com.long_request( "post", url_resource=self.API_SESSIONS_RUNNING, data=data, headers=self.DEFAULT_HEADERS, ) running_session = json_utils.attr_from_response(response, RunningSession) self._is_session_started = True return running_session
def prepare_match_data(match_data): # type: (MatchWindowData) -> bytes screenshot64 = match_data.app_output.screenshot64 if screenshot64: match_data.app_output.screenshot64 = None image = image_utils.image_from_base64(screenshot64) screenshot_bytes = image_utils.get_bytes(image) # type: bytes else: screenshot_bytes = b"" match_data_json = json_utils.to_json(match_data) logger.debug("MatchWindowData {}".format(match_data_json)) match_data_json_bytes = match_data_json.encode("utf-8") # type: bytes match_data_size_bytes = pack(">L", len(match_data_json_bytes)) # type: bytes body = match_data_size_bytes + match_data_json_bytes + screenshot_bytes return body
def test_configuration_serialization(eyes, screenshot): settings = Target.window().fully() config = eyes.get_configuration() config.use_dom = True config.enable_patterns = True config.ignore_displacements = True eyes.set_configuration(config) image_match_settings = MatchWindowTask.create_image_match_settings( settings, eyes, screenshot) assert image_match_settings.use_dom assert image_match_settings.enable_patterns assert image_match_settings.ignore_displacements serialized_img = json.loads(json_utils.to_json(image_match_settings)) assert serialized_img["useDom"] assert serialized_img["enablePatterns"] assert serialized_img["ignoreDisplacements"]
def start_session(self, session_start_info): # type: (SessionStartInfo) -> RunningSession """ Starts a new running session in the agent. Based on the given parameters, this running session will either be linked to an existing session, or to a completely new session. :param session_start_info: The start params for the session. :return: Represents the current running session. """ logger.debug("start_session called.") data = json_utils.to_json(session_start_info) response = self._com.request( requests.post, url_resource=self.API_SESSIONS_RUNNING, data=data ) running_session = json_utils.attr_from_response(response, RunningSession) running_session.is_new_session = response.status_code == requests.codes.created self._is_session_started = True return running_session
def get_text_in_running_session_image(self, data): # type: (TextSettingsData) -> List[Text] logger.debug( "call", _class=self.__class__.__name__, _method="extract_text", text_region_data=data, ) resp = self._com.long_request( "post", urljoin(self.API_SESSIONS_RUNNING, "images/text"), data=json_utils.to_json(data), ) if resp.ok: return resp.json() raise EyesError( "ServerConnector.extract_text - unexpected status {}".format( resp.status_code ) )
def match_window(self, running_session, match_data): # type: (RunningSession, MatchWindowData) -> MatchResult """ Matches the current window to the immediate expected window in the Eyes server. Notice that a window might be matched later at the end of the test, even if it was not immediately matched in this call. :param running_session: The current session that is running. :param match_data: The data for the requests.post. :return: The parsed response. """ logger.debug("match_window called. {}".format(running_session)) # logger.debug("Data length: %d, data: %s" % (len(data), repr(data))) if not self.is_session_started: raise EyesError("Session not started") app_output = match_data.app_output # when screenshot_url is present we don't need to upload again if app_output.screenshot_url is None and app_output.screenshot_bytes: app_output.screenshot_url = self.try_upload_image( match_data.app_output.screenshot_bytes) if app_output.screenshot_url is None: raise EyesError( "MatchWindow failed: could not upload image to storage service." ) logger.info("Screenshot image URL: {}".format( app_output.screenshot_url)) data = json_utils.to_json(match_data) headers = ServerConnector.DEFAULT_HEADERS.copy() response = self._com.long_request( "post", url_resource=urljoin(self.API_SESSIONS_RUNNING, running_session.id), data=data, headers=headers, ) return json_utils.attr_from_response(response, MatchResult)
def render(self, *render_requests): # type: (*RenderRequest) -> List[RunningRender] logger.debug("render called with {}".format(render_requests)) if self._render_info is None: raise EyesError("render_info must be fetched first") url = urljoin(self._render_info.service_url, self.RENDER) headers = ServerConnector.DEFAULT_HEADERS.copy() headers["Content-Type"] = "application/json" headers["X-Auth-Token"] = self._render_info.access_token data = json_utils.to_json(render_requests) response = self._com.request( requests.post, url, use_api_key=False, headers=headers, data=data ) if response.ok or response.status_code == requests.codes.not_found: return json_utils.attr_from_response(response, RunningRender) raise EyesError( "ServerConnector.render - unexpected status ({})\n\tcontent{}".format( response.status_code, response.content ) )
def get_text_regions_in_running_session_image(self, data): # type: (TextSettingsData) -> PATTERN_TEXT_REGIONS logger.debug( "call", _class=self.__class__.__name__, _method="extract_text_regions", text_region_data=data, ) resp = self._com.long_request( "post", urljoin(self.API_SESSIONS_RUNNING, "images/textregions"), data=json_utils.to_json(data), ) if resp.ok: return { pattern: json_utils.attr_from_dict(regions, TextRegion) for pattern, regions in iteritems(resp.json()) } raise EyesError( "ServerConnector.extract_text_regions - unexpected status {}".format( resp.status_code ) )
def test_render_request_serialize(browser_type): request_resources = { "url": VGResource( "some-url.com", content_type="application/png", content=b"some-content" ) } dom_url = "dom-url.com" r_info = RenderInfo( width=500, height=600, size_mode="full-page", selector=None, region=None, emulation_info=None, ) dom = RGridDom(url=dom_url, dom_nodes=[{}], resources=request_resources) requests = [ RenderRequest( webhook="some-webhook.com", agent_id="my-agent-id", stitching_service="https://some.stitchingserviceuri.com", url=dom_url, dom=dom, resources=request_resources, render_info=r_info, browser_name=browser_type.value, platform_name="linux", script_hooks=dict(), selectors_to_find_regions_for=[], send_dom=False, ) ] test_results_data = get_resource("unit/renderResult.json").decode("utf-8") test_results_data %= browser_type.value assert json.loads(test_results_data.replace("\n", "")) == json.loads( json_utils.to_json(requests) )
def _run_script(self, args, args_type, code_gen_func): # type: (Dict[Text, Any], type, Callable[[Text], Text]) -> ProcessPageResult args = {k: v for k, v in args.items() if k != "self"} code = code_gen_func(to_json(args_type(**args))) result_json = self._driver.execute_script(code) return ProcessPageResult.from_json(result_json)
def content(self): # type: () -> Text data = {"resources": self.resources, "domNodes": self.dom_nodes} return json_utils.to_json(data)