Bug 1225032 - Update web-platform-tests to revision a5f15d6bdbeeec010465dc906e542873d64797ec, a=testonly
authorJames Graham <james@hoppipolla.co.uk>
Wed, 11 Nov 2015 17:34:11 +0000
changeset 309234 c80f695917a704b291ef049872ec7e482d5a2ee8
parent 309233 7e3fe4f93eab6dae1d493c9246eee1444ac402d0
child 309235 2331a8a140bd0b96c8335ad60e58cc9a3f50e7b5
push id7579
push usercliu@mozilla.com
push dateTue, 17 Nov 2015 02:28:56 +0000
reviewerstestonly
bugs1225032
milestone45.0a1
Bug 1225032 - Update web-platform-tests to revision a5f15d6bdbeeec010465dc906e542873d64797ec, a=testonly
testing/web-platform/meta/MANIFEST.json
testing/web-platform/meta/mozilla-sync
testing/web-platform/tests/.gitignore
testing/web-platform/tests/IndexedDB/idbindex_getAll.html
testing/web-platform/tests/IndexedDB/idbindex_getAllKeys.html
testing/web-platform/tests/IndexedDB/idbobjectstore_getAll.html
testing/web-platform/tests/IndexedDB/idbobjectstore_getAllKeys.html
testing/web-platform/tests/IndexedDB/idbobjectstore_openKeyCursor.htm
testing/web-platform/tests/IndexedDB/idbtransaction_objectStoreNames.html
testing/web-platform/tests/IndexedDB/support.js
testing/web-platform/tests/README.md
testing/web-platform/tests/app-uri/appURI_test.html
testing/web-platform/tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html
testing/web-platform/tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html.sub.headers
testing/web-platform/tests/dom/collections/domstringmap-supported-property-names.html
testing/web-platform/tests/dom/collections/namednodemap-supported-property-names.html
testing/web-platform/tests/dom/collections/storage-supported-property-names.html
testing/web-platform/tests/dom/nodes/Document-createElement-namespace.html
testing/web-platform/tests/dom/nodes/Node-lookupNamespaceURI.html
testing/web-platform/tests/dom/nodes/getElementsByClassName-10.xml
testing/web-platform/tests/dom/nodes/getElementsByClassName-11.xml
testing/web-platform/tests/dom/nodes/selectors.js
testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/navigation-within-beforeunload.html
testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/unload/008.html
testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/unload/009.html
testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html
testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/testcase3.html
testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified-01.html
testing/web-platform/tests/html/dom/elements-embedded.js
testing/web-platform/tests/html/dom/elements-text.js
testing/web-platform/tests/html/dom/interfaces.html
testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html
testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html
testing/web-platform/tests/html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/script-IDL-event-htmlfor.html
testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html
testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align.html
testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js
testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-recurse.html
testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html
testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html
testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/cellIndex.html
testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/deleteRow.html
testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/insertRow.html
testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/deleteCell.html
testing/web-platform/tests/html/webappapis/animation-frames/callback-multicalls.html
testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-body-window.html
testing/web-platform/tests/lint.whitelist
testing/web-platform/tests/pointerevents/pointerevent_capture_suppressing_mouse-manual.html
testing/web-platform/tests/resources/testharness.js
testing/web-platform/tests/subresource-integrity/crossorigin-creds-script.js.sub.headers
testing/web-platform/tests/subresource-integrity/crossorigin-creds-style.css.sub.headers
testing/web-platform/tests/subresource-integrity/subresource-integrity.html
testing/web-platform/tests/subresource-integrity/subresource-integrity.sub.html
testing/web-platform/tests/tools/manifest/manifest.py
testing/web-platform/tests/tools/manifest/sourcefile.py
testing/web-platform/tests/tools/webdriver/webdriver/driver.py
testing/web-platform/tests/url/interfaces.html
testing/web-platform/tests/webdriver/base_test.py
testing/web-platform/tests/webdriver/command_contexts/__init__.py
testing/web-platform/tests/webdriver/command_contexts/open_and_close_window_test.py
testing/web-platform/tests/webdriver/command_contexts/res/first-page.html
testing/web-platform/tests/webdriver/command_contexts/res/other-page.html
testing/web-platform/tests/webdriver/command_contexts/window_handle_test.py
testing/web-platform/tests/webdriver/command_contexts/window_size_test.py
testing/web-platform/tests/webdriver/cookie/cookie_test.py
testing/web-platform/tests/webdriver/element_location/element_location_test.py
testing/web-platform/tests/webdriver/element_state/method_test.py
testing/web-platform/tests/webdriver/element_state/properties.py
testing/web-platform/tests/webdriver/element_state/res/element-hidden-by-z-index.html
testing/web-platform/tests/webdriver/element_state/res/element-moved-behind-other-element-by-transform.html
testing/web-platform/tests/webdriver/element_state/res/element-partially-hidden-by-other-element.html
testing/web-platform/tests/webdriver/element_state/res/element-selected.html
testing/web-platform/tests/webdriver/element_state/res/element-with-same-color-as-parent-background.html
testing/web-platform/tests/webdriver/element_state/res/elements_text.html
testing/web-platform/tests/webdriver/element_state/res/get-element-attribute-extended.html
testing/web-platform/tests/webdriver/element_state/selected_test.py
testing/web-platform/tests/webdriver/element_state/visibility_test.py
testing/web-platform/tests/webdriver/javascript/execute_script_test.py
testing/web-platform/tests/webdriver/modal/alerts_quit_test.py
testing/web-platform/tests/webdriver/modal/alerts_test.py
testing/web-platform/tests/webdriver/navigation/auth_tests.py
testing/web-platform/tests/webdriver/navigation/forward.py
testing/web-platform/tests/webdriver/navigation/forwardToNothing.py
testing/web-platform/tests/webdriver/navigation/get_from_http_test.py
testing/web-platform/tests/webdriver/navigation/invalid_cert_test.py
testing/web-platform/tests/webdriver/navigation/refresh_page.py
testing/web-platform/tests/webdriver/runtests_p0.py
testing/web-platform/tests/webdriver/screenshot/__init__.py
testing/web-platform/tests/webdriver/screenshot/res/screenshot.html
testing/web-platform/tests/webdriver/screenshot/take_screenshot.py
testing/web-platform/tests/webdriver/timeouts/implicit_waits_tests.py
testing/web-platform/tests/webdriver/timeouts/page_load_timeouts_tests.py
testing/web-platform/tests/webdriver/user_input/clear_test.py
testing/web-platform/tests/webdriver/user_input/click_test.py
testing/web-platform/tests/webdriver/user_input/res/click.html
testing/web-platform/tests/webdriver/user_input/res/text-form-landing.html
testing/web-platform/tests/webdriver/user_input/res/text-form.html
testing/web-platform/tests/webdriver/user_input/sendkeys_test.py
testing/web-platform/tests/webdriver/webdriver.cfg
testing/web-platform/tests/webdriver/windows/__init__.py
testing/web-platform/tests/webdriver/windows/res/win1.html
testing/web-platform/tests/webdriver/windows/res/win2.html
testing/web-platform/tests/webdriver/windows/res/win3.html
testing/web-platform/tests/webdriver/windows/res/win4.html
testing/web-platform/tests/webdriver/windows/res/win5.html
testing/web-platform/tests/webdriver/windows/tabbing.py
testing/web-platform/tests/webdriver/windows/window_manipulation.py
testing/web-platform/tests/webstorage/eventTestHarness.js
testing/web-platform/tests/webstorage/event_basic.js
testing/web-platform/tests/webstorage/event_body_attribute.js
testing/web-platform/tests/webstorage/event_case_sensitive.js
testing/web-platform/tests/webstorage/event_constructor_eventinit.html
testing/web-platform/tests/webstorage/event_local_key.html
testing/web-platform/tests/webstorage/event_local_newvalue.html
testing/web-platform/tests/webstorage/event_local_oldvalue.html
testing/web-platform/tests/webstorage/event_local_removeitem.html
testing/web-platform/tests/webstorage/event_local_storagearea.html
testing/web-platform/tests/webstorage/event_local_storageeventinit.html
testing/web-platform/tests/webstorage/event_local_url.html
testing/web-platform/tests/webstorage/event_session_key.html
testing/web-platform/tests/webstorage/event_session_newvalue.html
testing/web-platform/tests/webstorage/event_session_oldvalue.html
testing/web-platform/tests/webstorage/event_session_removeitem.html
testing/web-platform/tests/webstorage/event_session_storagearea.html
testing/web-platform/tests/webstorage/event_session_storageeventinit.html
testing/web-platform/tests/webstorage/event_session_url.html
testing/web-platform/tests/webstorage/event_setattribute.js
testing/web-platform/tests/webstorage/idlharness.html
testing/web-platform/tests/webstorage/resources/local_set_item_remove_iframe.html
testing/web-platform/tests/webstorage/resources/session_set_item_remove_iframe.html
testing/web-platform/tests/webstorage/storage_supported_property_names.html
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -11157,16 +11157,24 @@
         "path": "IndexedDB/idbindex_get6.htm",
         "url": "/IndexedDB/idbindex_get6.htm"
       },
       {
         "path": "IndexedDB/idbindex_get7.htm",
         "url": "/IndexedDB/idbindex_get7.htm"
       },
       {
+        "path": "IndexedDB/idbindex_getAll.html",
+        "url": "/IndexedDB/idbindex_getAll.html"
+      },
+      {
+        "path": "IndexedDB/idbindex_getAllKeys.html",
+        "url": "/IndexedDB/idbindex_getAllKeys.html"
+      },
+      {
         "path": "IndexedDB/idbindex_getKey.htm",
         "url": "/IndexedDB/idbindex_getKey.htm"
       },
       {
         "path": "IndexedDB/idbindex_getKey2.htm",
         "url": "/IndexedDB/idbindex_getKey2.htm"
       },
       {
@@ -11421,28 +11429,40 @@
         "path": "IndexedDB/idbobjectstore_get6.htm",
         "url": "/IndexedDB/idbobjectstore_get6.htm"
       },
       {
         "path": "IndexedDB/idbobjectstore_get7.htm",
         "url": "/IndexedDB/idbobjectstore_get7.htm"
       },
       {
+        "path": "IndexedDB/idbobjectstore_getAll.html",
+        "url": "/IndexedDB/idbobjectstore_getAll.html"
+      },
+      {
+        "path": "IndexedDB/idbobjectstore_getAllKeys.html",
+        "url": "/IndexedDB/idbobjectstore_getAllKeys.html"
+      },
+      {
         "path": "IndexedDB/idbobjectstore_index.htm",
         "url": "/IndexedDB/idbobjectstore_index.htm"
       },
       {
         "path": "IndexedDB/idbobjectstore_openCursor.htm",
         "url": "/IndexedDB/idbobjectstore_openCursor.htm"
       },
       {
         "path": "IndexedDB/idbobjectstore_openCursor_invalid.htm",
         "url": "/IndexedDB/idbobjectstore_openCursor_invalid.htm"
       },
       {
+        "path": "IndexedDB/idbobjectstore_openKeyCursor.htm",
+        "url": "/IndexedDB/idbobjectstore_openKeyCursor.htm"
+      },
+      {
         "path": "IndexedDB/idbobjectstore_put.htm",
         "url": "/IndexedDB/idbobjectstore_put.htm"
       },
       {
         "path": "IndexedDB/idbobjectstore_put10.htm",
         "url": "/IndexedDB/idbobjectstore_put10.htm"
       },
       {
@@ -11509,16 +11529,20 @@
         "path": "IndexedDB/idbtransaction.htm",
         "url": "/IndexedDB/idbtransaction.htm"
       },
       {
         "path": "IndexedDB/idbtransaction_abort.htm",
         "url": "/IndexedDB/idbtransaction_abort.htm"
       },
       {
+        "path": "IndexedDB/idbtransaction_objectStoreNames.html",
+        "url": "/IndexedDB/idbtransaction_objectStoreNames.html"
+      },
+      {
         "path": "IndexedDB/idbversionchangeevent.htm",
         "url": "/IndexedDB/idbversionchangeevent.htm"
       },
       {
         "path": "IndexedDB/index_sort_order.htm",
         "url": "/IndexedDB/index_sort_order.htm"
       },
       {
@@ -13277,18 +13301,22 @@
         "path": "dom/collections/HTMLCollection-empty-name.html",
         "url": "/dom/collections/HTMLCollection-empty-name.html"
       },
       {
         "path": "dom/collections/HTMLCollection-supported-property-names.html",
         "url": "/dom/collections/HTMLCollection-supported-property-names.html"
       },
       {
-        "path": "dom/collections/storage-supported-property-names.html",
-        "url": "/dom/collections/storage-supported-property-names.html"
+        "path": "dom/collections/domstringmap-supported-property-names.html",
+        "url": "/dom/collections/domstringmap-supported-property-names.html"
+      },
+      {
+        "path": "dom/collections/namednodemap-supported-property-names.html",
+        "url": "/dom/collections/namednodemap-supported-property-names.html"
       },
       {
         "path": "dom/events/Event-constants.html",
         "url": "/dom/events/Event-constants.html"
       },
       {
         "path": "dom/events/Event-constructors.html",
         "url": "/dom/events/Event-constructors.html"
@@ -13705,16 +13733,20 @@
         "path": "dom/nodes/Element-firstElementChild.xhtml",
         "url": "/dom/nodes/Element-firstElementChild.xhtml"
       },
       {
         "path": "dom/nodes/Element-getElementsByClassName.html",
         "url": "/dom/nodes/Element-getElementsByClassName.html"
       },
       {
+        "path": "dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html",
+        "url": "/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html"
+      },
+      {
         "path": "dom/nodes/Element-getElementsByTagName.html",
         "url": "/dom/nodes/Element-getElementsByTagName.html"
       },
       {
         "path": "dom/nodes/Element-getElementsByTagNameNS.html",
         "url": "/dom/nodes/Element-getElementsByTagNameNS.html"
       },
       {
@@ -13833,16 +13865,20 @@
         "path": "dom/nodes/Node-constants.html",
         "url": "/dom/nodes/Node-constants.html"
       },
       {
         "path": "dom/nodes/Node-contains.html",
         "url": "/dom/nodes/Node-contains.html"
       },
       {
+        "path": "dom/nodes/Node-contains.xml",
+        "url": "/dom/nodes/Node-contains.xml"
+      },
+      {
         "path": "dom/nodes/Node-insertBefore.html",
         "url": "/dom/nodes/Node-insertBefore.html"
       },
       {
         "path": "dom/nodes/Node-isEqualNode.xhtml",
         "url": "/dom/nodes/Node-isEqualNode.xhtml"
       },
       {
@@ -13969,16 +14005,24 @@
         "path": "dom/nodes/getElementsByClassName-08.htm",
         "url": "/dom/nodes/getElementsByClassName-08.htm"
       },
       {
         "path": "dom/nodes/getElementsByClassName-09.htm",
         "url": "/dom/nodes/getElementsByClassName-09.htm"
       },
       {
+        "path": "dom/nodes/getElementsByClassName-10.xml",
+        "url": "/dom/nodes/getElementsByClassName-10.xml"
+      },
+      {
+        "path": "dom/nodes/getElementsByClassName-11.xml",
+        "url": "/dom/nodes/getElementsByClassName-11.xml"
+      },
+      {
         "path": "dom/nodes/getElementsByClassName-12.htm",
         "url": "/dom/nodes/getElementsByClassName-12.htm"
       },
       {
         "path": "dom/nodes/getElementsByClassName-13.htm",
         "url": "/dom/nodes/getElementsByClassName-13.htm"
       },
       {
@@ -17905,16 +17949,20 @@
         "path": "html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html",
         "url": "/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html"
       },
       {
         "path": "html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html",
         "url": "/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html"
       },
       {
+        "path": "html/semantics/forms/the-select-element/select-ask-for-reset.html",
+        "url": "/html/semantics/forms/the-select-element/select-ask-for-reset.html"
+      },
+      {
         "path": "html/semantics/forms/the-select-element/select-named-getter.html",
         "url": "/html/semantics/forms/the-select-element/select-named-getter.html"
       },
       {
         "path": "html/semantics/forms/the-select-element/select-remove.html",
         "url": "/html/semantics/forms/the-select-element/select-remove.html"
       },
       {
@@ -18469,16 +18517,20 @@
         "path": "html/webappapis/animation-frames/callback-exception.html",
         "url": "/html/webappapis/animation-frames/callback-exception.html"
       },
       {
         "path": "html/webappapis/animation-frames/callback-invoked.html",
         "url": "/html/webappapis/animation-frames/callback-invoked.html"
       },
       {
+        "path": "html/webappapis/animation-frames/callback-multicalls.html",
+        "url": "/html/webappapis/animation-frames/callback-multicalls.html"
+      },
+      {
         "path": "html/webappapis/animation-frames/cancel-invoked.html",
         "url": "/html/webappapis/animation-frames/cancel-invoked.html"
       },
       {
         "path": "html/webappapis/animation-frames/idlharness.html",
         "url": "/html/webappapis/animation-frames/idlharness.html"
       },
       {
@@ -18493,16 +18545,20 @@
         "path": "html/webappapis/scripting/event-loops/task_microtask_ordering.html",
         "url": "/html/webappapis/scripting/event-loops/task_microtask_ordering.html"
       },
       {
         "path": "html/webappapis/scripting/events/body-onload.html",
         "url": "/html/webappapis/scripting/events/body-onload.html"
       },
       {
+        "path": "html/webappapis/scripting/events/event-handler-attributes-body-window.html",
+        "url": "/html/webappapis/scripting/events/event-handler-attributes-body-window.html"
+      },
+      {
         "path": "html/webappapis/scripting/events/event-handler-javascript.html",
         "url": "/html/webappapis/scripting/events/event-handler-javascript.html"
       },
       {
         "path": "html/webappapis/scripting/events/event-handler-spec-example.html",
         "url": "/html/webappapis/scripting/events/event-handler-spec-example.html"
       },
       {
@@ -26137,20 +26193,16 @@
         "path": "shadow-dom/untriaged/user-interaction/ranges-and-selections/test-001.html",
         "url": "/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-001.html"
       },
       {
         "path": "shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html",
         "url": "/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html"
       },
       {
-        "path": "subresource-integrity/subresource-integrity.html",
-        "url": "/subresource-integrity/subresource-integrity.html"
-      },
-      {
         "path": "touch-events/create-touch-touchlist.html",
         "url": "/touch-events/create-touch-touchlist.html"
       },
       {
         "path": "typedarrays/ArrayBuffer_constructor.html",
         "url": "/typedarrays/ArrayBuffer_constructor.html"
       },
       {
@@ -27613,16 +27665,20 @@
         "path": "webstorage/storage_setitem.html",
         "url": "/webstorage/storage_setitem.html"
       },
       {
         "path": "webstorage/storage_string_conversion.html",
         "url": "/webstorage/storage_string_conversion.html"
       },
       {
+        "path": "webstorage/storage_supported_property_names.html",
+        "url": "/webstorage/storage_supported_property_names.html"
+      },
+      {
         "path": "webvtt/interfaces.html",
         "url": "/webvtt/interfaces.html"
       },
       {
         "path": "webvtt/webvtt-api-for-browsers/vttcue-interface/align.html",
         "url": "/webvtt/webvtt-api-for-browsers/vttcue-interface/align.html"
       },
       {
@@ -29735,28 +29791,43 @@
       {
         "path": "webstorage/storage_session_setitem_quotaexceedederr.html",
         "timeout": "long",
         "url": "/webstorage/storage_session_setitem_quotaexceedederr.html"
       }
     ],
     "wdspec": [
       {
+        "path": "webdriver/command_contexts/open_and_close_window_test.py"
+      },
+      {
+        "path": "webdriver/command_contexts/window_handle_test.py"
+      },
+      {
+        "path": "webdriver/command_contexts/window_size_test.py"
+      },
+      {
         "path": "webdriver/cookie/cookie_test.py"
       },
       {
         "path": "webdriver/ecmascript/ecmascript_test.py"
       },
       {
         "path": "webdriver/element_location/element_location_test.py"
       },
       {
         "path": "webdriver/element_state/method_test.py"
       },
       {
+        "path": "webdriver/element_state/properties.py"
+      },
+      {
+        "path": "webdriver/element_state/selected_test.py"
+      },
+      {
         "path": "webdriver/element_state/visibility_test.py"
       },
       {
         "path": "webdriver/javascript/execute_script_test.py"
       },
       {
         "path": "webdriver/modal/alerts_quit_test.py"
       },
@@ -29777,38 +29848,47 @@
       },
       {
         "path": "webdriver/navigation/invalid_cert_test.py"
       },
       {
         "path": "webdriver/navigation/refresh-page.py"
       },
       {
+        "path": "webdriver/navigation/refresh_page.py"
+      },
+      {
+        "path": "webdriver/screenshot/take_screenshot.py"
+      },
+      {
         "path": "webdriver/timeouts/implicit_waits_tests.py"
       },
       {
         "path": "webdriver/timeouts/page_load_timeouts_tests.py"
       },
       {
         "path": "webdriver/user_input/clear_test.py"
+      },
+      {
+        "path": "webdriver/user_input/click_test.py"
+      },
+      {
+        "path": "webdriver/user_input/sendkeys_test.py"
+      },
+      {
+        "path": "webdriver/windows/tabbing.py"
+      },
+      {
+        "path": "webdriver/windows/window_manipulation.py"
       }
     ]
   },
   "local_changes": {
     "deleted": [],
-    "items": {
-      "testharness": {
-        "dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html": [
-          {
-            "path": "dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html",
-            "url": "/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html"
-          }
-        ]
-      }
-    },
+    "items": {},
     "reftest_nodes": {}
   },
   "reftest_nodes": {
     "2dcontext/building-paths/canvas_complexshapes_arcto_001.htm": [
       {
         "path": "2dcontext/building-paths/canvas_complexshapes_arcto_001.htm",
         "references": [
           [
@@ -31530,16 +31610,28 @@
           [
             "/html/rendering/bindings/the-textarea-element-0/textarea-ref.html",
             "=="
           ]
         ],
         "url": "/html/rendering/bindings/the-textarea-element-0/rows-zero.html"
       }
     ],
+    "html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html": [
+      {
+        "path": "html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html",
+        "references": [
+          [
+            "/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html",
+            "=="
+          ]
+        ],
+        "url": "/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html"
+      }
+    ],
     "html/rendering/non-replaced-elements/flow-content-0/figure.html": [
       {
         "path": "html/rendering/non-replaced-elements/flow-content-0/figure.html",
         "references": [
           [
             "/html/rendering/non-replaced-elements/flow-content-0/figure-ref.html",
             "=="
           ]
@@ -35323,12 +35415,12 @@
             "/webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped-ref.html",
             "=="
           ]
         ],
         "url": "/webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html"
       }
     ]
   },
-  "rev": "886dea2c3dbb79925360319a6a0f662ce196ab3c",
+  "rev": "a5f15d6bdbeeec010465dc906e542873d64797ec",
   "url_base": "/",
   "version": 2
-}
\ No newline at end of file
+}
--- a/testing/web-platform/meta/mozilla-sync
+++ b/testing/web-platform/meta/mozilla-sync
@@ -1,1 +1,1 @@
-0b6a123899da549977c73b35cf42d69daa94d823
\ No newline at end of file
+1e125923b6586c58492f54dc396e6cbfd09c6ae2
\ No newline at end of file
--- a/testing/web-platform/tests/.gitignore
+++ b/testing/web-platform/tests/.gitignore
@@ -4,8 +4,9 @@
 *~
 MANIFEST.json
 \#*
 _certs
 config.json
 node_modules
 scratch
 testharness_runner.html
+webdriver/.idea
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/idbindex_getAll.html
@@ -0,0 +1,232 @@
+<!DOCTYPE html>
+<title>IndexedDB: Test IDBIndex.getAll.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({explicit_done: true});
+
+var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
+var ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
+
+function doSetup(dbName, dbVersion, onsuccess) {
+  var delete_request = indexedDB.deleteDatabase(dbName);
+  delete_request.onerror = function() {
+    assert_unreached('deleteDatabase should not fail');
+  };
+  delete_request.onsuccess = function(e) {
+    var req = indexedDB.open(dbName, dbVersion);
+    req.onsuccess = onsuccess;
+    req.onerror = function() {
+      assert_unreached('open should not fail');
+    };
+    req.onupgradeneeded = function(evt) {
+      var connection = evt.target.result;
+
+      var store = connection.createObjectStore('generated',
+            {autoIncrement: true, keyPath: 'id'});
+      var index = store.createIndex('test_idx', 'upper');
+      alphabet.forEach(function(letter) {
+        store.put({ch: letter, upper: letter.toUpperCase()});
+      });
+
+      store = connection.createObjectStore('out-of-line', null);
+      index = store.createIndex('test_idx', 'upper');
+      alphabet.forEach(function(letter) {
+        store.put({ch: letter, upper: letter.toUpperCase()}, letter);
+      });
+
+      store = connection.createObjectStore('out-of-line-not-unique', null);
+      index = store.createIndex('test_idx', 'half');
+      alphabet.forEach(function(letter) {
+        if (letter <= 'm')
+          store.put({ch: letter, half: 'first'}, letter);
+        else
+          store.put({ch: letter, half: 'second'}, letter);
+      });
+
+      store = connection.createObjectStore('out-of-line-multi', null);
+      index = store.createIndex('test_idx', 'attribs', {multiEntry: true});
+      alphabet.forEach(function(letter) {
+        attrs = [];
+        if (['a', 'e', 'i', 'o', 'u'].indexOf(letter) != -1)
+          attrs.push('vowel');
+        else
+          attrs.push('consonant');
+        if (letter == 'a')
+          attrs.push('first');
+        if (letter == 'z')
+          attrs.push('last');
+        store.put({ch: letter, attribs: attrs}, letter);
+      });
+
+      store = connection.createObjectStore('empty', null);
+      index = store.createIndex('test_idx', 'upper');
+    };
+  };
+}
+
+function createGetAllRequest(t, storeName, connection, range, maxCount) {
+    var transaction = connection.transaction(storeName, 'readonly');
+    var store = transaction.objectStore(storeName);
+    var index = store.index('test_idx');
+    var req = index.getAll(range, maxCount);
+    req.onerror = t.unreached_func('getAll request should succeed');
+    return req;
+}
+
+doSetup(location.pathname + '-IDBIndex.getAll', 1, function(evt) {
+    var connection = evt.target.result;
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection, 'C');
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), ['c']);
+          assert_array_equals(data.map(function(e) { return e.upper; }), ['C']);
+          t.done();
+      });
+    }, 'Single item get');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'empty', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAll() on empty object store should return an empty array');
+          t.done();
+      });
+    }, 'Empty object store');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), alphabet);
+          assert_array_equals(data.map(function(e) { return e.upper; }), ALPHABET);
+          t.done();
+      });
+    }, 'Get all keys');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection, undefined,
+                                    10);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), 'abcdefghij'.split(''));
+          assert_array_equals(data.map(function(e) { return e.upper; }), 'ABCDEFGHIJ'.split(''));
+          t.done();
+      });
+    }, 'maxCount=10');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('G', 'M'));
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_array_equals(data.map(function(e) { return e.ch; }), 'ghijklm'.split(''));
+          assert_array_equals(data.map(function(e) { return e.upper; }), 'GHIJKLM'.split(''));
+          t.done();
+      });
+    }, 'Get bound range');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('G', 'M'), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), 'ghi'.split(''));
+          assert_array_equals(data.map(function(e) { return e.upper; }), 'GHI'.split(''));
+          t.done();
+      });
+    }, 'Get bound range with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+          IDBKeyRange.bound('G', 'K', false, true));
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), 'ghij'.split(''));
+          assert_array_equals(data.map(function(e) { return e.upper; }), 'GHIJ'.split(''));
+          t.done();
+      });
+    }, 'Get upper excluded');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+          IDBKeyRange.bound('G', 'K', true, false));
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), 'hijk'.split(''));
+          assert_array_equals(data.map(function(e) { return e.upper; }), 'HIJK'.split(''));
+          t.done();
+      });
+    }, 'Get lower excluded');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'generated',
+          connection, IDBKeyRange.bound(4, 15), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_true(Array.isArray(data));
+          assert_equals(data.length, 0);
+          t.done();
+      });
+    }, 'Get bound range (generated) with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line',
+          connection, "Doesn't exist");
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAll() using a nonexistent key should return an empty array');
+          t.done();
+      req.onerror = t.unreached_func('getAll request should succeed');
+      });
+    }, 'Non existent key');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+          undefined, 0);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), alphabet);
+          assert_array_equals(data.map(function(e) { return e.upper; }), ALPHABET);
+          t.done();
+      });
+    }, 'maxCount=0');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line-not-unique', connection,
+                                    'first');
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), 'abcdefghijklm'.split(''));
+          assert_true(data.every(function(e) { return e.half === 'first'; }));
+          t.done();
+      });
+    }, 'Retrieve multiEntry key');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line-multi', connection,
+                                    'vowel');
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_class_string(data, 'Array', 'result should be an array');
+          assert_array_equals(data.map(function(e) { return e.ch; }), ['a', 'e', 'i', 'o', 'u']);
+          assert_array_equals(data[0].attribs, ['vowel', 'first']);
+          assert_true(data.every(function(e) { return e.attribs[0] === 'vowel'; }));
+          t.done();
+      });
+    }, 'Retrieve one key multiple values');
+
+    // Explicit done needed in case async_test body fails synchronously.
+    done();
+});
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/idbindex_getAllKeys.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<title>IndexedDB: Test IDBIndex.getAllKeys.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({explicit_done: true});
+
+var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
+
+function doSetup(dbName, dbVersion, onsuccess) {
+  var delete_request = indexedDB.deleteDatabase(dbName);
+  delete_request.onerror = function() {
+    assert_unreached('deleteDatabase should not fail');
+  };
+  delete_request.onsuccess = function(e) {
+    var req = indexedDB.open(dbName, dbVersion);
+    req.onsuccess = onsuccess;
+    req.onerror = function() {
+      assert_unreached('open should not fail');
+    };
+    req.onupgradeneeded = function(evt) {
+      var connection = evt.target.result;
+
+      var store = connection.createObjectStore('generated',
+            {autoIncrement: true, keyPath: 'id'});
+      var index = store.createIndex('test_idx', 'upper');
+      alphabet.forEach(function(letter) {
+        store.put({ch: letter, upper: letter.toUpperCase()});
+      });
+
+      store = connection.createObjectStore('out-of-line', null);
+      index = store.createIndex('test_idx', 'upper');
+      alphabet.forEach(function(letter) {
+        store.put({ch: letter, upper: letter.toUpperCase()}, letter);
+      });
+
+      store = connection.createObjectStore('out-of-line-multi', null);
+      index = store.createIndex('test_idx', 'attribs', {multiEntry: true});
+      alphabet.forEach(function(letter) {
+        attrs = [];
+        if (['a', 'e', 'i', 'o', 'u'].indexOf(letter) != -1)
+          attrs.push('vowel');
+        else
+          attrs.push('consonant');
+        if (letter == 'a')
+          attrs.push('first');
+        if (letter == 'z')
+          attrs.push('last');
+        store.put({ch: letter, attribs: attrs}, letter.toUpperCase());
+      });
+
+      store = connection.createObjectStore('empty', null);
+      index = store.createIndex('test_idx', 'upper');
+    };
+  };
+}
+
+function createGetAllKeysRequest(t, storeName, connection, range, maxCount) {
+    var transaction = connection.transaction(storeName, 'readonly');
+    var store = transaction.objectStore(storeName);
+    var index = store.index('test_idx');
+    var req = index.getAllKeys(range, maxCount);
+    req.onerror = t.unreached_func('getAllKeys request should succeed');
+    return req;
+}
+
+doSetup(location.pathname + '-IDBIndex.getAllKeys', 1, function(evt) {
+    var connection = evt.target.result;
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection, 'C');
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_array_equals(evt.target.result, ['c']);
+          t.done();
+      });
+    }, 'Single item get');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'empty', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAllKeys() on empty object store should return empty array');
+          t.done();
+      });
+    }, 'Empty object store');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, alphabet,
+              'getAllKeys() should return a..z');
+          t.done();
+      });
+    }, 'Get all keys');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'generated', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+              [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
+               19, 20, 21, 22, 23, 24, 25, 26],
+              'getAllKeys() should return 1..26');
+          t.done();
+      });
+    }, 'Get all generated keys');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection, undefined,
+                                    10);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+                             'abcdefghij'.split(''),
+                             'getAllKeys() should return a..j');
+          t.done();
+      });
+    }, 'maxCount=10');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('G', 'M'));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+                              'ghijklm'.split(''),
+                              'getAllKeys() should return g..m');
+          t.done();
+      });
+    }, 'Get bound range');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('G', 'M'), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+                             ['g', 'h', 'i'],
+                             'getAllKeys() should return g..i');
+          t.done();
+      });
+    }, 'Get bound range with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+          IDBKeyRange.bound('G', 'K', false, true));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+                             ['g', 'h', 'i', 'j'],
+                             'getAllKeys() should return g..j');
+          t.done();
+      });
+    }, 'Get upper excluded');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+          IDBKeyRange.bound('G', 'K', true, false));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+                             ['h', 'i', 'j', 'k'],
+                             'getAllKeys() should return h..k');
+          t.done();
+      });
+    }, 'Get lower excluded');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'generated',
+          connection, IDBKeyRange.bound(4, 15), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+                              'getAllKeys() should return []');
+          t.done();
+      });
+    }, 'Get bound range (generated) with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line',
+          connection, "Doesn't exist");
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAllKeys() using a nonexistent key should return empty array');
+          t.done();
+      req.onerror = t.unreached_func('getAllKeys request should succeed');
+      });
+    }, 'Non existent key');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+          undefined, 0);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, alphabet,
+              'getAllKeys() should return a..z');
+          t.done();
+      });
+    }, 'maxCount=0');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line-multi', connection,
+                                        'vowel');
+      req.onsuccess = t.step_func(function(evt) {
+        assert_array_equals(evt.target.result, ['A','E','I','O','U'])
+        t.done();
+      });
+      req.onerror = t.unreached_func('getAllKeys request should succeed');
+    }, 'Retrieve multiEntry keys');
+
+    // Explicit done needed in case async_test body fails synchronously.
+    done();
+});
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/idbobjectstore_getAll.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<title>IndexedDB: Test IDBObjectStore.getAll.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({explicit_done: true});
+
+var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
+
+function doSetup(dbName, dbVersion, onsuccess) {
+  var delete_request = indexedDB.deleteDatabase(dbName);
+  delete_request.onerror = function() {
+    assert_unreached('deleteDatabase should not fail');
+  };
+  delete_request.onsuccess = function(e) {
+    var req = indexedDB.open(dbName, dbVersion);
+    req.onsuccess = onsuccess;
+    req.onerror = function() {
+      assert_unreached('open should not fail');
+    };
+    req.onupgradeneeded = function(evt) {
+      var connection = evt.target.result;
+
+      var store = connection.createObjectStore('generated',
+            {autoIncrement: true, keyPath: 'id'});
+      alphabet.forEach(function(letter) {
+        store.put({ch: letter});
+      });
+
+      store = connection.createObjectStore('out-of-line', null);
+      alphabet.forEach(function(letter) {
+        store.put('value-' + letter, letter);
+      });
+
+      store = connection.createObjectStore('empty', null);
+    };
+  };
+}
+
+function createGetAllRequest(t, storeName, connection, range, maxCount) {
+    var transaction = connection.transaction(storeName, 'readonly');
+    var store = transaction.objectStore(storeName);
+    var req = store.getAll(range, maxCount);
+    req.onerror = t.unreached_func('getAll request should succeed');
+    return req;
+}
+
+doSetup(location.pathname + '-IDBObjectStore.getAll', 1, function(evt) {
+    var connection = evt.target.result;
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection, 'c');
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['value-c']);
+          t.done();
+      });
+    }, 'Single item get');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'generated', connection, 3);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_true(Array.isArray(data));
+          assert_equals(data.length, 1);
+          assert_equals(data[0].id, 3);
+          assert_equals(data[0].ch, 'c');
+          t.done();
+      });
+    }, 'Single item get (generated key)');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'empty', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAll() on empty object store should return an empty array');
+          t.done();
+      });
+    }, 'getAll on empty object store');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+              alphabet.map(function(c) { return 'value-' + c; }));
+          t.done();
+      });
+    }, 'Get all values');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection, undefined,
+                                    10);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+              'abcdefghij'.split('').map(function(c) { return 'value-' + c; }));
+          t.done();
+      });
+    }, 'Test maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'm'));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+              'ghijklm'.split('').map(function(c) { return 'value-' + c; }));
+          t.done();
+      });
+    }, 'Get bound range');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'm'), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['g', 'h', 'i']
+              .map(function(c) { return 'value-' + c; }));
+          t.done();
+      });
+    }, 'Get bound range with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'k', false, true));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['g', 'h', 'i', 'j']
+              .map(function(c) { return 'value-' + c; }));
+          t.done();
+      });
+    }, 'Get upper excluded');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'k', true, false));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['h', 'i', 'j', 'k']
+              .map(function(c) { return 'value-' + c; }));
+          t.done();
+      });
+    }, 'Get lower excluded');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'generated', connection,
+                                    IDBKeyRange.bound(4, 15), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_true(Array.isArray(data));
+          assert_array_equals(data.map(function(e) { return e.ch; }), ['d', 'e', 'f']);
+          assert_array_equals(data.map(function(e) { return e.id; }), [4, 5, 6]);
+          t.done();
+      });
+    }, 'Get bound range (generated) with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection,
+                                    "Doesn't exist");
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAll() using a nonexistent key should return an empty array');
+          t.done();
+      });
+      req.onerror = t.unreached_func('getAll request should succeed');
+    }, 'Non existent key');
+
+    async_test(function(t) {
+      var req = createGetAllRequest(t, 'out-of-line', connection, undefined, 0);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result,
+              alphabet.map(function(c) { return 'value-' + c; }));
+          t.done();
+      });
+    }, 'zero maxCount');
+
+    // Explicit done needed in case async_test body fails synchronously.
+    done();
+});
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/idbobjectstore_getAllKeys.html
@@ -0,0 +1,167 @@
+<!DOCTYPE html>
+<title>IndexedDB: Test IDBObjectStore.getAllKeys.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({explicit_done: true});
+
+var alphabet = 'abcdefghijklmnopqrstuvwxyz'.split('');
+
+function doSetup(dbName, dbVersion, onsuccess) {
+  var delete_request = indexedDB.deleteDatabase(dbName);
+  delete_request.onerror = function() {
+    assert_unreached('deleteDatabase should not fail');
+  };
+  delete_request.onsuccess = function(e) {
+    var req = indexedDB.open(dbName, dbVersion);
+    req.onsuccess = onsuccess;
+    req.onerror = function() {
+      assert_unreached('open should not fail');
+    };
+    req.onupgradeneeded = function(evt) {
+      var connection = evt.target.result;
+
+      var store = connection.createObjectStore('generated',
+            {autoIncrement: true, keyPath: 'id'});
+      alphabet.forEach(function(letter) {
+        store.put({ch: letter});
+      });
+
+      store = connection.createObjectStore('out-of-line', null);
+      alphabet.forEach(function(letter) {
+        store.put('value-' + letter, letter);
+      });
+
+      store = connection.createObjectStore('empty', null);
+    };
+  };
+}
+
+function createGetAllKeysRequest(t, storeName, connection, range, maxCount) {
+    var transaction = connection.transaction(storeName, 'readonly');
+    var store = transaction.objectStore(storeName);
+    var req = store.getAllKeys(range, maxCount);
+    req.onerror = t.unreached_func('getAllKeys request should succeed');
+    return req;
+}
+
+doSetup(location.pathname + '-IDBObjectStore.getAllKeys', 1, function(evt) {
+    var connection = evt.target.result;
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection, 'c');
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['c']);
+          t.done();
+      });
+    }, 'Single item get');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'generated', connection, 3);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_true(Array.isArray(data));
+          assert_array_equals(data, [3]);
+          t.done();
+      });
+    }, 'Single item get (generated key)');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'empty', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAllKeys() on empty object store should return an empty ' +
+                  'array');
+          t.done();
+      });
+    }, 'getAllKeys on empty object store');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, alphabet);
+          t.done();
+      });
+    }, 'Get all values');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection, undefined,
+                                    10);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, 'abcdefghij'.split(''));
+          t.done();
+      });
+    }, 'Test maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'm'));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, 'ghijklm'.split(''));
+          t.done();
+      });
+    }, 'Get bound range');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'm'), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['g', 'h', 'i']);
+          t.done();
+      });
+    }, 'Get bound range with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'k', false, true));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['g', 'h', 'i', 'j']);
+          t.done();
+      });
+    }, 'Get upper excluded');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+                                    IDBKeyRange.bound('g', 'k', true, false));
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, ['h', 'i', 'j', 'k']);
+          t.done();
+      });
+    }, 'Get lower excluded');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'generated', connection,
+                                    IDBKeyRange.bound(4, 15), 3);
+      req.onsuccess = t.step_func(function(evt) {
+          var data = evt.target.result;
+          assert_true(Array.isArray(data));
+          assert_array_equals(data, [4, 5, 6]);
+          t.done();
+      });
+    }, 'Get bound range (generated) with maxCount');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection,
+                                    "Doesn't exist");
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, [],
+              'getAllKeys() using a nonexistent key should return an ' +
+                  'empty array');
+          t.done();
+      });
+      req.onerror = t.unreached_func('getAllKeys request should succeed');
+    }, 'Non existent key');
+
+    async_test(function(t) {
+      var req = createGetAllKeysRequest(t, 'out-of-line', connection, undefined,
+          0);
+      req.onsuccess = t.step_func(function(evt) {
+          assert_array_equals(evt.target.result, alphabet);
+          t.done();
+      });
+    }, 'zero maxCount');
+
+    // Explicit done needed in case async_test body fails synchronously.
+    done();
+});
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/idbobjectstore_openKeyCursor.htm
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+<title>IDBObjectStore.openKeyCursor()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function store_test(func, name) {
+    async_test(function(t) {
+        var del = indexedDB.deleteDatabase(name);
+        del.onerror = t.unreached_func("deleteDatabase failed");
+        var open = indexedDB.open(name);
+        open.onupgradeneeded = t.step_func(function() {
+            var db = open.result;
+            var store = db.createObjectStore("store");
+            for (var i = 0; i < 10; ++i) {
+                store.put("value: " + i, i);
+            }
+        });
+
+        open.onsuccess = t.step_func(function() {
+            var db = open.result;
+            var tx = db.transaction("store");
+            var store = tx.objectStore("store");
+            func(t, db, tx, store);
+        });
+    }, name);
+}
+
+store_test(function(t, db, tx, store) {
+    var expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+    var actual = [];
+    var request = store.openKeyCursor();
+    request.onsuccess = t.step_func(function() {
+        var cursor = request.result;
+        if (!cursor)
+            return;
+        assert_equals(cursor.direction, "next");
+        assert_false("value" in cursor);
+        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
+        actual.push(cursor.key);
+        cursor.continue();
+    });
+
+    tx.onabort = t.unreached_func("transaction aborted");
+    tx.oncomplete = t.step_func(function() {
+        assert_array_equals(expected, actual, "keys should match");
+        t.done();
+    });
+
+}, "IDBObjectStore.openKeyCursor() - forward iteration");
+
+store_test(function(t, db, tx, store) {
+    var expected = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0];
+    var actual = [];
+    var request = store.openKeyCursor(null, "prev");
+    request.onsuccess = t.step_func(function() {
+        var cursor = request.result;
+        if (!cursor)
+            return;
+        assert_equals(cursor.direction, "prev");
+        assert_false("value" in cursor);
+        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
+        actual.push(cursor.key);
+        cursor.continue();
+    });
+
+    tx.onabort = t.unreached_func("transaction aborted");
+    tx.oncomplete = t.step_func(function() {
+        assert_array_equals(expected, actual, "keys should match");
+        t.done();
+    });
+
+}, "IDBObjectStore.openKeyCursor() - reverse iteration");
+
+store_test(function(t, db, tx, store) {
+    var expected = [4, 5, 6];
+    var actual = [];
+    var request = store.openKeyCursor(IDBKeyRange.bound(4, 6));
+    request.onsuccess = t.step_func(function() {
+        var cursor = request.result;
+        if (!cursor)
+            return;
+        assert_equals(cursor.direction, "next");
+        assert_false("value" in cursor);
+        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
+        actual.push(cursor.key);
+        cursor.continue();
+    });
+
+    tx.onabort = t.unreached_func("transaction aborted");
+    tx.oncomplete = t.step_func(function() {
+        assert_array_equals(expected, actual, "keys should match");
+        t.done();
+    });
+
+}, "IDBObjectStore.openKeyCursor() - forward iteration with range");
+
+store_test(function(t, db, tx, store) {
+    var expected = [6, 5, 4];
+    var actual = [];
+    var request = store.openKeyCursor(IDBKeyRange.bound(4, 6), "prev");
+    request.onsuccess = t.step_func(function() {
+        var cursor = request.result;
+        if (!cursor)
+            return;
+        assert_equals(cursor.direction, "prev");
+        assert_false("value" in cursor);
+        assert_equals(indexedDB.cmp(cursor.key, cursor.primaryKey), 0);
+        actual.push(cursor.key);
+        cursor.continue();
+    });
+
+    tx.onabort = t.unreached_func("transaction aborted");
+    tx.oncomplete = t.step_func(function() {
+        assert_array_equals(expected, actual, "keys should match");
+        t.done();
+    });
+
+}, "IDBObjectStore.openKeyCursor() - reverse iteration with range");
+
+store_test(function(t, db, tx, store) {
+    assert_throws("DataError", function() { store.openKeyCursor(NaN); },
+        "openKeyCursor should throw on invalid number key");
+    assert_throws("DataError", function() { store.openKeyCursor(new Date(NaN)); },
+        "openKeyCursor should throw on invalid date key");
+    assert_throws("DataError", function() {
+        var cycle = [];
+        cycle.push(cycle);
+        store.openKeyCursor(cycle);
+    }, "openKeyCursor should throw on invalid array key");
+    assert_throws("DataError", function() { store.openKeyCursor({}); },
+        "openKeyCursor should throw on invalid key type");
+    setTimeout(t.step_func(function() {
+        assert_throws("TransactionInactiveError", function() { store.openKeyCursor(); },
+            "openKeyCursor should throw if transaction is inactive");
+        t.done();
+    }), 0);
+
+}, "IDBObjectStore.openKeyCursor() - invalid inputs");
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/IndexedDB/idbtransaction_objectStoreNames.html
@@ -0,0 +1,182 @@
+<!DOCTYPE html>
+<title>IndexedDB: IDBTransaction.objectStoreNames attribute</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+function indexeddb_test(upgrade_func, open_func, description) {
+    async_test(function(t) {
+        var dbname = document.location + '-' + t.name;
+        var del = indexedDB.deleteDatabase(dbname);
+        del.onerror = t.unreached_func('deleteDatabase should succeed');
+        var open = indexedDB.open(dbname, 1);
+        open.onerror = t.unreached_func('open should succeed');
+        open.onupgradeneeded = t.step_func(function() {
+            var db = open.result;
+            var tx = open.transaction;
+            upgrade_func(t, db, tx);
+        });
+        open.onsuccess = t.step_func(function() {
+            var db = open.result;
+            open_func(t, db);
+        });
+    }, description);
+}
+
+function with_stores_test(store_names, open_func, description) {
+    indexeddb_test(function(t, db, tx) {
+        store_names.forEach(function(name) {
+            db.createObjectStore(name);
+        });
+    }, open_func, description);
+}
+
+indexeddb_test(function(t, db, tx) {
+    assert_array_equals(tx.objectStoreNames, [],
+        'transaction objectStoreNames should be empty');
+    assert_array_equals(db.objectStoreNames, tx.objectStoreNames,
+        'connection and transacton objectStoreNames should match');
+
+    db.createObjectStore('s1');
+    assert_array_equals(tx.objectStoreNames, ['s1'],
+        'transaction objectStoreNames should have new store');
+    assert_array_equals(db.objectStoreNames, tx.objectStoreNames,
+        'connection and transacton objectStoreNames should match');
+
+    db.createObjectStore('s3');
+    assert_array_equals(tx.objectStoreNames, ['s1', 's3'],
+        'transaction objectStoreNames should have new store');
+    assert_array_equals(db.objectStoreNames, tx.objectStoreNames,
+        'connection and transacton objectStoreNames should match');
+
+    db.createObjectStore('s2');
+    assert_array_equals(tx.objectStoreNames, ['s1', 's2', 's3'],
+        'transaction objectStoreNames should be sorted');
+    assert_array_equals(db.objectStoreNames, tx.objectStoreNames,
+        'connection and transacton objectStoreNames should match');
+
+    db.deleteObjectStore('s1');
+    assert_array_equals(tx.objectStoreNames, ['s2', 's3'],
+        'transaction objectStoreNames should be updated after delete');
+    assert_array_equals(db.objectStoreNames, tx.objectStoreNames,
+        'connection and transacton objectStoreNames should match');
+}, function(t, db) {
+    t.done();
+}, 'IDBTransaction.objectStoreNames - during upgrade transaction');
+
+(function() {
+    var saved_tx;
+    indexeddb_test(function(t, db, tx) {
+        saved_tx = tx;
+        db.createObjectStore('s2');
+        db.createObjectStore('s3');
+    }, function(t, db) {
+        db.close();
+        var open2 = indexedDB.open(db.name, db.version + 1);
+        open2.onerror = t.unreached_func('open should succeed');
+        open2.onupgradeneeded = t.step_func(function() {
+            var db2 = open2.result;
+            var tx2 = open2.transaction;
+            assert_array_equals(tx2.objectStoreNames, ['s2', 's3'],
+                'transaction should have previous stores in scope');
+            assert_array_equals(db2.objectStoreNames, tx2.objectStoreNames,
+                'connection and transacton objectStoreNames should match');
+
+            db2.createObjectStore('s4');
+            assert_array_equals(tx2.objectStoreNames, ['s2', 's3', 's4'],
+                'transaction should have new store in scope');
+            assert_array_equals(db2.objectStoreNames, tx2.objectStoreNames,
+                'connection and transacton objectStoreNames should match');
+
+            assert_array_equals(saved_tx.objectStoreNames, ['s2', 's3'],
+                'previous transaction objectStoreNames should be unchanged');
+            assert_array_equals(db.objectStoreNames, saved_tx.objectStoreNames,
+                'connection and transaction objectStoreNames should match');
+            t.done();
+        });
+    }, 'IDBTransaction.objectStoreNames - value after close');
+}());
+
+with_stores_test(['s1', 's2'], function(t, db) {
+    assert_array_equals(db.transaction('s1').objectStoreNames, ['s1'],
+        'transaction should have one store in scope');
+    assert_array_equals(db.transaction(['s1', 's2']).objectStoreNames,
+        ['s1', 's2'],
+        'transaction should have two stores in scope');
+    t.done();
+}, 'IDBTransaction.objectStoreNames - transaction scope');
+
+with_stores_test(['s1', 's2'], function(t, db) {
+    var tx = db.transaction(['s1', 's2'], 'readwrite');
+    tx.objectStore('s1').put(0, 0);
+    tx.onabort = t.unreached_func('transaction should complete');
+    tx.oncomplete = t.step_func(function() {
+        assert_array_equals(tx.objectStoreNames, ['s1', 's2'],
+            'objectStoreNames should return scope after transaction commits');
+        t.done();
+    });
+}, 'IDBTransaction.objectStoreNames - value after commit');
+
+with_stores_test(['s1', 's2'], function(t, db) {
+    var tx = db.transaction(['s1', 's2'], 'readwrite');
+    tx.objectStore('s1').put(0, 0);
+    tx.objectStore('s1').add(0, 0);
+    tx.oncomplete = t.unreached_func('transaction should abort');
+    tx.onabort = t.step_func(function() {
+        assert_array_equals(tx.objectStoreNames, ['s1', 's2'],
+            'objectStoreNames should return scope after transaction aborts');
+        t.done();
+    });
+}, 'IDBTransaction.objectStoreNames - value after abort');
+
+with_stores_test(['s1', 's2', 's3'], function(t, db) {
+    assert_array_equals(db.transaction(['s3', 's2', 's1']).objectStoreNames,
+        ['s1', 's2', 's3'],
+        'transaction objectStoreNames should be sorted');
+    t.done();
+}, 'IDBTransaction.objectStoreNames - sorting');
+
+with_stores_test(['s1', 's2'], function(t, db) {
+    assert_array_equals(
+        db.transaction(['s2', 's1', 's2']).objectStoreNames,
+            ['s1', 's2'],
+        'transaction objectStoreNames should not have duplicates');
+    t.done();
+}, 'IDBTransaction.objectStoreNames - no duplicates');
+
+var unusual_names = [
+    '', // empty string
+
+    '\x00', // U+0000 NULL
+    '\xFF', // U+00FF LATIN SMALL LETTER Y WITH DIAERESIS
+
+    '1', // basic ASCII
+    '12', // basic ASCII
+    '123', // basic ASCII
+    'abc', // basic ASCII
+    'ABC', // basic ASCII
+
+    '\xA2', // U+00A2 CENT SIGN
+    '\u6C34', // U+6C34 CJK UNIFIED IDEOGRAPH (water)
+    '\uD834\uDD1E', // U+1D11E MUSICAL SYMBOL G-CLEF (UTF-16 surrogate pair)
+    '\uFFFD', // U+FFFD REPLACEMENT CHARACTER
+
+    '\uD800', // UTF-16 surrogate lead
+    '\uDC00', // UTF-16 surrogate trail
+];
+unusual_names.sort();
+
+indexeddb_test(function(t, db, tx) {
+    unusual_names.slice().reverse().forEach(function(name) {
+        db.createObjectStore(name);
+    });
+    assert_array_equals(tx.objectStoreNames, unusual_names,
+        'transaction should have names sorted');
+}, function(t, db) {
+    var tx = db.transaction(unusual_names.slice().reverse().concat(unusual_names));
+    assert_array_equals(tx.objectStoreNames, unusual_names,
+        'transaction should have names sorted with no duplicates');
+    t.done();
+}, 'IDBTransaction.objectStoreNames - unusual names');
+
+</script>
--- a/testing/web-platform/tests/IndexedDB/support.js
+++ b/testing/web-platform/tests/IndexedDB/support.js
@@ -1,34 +1,11 @@
 var databaseName = "database";
 var databaseVersion = 1;
 
-if (!window.indexedDB)
-{
-    if (window.msIndexedDB)
-    {
-        window.indexedDB = window.msIndexedDB;
-    }
-    else if (window.mozIndexedDB)
-    {
-        window.indexedDB = window.mozIndexedDB;
-    }
-    else if (window.webkitIndexedDB)
-    {
-        window.indexedDB        = webkitIndexedDB;
-        IDBCursor               = webkitIDBCursor;
-        IDBDatabaseException    = webkitIDBDatabaseException;
-        IDBIndex                = webkitIDBIndex;
-        IDBObjectStore          = webkitIDBObjectStore;
-        IDBRequest              = webkitIDBRequest;
-        IDBKeyRange             = webkitIDBKeyRange;
-        IDBTransaction          = webkitIDBTransaction;
-    }
-}
-
 /* Delete created databases
  *
  * Go through each finished test, see if it has an associated database. Close
  * that and delete the database. */
 add_completion_callback(function(tests)
 {
     for (var i in tests)
     {
--- a/testing/web-platform/tests/README.md
+++ b/testing/web-platform/tests/README.md
@@ -1,14 +1,16 @@
 The Web Platform Tests Project [![IRC chat](https://goo.gl/6nCIks)](http://irc.w3.org/?channels=testing)
 ==============================
 
 The Web Platform Tests Project is a W3C-coordinated attempt to build a
-cross-browser testsuite for the Web-platform stack. Writing tests in a
-way that allows them to be run in all browsers gives browser projects
+cross-browser testsuite for the Web-platform stack.  However, for mainly
+historic reasons, the CSS WG testsuite is in a separate repository,
+[csswg-test](https://github.com/w3c/csswg-test). Writing tests in a way
+that allows them to be run in all browsers gives browser projects
 confidence that they are shipping software that is compatible with other
 implementations, and that later implementations will be compatible with
 their implementations. This in turn gives Web authors/developers
 confidence that they can actually rely on the Web platform to deliver on
 the promise of working across browsers and devices without needing extra
 layers of abstraction to paper over the gaps left by specification
 editors and implementors.
 
--- a/testing/web-platform/tests/app-uri/appURI_test.html
+++ b/testing/web-platform/tests/app-uri/appURI_test.html
@@ -121,23 +121,23 @@
                 xhr.send();
             });
             delete name, URI, xhr, xhrTest;
         });
         delete CaseNormalizationXHRtests;
 
 
         /**
-         *	ContentType reponse
+         *	ContentType response
          *
          *	rules for dereferencing an app: URI => 
 		  8. Let potential-file be the result of attempting locate the file at path
          */
 
-        TC_name = "Test: [HTTP] 200 reponse status (OK),value of content-type as the [HTTP] ";
+        TC_name = "Test: [HTTP] 200 response status (OK),value of content-type as the [HTTP] ";
         TC_name += "Content-Type header, and the contents of potential-file as the response body";
 
         var ContentTypeResponsetests = [ /* scheme:[ TC name, URI, content-type] */
             [TC_name + ' [text/html]', 'resources/ExamPLE/mmY/index.html', 'text/html'],
             [TC_name + " [image/png]", 'resources/ImaGes/~t/%7b!a%7d/~sth.png', "image/png"],
             [TC_name + " [text/plain]", 'resources/ExamPLE/mmY/sth.txt', "text/plain"]
         ];
 
@@ -329,17 +329,17 @@
                         + xhr.status + " error, response:[" + xhr.response + "] " 
                         + "]");
                         xhrTest.done();
                     }
                 });
                 xhr.send();
             });
         }
-        Get_403_reponse(TC_name + " Access to resticted URI - 403 Forbidden error expected", 
+        Get_403_reponse(TC_name + " Access to restricted URI - 403 Forbidden error expected", 
         window.location.protocol + "//f15a6d20-cefa-13e5-1972-800e20d19a76/" + 'resources/ExamPLE/mmY/index.html', "");
 
 
         /**	
          *	404 Not Found error - response body MUST be empty
          *
          *	rules for dereferencing an app: URI => 
 		  9. If potential-file is not found at the given path inside the container, 
--- a/testing/web-platform/tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html
+++ b/testing/web-platform/tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html
@@ -1,42 +1,73 @@
 <!DOCTYPE html>
 <html>
 
 <head>
     <!-- Programmatically converted from a WebKit Reftest, please forgive resulting idiosyncracies.-->
     <title>scripthash-unicode-normalization</title>
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
-    <script src="/content-security-policy/support/alertAssert.sub.js?alerts=%5B%22PASS%22%2C%22PASS%22%5D">
-
 
     </script>
     <!-- enforcing policy:
-script-src 'self' 'unsafe-inline' 'sha256-xy4iRAvdlFCq+M5+4yu4B7dy0Kc2FfljmZO4Jkj3Yhw='; connect-src 'self';
+script-src 'self' 'nonce-nonceynonce' 'sha256-dWTP4Di8KBjaiXvQ5mRquI9OoBSo921ahYxLfYSiuT8='; connect-src 'self';
 -->
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
-    <!-- The following two scripts contain two separate code points (U+00C5
-        and U+212B, respectively) which, depending on your text editor, might be
-        rendered the same. However, their difference is important as they should
-        be NFC normalized to the same code point, thus they should hash to the
-        same value.-->
-    <script>
-        'Å';
-        alert_assert('PASS');
-
-    </script>
-    <script>
-        'Å';
-        alert_assert('PASS');
-
-    </script>
 </head>
 
 <body>
+    <!-- The following two scripts contain two separate code points (U+00C5
+        and U+212B, respectively) which, depending on your text editor, might be
+        rendered the same.However, their difference is important because, under
+        NFC normalization, they would become the same code point, which would be
+        against the spec. This test, therefore, validates that the scripts have
+        *different* hash values. -->
+    <script nonce="nonceynonce">
+      var matchingContent = 'Å';
+      var nonMatchingContent = 'Å';
+
+      // This script should have a hash value of
+      // sha256-9UFeeZbvnMa0tLNu76v96T4Hh+UtDWHm2lPQJoTWb9c=
+      var scriptContent1 = "window.finish('" + matchingContent + "');";
+
+      // This script should have a hash value of
+      // sha256-iNjjXUXds31FFvkAmbC74Sxnvreug3PzGtu16udQyqM=
+      var scriptContent2 = "window.finish('" + nonMatchingContent + "');";
+
+      var script1 = document.createElement('script');
+      script1.innerHTML = scriptContent1;
+      var script2 = document.createElement('script');
+      script2.innerHTML = scriptContent2;
+
+      script1.test = async_test("Inline script with hash in CSP");
+      script2.test = async_test("Inline script without hash in CSP");
+
+      var failure = function() {
+        assert_unreached();
+      }
+
+      window.finish = function(content) {
+        if (content == matchingContent) {
+          script1.test.step(function() {
+            script1.test.done();
+          });
+        } else {
+          assert_unreached();
+        }
+      }
+
+      script1.onerror = failure;
+      script2.onerror = script2.test.step_func(function() {
+        script2.test.done();
+      });
+      document.body.appendChild(script1);
+      document.body.appendChild(script2);
+    </script>
+
     <p>
         This tests Unicode normalization. While appearing the same, the strings in the scripts are different Unicode points, but through normalization, should be the same when the hash is taken.
     </p>
     <div id="log"></div>
-    <script async defer src="../support/checkReport.sub.js?reportExists=false"></script>
+    <script async defer src="../support/checkReport.sub.js?reportExists=true"></script>
 </body>
 
 </html>
--- a/testing/web-platform/tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html.sub.headers
+++ b/testing/web-platform/tests/content-security-policy/blink-contrib-2/scripthash-unicode-normalization.sub.html.sub.headers
@@ -1,6 +1,6 @@
 Expires: Mon, 26 Jul 1997 05:00:00 GMT
 Cache-Control: no-store, no-cache, must-revalidate
 Cache-Control: post-check=0, pre-check=0, false
 Pragma: no-cache
 Set-Cookie: scripthash-unicode-normalization={{$id:uuid()}}; Path=/content-security-policy/blink-contrib-2
-Content-Security-Policy: script-src 'self' 'sha256-xy4iRAvdlFCq+M5+4yu4B7dy0Kc2FfljmZO4Jkj3Yhw='; connect-src 'self'; report-uri /content-security-policy/support/report.py?op=put&reportID={{$id}}
+Content-Security-Policy: script-src 'self' 'nonce-nonceynonce' 'sha256-9UFeeZbvnMa0tLNu76v96T4Hh+UtDWHm2lPQJoTWb9c='; connect-src 'self'; report-uri /content-security-policy/support/report.py?op=put&reportID={{$id}}
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/dom/collections/domstringmap-supported-property-names.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>DOMStringMap Test: Supported property names</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+
+<div id="edge1" data-="012">Simple</div>
+
+<div id="edge2" data-id-="012">Simple</div>
+
+<div id="user" data-id="1234567890" data-user="johndoe" data-date-of-birth>
+    John Doe
+</div>
+
+<div id="user2" data-unique-id="1234567890"> Jane Doe </div>
+
+<div id="user3" data-unique-id="4324324241"> Jim Doe </div>
+
+<script>
+
+test(function() {
+    var element = document.querySelector('#edge1');
+    assert_array_equals(Object.getOwnPropertyNames(element.dataset),
+        [""]);
+}, "Object.getOwnPropertyNames on DOMStringMap, empty data attribute");
+
+test(function() {
+    var element = document.querySelector('#edge2');
+    assert_array_equals(Object.getOwnPropertyNames(element.dataset),
+        ["id-"]);
+}, "Object.getOwnPropertyNames on DOMStringMap, data attribute trailing hyphen");
+
+test(function() {
+    var element = document.querySelector('#user');
+    assert_array_equals(Object.getOwnPropertyNames(element.dataset),
+        ['id', 'user', 'dateOfBirth']);
+}, "Object.getOwnPropertyNames on DOMStringMap, multiple data attributes");
+
+test(function() {
+    var element = document.querySelector('#user2');
+    element.dataset.middleName = "mark";
+    assert_array_equals(Object.getOwnPropertyNames(element.dataset),
+        ['uniqueId', 'middleName']);
+}, "Object.getOwnPropertyNames on DOMStringMap, attribute set on dataset in JS");
+
+test(function() {
+    var element = document.querySelector('#user3');
+    element.setAttribute("data-age", 30);
+    assert_array_equals(Object.getOwnPropertyNames(element.dataset),
+        ['uniqueId', 'age']);
+}, "Object.getOwnPropertyNames on DOMStringMap, attribute set on element in JS");
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/dom/collections/namednodemap-supported-property-names.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>NamedNodeMap Test: Supported property names</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="simple" class="fancy">Simple</div>
+<input id="result" type="text" value="" width="200px">
+<script>
+
+test(function() {
+    var elt = document.querySelector('#simple');
+    assert_array_equals(Object.getOwnPropertyNames(elt.attributes),
+        ['0','1','id','class']);
+}, "Object.getOwnPropertyNames on NamedNodeMap");
+
+test(function() {
+    var result = document.getElementById("result");
+    assert_array_equals(Object.getOwnPropertyNames(result.attributes),
+        ['0','1','2','3','id','type','value','width']);
+}, "Object.getOwnPropertyNames on NamedNodeMap of input");
+
+test(function() {
+    var result = document.getElementById("result");
+    result.removeAttribute("width");
+    assert_array_equals(Object.getOwnPropertyNames(result.attributes),
+        ['0','1','2','id','type','value']);
+}, "Object.getOwnPropertyNames on NamedNodeMap after attribute removal");
+
+</script>
\ No newline at end of file
--- a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace.html
+++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace.html
@@ -8,32 +8,27 @@
 "use strict";
 /**
  * This tests the namespace of elements created by the Document interface's
  * createElement() method.  See bug:
  * https://www.w3.org/Bugs/Public/show_bug.cgi?id=19431
  */
 
 /**
- * Test that an element created using the Document object doc has the namespace
- * that would be expected for the given contentType.
+ * Test that an element created using the Document object doc has the HTML
+ * namespace.
  */
 function testDoc(doc, contentType) {
-  // WebKit doesn't support document.contentType, so they don't get this sanity
-  // check :(
   if (doc.contentType !== undefined) {
+    // Sanity check
     assert_equals(doc.contentType, contentType,
                   "Wrong MIME type -- incorrect server config?");
   }
 
-  var expectedNamespace = contentType == "text/html" ||
-                          contentType == "application/xhtml+xml"
-                          ? "http://www.w3.org/1999/xhtml" : null;
-
-  assert_equals(doc.createElement("x").namespaceURI, expectedNamespace);
+  assert_equals(doc.createElement("x").namespaceURI, "http://www.w3.org/1999/xhtml");
 }
 
 // First test various objects we create in JS
 test(function() {
   testDoc(document, "text/html")
 }, "Created element's namespace in current document");
 test(function() {
   testDoc(document.implementation.createHTMLDocument(""), "text/html");
--- a/testing/web-platform/tests/dom/nodes/Node-lookupNamespaceURI.html
+++ b/testing/web-platform/tests/dom/nodes/Node-lookupNamespaceURI.html
@@ -18,97 +18,94 @@ function lookupNamespaceURI(node, prefix
 function isDefaultNamespace(node, namespace, expected, name) {
   test(function() {
     assert_equals(node.isDefaultNamespace(namespace), expected);
   }, name);
 }
 
 
 var frag = document.createDocumentFragment();
-lookupNamespaceURI(frag, null, null, 'DocumentFragment should have null namespace');
-lookupNamespaceURI(frag, '', null, 'DocumentFragment should have null namespace');
-lookupNamespaceURI(frag, 'foo', null, 'DocumentFragment should have null namespace');
-lookupNamespaceURI(frag, 'xmlns', null, 'DocumentFragment should have null namespace');
-isDefaultNamespace(frag, null, true, 'DocumentFragment is in default namespace');
-isDefaultNamespace(frag, '', true, 'DocumentFragment is in default namespace');
-isDefaultNamespace(frag, 'foo', false, 'DocumentFragment is in default namespace');
-isDefaultNamespace(frag, 'xmlns', false, 'DocumentFragment is in default namespace');
+lookupNamespaceURI(frag, null, null, 'DocumentFragment should have null namespace, prefix null');
+lookupNamespaceURI(frag, '', null, 'DocumentFragment should have null namespace, prefix ""');
+lookupNamespaceURI(frag, 'foo', null, 'DocumentFragment should have null namespace, prefix "foo"');
+lookupNamespaceURI(frag, 'xmlns', null, 'DocumentFragment should have null namespace, prefix "xmlns"');
+isDefaultNamespace(frag, null, true, 'DocumentFragment is in default namespace, prefix null');
+isDefaultNamespace(frag, '', true, 'DocumentFragment is in default namespace, prefix ""');
+isDefaultNamespace(frag, 'foo', false, 'DocumentFragment is in default namespace, prefix "foo"');
+isDefaultNamespace(frag, 'xmlns', false, 'DocumentFragment is in default namespace, prefix "xmlns"');
 
 
 
 var fooElem = document.createElementNS('fooNamespace', 'prefix:elem');
 fooElem.setAttribute('bar', 'value');
 
-lookupNamespaceURI(fooElem, null, null, 'Element should have null namespace');
-lookupNamespaceURI(fooElem, '', null, 'Element should have null namespace');
+lookupNamespaceURI(fooElem, null, null, 'Element should have null namespace, prefix null');
+lookupNamespaceURI(fooElem, '', null, 'Element should have null namespace, prefix ""');
 lookupNamespaceURI(fooElem, 'fooNamespace', null, 'Element should not have namespace matching prefix with namespaceURI value');
 lookupNamespaceURI(fooElem, 'xmlns', null, 'Element should not have XMLNS namespace');
 lookupNamespaceURI(fooElem, 'prefix', 'fooNamespace', 'Element has namespace URI matching prefix');
-isDefaultNamespace(fooElem, null, true, 'Empty namespace is not default');
-isDefaultNamespace(fooElem, '', true, 'Empty namespace is not default');
+isDefaultNamespace(fooElem, null, true, 'Empty namespace is not default, prefix null');
+isDefaultNamespace(fooElem, '', true, 'Empty namespace is not default, prefix ""');
 isDefaultNamespace(fooElem, 'fooNamespace', false, 'fooNamespace is not default');
 isDefaultNamespace(fooElem, 'http://www.w3.org/2000/xmlns/', false, 'xmlns namespace is not default');
 
 fooElem.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:bar', 'barURI');
 fooElem.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'bazURI');
 
-lookupNamespaceURI(fooElem, null, 'bazURI', 'Element should have baz namespace');
-lookupNamespaceURI(fooElem, '', 'bazURI', 'Element should have baz namespace');
-lookupNamespaceURI(fooElem, 'prefix', 'fooNamespace', 'Element has namespace URI matching prefix');
+lookupNamespaceURI(fooElem, null, 'bazURI', 'Element should have baz namespace, prefix null');
+lookupNamespaceURI(fooElem, '', 'bazURI', 'Element should have baz namespace, prefix ""');
 lookupNamespaceURI(fooElem, 'xmlns', null, 'Element does not has namespace with xlmns prefix');
 lookupNamespaceURI(fooElem, 'bar', 'barURI', 'Element has bar namespace');
 
-isDefaultNamespace(fooElem, null, false, 'Empty namespace is not default');
-isDefaultNamespace(fooElem, '', false, 'Empty namespace is not default');
-isDefaultNamespace(fooElem, 'fooNamespace', false, 'fooNamespace is not default');
-isDefaultNamespace(fooElem, 'http://www.w3.org/2000/xmlns/', false, 'xmlns namespace is not default');
+isDefaultNamespace(fooElem, null, false, 'Empty namespace is not default on fooElem, prefix null');
+isDefaultNamespace(fooElem, '', false, 'Empty namespace is not default on fooElem, prefix ""');
 isDefaultNamespace(fooElem, 'barURI', false, 'bar namespace is not default');
 isDefaultNamespace(fooElem, 'bazURI', true, 'baz namespace is default');
 
 var comment = document.createComment('comment');
 fooElem.appendChild(comment);
 
 lookupNamespaceURI(comment, null, 'bazURI', 'Comment should inherit baz namespace');
 lookupNamespaceURI(comment, '', 'bazURI', 'Comment should inherit  baz namespace');
 lookupNamespaceURI(comment, 'prefix', 'fooNamespace', 'Comment should inherit namespace URI matching prefix');
 lookupNamespaceURI(comment, 'bar', 'barURI', 'Comment should inherit bar namespace');
 
-isDefaultNamespace(comment, null, false, 'For comment, empty namespace is not default');
-isDefaultNamespace(comment, '', false, 'For comment, empty namespace is not default');
+isDefaultNamespace(comment, null, false, 'For comment, empty namespace is not default, prefix null');
+isDefaultNamespace(comment, '', false, 'For comment, empty namespace is not default, prefix ""');
 isDefaultNamespace(comment, 'fooNamespace', false, 'For comment, fooNamespace is not default');
 isDefaultNamespace(comment, 'http://www.w3.org/2000/xmlns/', false, 'For comment, xmlns namespace is not default');
 isDefaultNamespace(comment, 'barURI', false, 'For comment, inherited bar namespace is not default');
 isDefaultNamespace(comment, 'bazURI', true, 'For comment, inherited baz namespace is default');
 
 var fooChild = document.createElementNS('childNamespace', 'childElem');
 fooElem.appendChild(fooChild);
 
 lookupNamespaceURI(fooChild, null, 'childNamespace', 'Child element should inherit baz namespace');
 lookupNamespaceURI(fooChild, '', 'childNamespace', 'Child element should have null namespace');
 lookupNamespaceURI(fooChild, 'xmlns', null, 'Child element should not have XMLNS namespace');
 lookupNamespaceURI(fooChild, 'prefix', 'fooNamespace', 'Child element has namespace URI matching prefix');
 
-isDefaultNamespace(fooChild, null, false, 'Empty namespace is not default for child');
-isDefaultNamespace(fooChild, '', false, 'Empty namespace is not default for child');
+isDefaultNamespace(fooChild, null, false, 'Empty namespace is not default for child, prefix null');
+isDefaultNamespace(fooChild, '', false, 'Empty namespace is not default for child, prefix ""');
 isDefaultNamespace(fooChild, 'fooNamespace', false, 'fooNamespace is not default for child');
 isDefaultNamespace(fooChild, 'http://www.w3.org/2000/xmlns/', false, 'xmlns namespace is not default for child');
 isDefaultNamespace(fooChild, 'barURI', false, 'bar namespace is not default for child');
 isDefaultNamespace(fooChild, 'bazURI', false, 'baz namespace is default for child');
 isDefaultNamespace(fooChild, 'childNamespace', true, 'childNamespace is default for child');
 
 document.documentElement.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:bar', 'barURI');
 document.documentElement.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'bazURI');
 
-lookupNamespaceURI(document, null, 'http://www.w3.org/1999/xhtml', 'Document should have xhtml namespace');
-lookupNamespaceURI(document, '', 'http://www.w3.org/1999/xhtml', 'Document should have xhtml namespace');
+lookupNamespaceURI(document, null, 'http://www.w3.org/1999/xhtml', 'Document should have xhtml namespace, prefix null');
+lookupNamespaceURI(document, '', 'http://www.w3.org/1999/xhtml', 'Document should have xhtml namespace, prefix ""');
 lookupNamespaceURI(document, 'prefix', null, 'Document has no namespace URI matching prefix');
 lookupNamespaceURI(document, 'bar', 'barURI', 'Document has bar namespace');
 
-isDefaultNamespace(document, null, false, 'For document, Empty namespace is not default');
-isDefaultNamespace(document, '', false, 'For document, Empty namespace is not default');
+isDefaultNamespace(document, null, false, 'For document, empty namespace is not default, prefix null');
+isDefaultNamespace(document, '', false, 'For document, empty namespace is not default, prefix ""');
 isDefaultNamespace(document, 'fooNamespace', false, 'For document, fooNamespace is not default');
 isDefaultNamespace(document, 'http://www.w3.org/2000/xmlns/', false, 'For document, xmlns namespace is not default');
 isDefaultNamespace(document, 'barURI', false, 'For document, bar namespace is not default');
 isDefaultNamespace(document, 'bazURI', false, 'For document, baz namespace is not default');
 isDefaultNamespace(document, 'http://www.w3.org/1999/xhtml', true, 'For document, xhtml namespace is default');
 
 var comment = document.createComment('comment');
 document.appendChild(comment);
--- a/testing/web-platform/tests/dom/nodes/getElementsByClassName-10.xml
+++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-10.xml
@@ -1,17 +1,19 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:g="http://www.w3.org/2000/svg">
  <head>
   <title>document.getElementsByClassName(): compound</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
  </head>
  <body>
   <div id="log"/>
-  <x class="a"/>
-  <g:x class="a"/>
+  <div id="tests">
+    <x class="a"/>
+    <g:x class="a"/>
+  </div>
   <script>test(function() {
                  assert_array_equals(document.getElementsByClassName("a"),
-                                     document.getElementsByTagName("x"));
+                                     document.getElementById("tests").children);
                })
   </script>
  </body>
 </html>
--- a/testing/web-platform/tests/dom/nodes/getElementsByClassName-11.xml
+++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-11.xml
@@ -1,22 +1,24 @@
 <html xmlns="http://www.w3.org/1999/xhtml" xmlns:g="http://www.w3.org/2000/svg" xmlns:h="http://www.w3.org/1999/xhtml" xmlns:t="http://tc.labs.opera.com/#test">
  <head>
   <title>document.getElementsByClassName(): "tricky" compound</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
  </head>
  <body>
   <div id="log" />
-  <x class="a"/>
-  <g:x class="a"/>
-  <x t:class="a" h:class="a" g:class="a"/>
-  <g:x t:class="a" h:class="a" g:class="a"/>
-  <t:x class="a" t:class="a" h:class="a" g:class="a"/>
+  <div id="tests">
+    <x class="a"/>
+    <g:x class="a"/>
+    <x t:class="a" h:class="a" g:class="a"/>
+    <g:x t:class="a" h:class="a" g:class="a"/>
+    <t:x class="a" t:class="a" h:class="a" g:class="a"/>
+  </div>
   <script>
    test(function() {
           var collection = document.getElementsByClassName("a");
-          var test = document.getElementsByTagName("x");
-          assert_array_equals(collection, [test[0], test[1]]);
+          var test = document.getElementById("tests").children;
+          assert_array_equals(collection, [test[0], test[1], test[4]]);
          })
   </script>
  </body>
 </html>
--- a/testing/web-platform/tests/dom/nodes/selectors.js
+++ b/testing/web-platform/tests/dom/nodes/selectors.js
@@ -261,36 +261,34 @@ var validSelectors = [
   // - ::after
   {name: ":after pseudo-element (one-colon syntax) selector, not matching any elements",         selector: "#pseudo-element:after",         expect: [] /*no matches*/, level: 2, testType: TEST_QSA},
   {name: "::after pseudo-element (two-colon syntax) selector, not matching any elements",        selector: "#pseudo-element::after",        expect: [] /*no matches*/, level: 3, testType: TEST_QSA},
 
   // Class Selectors
   {name: "Class selector, matching element with specified class",                                           selector: ".class-p",                expect: ["class-p1","class-p2", "class-p3"],                                              level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "Class selector, chained, matching only elements with all specified classes",                      selector: "#class .apple.orange.banana",    expect: ["class-div1", "class-div2", "class-p4", "class-div3", "class-p6", "class-div4"], level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "Class Selector, chained, with type selector",                                                     selector: "div.apple.banana.orange", expect: ["class-div1", "class-div2", "class-div3", "class-div4"],                         level: 1, testType: TEST_QSA | TEST_MATCH},
-  // Caution: If copying and pasting the folowing non-ASCII classes, ensure unicode normalisation is not performed in the process.
-  {name: "Class selector, matching element with class value using non-ASCII characters",                    selector: ".台北Táiběi",             expect: ["class-span1"],               level: 1, testType: TEST_QSA | TEST_MATCH},
-  {name: "Class selector, matching multiple elements with class value using non-ASCII characters",          selector: ".台北",                     expect: ["class-span1","class-span2"], level: 1, testType: TEST_QSA | TEST_MATCH},
-  {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters", selector: ".台北Táiběi.台北",          expect: ["class-span1"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, matching element with class value using non-ASCII characters (1)",                selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci",             expect: ["class-span1"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, matching multiple elements with class value using non-ASCII characters",          selector: ".\u53F0\u5317",                     expect: ["class-span1","class-span2"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters (1)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci.\u53F0\u5317",          expect: ["class-span1"],               level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "Class selector, matching element with class with escaped character",                              selector: ".foo\\:bar",              expect: ["class-span3"],               level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "Class selector, matching element with class with escaped character",                              selector: ".test\\.foo\\[5\\]bar",   expect: ["class-span4"],               level: 1, testType: TEST_QSA | TEST_MATCH},
 
   // ID Selectors
   {name: "ID selector, matching element with specified id",           selector: "#id #id-div1",              expect: ["id-div1"],            level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "ID selector, chained, matching element with specified id",  selector: "#id-div1, #id-div1",        expect: ["id-div1"],            level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "ID selector, chained, matching element with specified id",  selector: "#id-div1, #id-div2",        expect: ["id-div1", "id-div2"], level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "ID Selector, chained, with type selector",                  selector: "div#id-div1, div#id-div2",  expect: ["id-div1", "id-div2"], level: 1, testType: TEST_QSA | TEST_MATCH},
   {name: "ID selector, not matching non-existent descendant",         selector: "#id #none",                 expect: [] /*no matches*/,      level: 1, testType: TEST_QSA},
   {name: "ID selector, not matching non-existent ancestor",           selector: "#none #id-div1",            expect: [] /*no matches*/,      level: 1, testType: TEST_QSA},
   {name: "ID selector, matching multiple elements with duplicate id", selector: "#id-li-duplicate",          expect: ["id-li-duplicate", "id-li-duplicate", "id-li-duplicate", "id-li-duplicate"], level: 1, testType: TEST_QSA | TEST_MATCH},
 
-  // Caution: If copying and pasting the folowing non-ASCII IDs, ensure unicode normalisation is not performed in the process.
-  {name: "ID selector, matching id value using non-ASCII characters",    selector: "#台北Táiběi",           expect: ["台北Táiběi"],       level: 1, testType: TEST_QSA | TEST_MATCH},
-  {name: "ID selector, matching id value using non-ASCII characters",    selector: "#台北",                   expect: ["台北"],               level: 1, testType: TEST_QSA | TEST_MATCH},
-  {name: "ID selector, matching id values using non-ASCII characters",   selector: "#台北Táiběi, #台北",      expect: ["台北Táiběi", "台北"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, matching id value using non-ASCII characters (1)",    selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci",           expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci"],       level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, matching id value using non-ASCII characters (2)",    selector: "#\u53F0\u5317",                   expect: ["\u53F0\u5317"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, matching id values using non-ASCII characters (1)", selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci, #\u53F0\u5317",      expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci", "\u53F0\u5317"], level: 1, testType: TEST_QSA | TEST_MATCH},
 
   // XXX runMatchesTest() in level2-lib.js can't handle this because obtaining the expected nodes requires escaping characters when generating the selector from 'expect' values
   {name: "ID selector, matching element with id with escaped character", selector: "#\\#foo\\:bar",         expect: ["#foo:bar"],         level: 1, testType: TEST_QSA},
   {name: "ID selector, matching element with id with escaped character", selector: "#test\\.foo\\[5\\]bar", expect: ["test.foo[5]bar"],   level: 1, testType: TEST_QSA},
 
   // Namespaces
   // XXX runMatchesTest() in level2-lib.js can't handle these because non-HTML elements don't have a recognised id
   {name: "Namespace selector, matching element with any namespace",        selector: "#any-namespace *|div", expect: ["any-namespace-div1", "any-namespace-div2", "any-namespace-div3", "any-namespace-div4"], level: 3, testType: TEST_QSA},
@@ -626,36 +624,34 @@ var scopedSelectors = [
   // - ::after
   {name: ":after pseudo-element (one-colon syntax) selector, not matching any elements",         selector: "#pseudo-element:after",         ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND},
   {name: "::after pseudo-element (two-colon syntax) selector, not matching any elements",        selector: "#pseudo-element::after",        ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND},
 
   // Class Selectors
   {name: "Class selector, matching element with specified class (1)",                                           selector: ".class-p",                ctx: "", expect: ["class-p1","class-p2", "class-p3"],                                              level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "Class selector, chained, matching only elements with all specified classes (1)",                      selector: "#class .apple.orange.banana",    ctx: "", expect: ["class-div1", "class-div2", "class-p4", "class-div3", "class-p6", "class-div4"], level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "Class Selector, chained, with type selector (1)",                                                     selector: "div.apple.banana.orange", ctx: "", expect: ["class-div1", "class-div2", "class-div3", "class-div4"],                         level: 1, testType: TEST_FIND | TEST_MATCH},
-  // Caution: If copying and pasting the folowing non-ASCII classes, ensure unicode normalisation is not performed in the process.
-  {name: "Class selector, matching element with class value using non-ASCII characters",                    selector: ".台北Táiběi",             ctx: "", expect: ["class-span1"],               level: 1, testType: TEST_FIND | TEST_MATCH},
-  {name: "Class selector, matching multiple elements with class value using non-ASCII characters (1)",          selector: ".台北",                     ctx: "", expect: ["class-span1","class-span2"], level: 1, testType: TEST_FIND | TEST_MATCH},
-  {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters", selector: ".台北Táiběi.台北",          ctx: "", expect: ["class-span1"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, matching element with class value using non-ASCII characters (2)",                    selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci",             ctx: "", expect: ["class-span1"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, matching multiple elements with class value using non-ASCII characters (1)",          selector: ".\u53F0\u5317",                     ctx: "", expect: ["class-span1","class-span2"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters (2)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci.\u53F0\u5317",          ctx: "", expect: ["class-span1"],               level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "Class selector, matching element with class with escaped character (1)",                              selector: ".foo\\:bar",              ctx: "", expect: ["class-span3"],               level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "Class selector, matching element with class with escaped character (1)",                              selector: ".test\\.foo\\[5\\]bar",   ctx: "", expect: ["class-span4"],               level: 1, testType: TEST_FIND | TEST_MATCH},
 
   // ID Selectors
   {name: "ID selector, matching element with specified id (1)",           selector: "#id #id-div1",              ctx: "", expect: ["id-div1"],            level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "ID selector, chained, matching element with specified id (1)",  selector: "#id-div1, #id-div1",        ctx: "", expect: ["id-div1"],            level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "ID selector, chained, matching element with specified id (1)",  selector: "#id-div1, #id-div2",        ctx: "", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "ID Selector, chained, with type selector (1)",                  selector: "div#id-div1, div#id-div2",  ctx: "", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_FIND | TEST_MATCH},
   {name: "ID selector, not matching non-existent descendant",         selector: "#id #none",                 ctx: "", expect: [] /*no matches*/,      level: 1, testType: TEST_FIND},
   {name: "ID selector, not matching non-existent ancestor",           selector: "#none #id-div1",            ctx: "", expect: [] /*no matches*/,      level: 1, testType: TEST_FIND},
   {name: "ID selector, matching multiple elements with duplicate id (1)", selector: "#id-li-duplicate",          ctx: "", expect: ["id-li-duplicate", "id-li-duplicate", "id-li-duplicate", "id-li-duplicate"], level: 1, testType: TEST_FIND | TEST_MATCH},
 
-  // Caution: If copying and pasting the folowing non-ASCII IDs, ensure unicode normalisation is not performed in the process.
-  {name: "ID selector, matching id value using non-ASCII characters",    selector: "#台北Táiběi",           ctx: "", expect: ["台北Táiběi"],       level: 1, testType: TEST_FIND | TEST_MATCH},
-  {name: "ID selector, matching id value using non-ASCII characters (1)",    selector: "#台北",                   ctx: "", expect: ["台北"],               level: 1, testType: TEST_FIND | TEST_MATCH},
-  {name: "ID selector, matching id values using non-ASCII characters",   selector: "#台北Táiběi, #台北",      ctx: "", expect: ["台北Táiběi", "台北"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, matching id value using non-ASCII characters (3)",    selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci",           ctx: "", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci"],       level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, matching id value using non-ASCII characters (4)",    selector: "#\u53F0\u5317",                   ctx: "", expect: ["\u53F0\u5317"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, matching id values using non-ASCII characters (2)",   selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci, #\u53F0\u5317",      ctx: "", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci", "\u53F0\u5317"], level: 1, testType: TEST_FIND | TEST_MATCH},
 
   // XXX runMatchesTest() in level2-lib.js can't handle this because obtaining the expected nodes requires escaping characters when generating the selector from 'expect' values
   {name: "ID selector, matching element with id with escaped character", selector: "#\\#foo\\:bar",         ctx: "", expect: ["#foo:bar"],         level: 1, testType: TEST_FIND},
   {name: "ID selector, matching element with id with escaped character", selector: "#test\\.foo\\[5\\]bar", ctx: "", expect: ["test.foo[5]bar"],   level: 1, testType: TEST_FIND},
 
   // Namespaces
   // XXX runMatchesTest() in level2-lib.js can't handle these because non-HTML elements don't have a recognised id
   {name: "Namespace selector, matching element with any namespace",        selector: "#any-namespace *|div", ctx: "", expect: ["any-namespace-div1", "any-namespace-div2", "any-namespace-div3", "any-namespace-div4"], level: 3, testType: TEST_FIND},
--- a/testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/navigation-within-beforeunload.html
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/navigation-within-beforeunload.html
@@ -1,10 +1,10 @@
 <!doctype html>
-<title>Triggering navigation from withing beforeunload event</title>
+<title>Triggering navigation from within beforeunload event</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 beforeunload_fired = false;
 var t = async_test();
 
 var base_count = 0;
--- a/testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/unload/008.html
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/unload/008.html
@@ -1,14 +1,16 @@
 <!doctype html>
 <title>pagehide IDL attribute</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 var iframe;
 var t = async_test();
-onload = setTimeout(function() {
-                      var iframe = document.getElementsByTagName("iframe")[0];
-                      iframe.src="about:blank";
-                    }, 100)
+onload = function() {
+  setTimeout(function() {
+    var iframe = document.getElementsByTagName("iframe")[0];
+    iframe.src="about:blank";
+  }, 100)
+};
 </script>
 <iframe src="008-1.html"></iframe>
--- a/testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/unload/009.html
+++ b/testing/web-platform/tests/html/browsers/browsing-the-web/unloading-documents/unload/009.html
@@ -1,14 +1,16 @@
 <!doctype html>
 <title>unload IDL attribute</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id="log"></div>
 <script>
 var iframe;
 var t = async_test();
-onload = setTimeout(function() {
-                      var iframe = document.getElementsByTagName("iframe")[0];
-                      iframe.src="about:blank";
-                    }, 100)
+onload = function() {
+  setTimeout(function() {
+    var iframe = document.getElementsByTagName("iframe")[0];
+    iframe.src="about:blank";
+  }, 100)
+}
 </script>
 <iframe src="009-1.html"></iframe>
--- a/testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html
+++ b/testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/frameElement.sub.html
@@ -2,54 +2,71 @@
 <meta charset="utf-8"/>
 <title>HTML Test: window.frameElement</title>
 <link rel="author" title="Intel" href="http://www.intel.com/" />
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script>
 
 var t1 = async_test("The window's frameElement attribute must return its container element if it is a nested browsing context");
-var t2 = async_test("The SecurityError must be thrown if the container's document does not have the same effective script origin");
+var t2 = async_test("The SecurityError must be thrown if the window accesses to frameElement attribute of a Window which does not have the same effective script origin");
+var t3 = async_test("The window's frameElement attribute must return null if the container's document does not have the same effective script origin");
 
 function on_load() {
   t1.step(function () {
     assert_equals(frames[0].frameElement, document.getElementById("fr1"),
                   "The frameElement attribute should be the first iframe element.");
     assert_equals(window["win2"].frameElement, document.getElementById("obj"),
                   "The frameElement attribute should be the object element.");
     assert_equals(window["win3"].frameElement, document.getElementById("emb"),
                   "The frameElement attribute should be the embed element.");
-    assert_equals(document.getElementById("fr3").contentWindow[0].frameElement,
-                  document.getElementById("fr3").contentDocument.getElementById("f1"),
-                 "The frameElement attribute should be the frame element in 'test.html'.");
+    assert_equals(document.getElementById("fr4").contentWindow[0].frameElement,
+                  document.getElementById("fr4").contentDocument.getElementById("f1"),
+                  "The frameElement attribute should be the frame element in 'test.html'.");
   });
   t1.done();
 
   t2.step(function () {
     assert_throws("SecurityError", function () { frames[1].frameElement; },
                   "The SecurityError exception should be thrown.");
   });
   t2.done();
+
+  t3.step(function () {
+    document.getElementById("fr5").contentWindow.postMessage(null, "*");
+  });
+  window.addEventListener("message", function (event) {
+    var data = JSON.parse(event.data);
+    if (data.name == "testcase3") {
+      t3.step(function () {
+        assert_equals(data.result, "window.frameElement = null",
+                      "The frameElement attribute should be null.");
+      });
+      t3.done();
+    }
+  }, false);
 }
 
 </script>
 <body onload="on_load()">
   <div id="log"></div>
   <iframe id="fr1"></iframe>
-  <iframe id="fr2" src="test.html"></iframe>
+  <iframe id="fr2" src="test.html"></iframe> <!-- cross origin -->
   <iframe id="fr3" src="" style="display:none"></iframe>
   <object id="obj" name="win2" type="text/html" data="about:blank"></object>
   <embed id="emb" name="win3" type="image/svg+xml" src="/images/green.svg" />
+  <iframe id="fr4" src="test.html"></iframe> <!-- same origin -->
+  <iframe id="fr5" src="testcase3.html"></iframe> <!-- cross origin -->
   <script>
 
   setup(function () {
-    var src = "http://{{domains[www1]}}:{{ports[http][0]}}";
-    src += document.location.pathname.substring(0, document.location.pathname.lastIndexOf("/") + 1);
-    src += "test.html";
-    document.getElementById("fr2").src = src;
+    var src_base = "http://{{domains[www1]}}:{{ports[http][0]}}";
+    src_base += document.location.pathname.substring(0, document.location.pathname.lastIndexOf("/") + 1);
+    document.getElementById("fr2").src = src_base + "test.html";
+    document.getElementById("fr5").src = src_base + "testcase3.html";
   });
 
   test(function () {
     assert_equals(window.frameElement, null,
                   "The frameElement attribute should be null.");
   }, "The window's frameElement attribute must return null if it is not a nested browsing context");
 
   </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/browsers/windows/nested-browsing-contexts/testcase3.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<title>Testcase 3: frameElement attribute must return null if the container\'s document does not have the same effective script origin</title>
+<script>
+window.addEventListener("message", function (event) {
+  try {
+    var result = "window.frameElement = " + window.frameElement;
+  } catch (e) {
+    result = e.message;
+  }
+  event.source.postMessage(JSON.stringify({name: "testcase3", result: result}),
+                           "*");
+}, false);
+</script>
--- a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified-01.html
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified-01.html
@@ -20,24 +20,28 @@
                          "Format should match the pattern \"NN/NN/NNNN NN:NN:NN\".");
   }, "Date returned by lastModified is in the form \"MM/DD/YYYY hh:mm:ss\".");
 
 
   var hours = d.getHours()
   var minutes = d.getMinutes()
   var seconds = d.getSeconds()
 
-  test(function() {
-    var local_time = hours * 60 * 60 + minutes * 60 + seconds;
-    var m = pattern.exec(last_modified);
-    var last_modified_time = parseInt(m[1]) * 60 * 60 + parseInt(m[2]) * 60 + parseInt(m[3]);
-    assert_approx_equals(last_modified_time, local_time, 2,
-                         "Hours and minutes should match local time.");
-  }, "Date returned by lastModified is in the user's local time zone.");
-
+  // Checking whether d and and new instance of Date have the same timezone.
+  // Do not run the time zone test in the case daylight saving occurs.
+  var d2 = new Date();
+  if (d2.getTimezoneOffset() == d.getTimezoneOffset()) {
+    test(function() {
+      var local_time = hours * 60 * 60 + minutes * 60 + seconds;
+      var m = pattern.exec(last_modified);
+      var last_modified_time = parseInt(m[1]) * 60 * 60 + parseInt(m[2]) * 60 + parseInt(m[3]);
+      assert_approx_equals(last_modified_time, local_time, 2,
+                           "Hours and minutes should match local time.");
+    }, "Date returned by lastModified is in the user's local time zone.");
+  }
   var t = async_test("Date returned by lastModified is current after timeout.");
 
   setTimeout(function() {
     t.step(function() {
       var new_modified = Date.parse(document.lastModified) / 1000;
       var new_expected = Math.round(new Date() / 1000);
       assert_approx_equals(new_modified, new_expected, 2.5,
                            "(initial value was " + initial_modified + ")");
--- a/testing/web-platform/tests/html/dom/elements-embedded.js
+++ b/testing/web-platform/tests/html/dom/elements-embedded.js
@@ -136,17 +136,17 @@ var embeddedElements = {
     target: "string",
     download: "string",
     ping: "urls",
     rel: "string",
     relList: {type: "tokenlist", domAttrName: "rel"},
     hreflang: "string",
     type: "string",
 
-          //URLUtils
+    // HTMLHyperlinkElementUtils
     href: "url",
 
     // Obsolete
     noHref: "boolean"
   },
 };
 
 mergeElements(embeddedElements);
--- a/testing/web-platform/tests/html/dom/elements-text.js
+++ b/testing/web-platform/tests/html/dom/elements-text.js
@@ -5,17 +5,17 @@ var textElements = {
     target: "string",
     download: "string",
     ping: "urls",
     rel: "string",
     relList: {type: "tokenlist", domAttrName: "rel"},
     hreflang: "string",
     type: "string",
 
-    // URLUtils
+    // HTMLHyperlinkElementUtils
     href: "url",
 
     // Obsolete
     coords: "string",
     charset: "string",
     name: "string",
     rev: "string",
     shape: "string",
--- a/testing/web-platform/tests/html/dom/interfaces.html
+++ b/testing/web-platform/tests/html/dom/interfaces.html
@@ -6,26 +6,16 @@
 <script src=/resources/testharness.js></script>
 <script src=/resources/testharnessreport.js></script>
 <script src=/resources/WebIDLParser.js></script>
 <script src=/resources/idlharness.js></script>
 
 <h1>HTML IDL tests</h1>
 <div id=log></div>
 
-<!-- URLUtils* stubs -->
-<script type=text/plain class=untested>
-interface URLUtils {
-  stringifier;
-};
-interface URLUtilsReadOnly {
-  stringifier;
-};
-</script>
-<!-- DOM IDLs -->
 <script type=text/plain class=untested>
 [Constructor(DOMString type, optional EventInit eventInitDict)/*,
  Exposed=(Window,Worker)*/]
 interface Event {
   readonly attribute DOMString type;
   readonly attribute EventTarget? target;
   readonly attribute EventTarget? currentTarget;
 
@@ -863,16 +853,31 @@ interface CSSPropertyValue {
 <!-- HTML IDLs -->
 <script type=text/plain>
 typedef (Int8Array or Uint8Array or Uint8ClampedArray or
          Int16Array or Uint16Array or
          Int32Array or Uint32Array or
          Float32Array or Float64Array or
          DataView) ArrayBufferView;
 
+[NoInterfaceObject, Exposed=Window]
+interface HTMLHyperlinkElementUtils {
+  stringifier attribute USVString href;
+           attribute USVString origin;
+           attribute USVString protocol;
+           attribute USVString username;
+           attribute USVString password;
+           attribute USVString host;
+           attribute USVString hostname;
+           attribute USVString port;
+           attribute USVString pathname;
+           attribute USVString search;
+           attribute USVString hash;
+};
+
 interface HTMLAllCollection : HTMLCollection {
   // inherits length and 'getter'
   Element? item(unsigned long index);
   (HTMLCollection or Element)? item(DOMString name);
   legacycaller getter (HTMLCollection or Element)? namedItem(DOMString name); // shadows inherited namedItem()
 };
 
 interface HTMLFormControlsCollection : HTMLCollection {
@@ -1120,29 +1125,27 @@ interface HTMLDListElement : HTMLElement
   // also has obsolete members
 };
 
 interface HTMLDivElement : HTMLElement {
   // also has obsolete members
 };
 
 interface HTMLAnchorElement : HTMLElement {
-           attribute DOMString target;
-           attribute DOMString download;
-  [PutForwards=value] attribute DOMSettableTokenList ping;
-           attribute DOMString rel;
+  attribute DOMString target;
+  attribute DOMString download;
+  [PutForwards=value] readonly attribute DOMSettableTokenList ping;
+  attribute DOMString rel;
   readonly attribute DOMTokenList relList;
-           attribute DOMString hreflang;
-           attribute DOMString type;
-
-           attribute DOMString text;
-
-  // also has obsolete members
+  attribute DOMString hreflang;
+  attribute DOMString type;
+
+  attribute DOMString text;
 };
-HTMLAnchorElement implements URLUtils;
+HTMLAnchorElement implements HTMLHyperlinkElementUtils;
 
 interface HTMLDataElement : HTMLElement {
            attribute DOMString value;
 };
 
 interface HTMLTimeElement : HTMLElement {
            attribute DOMString dateTime;
 };
@@ -1489,30 +1492,27 @@ dictionary TrackEventInit : EventInit {
 
 interface HTMLMapElement : HTMLElement {
            attribute DOMString name;
   readonly attribute HTMLCollection areas;
   readonly attribute HTMLCollection images;
 };
 
 interface HTMLAreaElement : HTMLElement {
-           attribute DOMString alt;
-           attribute DOMString coords;
-           attribute DOMString shape;
-           attribute DOMString target;
-           attribute DOMString download;
-  [PutForwards=value] attribute DOMSettableTokenList ping;
-           attribute DOMString rel;
+  attribute DOMString alt;
+  attribute DOMString coords;
+  attribute DOMString shape;
+  attribute DOMString target;
+  attribute DOMString download;
+  [PutForwards=value] readonly attribute DOMSettableTokenList ping;
+  attribute DOMString rel;
   readonly attribute DOMTokenList relList;
-           attribute DOMString hreflang;
-           attribute DOMString type;
-
-  // also has obsolete members
+  // hreflang and type are not reflected
 };
-HTMLAreaElement implements URLUtils;
+HTMLAreaElement implements HTMLHyperlinkElementUtils;
 
 interface HTMLTableElement : HTMLElement {
            attribute HTMLTableCaptionElement? caption;
   HTMLElement createCaption();
   void deleteCaption();
            attribute HTMLTableSectionElement? tHead;
   HTMLElement createTHead();
   void deleteTHead();
@@ -2315,21 +2315,32 @@ interface History {
   void go(optional long delta);
   void back();
   void forward();
   void pushState(any data, DOMString title, optional DOMString? url = null);
   void replaceState(any data, DOMString title, optional DOMString? url = null);
 };
 
 [Unforgeable] interface Location {
-  void assign(DOMString url);
-  void replace(DOMString url);
+  stringifier attribute USVString href;
+           attribute USVString origin;
+           attribute USVString protocol;
+           attribute USVString host;
+           attribute USVString hostname;
+           attribute USVString port;
+           attribute USVString pathname;
+           attribute USVString search;
+           attribute USVString hash;
+
+  void assign(USVString url);
+  void replace(USVString url);
   void reload();
+
+  [SameObject] readonly attribute USVString[] ancestorOrigins;
 };
-Location implements URLUtils;
 
 [Constructor(DOMString type, optional PopStateEventInit eventInitDict), Exposed=Window,Worker]
 interface PopStateEvent : Event {
   readonly attribute any state;
 };
 
 dictionary PopStateEventInit : EventInit {
   any state;
@@ -2811,18 +2822,27 @@ WorkerGlobalScope implements WindowBase6
 
 [Exposed=Worker]
 interface WorkerNavigator {};
 WorkerNavigator implements NavigatorID;
 WorkerNavigator implements NavigatorLanguage;
 WorkerNavigator implements NavigatorOnLine;
 
 [Exposed=Worker]
-interface WorkerLocation { };
-WorkerLocation implements URLUtilsReadOnly;
+interface WorkerLocation {
+  stringifier readonly attribute USVString href;
+  readonly attribute USVString origin;
+  readonly attribute USVString protocol;
+  readonly attribute USVString host;
+  readonly attribute USVString hostname;
+  readonly attribute USVString port;
+  readonly attribute USVString pathname;
+  readonly attribute USVString search;
+  readonly attribute USVString hash;
+};
 
 interface Storage {
   readonly attribute unsigned long length;
   DOMString? key(unsigned long index);
   getter DOMString? getItem(DOMString key);
   setter creator void setItem(DOMString key, DOMString value);
   deleter void removeItem(DOMString key);
   void clear();
--- a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html
+++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html
@@ -4,30 +4,32 @@
 <title>HTMLAllCollection Tests</title>
 <link rel="author" title="Dan Druta" href="mailto:dan.druta@att.com"/>
 <link rel="help" href="2.7.2.1 - Common Infrastructure/Common DOM Interfaces/Collections/HTMLAllCollection"/>
 <meta name="flags" content="TOKENS" />
 <meta name="assert" content="TEST ASSERTION"/>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 </head>
-<body>
+<body id="tags">
 <img src="../../../../images/green.png" name="picture">
 <script>
 test(function(){ assert_equals(document.all.length,12)}, "Test for HTMLAllCollection size");
 
 test(function(){ assert_equals(document.all.item(0).tagName,"HTML")}, "Test lookup by index using ()");
 
 test(function(){ assert_equals(document.all[0].tagName,"HTML")}, "Test lookup by index using []");
 
-test(function(){ assert_equals(document.all.tags("script").length,3)}, "Test for multiple occurence 3 <script> found");
-
 test(function(){ assert_equals(document.all.item("picture").nodeName,"IMG")}, "Test lookup IMG by name");
 
 test(function(){ assert_equals(document.all.namedItem("picture").nodeName,"IMG")}, "Test lookup IMG by namedItem ");
 
 test(function(){ assert_equals(document.all("picture").nodeName,"IMG")}, "Test lookup IMG in collection using ()");
 
 test(function(){ assert_equals(document.all["picture"].nodeName,"IMG")}, "Test lookup IMG in collection using []");
+
+test(function(){ assert_equals(document.all.picture.nodeName,"IMG")}, "Test lookup IMG in collection using .");
+
+test(function(){ assert_equals(document.all.tags.id,"tags")}, "Test lookup tags in collection using .");
 </script>
 <div id="log"></div>
 </body>
-</html>
\ No newline at end of file
+</html>
--- a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html
+++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html
@@ -13,18 +13,22 @@
 <form id="f2">
   <table>
     <tr>
       <td>
         <input type="checkbox" id="cb">
         <input type="checkbox" name="cb">
       </td>
     </tr>
-    <button id="btn"></button>
-    <button name="btn"></button>
+    <tr>
+      <td>
+        <button id="btn"></button>
+        <button name="btn"></button>
+      </td>
+    </tr>
   </table>
 </form>
 
 <script>
 
 var coll1, coll2, rdo;
 
 setup(function () {
@@ -45,18 +49,18 @@ test(function () {
 }, "HTMLFormControlsCollection.item(index) must return the indexed item");
 
 test(function () {
   assert_equals(coll1[0], rdo, "HTMLFormControlsCollection[index] should return the 'input' element in radio status.");
 }, "HTMLFormControlsCollection[index] must return the indexed item");
 
 //getter - name
 test(function () {
-  assert_equals(coll1("r1"), rdo, "HTMLFormControlsCollection(name) should return the 'input' element in radio status.");
-}, "HTMLFormControlsCollection(name) must return the named item");
+  assert_throws(TypeError(), function() { coll1("r1") });
+}, "HTMLFormControlsCollection is not callable");
 
 test(function () {
   assert_equals(coll1["r1"], rdo, "HTMLFormControlsCollection[name] should return the 'input' element in radio status.");
 }, "HTMLFormControlsCollection[name] must return the named item");
 
 //getter - namedItem
 test(function () {
   assert_equals(coll1.namedItem("r1"), rdo, "HTMLFormControlsCollection.namedItem(name) should return the 'input' element in radio status.");
--- a/testing/web-platform/tests/html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/script-IDL-event-htmlfor.html
+++ b/testing/web-platform/tests/html/obsolete/requirements-for-implementations/other-elements-attributes-and-apis/script-IDL-event-htmlfor.html
@@ -11,47 +11,47 @@ test(function() {
   var script = document.createElement("script");
   assert_equals(script.event, "");
   assert_equals(script.htmlFor, "");
 })
 test(function() {
   var script = document.createElement("script");
   script.setAttribute("event", "blah");
   script.setAttribute("for", "blah");
-  assert_equals(script.event, "");
-  assert_equals(script.htmlFor, "");
+  assert_equals(script.event, "blah");
+  assert_equals(script.htmlFor, "blah");
   assert_equals(script.getAttribute("event"), "blah");
   assert_equals(script.getAttribute("for"), "blah");
 })
 test(function() {
   var script = document.createElement("script");
   script.setAttribute("event", "blah");
   script.setAttribute("for", "blah");
   script.event = "foo";
   script.htmlFor = "foo";
-  assert_equals(script.event, "");
-  assert_equals(script.htmlFor, "");
-  assert_equals(script.getAttribute("event"), "blah");
-  assert_equals(script.getAttribute("for"), "blah");
+  assert_equals(script.event, "foo");
+  assert_equals(script.htmlFor, "foo");
+  assert_equals(script.getAttribute("event"), "foo");
+  assert_equals(script.getAttribute("for"), "foo");
 })
 test(function() {
   var script = document.createElement("script");
   script.setAttribute("event", "blah");
   script.setAttribute("for", "blah");
   script.event = null;
   script.htmlFor = null;
-  assert_equals(script.event, "");
-  assert_equals(script.htmlFor, "");
-  assert_equals(script.getAttribute("event"), "blah");
-  assert_equals(script.getAttribute("for"), "blah");
+  assert_equals(script.event, "null");
+  assert_equals(script.htmlFor, "null");
+  assert_equals(script.getAttribute("event"), "null");
+  assert_equals(script.getAttribute("for"), "null");
 })
 test(function() {
   var script = document.createElement("script");
   script.setAttribute("event", "blah");
   script.setAttribute("for", "blah");
   script.event = undefined;
   script.htmlFor = undefined;
-  assert_equals(script.event, "");
-  assert_equals(script.htmlFor, "");
-  assert_equals(script.getAttribute("event"), "blah");
-  assert_equals(script.getAttribute("for"), "blah");
+  assert_equals(script.event, "undefined");
+  assert_equals(script.htmlFor, "undefined");
+  assert_equals(script.getAttribute("event"), "undefined");
+  assert_equals(script.getAttribute("for"), "undefined");
 })
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<link rel="match" href="div-align-ref.html">
+<style>
+.test { width: 50px; background-color: yellow; }
+.center { text-align: center; }
+.center .test { margin: 0 auto; }
+.left { text-align: left; }
+.left .test { margin-right: auto; }
+.right { text-align: right; }
+.right .test { margin-left: auto; }
+.rtl { direction: rtl; }
+.ltr { direction: ltr; }
+.left .margin { margin-left: 1em; }
+.right .margin { margin-right: 1em; }
+</style>
+</head>
+<body>
+<!-- Centered tests -->
+<div class=center>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class=center>
+<div class="test left">t א</div>
+<div class="test right">t א</div>
+</div>
+
+<div class=left>
+<div class=center>
+<div class=test>t א</div>
+</div>
+</div>
+
+<!-- Left-aligned tests -->
+<div class=left>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class="left rtl">
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class=left>
+<div class="test center">t א</div>
+<div class="test right">t א</div>
+</div>
+
+<!-- Right-aligned tests -->
+<div class=right>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class="right rtl">
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class=right>
+<div class="test left">t א</div>
+<div class="test center">t א</div>
+</div>
+
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<style>
+.test { width: 50px; background-color: yellow; }
+.rtl { direction: rtl; }
+.ltr { direction: ltr; }
+[align=left] .margin { margin-left: 1em }
+[align=right] .margin { margin-right: 1em }
+</style>
+</head>
+<body>
+<!-- Centered tests -->
+<div align=center>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=center>
+<div class=test align=left>t א</div>
+<div class=test align=right>t א</div>
+</div>
+
+<div align=left>
+<div align=center>
+<div class=test>t א</div>
+</div>
+</div>
+
+<!-- Left-aligned tests -->
+<div align=left>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=left class=rtl>
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=left>
+<div class=test align=center>t א</div>
+<div class=test align=right>t א</div>
+</div>
+
+<!-- Right-aligned tests -->
+<div align=right>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=right class=rtl>
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=right>
+<div class=test align=left>t א</div>
+<div class=test align=center>t א</div>
+</div>
+
+</body>
+</html>
+
--- a/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js
@@ -280,40 +280,20 @@ var validator = {
     });
     for (var attr in obj) {
       if (attr === "checked" || obj[attr] || obj[attr] === "")
         ctl[attr] = obj[attr];
     }
   },
 
   set_dirty: function(ctl) {
-    document.designMode = "on";
     ctl.focus();
     var old_value = ctl.value;
     ctl.value = "a";
     ctl.value = old_value;
-    if (
-      // See https://html.spec.whatwg.org/multipage/#input-type-attr-summary
-      // and https://html.spec.whatwg.org/multipage/#textFieldSelection
-      (
-        ctl.tagName === "INPUT" && (
-          ctl.type === "text" ||
-          ctl.type === "search" ||
-          ctl.type === "tel" ||
-          ctl.type === "url" ||
-          ctl.type === "password"
-        )
-      ) ||
-      ctl.tagName === "TEXTAREA"
-    ) {
-      ctl.value += "1";
-      ctl.setSelectionRange(ctl.value.length - 1, ctl.value.length);
-      document.execCommand("Delete");
-    }
-    document.designMode = "off";
   },
 
   pre_check: function(ctl, item) {
     switch (item) {
       case "willValidate":
         assert_true(item in ctl, "The " + item + " attribute doesn't exist.");
         break;
       case "checkValidity":
--- a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-recurse.html
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-recurse.html
@@ -69,9 +69,24 @@ test(function() {
   assert_equals(option.text, "text");
 }, "option.text should work if the option is in an SVG script element");
 test(function() {
   var script = document.createElementNS("http://www.w3.org/1998/Math/MathML", "script");
   var option = script.appendChild(document.createElement("option"));
   option.appendChild(document.createTextNode("text"));
   assert_equals(option.text, "text");
 }, "option.text should work if the option is in a MathML script element");
+
+test(function() {
+  var option = document.createElement("option");
+  option.appendChild(document.createTextNode("te"));
+  option.appendChild(document.createComment("comment"));
+  option.appendChild(document.createTextNode("xt"));
+  assert_equals(option.text, "text");
+}, "option.text should ignore comment children");
+test(function() {
+  var option = document.createElement("option");
+  option.appendChild(document.createTextNode("te"));
+  option.appendChild(document.createProcessingInstruction("target", "data"));
+  option.appendChild(document.createTextNode("xt"));
+  assert_equals(option.text, "text");
+}, "option.text should ignore PI children");
 </script>
--- a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html
@@ -1,15 +1,17 @@
 <!DOCTYPE html>
 <html>
 <head>
 <meta charset="utf-8">
 <title id='title'>HTMLOptionsCollection</title>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
 <div id="log"></div>
 <select id="selly">
   <option id="id1" name="name1">1</option>
   <option id="id2" name="name2">2</option>
   <option id="id3" name="name3">3</option>
   <option id="id4" name="name4">4</option>
   <option name="nameonly">nameonly</option>
   <option id="id3">duplicate ID</option>
@@ -32,31 +34,21 @@ test(function () {
     assert_equals(selly.namedItem('id2')["value"], "2");
 }, "if only one item has a name or *id* value matching the parameter, return that object and stop");
 
 test(function () {
     assert_equals(selly.namedItem('thisdoesnotexist'), null);
 }, "if no item has a name or id value matching the parameter, return null and stop");
 
 test(function () {
-    var testarr = [];
-    for (var i = 0; i < selly.namedItem('id3').length; i++) {
-        testarr.push(selly.namedItem('id3')[i].text);
-    }
-    assert_array_equals(testarr, ['3','duplicate ID']);
-}, "return an HTMLOptionsCollection in correct order for repeated 'id' value");
+    assert_equals(selly.namedItem('id3')["value"], "3");
+}, "if multiple items have a name or *id* value matching the parameter, return the first object and stop");
 
 test(function () {
-    var testarr = [];
-    for (var i = 0; i < selly.namedItem('name4').length; i++) {
-        testarr.push(selly.namedItem('name4')[i].text);
-    }
-    assert_array_equals(testarr, ['4', 'duplicate name']);
-}, "return an HTMLOptionsCollection in correct order for repeated 'name' value");
+    assert_equals(selly.namedItem('name4')["value"], "4");
+}, "if multiple items have a *name* or id value matching the parameter, return the first object and stop");
 
 test(function () {
-    var testarr = [];
-    for (var i = 0; i < selly.namedItem('mixed1').length; i++) {
-        testarr.push(selly.namedItem('mixed1')[i].text);
-    }
-    assert_array_equals(testarr, ['mixed ID', 'mixed name']);
-}, "return an HTMLOptionsCollection in correct order for repeated mixed value");
+    assert_equals(selly.namedItem('mixed1')["value"], "mixed ID");
+}, "if multiple items have a *name* or *id* value matching the parameter, return the first object and stop");
 </script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html
@@ -0,0 +1,97 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLSelectElement ask for reset</title>
+<link rel="author" title="Dongie Agnir" href="dongie.agnir@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+  var select = makeSelect(5);
+
+  select.children[4].selected = true;
+  unselectedExcept(select, 4);
+
+  select.children[4].remove();
+  unselectedExcept(select, 0); // remove selected node, should default to first
+
+  select.children[3].selected = true;
+
+  select.children[0].remove();
+  unselectedExcept(select, 2); // last node still selected
+
+  select.size = 2;
+  select.children[2].remove();
+
+  unselectedExcept(select, null);
+}, "ask for reset on node remove, non multiple.");
+
+test(function() {
+  var select = makeSelect(3);
+  select.children[1].selected = true;
+
+  // insert selected option, should remain selected
+  var opt4 = document.createElement("option");
+  opt4.selected = true;
+  select.appendChild(opt4);
+  unselectedExcept(select, 3);
+
+  // insert unselected, 3 should remain selected
+  var opt5 = document.createElement("option");
+  select.appendChild(opt5);
+  unselectedExcept(select, 3);
+}, "ask for reset on node insert, non multiple.");
+
+test(function() {
+  var select = makeSelect(3);
+
+  var options = select.children;
+
+  // select options from first to last
+  for (var i = 0; i < options.length; ++i) {
+    options[i].selected = true;
+    unselectedExcept(select, i);
+  }
+
+  // select options from last to first
+  for (var i = options.length - 1; i >= 0; --i) {
+    options[i].selected = true;
+    unselectedExcept(select, i);
+  }
+
+  options[2].selected = true;
+  options[2].selected = false; // none selected
+  unselectedExcept(select, 0);
+
+  // disable first so option at index 1 is first eligible
+  options[0].disabled = true;
+  options[2].selected = true;
+  options[2].selected = false; // none selected
+  unselectedExcept(select, 1);
+
+  select.size = 2;
+  options[1].selected = false;
+  unselectedExcept(select, null); // size > 1 so should not default to any
+}, "change selectedness of option, non multiple.");
+
+
+function unselectedExcept(sel, opt) {
+  for (var i = 0; i < sel.children.length; ++i) {
+    if (i != opt) {
+      assert_false(sel.children[i].selected, "option should not be selected.");
+    }
+    if (opt != null) {
+      assert_true(sel.children[opt].selected, "option should be selected.");
+    }
+  }
+}
+
+function makeSelect(n) {
+  var sel = document.createElement("select");
+  for (var i = 0; i < n; ++i) {
+    opt = document.createElement("option");
+    sel.appendChild(opt);
+  }
+  return sel;
+}
+</script>
--- a/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/cellIndex.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/cellIndex.html
@@ -33,9 +33,18 @@ test(function() {
 }, "For cells whose parent is not a HTML tr, cellIndex should be -1.")
 test(function() {
   var tr = document.createElement("tr");
   var th = tr.appendChild(document.createElement("th"));
   assert_equals(th.cellIndex, 0);
   var td = tr.appendChild(document.createElement("td"));
   assert_equals(td.cellIndex, 1);
 }, "For cells whose parent is a tr, cellIndex should be the index.")
+test(function() {
+  var tr = document.createElement("tr");
+  var th = tr.appendChild(document.createElement("th"));
+  assert_equals(th.cellIndex, 0);
+  tr.appendChild(document.createElement("div"));
+  tr.appendChild(document.createTextNode("Hello World"));
+  var td = tr.appendChild(document.createElement("td"));
+  assert_equals(td.cellIndex, 1)
+}, "For cells whose parent is a tr with non td/th sibling, cellIndex should skip those non td/th siblings.")
 </script>
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/deleteRow.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/deleteRow.html
@@ -38,9 +38,17 @@ test(function () {
 }, "HTMLTableSectionElement deleteRow(rows.length)");
 
 test(function () {
   assert_throws("IndexSizeError", function () {
     tbody.deleteRow(-2);
   });
 }, "HTMLTableSectionElement deleteRow(-2)");
 
+test(function () {
+  assert_equals(tbody.rows.length, 1);
+  tbody.deleteRow(-1);
+  assert_equals(tbody.rows.length, 0);
+  tbody.deleteRow(-1);
+  assert_equals(tbody.rows.length, 0);
+}, "HTMLTableSectionElement deleteRow(-1) with no rows");
+
 </script>
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/insertRow.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/insertRow.html
@@ -31,16 +31,22 @@ test(function () {
 
 test(function () {
   var trEle = tbody.insertRow();
   assert_equals(tbody.rows[tbody.rows.length - 1], trEle);
   assert_equals(tbody.rows.length, 4);
 }, "HTMLTableSectionElement insertRow()");
 
 test(function () {
+  var trEle = tbody.insertRow(tbody.rows.length);
+  assert_equals(tbody.rows[tbody.rows.length - 1], trEle);
+  assert_equals(tbody.rows.length, 5);
+}, "HTMLTableSectionElement insertRow(rows.length)");
+
+test(function () {
   assert_throws("IndexSizeError", function () {
     tbody.insertRow(-2);
   });
 }, "HTMLTableSectionElement insertRow(-2)");
 
 test(function () {
   assert_throws("IndexSizeError", function () {
     tbody.insertRow(tbody.rows.length + 1);
--- a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/deleteCell.html
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/deleteCell.html
@@ -38,9 +38,17 @@ test(function () {
 }, "HTMLTableRowElement deleteCell(-2)");
 
 test(function () {
   assert_throws("IndexSizeError", function () {
     tr.deleteCell(tr.cells.length);
   });
 }, "HTMLTableRowElement deleteCell(cells.length)");
 
+test(function () {
+  assert_equals(tr.cells.length, 1);
+  tr.deleteCell(-1);
+  assert_equals(tr.cells.length, 0);
+  tr.deleteCell(-1);
+  assert_equals(tr.cells.length, 0);
+}, "HTMLTableRowElement deleteCell(-1) with no cells");
+
 </script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/animation-frames/callback-multicalls.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>AnimationTiming Test: multiple calls to requestAnimationFrame with the same callback</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#dom-window-requestanimationframe">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+
+  async_test(function(t) {
+    var counter = 0;
+    window.requestAnimationFrame(callback);
+
+    function callback() {
+      ++counter;
+      if (counter == 2) {
+        t.done();
+      } else {
+        window.requestAnimationFrame(callback);
+      }
+    };
+
+  }, "Check that multiple calls to requestAnimationFrame with the same callback will result in multiple entries being in the list with that same callback.");
+
+</script>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-body-window.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>HTMLBodyElement event handlers</title>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<body>
+<script>
+function f() {
+  return 0;
+}
+
+var handlers = ['blur','error','focus','load','resize','scroll',
+                'afterprint','beforeprint','beforeunload','hashchange',
+                'languagechange','message','offline','online','pagehide',
+                'pageshow','popstate','storage','unload'];
+handlers.forEach(function(handler) {
+  test(function() {
+    document.body['on' + handler] = f;
+    assert_equals(window['on' + handler], f);
+  }, handler);
+});
+
+</script>
--- a/testing/web-platform/tests/lint.whitelist
+++ b/testing/web-platform/tests/lint.whitelist
@@ -19,17 +19,16 @@ INDENT TABS: html/editing/dnd/*
 INDENT TABS: old-tests/*
 INDENT TABS: pointerlock/*
 INDENT TABS: shadow-dom/*
 INDENT TABS: svg/import/*
 INDENT TABS: tools/*
 INDENT TABS: touch-events/*
 INDENT TABS: web-animations/*
 INDENT TABS: webaudio/*
-INDENT TABS: webdriver/*
 INDENT TABS: webvtt/*
 INDENT TABS: XMLHttpRequest/*
 
 TRAILING WHITESPACE: app-uri/*
 TRAILING WHITESPACE: battery-status/*
 TRAILING WHITESPACE: conformance-checkers/*
 TRAILING WHITESPACE: content-security-policy/*
 TRAILING WHITESPACE: custom-elements/*
@@ -38,17 +37,16 @@ TRAILING WHITESPACE: html-longdesc/*
 TRAILING WHITESPACE: microdata/*
 TRAILING WHITESPACE: old-tests/*
 TRAILING WHITESPACE: pointerevents/*
 TRAILING WHITESPACE: progress-events/*
 TRAILING WHITESPACE: shadow-dom/*
 TRAILING WHITESPACE: svg/import/*
 TRAILING WHITESPACE: tools/*
 TRAILING WHITESPACE: webaudio/*
-TRAILING WHITESPACE: webdriver/*
 TRAILING WHITESPACE: WebIDL/*
 TRAILING WHITESPACE: webvtt/*
 TRAILING WHITESPACE: XMLHttpRequest/*
 
 ## File types that should never be checked ##
 
 *:*.pdf
 *:*.jpg
@@ -103,8 +101,11 @@ PARSE-FAILED:ext-xhtml-pubid/the-xhtml-s
 PRINT STATEMENT:dom/nodes/Document-createElement-namespace-tests/generate.py
 
 # Should probably be fixed.
 W3C-TEST.ORG:subresource-integrity/refresh-header.js.headers
 
 # Lint doesn't know about sub.svg I guess
 PARSE-FAILED:content-security-policy/svg/including.sub.svg
 
+#Helper files that aren't valid XML
+PARSE-FAILED:dom/nodes/Document-createElement-namespace-tests/empty.xml
+PARSE-FAILED:dom/nodes/Document-createElement-namespace-tests/minimal_html.xml
\ No newline at end of file
--- a/testing/web-platform/tests/pointerevents/pointerevent_capture_suppressing_mouse-manual.html
+++ b/testing/web-platform/tests/pointerevents/pointerevent_capture_suppressing_mouse-manual.html
@@ -29,16 +29,17 @@
         <div id="target0"></div>
         <br>
         <div id="target1"></div>
         <br>
         <input type="button" id="btnCapture" value="Set Capture">
         <script type='text/javascript'>
             var isPointerCapture = false;
             var isRelatedTargetValueTested = false;
+            var isTargetAuthenticityTested = false;
             var count = 0;
 
             var detected_pointertypes = {};
             add_completion_callback(showPointerTypes);
 
             var target0 = document.getElementById('target0');
             var target1 = document.getElementById('target1');
             var captureButton = document.getElementById('btnCapture');
@@ -87,16 +88,23 @@
                     if(isPointerCapture) {
                         test_pointerover_capture.done();
                         if (!isRelatedTargetValueTested) {
                             test(function() {
                                 assert_true(event.relatedTarget==null, "relatedTarget is null when the capture is set")
                             }, "relatedTarget is null when the capture is set. relatedTarget is " + event.relatedTarget);
                             isRelatedTargetValueTested = true;
                         }
+                        var hitTest = document.elementFromPoint(event.clientX, event.clientY);
+                        if(event.target !== hitTest && !isTargetAuthenticityTested) {
+                            test(function () {
+                                assert_unreached("pointerover for this target shouldn't trigger events on capture target");
+                            }, "pointerover should only trigger over the black rectangle");
+                            isTargetAuthenticityTested = true;
+                        }
                     }
                     else {
                         test_pointerover_no_capture.done();
                     }
                 });
 
                 on_event(target0, "pointerout", function (event) {
                     log("pointerout", target0);
--- a/testing/web-platform/tests/resources/testharness.js
+++ b/testing/web-platform/tests/resources/testharness.js
@@ -1171,16 +1171,17 @@ policies and contribution forms [3].
             var code_name_map = {
                 INDEX_SIZE_ERR: 'IndexSizeError',
                 HIERARCHY_REQUEST_ERR: 'HierarchyRequestError',
                 WRONG_DOCUMENT_ERR: 'WrongDocumentError',
                 INVALID_CHARACTER_ERR: 'InvalidCharacterError',
                 NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError',
                 NOT_FOUND_ERR: 'NotFoundError',
                 NOT_SUPPORTED_ERR: 'NotSupportedError',
+                INUSE_ATTRIBUTE_ERR: 'InUseAttributeError',
                 INVALID_STATE_ERR: 'InvalidStateError',
                 SYNTAX_ERR: 'SyntaxError',
                 INVALID_MODIFICATION_ERR: 'InvalidModificationError',
                 NAMESPACE_ERR: 'NamespaceError',
                 INVALID_ACCESS_ERR: 'InvalidAccessError',
                 TYPE_MISMATCH_ERR: 'TypeMismatchError',
                 SECURITY_ERR: 'SecurityError',
                 NETWORK_ERR: 'NetworkError',
@@ -1197,16 +1198,17 @@ policies and contribution forms [3].
             var name_code_map = {
                 IndexSizeError: 1,
                 HierarchyRequestError: 3,
                 WrongDocumentError: 4,
                 InvalidCharacterError: 5,
                 NoModificationAllowedError: 7,
                 NotFoundError: 8,
                 NotSupportedError: 9,
+                InUseAttributeError: 10,
                 InvalidStateError: 11,
                 SyntaxError: 12,
                 InvalidModificationError: 13,
                 NamespaceError: 14,
                 InvalidAccessError: 15,
                 TypeMismatchError: 17,
                 SecurityError: 18,
                 NetworkError: 19,
--- a/testing/web-platform/tests/subresource-integrity/crossorigin-creds-script.js.sub.headers
+++ b/testing/web-platform/tests/subresource-integrity/crossorigin-creds-script.js.sub.headers
@@ -1,2 +1,2 @@
-Access-Control-Allow-Origin: {{location[scheme]}}://{{domains[]}}:{{location[port]}}
+Access-Control-Allow-Origin: {{location[scheme]}}://{{domains[]}}{{GET[acao_port]}}
 Access-Control-Allow-Credentials: true
--- a/testing/web-platform/tests/subresource-integrity/crossorigin-creds-style.css.sub.headers
+++ b/testing/web-platform/tests/subresource-integrity/crossorigin-creds-style.css.sub.headers
@@ -1,2 +1,2 @@
-Access-Control-Allow-Origin: {{location[scheme]}}://{{domains[]}}:{{location[port]}}
+Access-Control-Allow-Origin: {{location[scheme]}}://{{domains[]}}{{GET[acao_port]}}
 Access-Control-Allow-Credentials: true
deleted file mode 100644
--- a/testing/web-platform/tests/subresource-integrity/subresource-integrity.html
+++ /dev/null
@@ -1,545 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Subresource Integrity</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-
-<div id="log"></div>
-
-<div id="container"></div>
-<script>
-    // <script> tests
-    var xorigin_anon_script = location.protocol
-      + '//www1.' + location.hostname + ':' + location.port
-      + '/subresource-integrity/crossorigin-anon-script.js';
-
-    var xorigin_creds_script = location.protocol
-      + '//www1.' + location.hostname + ':' + location.port
-      + '/subresource-integrity/crossorigin-creds-script.js';
-
-    var xorigin_ineligible_script = location.protocol
-      + '//www1.' + location.hostname + ':' + location.port
-      + '/subresource-integrity/crossorigin-ineligible-script.js';
-
-    var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue) {
-        this.pass = pass;
-        this.name = "Script: " + name;
-        this.src = src;
-        this.integrityValue = integrityValue;
-        this.crossoriginValue = crossoriginValue;
-    }
-
-    SRIScriptTest.prototype.execute = function() {
-        var test = async_test(this.name);
-        var e = document.createElement("script");
-        e.src = this.src;
-        e.setAttribute("integrity", this.integrityValue);
-        if(this.crossoriginValue) {
-            e.setAttribute("crossorigin", this.crossoriginValue);
-        }
-        if(this.pass) {
-            e.addEventListener("load", function() {test.done()});
-            e.addEventListener("error", function() {
-                test.step(function(){ assert_unreached("Good load fired error handler.") })
-            });
-        } else {
-           e.addEventListener("load", function() {
-                test.step(function() { assert_unreached("Bad load succeeded.") })
-            });
-           e.addEventListener("error", function() {test.done()});
-        }
-        document.body.appendChild(e);
-    };
-
-    var xorigin_anon_style = location.protocol
-      + '//www1.' + location.hostname + ':' + location.port
-      + '/subresource-integrity/crossorigin-anon-style.css';
-
-    var xorigin_creds_style = location.protocol
-      + '//www1.' + location.hostname + ':' + location.port
-      + '/subresource-integrity/crossorigin-creds-style.css';
-
-    var xorigin_ineligible_style = location.protocol
-      + '//www1.' + location.hostname + ':' + location.port
-      + '/subresource-integrity/crossorigin-ineligible-style.css';
-
-    // <link> tests
-    // Style tests must be done synchronously because they rely on the presence
-    // and absence of global style, which can affect later tests. Thus, instead
-    // of executing them one at a time, the style tests are implemented as a
-    // queue that builds up a list of tests, and then executes them one at a
-    // time.
-    var SRIStyleTest = function(queue, pass, name, attrs, customCallback, altPassValue) {
-        this.pass = pass;
-        this.name = "Style: " + name;
-        this.customCallback = customCallback || function () {};
-        this.attrs = attrs || {};
-        this.passValue = altPassValue || "rgb(255, 255, 0)";
-
-        this.test = async_test(this.name);
-
-        this.queue = queue;
-        this.queue.push(this);
-    }
-
-    SRIStyleTest.prototype.execute = function() {
-        var that = this;
-        var container = document.getElementById("container");
-        while (container.hasChildNodes()) {
-          container.removeChild(container.firstChild);
-        }
-
-        var test = this.test;
-
-        var div = document.createElement("div");
-        div.className = "testdiv";
-        var e = document.createElement("link");
-        this.attrs.rel = this.attrs.rel || "stylesheet";
-        for (var key in this.attrs) {
-            if (this.attrs.hasOwnProperty(key)) {
-                e.setAttribute(key, this.attrs[key]);
-            }
-        }
-
-        if(this.pass) {
-            e.addEventListener("load", function() {
-                test.step(function() {
-                    var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
-                    assert_equals(background, that.passValue);
-                    test.done();
-                });
-            });
-            e.addEventListener("error", function() {
-                test.step(function(){ assert_unreached("Good load fired error handler.") })
-            });
-        } else {
-            e.addEventListener("load", function() {
-                 test.step(function() { assert_unreached("Bad load succeeded.") })
-             });
-            e.addEventListener("error", function() {
-                test.step(function() {
-                    var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
-                    assert_not_equals(background, that.passValue);
-                    test.done();
-                });
-            });
-        }
-        container.appendChild(div);
-        container.appendChild(e);
-        this.customCallback(e, container);
-    };
-
-    var style_tests = [];
-    style_tests.execute = function() {
-        if (this.length > 0) {
-            this.shift().execute();
-        }
-    }
-    add_result_callback(function(res) {
-        if (res.name.startsWith("Style: ")) {
-          style_tests.execute();
-        }
-    });
-
-    // Script tests
-    new SRIScriptTest(
-        true,
-        "Same-origin with correct sha256 hash.",
-        "matching-digest.js",
-        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E="
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with correct sha384 hash.",
-        "matching-digest.js",
-        "sha384-BDRTPSywZFyxfLEAzaLcL4FfERBgJgXfEkuT0r04LG93Yqn1PWNYPZMomaqEfE3H"
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with correct sha512 hash.",
-        "matching-digest.js",
-        "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg=="
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with empty integrity.",
-        "matching-digest.js",
-        ""
-    ).execute();
-
-    new SRIScriptTest(
-        false,
-        "Same-origin with incorrect hash.",
-        "non-matching-digest.js",
-        "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with multiple sha256 hashes, including correct.",
-        "matching-digest.js",
-        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with multiple sha256 hashes, including unknown algorithm.",
-        "matching-digest.js",
-        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with sha256 mismatch, sha512 match",
-        "matching-digest.js",
-        "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-    ).execute();
-
-    new SRIScriptTest(
-        false,
-        "Same-origin with sha256 match, sha512 mismatch",
-        "matching-digest.js",
-        "sha512-deadbeefspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E="
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "<crossorigin='anonymous'> with correct hash, ACAO: *",
-        xorigin_anon_script,
-        "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=",
-        "anonymous"
-    ).execute();
-
-    new SRIScriptTest(
-        false,
-        "<crossorigin='anonymous'> with incorrect hash, ACAO: *",
-        xorigin_anon_script,
-        "sha256-deadbeefcSLlbFZCj1OACLxTxVck2TOrBTEdUbwz1yU=",
-        "anonymous"
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "<crossorigin='use-credentials'> with correct hash, CORS-eligible",
-        xorigin_creds_script,
-        "sha256-IaGApVboXPQxVSm2wVFmhMq1Yu37gWklajgMdxKLIvc=",
-        "use-credentials"
-    ).execute();
-
-    new SRIScriptTest(
-        false,
-        "<crossorigin='use-credentials'> with incorrect hash CORS-eligible",
-        xorigin_creds_script,
-        "sha256-deadbeef2S+pTRZgiw3DWrhC6JLDlt2zRyGpwH7unU8=",
-        "use-credentials"
-    ).execute();
-
-    new SRIScriptTest(
-        false,
-        "<crossorigin='anonymous'> with CORS-ineligible resource",
-        xorigin_ineligible_script,
-        "sha256-F5fXKTX7SiWjtgybxiBZIo2qhh2WiQnNx372E60XrOo=",
-        "anonymous"
-    ).execute();
-
-    new SRIScriptTest(
-        false,
-        "Cross-origin, not CORS request, with correct hash",
-        xorigin_anon_script,
-        "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0="
-    ).execute();
-
-    new SRIScriptTest(
-        false,
-        "Cross-origin, not CORS request, with hash mismatch",
-        xorigin_anon_script,
-        "sha256-deadbeef01Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0="
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Cross-origin, empty integrity",
-        xorigin_anon_script,
-        ""
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with correct hash, options.",
-        "matching-digest.js",
-        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=?foo=bar?spam=eggs"
-    ).execute();
-
-    new SRIScriptTest(
-        true,
-        "Same-origin with unknown algorithm only.",
-        "matching-digest.js",
-        "foo666-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E="
-    ).execute();
-
-    // Style tests
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with correct sha256 hash",
-        {
-            href: "style.css?1",
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4="
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with correct sha384 hash",
-        {
-            href: "style.css?2",
-            integrity: "sha384-wDAWxH4tOWBwAwHfBn9B7XuNmFxHTMeigAMwn0iVQ0zq3FtmYMLxihcGnU64CwcX"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with correct sha512 hash",
-        {
-            href: "style.css?3",
-            integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w=="
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with empty integrity",
-        {
-            href: "style.css?4",
-            integrity: ""
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "Same-origin with incorrect hash.",
-        {
-            href: "style.css?5",
-            integrity: "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with multiple sha256 hashes, including correct.",
-        {
-            href: "style.css?6",
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with multiple sha256 hashes, including unknown algorithm.",
-        {
-            href: "style.css?7",
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with sha256 mismatch, sha512 match",
-        {
-            href: "style.css?8",
-            integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "Same-origin with sha256 match, sha512 mismatch",
-        {
-            href: "style.css?9",
-            integrity: "sha512-deadbeef9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2== sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4="
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "<crossorigin='anonymous'> with correct hash, ACAO: *",
-        {
-            href: xorigin_anon_style + '?1',
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
-            crossorigin: "anonymous"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "<crossorigin='anonymous'> with incorrect hash, ACAO: *",
-        {
-            href: xorigin_anon_style + '?2',
-            integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=",
-            crossorigin: "anonymous"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "<crossorigin='use-credentials'> with correct hash, CORS-eligible",
-        {
-            href: xorigin_creds_style + '?1',
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
-            crossorigin: "use-credentials"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "<crossorigin='use-credentials'> with incorrect hash CORS-eligible",
-        {
-            href: xorigin_creds_style + '?2',
-            integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=",
-            crossorigin: "use-credentials"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "<crossorigin='anonymous'> with CORS-ineligible resource",
-        {
-            href: xorigin_ineligible_style + '?1',
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
-            crossorigin: "anonymous"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "Cross-origin, not CORS request, with correct hash",
-        {
-            href: xorigin_anon_style + '?3',
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4="
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "Cross-origin, not CORS request, with hash mismatch",
-        {
-            href: xorigin_anon_style + '?4',
-            integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk="
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Cross-origin, empty integrity",
-        {
-            href: xorigin_anon_style + '?5',
-            integrity: ""
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with correct hash, options.",
-        {
-            href: "style.css?10",
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with unknown algorithm only.",
-        {
-            href: "style.css?11",
-            integrity: "foo666-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with correct sha256 hash, rel='stylesheet license'",
-        {
-            href: "style.css?12",
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
-            rel: "stylesheet license"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with correct sha256 hash, rel='license stylesheet'",
-        {
-            href: "style.css?13",
-            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
-            rel: "license stylesheet"
-        }
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        true,
-        "Same-origin with correct sha256 and sha512 hash, rel='alternate stylesheet' enabled",
-        {
-            href: "alternate.css?1",
-            title: "alt",
-            type: "text/css",
-            class: "alternate",
-            disabled: "disabled",
-            rel: "alternate stylesheet",
-            integrity: "sha256-phbz83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-8OYEB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==",
-        },
-        function (link, container) {
-            var alternate = document.querySelector('link.alternate');
-            alternate.disabled = false;
-        },
-        "rgb(255, 0, 0)"
-    );
-
-    new SRIStyleTest(
-        style_tests,
-        false,
-        "Same-origin with incorrect sha256 and sha512 hash, rel='alternate stylesheet' enabled",
-        {
-            href: "alternate.css?2",
-            title: "alt",
-            type: "text/css",
-            class: "alternate",
-            disabled: "disabled",
-            rel: "alternate stylesheet",
-            integrity: "sha256-fail83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-failB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==",
-        },
-        function (link, container) {
-            var alternate = document.querySelector('link.alternate');
-            alternate.disabled = false;
-        }
-    );
-
-    style_tests.execute();
-
-</script>
-<!--TODO check cache-poisoned resources, transfer-encoding, 3xx redirect
-   to resource with matching hash, and cross-origin leakage test as in sec5.3.
-   -->
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/subresource-integrity/subresource-integrity.sub.html
@@ -0,0 +1,573 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Subresource Integrity</title>
+<script src="../../../resources/testharness.js"></script>
+<script src="../../../resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<div id="container"></div>
+<script>
+    // This horrible hack is needed for the 'use-credentials' tests because, on
+    // response, if port 80 or 443 is the current port, it will not appear to
+    // the browser as part of the origin string. Since the origin *string* is
+    // used for CORS access control, instead of the origin itself, if there
+    // isn't an exact string match, the check will fail. For example,
+    // "http://example.com" would not match "http://example.com:80", because
+    // they are not exact string matches, even though the origins are the same.
+    //
+    // Thus, we only want the Access-Control-Allow-Origin header to have
+    // the port if it's not port 80 or 443, since the user agent will elide the
+    // ports in those cases.
+    var main_domain = "{{domains[]}}";
+    var www_domain = "{{domains[www]}}";
+    var default_port = "{{ports[http][0]}}";
+    if (location.protocol === "https:") {
+      default_port = "{{ports[https][0]}}";
+    }
+
+    var port_string = "";
+    if (default_port !== "80" && default_port !== "443")
+      port_string = ":" + default_port;
+
+    www_host_and_port = www_domain + port_string;
+
+    // <script> tests
+    var xorigin_anon_script = location.protocol
+      + '//' + www_host_and_port
+      + '/subresource-integrity/crossorigin-anon-script.js';
+
+    var xorigin_creds_script = location.protocol
+      + '//' + www_host_and_port
+      + '/subresource-integrity/crossorigin-creds-script.js?acao_port='
+      + port_string;
+
+    var xorigin_ineligible_script = location.protocol
+      + '//' + www_host_and_port
+      + '/subresource-integrity/crossorigin-ineligible-script.js';
+
+    var SRIScriptTest = function(pass, name, src, integrityValue, crossoriginValue) {
+        this.pass = pass;
+        this.name = "Script: " + name;
+        this.src = src;
+        this.integrityValue = integrityValue;
+        this.crossoriginValue = crossoriginValue;
+    }
+
+    SRIScriptTest.prototype.execute = function() {
+        var test = async_test(this.name);
+        var e = document.createElement("script");
+        e.src = this.src;
+        e.setAttribute("integrity", this.integrityValue);
+        if(this.crossoriginValue) {
+            e.setAttribute("crossorigin", this.crossoriginValue);
+        }
+        if(this.pass) {
+            e.addEventListener("load", function() {test.done()});
+            e.addEventListener("error", function() {
+                test.step(function(){ assert_unreached("Good load fired error handler.") })
+            });
+        } else {
+           e.addEventListener("load", function() {
+                test.step(function() { assert_unreached("Bad load succeeded.") })
+            });
+           e.addEventListener("error", function() {test.done()});
+        }
+        document.body.appendChild(e);
+    };
+
+    // Note that all of these style URLs have query parameters started, so any
+    // additional parameters should be appended starting with '&'.
+    var xorigin_anon_style = location.protocol
+      + '//' + www_host_and_port
+      + '/subresource-integrity/crossorigin-anon-style.css?';
+
+    var xorigin_creds_style = location.protocol
+      + '//' + www_host_and_port
+      + '/subresource-integrity/crossorigin-creds-style.css?acao_port='
+      + port_string;
+
+    var xorigin_ineligible_style = location.protocol
+      + '//' + www_host_and_port
+      + '/subresource-integrity/crossorigin-ineligible-style.css?';
+
+    // <link> tests
+    // Style tests must be done synchronously because they rely on the presence
+    // and absence of global style, which can affect later tests. Thus, instead
+    // of executing them one at a time, the style tests are implemented as a
+    // queue that builds up a list of tests, and then executes them one at a
+    // time.
+    var SRIStyleTest = function(queue, pass, name, attrs, customCallback, altPassValue) {
+        this.pass = pass;
+        this.name = "Style: " + name;
+        this.customCallback = customCallback || function () {};
+        this.attrs = attrs || {};
+        this.passValue = altPassValue || "rgb(255, 255, 0)";
+
+        this.test = async_test(this.name);
+
+        this.queue = queue;
+        this.queue.push(this);
+    }
+
+    SRIStyleTest.prototype.execute = function() {
+        var that = this;
+        var container = document.getElementById("container");
+        while (container.hasChildNodes()) {
+          container.removeChild(container.firstChild);
+        }
+
+        var test = this.test;
+
+        var div = document.createElement("div");
+        div.className = "testdiv";
+        var e = document.createElement("link");
+        this.attrs.rel = this.attrs.rel || "stylesheet";
+        for (var key in this.attrs) {
+            if (this.attrs.hasOwnProperty(key)) {
+                e.setAttribute(key, this.attrs[key]);
+            }
+        }
+
+        if(this.pass) {
+            e.addEventListener("load", function() {
+                test.step(function() {
+                    var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
+                    assert_equals(background, that.passValue);
+                    test.done();
+                });
+            });
+            e.addEventListener("error", function() {
+                test.step(function(){ assert_unreached("Good load fired error handler.") })
+            });
+        } else {
+            e.addEventListener("load", function() {
+                 test.step(function() { assert_unreached("Bad load succeeded.") })
+             });
+            e.addEventListener("error", function() {
+                test.step(function() {
+                    var background = window.getComputedStyle(div, null).getPropertyValue("background-color");
+                    assert_not_equals(background, that.passValue);
+                    test.done();
+                });
+            });
+        }
+        container.appendChild(div);
+        container.appendChild(e);
+        this.customCallback(e, container);
+    };
+
+    var style_tests = [];
+    style_tests.execute = function() {
+        if (this.length > 0) {
+            this.shift().execute();
+        }
+    }
+    add_result_callback(function(res) {
+        if (res.name.startsWith("Style: ")) {
+          style_tests.execute();
+        }
+    });
+
+    // Script tests
+    new SRIScriptTest(
+        true,
+        "Same-origin with correct sha256 hash.",
+        "matching-digest.js",
+        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E="
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with correct sha384 hash.",
+        "matching-digest.js",
+        "sha384-BDRTPSywZFyxfLEAzaLcL4FfERBgJgXfEkuT0r04LG93Yqn1PWNYPZMomaqEfE3H"
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with correct sha512 hash.",
+        "matching-digest.js",
+        "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg=="
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with empty integrity.",
+        "matching-digest.js",
+        ""
+    ).execute();
+
+    new SRIScriptTest(
+        false,
+        "Same-origin with incorrect hash.",
+        "non-matching-digest.js",
+        "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with multiple sha256 hashes, including correct.",
+        "matching-digest.js",
+        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with multiple sha256 hashes, including unknown algorithm.",
+        "matching-digest.js",
+        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with sha256 mismatch, sha512 match",
+        "matching-digest.js",
+        "sha512-geByvIIRspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+    ).execute();
+
+    new SRIScriptTest(
+        false,
+        "Same-origin with sha256 match, sha512 mismatch",
+        "matching-digest.js",
+        "sha512-deadbeefspbnUnwooKGNNCb39nvg+EW0O9hDScTXeo/9pVZztLSUYU3LNV6H0lZapo8bCJUpyPPLAzE9fDzpxg== sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E="
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "<crossorigin='anonymous'> with correct hash, ACAO: *",
+        xorigin_anon_script,
+        "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0=",
+        "anonymous"
+    ).execute();
+
+    new SRIScriptTest(
+        false,
+        "<crossorigin='anonymous'> with incorrect hash, ACAO: *",
+        xorigin_anon_script,
+        "sha256-deadbeefcSLlbFZCj1OACLxTxVck2TOrBTEdUbwz1yU=",
+        "anonymous"
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "<crossorigin='use-credentials'> with correct hash, CORS-eligible",
+        xorigin_creds_script,
+        "sha256-IaGApVboXPQxVSm2wVFmhMq1Yu37gWklajgMdxKLIvc=",
+        "use-credentials"
+    ).execute();
+
+    new SRIScriptTest(
+        false,
+        "<crossorigin='use-credentials'> with incorrect hash CORS-eligible",
+        xorigin_creds_script,
+        "sha256-deadbeef2S+pTRZgiw3DWrhC6JLDlt2zRyGpwH7unU8=",
+        "use-credentials"
+    ).execute();
+
+    new SRIScriptTest(
+        false,
+        "<crossorigin='anonymous'> with CORS-ineligible resource",
+        xorigin_ineligible_script,
+        "sha256-F5fXKTX7SiWjtgybxiBZIo2qhh2WiQnNx372E60XrOo=",
+        "anonymous"
+    ).execute();
+
+    new SRIScriptTest(
+        false,
+        "Cross-origin, not CORS request, with correct hash",
+        xorigin_anon_script,
+        "sha256-51AjITq701Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0="
+    ).execute();
+
+    new SRIScriptTest(
+        false,
+        "Cross-origin, not CORS request, with hash mismatch",
+        xorigin_anon_script,
+        "sha256-deadbeef01Y0yKSx3/UoIKtIY2UQ9+H8WGyyMuOWOC0="
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Cross-origin, empty integrity",
+        xorigin_anon_script,
+        ""
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with correct hash, options.",
+        "matching-digest.js",
+        "sha256-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E=?foo=bar?spam=eggs"
+    ).execute();
+
+    new SRIScriptTest(
+        true,
+        "Same-origin with unknown algorithm only.",
+        "matching-digest.js",
+        "foo666-U9WYDtBWkcHx13+9UKk/3Q5eoqDc4YGxYb07EPWzb9E="
+    ).execute();
+
+    // Style tests
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with correct sha256 hash",
+        {
+            href: "style.css?1",
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4="
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with correct sha384 hash",
+        {
+            href: "style.css?2",
+            integrity: "sha384-wDAWxH4tOWBwAwHfBn9B7XuNmFxHTMeigAMwn0iVQ0zq3FtmYMLxihcGnU64CwcX"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with correct sha512 hash",
+        {
+            href: "style.css?3",
+            integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w=="
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with empty integrity",
+        {
+            href: "style.css?4",
+            integrity: ""
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "Same-origin with incorrect hash.",
+        {
+            href: "style.css?5",
+            integrity: "sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with multiple sha256 hashes, including correct.",
+        {
+            href: "style.css?6",
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with multiple sha256 hashes, including unknown algorithm.",
+        {
+            href: "style.css?7",
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4= foo666-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with sha256 mismatch, sha512 match",
+        {
+            href: "style.css?8",
+            integrity: "sha512-9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2HSZX4l6w== sha256-deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdead"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "Same-origin with sha256 match, sha512 mismatch",
+        {
+            href: "style.css?9",
+            integrity: "sha512-deadbeef9wXDjd6Wq3H6nPAhI9zOvG7mJkUr03MTxaO+8ztTKnfJif42laL93Be/IF6YYZHHF4esitVYxiwpY2== sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4="
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "<crossorigin='anonymous'> with correct hash, ACAO: *",
+        {
+            href: xorigin_anon_style + '&1',
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
+            crossorigin: "anonymous"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "<crossorigin='anonymous'> with incorrect hash, ACAO: *",
+        {
+            href: xorigin_anon_style + '&2',
+            integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=",
+            crossorigin: "anonymous"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "<crossorigin='use-credentials'> with correct hash, CORS-eligible",
+        {
+            href: xorigin_creds_style + '&1',
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
+            crossorigin: "use-credentials"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "<crossorigin='use-credentials'> with incorrect hash CORS-eligible",
+        {
+            href: xorigin_creds_style + '&2',
+            integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk=",
+            crossorigin: "use-credentials"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "<crossorigin='anonymous'> with CORS-ineligible resource",
+        {
+            href: xorigin_ineligible_style + '&1',
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
+            crossorigin: "anonymous"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "Cross-origin, not CORS request, with correct hash",
+        {
+            href: xorigin_anon_style + '&3',
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4="
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "Cross-origin, not CORS request, with hash mismatch",
+        {
+            href: xorigin_anon_style + '&4',
+            integrity: "sha256-deadbeefCzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk="
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Cross-origin, empty integrity",
+        {
+            href: xorigin_anon_style + '&5',
+            integrity: ""
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with correct hash, options.",
+        {
+            href: "style.css?10",
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with unknown algorithm only.",
+        {
+            href: "style.css?11",
+            integrity: "foo666-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=?foo=bar?spam=eggs"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with correct sha256 hash, rel='stylesheet license'",
+        {
+            href: "style.css?12",
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
+            rel: "stylesheet license"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with correct sha256 hash, rel='license stylesheet'",
+        {
+            href: "style.css?13",
+            integrity: "sha256-CzHgdJ7wOccM8L89n4bhcJMz3F+SPLT7YZk7gyCWUV4=",
+            rel: "license stylesheet"
+        }
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        true,
+        "Same-origin with correct sha256 and sha512 hash, rel='alternate stylesheet' enabled",
+        {
+            href: "alternate.css?1",
+            title: "alt",
+            type: "text/css",
+            class: "alternate",
+            disabled: "disabled",
+            rel: "alternate stylesheet",
+            integrity: "sha256-phbz83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-8OYEB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==",
+        },
+        function (link, container) {
+            var alternate = document.querySelector('link.alternate');
+            alternate.disabled = false;
+        },
+        "rgb(255, 0, 0)"
+    );
+
+    new SRIStyleTest(
+        style_tests,
+        false,
+        "Same-origin with incorrect sha256 and sha512 hash, rel='alternate stylesheet' enabled",
+        {
+            href: "alternate.css?2",
+            title: "alt",
+            type: "text/css",
+            class: "alternate",
+            disabled: "disabled",
+            rel: "alternate stylesheet",
+            integrity: "sha256-fail83bWhnLig+d2VPKrRrTRyhqoDRo1ruGqZLZ0= sha512-failB7ktnzcb6h+kB9CUIuc8qvKIyLpygRJdQSEEycRy74dUsB+Yu9rSjpOPjRUblle8WWX9Gn7v39LK2Oceig==",
+        },
+        function (link, container) {
+            var alternate = document.querySelector('link.alternate');
+            alternate.disabled = false;
+        }
+    );
+
+    style_tests.execute();
+
+</script>
+<!-- TODO check cache-poisoned resources, transfer-encoding, 3xx redirect
+   to resource with matching hash, and cross-origin leakage test as in sec5.3.
+    -->
--- a/testing/web-platform/tests/tools/manifest/manifest.py
+++ b/testing/web-platform/tests/tools/manifest/manifest.py
@@ -371,8 +371,9 @@ def load(tests_root, manifest):
         return rv
 
     return Manifest.from_json(tests_root, json.load(manifest))
 
 
 def write(manifest, manifest_path):
     with open(manifest_path, "w") as f:
         json.dump(manifest.to_json(), f, sort_keys=True, indent=2, separators=(',', ': '))
+        f.write("\n")
--- a/testing/web-platform/tests/tools/manifest/sourcefile.py
+++ b/testing/web-platform/tests/tools/manifest/sourcefile.py
@@ -129,17 +129,17 @@ class SourceFile(object):
         ext = self.ext
 
         if not ext:
             return None
         if ext[0] == ".":
             ext = ext[1:]
         if ext in ["html", "htm"]:
             return "html"
-        if ext in ["xhtml", "xht"]:
+        if ext in ["xhtml", "xht", "xml"]:
             return "xhtml"
         if ext == "svg":
             return "svg"
         return None
 
     @cached_property
     def root(self):
         """Return an ElementTree Element for the root node of the file if it contains
--- a/testing/web-platform/tests/tools/webdriver/webdriver/driver.py
+++ b/testing/web-platform/tests/tools/webdriver/webdriver/driver.py
@@ -80,17 +80,17 @@ class WebDriver(searchcontext.SearchCont
 
     def maximize_window(self):
         """Maximize the current window."""
         return self._window_command('POST', '/maximize', 'maximize')
 
     def get_window_size(self):
         """Get the dimensions of the current window."""
         result = self._window_command('GET', '/size', 'getWindowSize')
-        return { 'height': result[height], 'width': result[width] }
+        return {'height': result['height'], 'width': result['width']}
 
     def set_window_size(self, height, width):
         """Set the size of the current window."""
         self._window_command(
             'POST',
             '/size',
             'setWindowSize',
             { 'height': height, 'width': width})
--- a/testing/web-platform/tests/url/interfaces.html
+++ b/testing/web-platform/tests/url/interfaces.html
@@ -4,64 +4,48 @@
 <script src=/resources/testharnessreport.js></script>
 <script src=/resources/WebIDLParser.js></script>
 <script src=/resources/idlharness.js></script>
 
 <h1>URL IDL tests</h1>
 <div id=log></div>
 
 <script type=text/plain>
-[Constructor(DOMString url, optional DOMString base = "about:blank"),
- Exposed=Window,Worker]
+[Constructor(USVString url, optional USVString base),
+ Exposed=(Window,Worker)]
 interface URL {
-  static DOMString domainToASCII(ScalarValueString domain);
-  static DOMString domainToUnicode(ScalarValueString domain);
-};
-URL implements URLUtils;
+  static USVString domainToASCII(USVString domain);
+  static USVString domainToUnicode(USVString domain);
 
-[NoInterfaceObject]
-interface URLUtils {
-  stringifier attribute ScalarValueString href;
-  readonly attribute DOMString origin;
-
-           attribute ScalarValueString protocol;
-           attribute ScalarValueString username;
-           attribute ScalarValueString password;
-           attribute ScalarValueString host;
-           attribute ScalarValueString hostname;
-           attribute ScalarValueString port;
-           attribute ScalarValueString pathname;
-           attribute ScalarValueString search;
-           readonly attribute URLSearchParams searchParams;
-           attribute ScalarValueString hash;
+  stringifier attribute USVString href;
+  readonly attribute USVString origin;
+           attribute USVString protocol;
+           attribute USVString username;
+           attribute USVString password;
+           attribute USVString host;
+           attribute USVString hostname;
+           attribute USVString port;
+           attribute USVString pathname;
+           attribute USVString search;
+  readonly attribute URLSearchParams searchParams;
+           attribute USVString hash;
 };
 
-[NoInterfaceObject]
-interface URLUtilsReadOnly {
-  stringifier readonly attribute DOMString href;
-  readonly attribute DOMString origin;
-
-  readonly attribute DOMString protocol;
-  readonly attribute DOMString host;
-  readonly attribute DOMString hostname;
-  readonly attribute DOMString port;
-  readonly attribute DOMString pathname;
-  readonly attribute DOMString search;
-  readonly attribute DOMString hash;
-};
+[Constructor(optional (USVString or URLSearchParams) init = ""),
+ Exposed=(Window,Worker)]
 interface URLSearchParams {
-  void append(ScalarValueString name, ScalarValueString value);
-  void delete(ScalarValueString name);
-  DOMString? get(ScalarValueString name);
-  sequence<DOMString> getAll(ScalarValueString name);
-  boolean has(ScalarValueString name);
-  void set(ScalarValueString name, ScalarValueString value);
+  void append(USVString name, USVString value);
+  void delete(USVString name);
+  USVString? get(USVString name);
+  sequence<USVString> getAll(USVString name);
+  boolean has(USVString name);
+  void set(USVString name, USVString value);
+  iterable<USVString, USVString>;
   stringifier;
 };
-typedef DOMString ScalarValueString;
 </script>
 <script>
 "use strict";
 var idlArray;
 setup(function() {
   idlArray = new IdlArray();
   [].forEach.call(document.querySelectorAll("script[type=text\\/plain]"), function(node) {
     if (node.className == "untested") {
--- a/testing/web-platform/tests/webdriver/base_test.py
+++ b/testing/web-platform/tests/webdriver/base_test.py
@@ -5,17 +5,17 @@ import sys
 import unittest
 
 from network import get_lan_ip
 
 repo_root = os.path.abspath(os.path.join(__file__, "../.."))
 sys.path.insert(1, os.path.join(repo_root, "tools", "webdriver"))
 sys.path.insert(1, os.path.join(repo_root, "tools", "wptserve"))
 from wptserve import server
-from webdriver.driver import WebDriver
+from selenium import webdriver
 
 
 class WebDriverBaseTest(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         cls.driver = create_driver()
 
         cls.webserver = server.WebTestHttpd(host=get_lan_ip())
@@ -28,22 +28,33 @@ class WebDriverBaseTest(unittest.TestCas
         if cls.driver:
             cls.driver.quit()
 
 
 def create_driver():
     config = ConfigParser.ConfigParser()
     config.read('webdriver.cfg')
     section = os.environ.get("WD_BROWSER", 'firefox')
-    url = 'http://127.0.0.1:4444/wd/hub'
     if config.has_option(section, 'url'):
         url = config.get(section, "url")
+    else:
+        url = 'http://127.0.0.1:4444/wd/hub'
     capabilities = None
     if config.has_option(section, 'capabilities'):
         try:
             capabilities = json.loads(config.get(section, "capabilities"))
         except:
             pass
     mode = 'compatibility'
     if config.has_option(section, 'mode'):
         mode = config.get(section, 'mode')
+    if section == 'firefox':
+        driver = webdriver.Firefox()
+    elif section == 'chrome':
+        driver = webdriver.Chrome()
+    elif section == 'edge':
+        driver = webdriver.Remote()
+    elif section == 'ie':
+        driver = webdriver.Ie()
+    elif section == 'selendroid':
+        driver = webdriver.Android()
 
-    return WebDriver(url, {}, capabilities, mode)
+    return driver
new file mode 100644
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/command_contexts/open_and_close_window_test.py
@@ -0,0 +1,64 @@
+import os
+import sys
+import random
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+repo_root = os.path.abspath(os.path.join(__file__, "../../.."))
+sys.path.insert(1, os.path.join(repo_root, "tools", "webdriver"))
+from webdriver import exceptions
+
+
+class OpenAndCloseWindowTest(base_test.WebDriverBaseTest):
+    def setUp(self):
+        self.driver.get(self.webserver.where_is("command_contexts/res/first-page.html"))
+
+    def tearDown(self):
+        handles = self.driver.get_window_handles()
+
+        for i in range(len(handles) - 1):
+            self.driver.switch_to_window(handles[i])
+            self.driver.close()
+
+        self.driver.switch_to_window(self.driver.get_window_handles()[0])
+
+    def test_open_new_window(self):
+        handles = self.driver.get_window_handles()
+        self.driver.find_element_by_id("open_new_window").click()
+        self.assertEquals(len(handles) + 1, len(self.driver.get_window_handles()))
+
+    def test_get_window_handles_returns_the_windows_that_have_been_opened(self):
+        self.driver.find_element_by_id("open_new_window").click()
+        handles = self.driver.get_window_handles()
+        self.driver.switch_to_window(handles[0])
+        url1 = self.driver.get_current_url()
+        self.driver.switch_to_window(handles[1])
+        url2 = self.driver.get_current_url()
+
+        if url1 == self.webserver.where_is("controlling_windows/res/other-page.html"):
+            self.assertEquals(url2, self.webserver.where_is("controlling_windows/res/first-page.html"))
+        elif url1 == self.webserver.where_is("controlling_windows/res/first-page.html"):
+            self.assertEquals(url2, self.webserver.where_is("controlling_windows/res/other-page.html"))
+        else:
+            self.fail("The wrong set of URLs were returned")
+
+    def test_close_window(self):
+        open_windows = len(self.driver.get_window_handles())
+
+        self.driver.find_element_by_id("open_new_window").click()
+        self.assertEquals(1 + open_windows, len(self.driver.get_window_handles()))
+
+        self.driver.close()
+        self.assertEquals(open_windows, len(self.driver.get_window_handles()))
+
+    def test_command_sent_to_closed_window_returns_no_such_window_exception(self):
+        self.driver.find_element_by_id("open_new_window").click()
+        self.driver.close()
+
+        with self.assertRaises(exceptions.NoSuchWindowException):
+            self.driver.get_window_handle()
+
+if __name__ == "__main__":
+    unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/command_contexts/res/first-page.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta charset="utf-8" />
+    <title>First Page</title>
+</head>
+<body>
+    <a href="./other-page.html" target="_blank" id="open_new_window">Open new window</a>
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/command_contexts/res/other-page.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta charset="utf-8" />
+    <title>Other Page</title>
+</head>
+<body>
+    <a href="./other-page.html" target="_blank" id="open_new_window">Open new window</a>
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/command_contexts/window_handle_test.py
@@ -0,0 +1,33 @@
+import os
+import sys
+import random
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+repo_root = os.path.abspath(os.path.join(__file__, "../../.."))
+sys.path.insert(1, os.path.join(repo_root, "tools", "webdriver"))
+from webdriver import exceptions
+
+
+class WindowHandleTest(base_test.WebDriverBaseTest):
+    def setUp(self):
+        self.driver.get(self.webserver.where_is("command_contexts/res/first-page.html"))
+
+    def test_window_handle_is_not_current(self):
+        handle = self.driver.get_window_handle()
+        self.assertNotEquals(handle, "current")
+
+    def test_window_handles_are_unique(self):
+        number_of_windows = 20
+        new_window_button = self.driver.find_element_by_id("open_new_window")
+        for i in range(0, number_of_windows):
+            new_window_button.click()
+
+        handles = self.driver.get_window_handles()
+        if len(handles) > len(set(handles)):
+            self.fail('At least one window handle was repeated')
+
+if __name__ == "__main__":
+    unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/command_contexts/window_size_test.py
@@ -0,0 +1,35 @@
+import os
+import sys
+import random
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+repo_root = os.path.abspath(os.path.join(__file__, "../../.."))
+sys.path.insert(1, os.path.join(repo_root, "tools", "webdriver"))
+from webdriver import exceptions
+
+class WindowSizeTest(base_test.WebDriverBaseTest):
+
+    def test_set_and_get_window_size(self):
+        self.driver.get(self.webserver.where_is("command_contexts/res/first-page.html"))
+
+        initial_dimensions = self.driver.get_window_size()
+
+        new_dimensions = {
+            "height": initial_dimensions["height"] - 100,
+            "width": initial_dimensions["width"] - 100}
+
+        try:
+            self.driver.set_window_size(new_dimensions["height"], new_dimensions["width"])
+
+            actual_dimensions = self.driver.get_window_size()
+
+            self.assertDictEqual(new_dimensions, actual_dimensions)
+        except exceptions.UnsupportedOperationException:
+            pass
+
+
+if __name__ == "__main__":
+    unittest.main()
--- a/testing/web-platform/tests/webdriver/cookie/cookie_test.py
+++ b/testing/web-platform/tests/webdriver/cookie/cookie_test.py
@@ -1,65 +1,55 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions
+from selenium.common import exceptions
 
 
 class CookieTest(base_test.WebDriverBaseTest):
     def setUp(self):
         self.driver.get(self.webserver.where_is("cookie/res/cookie_container.html"))
 
     def test_can_create_a_well_formed_cookie( self ):
-        name = 'foo'
-        value = 'bar'
-
-        self.driver.add_cookie({ 'name': name, 'value': value })
+        self.driver.add_cookie({'name': 'foo', 'value': 'bar'})
 
     def test_cookies_should_allow_secure_to_be_set( self ):
         name = 'foo'
-        value = 'bar'
-        secure = True
-
-        self.driver.add_cookie({ 'name': name,
-                                 'value': value,
-                                 'path': '/',
-                                 'secure': secure})
+        self.driver.add_cookie({'name': name,
+                                'value': 'bar',
+                                'path': '/',
+                                'secure': (True)})
         self.assertTrue(self.driver.get_cookie(name)[0]['secure'])
 
     def test_secure_defaults_to_false( self ):
         name = 'foo'
         value = 'bar'
 
         self.driver.add_cookie({ 'name': name,
                                  'value': value})
 
         self.assertFalse(self.driver.get_cookie(name)[0]['secure'])
 
     def test_should_throw_an_exception_when_semicolon_exists_in_the_cookie_attribute(self):
         invalid_name = 'foo;bar'
-        value = 'foobar'
-
         try:
-            self.driver.add_cookie({ 'name': invalid_name, 'value': value })
+            self.driver.add_cookie({'name': invalid_name, 'value': 'foobar'})
             self.fail( 'should have thrown exceptions.' )
 
         except exceptions.UnableToSetCookieException:
             pass
         except exceptions.InvalidCookieDomainException:
             pass
 
     def test_should_throw_an_exception_the_name_is_null(self):
-        val = 'foobar'
-
         try:
-            self.driver.add_cookie({ 'name': None, 'value': val })
+            self.driver.add_cookie({'name': None, 'value': 'foobar'})
             self.fail( 'should have thrown exceptions.' )
 
         except exceptions.UnableToSetCookieException:
             pass
         except exceptions.InvalidCookieDomainException:
             pass
 
 
--- a/testing/web-platform/tests/webdriver/element_location/element_location_test.py
+++ b/testing/web-platform/tests/webdriver/element_location/element_location_test.py
@@ -1,25 +1,24 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
 
-
 class ElementLocationTest(base_test.WebDriverBaseTest):
     def test_find_element_by_name(self):
         self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
-        e = self.driver.find_element_by_css("*[name='name']")
+        e = self.driver.find_element_by_name("name")
         self.assertEquals("name", e.text)
 
     def test_find_element_by_css_selector(self):
         self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
-        e = self.driver.find_element_by_css("#id")
+        e = self.driver.find_element_by_css_selector("#id")
         self.assertEquals("id", e.text)
 
     def test_find_element_by_link_text(self):
         self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
         e = self.driver.find_element_by_link_text("link text")
         self.assertEquals("link text", e.text)
 
     def test_find_element_by_partial_link_text(self):
@@ -27,11 +26,35 @@ class ElementLocationTest(base_test.WebD
         e = self.driver.find_element_by_partial_link_text("link tex")
         self.assertEquals("link text", e.text)
 
     def test_find_element_by_xpath(self):
         self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
         e = self.driver.find_element_by_xpath("//*[@id='id']")
         self.assertEquals("id", e.text)
 
+    def test_find_elements_by_name(self):
+        self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
+        e = self.driver.find_elements_by_name("name")
+        self.assertEquals("name", e[0].text)
+
+    def test_find_elements_by_css_selector(self):
+        self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
+        e = self.driver.find_elements_by_css_selector("#id")
+        self.assertEquals("id", e[0].text)
+
+    def test_find_elements_by_link_text(self):
+        self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
+        e = self.driver.find_elements_by_link_text("link text")
+        self.assertEquals("link text", e[0].text)
+
+    def test_find_elements_by_partial_link_text(self):
+        self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
+        e = self.driver.find_elements_by_partial_link_text("link tex")
+        self.assertEquals("link text", e[0].text)
+
+    def test_find_elements_by_xpath(self):
+        self.driver.get(self.webserver.where_is("element_location/res/elements.html"))
+        e = self.driver.find_elements_by_xpath("//*[@id='id']")
+        self.assertEquals("id", e[0].text)
 
 if __name__ == "__main__":
     unittest.main()
--- a/testing/web-platform/tests/webdriver/element_state/method_test.py
+++ b/testing/web-platform/tests/webdriver/element_state/method_test.py
@@ -4,68 +4,104 @@ import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
 
 
 class GetElementAttributeTest(base_test.WebDriverBaseTest):
     def test_get_element_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-with-id-attribute.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         self.assertEqual("myId", el.get_attribute("id"))
 
     def test_style_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-with-style-attribute.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         expected_style = """
                          font-family: \"Gill Sans Extrabold\",Helvetica,sans-serif;
                          line-height: 1.2; font-weight: bold;
                          """
         self.assertEqual(expected_style, el.get_attribute("style"))
 
     def test_color_serialization_of_style_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-with-color-style-attribute.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         self.assertEqual("color: rgba(255, 0, 0, 1.0);", el.get_attribute("style"))
 
     def test_true_if_boolean_attribute_present(self):
         self.driver.get(self.webserver.where_is("element_state/res/input-with-checked-attribute.html"))
-        el = self.driver.find_element_by_css("input")
+        el = self.driver.find_element_by_css_selector("input")
         self.assertEqual("true", el.get_attribute("checked"))
 
     def test_none_if_boolean_attribute_absent(self):
         self.driver.get(self.webserver.where_is("element_state/res/input-without-checked-attribute.html"))
-        el = self.driver.find_element_by_css("input")
+        el = self.driver.find_element_by_css_selector("input")
         self.assertIsNone(el.get_attribute("checked"))
 
     def test_option_with_attribute_value(self):
         self.driver.get(self.webserver.where_is("element_state/res/option-with-value-attribute.html"))
-        el = self.driver.find_element_by_css("option")
+        el = self.driver.find_element_by_css_selector("option")
         self.assertEqual("value1", el.get_attribute("value"))
 
     def test_option_without_value_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/option-without-value-attribute.html"))
-        el = self.driver.find_element_by_css("option")
+        el = self.driver.find_element_by_css_selector("option")
         self.assertEqual("Value 1", el.get_attribute("value"))
 
     def test_a_href_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/a-with-href-attribute.html"))
-        el = self.driver.find_element_by_css("a")
+        el = self.driver.find_element_by_css_selector("a")
         self.assertEqual("http://web-platform.test:8000/path#fragment", el.get_attribute("href"))
 
     def test_img_src_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/img-with-src-attribute.html"))
-        el = self.driver.find_element_by_css("img")
+        el = self.driver.find_element_by_css_selector("img")
         self.assertEqual("http://web-platform.test:8000/images/blue.png", el.get_attribute("src"))
 
     def test_custom_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-with-custom-attribute.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         self.assertEqual("attribute value", el.get_attribute("webdriver-custom-attribute"))
 
     def test_attribute_not_present(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-without-attribute.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         self.assertIsNone(el.get_attribute("class"))
 
+    def test_find_attribute_with_special_characters(self):
+        self.driver.get(self.webserver.where_is("element_state/res/get-element-attribute-extended.html"))
+        element = self.driver.find_element_by_id("id_special_char_attribute_name")
+        attribute = element.get_attribute("*")
+        self.assertEquals("special_char_attribute_name", attribute)
+
+    def test_find_attribute_with_special_char_name_and_value(self):
+        self.driver.get(self.webserver.where_is("element_state/res/get-element-attribute-extended.html"))
+        element = self.driver.find_element_by_id("id_special_char_attribute_name_and_value")
+        attribute = element.get_attribute("@")
+        self.assertEquals("(", attribute)
+
+    def test_find_attribute_with_numeric_name(self):
+        self.driver.get(self.webserver.where_is("element_state/res/get-element-attribute-extended.html"))
+        element = self.driver.find_element_by_id("id_attribute_name_numeric")
+        attribute = element.get_attribute("1")
+        self.assertEquals("numeric attribute name", attribute)
+
+    def test_find_attribute_with_numeric_value(self):
+        self.driver.get(self.webserver.where_is("element_state/res/get-element-attribute-extended.html"))
+        element = self.driver.find_element_by_id("id_attribute_value_numeric")
+        attribute = element.get_attribute("one")
+        self.assertEquals("2", attribute)
+
+    def test_find_attribute_with_negative_numeric_name(self):
+        self.driver.get(self.webserver.where_is("element_state/res/get-element-attribute-extended.html"))
+        element = self.driver.find_element_by_id("id_attribute_negative_numeric_name")
+        attribute = element.get_attribute("-5")
+        self.assertEquals("attribute name is -5", attribute)
+
+    def test_find_attribute_with_negative_numeric_value(self):
+        self.driver.get(self.webserver.where_is("element_state/res/get-element-attribute-extended.html"))
+        element = self.driver.find_element_by_id("id_attribute_negative_numeric_value")
+        attribute = element.get_attribute("negative_numeric_value")
+        self.assertEquals("-9", attribute)
+
 
 if __name__ == "__main__":
     unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/element_state/properties.py
@@ -0,0 +1,17 @@
+import os
+import sys
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+
+class GetElementPropertiesTest(base_test.WebDriverBaseTest):
+    def test_get_element_text(self):
+        self.driver.get(self.webserver.where_is("element_state/res/elements_text.html"))
+        e = self.driver.find_element_by_name("name")
+        self.assertEquals("name", e.text)
+
+
+if __name__ == "__main__":
+    unittest.main()
--- a/testing/web-platform/tests/webdriver/element_state/res/element-hidden-by-z-index.html
+++ b/testing/web-platform/tests/webdriver/element_state/res/element-hidden-by-z-index.html
@@ -5,17 +5,17 @@
 <style>
   * { position: relative }
 
   #overlay,
   #hidden {
     height: 50px;
     width: 50px;
   }
-  
+
   #overlay {
     background: blue;
 
     z-index: 1;
   }
 
   #hidden {
     background: red;
--- a/testing/web-platform/tests/webdriver/element_state/res/element-moved-behind-other-element-by-transform.html
+++ b/testing/web-platform/tests/webdriver/element_state/res/element-moved-behind-other-element-by-transform.html
@@ -1,28 +1,28 @@
 <!DOCTYPE html>
 <meta charset="utf-8" />
 <title>Element moved behind other element by transform</title>
 
 <style>
   * { position: relative }
-  
+
   #overlay {
     height: 50px;
     width: 50px;
     background: blue;
     z-index: 1;
   }
-  
+
   #hidden {
     height: 50px;
     width: 50px;
     background: red;
     z-index: -1;
-  
+
     transform: translate(0, -50px);
 
     /* fix your browsers god damnit */
     -webkit-transform: translate(0, -50px);
     -moz-transform: translate(0x, -50px);
   }
 </style>
 
--- a/testing/web-platform/tests/webdriver/element_state/res/element-partially-hidden-by-other-element.html
+++ b/testing/web-platform/tests/webdriver/element_state/res/element-partially-hidden-by-other-element.html
@@ -2,17 +2,17 @@
 <meta charset="utf-8" />
 <title>Element partially hidden by other element</title>
 
 <style>
   div {
     height: 100px;
     width: 100px;
   }
-  
+
   #partial {
     background: yellow;
   }
 
   #other {
     background: blue;
     margin-top: -50px;
     margin-left: 50px;
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/element_state/res/element-selected.html
@@ -0,0 +1,89 @@
+<html>
+<body>
+<select>
+    <option id="selected-1">selected-1</option>
+</select>
+<select>
+    <option id="selected-2">selected-2</option>
+    <option id="unselected-1">unselected-1</option>
+</select>
+<select disabled>
+    <option id="unselected-2">unselected-2</option>
+    <option id="selected-3" selected>selected-3</option>
+    <option id="unselected-3">unselected-3</option>
+</select>
+<select>
+    <option id="unselected-4" checked>unselected-4</option>
+    <option id="unselected-5">unselected-5</option>
+    <option id="selected-4" selected>selected-4</option>
+</select>
+<select>
+    <option id="unselected-6" selected>unselected-6</option>
+    <option id="selected-5">selected-5</option>
+</select>
+<script>
+    document.getElementById("selected-5").selected = true;
+</script>
+<select multiple>
+    <option id="unselected-7">unselected-7</option>
+    <option id="unselected-8">unselected-8</option>
+</select>
+<select multiple>
+    <option id="selected-6" selected>selected-6</option>
+    <option id="unselected-9" selected>unselected-9</option>
+    <option id="selected-7">selected-7</option>
+</select>
+<script>
+    document.getElementById("unselected-9").selected = false;
+    document.getElementById("selected-7").selected = true;
+</script>
+
+<h1>Input Checkbox Elements</h1>
+<input type="checkbox" id="selected-8" />selected-8
+<script>
+   document.getElementById("selected-8").checked = true;
+</script>
+<input type="checkbox" id="selected-9" checked />selected-9
+<script>
+   document.getElementById("selected-9").indeterminate = true;
+</script>
+<input type="checkbox" id="unselected-10" />unselected-10
+<input type="checkbox" id="unselected-11" checked />unselected-11
+<script>
+   document.getElementById("unselected-11").checked = false;
+</script>
+<input type="checkbox" id="unselected-12" />unselected-12
+<script>
+   document.getElementById("unselected-12").indeterminate = true;
+</script>
+<input type="checkbox" id="unselected-13" selected />unselected-13
+<input type="checkbox" id="selected-10" checked />selected-10
+
+<h1>Input Radio Elements</h1>
+<br>Group 1:<br>
+<input type="radio" name="group1" id="selected-11" checked />selected-11
+<br>Group 2:<br>
+<input type="radio" name="group2" id="selected-12" />selected-12
+<script>
+   document.getElementById("selected-12").checked = true;
+</script>
+<br>Group 3:<br>
+<input type="radio" name="group3" id="unselected-14" />unselected-14
+<input type="radio" name="group3" id="selected-13" checked />selected-13
+<br>Group 4:<br>
+<input type="radio" name="group4" id="unselected-15" checked />unselected-15
+<input type="radio" name="group4" id="selected-14" checked />selected-14
+<br>Group 5:<br>
+<input type="radio" name="group5" id="unselected-16" />unselected-16
+<input type="radio" name="group5" id="unselected-17" checked />unselected-17
+<script>
+   document.getElementById("unselected-17").checked = false;
+</script>
+<br>Group 6<br>
+<input type="radio" name="group6" id="selected-15" />selected-15
+<input type="radio" name="group6" id="unselected-18" checked />unselected-18
+<script>
+   document.getElementById("selected-15").checked = true;
+</script>
+</body>
+</html>
--- a/testing/web-platform/tests/webdriver/element_state/res/element-with-same-color-as-parent-background.html
+++ b/testing/web-platform/tests/webdriver/element_state/res/element-with-same-color-as-parent-background.html
@@ -3,16 +3,16 @@
 <title>Element with same color as background</title>
 
 <style>
   #overlay,
   #hidden {
     background: blue;
     width: 50px; height: 50px;
   }
-  
+
   #hidden {
     margin-top: -50px;
   }
 </style>
 
 <div id="overlay"></div>
 <div id="hidden"></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/element_state/res/elements_text.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<title>Element location</title>
+
+<body>
+  <div id="id">id</div>
+  <div id="name" name="name">name</div>
+  <a id="link">link text</a>
+</body>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/element_state/res/get-element-attribute-extended.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Get Element Attribute Extended</title>
+
+<span id=my_id_with_a_relatively_long_name_test class=my_id_with_a_relatively_long_name_test_class>Span</span>
+<span id=my-id>Span</span>
+
+<div class=container>
+ <div id=div1 name=div-name>
+  <div id=div1-1_div1>
+   <h1 id=h1_div1.1_div1 class=span-class>h1 element, id:h1_div1.1_div1</h1>
+  </div>
+ </div>
+
+ <div class=div-depth-2>
+  <div class=div-depth-3>
+   <div class=div-depth-4>
+    <span id=my_id_with_a_relatively_long_name_test class=my_id_with_a_relatively_long_name_test_class>Span</span>
+   </div>
+  </div>
+ </div>
+
+ <div>
+  <a>anchor text 123</a>
+  <a>anchor text 123</a>
+
+  <select>
+   <option id="opt-1" style="font-size: 11px; display: block;" selected>My Option 1</option>
+   <option class="opt" >My Option 2</option>
+   <option value="one">My Option 3</option>
+  </select>
+ </div>
+
+ <a id="no-vi-1" class="cant-see" style="display:none">no visibility</a><br/>
+ <a id="no-vi-2" style="display:none">no visibility</a><br/>
+ <a id="no-vi-2" style="display:none">no visibility</a><br/>
+
+ <span id=my_id_with_a_relatively_long_name_test2>Span</span>
+ <span id="id.period">Span</span>
+</div>
+
+<div id=id_attribute_accesskey accesskey=nothing></div>
+
+<!-- Multiple elements with same class  -->
+
+<div id=id_div_multiple_elements_same_class_nested_depth_0 class=multiple_elements_same_class_nested>
+ <div id=id_multiple_elements_same_class_nested_div_depth_1 class=multiple_elements_same_class_nested>
+  <div id=id_multiple_elements_same_class_nested_div_depth_2 class=multiple_elements_same_class_nested>
+  </div>
+ </div>
+</div>
+
+<!-- Attribute name with special characters -->
+<div id=id_special_char_attribute_name *=special_char_attribute_name></div>
+
+<!-- Attribute value with special characters -->
+<div id=id_special_char_attribute_value name="*"></div>
+
+<!-- Attribute value and name with special characters -->
+<div id=id_special_char_attribute_name_and_value @="("></div>
+
+<!-- Attribute name is numeric. -->
+<div id"id_attribute_name_numeric 1="numeric attribute name"></div>
+
+<!-- Attribute value is numeric. -->
+<div id=id_attribute_value_numeric one=2></div>
+
+<!-- Attribute name is negative numeric. -->
+<div id=id_attribute_negative_numeric_name -5="attribute name is -5"></div>
+
+<!-- Attribute value is negative numeric. -->
+<div id=id_attribute_negative_numeric_value negative_numeric_value=-9></div>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/element_state/selected_test.py
@@ -0,0 +1,210 @@
+import os
+import sys
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+
+class GetElementSelectedTest(base_test.WebDriverBaseTest):
+    def test_selected_1(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-1")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_2(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-2")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_3(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-3")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_4(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-4")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_5(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-5")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_6(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-6")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_7(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-7")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_8(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-8")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_9(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-9")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_10(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-10")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_11(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-11")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_12(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-12")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_13(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-13")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_14(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-14")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_selected_15(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("selected-15")
+
+        self.assertEquals(element.is_selected(), True)
+
+    def test_unselected_1(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-1")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_2(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-2")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_3(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-3")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_4(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-4")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_5(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-5")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_6(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-6")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_7(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-7")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_8(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-8")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_9(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-9")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_10(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-10")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_11(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-11")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_12(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-12")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_13(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-13")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_14(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-14")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_15(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-15")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_16(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-16")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_17(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-17")
+
+        self.assertEquals(element.is_selected(), False)
+
+    def test_unselected_18(self):
+        self.driver.get(self.webserver.where_is("element_state/res/element-selected.html"))
+        element = self.driver.find_element_by_id("unselected-18")
+
+        self.assertEquals(element.is_selected(), False)
+
+
+if __name__ == "__main__":
+    unittest.main()
--- a/testing/web-platform/tests/webdriver/element_state/visibility_test.py
+++ b/testing/web-platform/tests/webdriver/element_state/visibility_test.py
@@ -1,93 +1,93 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions
+from selenium.common import exceptions
 
 
 class NaturalNonVisibleElementsTest(base_test.WebDriverBaseTest):
     def test_0x0_pixel_element_is_not_visible(self):
         self.driver.get(self.webserver.where_is("element_state/res/0x0-pixels.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         self.assertFalse(el.is_displayed())
 
     def test_0x0_pixel_text_node_is_visible(self):
         self.driver.get(self.webserver.where_is("element_state/res/0x0-pixels-text-node.html"))
-        el = self.driver.find_element_by_css("p")
+        el = self.driver.find_element_by_css_selector("p")
         self.assertTrue(el.is_displayed())
 
     def test_1x1_pixel_element(self):
         self.driver.get(self.webserver.where_is("element_state/res/1x1-pixels.html"))
-        el = self.driver.find_element_by_css("p")
+        el = self.driver.find_element_by_css_selector("p")
         self.assertTrue(el.is_displayed())
 
     def test_zero_sized_element_is_shown_if_decendant_has_size(self):
         self.driver.get(self.webserver.where_is("element_state/res/zero-sized-element-with-sizable-decendant.html"))
-        parent = self.driver.find_element_by_css("#parent")
-        child = self.driver.find_element_by_css("#child")
+        parent = self.driver.find_element_by_css_selector("#parent")
+        child = self.driver.find_element_by_css_selector("#child")
 
         self.assertTrue(parent.is_displayed())
         self.assertTrue(child.is_displayed())
 
     def test_input_type_hidden_is_never_visible(self):
         self.driver.get(self.webserver.where_is("element_state/res/input-type-hidden.html"))
-        input = self.driver.find_element_by_css("input")
+        input = self.driver.find_element_by_css_selector("input")
         self.assertFalse(input.is_displayed())
 
     def test_input_morphs_into_hidden(self):
         self.driver.get(self.webserver.where_is("element_state/res/input-morphs-into-hidden.html"))
-        input = self.driver.find_element_by_css("input")
+        input = self.driver.find_element_by_css_selector("input")
         self.assertFalse(input.is_displayed())
 
     def test_parent_node_visible_when_all_children_are_absolutely_positioned_and_overflow_is_hidden(self):
         pass
 
     def test_parent_of_absolutely_positioned_elements_visible_where_ancestor_overflow_is_hidden(self):
         """When a parent's ancestor hides any overflow, absolutely positioned child elements are
         still visible.  The parent container is also considered visible by webdriver for this
         reason because it is interactable."""
 
         self.driver.get(self.webserver.where_is("element_state/res/absolute-children-ancestor-hidden-overflow.html"))
 
-        children = self.driver.find_elements_by_css(".child")
+        children = self.driver.find_elements_by_css_selector(".child")
         assert all(child.is_displayed() for child in children)
 
-        parent = self.driver.find_element_by_css("#parent")
+        parent = self.driver.find_element_by_css_selector("#parent")
         assert parent.is_displayed()
 
     def test_element_hidden_by_overflow_x_is_not_visible(self):
         # TODO(andreastt): This test should probably be split in three.  Also it's making two
         # assertions.
         pages = ["element_state/res/x-hidden-y-hidden.html",
                  "element_state/res/x-hidden-y-scroll.html",
                  "element_state/res/x-hidden-y-auto.html"]
 
         for page in pages:
             self.driver.get(self.webserver.where_is(page))
-            right = self.driver.find_element_by_css("#right")
-            bottom_right = self.driver.find_element_by_css("#bottom-right")
+            right = self.driver.find_element_by_css_selector("#right")
+            bottom_right = self.driver.find_element_by_css_selector("#bottom-right")
 
             self.assertFalse(right.is_displayed())
             self.assertFalse(bottom_right.is_displayed())
 
     def test_element_hidden_by_overflow_y_is_not_visible(self):
         # TODO(andreastt): This test should probably be split in three.  Also it's making two
         # assertions.
         pages = ["element_state/res/x-hidden-y-hidden.html",
                  "element_state/res/x-scroll-y-hidden.html",
                  "element_state/res/x-auto-y-hidden.html"]
 
         for page in pages:
             self.driver.get(self.webserver.where_is(page))
-            bottom = self.driver.find_element_by_css("#bottom")
-            bottom_right = self.driver.find_element_by_css("#bottom-right")
+            bottom = self.driver.find_element_by_css_selector("#bottom")
+            bottom_right = self.driver.find_element_by_css_selector("#bottom-right")
 
             self.assertFalse(bottom.is_displayed())
             self.assertFalse(bottom_right.is_displayed())
 
     def test_parent_node_visible_when_all_children_are_absolutely_position_and_overflow_is_hidden(self):
         pass
 
     def test_element_scrollable_by_overflow_x_is_visible(self):
@@ -99,88 +99,88 @@ class NaturalNonVisibleElementsTest(base
     def test_element_scrollable_by_overflow_x_and_y_is_visible(self):
         pass
 
     def test_element_scrollable_by_overflow_y_is_visible(self):
         pass
 
     def test_element_outside_viewport(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-outside-viewport.html"))
-        hidden = self.driver.find_element_by_css("div")
+        hidden = self.driver.find_element_by_css_selector("div")
         self.assertFalse(hidden.is_displayed())
 
     def test_element_dynamically_moved_outside_viewport(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-dynamically-moved-outside-viewport.html"))
-        hidden = self.driver.find_element_by_css("div")
+        hidden = self.driver.find_element_by_css_selector("div")
         self.assertFalse(hidden.is_displayed())
 
     def test_element_hidden_by_other_element(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-hidden-by-other-element.html"))
-        overlay = self.driver.find_element_by_css("#overlay")
-        hidden = self.driver.find_element_by_css("#hidden")
+        overlay = self.driver.find_element_by_css_selector("#overlay")
+        hidden = self.driver.find_element_by_css_selector("#hidden")
 
         self.assertTrue(overlay.is_displayed())
         self.assertFalse(hidden.is_displayed())
 
     def test_element_partially_hidden_by_other_element(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-partially-hidden-by-other-element.html"))
-        partial = self.driver.find_element_by_css("#partial")
+        partial = self.driver.find_element_by_css_selector("#partial")
         self.assertTrue(partial.is_displayed())
 
     def test_element_hidden_by_z_index(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-hidden-by-z-index.html"))
-        overlay = self.driver.find_element_by_css("#overlay")
-        hidden = self.driver.find_element_by_css("#hidden")
+        overlay = self.driver.find_element_by_css_selector("#overlay")
+        hidden = self.driver.find_element_by_css_selector("#hidden")
 
         self.assertTrue(overlay.is_displayed())
         self.assertFalse(hidden.is_displayed())
 
     def test_element_moved_outside_viewport_by_transform(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-moved-outside-viewport-by-transform.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         self.assertFalse(el.is_displayed())
 
     def test_element_moved_behind_other_element_by_transform(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-moved-behind-other-element-by-transform.html"))
-        overlay = self.driver.find_element_by_css("#overlay")
-        hidden = self.driver.find_element_by_css("#hidden")
+        overlay = self.driver.find_element_by_css_selector("#overlay")
+        hidden = self.driver.find_element_by_css_selector("#hidden")
 
         self.assertTrue(overlay.is_displayed())
         self.assertFalse(hidden.is_displayed())
 
     def test_text_with_same_color_as_background(self):
         self.driver.get(self.webserver.where_is("element_state/res/text-with-same-color-as-background.html"))
-        p = self.driver.find_element_by_css("p")
+        p = self.driver.find_element_by_css_selector("p")
         self.assertFalse(p.is_displayed())
 
     def test_text_with_same_color_as_parent_background(self):
         self.driver.get(self.webserver.where_is("element_state/res/text-with-same-color-as-parent-background.html"))
-        p = self.driver.find_element_by_css("p")
+        p = self.driver.find_element_by_css_selector("p")
         self.assertFalse(p.is_displayed())
 
     def test_text_with_matching_color_and_background(self):
         self.driver.get(self.webserver.where_is("element_state/res/text-with-matching-color-and-background.html"))
-        p = self.driver.find_element_by_css("p")
+        p = self.driver.find_element_by_css_selector("p")
         self.assertTrue(p.is_displayed())
 
     def test_element_with_same_color_as_background(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-with-same-color-as-background.html"))
-        el = self.driver.find_element_by_css("div")
+        el = self.driver.find_element_by_css_selector("div")
         self.assertFalse(el.is_displayed())
 
     def test_element_with_same_color_as_parent_background(self):
         self.driver.get(self.webserver.where_is("element_state/res/element-with-same-color-as-parent-background.html"))
-        hidden = self.driver.find_element_by_css("#hidden")
+        hidden = self.driver.find_element_by_css_selector("#hidden")
         self.assertFalse(hidden.is_displayed())
 
 
 class BodyElementIsAlwaysDisplayedTest(base_test.WebDriverBaseTest):
     def assert_body_is_displayed_on(self, page):
         self.driver.get(self.webserver.where_is(page))
-        body = self.driver.find_element_by_css("body")
+        body = self.driver.find_element_by_css_selector("body")
         assert body.is_displayed()
 
     def test_implicit(self):
         self.assert_body_is_displayed_on("element_state/res/body_implicit.html")
 
     def test_empty(self):
         self.assert_body_is_displayed_on("element_state/res/body_empty.html")
 
@@ -189,133 +189,133 @@ class BodyElementIsAlwaysDisplayedTest(b
 
     def test_overflow_hidden(self):
         self.assert_body_is_displayed_on("element_state/res/body_overflow_hidden.html")
 
 
 class DisplayTest(base_test.WebDriverBaseTest):
     def test_display_block(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-block.html"))
-        el = self.driver.find_element_by_css("p")
+        el = self.driver.find_element_by_css_selector("p")
         self.assertTrue(el.is_displayed())
 
     def test_display_none(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-none.html"))
-        el = self.driver.find_element_by_css("p")
+        el = self.driver.find_element_by_css_selector("p")
         self.assertFalse(el.is_displayed())
 
     def test_display_none_hides_child_node(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-none-child.html"))
-        parent = self.driver.find_element_by_css("#parent")
-        child = self.driver.find_element_by_css("#child")
+        parent = self.driver.find_element_by_css_selector("#parent")
+        child = self.driver.find_element_by_css_selector("#child")
 
         self.assertFalse(parent.is_displayed())
         self.assertFalse(child.is_displayed())
 
     def test_display_none_hides_child_node_link(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-none-child-link.html"))
-        child = self.driver.find_element_by_css("#child")
+        child = self.driver.find_element_by_css_selector("#child")
         self.assertFalse(child.is_displayed())
 
     def test_display_none_hides_child_node_paragraph(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-none-child-paragraph.html"))
-        child = self.driver.find_element_by_css("#child")
+        child = self.driver.find_element_by_css_selector("#child")
         self.assertFalse(child.is_displayed())
 
     def test_display_none_on_parent_takes_presedence(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-none-parent-presedence.html"))
-        child = self.driver.find_element_by_css("#child")
+        child = self.driver.find_element_by_css_selector("#child")
         self.assertFalse(child.is_displayed())
 
     def test_display_none_on_parent_takes_presedence_over_visibility_visible(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-none-parent-presedence-visibility.html"))
-        child = self.driver.find_element_by_css("#child")
+        child = self.driver.find_element_by_css_selector("#child")
         self.assertFalse(child.is_displayed())
 
     def test_display_none_hidden_dynamically(self):
         self.driver.get(self.webserver.where_is("element_state/res/display-none-dynamic.html"))
-        hidden = self.driver.find_element_by_css("#hidden")
+        hidden = self.driver.find_element_by_css_selector("#hidden")
         self.assertFalse(hidden.is_displayed())
 
 
 class VisibilityTest(base_test.WebDriverBaseTest):
     def test_element_state_hidden(self):
         self.driver.get(self.webserver.where_is("element_state/res/visibility-hidden.html"))
-        el = self.driver.find_element_by_css("p")
+        el = self.driver.find_element_by_css_selector("p")
         self.assertFalse(el.is_displayed())
 
     def test_element_state_visible(self):
         self.driver.get(self.webserver.where_is("element_state/res/visibility-visible.html"))
-        el = self.driver.find_element_by_css("p")
+        el = self.driver.find_element_by_css_selector("p")
         self.assertTrue(el.is_displayed())
 
     def test_visibility_hidden_hides_child_node(self):
         self.driver.get(self.webserver.where_is("element_state/res/visibility-child.html"))
-        parent = self.driver.find_element_by_css("#parent")
-        child = self.driver.find_element_by_css("#child")
+        parent = self.driver.find_element_by_css_selector("#parent")
+        child = self.driver.find_element_by_css_selector("#child")
 
         self.assertFalse(parent.is_displayed())
         self.assertFalse(child.is_displayed())
 
     def test_visibility_hidden_hides_child_node_link(self):
         self.driver.get(self.webserver.where_is("element_state/res/visibility-child-link.html"))
-        parent = self.driver.find_element_by_css("#parent")
-        child = self.driver.find_element_by_css("#child")
+        parent = self.driver.find_element_by_css_selector("#parent")
+        child = self.driver.find_element_by_css_selector("#child")
 
         self.assertFalse(parent.is_displayed())
         self.assertFalse(child.is_displayed())
 
     def test_visibility_hidden_hides_child_node_paragraph(self):
         self.driver.get(self.webserver.where_is("element_state/res/visibility-child-paragraph.html"))
-        parent = self.driver.find_element_by_css("#parent")
-        child = self.driver.find_element_by_css("#child")
+        parent = self.driver.find_element_by_css_selector("#parent")
+        child = self.driver.find_element_by_css_selector("#child")
 
         self.assertFalse(parent.is_displayed())
         self.assertFalse(child.is_displayed())
 
     def test_visibility_hidden_on_child_takes_precedence(self):
         self.driver.get(self.webserver.where_is("element_state/res/visibility-child-presedence.html"))
-        child = self.driver.find_element_by_css("#child")
+        child = self.driver.find_element_by_css_selector("#child")
         self.assertTrue(child.is_displayed())
 
     def test_visibility_hidden_on_parent_takes_precedence_over_display_block(self):
         pass
 
     def test_visibility_hidden_set_dynamically(self):
         pass
 
     def test_should_show_element_not_visible_with_hidden_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/hidden.html"))
-        singleHidden = self.driver.find_element_by_css('#singleHidden')
+        singleHidden = self.driver.find_element_by_css_selector('#singleHidden')
         self.assertFalse(singleHidden.is_displayed())
 
     def test_should_show_element_not_visible_when_parent_element_has_hidden_attribute(self):
         self.driver.get(self.webserver.where_is("element_state/res/hidden.html"))
-        child = self.driver.find_element_by_css('#child')
+        child = self.driver.find_element_by_css_selector('#child')
         self.assertFalse(child.is_displayed())
 
 
 class VisibilityInteractionTest(base_test.WebDriverBaseTest):
     def test_input_hidden_is_unclickable(self):
         self.driver.get(self.webserver.where_is("element_state/res/input-type-hidden-unclickable.html"))
-        input = self.driver.find_element_by_css("input")
+        input = self.driver.find_element_by_css_selector("input")
 
         with self.assertRaises(exceptions.ElementNotVisibleException):
             input.click()
 
     def test_hidden_input_checkbox_is_untogglable(self):
         self.driver.get(self.webserver.where_is("element_state/res/hidden-input-type-checkbox-untogglable.html"))
-        checkbox = self.driver.find_element_by_css("input")
+        checkbox = self.driver.find_element_by_css_selector("input")
 
         with self.assertRaises(exceptions.ElementNotVisibleException):
             checkbox.click()
 
     def test_typing_in_hidden_input_is_impossible(self):
         self.driver.get(self.webserver.where_is("element_state/res/hidden-input-type-text-writing.html"))
-        textfield = self.driver.find_element_by_css("input")
+        textfield = self.driver.find_element_by_css_selector("input")
 
         with self.assertRaises(exceptions.ElementNotVisibleException):
             textfield.send_keys("Koha is a popular Indian cheese")
 
 
 class OpacityTest(base_test.WebDriverBaseTest):
     pass
 
--- a/testing/web-platform/tests/webdriver/javascript/execute_script_test.py
+++ b/testing/web-platform/tests/webdriver/javascript/execute_script_test.py
@@ -1,14 +1,15 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
+from selenium.webdriver.remote.webelement import WebElement
 
 
 class ExecuteScriptTest(base_test.WebDriverBaseTest):
     def test_ecmascript_translates_null_return_to_none(self):
         self.driver.get(self.webserver.where_is("javascript/res/execute_script_test.html"))
         result = self.driver.execute_script("return null;")
         self.assertIsNone(result)
 
--- a/testing/web-platform/tests/webdriver/modal/alerts_quit_test.py
+++ b/testing/web-platform/tests/webdriver/modal/alerts_quit_test.py
@@ -1,24 +1,25 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions, wait
+from selenium.common import exceptions
+from selenium.webdriver.support import wait
 
 
 class AlertsQuitTest(base_test.WebDriverBaseTest):
     def setUp(self):
-        self.wait = wait.WebDriverWait(self.driver, 5, ignored_exceptions=[exceptions.NoSuchAlertException])
+        self.wait = wait.WebDriverWait(self.driver, 5, ignored_exceptions=[exceptions.NoAlertPresentException])
         self.driver.get(self.webserver.where_is('modal/res/alerts.html'))
 
     def test_can_quit_when_an_alert_is_present(self):
-        self.driver.find_element_by_css('#alert').click()
+        self.driver.find_element_by_css_selector('#alert').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         self.driver.quit()
         with self.assertRaises(Exception):
             alert.accept()
         AlertsQuitTest.driver = None
 
 
 if __name__ == '__main__':
--- a/testing/web-platform/tests/webdriver/modal/alerts_test.py
+++ b/testing/web-platform/tests/webdriver/modal/alerts_test.py
@@ -1,147 +1,148 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions, wait
-
+from selenium.common import exceptions
+from selenium.webdriver.support import wait
 
 class AlertsTest(base_test.WebDriverBaseTest):
     def setUp(self):
-        self.wait = wait.WebDriverWait(self.driver, 5, ignored_exceptions = [exceptions.NoSuchAlertException])
+        self.wait = wait.WebDriverWait(self.driver, 5, ignored_exceptions = [exceptions.NoAlertPresentException])
         self.driver.get(self.webserver.where_is('modal/res/alerts.html'))
 
     def tearDown(self):
         try:
             self.driver.switch_to_alert().dismiss()
-        except exceptions.NoSuchAlertException:
+        except exceptions.NoAlertPresentException:
             pass
 
     # Alerts
     def test_should_allow_user_to_accept_an_alert(self):
-        self.driver.find_element_by_css('#alert').click()
+        self.driver.find_element_by_css_selector('#alert').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        self.driver.get_current_url()
+        self.driver.current_url
 
     def test_should_allow_user_to_accept_an_alert_with_no_text(self):
-        self.driver.find_element_by_css('#empty-alert').click()
+        self.driver.find_element_by_css_selector('#empty-alert').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        self.driver.get_current_url()
+        self.driver.current_url
 
     def test_should_allow_user_to_dismiss_an_alert(self):
-        self.driver.find_element_by_css('#alert').click()
+        self.driver.find_element_by_css_selector('#alert').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.dismiss()
-        self.driver.get_current_url()
+        self.driver.current_url
 
     def test_should_allow_user_to_get_text_of_an_alert(self):
-        self.driver.find_element_by_css('#alert').click()
+        self.driver.find_element_by_css_selector('#alert').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
-        value = alert.get_text()
+        value = alert.text
         alert.accept()
         self.assertEquals('cheese', value)
 
     def test_setting_the_value_of_an_alert_throws(self):
-        self.driver.find_element_by_css('#alert').click()
+        self.driver.find_element_by_css_selector('#alert').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
-	with self.assertRaises(exceptions.ElementNotVisibleException):
-	    alert.send_keys('cheese')
+        with self.assertRaises(exceptions.ElementNotVisibleException):
+            alert.send_keys('cheese')
         alert.accept()
 
     def test_alert_should_not_allow_additional_commands_if_dismissed(self):
-        self.driver.find_element_by_css('#alert').click()
+        self.driver.find_element_by_css_selector('#alert').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        with self.assertRaises(exceptions.NoSuchAlertException):
-            alert.get_text()
+        with self.assertRaises(exceptions.NoAlertPresentException):
+            alert.text
 
     # Prompts
     def test_should_allow_user_to_accept_a_prompt(self):
-        self.driver.find_element_by_css('#prompt').click()
+        self.driver.find_element_by_css_selector('#prompt').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        self.wait.until(lambda x: x.find_element_by_css('#text').text == '')
+        self.wait.until(lambda x: x.find_element_by_css_selector('#text').text == '')
 
     def test_should_allow_user_to_dismiss_a_prompt(self):
-        self.driver.find_element_by_css('#prompt').click()
+        self.driver.find_element_by_css_selector('#prompt').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.dismiss()
-        self.wait.until(lambda x: x.find_element_by_css('#text').text == 'null')
+        self.wait.until(lambda x: x.find_element_by_css_selector('#text').text == 'null')
 
     def test_should_allow_user_to_set_the_value_of_a_prompt(self):
-        self.driver.find_element_by_css('#prompt').click()
+        self.driver.find_element_by_css_selector('#prompt').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.send_keys('cheese')
         alert.accept()
-        self.wait.until(lambda x: x.find_element_by_css('#text').text == 'cheese')
+        self.wait.until(lambda x: x.find_element_by_css_selector('#text').text == 'cheese')
 
     def test_should_allow_user_to_get_text_of_a_prompt(self):
-        self.driver.find_element_by_css('#prompt').click()
+        self.driver.find_element_by_css_selector('#prompt').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
-        value = alert.get_text()
+        value = alert.text
         alert.accept()
         self.assertEquals('Enter something', value)
 
     def test_prompt_should_not_allow_additional_commands_if_dismissed(self):
-        self.driver.find_element_by_css('#prompt').click()
+        self.driver.find_element_by_css_selector('#prompt').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        with self.assertRaises(exceptions.NoSuchAlertException):
-            alert.get_text()
+        with self.assertRaises(exceptions.NoAlertPresentException):
+            alert.text
 
     def test_prompt_should_use_default_value_if_no_keys_sent(self):
-        self.driver.find_element_by_css('#prompt-with-default').click()
+        self.driver.find_element_by_css_selector('#prompt-with-default').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        self.wait.until(lambda x: x.find_element_by_css('#text').text == 'This is a default value')
+        self.wait.until(lambda x: x.find_element_by_css_selector('#text').text == 'This is a default value')
 
     def test_prompt_should_have_null_value_if_dismissed(self):
-        self.driver.find_element_by_css('#prompt-with-default').click()
+        self.driver.find_element_by_css_selector('#prompt-with-default').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.dismiss()
-        self.wait.until(lambda x: x.find_element_by_css('#text').text == 'null')
+        self.wait.until(lambda x: x.find_element_by_css_selector('#text').text == 'null')
 
     # Confirmations
     def test_should_allow_user_to_accept_a_confirm(self):
-        self.driver.find_element_by_css('#confirm').click()
+        self.driver.find_element_by_css_selector('#confirm').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        self.wait.until(lambda x: x.find_element_by_css('#text').text == 'true')
+        self.wait.until(lambda x: x.find_element_by_css_selector('#text').text == 'true')
 
     def test_should_allow_user_to_dismiss_a_confirm(self):
-        self.driver.find_element_by_css('#confirm').click()
+        self.driver.find_element_by_css_selector('#confirm').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.dismiss()
-        self.wait.until(lambda x: x.find_element_by_css('#text').text == 'false')
+        self.wait.until(lambda x: x.find_element_by_css_selector('#text').text == 'false')
 
     def test_setting_the_value_of_a_confirm_throws(self):
-        self.driver.find_element_by_css('#confirm').click()
+        self.driver.find_element_by_css_selector('#confirm').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         with self.assertRaises(exceptions.ElementNotVisibleException):
             alert.send_keys('cheese')
         alert.accept()
 
     def test_should_allow_user_to_get_text_of_a_confirm(self):
-        self.driver.find_element_by_css('#confirm').click()
+        self.driver.find_element_by_css_selector('#confirm').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
-        value = alert.get_text()
+        value = alert.text
         alert.accept()
         self.assertEquals('cheese', value)
 
     def test_confirm_should_not_allow_additional_commands_if_dismissed(self):
-        self.driver.find_element_by_css('#confirm').click()
+        self.driver.find_element_by_css_selector('#confirm').click()
         alert = self.wait.until(lambda x: x.switch_to_alert())
         alert.accept()
-        with self.assertRaises(exceptions.NoSuchAlertException):
-            alert.get_text()
+        with self.assertRaises(exceptions.NoAlertPresentException):
+            alert.text
 
+"""
     def test_switch_to_missing_alert_fails(self):
-        with self.assertRaises(exceptions.NoSuchAlertException):
+        with self.assertRaises(exceptions.NoAlertPresentException):
             self.driver.switch_to_alert()
-
+"""
 
 if __name__ == '__main__':
     unittest.main()
--- a/testing/web-platform/tests/webdriver/navigation/auth_tests.py
+++ b/testing/web-platform/tests/webdriver/navigation/auth_tests.py
@@ -1,23 +1,23 @@
 import os
 import sys
 import unittest
 import ConfigParser
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions
+from selenium.common import exceptions
 from wptserve import server
 from wptserve.router import any_method
 from wptserve.handlers import basic_auth_handler
 
 class WebDriverAuthTest(unittest.TestCase):
 
-    # Set up class to start HTTP Server that responds to 
+    # Set up class to start HTTP Server that responds to
     # test URLs with various 401 responses
     @classmethod
     def setUpClass(cls):
         cls.driver = base_test.create_driver()
         cls.webserver = server.WebTestHttpd(routes=[(any_method, "*", basic_auth_handler)])
         cls.webserver.start()
 
     @classmethod
--- a/testing/web-platform/tests/webdriver/navigation/forward.py
+++ b/testing/web-platform/tests/webdriver/navigation/forward.py
@@ -6,19 +6,19 @@ sys.path.insert(1, os.path.abspath(os.pa
 import base_test
 
 
 class ForwardTest(base_test.WebDriverBaseTest):
     # Get a static page that must be the same upon refresh
     def test_forward(self):
         self.driver.get(self.webserver.where_is('navigation/res/forwardStart.html'))
         self.driver.get(self.webserver.where_is('navigation/res/forwardNext.html'))
-        nextbody = self.driver.find_element_by_css("body").text
-        self.driver.go_back()
-        currbody = self.driver.find_element_by_css("body").text
+        nextbody = self.driver.find_element_by_css_selector("body").text
+        self.driver.back()
+        currbody = self.driver.find_element_by_css_selector("body").text
         self.assertNotEqual(nextbody, currbody)
-        self.driver.go_forward()
-        currbody = self.driver.find_element_by_css("body").text
+        self.driver.forward()
+        currbody = self.driver.find_element_by_css_selector("body").text
         self.assertEqual(nextbody, currbody)
 
 
 if __name__ == '__main__':
     unittest.main()
--- a/testing/web-platform/tests/webdriver/navigation/forwardToNothing.py
+++ b/testing/web-platform/tests/webdriver/navigation/forwardToNothing.py
@@ -5,16 +5,16 @@ import unittest
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
 
 
 class ForwardToNothingTest(base_test.WebDriverBaseTest):
     # Get a static page that must be the same upon refresh
     def test_forwardToNothing(self):
         self.driver.get(self.webserver.where_is('navigation/forwardStart.html'))
-        body = self.driver.find_element_by_css("body").text
-        self.driver.go_forward()
-        currbody = self.driver.find_element_by_css("body").text
+        body = self.driver.find_element_by_css_selector("body").text
+        self.driver.forward()
+        currbody = self.driver.find_element_by_css_selector("body").text
         self.assertEqual(body, currbody)
 
 
 if __name__ == '__main__':
     unittest.main()
--- a/testing/web-platform/tests/webdriver/navigation/get_from_http_test.py
+++ b/testing/web-platform/tests/webdriver/navigation/get_from_http_test.py
@@ -5,48 +5,48 @@ import unittest
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
 
 
 class GetFromHttpTest(base_test.WebDriverBaseTest):
     def testGetUrlWithNoRedirectionOverHttp(self):
         page = self.webserver.where_is('navigation/res/empty.html')
         self.driver.get(page)
-        url = self.driver.get_current_url()
+        url = self.driver.current_url
         self.assertEquals(page, url)
 
 
     def testGetWillFollowTheLocationHeader(self):
         page = self.webserver.where_is('navigation/redirect')
         self.driver.get(page)
         expected = self.webserver.where_is('navigation/res/empty.html')
-        url = self.driver.get_current_url()
+        url = self.driver.current_url
         self.assertEquals(expected, url)
 
 
     def testGetWillFollowMetaRefreshThatRefreshesInstantly(self):
         page = self.webserver.where_is('navigation/res/instant-meta-redirect.html')
         self.driver.get(page)
         expected = self.webserver.where_is('navigation/res/empty.html')
-        url = self.driver.get_current_url()
+        url = self.driver.current_url
         self.assertEquals(expected, url)
 
 
     def testGetWillFollowMetaRefreshThatRefreshesAfterOneSecond(self):
         page = self.webserver.where_is('navigation/res/1s-meta-redirect.html')
         self.driver.get(page)
         expected = self.webserver.where_is('navigation/res/empty.html')
-        url = self.driver.get_current_url()
+        url = self.driver.current_url
         self.assertEquals(expected, url)
 
 
     def testGetWillNotFollowMetaRefreshThatRefreshesAfterMoreThanOneSecond(self):
         page = self.webserver.where_is('navigation/res/60s-meta-redirect.html')
         self.driver.get(page)
-        url = self.driver.get_current_url()
+        url = self.driver.current_url
         self.assertEquals(page, url)
 
 
     def testGetFragmentInCurrentDocumentDoesNotReloadPage(self):
         page = self.webserver.where_is("navigation/res/fragment.html")
         fragment_page = "%s#%s" % (page, "fragment")
 
         self.driver.get(page)
--- a/testing/web-platform/tests/webdriver/navigation/invalid_cert_test.py
+++ b/testing/web-platform/tests/webdriver/navigation/invalid_cert_test.py
@@ -16,13 +16,13 @@ class InvalidCertTest(base_test.WebDrive
         self.webserver.httpd.socket = ssl.wrap_socket(
             self.webserver.httpd.socket,
             certfile=os.path.join(here, 'res/self-signed.key'),
             server_side=True)
         expected = self.webserver.where_is(
             'navigation/res/empty.html').replace('http:', 'https:', 1)
 
         self.driver.get(expected)
-        self.assertEquals(expected, self.driver.get_current_url())
+        self.assertEquals(expected, self.driver.current_url)
 
 
 if __name__ == '__main__':
     unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/navigation/refresh_page.py
@@ -0,0 +1,27 @@
+import os
+import sys
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+
+class RefreshPageTest(base_test.WebDriverBaseTest):
+    # Get a static page that must be the same upon refresh
+    def test_refreshPage(self):
+        self.driver.get(self.webserver.where_is('navigation/res/refreshPageStatic.html'))
+        body = self.driver.find_element_by_css_selector("body").text
+        self.driver.execute_script("document.getElementById('body').innerHTML=''")
+        self.driver.refresh()
+        newbody = self.driver.find_element_by_css_selector("body").text
+        self.assertEqual(body, newbody)
+
+        self.driver.get(self.webserver.where_is('navigation/res/refreshPageDynamic.html'))
+        body = self.driver.find_element_by_css_selector("body").text
+        self.driver.refresh()
+        newbody = self.driver.find_element_by_css_selector("body").text
+        self.assertNotEqual(body, newbody)
+
+
+if __name__ == '__main__':
+    unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/runtests_p0.py
@@ -0,0 +1,42 @@
+import unittest
+
+from unittest import TestLoader, TextTestRunner, TestSuite
+
+from cookie import cookie_test
+from navigation import forward
+from navigation import forwardToNothing
+from navigation import get_from_http_test
+from navigation import refresh_page
+from element_location import element_location_test
+from element_state import visibility_test
+from element_state import method_test
+from element_state import properties
+from javascript import execute_script_test
+from user_input import clear_test
+from windows import window_manipulation
+from windows import tabbing
+
+
+
+if __name__ == "__main__":
+
+    loader = TestLoader()
+    suite = TestSuite((
+        loader.loadTestsFromModule(cookie_test),
+        loader.loadTestsFromModule(forward),
+        loader.loadTestsFromModule(forwardToNothing),
+        loader.loadTestsFromModule(element_location_test),
+        loader.loadTestsFromModule(visibility_test),
+        loader.loadTestsFromModule(execute_script_test),
+        loader.loadTestsFromModule(clear_test),
+        loader.loadTestsFromModule(method_test),
+        loader.loadTestsFromModule(properties),
+        loader.loadTestsFromModule(refresh_page),
+        loader.loadTestsFromModule(get_from_http_test),
+        loader.loadTestsFromModule(window_manipulation),
+        loader.loadTestsFromModule(tabbing)
+        ))
+
+    runner = TextTestRunner(verbosity=2)
+    runner.run(suite)
+    unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/screenshot/__init__.py
@@ -0,0 +1,1 @@
+__author__ = 'b-redeg'
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/screenshot/res/screenshot.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>"img" element with not fully qualified url</title>
+
+<img src="//web-platform.test:8000/images/blue.png">&nbsp;</a>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/screenshot/take_screenshot.py
@@ -0,0 +1,15 @@
+import os
+import sys
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+
+class ScreenShotTest(base_test.WebDriverBaseTest):
+    # Get a static page that must be the same upon refresh
+    def test_screenShot(self):
+        self.driver.get(self.webserver.where_is('screenshot/res/screen.html'))
+
+if __name__ == '__main__':
+    unittest.main()
--- a/testing/web-platform/tests/webdriver/timeouts/implicit_waits_tests.py
+++ b/testing/web-platform/tests/webdriver/timeouts/implicit_waits_tests.py
@@ -1,64 +1,64 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions
+from selenium.common import exceptions
 
 
 class ImplicitWaitsTests(base_test.WebDriverBaseTest):
     def setUp(self):
         self.driver.get(self.webserver.where_is('timeouts/res/implicit_waits_tests.html'))
 
     def test_find_element_by_id(self):
-        add = self.driver.find_element_by_css("#adder")
-        self.driver.set_implicit_timeout(3)
+        add = self.driver.find_element_by_css_selector("#adder")
+        self.driver.implicitly_wait(3)
         add.click()
-        self.driver.find_element_by_css("#box0")  # All is well if this doesn't throw.
+        self.driver.find_element_by_css_selector("#box0")  # All is well if this doesn't throw.
 
     def test_should_still_fail_to_find_an_element_when_implicit_waits_are_enabled(self):
-        self.driver.set_implicit_timeout(0.5)
+        self.driver.implicitly_wait(0.5)
         try:
-            self.driver.find_element_by_css("#box0")
+            self.driver.find_element_by_css_selector("#box0")
             self.fail("Expected NoSuchElementException to have been thrown")
         except exceptions.NoSuchElementException as e:
             pass
         except Exception as e:
             self.fail("Expected NoSuchElementException but got " + str(e))
 
     def test_should_return_after_first_attempt_to_find_one_after_disabling_implicit_waits(self):
-        self.driver.set_implicit_timeout(3)
-        self.driver.set_implicit_timeout(0)
+        self.driver.implicitly_wait(3)
+        self.driver.implicitly_wait(0)
         try:
-            self.driver.find_element_by_css("#box0")
+            self.driver.find_element_by_css_selector("#box0")
             self.fail("Expected NoSuchElementException to have been thrown")
         except exceptions.NoSuchElementException as e:
             pass
         except Exception as e:
             self.fail("Expected NoSuchElementException but got " + str(e))
 
     def test_should_implicitly_wait_until_at_least_one_element_is_found_when_searching_for_many(self):
-        add = self.driver.find_element_by_css("#adder")
-        self.driver.set_implicit_timeout(2)
+        add = self.driver.find_element_by_css_selector("#adder")
+        self.driver.implicitly_wait(2)
         add.click()
         add.click()
-        elements = self.driver.find_elements_by_css(".redbox")
+        elements = self.driver.find_elements_by_css_selector(".redbox")
         self.assertTrue(len(elements) >= 1)
 
     def test_should_still_fail_to_find_an_element_by_class_when_implicit_waits_are_enabled(self):
-        self.driver.set_implicit_timeout(0.5)
-        elements = self.driver.find_elements_by_css(".redbox")
+        self.driver.implicitly_wait(0.5)
+        elements = self.driver.find_elements_by_css_selector(".redbox")
         self.assertEqual(0, len(elements))
 
     def test_should_return_after_first_attempt_to_find_many_after_disabling_implicit_waits(self):
-        add = self.driver.find_element_by_css("#adder")
-        self.driver.set_implicit_timeout(1.1)
-        self.driver.set_implicit_timeout(0)
+        add = self.driver.find_element_by_css_selector("#adder")
+        self.driver.implicitly_wait(1.1)
+        self.driver.implicitly_wait(0)
         add.click()
-        elements = self.driver.find_elements_by_css(".redbox")
+        elements = self.driver.find_elements_by_css_selector(".redbox")
         self.assertEqual(0, len(elements))
 
 
 if __name__ == "__main__":
     unittest.main()
--- a/testing/web-platform/tests/webdriver/timeouts/page_load_timeouts_tests.py
+++ b/testing/web-platform/tests/webdriver/timeouts/page_load_timeouts_tests.py
@@ -1,15 +1,15 @@
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions
+from selenium.common import exceptions
 
 
 class PageLoadTimeoutTest(base_test.WebDriverBaseTest):
     def test_should_timeout_on_page_load_taking_too_long(self):
         self.driver.set_page_load_timeout(0.01)
         with self.assertRaises(exceptions.TimeoutException):
             self.load_page()
 
--- a/testing/web-platform/tests/webdriver/user_input/clear_test.py
+++ b/testing/web-platform/tests/webdriver/user_input/clear_test.py
@@ -1,53 +1,53 @@
 # -*- mode: python; fill-column: 100; comment-column: 100; -*-
 
 import os
 import sys
 import unittest
 
 sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
 import base_test
-from webdriver import exceptions
+from selenium.common import exceptions
 
 
 class ElementClearTest(base_test.WebDriverBaseTest):
     def test_writable_text_input_element_should_clear(self):
         self.driver.get(self.webserver.where_is("user_input/res/element_clear_writable_input_page.html"))
-        e = self.driver.find_element_by_css("#writableTextInput")
+        e = self.driver.find_element_by_css_selector("#writableTextInput")
         e.clear()
         self.assertEquals("", e.get_attribute("value"))
 
     def test_disabled_text_input_element_should_not_clear(self):
         self.driver.get(self.webserver.where_is("user_input/res/element_clear_disabled_input_page.html"))
-        e = self.driver.find_element_by_css("#disabledTextInput")
+        e = self.driver.find_element_by_css_selector("#disabledTextInput")
         self.assertRaises(exceptions.InvalidElementStateException, lambda: e.clear())
 
     def test_read_only_text_input_element_should_not_clear(self):
         self.driver.get(self.webserver.where_is("user_input/res/element_clear_readonly_input_page.html"))
-        e = self.driver.find_element_by_css("#readOnlyTextInput")
+        e = self.driver.find_element_by_css_selector("#readOnlyTextInput")
         self.assertRaises(exceptions.InvalidElementStateException, lambda: e.clear())
 
     def test_writable_text_area_element_should_clear(self):
         self.driver.get(self.webserver.where_is("user_input/res/element_clear_writable_textarea_page.html"))
-        e = self.driver.find_element_by_css("#writableTextArea")
+        e = self.driver.find_element_by_css_selector("#writableTextArea")
         e.clear()
         self.assertEquals("", e.get_attribute("value"))
 
     def test_disabled_text_area_element_should_not_clear(self):
         self.driver.get(self.webserver.where_is("user_input/res/element_clear_disabled_textarea_page.html"))
-        e = self.driver.find_element_by_css("#disabledTextArea")
+        e = self.driver.find_element_by_css_selector("#disabledTextArea")
         self.assertRaises(exceptions.InvalidElementStateException, lambda: e.clear())
 
     def test_read_only_text_input_element_should_not_clear(self):
         self.driver.get(self.webserver.where_is("user_input/res/element_clear_readonly_textarea_page.html"))
-        e = self.driver.find_element_by_css("#readOnlyTextArea")
+        e = self.driver.find_element_by_css_selector("#readOnlyTextArea")
         self.assertRaises(exceptions.InvalidElementStateException, lambda: e.clear())
 
     def test_content_editable_area_should_clear(self):
         self.driver.get(self.webserver.where_is("user_input/res/element_clear_contenteditable_page.html"))
-        e = self.driver.find_element_by_css("#contentEditableElement")
+        e = self.driver.find_element_by_css_selector("#contentEditableElement")
         e.clear()
         self.assertEquals("", e.text)
 
 
 if __name__ == "__main__":
     unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/user_input/click_test.py
@@ -0,0 +1,349 @@
+import os
+import sys
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+repo_root = os.path.abspath(os.path.join(__file__, "../../.."))
+sys.path.insert(1, os.path.join(repo_root, "tools", "webdriver"))
+from webdriver import exceptions, wait
+
+
+class ClickTest(base_test.WebDriverBaseTest):
+    def setUp(self):
+        self.wait = wait.WebDriverWait(self.driver, 5, ignored_exceptions = [exceptions.NoSuchAlertException])
+        self.driver.get(self.webserver.where_is('modal/res/alerts.html'))
+
+    def tearDown(self):
+        try:
+            self.driver.switch_to_alert().dismiss()
+        except exceptions.NoSuchAlertException:
+            pass
+
+    def test_click_div(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("div")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "div")
+
+    def test_click_p(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("p")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "p")
+
+    def test_click_h1(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("h1")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "h1")
+
+    def test_click_pre(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("pre")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "pre")
+
+    def test_click_ol(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("ol")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "ol")
+
+    def test_click_ul(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("ul")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "ul")
+
+    def test_click_a(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("a")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "a")
+
+    def test_click_img(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("img")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "img")
+
+    def test_click_video(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("video")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "video")
+
+    def test_click_canvas(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("canvas")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "canvas")
+
+    def test_click_progress(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("progress")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "progress")
+
+    def test_click_textarea(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("textarea")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "textarea")
+
+    def test_click_button(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("button")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "button")
+
+    def test_click_svg(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("svg")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "svg")
+
+    def test_click_input_range(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_range")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_range")
+
+    def test_click_input_button(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_button")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_button")
+
+    def test_click_input_submit(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_submit")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_submit")
+
+    def test_click_input_reset(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_reset")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_reset")
+
+    def test_click_input_checkbox(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_checkbox")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_checkbox")
+
+    def test_click_input_radio(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_radio")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_radio")
+
+    def test_click_input_text(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_text")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_text")
+
+    def test_click_input_number(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_number")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_number")
+
+    def test_click_input_tel(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_tel")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_tel")
+
+    def test_click_input_url(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_url")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_url")
+
+    def test_click_input_email(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_email")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_email")
+
+    def test_click_input_search(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_search")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_search")
+
+    def test_click_input_image(self):
+        self.driver.get(self.webserver.where_is("user_input/res/click.html"))
+
+        element = self.driver.find_element_by_id("input_image")
+        element.click()
+
+        alert = self.wait.until(lambda x: x.switch_to_alert())
+        value = alert.get_text()
+        alert.accept()
+
+        self.assertEquals(value, "input_image")
+
+if __name__ == "__main__":
+    unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/user_input/res/click.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta charset="utf-8" />
+    <title></title>
+    <style>
+        .testcase {
+            background-color: #DDD;
+            margin: 30px;
+            min-width: 500px;
+            min-height: 70px;
+        }
+    </style>
+</head>
+<body>
+    <div id="div" class="testcase" onclick="alert('div')">div</div>
+    <p id="p" class="testcase" onclick="alert('p')">p</p>
+    <h1 id="h1" class="testcase" onclick="alert('h1')">h1</h1>
+    <pre id="pre" class="testcase" onclick="alert('pre')">pre</pre>
+    <ol id="ol" class="testcase" onclick="alert('ol')">ol</ol>
+    <ul id="ul" class="testcase" onclick="alert('ul')">ul</ul>
+    <a id="a" class="testcase" onclick="alert('a')">a</a>
+    <img id="img" class="testcase" onclick="alert('img')" src="data:image/png;base64,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AJgMEkAAAAAAk0ECCAAAAGAySAABAAAATAYJIAAAAIDJIAEEAAAAMBkkgAAAAAAmgwQQAAAAwGSQAAIAAACYDBJAAAAAAJNBAggAAABgMkgAAQAAAEwGCSAAAACAySABBAAAADAZJIAAAAAAJoMEEAAAAMBkkAACAAAAmAwSQAAAAACTQQIIAAAAYDJIAAEAAABMBgkgAAAAgMkgAQQAAAAwGSSAAAAAACaDBBAAAADAZJAAAgAAAJgMEkAAAAAAk0ECCAAAAGAySAABAAAATAYJIAAAAIDJIAEEAAAAMBkkgAAAAAAmgwQQAAAAwGSQAAIAAACYDBJAAAAAAJNBAggAAABgMkgAAQAAAEwGCSAAAACAySABBAAAADAZJIAAAAAAJoMEEAAAAMBkkAACAAAAmAwSQAAAAACTQQIIAAAAYDJIAAEAAABMBgkgAAAAgMkgAQQAAAAwGSSAAAAAACaDBBAAAADAZJAAAgAAAJgMEkAAAAAAk0ECCAAAAGAySAABAAAATAYJIAAAAIDJIAEEAAAAMBkkgAAAAAAmgwQQAAAAwGSQAAIAAACYDBJAAAAAAJNBAggAAABgMkgAAQAAAEwGCSAAAACAySABBAAAADAZJIAAAAAAJoMEEAAAAMBkkAACAAAAmAwSQAAAAACTQQIIAAAAYDJIAAEAAABMBgkgAAAAgMkgAQQAAAAwFaL/A1remQsHpt6bAAAAAElFTkSuQmCC" />
+    <video id="video" class="testcase" onclick="alert('video')">video</video>
+    <canvas id="canvas" class="testcase" onclick="alert('canvas')">canvas</canvas>
+    <progress id="progress" class="testcase" onclick="alert('progress')">progress</progress>
+    <textarea id="textarea" class="testcase" onclick="alert('textarea')">textarea</textarea>
+    <button id="button" class="testcase" onclick="alert('button')">button</button>
+    <svg id="svg" class="testcase" onclick="alert('svg')"><circle cx="50" cy="50" r="40" stroke="white" stroke-width="4" fill="blue" /></svg>
+    <input id="input_range" class="testcase" onclick="alert('input_range')" type="range" />
+    <input id="input_button" class="testcase" onclick="alert('input_button')" type="button" />
+    <input id="input_submit" class="testcase" onclick="alert('input_submit')" type="submit" />
+    <input id="input_reset" class="testcase" onclick="alert('input_reset')" type="reset" />
+    <input id="input_checkbox" class="testcase" onclick="alert('input_checkbox')" type="checkbox" />
+    <input id="input_radio" class="testcase" onclick="alert('input_radio')" type="radio" />
+    <input id="input_text" class="testcase" onclick="alert('input_text')" type="text" />
+    <input id="input_number" class="testcase" onclick="alert('input_number')" type="number" />
+    <input id="input_tel" class="testcase" onclick="alert('input_tel')" type="tel" />
+    <input id="input_url" class="testcase" onclick="alert('input_url')" type="url" />
+    <input id="input_email" class="testcase" onclick="alert('input_email')" type="email" />
+    <input id="input_search" class="testcase" onclick="alert('input_search')" type="search" />
+    <input id="input_image" class="testcase" onclick="alert('input_image')" type="image" />
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/user_input/res/text-form-landing.html
@@ -0,0 +1,8 @@
+<html>
+<head>
+    <meta charset="utf-8" />
+    <title>Text Form Landing</title>
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/user_input/res/text-form.html
@@ -0,0 +1,25 @@
+<html>
+<head>
+    <title>Text Form</title>
+    <meta charset="utf-8" />
+    <script>
+        function key_press() {
+            document.getElementById("text").textContent = document.getElementById("Text1").value;
+        }
+
+        function got_focus() {
+            var output = document.getElementById("output");
+            output.checked = true;
+        }
+    </script>
+</head>
+<body>
+    <p id="text"></p>
+    <form action="text-form-landing.html">
+        <input id="Text1" type="text" onkeyup="key_press()"/>
+        <input id="Text2" type="text" onfocus="got_focus()" />
+        <input id="output" type="checkbox" />
+        <input type="submit" name="e" value="mc2" />
+    </form>
+</body>
+</html>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/user_input/sendkeys_test.py
@@ -0,0 +1,96 @@
+import os
+import sys
+import random
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+
+repo_root = os.path.abspath(os.path.join(__file__, "../../.."))
+sys.path.insert(1, os.path.join(repo_root, "tools", "webdriver"))
+from webdriver import exceptions
+
+
+class SendKeysTest(base_test.WebDriverBaseTest):
+    def setUp(self):
+        self.driver.get(self.webserver.where_is("user_input/res/text-form.html"))
+
+    def test_send_simple_string(self):
+        element = self.driver.find_element_by_id("Text1")
+        element.send_keys("lorem ipsum")
+
+        self.assertEquals(self.driver.find_element_by_id("text").get_text(), u"lorem ipsum")
+
+    def test_send_return(self):
+        element = self.driver.find_element_by_id("Text1")
+        returnkey = unichr(int("E006", 16))
+        element.send_keys([returnkey])
+
+        self.assertEquals(u"" + self.driver.get_current_url(), u"" + self.webserver.where_is("user_input/res/text-form-landing.html?e=mc2"))
+
+    def test_send_backspace(self):
+        element = self.driver.find_element_by_id("Text1")
+        element.send_keys("world ")
+        element.send_keys("wide ")
+        element.send_keys("web ")
+        element.send_keys("consortium")
+
+        backspace= unichr(int("E003", 16))
+        for i in range(0, 11):
+            element.send_keys([backspace])
+
+        self.assertEquals(self.driver.find_element_by_id("text").get_text(), u"world wide web")
+
+    def test_send_tab(self):
+        element1 = self.driver.find_element_by_id("Text1")
+        element2 = self.driver.find_element_by_id("Text2")
+        element1.send_keys("typing here")
+
+        tab= unichr(int("E004", 16))
+        element1.send_keys([tab])
+
+        output = self.driver.find_element_by_id("output")
+        tab_pressed = output.get_attribute("checked")
+        self.assertEquals(tab_pressed, u"true")
+
+    def test_send_shift(self):
+        element = self.driver.find_element_by_id("Text1")
+        element.send_keys("low ")
+
+        shift= unichr(int("E008", 16))
+        element.send_keys([shift , "u", "p", shift])
+
+        self.assertEquals(self.driver.find_element_by_id("text").get_text(), u"low UP")
+
+    def test_send_arrow_keys(self):
+        element = self.driver.find_element_by_id("Text1")
+
+        element.send_keys("internet")
+
+        backspace= unichr(int("E003", 16))
+        left= unichr(int("E012", 16))
+        right= unichr(int("E014", 16))
+        for i in range(0, 4):
+            element.send_keys([left])
+
+        element.send_keys([backspace])
+        element.send_keys([right])
+        element.send_keys("a")
+
+        self.assertEquals(self.driver.find_element_by_id("text").get_text(), u"intranet")
+
+    def test_select_text_with_shift(self):
+        element = self.driver.find_element_by_id("Text1")
+
+        element.send_keys("WebDriver")
+        backspace= unichr(int("E003", 16))
+        shift= unichr(int("E008", 16))
+        left= unichr(int("E012", 16))
+
+        element.send_keys([shift, left, left, left, left, left, left, backspace])
+
+        self.assertEquals(self.driver.find_element_by_id("text").get_text(), u"Web")
+
+
+if __name__ == "__main__":
+    unittest.main()
--- a/testing/web-platform/tests/webdriver/webdriver.cfg
+++ b/testing/web-platform/tests/webdriver/webdriver.cfg
@@ -16,16 +16,20 @@ mode: compatibility
 url: http://localhost:9515
 capabilities: {"browserName": "chrome"}
 mode: compatibility
 
 [ie]
 capabilities: {"browserName": "ie"}
 mode: compatibility
 
+[edge]
+capabilities: {"browserName": "edge"}
+mode: compatibility
+
 [ios-driver]
 capabilities: {"browserName": "iphone"}
 mode: compatibility
 
 [blackberry]
 url: http://169.254.0.1:1338
 capabilities: {"browserName": "blackberry"}
 mode: compatibility
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/__init__.py
@@ -0,0 +1,1 @@
+__author__ = 'b-redeg'
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/res/win1.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>window one</title>
+
+<div onclick="window.open('win2.html')">win2</div>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/res/win2.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>window two</title>
+
+<img src="//web-platform.test:8000/images/blue.png">&nbsp;</a>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/res/win3.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>window three</title>
+
+<img src="//web-platform.test:8000/images/blue.png">&nbsp;</a>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/res/win4.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>window four</title>
+
+<img src="//web-platform.test:8000/images/blue.png">&nbsp;</a>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/res/win5.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<title>window five</title>
+
+<img src="//web-platform.test:8000/images/blue.png">&nbsp;</a>
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/tabbing.py
@@ -0,0 +1,30 @@
+# -*- mode: python; fill-column: 100; comment-column: 100; -*-
+
+import os
+import sys
+import unittest
+import time
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+from selenium.common import exceptions
+from selenium.webdriver.common.keys import Keys
+from selenium.webdriver.common.action_chains import ActionChains
+
+
+class tabbingTest(base_test.WebDriverBaseTest):
+    def test_open_close_tab(self):
+        self.driver.get(self.webserver.where_is("windows/res/win1.html"))
+        self.driver.find_element_by_tag_name("div").click()
+        h = self.driver.window_handles
+        self.assertEquals(2, len(h))
+        self.driver.switch_to.window(h[1])
+        try:
+            self.driver.switch_to.window("does not exist")
+            self.fail("NoSuchWindowException expected")
+        except exceptions.NoSuchWindowException:
+            pass
+        self.driver.close()
+
+if __name__ == "__main__":
+    unittest.main()
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/webdriver/windows/window_manipulation.py
@@ -0,0 +1,43 @@
+# -*- mode: python; fill-column: 100; comment-column: 100; -*-
+
+import os
+import sys
+import unittest
+
+sys.path.insert(1, os.path.abspath(os.path.join(__file__, "../..")))
+import base_test
+from selenium.common import exceptions
+
+
+class WindowingTest(base_test.WebDriverBaseTest):
+    def test_maximize(self):
+        #self.driver.get(self.webserver.where_is("windows/res/win1.html"))
+        self.driver.maximize_window()
+
+    def test_window_size_manipulation(self):
+        #self.driver.get(self.webserver.where_is("windows/res/win1.html"))
+        self.driver.set_window_size(400, 400)
+        window_size = self.driver.get_window_size()
+        self.assertTrue("width" in window_size)
+        self.assertTrue("height" in window_size)
+        self.assertEquals({"width": 400, "height":400}, window_size)
+
+        """
+        todo: make that work
+        see: https://w3c.github.io/webdriver/webdriver-spec.html#setwindowsize
+                result = self.driver.set_window_size(100, 100)
+                self.assertTrue("status" in result)
+                self.assertEquals(result["status"], 500)
+        """
+
+    def test_window_position_manipulation(self):
+        #self.driver.get(self.webserver.where_is("windows/res/win1.html"))
+        self.driver.set_window_position(400, 400)
+        window_position = self.driver.get_window_position()
+        self.assertTrue("x" in window_position)
+        self.assertTrue("y" in window_position)
+        self.assertEquals({"x": 400, "y": 400}, window_position)
+
+
+if __name__ == "__main__":
+    unittest.main()
--- a/testing/web-platform/tests/webstorage/eventTestHarness.js
+++ b/testing/web-platform/tests/webstorage/eventTestHarness.js
@@ -28,16 +28,30 @@ function countStorageEvents(callback, ex
             callback(msg);
         } else {
             countStorageEvents(callback, expectedNumEvents, times+1);
         }
     }
     setTimeout(onTimeout, 20);
 }
 
+function clearStorage(storageName, callback)
+{
+    if (window[storageName].length === 0) {
+        storageEventList = [];
+        setTimeout(callback, 0);
+    } else {
+        window[storageName].clear();
+        runAfterNStorageEvents(function() {
+            storageEventList = [];
+            callback();
+        }, 1);
+    }
+}
+
 function testStorages(testCallback)
 {
     testCallback("sessionStorage");
     var hit = false;
     add_result_callback(function() {
         if (!hit) {
             hit = true;
             testCallback("localStorage");
--- a/testing/web-platform/tests/webstorage/event_basic.js
+++ b/testing/web-platform/tests/webstorage/event_basic.js
@@ -1,23 +1,19 @@
 testStorages(function(storageString) {
     async_test(function(t) {
         assert_true(storageString in window, storageString + " exist");
         var storage = window[storageString];
         t.add_cleanup(function() { storage.clear() });
 
-        storageEventList = new Array();
-        storage.clear();
+        clearStorage(storageString, t.step_func(step1));
         assert_equals(storage.length, 0, "storage.length");
 
-        runAfterNStorageEvents(t.step_func(step1), 0);
-
         function step1(msg)
         {
-            storageEventList = new Array();
             storage.setItem('FOO', 'BAR');
 
             runAfterNStorageEvents(t.step_func(step2), 1);
         }
 
         function step2(msg)
         {
             if(msg != undefined) {
--- a/testing/web-platform/tests/webstorage/event_body_attribute.js
+++ b/testing/web-platform/tests/webstorage/event_body_attribute.js
@@ -1,19 +1,22 @@
 testStorages(function(storageString) {
     async_test(function(t) {
         assert_true(storageString in window, storageString + " exist");
         var storage = window[storageString];
         t.add_cleanup(function() { storage.clear() });
 
-        storage.clear();
+        clearStorage(storageString, t.step_func(step0));
         assert_equals(storage.length, 0, "storage.length");
 
-        iframe.onload = t.step_func(step1);
-        iframe.src = "resources/event_body_handler.html";
+        function step0(msg)
+        {
+            iframe.onload = t.step_func(step1);
+            iframe.src = "resources/event_body_handler.html";
+        }
 
         function step1(msg)
         {
             storageEventList = new Array();
             storage.setItem('FOO', 'BAR');
 
             runAfterNStorageEvents(t.step_func(step2), 1);
         }
--- a/testing/web-platform/tests/webstorage/event_case_sensitive.js
+++ b/testing/web-platform/tests/webstorage/event_case_sensitive.js
@@ -1,19 +1,22 @@
 testStorages(function(storageString) {
     async_test(function(t) {
         assert_true(storageString in window, storageString + " exist");
         var storage = window[storageString];
         t.add_cleanup(function() { storage.clear() });
 
-        storage.clear();
+        clearStorage(storageString, t.step_func(step0));
         assert_equals(storage.length, 0, "storage.length");
-        storage.foo = "test";
 
-        runAfterNStorageEvents(t.step_func(step1), 1);
+        function step0(msg)
+        {
+            storage.foo = "test";
+            runAfterNStorageEvents(t.step_func(step1), 1);
+        }
 
         function step1(msg)
         {
             storageEventList = new Array();
             storage.foo = "test";
 
             runAfterNStorageEvents(t.step_func(step2), 0);
         }
--- a/testing/web-platform/tests/webstorage/event_constructor_eventinit.html
+++ b/testing/web-platform/tests/webstorage/event_constructor_eventinit.html
@@ -4,34 +4,31 @@
   <title>WebStorage Test: StorageEvent - StorageEventInit with null value</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
  </head>
  <body>
     <h1>event_Constructor</h1>
     <div id="log"></div>
     <script>
-        test(function() {
-            var t = async_test("StorageEvent constructor and nulls");
+        async_test(function(t) {
             function onStorageEvent(event) {
-                t.step(function() {
-                    assert_equals(event.type, 'storage', 'type');
-                    assert_equals(event.key, null, 'key');
-                    assert_equals(event.oldValue, null, 'oldValue');
-                    assert_equals(event.newValue, null, 'newValue');
-                    assert_equals(event.url, 'null', 'url');
-                    assert_equals(event.storageArea, null, 'storageArea');
-                });
+                assert_equals(event.type, 'storage', 'type');
+                assert_equals(event.key, null, 'key');
+                assert_equals(event.oldValue, null, 'oldValue');
+                assert_equals(event.newValue, null, 'newValue');
+                assert_equals(event.url, 'null', 'url');
+                assert_equals(event.storageArea, null, 'storageArea');
                 t.done();
             }
 
-            window.addEventListener('storage', onStorageEvent, false);
+            window.addEventListener('storage', t.step_func(onStorageEvent), false);
             var event = new StorageEvent('storage', {
                 key: null,
                 oldValue: null,
                 newValue: null,
                 url: null
             });
             window.dispatchEvent(event);
-        }, "Construct StorageEvent with StorageEventInit.");
+        }, "StorageEvent constructor and nulls - Construct StorageEvent with StorageEventInit.");
     </script>
  </body>
 </html>
--- a/testing/web-platform/tests/webstorage/event_local_key.html
+++ b/testing/web-platform/tests/webstorage/event_local_key.html
@@ -1,43 +1,38 @@
 <!DOCTYPE HTML>
 <html>
  <head>
   <title>WebStorage Test: localStorage event - key</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
-  <script>
-      function fail(msg) {
-          t.step(function() {
-              assert_unreached(msg);
-          });
-          t.done();
-      }
-  </script>
  </head>
  <body>
     <h1>event_local_key</h1>
     <div id="log"></div>
     <script>
-        var t = async_test("key property test of local event");
+        async_test(function(t) {
+            localStorage.clear();
+            t.add_cleanup(function() { localStorage.clear() });
 
-        test(function() {
-            localStorage.clear();
+            self.fail = t.step_func(function(msg) {
+                assert_unreached(msg);
+                t.done();
+            });
+
             var expected = ['name', null]
             function onStorageEvent(event) {
-                t.step(function() {
-                    assert_equals(event.key, expected.shift());
-                });
+                assert_equals(event.key, expected.shift());
                 if (!expected.length) {
                     t.done();
                 }
             }
 
-            window.addEventListener('storage', onStorageEvent, false);
+            window.addEventListener('storage', t.step_func(onStorageEvent), false);
 
             var el = document.createElement("iframe");
             el.setAttribute('id', 'ifrm');
             el.setAttribute('src', 'resources/local_set_item_clear_iframe.html');
             document.body.appendChild(el);
-        }, "Local event is fired due to an invocation of the setItem(), clear() methods.");
+        }, "key property test of local event - Local event is fired due to an invocation of the setItem(), clear() methods.");
     </script>
  </body>
 </html>
--- a/testing/web-platform/tests/webstorage/event_local_newvalue.html
+++ b/testing/web-platform/tests/webstorage/event_local_newvalue.html
@@ -1,43 +1,38 @@
 <!DOCTYPE HTML>
 <html>
  <head>
   <title>WebStorage Test: localStorage event - newValue</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
-  <script>
-      function fail(msg) {
-          t.step(function() {
-              assert_unreached(msg);
-          });
-          t.done();
-      }
-  </script>
  </head>
  <body>
     <h1>event_local_newValue</h1>
     <div id="log"></div>
     <script>
-        var t = async_test("newValue property test of local event");
+        async_test(function(t) {
+            localStorage.clear();
+            t.add_cleanup(function() { localStorage.clear() });
 
-        test(function() {
-            localStorage.clear();
+            self.fail = t.step_func(function(msg) {
+                assert_unreached(msg);
+                t.done();
+            });
+
             var expected = ['user1', 'user2', null]
             function onStorageEvent(event) {
-                t.step(function() {
-                    assert_equals(event.newValue, expected.shift());
-                });
+                assert_equals(event.newValue, expected.shift());
                 if (!expected.length) {
                     t.done();
                 }
             }
 
-            window.addEventListener('storage', onStorageEvent, false);
+            window.addEventListener('storage', t.step_func(onStorageEvent), false);
 
             var el = document.createElement("iframe");
             el.setAttribute('id', 'ifrm');
             el.setAttribute('src', 'resources/local_change_item_iframe.html');
             document.body.appendChild(el);
-        }, "Local event is fired due to an invocation of the setItem(), clear() methods.");
+        }, "newValue property test of local event - Local event is fired due to an invocation of the setItem(), clear() methods.");
     </script>
  </body>
 </html>
--- a/testing/web-platform/tests/webstorage/event_local_oldvalue.html
+++ b/testing/web-platform/tests/webstorage/event_local_oldvalue.html
@@ -1,43 +1,38 @@
 <!DOCTYPE HTML>
 <html>
  <head>
   <title>WebStorage Test: localStorage event - oldValue</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
-  <script>
-      function fail(msg) {
-          t.step(function() {
-              assert_unreached(msg);
-          });
-          t.done();
-      }
-  </script>
  </head>
  <body>
     <h1>event_local_oldValue</h1>
     <div id="log"></div>
     <script>
-        var t = async_test("oldValue property test of local event");
+        async_test(function(t) {
+            localStorage.clear();
+            t.add_cleanup(function() { localStorage.clear() });
 
-        test(function() {
-            localStorage.clear();
+            self.fail = t.step_func(function(msg) {
+                assert_unreached(msg);
+                t.done();
+            });
+
             var expected = [null, 'user1', null]
             function onStorageEvent(event) {
-                t.step(function() {
-                    assert_equals(event.oldValue, expected.shift());
-                });
+                assert_equals(event.oldValue, expected.shift());
                 if (!expected.length) {
                     t.done();
                 }
             }
 
-            window.addEventListener('storage', onStorageEvent, false);
+            window.addEventListener('storage', t.step_func(onStorageEvent), false);
 
             var el = document.createElement("iframe");
             el.setAttribute('id', 'ifrm');
             el.setAttribute('src', 'resources/local_change_item_iframe.html');
             document.body.appendChild(el);
-        }, "Local event is fired due to an invocation of the setItem(), clear() methods.");
+        }, "oldValue property test of local event - Local event is fired due to an invocation of the setItem(), clear() methods.");
     </script>
  </body>
 </html>
--- a/testing/web-platform/tests/webstorage/event_local_removeitem.html
+++ b/testing/web-platform/tests/webstorage/event_local_removeitem.html
@@ -4,20 +4,21 @@
 <link rel="author" title="Intel" href="http://www.intel.com">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 
 <div id="log"></div>
 
 <script>
 
-var t = async_test("key property test of local event");
+async_test(function(t) {
+    localStorage.clear();
+    t.add_cleanup(function() { localStorage.clear() });
 
-t.step(function() {
-    localStorage.clear();
+    self.step = function(f) { t.step(f); };
 
     var event_index = 0;
     window.addEventListener('storage', t.step_func(function(event) {
         switch(++event_index) {
             case 1:
                 assert_equals(event.key, "name", "set key");
                 assert_equals(event.oldValue, null, "set oldValue");
                 assert_equals(event.newValue, "user1", "set newValue");
@@ -34,11 +35,11 @@ t.step(function() {
                 break;
         }
     }), false);
 
     var el = document.createElement("iframe");
     el.setAttribute('id', 'ifrm');
     el.setAttribute('src', 'resources/local_set_item_remove_iframe.html');
     document.body.appendChild(el);
-});
+}, "key property test of local event");
 
 </script>
--- a/testing/web-platform/tests/webstorage/event_local_storagearea.html
+++ b/testing/web-platform/tests/webstorage/event_local_storagearea.html
@@ -1,44 +1,39 @@
 <!DOCTYPE HTML>
 <html>
  <head>
   <title>WebStorage Test: localStorage event - storageArea</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
-  <script>
-      function fail(msg) {
-          t.step(function() {
-              assert_unreached(msg);
-          });
-          t.done();
-      }
-  </script>
  </head>
  <body>
     <h1>event_local_storageArea</h1>
     <div id="log"></div>
     <script>
-        var t = async_test("storageArea property test of local event");
+        async_test(function(t) {
+            localStorage.clear();
+            t.add_cleanup(function() { localStorage.clear() });
 
-        test(function() {
-            localStorage.clear();
+            self.fail = t.step_func(function(msg) {
+                assert_unreached(msg);
+                t.done();
+            });
+
             function onStorageEvent(event) {
-                t.step(function() {
-                    assert_equals(event.storageArea.length, 1);
-                    var key = event.storageArea.key(0);
-                    var value = event.storageArea.getItem(key);
-                    assert_equals(key, "name");
-                    assert_equals(value, "user1");
-                });
+                assert_equals(event.storageArea.length, 1);
+                var key = event.storageArea.key(0);
+                var value = event.storageArea.getItem(key);
+                assert_equals(key, "name");
+                assert_equals(value, "user1");
                 t.done();
             }
 
-            window.addEventListener('storage', onStorageEvent, false);
+            window.addEventListener('storage', t.step_func(onStorageEvent), false);
 
             var el = document.createElement("iframe");
             el.setAttribute('id', 'ifrm');
             el.setAttribute('src', 'resources/local_set_item_iframe.html');
             document.body.appendChild(el);
-        }, "Local event is fired due to an invocation of the setItem() method.");
+        }, "storageArea property test of local event - Local event is fired due to an invocation of the setItem() method.");
     </script>
  </body>
 </html>
--- a/testing/web-platform/tests/webstorage/event_local_storageeventinit.html
+++ b/testing/web-platform/tests/webstorage/event_local_storageeventinit.html
@@ -4,36 +4,34 @@
   <title>WebStorage Test: localStorage event - StorageEventInit</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
  </head>
  <body>
     <h1>event_local_StorageEventInit</h1>
     <div id="log"></div>
     <script>
-        test(function() {
-            var t = async_test("storageeventinit test");
+        async_test(function(t) {
+
             function onStorageEvent(event) {
-                t.step(function() {
-                    assert_equals(event.key, 'key');
-                    assert_equals(event.oldValue, 'oldValue');
-                    assert_equals(event.newValue, 'newValue');
-                    assert_equals(event.url, window.location.href);
-                    assert_equals(event.storageArea, window.localStorage);
-                });
+                assert_equals(event.key, 'key');
+                assert_equals(event.oldValue, 'oldValue');
+                assert_equals(event.newValue, 'newValue');
+                assert_equals(event.url, window.location.href);
+                assert_equals(event.storageArea, window.localStorage);
                 t.done();
             }
 
-            window.addEventListener('storage', onStorageEvent, false);
+            window.addEventListener('storage', t.step_func(onStorageEvent), false);
 
             var event = new StorageEvent('storage', {
                 key: 'key',
                 oldValue: 'oldValue',
                 newValue: 'newValue',
                 url: window.location.href,
                 storageArea: window.localStorage
             });
 
             window.dispatchEvent(event);
-        }, "Storage event is fired due to set values for StorageEventInit.");
+        }, "storageeventinit test - Storage event is fired due to set values for StorageEventInit.");
     </script>
  </body>
 </html>
--- a/testing/web-platform/tests/webstorage/event_local_url.html
+++ b/testing/web-platform/tests/webstorage/event_local_url.html
@@ -1,48 +1,43 @@
 <!DOCTYPE HTML>
 <html>
  <head>
   <title>WebStorage Test: localStorage event - url</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
-  <script>
-      function fail(msg) {
-          t.step(function() {
-              assert_unreached(msg);
-          });
-          t.done();
-      }
-  </script>
  </head>
  <body>
     <h1>event_local_url</h1>
     <div id="log"></div>
     <script>
-        var t = async_test("url property test of local event");
-
-        test(function() {
+        async_test(function(t) {
             localStorage.clear();
-            function onStorageEvent(event) {
-                t.step(function() {
-                    var url = window.location.href;
+            t.add_cleanup(function() { localStorage.clear() });
+
+            self.fail = t.step_func(function(msg) {
+                assert_unreached(msg);
+                t.done();
+            });
 
-                    var pos = url.lastIndexOf("/");
-                    if (pos != -1) {
-                        url = url.substr(0, pos + 1);
-                        url = url + "resources/local_set_item_iframe.html";
-                    }
+            function onStorageEvent(event) {
+                var url = window.location.href;
 
-                   assert_equals(event.url, url);
-                });
+                var pos = url.lastIndexOf("/");
+                if (pos != -1) {
+                    url = url.substr(0, pos + 1);
+                    url = url + "resources/local_set_item_iframe.html";
+                }
+
+                assert_equals(event.url, url);
                 t.done();
             }
 
-            window.addEventListener('storage', onStorageEvent, false);
+            window.addEventListener('storage', t.step_func(onStorageEvent), false);
 
             var el = document.createElement("iframe");
             el.setAttribute('id', 'ifrm');
             el.setAttribute('src', 'resources/local_set_item_iframe.html');
             document.body.appendChild(el);
-        }, "Local event is fired due to an invocation of the setItem() method.");
+        }, "url property test of local event - Local event is fired due to an invocation of the setItem() method.");
     </script>
  </body>
 </html>
--- a/testing/web-platform/tests/webstorage/event_session_key.html
+++ b/testing/web-platform/tests/webstorage/event_session_key.html
@@ -1,43 +1,38 @@
 <!DOCTYPE HTML>
 <html>
  <head>
   <title>WebStorage Test: sessionStorage event - key</title>
   <script src="/resources/testharness.js"></script>
   <script src="/resources/testharnessreport.js"></script>
-  <script>
-      function fail(msg) {
-          t.step(function() {
-              assert_unreached(msg);
-          });
-          t.done();
-      }
-  </script>
  </head>
  <body>
     <h1>event_session_key</h1>
     <div id="log"></div>
     <script>
-        var t = async_test("key property test of session event");