Update web-platform-tests to revision b704e37ec97fe90b3a3d59c10f78c21907b5b576

This commit is contained in:
WPT Sync Bot 2018-10-30 21:33:00 -04:00
parent cc0ac89e1a
commit 9f516d3717
70 changed files with 1688 additions and 806 deletions

View file

@ -1,234 +1 @@
import copy
import json
import os
import urlparse
import pytest
import webdriver
from tests.support import defaults
from tests.support.helpers import cleanup_session
from tests.support.http_request import HTTPRequest
from tests.support.sync import Poll
_current_session = None
_custom_session = False
def pytest_configure(config):
# register the capabilities marker
config.addinivalue_line("markers",
"capabilities: mark test to use capabilities")
@pytest.fixture
def capabilities():
"""Default capabilities to use for a new WebDriver session."""
return {}
def pytest_generate_tests(metafunc):
if "capabilities" in metafunc.fixturenames:
marker = metafunc.definition.get_closest_marker(name="capabilities")
if marker:
metafunc.parametrize("capabilities", marker.args, ids=None)
@pytest.fixture
def add_event_listeners(session):
"""Register listeners for tracked events on element."""
def add_event_listeners(element, tracked_events):
element.session.execute_script("""
let element = arguments[0];
let trackedEvents = arguments[1];
if (!("events" in window)) {
window.events = [];
}
for (var i = 0; i < trackedEvents.length; i++) {
element.addEventListener(trackedEvents[i], function (event) {
window.events.push(event.type);
});
}
""", args=(element, tracked_events))
return add_event_listeners
@pytest.fixture
def create_cookie(session, url):
"""Create a cookie"""
def create_cookie(name, value, **kwargs):
if kwargs.get("path", None) is not None:
session.url = url(kwargs["path"])
session.set_cookie(name, value, **kwargs)
return session.cookies(name)
return create_cookie
@pytest.fixture
def create_frame(session):
"""Create an `iframe` element in the current browsing context and insert it
into the document. Return a reference to the newly-created element."""
def create_frame():
append = """
var frame = document.createElement('iframe');
document.body.appendChild(frame);
return frame;
"""
return session.execute_script(append)
return create_frame
@pytest.fixture
def create_window(session):
"""Open new window and return the window handle."""
def create_window():
windows_before = session.handles
name = session.execute_script("window.open()")
assert len(session.handles) == len(windows_before) + 1
new_windows = list(set(session.handles) - set(windows_before))
return new_windows.pop()
return create_window
@pytest.fixture
def http(configuration):
return HTTPRequest(configuration["host"], configuration["port"])
@pytest.fixture
def server_config():
return json.loads(os.environ.get("WD_SERVER_CONFIG"))
@pytest.fixture(scope="session")
def configuration():
host = os.environ.get("WD_HOST", defaults.DRIVER_HOST)
port = int(os.environ.get("WD_PORT", str(defaults.DRIVER_PORT)))
capabilities = json.loads(os.environ.get("WD_CAPABILITIES", "{}"))
return {
"host": host,
"port": port,
"capabilities": capabilities
}
@pytest.fixture(scope="function")
def session(capabilities, configuration, request):
"""Create and start a session for a test that does not itself test session creation.
By default the session will stay open after each test, but we always try to start a
new one and assume that if that fails there is already a valid session. This makes it
possible to recover from some errors that might leave the session in a bad state, but
does not demand that we start a new session per test."""
global _current_session
# Update configuration capabilities with custom ones from the
# capabilities fixture, which can be set by tests
caps = copy.deepcopy(configuration["capabilities"])
caps.update(capabilities)
caps = {"alwaysMatch": caps}
# If there is a session with different capabilities active, end it now
if _current_session is not None and (
caps != _current_session.requested_capabilities):
_current_session.end()
_current_session = None
if _current_session is None:
_current_session = webdriver.Session(
configuration["host"],
configuration["port"],
capabilities=caps)
try:
_current_session.start()
except webdriver.error.SessionNotCreatedException:
if not _current_session.session_id:
raise
# Enforce a fixed default window size
_current_session.window.size = defaults.WINDOW_SIZE
yield _current_session
cleanup_session(_current_session)
@pytest.fixture(scope="function")
def current_session():
return _current_session
@pytest.fixture
def url(server_config):
def inner(path, protocol="http", query="", fragment=""):
port = server_config["ports"][protocol][0]
host = "%s:%s" % (server_config["browser_host"], port)
return urlparse.urlunsplit((protocol, host, path, query, fragment))
inner.__name__ = "url"
return inner
@pytest.fixture
def create_dialog(session):
"""Create a dialog (one of "alert", "prompt", or "confirm") and provide a
function to validate that the dialog has been "handled" (either accepted or
dismissed) by returning some value."""
def create_dialog(dialog_type, text=None):
assert dialog_type in ("alert", "confirm", "prompt"), (
"Invalid dialog type: '%s'" % dialog_type)
if text is None:
text = ""
assert isinstance(text, basestring), "`text` parameter must be a string"
# Script completes itself when the user prompt has been opened.
# For prompt() dialogs, add a value for the 'default' argument,
# as some user agents (IE, for example) do not produce consistent
# values for the default.
session.execute_async_script("""
let dialog_type = arguments[0];
let text = arguments[1];
setTimeout(function() {
if (dialog_type == 'prompt') {
window.dialog_return_value = window[dialog_type](text, '');
} else {
window.dialog_return_value = window[dialog_type](text);
}
}, 0);
""", args=(dialog_type, text))
wait = Poll(
session,
timeout=15,
ignored_exceptions=webdriver.NoSuchAlertException,
message="No user prompt with text '{}' detected".format(text))
wait.until(lambda s: s.alert.text == text)
return create_dialog
@pytest.fixture
def closed_window(session, create_window):
original_handle = session.window_handle
new_handle = create_window()
session.window_handle = new_handle
session.close()
assert new_handle not in session.handles, "Unable to close window {}".format(new_handle)
yield new_handle
session.window_handle = original_handle
pytest_plugins = "tests.support.fixtures"

View file

@ -51,7 +51,7 @@ def square(size):
<script>
window.clicks = [];
let div = document.querySelector("div");
div.addEventListener("click", ({{clientX, clientY}}) => window.clicks.push([clientX, clientY]));
div.addEventListener("click", function(e) {{ window.clicks.push([e.clientX, e.clientY]) }});
</script>
""".format(size=size))

View file

@ -1,3 +1,6 @@
import base64
import imghdr
from webdriver import Element, NoSuchAlertException, WebDriverException
@ -189,3 +192,10 @@ def assert_move_to_coordinates(point, target, events):
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 = base64.decodestring(screenshot)
mime_type = imghdr.what("", image)
assert mime_type == "png", "Expected image to be PNG, but it was {}".format(mime_type)

View file

@ -0,0 +1,234 @@
import copy
import json
import os
import urlparse
import pytest
import webdriver
from tests.support import defaults
from tests.support.helpers import cleanup_session
from tests.support.http_request import HTTPRequest
from tests.support.sync import Poll
_current_session = None
_custom_session = False
def pytest_configure(config):
# register the capabilities marker
config.addinivalue_line("markers",
"capabilities: mark test to use capabilities")
@pytest.fixture
def capabilities():
"""Default capabilities to use for a new WebDriver session."""
return {}
def pytest_generate_tests(metafunc):
if "capabilities" in metafunc.fixturenames:
marker = metafunc.definition.get_closest_marker(name="capabilities")
if marker:
metafunc.parametrize("capabilities", marker.args, ids=None)
@pytest.fixture
def add_event_listeners(session):
"""Register listeners for tracked events on element."""
def add_event_listeners(element, tracked_events):
element.session.execute_script("""
let element = arguments[0];
let trackedEvents = arguments[1];
if (!("events" in window)) {
window.events = [];
}
for (var i = 0; i < trackedEvents.length; i++) {
element.addEventListener(trackedEvents[i], function (event) {
window.events.push(event.type);
});
}
""", args=(element, tracked_events))
return add_event_listeners
@pytest.fixture
def create_cookie(session, url):
"""Create a cookie"""
def create_cookie(name, value, **kwargs):
if kwargs.get("path", None) is not None:
session.url = url(kwargs["path"])
session.set_cookie(name, value, **kwargs)
return session.cookies(name)
return create_cookie
@pytest.fixture
def create_frame(session):
"""Create an `iframe` element in the current browsing context and insert it
into the document. Return a reference to the newly-created element."""
def create_frame():
append = """
var frame = document.createElement('iframe');
document.body.appendChild(frame);
return frame;
"""
return session.execute_script(append)
return create_frame
@pytest.fixture
def create_window(session):
"""Open new window and return the window handle."""
def create_window():
windows_before = session.handles
name = session.execute_script("window.open()")
assert len(session.handles) == len(windows_before) + 1
new_windows = list(set(session.handles) - set(windows_before))
return new_windows.pop()
return create_window
@pytest.fixture
def http(configuration):
return HTTPRequest(configuration["host"], configuration["port"])
@pytest.fixture
def server_config():
return json.loads(os.environ.get("WD_SERVER_CONFIG"))
@pytest.fixture(scope="session")
def configuration():
host = os.environ.get("WD_HOST", defaults.DRIVER_HOST)
port = int(os.environ.get("WD_PORT", str(defaults.DRIVER_PORT)))
capabilities = json.loads(os.environ.get("WD_CAPABILITIES", "{}"))
return {
"host": host,
"port": port,
"capabilities": capabilities
}
@pytest.fixture(scope="function")
def session(capabilities, configuration, request):
"""Create and start a session for a test that does not itself test session creation.
By default the session will stay open after each test, but we always try to start a
new one and assume that if that fails there is already a valid session. This makes it
possible to recover from some errors that might leave the session in a bad state, but
does not demand that we start a new session per test."""
global _current_session
# Update configuration capabilities with custom ones from the
# capabilities fixture, which can be set by tests
caps = copy.deepcopy(configuration["capabilities"])
caps.update(capabilities)
caps = {"alwaysMatch": caps}
# If there is a session with different capabilities active, end it now
if _current_session is not None and (
caps != _current_session.requested_capabilities):
_current_session.end()
_current_session = None
if _current_session is None:
_current_session = webdriver.Session(
configuration["host"],
configuration["port"],
capabilities=caps)
try:
_current_session.start()
except webdriver.error.SessionNotCreatedException:
if not _current_session.session_id:
raise
# Enforce a fixed default window size
_current_session.window.size = defaults.WINDOW_SIZE
yield _current_session
cleanup_session(_current_session)
@pytest.fixture(scope="function")
def current_session():
return _current_session
@pytest.fixture
def url(server_config):
def inner(path, protocol="http", query="", fragment=""):
port = server_config["ports"][protocol][0]
host = "%s:%s" % (server_config["browser_host"], port)
return urlparse.urlunsplit((protocol, host, path, query, fragment))
inner.__name__ = "url"
return inner
@pytest.fixture
def create_dialog(session):
"""Create a dialog (one of "alert", "prompt", or "confirm") and provide a
function to validate that the dialog has been "handled" (either accepted or
dismissed) by returning some value."""
def create_dialog(dialog_type, text=None):
assert dialog_type in ("alert", "confirm", "prompt"), (
"Invalid dialog type: '%s'" % dialog_type)
if text is None:
text = ""
assert isinstance(text, basestring), "`text` parameter must be a string"
# Script completes itself when the user prompt has been opened.
# For prompt() dialogs, add a value for the 'default' argument,
# as some user agents (IE, for example) do not produce consistent
# values for the default.
session.execute_async_script("""
let dialog_type = arguments[0];
let text = arguments[1];
setTimeout(function() {
if (dialog_type == 'prompt') {
window.dialog_return_value = window[dialog_type](text, '');
} else {
window.dialog_return_value = window[dialog_type](text);
}
}, 0);
""", args=(dialog_type, text))
wait = Poll(
session,
timeout=15,
ignored_exceptions=webdriver.NoSuchAlertException,
message="No user prompt with text '{}' detected".format(text))
wait.until(lambda s: s.alert.text == text)
return create_dialog
@pytest.fixture
def closed_window(session, create_window):
original_handle = session.window_handle
new_handle = create_window()
session.window_handle = new_handle
session.close()
assert new_handle not in session.handles, "Unable to close window {}".format(new_handle)
yield new_handle
session.window_handle = original_handle

View file

@ -117,3 +117,11 @@ def is_element_in_viewport(session, element):
return !(rect.right < 0 || rect.bottom < 0 ||
rect.left > viewport.width || rect.top > viewport.height)
""", args=(element,))
def document_dimensions(session):
return tuple(session.execute_script("""
let {devicePixelRatio} = window;
let {width, height} = document.documentElement.getBoundingClientRect();
return [width * devicePixelRatio, height * devicePixelRatio];
"""))

View file

@ -0,0 +1,11 @@
import base64
import struct
from tests.support.asserts import assert_png
def png_dimensions(screenshot):
assert_png(screenshot)
image = base64.decodestring(screenshot)
width, height = struct.unpack(">LL", image[16:24])
return int(width), int(height)

View file

@ -2,7 +2,7 @@ import urllib
def inline(doc, doctype="html", mime="text/html;charset=utf-8", protocol="http"):
from ..conftest import server_config, url
from .fixtures import server_config, url
build_url = url(server_config())
if doctype == "html":