Bug 1408509 - Add initial support for web frame and web window to WPT WebDriver client. r?whimboo
This adds marshalling support for web frames and web windows to the
WPT WebDriver client. It can now receive and send complex objects
representing DOM frames and WindowProxies.
The support for these new objects is preliminary as they are not
used in practice yet.
MozReview-Commit-ID: IsEJTCiLEUo
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -523104,17 +523104,17 @@
"ab3c3d205e59df800ba5b4217245b83685521c31",
"reftest"
],
"css/css-scoping/shadow-host-with-before-after.html": [
"99af6e29e69b3131b59dbdc2b0eead52931123c2",
"reftest"
],
"css/css-scoping/shadow-link-rel-stylesheet-no-style-leak.html": [
- "76a54dabd8bd09f7155ab0331e3d17d1a0cae243",
+ "a46be006762a16c2deb3d1d3a760e3c4e348668c",
"reftest"
],
"css/css-scoping/shadow-link-rel-stylesheet.html": [
"07862ce7d2a954988bdbce882869a4c5f097089a",
"reftest"
],
"css/css-scoping/shadow-reassign-dynamic-001.html": [
"11ed4da2e6ce88d8a2b98a8f1c814417ef7770dd",
@@ -559700,17 +559700,17 @@
"d1661ab1734f7d1a252030aeac7e9842a7a4cb3b",
"testharness"
],
"custom-elements/Document-createElement-svg.svg": [
"9af8f2dc7778feeea4fa8e557d7885b10d325dea",
"testharness"
],
"custom-elements/Document-createElement.html": [
- "46e64c9f412fb04582f8ec287e08783ac83cb933",
+ "0edab8da0f16d5d2239ffb21f446c371fe4c76c3",
"testharness"
],
"custom-elements/Document-createElementNS.html": [
"da90b2a1c13cf18fd5cade85dcae2dadef6243c9",
"testharness"
],
"custom-elements/HTMLElement-constructor.html": [
"4dc04a8b026538bddee52586f2df50206abc9334",
@@ -577844,17 +577844,17 @@
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"html/resources/common.js": [
"0f18ee2c61b99893cfe2a3d1ff549b170a8d715d",
"support"
],
"html/scripting/the-noscript-element/non-html-noscript.html": [
- "c0c5453111f29e5a0206f988f4d127ec8ebc2f13",
+ "121760184777008c2ddeb598278216e40b34e367",
"testharness"
],
"html/semantics/.gitkeep": [
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"support"
],
"html/semantics/OWNERS": [
"abd95839027a88741c4d351ff374d81b773c80fa",
@@ -609796,17 +609796,17 @@
"9bea44e9ab6d8452aadc57d5e6d5a1eaa017ac78",
"support"
],
"service-workers/service-worker/resources/pass.txt": [
"27d2303f215d7d1a8f12f0b80b9b56a2cdf6c9a7",
"support"
],
"service-workers/service-worker/resources/performance-timeline-worker.js": [
- "fc275abc58d82c338ff369ba62994bd3d5609a67",
+ "c4c32d5b7ca352a3f18548928570a8a7339fa687",
"support"
],
"service-workers/service-worker/resources/postmessage-blob-url.js": [
"728244e7f0b717aec29c3057bde7a6ba12768587",
"support"
],
"service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js": [
"11d46afb4cf17c8dcd9b49cda4e07e110a42a36d",
--- a/testing/web-platform/tests/tools/webdriver/webdriver/__init__.py
+++ b/testing/web-platform/tests/tools/webdriver/webdriver/__init__.py
@@ -1,9 +1,16 @@
-from client import Cookies, Element, Find, Session, Timeouts, Window
+from client import (
+ Cookies,
+ Element,
+ Find,
+ Frame,
+ Session,
+ Timeouts,
+ Window)
from error import (
ElementNotSelectableException,
ElementNotVisibleException,
InvalidArgumentException,
InvalidCookieDomainException,
InvalidElementCoordinatesException,
InvalidElementStateException,
InvalidSelectorException,
--- a/testing/web-platform/tests/tools/webdriver/webdriver/client.py
+++ b/testing/web-platform/tests/tools/webdriver/webdriver/client.py
@@ -229,16 +229,18 @@ class Actions(object):
"""Return an empty ActionSequence of the designated type.
See ActionSequence for parameter list.
"""
return ActionSequence(self.session, *args, **kwargs)
class Window(object):
+ identifier = "window-fcc6-11e5-b4f8-330a88ab9d7f"
+
def __init__(self, session):
self.session = session
@property
@command
def rect(self):
return self.session.send_session_command("GET", "window/rect")
@@ -279,16 +281,33 @@ class Window(object):
@command
def minimize(self):
return self.session.send_session_command("POST", "window/minimize")
@command
def fullscreen(self):
return self.session.send_session_command("POST", "window/fullscreen")
+ @classmethod
+ def from_json(cls, json, session):
+ uuid = json[Window.identifier]
+ return cls(uuid, session)
+
+
+class Frame(object):
+ identifier = "frame-075b-4da1-b6ba-e579c2d3230a"
+
+ def __init__(self, session):
+ self.session = session
+
+ @classmethod
+ def from_json(cls, json, session):
+ uuid = json[Frame.identifier]
+ return cls(uuid, session)
+
class Find(object):
def __init__(self, session):
self.session = session
@command
def css(self, selector, all=True):
return self._find_element("css selector", selector, all)
--- a/testing/web-platform/tests/tools/webdriver/webdriver/protocol.py
+++ b/testing/web-platform/tests/tools/webdriver/webdriver/protocol.py
@@ -11,25 +11,33 @@ class Encoder(json.JSONEncoder):
kwargs.pop("session")
super(Encoder, self).__init__(*args, **kwargs)
def default(self, obj):
if isinstance(obj, (list, tuple)):
return [self.default(x) for x in obj]
elif isinstance(obj, webdriver.Element):
return {webdriver.Element.identifier: obj.id}
+ elif isinstance(obj, webdriver.Frame):
+ return {webdriver.Frame.identifier: obj.id}
+ elif isinstance(obj, webdriver.Window):
+ return {webdriver.Frame.identifier: obj.id}
return super(Encoder, self).default(obj)
class Decoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
self.session = kwargs.pop("session")
super(Decoder, self).__init__(
object_hook=self.object_hook, *args, **kwargs)
def object_hook(self, payload):
if isinstance(payload, (list, tuple)):
return [self.object_hook(x) for x in payload]
elif isinstance(payload, dict) and webdriver.Element.identifier in payload:
return webdriver.Element.from_json(payload, self.session)
+ elif isinstance(payload, dict) and webdriver.Frame.identifier in payload:
+ return webdriver.Frame.from_json(payload, self.session)
+ elif isinstance(payload, dict) and webdriver.Window.identifier in payload:
+ return webdriver.Window.from_json(payload, self.session)
elif isinstance(payload, dict):
return {k: self.object_hook(v) for k, v in payload.iteritems()}
return payload
--- a/testing/web-platform/tests/tools/webdriver/webdriver/transport.py
+++ b/testing/web-platform/tests/tools/webdriver/webdriver/transport.py
@@ -45,18 +45,19 @@ class Response(object):
return cls(http_response.status, body)
class HTTPWireProtocol(object):
"""
Transports messages (commands and responses) over the WebDriver
wire protocol.
- Complex objects, such as ``webdriver.Element``, are by default
- not marshaled to enable use of `session.transport.send` in WPT tests::
+ Complex objects, such as ``webdriver.Element``, ``webdriver.Frame``,
+ and ``webdriver.Window`` are by default not marshaled to enable
+ use of `session.transport.send` in WPT tests::
session = webdriver.Session("127.0.0.1", 4444)
response = transport.send("GET", "element/active", None)
print response.body["value"]
# => {u'element-6066-11e4-a52e-4f735466cecf': u'<uuid>'}
Automatic marshaling is provided by ``webdriver.protocol.Encoder``
and ``webdriver.protocol.Decoder``, which can be passed in to
@@ -95,18 +96,19 @@ class HTTPWireProtocol(object):
encoder=json.JSONEncoder,
decoder=json.JSONDecoder,
**codec_kwargs):
"""
Send a command to the remote.
The request `body` must be JSON serialisable unless a
custom `encoder` has been provided. This means complex
- objects such as ``webdriver.Element`` are not automatically
- made into JSON. This behaviour is, however, provided by
+ objects such as ``webdriver.Element``, ``webdriver.Frame``,
+ and `webdriver.Window`` are not automatically made
+ into JSON. This behaviour is, however, provided by
``webdriver.protocol.Encoder``, should you want it.
Similarly, the response body is returned au natural
as plain JSON unless a `decoder` that converts web
element references to ``webdriver.Element`` is provided.
Use ``webdriver.protocol.Decoder`` to achieve this behaviour.
:param method: `GET`, `POST`, or `DELETE`.