import imghdr import struct from base64 import decodebytes from webdriver import Element, NoSuchAlertException, WebDriverException # WebDriver specification ID: dfn-error-response-data errors = { "detached shadow root": 404, "element click intercepted": 400, "element not selectable": 400, "element not interactable": 400, "insecure certificate": 400, "invalid argument": 400, "invalid cookie domain": 400, "invalid coordinates": 400, "invalid element state": 400, "invalid selector": 400, "invalid session id": 404, "javascript error": 500, "move target out of bounds": 500, "no such alert": 404, "no such cookie": 404, "no such element": 404, "no such frame": 404, "no such shadow root": 404, "no such window": 404, "script timeout": 500, "session not created": 500, "stale element reference": 404, "timeout": 500, "unable to set cookie": 500, "unable to capture screen": 500, "unexpected alert open": 500, "unknown command": 404, "unknown error": 500, "unknown method": 405, "unsupported operation": 500, } def assert_error(response, error_code): """ Verify that the provided webdriver.Response instance described a valid error response as defined by `dfn-send-an-error` and the provided error code. :param response: ``webdriver.Response`` instance. :param error_code: String value of the expected error code """ assert response.status == errors[error_code] assert "value" in response.body assert response.body["value"]["error"] == error_code assert isinstance(response.body["value"]["message"], str) assert isinstance(response.body["value"]["stacktrace"], str) assert_response_headers(response.headers) def assert_success(response, value=None): """ Verify that the provided webdriver.Response instance described a valid success response as defined by `dfn-send-a-response` and the provided response value. :param response: ``webdriver.Response`` instance. :param value: Expected value of the response body, if any. """ assert response.status == 200, str(response.error) if value is not None: assert response.body["value"] == value assert_response_headers(response.headers) return response.body.get("value") def assert_response_headers(headers): """ Method to assert response headers for WebDriver requests :param headers: dict with header data """ assert 'cache-control' in headers assert 'no-cache' == headers['cache-control'] assert 'content-type' in headers assert 'application/json; charset=utf-8' == headers['content-type'] def assert_dialog_handled(session, expected_text, expected_retval): # If there were any existing dialogs prior to the creation of this # fixture's dialog, then the "Get Alert Text" command will return # successfully. In that case, the text must be different than that # of this fixture's dialog. try: assert session.alert.text != expected_text, ( "User prompt with text '{}' was not handled.".format(expected_text)) except NoSuchAlertException: # If dialog has been closed and no other one is open, check its return value prompt_retval = session.execute_script(" return window.dialog_return_value;") assert prompt_retval == expected_retval def assert_files_uploaded(session, element, files): def get_file_contents(file_index): return session.execute_async_script(""" let files = arguments[0].files; let index = arguments[1]; let resolve = arguments[2]; var reader = new FileReader(); reader.onload = function(event) { resolve(reader.result); }; reader.readAsText(files[index]); """, (element, file_index)) def get_uploaded_file_names(): return session.execute_script(""" let fileList = arguments[0].files; let files = []; for (var i = 0; i < fileList.length; i++) { files.push(fileList[i].name); } return files; """, args=(element,)) expected_file_names = [str(f.basename) for f in files] assert get_uploaded_file_names() == expected_file_names for index, f in enumerate(files): assert get_file_contents(index) == f.read() def assert_is_active_element(session, element): """Verify that element reference is the active element.""" from_js = session.execute_script("return document.activeElement") if element is None: assert from_js is None else: assert_same_element(session, element, from_js) def assert_same_element(session, a, b): """Verify that two element references describe the same element.""" if isinstance(a, dict): assert Element.identifier in a, "Actual value does not describe an element" a_id = a[Element.identifier] elif isinstance(a, Element): a_id = a.id else: raise AssertionError("Actual value is not a dictionary or web element") if isinstance(b, dict): assert Element.identifier in b, "Expected value does not describe an element" b_id = b[Element.identifier] elif isinstance(b, Element): b_id = b.id else: raise AssertionError("Expected value is not a dictionary or web element") if a_id == b_id: return message = ("Expected element references to describe the same element, " + "but they did not.") # Attempt to provide more information, accounting for possible errors such # as stale element references or not visible elements. try: a_markup = session.execute_script("return arguments[0].outerHTML;", args=(a,)) b_markup = session.execute_script("return arguments[0].outerHTML;", args=(b,)) message += " Actual: `%s`. Expected: `%s`." % (a_markup, b_markup) except WebDriverException: pass raise AssertionError(message) def assert_in_events(session, expected_events): actual_events = session.execute_script("return window.events") for expected_event in expected_events: assert expected_event in actual_events def assert_events_equal(session, expected_events): actual_events = session.execute_script("return window.events") assert actual_events == expected_events def assert_element_has_focus(target_element): session = target_element.session active_element = session.execute_script("return document.activeElement") active_tag = active_element.property("localName") target_tag = target_element.property("localName") assert active_element == target_element, ( "Focussed element is <%s>, not <%s>" % (active_tag, target_tag)) def assert_move_to_coordinates(point, target, events): for e in events: if e["type"] != "mousemove": assert e["pageX"] == point["x"] assert e["pageY"] == point["y"] assert e["target"] == target def assert_png(screenshot): """Test that screenshot is a Base64 encoded PNG file.""" image = decodebytes(screenshot.encode()) mime_type = imghdr.what("", image) assert mime_type == "png", "Expected image to be PNG, but it was {}".format(mime_type)