Bug 1408509 - Add initial support for web frame and web window to WPT WebDriver client. r?whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Tue, 19 Jun 2018 20:06:02 +0100
changeset 809883 36b7045989e4b3948ccf48e26eff0396c8e065ea
parent 809882 caafce36bbbfe1b3c0035743267790090dc93e9c
child 809884 8c81fbed6dff2dec0458148b1846dcbaf4ea15cc
push id113833
push userbmo:ato@sny.no
push dateSat, 23 Jun 2018 12:17:51 +0000
reviewerswhimboo
bugs1408509
milestone62.0a1
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
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/tools/webdriver/webdriver/__init__.py
testing/web-platform/tests/tools/webdriver/webdriver/client.py
testing/web-platform/tests/tools/webdriver/webdriver/protocol.py
testing/web-platform/tests/tools/webdriver/webdriver/transport.py
--- 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",
@@ -548596,17 +548596,17 @@
    "cd3f0233cc0eaf9295e602ca25aef87fb68df851",
    "support"
   ],
   "css/mediaqueries/support/min-width-tables-001-iframe.html": [
    "29e7fb34c94e2e8411514d1e71d09aca2ddb642e",
    "support"
   ],
   "css/mediaqueries/test_media_queries.html": [
-   "a7d78b13e119f8cd1ffa8812a9af67e59280084d",
+   "cff3585932589f611a7101329d3b5b6ca27820aa",
    "testharness"
   ],
   "css/mediaqueries/viewport-script-dynamic-ref.html": [
    "7d55c513e2de39c9b362fc864233a3008ca6ced2",
    "support"
   ],
   "css/mediaqueries/viewport-script-dynamic.html": [
    "1c2ba1a9116942599804ed29553e85628afadb04",
@@ -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",
--- 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`.