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 810827 7d370b365d635321cbb61f13085f034671fa4118
parent 810826 73b4fe068be41301f0d98b5a3be6ee3a6ae47c12
child 810828 284b67f6da24d3e83d804830eef0c35c7244ce44
push id114124
push userbmo:ato@sny.no
push dateTue, 26 Jun 2018 15:47:34 +0000
reviewerswhimboo
bugs1408509
milestone63.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",
@@ -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`.