aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--appveyor.yml4
-rw-r--r--components/canvas/webgl_paint_thread.rs29
-rw-r--r--components/compositing/Cargo.toml2
-rw-r--r--components/compositing/compositor.rs4
-rw-r--r--components/compositing/constellation.rs193
-rw-r--r--components/compositing/pipeline.rs9
-rw-r--r--components/compositing/sandboxing.rs4
-rw-r--r--components/gfx/Cargo.toml2
-rw-r--r--components/gfx/font_context.rs2
-rw-r--r--components/gfx/platform/macos/font.rs2
-rw-r--r--components/gfx/platform/macos/font_template.rs41
-rw-r--r--components/layout/Cargo.toml2
-rw-r--r--components/layout/flex.rs137
-rw-r--r--components/layout/flow_list.rs6
-rw-r--r--components/layout/fragment.rs31
-rw-r--r--components/layout/webrender_helpers.rs25
-rw-r--r--components/layout/wrapper.rs4
-rw-r--r--components/net/Cargo.toml1
-rw-r--r--components/net/fetch/methods.rs162
-rw-r--r--components/net/lib.rs3
-rw-r--r--components/net_traits/Cargo.toml2
-rw-r--r--components/net_traits/response.rs2
-rw-r--r--components/script/Cargo.toml4
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py16
-rw-r--r--components/script/dom/bindings/js.rs2
-rw-r--r--components/script/dom/bindings/trace.rs6
-rw-r--r--components/script/dom/canvasrenderingcontext2d.rs18
-rw-r--r--components/script/dom/document.rs96
-rw-r--r--components/script/dom/element.rs10
-rw-r--r--components/script/dom/htmlbaseelement.rs30
-rw-r--r--components/script/dom/htmlformelement.rs2
-rw-r--r--components/script/dom/htmlhrelement.rs7
-rw-r--r--components/script/dom/htmliframeelement.rs10
-rw-r--r--components/script/dom/htmlimageelement.rs73
-rw-r--r--components/script/dom/htmlinputelement.rs170
-rw-r--r--components/script/dom/htmltableelement.rs147
-rw-r--r--components/script/dom/htmltablerowelement.rs48
-rw-r--r--components/script/dom/performancetiming.rs10
-rw-r--r--components/script/dom/webglprogram.rs11
-rw-r--r--components/script/dom/webglrenderingcontext.rs56
-rw-r--r--components/script/dom/webglshader.rs1
-rw-r--r--components/script/dom/webidls/CSSStyleDeclaration.webidl1
-rw-r--r--components/script/dom/webidls/HTMLBaseElement.webidl4
-rw-r--r--components/script/dom/webidls/HTMLHRElement.webidl2
-rw-r--r--components/script/dom/webidls/HTMLImageElement.webidl10
-rw-r--r--components/script/dom/webidls/HTMLInputElement.webidl20
-rw-r--r--components/script/dom/webidls/HTMLTableElement.webidl16
-rw-r--r--components/script/dom/webidls/HTMLTableRowElement.webidl4
-rw-r--r--components/script/dom/webidls/PerformanceTiming.webidl4
-rw-r--r--components/script/dom/webidls/WebGLRenderingContext.webidl2
-rw-r--r--components/script/dom/websocket.rs8
-rw-r--r--components/script/dom/window.rs3
-rw-r--r--components/script/dom/xmlhttprequest.rs6
-rw-r--r--components/script/lib.rs1
-rw-r--r--components/script/origin.rs73
-rw-r--r--components/script/script_runtime.rs177
-rw-r--r--components/script/script_thread.rs3
-rw-r--r--components/script_traits/script_msg.rs6
-rw-r--r--components/servo/Cargo.lock232
-rw-r--r--components/servo/Cargo.toml2
-rw-r--r--components/servo/lib.rs6
-rw-r--r--components/style/Cargo.toml5
-rw-r--r--components/style/animation.rs2
-rw-r--r--components/style/build.rs4
-rw-r--r--components/style/properties.mako.rs221
-rw-r--r--components/style/values.rs2
-rw-r--r--components/util/Cargo.toml2
-rw-r--r--components/util/prefs.rs26
-rw-r--r--components/util/resource_files.rs49
-rw-r--r--components/webdriver_server/Cargo.toml2
-rw-r--r--ports/cef/Cargo.lock220
-rw-r--r--ports/geckolib/Cargo.lock40
-rw-r--r--ports/geckolib/Cargo.toml4
-rw-r--r--ports/geckolib/properties.mako.rs2
-rw-r--r--ports/gonk/Cargo.lock216
-rw-r--r--python/tidy.py9
-rw-r--r--python/tidy_self_test/speclink.rs9
-rw-r--r--python/tidy_self_test/tidy_self_test.py5
-rw-r--r--resources/prefs.json35
-rw-r--r--tests/html/nested-fixed-position.html7
-rw-r--r--tests/html/test_webgl_triangle.html30
-rw-r--r--tests/unit/net/fetch.rs78
-rw-r--r--tests/unit/script/Cargo.toml6
-rw-r--r--tests/unit/script/lib.rs5
-rw-r--r--tests/unit/script/origin.rs105
-rw-r--r--tests/unit/style/Cargo.toml2
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-inherit.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-integer.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-invalid.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-negative.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order.htm.ini3
-rw-r--r--tests/wpt/metadata-css/css-flexbox-1_dev/html/order_value.htm.ini5
-rw-r--r--tests/wpt/metadata-css/css21_dev/html4/max-width-110.htm.ini3
-rw-r--r--tests/wpt/metadata/MANIFEST.json6278
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/data-uri.htm.ini1
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/open-url-base-inserted.htm.ini5
-rw-r--r--tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-value.htm.ini5
-rw-r--r--tests/wpt/metadata/dom/collections/HTMLCollection-as-proto-length-get-throws.html.ini5
-rw-r--r--tests/wpt/metadata/dom/interfaces.html.ini6
-rw-r--r--tests/wpt/metadata/dom/nodes/Document-getElementsByTagName.html.ini6
-rw-r--r--tests/wpt/metadata/dom/nodes/Element-classlist.html.ini8
-rw-r--r--tests/wpt/metadata/dom/nodes/Element-getElementsByTagName.html.ini6
-rw-r--r--tests/wpt/metadata/dom/nodes/case.html.ini17
-rw-r--r--tests/wpt/metadata/dom/nodes/getElementsByClassName-20.htm.ini5
-rw-r--r--tests/wpt/metadata/dom/nodes/getElementsByClassName-22.htm.ini5
-rw-r--r--tests/wpt/metadata/dom/nodes/getElementsByClassName-25.htm.ini5
-rw-r--r--tests/wpt/metadata/dom/nodes/remove-unscopable.html.ini5
-rw-r--r--tests/wpt/metadata/domparsing/DOMParser-parseFromString-html.html.ini1
-rw-r--r--tests/wpt/metadata/encoding/api-basics.html.ini9
-rw-r--r--tests/wpt/metadata/encoding/textdecoder-streaming.html.ini27
-rw-r--r--tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini119
-rw-r--r--tests/wpt/metadata/hr-time/test_cross_frame_start.html.ini8
-rw-r--r--tests/wpt/metadata/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain.html.ini5
-rw-r--r--tests/wpt/metadata/html/dom/interfaces.html.ini144
-rw-r--r--tests/wpt/metadata/html/dom/reflection-embedded.html.ini207
-rw-r--r--tests/wpt/metadata/html/dom/reflection-forms.html.ini1179
-rw-r--r--tests/wpt/metadata/html/dom/reflection-grouping.html.ini129
-rw-r--r--tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_empty.html.ini8
-rw-r--r--tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html.ini5
-rw-r--r--tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_unspecified.html.ini8
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini561
-rw-r--r--tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini162
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini45
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/email.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini6
-rw-r--r--tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini18
-rw-r--r--tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/rowIndex.html.ini38
-rw-r--r--tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html.ini59
-rw-r--r--tests/wpt/metadata/mozilla-sync2
-rw-r--r--tests/wpt/metadata/url/a-element-xhtml.xhtml.ini6
-rw-r--r--tests/wpt/metadata/url/a-element.html.ini6
-rw-r--r--tests/wpt/metadata/url/url-constructor.html.ini12
-rw-r--r--tests/wpt/metadata/workers/semantics/xhr/001.html.ini3
-rw-r--r--tests/wpt/metadata/workers/semantics/xhr/002.html.ini6
-rw-r--r--tests/wpt/mozilla/meta/MANIFEST.json132
-rw-r--r--tests/wpt/mozilla/meta/mozilla/preferences.html.ini9
-rw-r--r--tests/wpt/mozilla/tests/css/250x250_green.pngbin0 -> 628 bytes
-rw-r--r--tests/wpt/mozilla/tests/css/flex-item-assign-inline-size.html67
-rw-r--r--tests/wpt/mozilla/tests/css/inline_font_size_zero_a.html9
-rw-r--r--tests/wpt/mozilla/tests/css/inline_font_size_zero_ref.html9
-rw-r--r--tests/wpt/mozilla/tests/css/max_inline_block_size.html21
-rw-r--r--tests/wpt/mozilla/tests/css/max_inline_block_size_canvas.html24
-rw-r--r--tests/wpt/mozilla/tests/css/max_inline_block_size_image.html18
-rw-r--r--tests/wpt/mozilla/tests/css/max_inline_block_size_ref.html20
-rw-r--r--tests/wpt/mozilla/tests/mozilla/webgl/invalid_vertex_attributes.html60
-rw-r--r--tests/wpt/web-platform-tests/XMLHttpRequest/setrequestheader-bogus-value.htm18
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001-ref.html6
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001a.html9
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001b.html9
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001c.html9
-rw-r--r--tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001d.html9
-rw-r--r--tests/wpt/web-platform-tests/dom/collections/HTMLCollection-as-proto-length-get-throws.html13
-rw-r--r--tests/wpt/web-platform-tests/dom/interfaces.html3
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/Document-Element-getElementsByTagName.js8
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml8
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/Element-classlist.html8
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentElement.html91
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentText.html76
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/case.js11
-rw-r--r--tests/wpt/web-platform-tests/dom/nodes/remove-unscopable.html18
-rw-r--r--tests/wpt/web-platform-tests/encoding/api-basics.html28
-rw-r--r--tests/wpt/web-platform-tests/encoding/api-invalid-label.html4
-rw-r--r--tests/wpt/web-platform-tests/encoding/api-replacement-encodings.html2
-rw-r--r--tests/wpt/web-platform-tests/encoding/idlharness.html2
-rw-r--r--tests/wpt/web-platform-tests/encoding/textdecoder-streaming.html15
-rw-r--r--tests/wpt/web-platform-tests/encoding/textencoder-constructor-non-utf.html18
-rw-r--r--tests/wpt/web-platform-tests/fetch/api/policies/referrer-origin.js4
-rw-r--r--tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html31
-rw-r--r--tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html24
-rw-r--r--tests/wpt/web-platform-tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js7
-rw-r--r--tests/wpt/web-platform-tests/html/resources/common.js4
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tFoot.html48
-rw-r--r--tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tHead.html66
-rw-r--r--tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subframe.sub.html12
-rw-r--r--tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subsubframe.sub.html13
-rw-r--r--tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global.sub.html20
-rw-r--r--tests/wpt/web-platform-tests/lint.whitelist3
-rw-r--r--tests/wpt/web-platform-tests/selection/collapse.html1
-rw-r--r--tests/wpt/web-platform-tests/selection/extend.html1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html11
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html37
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js8
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js132
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html (renamed from tests/wpt/metadata/html/browsers/history/the-location-interface/document_location.html.ini)0
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js23
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js25
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py14
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html127
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html45
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/activate-event-after-install-state-change.https.html32
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/activation-after-registration.https.html29
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/active.https.html55
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/appcache-ordering-main.https.html91
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/claim-not-using-registration.https.html123
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/claim-using-registration.https.html100
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/clients-get-cross-origin.https.html42
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/clients-get.https.html70
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-client-types.https.html78
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html93
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall.https.html45
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-load.https.html45
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-reload.https.html54
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html30
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-waituntil.https.html125
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html38
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html38
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-cors-xhr.https.html38
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-csp.https.html32
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html65
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html34
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-network-error.https.html42
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html997
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html35
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html466
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-frame-resource.https.html221
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https.html52
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html27
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html27
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-base-url.https.html56
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-images.https.html99
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-fallback.https.html113
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https.html53
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-redirect.https.html176
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html142
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https.html33
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-response-xhr.https.html37
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https.html63
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/getregistration.https.html87
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/getregistrations.https.html159
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/indexeddb.https.html35
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/install-event-type.https.html30
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/installing.https.html37
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/interfaces.https.html56
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/invalid-blobtype.https.html30
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/invalid-header.https.html30
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/multiple-register.https.html116
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/multiple-update.https.html92
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html449
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/onactivate-script-error.https.html75
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/oninstall-script-error.https.html67
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/performance-timeline.https.html11
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-msgport-to-client.https.html51
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html49
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/postmessage.https.html60
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/ready.https.html172
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/referer.https.html30
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/register-closed-window.https.html35
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/register-default-scope.https.html66
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/register-same-scope-different-script-url.https.html240
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https.html30
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/registration-end-to-end.https.html96
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/registration-events.https.html37
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/registration-iframe.https.html108
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/registration-service-worker-attributes.https.html70
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/registration.https.html368
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/rejections.https.html21
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/request-end-to-end.https.html61
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resource-timing.https.html58
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/404.py5
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.install.html26
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.html13
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.js1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.manifest7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/blank.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/claim-worker.js14
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-frame.html12
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-other-origin.html64
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js53
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html8
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js4
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-worker.js24
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-interceptor.js21
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-script.py9
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.html2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.txt1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/empty-worker.js1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/empty.js (renamed from tests/wpt/mozilla/meta/mozilla/windowproxy.html.ini)0
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/end-to-end-worker.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/events-worker.js12
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js20
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-waituntil.js75
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fail-on-fetch-worker.js5
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control-login.html16
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py69
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html277
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html210
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html72
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html22
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js19
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html59
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-worker.js46
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-redirect-iframe.html20
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js15
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js131
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-header-visibility-iframe.html66
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html71
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html80
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe.html71
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-style.css1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js27
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-iframe.html15
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-worker.js13
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js18
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html35
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html51
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-worker.js23
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html179
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js22
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html35
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-worker.js12
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js118
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js17
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/frame-for-getregistrations.html19
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/get-host-info.sub.js26
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/indexeddb-worker.js26
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/install-event-type-worker.js8
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js108
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces.js15
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html29
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-worker.js10
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py11
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding.py2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-iframe.https.html26
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-worker.js12
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/load_worker.js29
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/malformed-worker.py10
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/mime-type-worker.py4
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html66
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py15
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py15
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py15
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-worker.js75
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js13
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js3
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-worker.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js12
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js3
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js2
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-worker.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/other.html3
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/override_assert_object_equals.js58
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/performance-timeline-worker.js58
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js20
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-to-client-worker.js10
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-worker.js19
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect.py25
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/referer-iframe.html39
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/register-closed-window-iframe.html16
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/registration-worker.js1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/reject-install-worker.js3
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-end-to-end-worker.js32
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-headers.py6
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.html4
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js5
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/service-worker-csp-worker.py153
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-controlled.js8
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-import.js1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/silence.ogabin0 -> 12983 bytes
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js5
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.html3
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.txt1
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-installed-worker.js24
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-worker.js25
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/square.pngbin0 -> 18299 bytes
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/success.py8
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js227
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/testharness-helpers.js163
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/unregister-controller-page.html16
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-nocookie-worker.py15
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-worker.py46
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/update/update-after-oneday.https.html8
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/wait-forever-in-install-worker.js3
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/websocket.js7
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-interception-iframe.https.html39
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-load-interceptor.js13
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-testharness.js49
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/resources/xhr.js6
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-connect.https.html10
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-default.https.html10
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-script.https.html10
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/serviceworkerobject-scripturl.https.html26
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/shared-worker-controlled.https.html77
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-installed.https.html67
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html60
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-client.https.html13
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html42
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting.https.html54
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/state.https.html69
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/synced-state.https.html64
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/uncontrolled-page.https.html39
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/unregister-controller.https.html108
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html159
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register.https.html129
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/unregister.https.html40
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https.html34
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/update-after-oneday.https.html50
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/update.https.html124
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/waiting.https.html44
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/websocket.https.html46
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/worker-interception.https.html155
-rw-r--r--tests/wpt/web-platform-tests/service-workers/service-worker/xhr.https.html35
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/resources/shadow-dom-utils.js154
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html53
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005.html43
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006.html4
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001.html61
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/non-element-nodes-001.html104
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-001.html6
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html7
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-003.html55
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html23
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-002.html46
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html43
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007.html29
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-009.html19
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-010.html51
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-011.html27
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-012.html13
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013.html13
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-014.html48
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001.html12
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004.html27
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006.html8
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007.html10
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010.html25
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-001.html81
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-002.html97
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-003.html129
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-005.html93
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-006.html93
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-001.html65
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-002.html50
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-004.html106
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-001.html119
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-002.html13
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-003.html27
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-001.html50
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-002.html59
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-003.html27
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-004.html149
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-001.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-002.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-003.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-004.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-005.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-006.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-007.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-008.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-009.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-001.html227
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-002.html13
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-003.html13
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-001.html7
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-002.html5
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-003.html5
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/events/test-001.html38
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-001.html75
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-002.html21
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-003.html25
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-004.html11
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-001.html10
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-002.html20
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html22
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-001.html16
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-002.html21
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/resources/bobs_page.html58
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/composition/test-001.html163
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-001.html76
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-002.html66
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/custom-pseudo-elements/test-001.html63
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001-ref.html35
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html47
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002-ref.html40
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html53
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-003.html74
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-003.html130
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-004.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-005.html66
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest-ref.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/test-001.html98
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/rendering-shadow-trees/test-001.html255
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002-ref.html30
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html40
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/test-001.html175
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-001.html59
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-002.html65
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-003.html66
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-004.html65
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-005.html65
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-001.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-002.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html20
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html17
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002.html38
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-001.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-002.html9
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-001.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-002.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/shadow-root-001.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-005.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-007.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-009.html58
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html44
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-001.html45
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-002.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-003.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/css-variables/test-001.html65
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/deep-combinator/deep-combinator-001.html156
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html2
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/shadow-pseudoelement/shadow-pseudoelement-001.html150
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-001.html142
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-003.html5
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-005.html63
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-007.html133
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-008.html75
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-009.html73
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-010.html37
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/testcommon.js271
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-001.html27
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-002.html29
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/editing/inheritance-of-content-editable-001.html3
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-001.html87
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-002.html381
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-003.html399
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-004.html741
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-001.html53
-rw-r--r--tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html54
-rw-r--r--tests/wpt/web-platform-tests/tools/.gitmodules3
-rw-r--r--tests/wpt/web-platform-tests/tools/localpaths.py2
-rw-r--r--tests/wpt/web-platform-tests/tools/py/.hgignore29
-rw-r--r--tests/wpt/web-platform-tests/tools/py/.hgtags67
-rw-r--r--tests/wpt/web-platform-tests/tools/py/AUTHORS24
-rw-r--r--tests/wpt/web-platform-tests/tools/py/CHANGELOG1089
-rw-r--r--tests/wpt/web-platform-tests/tools/py/LICENSE19
-rw-r--r--tests/wpt/web-platform-tests/tools/py/MANIFEST.in9
-rw-r--r--tests/wpt/web-platform-tests/tools/py/README.txt21
-rw-r--r--tests/wpt/web-platform-tests/tools/py/bench/localpath.py75
-rw-r--r--tests/wpt/web-platform-tests/tools/py/conftest.py71
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/Makefile133
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/_templates/layout.html18
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.0.txt7
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.2.txt27
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.0.txt63
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.1.txt48
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.2.txt5
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.0.txt115
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.1.txt48
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.0.txt116
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.1.txt66
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.0.txt580
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.1.txt104
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.2.txt720
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.3.txt26
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.4.txt22
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.0.txt47
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.1.txt47
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/announce/releases.txt16
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/changelog.txt3
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/code.txt150
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/conf.py263
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/download.html18
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/example/genhtml.py13
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/example/genhtmlcss.py23
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/example/genxml.py17
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/faq.txt172
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/img/pylib.pngbin0 -> 8276 bytes
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/index.txt43
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/install.txt88
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/io.txt59
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/links.inc16
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/log.txt208
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/misc.txt93
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/path.txt260
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/style.css1044
-rw-r--r--tests/wpt/web-platform-tests/tools/py/doc/xml.txt164
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/__init__.py150
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/__metainfo.py2
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_apipkg.py181
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_builtin.py248
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_code/__init__.py1
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_code/_assertionnew.py339
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_code/_assertionold.py555
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_code/_py2traceback.py79
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_code/assertion.py94
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_code/code.py787
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_code/source.py419
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_error.py88
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_iniconfig.py162
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_io/__init__.py1
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_io/capture.py371
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_io/saferepr.py71
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_io/terminalwriter.py348
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_log/__init__.py2
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_log/log.py186
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_log/warning.py76
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_path/__init__.py1
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_path/cacheutil.py114
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_path/common.py403
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_path/local.py911
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_path/svnurl.py380
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_path/svnwc.py1240
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_process/__init__.py1
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_process/cmdexec.py49
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_process/forkedfunc.py120
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_process/killproc.py23
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_std.py18
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/_xmlgen.py253
-rw-r--r--tests/wpt/web-platform-tests/tools/py/py/test.py10
-rw-r--r--tests/wpt/web-platform-tests/tools/py/setup.cfg5
-rw-r--r--tests/wpt/web-platform-tests/tools/py/setup.py38
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/code/test_assertion.py308
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/code/test_code.py159
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/code/test_excinfo.py909
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/code/test_source.py651
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/conftest.py3
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/io_/__init__.py1
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/io_/test_capture.py501
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/io_/test_saferepr.py78
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/io_/test_terminalwriter.py271
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/log/__init__.py0
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/log/test_log.py190
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/log/test_warning.py76
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/common.py470
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/conftest.py80
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/repotest.dump228
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/svntestbase.py31
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/test_cacheutil.py84
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/test_local.py860
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/test_svnauth.py454
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/test_svnurl.py95
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/path/test_svnwc.py549
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/process/__init__.py1
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/process/test_cmdexec.py39
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/process/test_forkedfunc.py177
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/process/test_killproc.py16
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/root/__init__.py1
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/root/test_builtin.py179
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/root/test_error.py37
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/root/test_py_imports.py68
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/root/test_std.py13
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/root/test_xmlgen.py145
-rw-r--r--tests/wpt/web-platform-tests/tools/py/testing/test_iniconfig.py299
-rw-r--r--tests/wpt/web-platform-tests/tools/py/tox.ini39
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/.gitignore1
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/README.md48
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/setup.py18
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/__init__.py31
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/alert.py26
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/capabilities.py30
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/client.py409
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/command.py111
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/driver.py199
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py144
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/exceptions.py166
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/keys.py68
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/searchcontext.py54
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/servo.py22
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/transport.py117
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/wait.py87
-rw-r--r--tests/wpt/web-platform-tests/tools/webdriver/webdriver/webelement.py56
-rw-r--r--tests/wpt/web-platform-tests/url/OWNERS1
-rw-r--r--tests/wpt/web-platform-tests/url/historical.html8
-rw-r--r--tests/wpt/web-platform-tests/url/historical.worker.js8
-rw-r--r--tests/wpt/web-platform-tests/url/url-constructor.html102
-rw-r--r--tests/wpt/web-platform-tests/url/urltestdata.json33
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-effect-timing/delay.html62
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-effect-timing/direction.html28
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getAnimations.html13
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getComputedStyle.html69
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-effect-timing/iterations.html57
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-after.html419
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-before.html418
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-next-sibling.html503
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-parent.html53
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-previous-sibling.html511
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-remove.html239
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-replace.html444
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation-node/idlharness.html54
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/cancel.html61
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/finish.html210
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/play.html35
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/playState.html54
-rw-r--r--tests/wpt/web-platform-tests/web-animations/animation/playbackRate.html89
-rw-r--r--tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html272
-rw-r--r--tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html282
-rw-r--r--tests/wpt/web-platform-tests/web-animations/keyframe-effect/getComputedTiming.html14
-rw-r--r--tests/wpt/web-platform-tests/web-animations/testcommon.js29
-rw-r--r--tests/wpt/web-platform-tests/webgl/OWNERS1
-rw-r--r--tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-child-with-worker.html78
-rw-r--r--tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-upon-reload-child.html77
-rw-r--r--tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/extensions/oes-vertex-array-object.html4
-rw-r--r--tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/more/functions/texImage2DBadArgs.html2
-rw-r--r--tests/wpt/web-platform-tests/webgl/conformance-1.0.3/resources/js-test-pre.js27
-rwxr-xr-xtests/wpt/web-platform-tests/webgl/tools/import-conformance-tests.py5
-rw-r--r--tests/wpt/web-platform-tests/webgl/tools/js-test-pre.patch45
-rw-r--r--tests/wpt/web-platform-tests/webstorage/event_setattribute.js3
-rw-r--r--tests/wpt/web-platform-tests/webstorage/resources/event_setattribute_handler.html2
707 files changed, 41613 insertions, 18561 deletions
diff --git a/.travis.yml b/.travis.yml
index 4872e5de094..87bad747c60 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -14,6 +14,7 @@ matrix:
- ./mach build -d --verbose
- ./mach test-unit
- ./mach test-compiletest
+ - bash etc/ci/check_no_unwrap.sh
- bash etc/ci/lockfile_changed.sh
- bash etc/ci/manifest_changed.sh
cache:
diff --git a/appveyor.yml b/appveyor.yml
index 6793fffb93c..ea0a90626b5 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -15,8 +15,8 @@ platform:
- x64
cache:
- - .servo
- - .cargo
+ - .servo -> rust-nightly-date, cargo-nightly-build
+ - .cargo -> rust-nightly-date, cargo-nightly-build
install:
# Check if commit in auto branch exists in master, if exists build will be canceled.
diff --git a/components/canvas/webgl_paint_thread.rs b/components/canvas/webgl_paint_thread.rs
index c88f2a378b7..30e47c06082 100644
--- a/components/canvas/webgl_paint_thread.rs
+++ b/components/canvas/webgl_paint_thread.rs
@@ -6,7 +6,7 @@ use canvas_traits::{CanvasCommonMsg, CanvasMsg, CanvasPixelData, CanvasData, Fro
use euclid::size::Size2D;
use gleam::gl;
use ipc_channel::ipc::{self, IpcSender, IpcSharedMemory};
-use offscreen_gl_context::{ColorAttachmentType, GLContext, GLContextAttributes, NativeGLContext};
+use offscreen_gl_context::{ColorAttachmentType, GLContext, GLLimits, GLContextAttributes, NativeGLContext};
use std::borrow::ToOwned;
use std::sync::mpsc::channel;
use util::thread::spawn_named;
@@ -26,20 +26,24 @@ pub struct WebGLPaintThread {
impl WebGLPaintThread {
fn new(size: Size2D<i32>,
attrs: GLContextAttributes,
- webrender_api_sender: Option<webrender_traits::RenderApiSender>) -> Result<WebGLPaintThread, String> {
- let data = if let Some(sender) = webrender_api_sender {
+ webrender_api_sender: Option<webrender_traits::RenderApiSender>)
+ -> Result<(WebGLPaintThread, GLLimits), String> {
+ let (data, limits) = if let Some(sender) = webrender_api_sender {
let webrender_api = sender.create_api();
- let (id, _) = try!(webrender_api.request_webgl_context(&size, attrs));
- WebGLPaintTaskData::WebRender(webrender_api, id)
+ let (id, limits) = try!(webrender_api.request_webgl_context(&size, attrs));
+ (WebGLPaintTaskData::WebRender(webrender_api, id), limits)
} else {
let context = try!(GLContext::<NativeGLContext>::new(size, attrs, ColorAttachmentType::Texture, None));
- WebGLPaintTaskData::Servo(context)
+ let limits = context.borrow_limits().clone();
+ (WebGLPaintTaskData::Servo(context), limits)
};
- Ok(WebGLPaintThread {
+ let painter_object = WebGLPaintThread {
size: size,
data: data,
- })
+ };
+
+ Ok((painter_object, limits))
}
pub fn handle_webgl_message(&self, message: webrender_traits::WebGLCommand) {
@@ -59,13 +63,13 @@ impl WebGLPaintThread {
pub fn start(size: Size2D<i32>,
attrs: GLContextAttributes,
webrender_api_sender: Option<webrender_traits::RenderApiSender>)
- -> Result<IpcSender<CanvasMsg>, String> {
+ -> Result<(IpcSender<CanvasMsg>, GLLimits), String> {
let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap();
let (result_chan, result_port) = channel();
spawn_named("WebGLThread".to_owned(), move || {
let mut painter = match WebGLPaintThread::new(size, attrs, webrender_api_sender) {
- Ok(thread) => {
- result_chan.send(Ok(())).unwrap();
+ Ok((thread, limits)) => {
+ result_chan.send(Ok(limits)).unwrap();
thread
},
Err(e) => {
@@ -95,8 +99,7 @@ impl WebGLPaintThread {
}
});
- try!(result_port.recv().unwrap());
- Ok(sender)
+ result_port.recv().unwrap().map(|limits| (sender, limits))
}
fn send_data(&mut self, chan: IpcSender<CanvasData>) {
diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml
index de33358873f..cec58afb9dd 100644
--- a/components/compositing/Cargo.toml
+++ b/components/compositing/Cargo.toml
@@ -89,7 +89,7 @@ git = "https://github.com/servo/webrender"
app_units = {version = "0.2.3", features = ["plugins"]}
euclid = {version = "0.6.4", features = ["plugins"]}
gleam = "0.2.8"
-image = "0.7"
+image = "0.9"
log = "0.3.5"
num = "0.1.24"
offscreen_gl_context = "0.1.2"
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index 5950e13dc8f..e0fb0e144cb 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -755,7 +755,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
if !self.pipeline_details.contains_key(&pipeline_id) {
self.pipeline_details.insert(pipeline_id, PipelineDetails::new());
}
- self.pipeline_details.get_mut(&pipeline_id).unwrap()
+ self.pipeline_details.get_mut(&pipeline_id).expect("Insert then get failed!")
}
pub fn pipeline(&self, pipeline_id: PipelineId) -> Option<&CompositionPipeline> {
@@ -2191,7 +2191,7 @@ impl<Window: WindowMethods> IOCompositor<Window> {
let src_slice = &orig_pixels[src_start .. src_start + stride];
(&mut pixels[dst_start .. dst_start + stride]).clone_from_slice(&src_slice[..stride]);
}
- RgbImage::from_raw(width as u32, height as u32, pixels).unwrap()
+ RgbImage::from_raw(width as u32, height as u32, pixels).expect("Flipping image failed!")
}
fn composite_if_necessary(&mut self, reason: CompositingReason) {
diff --git a/components/compositing/constellation.rs b/components/compositing/constellation.rs
index b52a1a22395..74b09dcb477 100644
--- a/components/compositing/constellation.rs
+++ b/components/compositing/constellation.rs
@@ -39,7 +39,7 @@ use msg::webdriver_msg;
use net_traits::image_cache_thread::ImageCacheThread;
use net_traits::storage_thread::{StorageThread, StorageThreadMsg};
use net_traits::{self, ResourceThread};
-use offscreen_gl_context::GLContextAttributes;
+use offscreen_gl_context::{GLContextAttributes, GLLimits};
use pipeline::{CompositionPipeline, InitialPipelineState, Pipeline, UnprivilegedPipelineContent};
use profile_traits::mem;
use profile_traits::time;
@@ -265,14 +265,14 @@ impl<'a> Iterator for FrameTreeIterator<'a> {
let frame = match self.frames.get(&frame_id) {
Some(frame) => frame,
None => {
- debug!("Frame {:?} iterated after closure.", frame_id);
+ warn!("Frame {:?} iterated after closure.", frame_id);
continue;
},
};
let pipeline = match self.pipelines.get(&frame.current) {
Some(pipeline) => pipeline,
None => {
- debug!("Pipeline {:?} iterated after closure.", frame.current);
+ warn!("Pipeline {:?} iterated after closure.", frame.current);
continue;
},
};
@@ -461,25 +461,38 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// avoiding this panic would require a mechanism for dealing
// with low-resource scenarios.
let (server, token) =
- IpcOneShotServer::<IpcSender<UnprivilegedPipelineContent>>::new().unwrap();
+ IpcOneShotServer::<IpcSender<UnprivilegedPipelineContent>>::new()
+ .expect("Failed to create IPC one-shot server.");
// If there is a sandbox, use the `gaol` API to create the child process.
let child_process = if opts::get().sandbox {
- let mut command = sandbox::Command::me().unwrap();
+ let mut command = sandbox::Command::me().expect("Failed to get current sandbox.");
command.arg("--content-process").arg(token);
+
+ if let Ok(value) = env::var("RUST_BACKTRACE") {
+ command.env("RUST_BACKTRACE", value);
+ }
+
let profile = sandboxing::content_process_sandbox_profile();
- ChildProcess::Sandboxed(Sandbox::new(profile).start(&mut command).expect(
- "Failed to start sandboxed child process!"))
+ ChildProcess::Sandboxed(Sandbox::new(profile).start(&mut command)
+ .expect("Failed to start sandboxed child process!"))
} else {
- let path_to_self = env::current_exe().unwrap();
+ let path_to_self = env::current_exe()
+ .expect("Failed to get current executor.");
let mut child_process = process::Command::new(path_to_self);
child_process.arg("--content-process");
child_process.arg(token);
- ChildProcess::Unsandboxed(child_process.spawn().unwrap())
+
+ if let Ok(value) = env::var("RUST_BACKTRACE") {
+ child_process.env("RUST_BACKTRACE", value);
+ }
+
+ ChildProcess::Unsandboxed(child_process.spawn()
+ .expect("Failed to start unsandboxed child process!"))
};
self.child_processes.push(child_process);
- let (_receiver, sender) = server.accept().unwrap();
+ let (_receiver, sender) = server.accept().expect("Server failed to accept.");
sender.send(unprivileged_pipeline_content)
.unwrap_or_else(|_| self.handle_send_error(pipeline_id));
}
@@ -688,7 +701,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
debug!("constellation got set final url message");
pipeline.url = final_url;
} else {
- debug!("constellation got set final url message for dead pipeline");
+ warn!("constellation got set final url message for dead pipeline");
}
}
Request::Script(FromScriptMsg::MozBrowserEvent(pipeline_id,
@@ -722,16 +735,16 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let result = self.clipboard_ctx.as_ref().map_or(
"".to_owned(),
|ctx| ctx.get_contents().unwrap_or_else(|e| {
- debug!("Error getting clipboard contents ({}), defaulting to empty string", e);
+ warn!("Error getting clipboard contents ({}), defaulting to empty string", e);
"".to_owned()
})
);
- sender.send(result).unwrap_or_else(|e| debug!("Failed to send clipboard ({})", e))
+ sender.send(result).unwrap_or_else(|e| warn!("Failed to send clipboard ({})", e))
}
Request::Script(FromScriptMsg::SetClipboardContents(s)) => {
if let Some(ref mut ctx) = self.clipboard_ctx {
if let Err(e) = ctx.set_contents(s) {
- debug!("Error setting clipboard contents ({})", e);
+ warn!("Error setting clipboard contents ({})", e);
}
}
}
@@ -739,7 +752,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
debug!("constellation got remove iframe message");
self.handle_remove_iframe_msg(pipeline_id);
if let Some(sender) = sender {
- sender.send(()).unwrap_or_else(|e| debug!("Error replying to remove iframe ({})", e));
+ sender.send(()).unwrap_or_else(|e| warn!("Error replying to remove iframe ({})", e));
}
}
Request::Script(FromScriptMsg::NewFavicon(url)) => {
@@ -805,20 +818,20 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
}
self.image_cache_thread.exit();
self.resource_thread.send(net_traits::ControlMsg::Exit)
- .unwrap_or_else(|e| debug!("Exit resource thread failed ({})", e));
+ .unwrap_or_else(|e| warn!("Exit resource thread failed ({})", e));
self.devtools_chan.as_ref().map(|chan| {
chan.send(DevtoolsControlMsg::FromChrome(ChromeToDevtoolsControlMsg::ServerExitMsg))
- .unwrap_or_else(|e| debug!("Exit devtools failed ({})", e));
+ .unwrap_or_else(|e| warn!("Exit devtools failed ({})", e));
});
self.storage_thread.send(StorageThreadMsg::Exit)
- .unwrap_or_else(|e| debug!("Exit storage thread failed ({})", e));
+ .unwrap_or_else(|e| warn!("Exit storage thread failed ({})", e));
self.font_cache_thread.exit();
self.compositor_proxy.send(ToCompositorMsg::ShutdownComplete);
}
fn handle_send_error(&mut self, pipeline_id: PipelineId) {
let parent_info = match self.pipelines.get(&pipeline_id) {
- None => return debug!("Pipeline {:?} send error after closure.", pipeline_id),
+ None => return warn!("Pipeline {:?} send error after closure.", pipeline_id),
Some(pipeline) => pipeline.parent_info,
};
// Treat send error the same as receiving a failure message
@@ -832,7 +845,8 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// It's quite difficult to make Servo exit cleanly if some threads have failed.
// Hard fail exists for test runners so we crash and that's good enough.
let mut stderr = io::stderr();
- stderr.write_all("Pipeline failed in hard-fail mode. Crashing!\n".as_bytes()).unwrap();
+ stderr.write_all("Pipeline failed in hard-fail mode. Crashing!\n".as_bytes())
+ .expect("Failed to write to stderr!");
process::exit(1);
}
@@ -843,11 +857,11 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
while let Some(pending_pipeline_id) = self.pending_frames.iter().find(|pending| {
pending.old_pipeline_id == Some(pipeline_id)
}).map(|frame| frame.new_pipeline_id) {
- debug!("removing pending frame change for failed pipeline");
+ warn!("removing pending frame change for failed pipeline");
self.close_pipeline(pending_pipeline_id, ExitPipelineMode::Force);
}
- debug!("creating replacement pipeline for about:failure");
+ warn!("creating replacement pipeline for about:failure");
let new_pipeline_id = PipelineId::new();
self.new_pipeline(new_pipeline_id,
@@ -897,15 +911,15 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
fn handle_subframe_loaded(&mut self, pipeline_id: PipelineId) {
let parent_info = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.parent_info,
- None => return debug!("Pipeline {:?} loaded after closure.", pipeline_id),
+ None => return warn!("Pipeline {:?} loaded after closure.", pipeline_id),
};
let subframe_parent_id = match parent_info {
Some(ref parent) => parent.0,
- None => return debug!("Pipeline {:?} has no parent.", pipeline_id),
+ None => return warn!("Pipeline {:?} has no parent.", pipeline_id),
};
let script_chan = match self.pipelines.get(&subframe_parent_id) {
Some(pipeline) => pipeline.script_chan.clone(),
- None => return debug!("Pipeline {:?} subframe loaded after closure.", subframe_parent_id),
+ None => return warn!("Pipeline {:?} subframe loaded after closure.", subframe_parent_id),
};
let msg = ConstellationControlMsg::DispatchFrameLoadEvent {
target: pipeline_id,
@@ -929,7 +943,10 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let old_pipeline = old_pipeline_id
.and_then(|old_pipeline_id| self.pipelines.get(&old_pipeline_id));
- let source_pipeline = self.pipelines.get(&load_info.containing_pipeline_id);
+ let source_pipeline = match self.pipelines.get(&load_info.containing_pipeline_id) {
+ Some(source_pipeline) => source_pipeline,
+ None => return warn!("Script loaded url in closed iframe {}.", load_info.containing_pipeline_id),
+ };
// If no url is specified, reload.
let new_url = load_info.url.clone()
@@ -938,25 +955,23 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// Compare the pipeline's url to the new url. If the origin is the same,
// then reuse the script thread in creating the new pipeline
- let script_chan = source_pipeline.and_then(|source_pipeline| {
- let source_url = source_pipeline.url.clone();
-
- let same_script = (source_url.host() == new_url.host() &&
- source_url.port() == new_url.port()) &&
- load_info.sandbox == IFrameSandboxState::IFrameUnsandboxed;
-
- // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
- // Reuse the script thread if the URL is same-origin
- if same_script {
- debug!("Constellation: loading same-origin iframe, \
- parent url {:?}, iframe url {:?}", source_url, new_url);
- Some(source_pipeline.script_chan.clone())
- } else {
- debug!("Constellation: loading cross-origin iframe, \
- parent url {:?}, iframe url {:?}", source_url, new_url);
- None
- }
- });
+ let source_url = &source_pipeline.url;
+
+ let same_script = source_url.host() == new_url.host() &&
+ source_url.port() == new_url.port() &&
+ load_info.sandbox == IFrameSandboxState::IFrameUnsandboxed;
+
+ // FIXME(tkuehn): Need to follow the standardized spec for checking same-origin
+ // Reuse the script thread if the URL is same-origin
+ let script_chan = if same_script {
+ debug!("Constellation: loading same-origin iframe, \
+ parent url {:?}, iframe url {:?}", source_url, new_url);
+ Some(source_pipeline.script_chan.clone())
+ } else {
+ debug!("Constellation: loading cross-origin iframe, \
+ parent url {:?}, iframe url {:?}", source_url, new_url);
+ None
+ };
let window_size = old_pipeline.and_then(|old_pipeline| old_pipeline.size);
@@ -995,7 +1010,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
fn handle_tick_animation(&mut self, pipeline_id: PipelineId, tick_type: AnimationTickType) {
let (layout_chan, script_chan) = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => (pipeline.layout_chan.0.clone(), pipeline.script_chan.clone()),
- None => return debug!("Pipeline {:?} got tick after closure.", pipeline_id),
+ None => return warn!("Pipeline {:?} got tick after closure.", pipeline_id),
};
match tick_type {
AnimationTickType::Script => {
@@ -1036,7 +1051,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let script_chan = match self.pipelines.get(&parent_pipeline_id) {
Some(parent_pipeline) => parent_pipeline.script_chan.clone(),
None => {
- debug!("Pipeline {:?} child loaded after closure", parent_pipeline_id);
+ warn!("Pipeline {:?} child loaded after closure", parent_pipeline_id);
return None;
},
};
@@ -1072,7 +1087,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// Send message to ScriptThread that will suspend all timers
match self.pipelines.get(&source_id) {
Some(source) => source.freeze(),
- None => debug!("Pipeline {:?} loaded after closure", source_id),
+ None => warn!("Pipeline {:?} loaded after closure", source_id),
};
Some(new_pipeline_id)
}
@@ -1132,7 +1147,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// If the frame_id lookup fails, then we are in the middle of tearing down
// the root frame, so it is reasonable to silently ignore the navigation.
let frame_id = match frame_id {
- None => return debug!("Navigation after root's closure."),
+ None => return warn!("Navigation after root's closure."),
Some(frame_id) => frame_id,
};
@@ -1148,7 +1163,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
NavigationDirection::Forward => {
match frame.next.pop() {
None => {
- debug!("no next page to navigate to");
+ warn!("no next page to navigate to");
return;
},
Some(next) => {
@@ -1160,7 +1175,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
NavigationDirection::Back => {
match frame.prev.pop() {
None => {
- debug!("no previous page to navigate to");
+ warn!("no previous page to navigate to");
return;
},
Some(prev) => {
@@ -1175,7 +1190,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
(prev, next)
},
None => {
- debug!("no frame to navigate from");
+ warn!("no frame to navigate from");
return;
},
};
@@ -1203,13 +1218,13 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// This makes things like contentDocument work correctly.
if let Some((parent_pipeline_id, subpage_id)) = pipeline_info {
let script_chan = match self.pipelines.get(&parent_pipeline_id) {
- None => return debug!("Pipeline {:?} child navigated after closure.", parent_pipeline_id),
+ None => return warn!("Pipeline {:?} child navigated after closure.", parent_pipeline_id),
Some(pipeline) => pipeline.script_chan.clone(),
};
let new_subpage_id = match self.pipelines.get(&next_pipeline_id) {
- None => return debug!("Pipeline {:?} navigated to after closure.", next_pipeline_id),
+ None => return warn!("Pipeline {:?} navigated to after closure.", next_pipeline_id),
Some(pipeline) => match pipeline.parent_info {
- None => return debug!("Pipeline {:?} has no parent info.", next_pipeline_id),
+ None => return warn!("Pipeline {:?} has no parent info.", next_pipeline_id),
Some((_, new_subpage_id)) => new_subpage_id,
},
};
@@ -1267,7 +1282,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// so it is reasonable to silently ignore the event.
match self.pipelines.get(&containing_pipeline_id) {
Some(pipeline) => pipeline.trigger_mozbrowser_event(subpage_id, event),
- None => debug!("Pipeline {:?} handling mozbrowser event after closure.", containing_pipeline_id),
+ None => warn!("Pipeline {:?} handling mozbrowser event after closure.", containing_pipeline_id),
}
}
@@ -1280,7 +1295,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
.find(|x| x.old_pipeline_id == current_pipeline_id)
.map(|x| x.new_pipeline_id).or(current_pipeline_id);
resp_chan.send(pipeline_id)
- .unwrap_or_else(|_| debug!("Failed get_pipeline response."));
+ .unwrap_or_else(|_| warn!("Failed get_pipeline response."));
}
fn handle_get_frame(&mut self,
@@ -1288,21 +1303,21 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
resp_chan: IpcSender<Option<FrameId>>) {
let frame_id = self.pipeline_to_frame_map.get(&pipeline_id).map(|x| *x);
resp_chan.send(frame_id)
- .unwrap_or_else(|_| debug!("Failed get_pipeline response."));
+ .unwrap_or_else(|_| warn!("Failed get_pipeline response."));
}
fn focus_parent_pipeline(&mut self, pipeline_id: PipelineId) {
let parent_info = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.parent_info,
- None => return debug!("Pipeline {:?} focus parent after closure.", pipeline_id),
+ None => return warn!("Pipeline {:?} focus parent after closure.", pipeline_id),
};
let (containing_pipeline_id, subpage_id) = match parent_info {
Some(info) => info,
- None => return debug!("Pipeline {:?} focus has no parent.", pipeline_id),
+ None => return warn!("Pipeline {:?} focus has no parent.", pipeline_id),
};
let script_chan = match self.pipelines.get(&containing_pipeline_id) {
Some(pipeline) => pipeline.script_chan.clone(),
- None => return debug!("Pipeline {:?} focus after closure.", containing_pipeline_id),
+ None => return warn!("Pipeline {:?} focus after closure.", containing_pipeline_id),
};
// Send a message to the parent of the provided pipeline (if it exists)
@@ -1342,19 +1357,19 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let webrender_api = self.webrender_api_sender.clone();
let sender = CanvasPaintThread::start(*size, webrender_api);
response_sender.send(sender)
- .unwrap_or_else(|e| debug!("Create canvas paint thread response failed ({})", e))
+ .unwrap_or_else(|e| warn!("Create canvas paint thread response failed ({})", e))
}
fn handle_create_webgl_paint_thread_msg(
&mut self,
size: &Size2D<i32>,
attributes: GLContextAttributes,
- response_sender: IpcSender<Result<IpcSender<CanvasMsg>, String>>) {
+ response_sender: IpcSender<Result<(IpcSender<CanvasMsg>, GLLimits), String>>) {
let webrender_api = self.webrender_api_sender.clone();
- let sender = WebGLPaintThread::start(*size, attributes, webrender_api);
+ let response = WebGLPaintThread::start(*size, attributes, webrender_api);
- response_sender.send(sender)
- .unwrap_or_else(|e| debug!("Create WebGL paint thread response failed ({})", e))
+ response_sender.send(response)
+ .unwrap_or_else(|e| warn!("Create WebGL paint thread response failed ({})", e))
}
fn handle_webdriver_msg(&mut self, msg: WebDriverCommandMsg) {
@@ -1367,14 +1382,14 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
WebDriverCommandMsg::Refresh(pipeline_id, reply) => {
let load_data = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => LoadData::new(pipeline.url.clone()),
- None => return debug!("Pipeline {:?} Refresh after closure.", pipeline_id),
+ None => return warn!("Pipeline {:?} Refresh after closure.", pipeline_id),
};
self.load_url_for_webdriver(pipeline_id, load_data, reply);
}
WebDriverCommandMsg::ScriptCommand(pipeline_id, cmd) => {
let script_channel = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.script_chan.clone(),
- None => return debug!("Pipeline {:?} ScriptCommand after closure.", pipeline_id),
+ None => return warn!("Pipeline {:?} ScriptCommand after closure.", pipeline_id),
};
let control_msg = ConstellationControlMsg::WebDriverScriptCommand(pipeline_id, cmd);
script_channel.send(control_msg)
@@ -1383,7 +1398,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
WebDriverCommandMsg::SendKeys(pipeline_id, cmd) => {
let script_channel = match self.pipelines.get(&pipeline_id) {
Some(pipeline) => pipeline.script_chan.clone(),
- None => return debug!("Pipeline {:?} SendKeys after closure.", pipeline_id),
+ None => return warn!("Pipeline {:?} SendKeys after closure.", pipeline_id),
};
for (key, mods, state) in cmd {
let event = CompositorEvent::KeyEvent(key, state, mods);
@@ -1399,7 +1414,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
if Some(pipeline_id) == current_pipeline_id {
self.compositor_proxy.send(ToCompositorMsg::CreatePng(reply));
} else {
- reply.send(None).unwrap_or_else(|e| debug!("Screenshot reply failed ({})", e));
+ reply.send(None).unwrap_or_else(|e| warn!("Screenshot reply failed ({})", e));
}
},
}
@@ -1532,18 +1547,18 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// Send Resize (or ResizeInactive) messages to each
// pipeline in the frame tree.
let frame = match self.frames.get(&root_frame_id) {
- None => return debug!("Frame {:?} resized after closing.", root_frame_id),
+ None => return warn!("Frame {:?} resized after closing.", root_frame_id),
Some(frame) => frame,
};
let pipeline_id = frame.current;
let pipeline = match self.pipelines.get(&pipeline_id) {
- None => return debug!("Pipeline {:?} resized after closing.", pipeline_id),
+ None => return warn!("Pipeline {:?} resized after closing.", pipeline_id),
Some(pipeline) => pipeline,
};
let _ = pipeline.script_chan.send(ConstellationControlMsg::Resize(pipeline.id, new_size));
for pipeline_id in frame.prev.iter().chain(&frame.next) {
let pipeline = match self.pipelines.get(&pipeline_id) {
- None => { debug!("Inactive pipeline {:?} resized after closing.", pipeline_id); continue; },
+ None => { warn!("Inactive pipeline {:?} resized after closing.", pipeline_id); continue; },
Some(pipeline) => pipeline,
};
let _ = pipeline.script_chan.send(ConstellationControlMsg::ResizeInactive(pipeline.id,
@@ -1555,7 +1570,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
for pending_frame in &self.pending_frames {
let pipeline_id = pending_frame.new_pipeline_id;
let pipeline = match self.pipelines.get(&pipeline_id) {
- None => { debug!("Pending pipeline {:?} is closed", pipeline_id); continue; }
+ None => { warn!("Pending pipeline {:?} is closed", pipeline_id); continue; }
Some(pipeline) => pipeline,
};
if pipeline.parent_info.is_none() {
@@ -1606,7 +1621,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let pipeline_id = frame.current;
let pipeline = match self.pipelines.get(&pipeline_id) {
- None => { debug!("Pipeline {:?} screenshot while closing.", pipeline_id); continue; },
+ None => { warn!("Pipeline {:?} screenshot while closing.", pipeline_id); continue; },
Some(pipeline) => pipeline,
};
@@ -1618,10 +1633,10 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// before we check whether the document is ready; otherwise,
// there's a race condition where a webfont has finished loading,
// but hasn't yet notified the document.
- let (sender, receiver) = ipc::channel().unwrap();
+ let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
let msg = LayoutControlMsg::GetWebFontLoadState(sender);
pipeline.layout_chan.0.send(msg)
- .unwrap_or_else(|e| debug!("Get web font failed ({})", e));
+ .unwrap_or_else(|e| warn!("Get web font failed ({})", e));
if receiver.recv().unwrap_or(true) {
return ReadyToSave::WebFontNotLoaded;
}
@@ -1654,12 +1669,16 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
// epoch matches what the compositor has drawn. If they match
// (and script is idle) then this pipeline won't change again
// and can be considered stable.
- let (sender, receiver) = ipc::channel().unwrap();
+ let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
let LayoutControlChan(ref layout_chan) = pipeline.layout_chan;
- layout_chan.send(LayoutControlMsg::GetCurrentEpoch(sender)).unwrap();
- let layout_thread_epoch = receiver.recv().unwrap();
- if layout_thread_epoch != *compositor_epoch {
- return ReadyToSave::EpochMismatch;
+ if let Err(e) = layout_chan.send(LayoutControlMsg::GetCurrentEpoch(sender)) {
+ warn!("Failed to send GetCurrentEpoch ({}).", e);
+ }
+ match receiver.recv() {
+ Err(e) => warn!("Failed to receive current epoch ({}).", e),
+ Ok(layout_thread_epoch) => if layout_thread_epoch != *compositor_epoch {
+ return ReadyToSave::EpochMismatch;
+ },
}
}
None => {
@@ -1715,12 +1734,12 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
}
if let None = self.frames.remove(&frame_id) {
- debug!("Closing frame {:?} twice.", frame_id);
+ warn!("Closing frame {:?} twice.", frame_id);
}
if let Some((parent_pipeline_id, _)) = parent_info {
let parent_pipeline = match self.pipelines.get_mut(&parent_pipeline_id) {
- None => return debug!("Pipeline {:?} child closed after parent.", parent_pipeline_id),
+ None => return warn!("Pipeline {:?} child closed after parent.", parent_pipeline_id),
Some(parent_pipeline) => parent_pipeline,
};
parent_pipeline.remove_child(frame_id);
@@ -1750,7 +1769,7 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
let pipeline = match self.pipelines.remove(&pipeline_id) {
Some(pipeline) => pipeline,
- None => return debug!("Closing pipeline {:?} twice.", pipeline_id),
+ None => return warn!("Closing pipeline {:?} twice.", pipeline_id),
};
// If a child pipeline, remove from subpage map
@@ -1835,12 +1854,12 @@ impl<LTF: LayoutThreadFactory, STF: ScriptThreadFactory> Constellation<LTF, STF>
if let Some(root_frame_id) = self.root_frame_id {
if let Some(frame_tree) = self.frame_to_sendable(root_frame_id) {
- let (chan, port) = ipc::channel().unwrap();
+ let (chan, port) = ipc::channel().expect("Failed to create IPC channel!");
self.compositor_proxy.send(ToCompositorMsg::SetFrameTree(frame_tree,
chan,
self.compositor_sender.clone()));
if port.recv().is_err() {
- debug!("Compositor has discarded SetFrameTree");
+ warn!("Compositor has discarded SetFrameTree");
return; // Our message has been discarded, probably shutting down.
}
}
diff --git a/components/compositing/pipeline.rs b/components/compositing/pipeline.rs
index 8c22ce0348b..3a45a486b8a 100644
--- a/components/compositing/pipeline.rs
+++ b/components/compositing/pipeline.rs
@@ -26,6 +26,7 @@ use profile_traits::time;
use script_traits::{ConstellationControlMsg, InitialScriptState, MozBrowserEvent};
use script_traits::{LayoutControlMsg, LayoutMsg, NewLayoutInfo, ScriptMsg};
use script_traits::{ScriptToCompositorMsg, ScriptThreadFactory, TimerEventRequest};
+use std::collections::HashMap;
use std::mem;
use std::sync::mpsc::{Receiver, Sender, channel};
use url::Url;
@@ -33,7 +34,7 @@ use util;
use util::geometry::{PagePx, ViewportPx};
use util::ipc::OptionalIpcSender;
use util::opts::{self, Opts};
-use util::prefs;
+use util::prefs::{self, Pref};
use util::thread;
use webrender_traits;
@@ -232,6 +233,7 @@ impl Pipeline {
failure: failure,
script_port: script_port,
opts: (*opts::get()).clone(),
+ prefs: prefs::get_cloned(),
layout_to_paint_chan: layout_to_paint_chan,
pipeline_port: pipeline_port,
layout_shutdown_chan: layout_shutdown_chan,
@@ -408,6 +410,7 @@ pub struct UnprivilegedPipelineContent {
script_port: Option<IpcReceiver<ConstellationControlMsg>>,
layout_to_paint_chan: OptionalIpcSender<LayoutToPaintMsg>,
opts: Opts,
+ prefs: HashMap<String, Pref>,
paint_shutdown_chan: IpcSender<()>,
pipeline_port: Option<IpcReceiver<LayoutControlMsg>>,
pipeline_namespace_id: PipelineNamespaceId,
@@ -472,6 +475,10 @@ impl UnprivilegedPipelineContent {
pub fn opts(&self) -> Opts {
self.opts.clone()
}
+
+ pub fn prefs(&self) -> HashMap<String, Pref> {
+ self.prefs.clone()
+ }
}
pub struct PrivilegedPipelineContent {
diff --git a/components/compositing/sandboxing.rs b/components/compositing/sandboxing.rs
index 41273cad0a7..945e0605f09 100644
--- a/components/compositing/sandboxing.rs
+++ b/components/compositing/sandboxing.rs
@@ -16,7 +16,9 @@ pub fn content_process_sandbox_profile() -> Profile {
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/Library/Fonts"))),
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from("/System/Library/Fonts"))),
Operation::FileReadAll(PathPattern::Subpath(PathBuf::from(
- "/System/Library/Frameworks/ApplicationServices.framework/"))),
+ "/System/Library/Frameworks/ApplicationServices.framework"))),
+ Operation::FileReadAll(PathPattern::Subpath(PathBuf::from(
+ "/System/Library/Frameworks/CoreGraphics.framework"))),
Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/"))),
Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/Library"))),
Operation::FileReadMetadata(PathPattern::Literal(PathBuf::from("/System"))),
diff --git a/components/gfx/Cargo.toml b/components/gfx/Cargo.toml
index 823b78ed271..f470f7dcd48 100644
--- a/components/gfx/Cargo.toml
+++ b/components/gfx/Cargo.toml
@@ -27,7 +27,7 @@ serde = "0.7"
serde_macros = "0.7"
servo-skia = "0.20130412.0"
smallvec = "0.1"
-string_cache = {version = "0.2.11", features = ["heap_size"]}
+string_cache = {version = "0.2.12", features = ["heap_size"]}
time = "0.1.12"
unicode-script = { version = "0.1", features = ["harfbuzz"] }
url = {version = "0.5.7", features = ["heap_size"]}
diff --git a/components/gfx/font_context.rs b/components/gfx/font_context.rs
index 7cb95e6fc54..ff7715e2cb7 100644
--- a/components/gfx/font_context.rs
+++ b/components/gfx/font_context.rs
@@ -38,7 +38,7 @@ fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFo
#[cfg(target_os = "macos")]
fn create_scaled_font(template: &Arc<FontTemplateData>, pt_size: Au) -> ScaledFont {
- let cgfont = template.ctfont().as_ref().unwrap().copy_to_CGFont();
+ let cgfont = template.ctfont(pt_size.to_f64_px()).as_ref().unwrap().copy_to_CGFont();
ScaledFont::new(BackendType::Skia, &cgfont, pt_size.to_f32_px())
}
diff --git a/components/gfx/platform/macos/font.rs b/components/gfx/platform/macos/font.rs
index a0667245cbe..abdb620ba36 100644
--- a/components/gfx/platform/macos/font.rs
+++ b/components/gfx/platform/macos/font.rs
@@ -72,7 +72,7 @@ impl FontHandleMethods for FontHandle {
Some(s) => s.to_f64_px(),
None => 0.0
};
- match template.ctfont() {
+ match template.ctfont(size) {
Some(ref ctfont) => {
Ok(FontHandle {
font_data: template.clone(),
diff --git a/components/gfx/platform/macos/font_template.rs b/components/gfx/platform/macos/font_template.rs
index 3099bbd28ed..a36b49eebe3 100644
--- a/components/gfx/platform/macos/font_template.rs
+++ b/components/gfx/platform/macos/font_template.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use app_units::Au;
use core_graphics::data_provider::CGDataProvider;
use core_graphics::font::CGFont;
use core_text;
@@ -9,6 +10,7 @@ use core_text::font::CTFont;
use serde::de::{Error, Visitor};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::borrow::ToOwned;
+use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::ops::Deref;
@@ -26,7 +28,7 @@ pub struct FontTemplateData {
/// `CTFont` instances over and over. It can always be recreated from the `identifier` and/or
/// `font_data` fields.
///
- /// When sending a `FontTemplateData` instance across processes, this will be set to `None` on
+ /// When sending a `FontTemplateData` instance across processes, this will be cleared out on
/// the other side, because `CTFont` instances cannot be sent across processes. This is
/// harmless, however, because it can always be recreated.
ctfont: CachedCTFont,
@@ -41,29 +43,38 @@ unsafe impl Sync for FontTemplateData {}
impl FontTemplateData {
pub fn new(identifier: Atom, font_data: Option<Vec<u8>>) -> FontTemplateData {
FontTemplateData {
- ctfont: CachedCTFont(Mutex::new(None)),
+ ctfont: CachedCTFont(Mutex::new(HashMap::new())),
identifier: identifier.to_owned(),
font_data: font_data
}
}
/// Retrieves the Core Text font instance, instantiating it if necessary.
- pub fn ctfont(&self) -> Option<CTFont> {
- let mut ctfont = self.ctfont.lock().unwrap();
- if ctfont.is_none() {
- *ctfont = match self.font_data {
+ pub fn ctfont(&self, pt_size: f64) -> Option<CTFont> {
+ let mut ctfonts = self.ctfont.lock().unwrap();
+ let pt_size_key = Au::from_f64_px(pt_size);
+ if !ctfonts.contains_key(&pt_size_key) {
+ // If you pass a zero font size to one of the Core Text APIs, it'll replace it with
+ // 12.0. We don't want that! (Issue #10492.)
+ let clamped_pt_size = pt_size.max(0.01);
+ let ctfont = match self.font_data {
Some(ref bytes) => {
let fontprov = CGDataProvider::from_buffer(bytes);
let cgfont_result = CGFont::from_data_provider(fontprov);
match cgfont_result {
- Ok(cgfont) => Some(core_text::font::new_from_CGFont(&cgfont, 0.0)),
+ Ok(cgfont) => {
+ Some(core_text::font::new_from_CGFont(&cgfont, clamped_pt_size))
+ }
Err(_) => None
}
}
- None => core_text::font::new_from_name(&*self.identifier, 0.0).ok(),
+ None => core_text::font::new_from_name(&*self.identifier, clamped_pt_size).ok(),
+ };
+ if let Some(ctfont) = ctfont {
+ ctfonts.insert(pt_size_key, ctfont);
}
}
- ctfont.as_ref().map(|ctfont| (*ctfont).clone())
+ ctfonts.get(&pt_size_key).map(|ctfont| (*ctfont).clone())
}
/// Returns a clone of the data in this font. This may be a hugely expensive
@@ -75,7 +86,7 @@ impl FontTemplateData {
None => {}
}
- let path = Url::parse(&*self.ctfont()
+ let path = Url::parse(&*self.ctfont(0.0)
.expect("No Core Text font available!")
.url()
.expect("No URL for Core Text font!")
@@ -96,16 +107,16 @@ impl FontTemplateData {
/// Returns the native font that underlies this font template, if applicable.
pub fn native_font(&self) -> Option<CGFont> {
- self.ctfont().map(|ctfont| ctfont.copy_to_CGFont())
+ self.ctfont(0.0).map(|ctfont| ctfont.copy_to_CGFont())
}
}
#[derive(Debug)]
-pub struct CachedCTFont(Mutex<Option<CTFont>>);
+pub struct CachedCTFont(Mutex<HashMap<Au, CTFont>>);
impl Deref for CachedCTFont {
- type Target = Mutex<Option<CTFont>>;
- fn deref(&self) -> &Mutex<Option<CTFont>> {
+ type Target = Mutex<HashMap<Au, CTFont>>;
+ fn deref(&self) -> &Mutex<HashMap<Au, CTFont>> {
&self.0
}
}
@@ -126,7 +137,7 @@ impl Deserialize for CachedCTFont {
#[inline]
fn visit_none<E>(&mut self) -> Result<CachedCTFont, E> where E: Error {
- Ok(CachedCTFont(Mutex::new(None)))
+ Ok(CachedCTFont(Mutex::new(HashMap::new())))
}
}
diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml
index f7371a7a34a..35ca6cd1173 100644
--- a/components/layout/Cargo.toml
+++ b/components/layout/Cargo.toml
@@ -76,7 +76,7 @@ serde = "0.7"
serde_json = "0.7"
serde_macros = "0.7"
smallvec = "0.1"
-string_cache = {version = "0.2.11", features = ["heap_size"]}
+string_cache = {version = "0.2.12", features = ["heap_size"]}
time = "0.1"
unicode-bidi = "0.2"
unicode-script = { version = "0.1", features = ["harfbuzz"] }
diff --git a/components/layout/flex.rs b/components/layout/flex.rs
index 4c8f749b086..eed7ec8aae3 100644
--- a/components/layout/flex.rs
+++ b/components/layout/flex.rs
@@ -13,9 +13,9 @@ use display_list_builder::{DisplayListBuildState, FlexFlowDisplayListBuilding};
use euclid::Point2D;
use floats::FloatKind;
use flow;
-use flow::INLINE_POSITION_IS_STATIC;
-use flow::IS_ABSOLUTELY_POSITIONED;
use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
+use flow::{INLINE_POSITION_IS_STATIC, IS_ABSOLUTELY_POSITIONED};
+use flow_ref::{self, FlowRef};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx::display_list::{StackingContext, StackingContextId};
use incremental::{REFLOW, REFLOW_OUT_OF_FLOW};
@@ -73,6 +73,19 @@ enum Mode {
Block
}
+#[derive(Debug)]
+struct FlexItem {
+ pub flow: FlowRef,
+}
+
+impl FlexItem {
+ fn new(flow: FlowRef) -> FlexItem {
+ FlexItem {
+ flow: flow
+ }
+ }
+}
+
/// A block with the CSS `display` property equal to `flex`.
#[derive(Debug)]
pub struct FlexFlow {
@@ -84,23 +97,9 @@ pub struct FlexFlow {
/// The available main axis size
available_main_size: AxisSize,
/// The available cross axis size
- available_cross_size: AxisSize
-}
-
-// TODO(zentner): This function should use flex-basis.
-fn flex_item_inline_sizes(flow: &mut Flow) -> IntrinsicISizes {
- let _scope = layout_debug_scope!("flex::flex_item_inline_sizes");
- debug!("flex_item_inline_sizes");
- let base = flow::mut_base(flow);
-
- debug!("FlexItem intrinsic inline sizes: {:?}, {:?}",
- base.intrinsic_inline_sizes.minimum_inline_size,
- base.intrinsic_inline_sizes.preferred_inline_size);
-
- IntrinsicISizes {
- minimum_inline_size: base.intrinsic_inline_sizes.minimum_inline_size,
- preferred_inline_size: base.intrinsic_inline_sizes.preferred_inline_size,
- }
+ available_cross_size: AxisSize,
+ /// List of flex-items that belong to this flex-container
+ items: Vec<FlexItem>
}
impl FlexFlow {
@@ -117,7 +116,8 @@ impl FlexFlow {
block_flow: BlockFlow::from_fragment(fragment, flotation),
main_mode: main_mode,
available_main_size: AxisSize::Infinite,
- available_cross_size: AxisSize::Infinite
+ available_cross_size: AxisSize::Infinite,
+ items: Vec::new()
}
}
@@ -132,11 +132,15 @@ impl FlexFlow {
let mut computation = self.block_flow.fragment.compute_intrinsic_inline_sizes();
if !fixed_width {
- for kid in self.block_flow.base.child_iter_mut() {
- let is_absolutely_positioned =
- flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED);
+ for kid in &mut self.items {
+ let base = flow::mut_base(flow_ref::deref_mut(&mut kid.flow));
+ let is_absolutely_positioned = base.flags.contains(IS_ABSOLUTELY_POSITIONED);
if !is_absolutely_positioned {
- computation.union_nonbreaking_inline(&flex_item_inline_sizes(kid));
+ let flex_item_inline_sizes = IntrinsicISizes {
+ minimum_inline_size: base.intrinsic_inline_sizes.minimum_inline_size,
+ preferred_inline_size: base.intrinsic_inline_sizes.preferred_inline_size,
+ };
+ computation.union_nonbreaking_inline(&flex_item_inline_sizes);
}
}
}
@@ -154,18 +158,17 @@ impl FlexFlow {
let mut computation = self.block_flow.fragment.compute_intrinsic_inline_sizes();
if !fixed_width {
- for kid in self.block_flow.base.child_iter_mut() {
- let is_absolutely_positioned =
- flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED);
- let child_base = flow::mut_base(kid);
+ for kid in &mut self.items {
+ let base = flow::mut_base(flow_ref::deref_mut(&mut kid.flow));
+ let is_absolutely_positioned = base.flags.contains(IS_ABSOLUTELY_POSITIONED);
if !is_absolutely_positioned {
computation.content_intrinsic_sizes.minimum_inline_size =
max(computation.content_intrinsic_sizes.minimum_inline_size,
- child_base.intrinsic_inline_sizes.minimum_inline_size);
+ base.intrinsic_inline_sizes.minimum_inline_size);
computation.content_intrinsic_sizes.preferred_inline_size =
max(computation.content_intrinsic_sizes.preferred_inline_size,
- child_base.intrinsic_inline_sizes.preferred_inline_size);
+ base.intrinsic_inline_sizes.preferred_inline_size);
}
}
}
@@ -186,36 +189,33 @@ impl FlexFlow {
// FIXME (mbrubeck): Get correct mode for absolute containing block
let containing_block_mode = self.block_flow.base.writing_mode;
- let mut iterator = self.block_flow.base.child_iter_mut().enumerate().peekable();
- while let Some((_, kid)) = iterator.next() {
- {
- let kid_base = flow::mut_base(kid);
- kid_base.block_container_explicit_block_size = match self.available_main_size {
- AxisSize::Definite(length) => Some(length),
- _ => None
- }
- }
-
- // The inline-start margin edge of the child flow is at our inline-start content edge,
- // and its inline-size is our content inline-size.
- let kid_mode = flow::base(kid).writing_mode;
+ let container_block_size = match self.available_main_size {
+ AxisSize::Definite(length) => Some(length),
+ _ => None
+ };
+ let container_inline_size = match self.available_cross_size {
+ AxisSize::Definite(length) => length,
+ AxisSize::MinMax(ref constraint) => constraint.clamp(content_inline_size),
+ AxisSize::Infinite => content_inline_size
+ };
+ for kid in &mut self.items {
{
- let kid_base = flow::mut_base(kid);
+ let kid_base = flow::mut_base(flow_ref::deref_mut(&mut kid.flow));
+ kid_base.block_container_explicit_block_size = container_block_size;
if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) {
+ // The inline-start margin edge of the child flow is at our inline-start content edge,
+ // and its inline-size is our content inline-size.
kid_base.position.start.i =
- if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() {
+ if kid_base.writing_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() {
inline_start_content_edge
} else {
// The kid's inline 'start' is at the parent's 'end'
inline_end_content_edge
};
}
- kid_base.block_container_inline_size = match self.available_main_size {
- AxisSize::Definite(length) => length,
- AxisSize::MinMax(ref constraint) => constraint.clamp(content_inline_size),
- AxisSize::Infinite => content_inline_size,
- };
+ kid_base.block_container_inline_size = container_inline_size;
kid_base.block_container_writing_mode = containing_block_mode;
+ kid_base.position.start.i = inline_start_content_edge;
}
}
}
@@ -247,25 +247,30 @@ impl FlexFlow {
let even_content_inline_size = inline_size / child_count;
- let inline_size = self.block_flow.base.block_container_inline_size;
let container_mode = self.block_flow.base.block_container_writing_mode;
self.block_flow.base.position.size.inline = inline_size;
let block_container_explicit_block_size = self.block_flow.base.block_container_explicit_block_size;
let mut inline_child_start = inline_start_content_edge;
- for kid in self.block_flow.base.child_iter_mut() {
- let kid_base = flow::mut_base(kid);
+ for kid in &mut self.items {
+ let base = flow::mut_base(flow_ref::deref_mut(&mut kid.flow));
- kid_base.block_container_inline_size = even_content_inline_size;
- kid_base.block_container_writing_mode = container_mode;
- kid_base.block_container_explicit_block_size = block_container_explicit_block_size;
- kid_base.position.start.i = inline_child_start;
+ base.block_container_inline_size = even_content_inline_size;
+ base.block_container_writing_mode = container_mode;
+ base.block_container_explicit_block_size = block_container_explicit_block_size;
+ base.position.start.i = inline_child_start;
inline_child_start = inline_child_start + even_content_inline_size;
}
}
// TODO(zentner): This function should actually flex elements!
fn block_mode_assign_block_size<'a>(&mut self, layout_context: &'a LayoutContext<'a>) {
+ let mut cur_b = self.block_flow.fragment.border_padding.block_start;
+ for kid in &mut self.items {
+ let base = flow::mut_base(flow_ref::deref_mut(&mut kid.flow));
+ base.position.start.b = cur_b;
+ cur_b = cur_b + base.position.size.block;
+ }
self.block_flow.assign_block_size(layout_context)
}
@@ -334,6 +339,10 @@ impl Flow for FlexFlow {
FlowClass::Flex
}
+ fn as_block(&self) -> &BlockFlow {
+ &self.block_flow
+ }
+
fn as_mut_block(&mut self) -> &mut BlockFlow {
&mut self.block_flow
}
@@ -351,8 +360,18 @@ impl Flow for FlexFlow {
// Flexbox Section 9.1: Re-order the flex items (and any absolutely positioned flex
// container children) according to their order.
- // TODO(zentner): We need to re-order the items at some point. However, all the operations
- // here ignore order, so we can afford to do it later, if necessary.
+
+ let mut items = self.block_flow.base.children.iter_flow_ref_mut().map(|flow| {
+ FlexItem::new(flow.clone())
+ }).collect::<Vec<FlexItem>>();
+
+ items.sort_by(|item1, item2| {
+ item1.flow.as_block().fragment.style.get_position().order.cmp(
+ &item2.flow.as_block().fragment.style.get_position().order
+ )
+ });
+
+ self.items = items;
match self.main_mode {
Mode::Inline => self.inline_mode_bubble_inline_sizes(),
diff --git a/components/layout/flow_list.rs b/components/layout/flow_list.rs
index 37044008f7f..96f4d5ba7ef 100644
--- a/components/layout/flow_list.rs
+++ b/components/layout/flow_list.rs
@@ -64,6 +64,12 @@ impl FlowList {
}
}
+ /// Provide a forward iterator with FlowRef items
+ #[inline]
+ pub fn iter_flow_ref_mut<'a>(&'a mut self) -> linked_list::IterMut<'a, FlowRef> {
+ self.flows.iter_mut()
+ }
+
/// O(1)
#[inline]
pub fn is_empty(&self) -> bool {
diff --git a/components/layout/fragment.rs b/components/layout/fragment.rs
index 439e8a79f60..03638be5fab 100644
--- a/components/layout/fragment.rs
+++ b/components/layout/fragment.rs
@@ -1029,12 +1029,15 @@ impl Fragment {
fn style_specified_intrinsic_inline_size(&self) -> IntrinsicISizesContribution {
let flags = self.quantities_included_in_intrinsic_inline_size();
let style = self.style();
- let specified = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) {
- max(model::specified(style.min_inline_size(), Au(0)),
- MaybeAuto::from_style(style.content_inline_size(), Au(0)).specified_or_zero())
- } else {
- Au(0)
- };
+ let mut specified = Au(0);
+
+ if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) {
+ specified = MaybeAuto::from_style(style.content_inline_size(), Au(0)).specified_or_zero();
+ specified = max(model::specified(style.min_inline_size(), Au(0)), specified);
+ if let Some(max) = model::specified_or_none(style.max_inline_size(), Au(0)) {
+ specified = min(specified, max)
+ }
+ }
// FIXME(#2261, pcwalton): This won't work well for inlines: is this OK?
let surrounding_inline_size = self.surrounding_intrinsic_inline_size();
@@ -1375,7 +1378,7 @@ impl Fragment {
result.union_block(&block_flow.base.intrinsic_inline_sizes)
}
SpecificFragmentInfo::Image(ref mut image_fragment_info) => {
- let image_inline_size = match self.style.content_inline_size() {
+ let mut image_inline_size = match self.style.content_inline_size() {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Percentage(_) => {
image_fragment_info.image_inline_size()
@@ -1383,13 +1386,19 @@ impl Fragment {
LengthOrPercentageOrAuto::Length(length) => length,
LengthOrPercentageOrAuto::Calc(calc) => calc.length(),
};
+
+ image_inline_size = max(model::specified(self.style.min_inline_size(), Au(0)), image_inline_size);
+ if let Some(max) = model::specified_or_none(self.style.max_inline_size(), Au(0)) {
+ image_inline_size = min(image_inline_size, max)
+ }
+
result.union_block(&IntrinsicISizes {
minimum_inline_size: image_inline_size,
preferred_inline_size: image_inline_size,
});
}
SpecificFragmentInfo::Canvas(ref mut canvas_fragment_info) => {
- let canvas_inline_size = match self.style.content_inline_size() {
+ let mut canvas_inline_size = match self.style.content_inline_size() {
LengthOrPercentageOrAuto::Auto |
LengthOrPercentageOrAuto::Percentage(_) => {
canvas_fragment_info.canvas_inline_size()
@@ -1397,6 +1406,12 @@ impl Fragment {
LengthOrPercentageOrAuto::Length(length) => length,
LengthOrPercentageOrAuto::Calc(calc) => calc.length(),
};
+
+ canvas_inline_size = max(model::specified(self.style.min_inline_size(), Au(0)), canvas_inline_size);
+ if let Some(max) = model::specified_or_none(self.style.max_inline_size(), Au(0)) {
+ canvas_inline_size = min(canvas_inline_size, max)
+ }
+
result.union_block(&IntrinsicISizes {
minimum_inline_size: canvas_inline_size,
preferred_inline_size: canvas_inline_size,
diff --git a/components/layout/webrender_helpers.rs b/components/layout/webrender_helpers.rs
index fcf0e204a0d..1d21ab4e462 100644
--- a/components/layout/webrender_helpers.rs
+++ b/components/layout/webrender_helpers.rs
@@ -28,6 +28,7 @@ trait WebRenderStackingContextConverter {
pipeline_id: webrender_traits::PipelineId,
epoch: webrender_traits::Epoch,
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
+ scroll_policy: ScrollPolicy,
frame_builder: &mut WebRenderFrameBuilder)
-> webrender_traits::StackingContextId;
@@ -37,6 +38,7 @@ trait WebRenderStackingContextConverter {
pipeline_id: webrender_traits::PipelineId,
epoch: webrender_traits::Epoch,
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
+ scroll_policy: ScrollPolicy,
builder: &mut webrender_traits::DisplayListBuilder,
frame_builder: &mut WebRenderFrameBuilder,
force_positioned_stacking_level: bool);
@@ -276,6 +278,7 @@ impl WebRenderStackingContextConverter for StackingContext {
pipeline_id: webrender_traits::PipelineId,
epoch: webrender_traits::Epoch,
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
+ scroll_policy: ScrollPolicy,
builder: &mut webrender_traits::DisplayListBuilder,
frame_builder: &mut WebRenderFrameBuilder,
force_positioned_stacking_level: bool) {
@@ -295,6 +298,7 @@ impl WebRenderStackingContextConverter for StackingContext {
pipeline_id,
epoch,
None,
+ scroll_policy,
frame_builder);
builder.push_stacking_context(child.web_render_stacking_level(),
stacking_context_id);
@@ -304,6 +308,7 @@ impl WebRenderStackingContextConverter for StackingContext {
pipeline_id,
epoch,
scroll_layer_id,
+ scroll_policy,
builder,
frame_builder,
true);
@@ -323,19 +328,21 @@ impl WebRenderStackingContextConverter for StackingContext {
pipeline_id: webrender_traits::PipelineId,
epoch: webrender_traits::Epoch,
scroll_layer_id: Option<webrender_traits::ScrollLayerId>,
+ mut scroll_policy: ScrollPolicy,
frame_builder: &mut WebRenderFrameBuilder)
-> webrender_traits::StackingContextId {
- let scroll_policy = self.layer_info
- .map_or(webrender_traits::ScrollPolicy::Scrollable, |info| {
- match info.scroll_policy {
- ScrollPolicy::Scrollable => webrender_traits::ScrollPolicy::Scrollable,
- ScrollPolicy::FixedPosition => webrender_traits::ScrollPolicy::Fixed,
- }
- });
+ if let Some(ref layer_info) = self.layer_info {
+ scroll_policy = layer_info.scroll_policy
+ }
+
+ let webrender_scroll_policy = match scroll_policy {
+ ScrollPolicy::Scrollable => webrender_traits::ScrollPolicy::Scrollable,
+ ScrollPolicy::FixedPosition => webrender_traits::ScrollPolicy::Fixed,
+ };
let mut sc =
webrender_traits::StackingContext::new(scroll_layer_id,
- scroll_policy,
+ webrender_scroll_policy,
self.bounds.to_rectf(),
self.overflow.to_rectf(),
self.z_index,
@@ -351,6 +358,7 @@ impl WebRenderStackingContextConverter for StackingContext {
pipeline_id,
epoch,
scroll_layer_id,
+ scroll_policy,
&mut builder,
frame_builder,
false);
@@ -386,6 +394,7 @@ impl WebRenderDisplayListConverter for DisplayList {
pipeline_id,
epoch,
scroll_layer_id,
+ ScrollPolicy::Scrollable,
frame_builder)
}
}
diff --git a/components/layout/wrapper.rs b/components/layout/wrapper.rs
index ad8ce2f5141..e76af843ea0 100644
--- a/components/layout/wrapper.rs
+++ b/components/layout/wrapper.rs
@@ -1050,7 +1050,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
return TextContent::Text(data);
}
if let Some(input) = this.downcast::<HTMLInputElement>() {
- let data = unsafe { input.get_value_for_layout() };
+ let data = unsafe { input.value_for_layout() };
return TextContent::Text(data);
}
if let Some(area) = this.downcast::<HTMLTextAreaElement>() {
@@ -1076,7 +1076,7 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
}
}
if let Some(input) = this.downcast::<HTMLInputElement>() {
- if let Some(selection) = unsafe { input.get_selection_for_layout() } {
+ if let Some(selection) = unsafe { input.selection_for_layout() } {
return Some(Range::new(CharIndex(selection.begin()),
CharIndex(selection.length())));
}
diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml
index 58a60da2bb1..955ceb24fcb 100644
--- a/components/net/Cargo.toml
+++ b/components/net/Cargo.toml
@@ -44,6 +44,7 @@ openssl = "0.7.6"
rustc-serialize = "0.3"
threadpool = "1.0"
time = "0.1.17"
+unicase = "1.4.0"
url = {version = "0.5.7", features = ["heap_size"]}
uuid = { version = "0.2", features = ["v4"] }
websocket = "0.16.1"
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs
index d99dc3f10e4..76140b1245f 100644
--- a/components/net/fetch/methods.rs
+++ b/components/net/fetch/methods.rs
@@ -5,12 +5,12 @@
use data_loader::decode;
use fetch::cors_cache::{BasicCORSCache, CORSCache, CacheRequestDetails};
use http_loader::{NetworkHttpRequestFactory, create_http_connector, obtain_response};
-use hyper::header::{Accept, CacheControl, IfMatch, IfRange, IfUnmodifiedSince, Location};
-use hyper::header::{AcceptLanguage, ContentLength, ContentLanguage, HeaderView, Pragma};
-use hyper::header::{AccessControlAllowCredentials, AccessControlAllowOrigin};
-use hyper::header::{Authorization, Basic, CacheDirective, ContentEncoding, Encoding};
-use hyper::header::{ContentType, Headers, IfModifiedSince, IfNoneMatch};
-use hyper::header::{QualityItem, q, qitem, Referer as RefererHeader, UserAgent};
+use hyper::header::{Accept, AcceptLanguage, Authorization, AccessControlAllowCredentials};
+use hyper::header::{AccessControlAllowOrigin, AccessControlAllowHeaders, AccessControlAllowMethods};
+use hyper::header::{AccessControlRequestHeaders, AccessControlMaxAge, AccessControlRequestMethod, Basic};
+use hyper::header::{CacheControl, CacheDirective, ContentEncoding, ContentLength, ContentLanguage, ContentType};
+use hyper::header::{Encoding, HeaderView, Headers, IfMatch, IfRange, IfUnmodifiedSince, IfModifiedSince};
+use hyper::header::{IfNoneMatch, Pragma, Location, QualityItem, Referer as RefererHeader, UserAgent, q, qitem};
use hyper::method::Method;
use hyper::mime::{Mime, SubLevel, TopLevel};
use hyper::status::StatusCode;
@@ -20,9 +20,12 @@ use net_traits::request::{RedirectMode, Referer, Request, RequestMode, ResponseT
use net_traits::response::{HttpsState, TerminationReason};
use net_traits::response::{Response, ResponseBody, ResponseType};
use resource_thread::CancellationListener;
+use std::collections::HashSet;
use std::io::Read;
+use std::iter::FromIterator;
use std::rc::Rc;
use std::thread;
+use unicase::UniCase;
use url::idna::domain_to_ascii;
use url::{Origin as UrlOrigin, OpaqueOrigin, Url, UrlParser, whatwg_scheme_type_mapper};
use util::thread::spawn_named;
@@ -210,7 +213,7 @@ fn main_fetch(request: Rc<Request>, cors_flag: bool, recursive_flag: bool) -> Re
let internal_response = if response.is_network_error() {
&network_error_res
} else {
- response.get_actual_response()
+ response.actual_response()
};
// Step 13
@@ -245,7 +248,7 @@ fn main_fetch(request: Rc<Request>, cors_flag: bool, recursive_flag: bool) -> Re
// Step 16
if request.synchronous {
- response.get_actual_response().wait_until_done();
+ response.actual_response().wait_until_done();
return response;
}
@@ -263,7 +266,7 @@ fn main_fetch(request: Rc<Request>, cors_flag: bool, recursive_flag: bool) -> Re
let internal_response = if response.is_network_error() {
&network_error_res
} else {
- response.get_actual_response()
+ response.actual_response()
};
// Step 18
@@ -365,7 +368,7 @@ fn http_fetch(request: Rc<Request>,
}
// Substep 4
- let actual_response = res.get_actual_response();
+ let actual_response = res.actual_response();
if actual_response.url_list.borrow().is_empty() {
*actual_response.url_list.borrow_mut() = request.url_list.borrow().clone();
}
@@ -390,7 +393,7 @@ fn http_fetch(request: Rc<Request>,
}, request.method.borrow().clone());
let method_mismatch = !method_cache_match && (!is_simple_method(&request.method.borrow()) ||
- request.use_cors_preflight);
+ request.use_cors_preflight);
let header_mismatch = request.headers.borrow().iter().any(|view|
!cache.match_header(CacheRequestDetails {
origin: origin.clone(),
@@ -401,7 +404,7 @@ fn http_fetch(request: Rc<Request>,
// Sub-substep 1
if method_mismatch || header_mismatch {
- let preflight_result = preflight_fetch(request.clone());
+ let preflight_result = cors_preflight_fetch(request.clone(), Some(cache));
// Sub-substep 2
if preflight_result.response_type == ResponseType::Error {
return Response::network_error();
@@ -415,8 +418,7 @@ fn http_fetch(request: Rc<Request>,
// Substep 3
let credentials = match request.credentials_mode {
CredentialsMode::Include => true,
- CredentialsMode::CredentialsSameOrigin if
- request.response_tainting.get() == ResponseTainting::Basic
+ CredentialsMode::CredentialsSameOrigin if request.response_tainting.get() == ResponseTainting::Basic
=> true,
_ => false
};
@@ -437,7 +439,7 @@ fn http_fetch(request: Rc<Request>,
let mut response = response.unwrap();
// Step 5
- match response.get_actual_response().status.unwrap() {
+ match response.actual_response().status.unwrap() {
// Code 301, 302, 303, 307, 308
StatusCode::MovedPermanently | StatusCode::Found | StatusCode::SeeOther |
@@ -518,21 +520,21 @@ fn http_redirect_fetch(request: Rc<Request>,
assert_eq!(response.return_internal.get(), true);
// Step 3
- // this step is done early, because querying if Location is available says
+ // this step is done early, because querying if Location exists says
// if it is None or Some, making it easy to seperate from the retrieval failure case
- if !response.get_actual_response().headers.has::<Location>() {
+ if !response.actual_response().headers.has::<Location>() {
return Rc::try_unwrap(response).ok().unwrap();
}
// Step 2
- let location = match response.get_actual_response().headers.get::<Location>() {
+ let location = match response.actual_response().headers.get::<Location>() {
Some(&Location(ref location)) => location.clone(),
// Step 4
_ => return Response::network_error()
};
// Step 5
- let response_url = response.get_actual_response().url.as_ref().unwrap();
+ let response_url = response.actual_response().url.as_ref().unwrap();
let location_url = UrlParser::new().base_url(response_url).parse(&*location);
// Step 6
@@ -575,7 +577,7 @@ fn http_redirect_fetch(request: Rc<Request>,
}
// Step 13
- let status_code = response.get_actual_response().status.unwrap();
+ let status_code = response.actual_response().status.unwrap();
if ((status_code == StatusCode::MovedPermanently || status_code == StatusCode::Found) &&
*request.method.borrow() == Method::Post) ||
status_code == StatusCode::SeeOther {
@@ -876,11 +878,11 @@ fn http_network_fetch(request: Rc<Request>,
// Substep 2
- // TODO how can I tell if response was retrieved over HTTPS?
+ // TODO Determine if response was retrieved over HTTPS
// TODO Servo needs to decide what ciphers are to be treated as "deprecated"
response.https_state = HttpsState::None;
- // TODO how do I read request?
+ // TODO Read request
// Step 5
// TODO when https://bugzilla.mozilla.org/show_bug.cgi?id=1030660
@@ -925,8 +927,113 @@ fn http_network_fetch(request: Rc<Request>,
}
/// [CORS preflight fetch](https://fetch.spec.whatwg.org#cors-preflight-fetch)
-fn preflight_fetch(_request: Rc<Request>) -> Response {
- // TODO: Implement preflight fetch spec
+fn cors_preflight_fetch(request: Rc<Request>, cache: Option<BasicCORSCache>) -> Response {
+ // Step 1
+ let mut preflight = Request::new(request.current_url(), Some(request.origin.borrow().clone()), false);
+ *preflight.method.borrow_mut() = Method::Options;
+ preflight.initiator = request.initiator.clone();
+ preflight.type_ = request.type_.clone();
+ preflight.destination = request.destination.clone();
+ preflight.referer = request.referer.clone();
+
+ // Step 2
+ preflight.headers.borrow_mut().set::<AccessControlRequestMethod>(
+ AccessControlRequestMethod(request.method.borrow().clone()));
+
+ // Step 3, 4
+ let mut value = request.headers.borrow().iter()
+ .filter_map(|ref view| if is_simple_header(view) {
+ None
+ } else {
+ Some(UniCase(view.name().to_owned()))
+ }).collect::<Vec<UniCase<String>>>();
+ value.sort();
+
+ // Step 5
+ preflight.headers.borrow_mut().set::<AccessControlRequestHeaders>(
+ AccessControlRequestHeaders(value));
+
+ // Step 6
+ let preflight = Rc::new(preflight);
+ let response = http_network_or_cache_fetch(preflight.clone(), false, false);
+
+ // Step 7
+ if cors_check(request.clone(), &response).is_ok() &&
+ response.status.map_or(false, |status| status.is_success()) {
+ // Substep 1
+ let mut methods = if response.headers.has::<AccessControlAllowMethods>() {
+ match response.headers.get::<AccessControlAllowMethods>() {
+ Some(&AccessControlAllowMethods(ref m)) => m.clone(),
+ // Substep 3
+ None => return Response::network_error()
+ }
+ } else {
+ vec![]
+ };
+
+ // Substep 2
+ let header_names = if response.headers.has::<AccessControlAllowHeaders>() {
+ match response.headers.get::<AccessControlAllowHeaders>() {
+ Some(&AccessControlAllowHeaders(ref hn)) => hn.clone(),
+ // Substep 3
+ None => return Response::network_error()
+ }
+ } else {
+ vec![]
+ };
+
+ // Substep 4
+ if methods.is_empty() && request.use_cors_preflight {
+ methods = vec![request.method.borrow().clone()];
+ }
+
+ // Substep 5
+ if methods.iter().all(|method| *method != *request.method.borrow()) &&
+ !is_simple_method(&*request.method.borrow()) {
+ return Response::network_error();
+ }
+
+ // Substep 6
+ let set: HashSet<&UniCase<String>> = HashSet::from_iter(header_names.iter());
+ if request.headers.borrow().iter().any(|ref hv| !set.contains(&UniCase(hv.name().to_owned())) &&
+ !is_simple_header(hv)) {
+ return Response::network_error();
+ }
+
+ // Substep 7, 8
+ let max_age = response.headers.get::<AccessControlMaxAge>().map(|acma| acma.0).unwrap_or(0);
+
+ // TODO: Substep 9 - Need to define what an imposed limit on max-age is
+
+ // Substep 10
+ let mut cache = match cache {
+ Some(c) => c,
+ None => return response
+ };
+
+ // Substep 11, 12
+ for method in &methods {
+ cache.match_method_and_update(CacheRequestDetails {
+ origin: request.origin.borrow().clone(),
+ destination: request.current_url(),
+ credentials: request.credentials_mode == CredentialsMode::Include
+ }, method.clone(), max_age);
+ }
+
+ // Substep 13, 14
+ for header_name in &header_names {
+ cache.match_header_and_update(CacheRequestDetails {
+ origin: request.origin.borrow().clone(),
+ destination: request.current_url(),
+ credentials: request.credentials_mode == CredentialsMode::Include
+ }, &*header_name, max_age);
+ }
+
+ // Substep 15
+ return response;
+ }
+
+ // Step 8
Response::network_error()
}
@@ -934,7 +1041,6 @@ fn preflight_fetch(_request: Rc<Request>) -> Response {
fn cors_check(request: Rc<Request>, response: &Response) -> Result<(), ()> {
// Step 1
- // let headers = request.headers.borrow();
let origin = response.headers.get::<AccessControlAllowOrigin>().cloned();
// Step 2
@@ -942,18 +1048,18 @@ fn cors_check(request: Rc<Request>, response: &Response) -> Result<(), ()> {
// Step 3
if request.credentials_mode != CredentialsMode::Include &&
- origin == AccessControlAllowOrigin::Any {
+ origin == AccessControlAllowOrigin::Any {
return Ok(());
}
// Step 4
let origin = match origin {
AccessControlAllowOrigin::Value(origin) => origin,
- // if it's Any or Null at this point, I see nothing to do but return Err(())
+ // if it's Any or Null at this point, there's nothing to do but return Err(())
_ => return Err(())
};
- // strings are already utf-8 encoded, so I don't need to re-encode origin for this step
+ // strings are already utf-8 encoded, so there's no need to re-encode origin for this step
match ascii_serialise_origin(&request.origin.borrow()) {
Ok(request_origin) => {
if request_origin != origin {
diff --git a/components/net/lib.rs b/components/net/lib.rs
index dafb7f55c47..47342299130 100644
--- a/components/net/lib.rs
+++ b/components/net/lib.rs
@@ -29,6 +29,7 @@ extern crate openssl;
extern crate rustc_serialize;
extern crate threadpool;
extern crate time;
+extern crate unicase;
extern crate url;
extern crate util;
extern crate uuid;
@@ -49,7 +50,7 @@ pub mod resource_thread;
pub mod storage_thread;
pub mod websocket_loader;
-/// An implementation of the [Fetch spec](https://fetch.spec.whatwg.org/)
+/// An implementation of the [Fetch specification](https://fetch.spec.whatwg.org/)
pub mod fetch {
pub mod cors_cache;
pub mod methods;
diff --git a/components/net_traits/Cargo.toml b/components/net_traits/Cargo.toml
index c22a270c03f..d8cdd4213f0 100644
--- a/components/net_traits/Cargo.toml
+++ b/components/net_traits/Cargo.toml
@@ -24,7 +24,7 @@ path = "../plugins"
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
hyper = { version = "0.8", features = [ "serde-serialization" ] }
-image = "0.7"
+image = "0.9"
lazy_static = "0.1.15"
log = "0.3.5"
serde = "0.7"
diff --git a/components/net_traits/response.rs b/components/net_traits/response.rs
index 9e6cedd2765..1c1796df52a 100644
--- a/components/net_traits/response.rs
+++ b/components/net_traits/response.rs
@@ -144,7 +144,7 @@ impl Response {
}
}
- pub fn get_actual_response(&self) -> &Response {
+ pub fn actual_response(&self) -> &Response {
if self.return_internal.get() && self.internal_response.is_some() {
&**self.internal_response.as_ref().unwrap()
} else {
diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml
index 6a8a5d1b25e..9fda41e036f 100644
--- a/components/script/Cargo.toml
+++ b/components/script/Cargo.toml
@@ -75,7 +75,7 @@ heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
html5ever = {version = "0.5.1", features = ["heap_size", "unstable"]}
hyper = { version = "0.8", features = [ "serde-serialization" ] }
-image = "0.7"
+image = "0.9"
libc = "0.2"
log = "0.3.5"
num = "0.1.24"
@@ -91,7 +91,7 @@ rustc-serialize = "0.3"
selectors = {version = "0.5", features = ["heap_size"]}
serde = "0.7"
smallvec = "0.1"
-string_cache = {version = "0.2.11", features = ["heap_size", "unstable"]}
+string_cache = {version = "0.2.12", features = ["heap_size", "unstable"]}
time = "0.1.12"
unicase = "1.0"
url = {version = "0.5.7", features = ["heap_size"]}
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index 51c29764125..57b7be5c7bb 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -3800,22 +3800,6 @@ class CGUnionConversionStruct(CGThing):
pre="impl FromJSValConvertible for %s {\n" % self.type,
post="\n}")
- conversions.append(CGGeneric(
- "throw_not_in_union(cx, \"%s\");\n"
- "Err(())" % ", ".join(names)))
- method = CGWrapper(
- CGIndenter(CGList(conversions, "\n\n")),
- pre="unsafe fn from_jsval(cx: *mut JSContext,\n"
- " value: HandleValue, _option: ()) -> Result<%s, ()> {\n" % self.type,
- post="\n}")
- return CGWrapper(
- CGIndenter(CGList([
- CGGeneric("type Config = ();"),
- method,
- ], "\n")),
- pre="impl FromJSValConvertible for %s {\n" % self.type,
- post="\n}")
-
def try_method(self, t):
templateVars = getUnionTypeTemplateVars(t, self.descriptorProvider)
returnType = "Result<Option<%s>, ()>" % templateVars["typeName"]
diff --git a/components/script/dom/bindings/js.rs b/components/script/dom/bindings/js.rs
index d171715d474..10b9a481382 100644
--- a/components/script/dom/bindings/js.rs
+++ b/components/script/dom/bindings/js.rs
@@ -566,7 +566,7 @@ impl<T: Castable> Root<T> {
impl<T: Reflectable> Root<T> {
/// Create a new stack-bounded root for the provided JS-owned value.
- /// It cannot not outlive its associated `RootCollection`, and it gives
+ /// It cannot outlive its associated `RootCollection`, and it gives
/// out references which cannot outlive this new `Root`.
pub fn new(unrooted: NonZero<*const T>) -> Root<T> {
debug_assert!(thread_state::get().is_script());
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs
index 9cc2d13fb77..50c3fbf682f 100644
--- a/components/script/dom/bindings/trace.rs
+++ b/components/script/dom/bindings/trace.rs
@@ -62,6 +62,7 @@ use net_traits::image::base::{Image, ImageMetadata};
use net_traits::image_cache_thread::{ImageCacheChan, ImageCacheThread};
use net_traits::response::HttpsState;
use net_traits::storage_thread::StorageType;
+use offscreen_gl_context::GLLimits;
use profile_traits::mem::ProfilerChan as MemProfilerChan;
use profile_traits::time::ProfilerChan as TimeProfilerChan;
use script_runtime::ScriptChan;
@@ -88,6 +89,7 @@ use style::properties::PropertyDeclarationBlock;
use style::restyle_hints::ElementSnapshot;
use style::selector_impl::PseudoElement;
use style::values::specified::Length;
+use url::Origin as UrlOrigin;
use url::Url;
use util::str::{DOMString, LengthOrPercentageOrAuto};
use uuid::Uuid;
@@ -275,7 +277,7 @@ impl<A: JSTraceable, B: JSTraceable, C: JSTraceable> JSTraceable for (A, B, C) {
}
}
-no_jsmanaged_fields!(bool, f32, f64, String, Url, AtomicBool, AtomicUsize, Uuid);
+no_jsmanaged_fields!(bool, f32, f64, String, Url, AtomicBool, AtomicUsize, UrlOrigin, Uuid);
no_jsmanaged_fields!(usize, u8, u16, u32, u64);
no_jsmanaged_fields!(isize, i8, i16, i32, i64);
no_jsmanaged_fields!(Sender<T>);
@@ -308,7 +310,7 @@ no_jsmanaged_fields!(StorageType);
no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle);
no_jsmanaged_fields!(LineCapStyle, LineJoinStyle, CompositionOrBlending);
no_jsmanaged_fields!(RepetitionStyle);
-no_jsmanaged_fields!(WebGLError);
+no_jsmanaged_fields!(WebGLError, GLLimits);
no_jsmanaged_fields!(TimeProfilerChan);
no_jsmanaged_fields!(MemProfilerChan);
no_jsmanaged_fields!(PseudoElement);
diff --git a/components/script/dom/canvasrenderingcontext2d.rs b/components/script/dom/canvasrenderingcontext2d.rs
index aa5c7d9f72b..492b98f0edf 100644
--- a/components/script/dom/canvasrenderingcontext2d.rs
+++ b/components/script/dom/canvasrenderingcontext2d.rs
@@ -19,7 +19,7 @@ use dom::bindings::codegen::Bindings::ImageDataBinding::ImageDataMethods;
use dom::bindings::codegen::Bindings::WindowBinding::WindowMethods;
use dom::bindings::codegen::UnionTypes::HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D;
use dom::bindings::codegen::UnionTypes::StringOrCanvasGradientOrCanvasPattern;
-use dom::bindings::error::{Error, Fallible};
+use dom::bindings::error::{Error, Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::{JS, LayoutJS, Root};
@@ -277,7 +277,7 @@ impl CanvasRenderingContext2D {
dy: f64,
dw: Option<f64>,
dh: Option<f64>)
- -> Fallible<()> {
+ -> ErrorResult {
let result = match image {
HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D::HTMLCanvasElement(ref canvas) => {
self.draw_html_canvas_element(canvas.r(),
@@ -333,7 +333,7 @@ impl CanvasRenderingContext2D {
dy: f64,
dw: Option<f64>,
dh: Option<f64>)
- -> Fallible<()> {
+ -> ErrorResult {
// 1. Check the usability of the image argument
if !canvas.is_valid() {
return Err(Error::InvalidState);
@@ -408,7 +408,7 @@ impl CanvasRenderingContext2D {
dy: f64,
dw: f64,
dh: f64)
- -> Fallible<()> {
+ -> ErrorResult {
// Establish the source and destination rectangles
let (source_rect, dest_rect) = self.adjust_source_dest_rects(image_size,
sx,
@@ -742,7 +742,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
image: HTMLImageElementOrHTMLCanvasElementOrCanvasRenderingContext2D,
dx: f64,
dy: f64)
- -> Fallible<()> {
+ -> ErrorResult {
if !(dx.is_finite() && dy.is_finite()) {
return Ok(());
}
@@ -757,7 +757,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
dy: f64,
dw: f64,
dh: f64)
- -> Fallible<()> {
+ -> ErrorResult {
if !(dx.is_finite() && dy.is_finite() && dw.is_finite() && dh.is_finite()) {
return Ok(());
}
@@ -776,7 +776,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
dy: f64,
dw: f64,
dh: f64)
- -> Fallible<()> {
+ -> ErrorResult {
if !(sx.is_finite() && sy.is_finite() && sw.is_finite() && sh.is_finite() &&
dx.is_finite() && dy.is_finite() && dw.is_finite() && dh.is_finite()) {
return Ok(());
@@ -852,7 +852,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-arc
- fn Arc(&self, x: f64, y: f64, r: f64, start: f64, end: f64, ccw: bool) -> Fallible<()> {
+ fn Arc(&self, x: f64, y: f64, r: f64, start: f64, end: f64, ccw: bool) -> ErrorResult {
if !([x, y, r, start, end].iter().all(|x| x.is_finite())) {
return Ok(());
}
@@ -872,7 +872,7 @@ impl CanvasRenderingContext2DMethods for CanvasRenderingContext2D {
}
// https://html.spec.whatwg.org/multipage/#dom-context-2d-arcto
- fn ArcTo(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, r: f64) -> Fallible<()> {
+ fn ArcTo(&self, cp1x: f64, cp1y: f64, cp2x: f64, cp2y: f64, r: f64) -> ErrorResult {
if !([cp1x, cp1y, cp2x, cp2y, r].iter().all(|x| x.is_finite())) {
return Ok(());
}
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index ad68be7175f..723e461df30 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -94,6 +94,7 @@ use net_traits::CookieSource::NonHTTP;
use net_traits::response::HttpsState;
use net_traits::{AsyncResponseTarget, PendingAsyncLoad};
use num::ToPrimitive;
+use origin::Origin;
use script_runtime::ScriptChan;
use script_thread::{MainThreadScriptChan, MainThreadScriptMsg, Runnable};
use script_traits::UntrustedNodeAddress;
@@ -209,18 +210,22 @@ pub struct Document {
modified_elements: DOMRefCell<HashMap<JS<Element>, ElementSnapshot>>,
/// http://w3c.github.io/touch-events/#dfn-active-touch-point
active_touch_points: DOMRefCell<Vec<JS<Touch>>>,
- /// DOM-Related Navigation Timing properties:
- /// http://w3c.github.io/navigation-timing/#widl-PerformanceTiming-domLoading
+ /// Navigation Timing properties:
+ /// https://w3c.github.io/navigation-timing/#sec-PerformanceNavigationTiming
dom_loading: Cell<u64>,
dom_interactive: Cell<u64>,
dom_content_loaded_event_start: Cell<u64>,
dom_content_loaded_event_end: Cell<u64>,
dom_complete: Cell<u64>,
+ load_event_start: Cell<u64>,
+ load_event_end: Cell<u64>,
/// Vector to store CSS errors
css_errors_store: DOMRefCell<Vec<CSSError>>,
/// https://html.spec.whatwg.org/multipage/#concept-document-https-state
https_state: Cell<HttpsState>,
touchpad_pressure_phase: Cell<TouchpadPressurePhase>,
+ /// The document's origin.
+ origin: Origin,
}
#[derive(JSTraceable, HeapSizeOf)]
@@ -544,14 +549,14 @@ impl Document {
DocumentReadyState::Loading => {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserconnected
self.trigger_mozbrowser_event(MozBrowserEvent::Connected);
- update_with_current_time(&self.dom_loading);
+ update_with_current_time_ms(&self.dom_loading);
},
DocumentReadyState::Complete => {
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserloadend
self.trigger_mozbrowser_event(MozBrowserEvent::LoadEnd);
- update_with_current_time(&self.dom_complete);
+ update_with_current_time_ms(&self.dom_complete);
},
- DocumentReadyState::Interactive => update_with_current_time(&self.dom_interactive),
+ DocumentReadyState::Interactive => update_with_current_time_ms(&self.dom_interactive),
};
self.ready_state.set(state);
@@ -1447,7 +1452,7 @@ impl Document {
}
self.domcontentloaded_dispatched.set(true);
- update_with_current_time(&self.dom_content_loaded_event_start);
+ update_with_current_time_ms(&self.dom_content_loaded_event_start);
let chan = MainThreadScriptChan(self.window().main_thread_script_chan().clone()).clone();
let doctarget = Trusted::new(self.upcast::<EventTarget>(), chan);
@@ -1458,7 +1463,7 @@ impl Document {
ReflowQueryType::NoQuery,
ReflowReason::DOMContentLoaded);
- update_with_current_time(&self.dom_content_loaded_event_end);
+ update_with_current_time_ms(&self.dom_content_loaded_event_end);
}
pub fn notify_constellation_load(&self) {
@@ -1513,6 +1518,14 @@ impl Document {
self.dom_complete.get()
}
+ pub fn get_load_event_start(&self) -> u64 {
+ self.load_event_start.get()
+ }
+
+ pub fn get_load_event_end(&self) -> u64 {
+ self.load_event_end.get()
+ }
+
// https://html.spec.whatwg.org/multipage/#fire-a-focus-event
fn fire_focus_event(&self, focus_event_type: FocusEventType, node: &Node, relatedTarget: Option<&EventTarget>) {
let (event_name, does_bubble) = match focus_event_type {
@@ -1534,14 +1547,6 @@ impl Document {
/// https://html.spec.whatwg.org/multipage/#cookie-averse-document-object
fn is_cookie_averse(&self) -> bool {
- /// https://url.spec.whatwg.org/#network-scheme
- fn url_has_network_scheme(url: &Url) -> bool {
- match &*url.scheme {
- "ftp" | "http" | "https" => true,
- _ => false,
- }
- }
-
self.browsing_context.is_none() || !url_has_network_scheme(&self.url)
}
@@ -1580,6 +1585,14 @@ impl LayoutDocumentHelpers for LayoutJS<Document> {
}
}
+/// https://url.spec.whatwg.org/#network-scheme
+fn url_has_network_scheme(url: &Url) -> bool {
+ match &*url.scheme {
+ "ftp" | "http" | "https" => true,
+ _ => false,
+ }
+}
+
impl Document {
pub fn new_inherited(window: &Window,
browsing_context: Option<&BrowsingContext>,
@@ -1598,6 +1611,15 @@ impl Document {
(DocumentReadyState::Complete, true)
};
+ // Incomplete implementation of Document origin specification at
+ // https://html.spec.whatwg.org/multipage/#origin:document
+ let origin = if url_has_network_scheme(&url) {
+ Origin::new(&url)
+ } else {
+ // Default to DOM standard behaviour
+ Origin::opaque_identifier()
+ };
+
Document {
node: Node::new_document_node(),
window: JS::from_ref(window),
@@ -1658,9 +1680,12 @@ impl Document {
dom_content_loaded_event_start: Cell::new(Default::default()),
dom_content_loaded_event_end: Cell::new(Default::default()),
dom_complete: Cell::new(Default::default()),
+ load_event_start: Cell::new(Default::default()),
+ load_event_end: Cell::new(Default::default()),
css_errors_store: DOMRefCell::new(vec![]),
https_state: Cell::new(HttpsState::None),
touchpad_pressure_phase: Cell::new(TouchpadPressurePhase::BeforeClick),
+ origin: origin,
}
}
@@ -1856,9 +1881,18 @@ impl DocumentMethods for Document {
// https://html.spec.whatwg.org/multipage/#relaxing-the-same-origin-restriction
fn Domain(&self) -> DOMString {
- // TODO: This should use the effective script origin when it exists
- let origin = self.window.get_url();
- DOMString::from(origin.serialize_host().unwrap_or_else(|| "".to_owned()))
+ // Step 1.
+ if self.browsing_context().is_none() {
+ return DOMString::new();
+ }
+
+ if let Some(host) = self.origin.host() {
+ // Step 4.
+ DOMString::from(host.serialize())
+ } else {
+ // Step 3.
+ DOMString::new()
+ }
}
// https://dom.spec.whatwg.org/#dom-document-documenturi
@@ -2485,10 +2519,11 @@ impl DocumentMethods for Document {
return Ok(DOMString::new());
}
- let url = self.url();
- if !is_scheme_host_port_tuple(&url) {
+ if !self.origin.is_scheme_host_port_tuple() {
return Err(Error::Security);
}
+
+ let url = self.url();
let (tx, rx) = ipc::channel().unwrap();
let _ = self.window.resource_thread().send(GetCookiesForUrl((*url).clone(), tx, NonHTTP));
let cookies = rx.recv().unwrap();
@@ -2501,10 +2536,11 @@ impl DocumentMethods for Document {
return Ok(());
}
- let url = self.url();
- if !is_scheme_host_port_tuple(url) {
+ if !self.origin.is_scheme_host_port_tuple() {
return Err(Error::Security);
}
+
+ let url = self.url();
let _ = self.window
.resource_thread()
.send(SetCookiesForUrl((*url).clone(), String::from(cookie), NonHTTP));
@@ -2708,13 +2744,10 @@ impl DocumentMethods for Document {
}
}
-fn is_scheme_host_port_tuple(url: &Url) -> bool {
- url.host().is_some() && url.port_or_default().is_some()
-}
-
-fn update_with_current_time(marker: &Cell<u64>) {
+fn update_with_current_time_ms(marker: &Cell<u64>) {
if marker.get() == Default::default() {
- let current_time_ms = time::get_time().sec * 1000;
+ let time = time::get_time();
+ let current_time_ms = time.sec * 1000 + time.nsec as i64 / 1000000;
marker.set(current_time_ms as u64);
}
}
@@ -2744,8 +2777,15 @@ impl DocumentProgressHandler {
EventCancelable::NotCancelable);
let wintarget = window.upcast::<EventTarget>();
event.set_trusted(true);
+
+ // http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventStart
+ update_with_current_time_ms(&document.load_event_start);
+
let _ = wintarget.dispatch_event_with_target(document.upcast(), &event);
+ // http://w3c.github.io/navigation-timing/#widl-PerformanceNavigationTiming-loadEventEnd
+ update_with_current_time_ms(&document.load_event_end);
+
document.notify_constellation_load();
window.reflow(ReflowGoal::ForDisplay,
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 4e2af78f31a..e14e1af0d97 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -377,7 +377,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
},
// Others
_ => {
- match this.get_size_for_layout() {
+ match this.size_for_layout() {
0 => None,
s => Some(s as i32),
}
@@ -571,7 +571,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
// TODO option and menuitem can also have a checked state.
match self.downcast::<HTMLInputElement>() {
Some(input) => unsafe {
- input.get_checked_state_for_layout()
+ input.checked_state_for_layout()
},
None => false,
}
@@ -583,7 +583,7 @@ impl LayoutElementHelpers for LayoutJS<Element> {
// TODO progress elements can also be matched with :indeterminate
match self.downcast::<HTMLInputElement>() {
Some(input) => unsafe {
- input.get_indeterminate_state_for_layout()
+ input.indeterminate_state_for_layout()
},
None => false,
}
@@ -1489,7 +1489,7 @@ impl ElementMethods for Element {
}
/// https://w3c.github.io/DOM-Parsing/#widl-Element-innerHTML
- fn SetInnerHTML(&self, value: DOMString) -> Fallible<()> {
+ fn SetInnerHTML(&self, value: DOMString) -> ErrorResult {
let context_node = self.upcast::<Node>();
// Step 1.
let frag = try!(context_node.parse_fragment(value));
@@ -1510,7 +1510,7 @@ impl ElementMethods for Element {
}
// https://dvcs.w3.org/hg/innerhtml/raw-file/tip/index.html#widl-Element-outerHTML
- fn SetOuterHTML(&self, value: DOMString) -> Fallible<()> {
+ fn SetOuterHTML(&self, value: DOMString) -> ErrorResult {
let context_document = document_from_node(self);
let context_node = self.upcast::<Node>();
// Step 1.
diff --git a/components/script/dom/htmlbaseelement.rs b/components/script/dom/htmlbaseelement.rs
index 7f1ce7641d3..241c209c7a8 100644
--- a/components/script/dom/htmlbaseelement.rs
+++ b/components/script/dom/htmlbaseelement.rs
@@ -2,8 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use dom::attr::Attr;
+use dom::attr::{Attr, AttrValue};
use dom::bindings::codegen::Bindings::HTMLBaseElementBinding;
+use dom::bindings::codegen::Bindings::HTMLBaseElementBinding::HTMLBaseElementMethods;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
use dom::document::Document;
@@ -60,6 +61,33 @@ impl HTMLBaseElement {
}
}
+impl HTMLBaseElementMethods for HTMLBaseElement {
+ // https://html.spec.whatwg.org/multipage/#dom-base-href
+ fn Href(&self) -> DOMString {
+ let document = document_from_node(self);
+
+ // Step 1.
+ if !self.upcast::<Element>().has_attribute(&atom!("href")) {
+ return DOMString::from(document.base_url().serialize());
+ }
+
+ // Step 2.
+ let fallback_base_url = document.fallback_base_url();
+
+ // Step 3.
+ let url = self.upcast::<Element>().get_url_attribute(&atom!("href"));
+
+ // Step 4.
+ let url_record = fallback_base_url.join(&*url);
+
+ // Step 5, 6.
+ DOMString::from(url_record.ok().map_or("".to_owned(), |record| record.serialize()))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-base-href
+ make_url_setter!(SetHref, "href");
+}
+
impl VirtualMethods for HTMLBaseElement {
fn super_type(&self) -> Option<&VirtualMethods> {
Some(self.upcast::<HTMLElement>() as &VirtualMethods)
diff --git a/components/script/dom/htmlformelement.rs b/components/script/dom/htmlformelement.rs
index 70a2a7ad730..3e7421de443 100644
--- a/components/script/dom/htmlformelement.rs
+++ b/components/script/dom/htmlformelement.rs
@@ -414,7 +414,7 @@ impl HTMLFormElement {
HTMLElementTypeId::HTMLInputElement => {
let input = child.downcast::<HTMLInputElement>().unwrap();
// Step 3.2-3.7
- if let Some(datum) = input.get_form_datum(submitter) {
+ if let Some(datum) = input.form_datum(submitter) {
data_set.push(datum);
}
}
diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs
index 93fdebbc954..bea12efbfea 100644
--- a/components/script/dom/htmlhrelement.rs
+++ b/components/script/dom/htmlhrelement.rs
@@ -37,6 +37,12 @@ impl HTMLHRElement {
}
impl HTMLHRElementMethods for HTMLHRElement {
+ // https://html.spec.whatwg.org/multipage/#dom-hr-align
+ make_getter!(Align, "align");
+
+ // https://html.spec.whatwg.org/multipage/#dom-hr-align
+ make_atomic_setter!(SetAlign, "align");
+
// https://html.spec.whatwg.org/multipage/#dom-hr-color
make_getter!(Color, "color");
@@ -86,6 +92,7 @@ impl VirtualMethods for HTMLHRElement {
fn parse_plain_attribute(&self, name: &Atom, value: DOMString) -> AttrValue {
match name {
+ &atom!("align") => AttrValue::from_dimension(value),
&atom!("color") => AttrValue::from_legacy_color(value),
&atom!("width") => AttrValue::from_dimension(value),
_ => self.super_type().unwrap().parse_plain_attribute(name, value),
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index beb3134698f..7273e063e0b 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -367,7 +367,7 @@ impl MozBrowserEventDetailBuilder for HTMLIFrameElement {
}
}
-pub fn Navigate(iframe: &HTMLIFrameElement, direction: NavigationDirection) -> Fallible<()> {
+pub fn Navigate(iframe: &HTMLIFrameElement, direction: NavigationDirection) -> ErrorResult {
if iframe.Mozbrowser() {
if iframe.upcast::<Node>().is_in_doc() {
let window = window_from_node(iframe);
@@ -468,17 +468,17 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goBack
- fn GoBack(&self) -> Fallible<()> {
+ fn GoBack(&self) -> ErrorResult {
Navigate(self, NavigationDirection::Back)
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/goForward
- fn GoForward(&self) -> Fallible<()> {
+ fn GoForward(&self) -> ErrorResult {
Navigate(self, NavigationDirection::Forward)
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/reload
- fn Reload(&self, _hardReload: bool) -> Fallible<()> {
+ fn Reload(&self, _hardReload: bool) -> ErrorResult {
if self.Mozbrowser() {
if self.upcast::<Node>().is_in_doc() {
self.navigate_or_reload_child_browsing_context(None);
@@ -492,7 +492,7 @@ impl HTMLIFrameElementMethods for HTMLIFrameElement {
}
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLIFrameElement/stop
- fn Stop(&self) -> Fallible<()> {
+ fn Stop(&self) -> ErrorResult {
Err(Error::NotSupported)
}
diff --git a/components/script/dom/htmlimageelement.rs b/components/script/dom/htmlimageelement.rs
index c36bcb02651..92291600ca3 100644
--- a/components/script/dom/htmlimageelement.rs
+++ b/components/script/dom/htmlimageelement.rs
@@ -21,6 +21,7 @@ use dom::htmlelement::HTMLElement;
use dom::node::{Node, NodeDamage, document_from_node, window_from_node};
use dom::values::UNSIGNED_LONG_MAX;
use dom::virtualmethods::VirtualMethods;
+use heapsize::HeapSizeOf;
use ipc_channel::ipc;
use ipc_channel::router::ROUTER;
use net_traits::image::base::{Image, ImageMetadata};
@@ -33,17 +34,31 @@ use string_cache::Atom;
use url::Url;
use util::str::{DOMString, LengthOrPercentageOrAuto};
+#[derive(JSTraceable, HeapSizeOf)]
+#[allow(dead_code)]
+enum State {
+ Unavailable,
+ PartiallyAvailable,
+ CompletelyAvailable,
+ Broken,
+}
+#[derive(JSTraceable, HeapSizeOf)]
+struct ImageRequest {
+ state: State,
+ url: Option<Url>,
+ image: Option<Arc<Image>>,
+ metadata: Option<ImageMetadata>,
+}
#[dom_struct]
pub struct HTMLImageElement {
htmlelement: HTMLElement,
- url: DOMRefCell<Option<Url>>,
- image: DOMRefCell<Option<Arc<Image>>>,
- metadata: DOMRefCell<Option<ImageMetadata>>,
+ current_request: DOMRefCell<ImageRequest>,
+ pending_request: DOMRefCell<ImageRequest>,
}
impl HTMLImageElement {
pub fn get_url(&self) -> Option<Url>{
- self.url.borrow().clone()
+ self.current_request.borrow().url.clone()
}
}
@@ -77,8 +92,8 @@ impl Runnable for ImageResponseHandlerRunnable {
}
ImageResponse::None => (None, None, true)
};
- *element_ref.image.borrow_mut() = image;
- *element_ref.metadata.borrow_mut() = metadata;
+ element_ref.current_request.borrow_mut().image = image;
+ element_ref.current_request.borrow_mut().metadata = metadata;
// Mark the node dirty
let document = document_from_node(&*element);
@@ -104,14 +119,14 @@ impl HTMLImageElement {
let image_cache = window.image_cache_thread();
match value {
None => {
- *self.url.borrow_mut() = None;
- *self.image.borrow_mut() = None;
+ self.current_request.borrow_mut().url = None;
+ self.current_request.borrow_mut().image = None;
}
Some((src, base_url)) => {
let img_url = base_url.join(&src);
// FIXME: handle URL parse errors more gracefully.
let img_url = img_url.unwrap();
- *self.url.borrow_mut() = Some(img_url.clone());
+ self.current_request.borrow_mut().url = Some(img_url.clone());
let trusted_node = Trusted::new(self, window.networking_task_source());
let (responder_sender, responder_receiver) = ipc::channel().unwrap();
@@ -134,13 +149,21 @@ impl HTMLImageElement {
}
}
}
-
fn new_inherited(localName: Atom, prefix: Option<DOMString>, document: &Document) -> HTMLImageElement {
HTMLImageElement {
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
- url: DOMRefCell::new(None),
- image: DOMRefCell::new(None),
- metadata: DOMRefCell::new(None),
+ current_request: DOMRefCell::new(ImageRequest {
+ state: State::Unavailable,
+ url: None,
+ image: None,
+ metadata: None
+ }),
+ pending_request: DOMRefCell::new(ImageRequest {
+ state: State::Unavailable,
+ url: None,
+ image: None,
+ metadata: None
+ }),
}
}
@@ -182,12 +205,12 @@ pub trait LayoutHTMLImageElementHelpers {
impl LayoutHTMLImageElementHelpers for LayoutJS<HTMLImageElement> {
#[allow(unsafe_code)]
unsafe fn image(&self) -> Option<Arc<Image>> {
- (*self.unsafe_get()).image.borrow_for_layout().clone()
+ (*self.unsafe_get()).current_request.borrow_for_layout().image.clone()
}
#[allow(unsafe_code)]
unsafe fn image_url(&self) -> Option<Url> {
- (*self.unsafe_get()).url.borrow_for_layout().clone()
+ (*self.unsafe_get()).current_request.borrow_for_layout().url.clone()
}
#[allow(unsafe_code)]
@@ -224,6 +247,11 @@ impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-src
make_setter!(SetSrc, "src");
+ // https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin
+ make_enumerated_getter!(CrossOrigin, "crossorigin", "anonymous", ("use-credentials"));
+ // https://html.spec.whatwg.org/multipage/#dom-img-crossOrigin
+ make_setter!(SetCrossOrigin, "crossorigin");
+
// https://html.spec.whatwg.org/multipage/#dom-img-usemap
make_getter!(UseMap, "usemap");
// https://html.spec.whatwg.org/multipage/#dom-img-usemap
@@ -260,7 +288,7 @@ impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-naturalwidth
fn NaturalWidth(&self) -> u32 {
- let metadata = self.metadata.borrow();
+ let ref metadata = self.current_request.borrow().metadata;
match *metadata {
Some(ref metadata) => metadata.width,
@@ -270,7 +298,7 @@ impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-naturalheight
fn NaturalHeight(&self) -> u32 {
- let metadata = self.metadata.borrow();
+ let ref metadata = self.current_request.borrow().metadata;
match *metadata {
Some(ref metadata) => metadata.height,
@@ -280,10 +308,19 @@ impl HTMLImageElementMethods for HTMLImageElement {
// https://html.spec.whatwg.org/multipage/#dom-img-complete
fn Complete(&self) -> bool {
- let image = self.image.borrow();
+ let ref image = self.current_request.borrow().image;
image.is_some()
}
+ // https://html.spec.whatwg.org/multipage/#dom-img-currentsrc
+ fn CurrentSrc(&self) -> DOMString {
+ let ref url = self.current_request.borrow().url;
+ match *url {
+ Some(ref url) => DOMString::from(url.serialize()),
+ None => DOMString::from(""),
+ }
+ }
+
// https://html.spec.whatwg.org/multipage/#dom-img-name
make_getter!(Name, "name");
diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs
index 174a312448f..9c969ceec98 100644
--- a/components/script/dom/htmlinputelement.rs
+++ b/components/script/dom/htmlinputelement.rs
@@ -164,7 +164,7 @@ impl HTMLInputElement {
}
// https://html.spec.whatwg.org/multipage/#input-type-attr-summary
- fn get_value_mode(&self) -> ValueMode {
+ fn value_mode(&self) -> ValueMode {
match self.input_type.get() {
InputType::InputSubmit |
InputType::InputReset |
@@ -208,15 +208,15 @@ impl HTMLInputElement {
pub trait LayoutHTMLInputElementHelpers {
#[allow(unsafe_code)]
- unsafe fn get_value_for_layout(self) -> String;
+ unsafe fn value_for_layout(self) -> String;
#[allow(unsafe_code)]
- unsafe fn get_size_for_layout(self) -> u32;
+ unsafe fn size_for_layout(self) -> u32;
#[allow(unsafe_code)]
- unsafe fn get_selection_for_layout(self) -> Option<Range<isize>>;
+ unsafe fn selection_for_layout(self) -> Option<Range<isize>>;
#[allow(unsafe_code)]
- unsafe fn get_checked_state_for_layout(self) -> bool;
+ unsafe fn checked_state_for_layout(self) -> bool;
#[allow(unsafe_code)]
- unsafe fn get_indeterminate_state_for_layout(self) -> bool;
+ unsafe fn indeterminate_state_for_layout(self) -> bool;
}
#[allow(unsafe_code)]
@@ -226,7 +226,7 @@ unsafe fn get_raw_textinput_value(input: LayoutJS<HTMLInputElement>) -> DOMStrin
impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
#[allow(unsafe_code)]
- unsafe fn get_value_for_layout(self) -> String {
+ unsafe fn value_for_layout(self) -> String {
#[allow(unsafe_code)]
unsafe fn get_raw_attr_value(input: LayoutJS<HTMLInputElement>, default: &str) -> String {
let elem = input.upcast::<Element>();
@@ -245,7 +245,7 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
InputType::InputPassword => {
let text = get_raw_textinput_value(self);
if !text.is_empty() {
- // The implementation of get_selection_for_layout expects a 1:1 mapping of chars.
+ // The implementation of selection_for_layout expects a 1:1 mapping of chars.
text.chars().map(|_| '●').collect()
} else {
String::from((*self.unsafe_get()).placeholder.borrow_for_layout().clone())
@@ -254,7 +254,7 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
_ => {
let text = get_raw_textinput_value(self);
if !text.is_empty() {
- // The implementation of get_selection_for_layout expects a 1:1 mapping of chars.
+ // The implementation of selection_for_layout expects a 1:1 mapping of chars.
String::from(text)
} else {
String::from((*self.unsafe_get()).placeholder.borrow_for_layout().clone())
@@ -265,19 +265,19 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
- unsafe fn get_size_for_layout(self) -> u32 {
+ unsafe fn size_for_layout(self) -> u32 {
(*self.unsafe_get()).size.get()
}
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
- unsafe fn get_selection_for_layout(self) -> Option<Range<isize>> {
+ unsafe fn selection_for_layout(self) -> Option<Range<isize>> {
if !(*self.unsafe_get()).upcast::<Element>().focus_state() {
return None;
}
// Use the raw textinput to get the index as long as we use a 1:1 char mapping
- // in get_value_for_layout.
+ // in value_for_layout.
let raw = match (*self.unsafe_get()).input_type.get() {
InputType::InputText |
InputType::InputPassword => get_raw_textinput_value(self),
@@ -293,18 +293,37 @@ impl LayoutHTMLInputElementHelpers for LayoutJS<HTMLInputElement> {
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
- unsafe fn get_checked_state_for_layout(self) -> bool {
+ unsafe fn checked_state_for_layout(self) -> bool {
self.upcast::<Element>().get_state_for_layout().contains(IN_CHECKED_STATE)
}
#[allow(unrooted_must_root)]
#[allow(unsafe_code)]
- unsafe fn get_indeterminate_state_for_layout(self) -> bool {
+ unsafe fn indeterminate_state_for_layout(self) -> bool {
self.upcast::<Element>().get_state_for_layout().contains(IN_INDETERMINATE_STATE)
}
}
impl HTMLInputElementMethods for HTMLInputElement {
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-accept
+ make_getter!(Accept, "accept");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-accept
+ make_setter!(SetAccept, "accept");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-alt
+ make_getter!(Alt, "alt");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-alt
+ make_setter!(SetAlt, "alt");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-dirName
+ make_getter!(DirName, "dirname");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-dirName
+ make_setter!(SetDirName, "dirname");
+
// https://html.spec.whatwg.org/multipage/#dom-fe-disabled
make_bool_getter!(Disabled, "disabled");
@@ -361,7 +380,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-value
fn Value(&self) -> DOMString {
- match self.get_value_mode() {
+ match self.value_mode() {
ValueMode::Value => self.textinput.borrow().get_content(),
ValueMode::Default => {
self.upcast::<Element>()
@@ -384,7 +403,7 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#dom-input-value
fn SetValue(&self, value: DOMString) -> ErrorResult {
- match self.get_value_mode() {
+ match self.value_mode() {
ValueMode::Value => {
self.textinput.borrow_mut().set_content(value);
self.value_dirty.set(true);
@@ -458,12 +477,54 @@ impl HTMLInputElementMethods for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#attr-fs-formnovalidate
make_bool_setter!(SetFormNoValidate, "formnovalidate");
+ // https://html.spec.whatwg.org/multipage/#attr-input-max
+ make_getter!(Max, "max");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-max
+ make_setter!(SetMax, "max");
+
// https://html.spec.whatwg.org/multipage/#dom-input-maxlength
make_int_getter!(MaxLength, "maxlength", DEFAULT_MAX_LENGTH);
// https://html.spec.whatwg.org/multipage/#dom-input-maxlength
make_limited_int_setter!(SetMaxLength, "maxlength", DEFAULT_MAX_LENGTH);
+ // https://html.spec.whatwg.org/multipage/#attr-input-min
+ make_getter!(Min, "min");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-min
+ make_setter!(SetMin, "min");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-multiple
+ make_bool_getter!(Multiple, "multiple");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-multiple
+ make_bool_setter!(SetMultiple, "multiple");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-pattern
+ make_getter!(Pattern, "pattern");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-pattern
+ make_setter!(SetPattern, "pattern");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-required
+ make_bool_getter!(Required, "required");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-required
+ make_bool_setter!(SetRequired, "required");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-src
+ make_getter!(Src, "src");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-src
+ make_setter!(SetSrc, "src");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-step
+ make_getter!(Step, "step");
+
+ // https://html.spec.whatwg.org/multipage/#attr-input-step
+ make_setter!(SetStep, "step");
+
// https://html.spec.whatwg.org/multipage/#dom-input-indeterminate
fn Indeterminate(&self) -> bool {
self.upcast::<Element>().state().contains(IN_INDETERMINATE_STATE)
@@ -581,7 +642,7 @@ fn in_same_group(other: &HTMLInputElement, owner: Option<&HTMLFormElement>,
other.input_type.get() == InputType::InputRadio &&
// TODO Both a and b are in the same home subtree.
other.form_owner().r() == owner &&
- match (other.get_radio_group_name(), group) {
+ match (other.radio_group_name(), group) {
(Some(ref s1), Some(s2)) => compatibility_caseless_match_str(s1, s2) && s2 != &atom!(""),
_ => false
}
@@ -596,7 +657,7 @@ impl HTMLInputElement {
/// https://html.spec.whatwg.org/multipage/#constructing-the-form-data-set
/// Steps range from 3.1 to 3.7 which related to the HTMLInputElement
- pub fn get_form_datum(&self, submitter: Option<FormSubmitter>) -> Option<FormDatum> {
+ pub fn form_datum(&self, submitter: Option<FormSubmitter>) -> Option<FormDatum> {
// Step 3.2
let ty = self.type_();
// Step 3.4
@@ -632,7 +693,7 @@ impl HTMLInputElement {
}
// https://html.spec.whatwg.org/multipage/#radio-button-group
- fn get_radio_group_name(&self) -> Option<Atom> {
+ fn radio_group_name(&self) -> Option<Atom> {
//TODO: determine form owner
self.upcast::<Element>()
.get_attribute(&ns!(), &atom!("name"))
@@ -648,19 +709,15 @@ impl HTMLInputElement {
if self.input_type.get() == InputType::InputRadio && checked {
broadcast_radio_checked(self,
- self.get_radio_group_name().as_ref());
+ self.radio_group_name().as_ref());
}
self.upcast::<Node>().dirty(NodeDamage::OtherNodeDamage);
//TODO: dispatch change event
}
- pub fn get_indeterminate_state(&self) -> bool {
- self.Indeterminate()
- }
-
// https://html.spec.whatwg.org/multipage/#concept-fe-mutable
- fn mutable(&self) -> bool {
+ fn is_mutable(&self) -> bool {
// https://html.spec.whatwg.org/multipage/#the-input-element:concept-fe-mutable
// https://html.spec.whatwg.org/multipage/#the-readonly-attribute:concept-fe-mutable
!(self.upcast::<Element>().disabled_state() || self.ReadOnly())
@@ -740,9 +797,9 @@ impl VirtualMethods for HTMLInputElement {
};
// https://html.spec.whatwg.org/multipage/#input-type-change
- let (old_value_mode, old_idl_value) = (self.get_value_mode(), self.Value());
+ let (old_value_mode, old_idl_value) = (self.value_mode(), self.Value());
self.input_type.set(new_type);
- let new_value_mode = self.get_value_mode();
+ let new_value_mode = self.value_mode();
match (&old_value_mode, old_idl_value.is_empty(), new_value_mode) {
@@ -774,7 +831,7 @@ impl VirtualMethods for HTMLInputElement {
// Step 5
if new_type == InputType::InputRadio {
self.radio_group_updated(
- self.get_radio_group_name().as_ref());
+ self.radio_group_name().as_ref());
}
// TODO: Step 6 - value sanitization
@@ -783,7 +840,7 @@ impl VirtualMethods for HTMLInputElement {
if self.input_type.get() == InputType::InputRadio {
broadcast_radio_checked(
self,
- self.get_radio_group_name().as_ref());
+ self.radio_group_name().as_ref());
}
self.input_type.set(InputType::InputText);
}
@@ -916,7 +973,7 @@ impl Activatable for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#checkbox-state-%28type=checkbox%29:activation-behaviour-2
// https://html.spec.whatwg.org/multipage/#radio-button-state-%28type=radio%29:activation-behaviour-2
InputType::InputSubmit | InputType::InputReset
- | InputType::InputCheckbox | InputType::InputRadio => self.mutable(),
+ | InputType::InputCheckbox | InputType::InputRadio => self.is_mutable(),
_ => false
}
}
@@ -927,7 +984,7 @@ impl Activatable for HTMLInputElement {
let mut cache = self.activation_state.borrow_mut();
let ty = self.input_type.get();
cache.old_type = ty;
- cache.was_mutable = self.mutable();
+ cache.was_mutable = self.is_mutable();
if cache.was_mutable {
match ty {
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior
@@ -952,7 +1009,7 @@ impl Activatable for HTMLInputElement {
let owner = self.form_owner();
let doc = document_from_node(self);
let doc_node = doc.upcast::<Node>();
- let group = self.get_radio_group_name();;
+ let group = self.radio_group_name();;
// Safe since we only manipulate the DOM tree after finding an element
let checked_member = doc_node.query_selector_iter(DOMString::from("input[type=radio]"))
@@ -998,16 +1055,12 @@ impl Activatable for HTMLInputElement {
InputType::InputRadio => {
// We want to restore state only if the element had been changed in the first place
if cache.was_mutable {
- let name = self.get_radio_group_name();
match cache.checked_radio.r() {
Some(o) => {
// Avoiding iterating through the whole tree here, instead
// we can check if the conditions for radio group siblings apply
- if name == o.get_radio_group_name() && // TODO should be compatibility caseless
- self.form_owner() == o.form_owner() &&
- // TODO Both a and b are in the same home subtree
- o.input_type.get() == InputType::InputRadio {
- o.SetChecked(true);
+ if in_same_group(&o, self.form_owner().r(), self.radio_group_name().as_ref()) {
+ o.SetChecked(true);
} else {
self.SetChecked(false);
}
@@ -1024,8 +1077,8 @@ impl Activatable for HTMLInputElement {
// https://html.spec.whatwg.org/multipage/#run-post-click-activation-steps
fn activation_behavior(&self, _event: &Event, _target: &EventTarget) {
let ty = self.input_type.get();
- if self.activation_state.borrow().old_type != ty {
- // Type changed, abandon ship
+ if self.activation_state.borrow().old_type != ty || !self.is_mutable() {
+ // Type changed or input is immutable, abandon ship
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=27414
return;
}
@@ -1033,34 +1086,31 @@ impl Activatable for HTMLInputElement {
InputType::InputSubmit => {
// https://html.spec.whatwg.org/multipage/#submit-button-state-(type=submit):activation-behavior
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
- if self.mutable() /* and document owner is fully active */ {
- self.form_owner().map(|o| {
- o.submit(SubmittedFrom::NotFromFormSubmitMethod,
- FormSubmitter::InputElement(self.clone()))
- });
- }
+ // Check if document owner is fully active
+ self.form_owner().map(|o| {
+ o.submit(SubmittedFrom::NotFromFormSubmitMethod,
+ FormSubmitter::InputElement(self.clone()))
+ });
},
InputType::InputReset => {
// https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset):activation-behavior
// FIXME (Manishearth): support document owners (needs ability to get parent browsing context)
- if self.mutable() /* and document owner is fully active */ {
- self.form_owner().map(|o| {
- o.reset(ResetFrom::NotFromFormResetMethod)
- });
- }
+ // Check if document owner is fully active
+ self.form_owner().map(|o| {
+ o.reset(ResetFrom::NotFromFormResetMethod)
+ });
},
InputType::InputCheckbox | InputType::InputRadio => {
// https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox):activation-behavior
// https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio):activation-behavior
- if self.mutable() {
- let target = self.upcast::<EventTarget>();
- target.fire_event("input",
- EventBubbles::Bubbles,
- EventCancelable::NotCancelable);
- target.fire_event("change",
- EventBubbles::Bubbles,
- EventCancelable::NotCancelable);
- }
+ // Check if document owner is fully active
+ let target = self.upcast::<EventTarget>();
+ target.fire_event("input",
+ EventBubbles::Bubbles,
+ EventCancelable::NotCancelable);
+ target.fire_event("change",
+ EventBubbles::Bubbles,
+ EventCancelable::NotCancelable);
},
_ => ()
}
diff --git a/components/script/dom/htmltableelement.rs b/components/script/dom/htmltableelement.rs
index ab611716b90..4ea908675b1 100644
--- a/components/script/dom/htmltableelement.rs
+++ b/components/script/dom/htmltableelement.rs
@@ -7,13 +7,15 @@ use dom::attr::{Attr, AttrValue};
use dom::bindings::codegen::Bindings::HTMLTableElementBinding;
use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
+use dom::bindings::error::{Error, ErrorResult};
use dom::bindings::inheritance::Castable;
-use dom::bindings::js::{JS, LayoutJS, Root, RootedReference};
+use dom::bindings::js::{JS, LayoutJS, MutNullableHeap, Root, RootedReference};
use dom::document::Document;
use dom::element::{AttributeMutation, Element, RawLayoutElementHelpers};
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
use dom::htmlelement::HTMLElement;
use dom::htmltablecaptionelement::HTMLTableCaptionElement;
+use dom::htmltablecolelement::HTMLTableColElement;
use dom::htmltablerowelement::HTMLTableRowElement;
use dom::htmltablesectionelement::HTMLTableSectionElement;
use dom::node::{Node, document_from_node, window_from_node};
@@ -28,6 +30,7 @@ pub struct HTMLTableElement {
htmlelement: HTMLElement,
border: Cell<Option<u32>>,
cellspacing: Cell<Option<u32>>,
+ tbodies: MutNullableHeap<JS<HTMLCollection>>,
}
impl HTMLTableElement {
@@ -37,6 +40,7 @@ impl HTMLTableElement {
htmlelement: HTMLElement::new_inherited(localName, prefix, document),
border: Cell::new(None),
cellspacing: Cell::new(None),
+ tbodies: Default::default(),
}
}
@@ -50,6 +54,70 @@ impl HTMLTableElement {
pub fn get_border(&self) -> Option<u32> {
self.border.get()
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-thead
+ // https://html.spec.whatwg.org/multipage/#dom-table-tfoot
+ fn get_first_section_of_type(&self, atom: &Atom) -> Option<Root<HTMLTableSectionElement>> {
+ self.upcast::<Node>()
+ .child_elements()
+ .find(|n| n.is::<HTMLTableSectionElement>() && n.local_name() == atom)
+ .and_then(|n| n.downcast().map(Root::from_ref))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-thead
+ // https://html.spec.whatwg.org/multipage/#dom-table-tfoot
+ fn set_first_section_of_type<P>(&self,
+ atom: &Atom,
+ section: Option<&HTMLTableSectionElement>,
+ reference_predicate: P)
+ -> ErrorResult
+ where P: FnMut(&Root<Element>) -> bool {
+ if let Some(e) = section {
+ if e.upcast::<Element>().local_name() != atom {
+ return Err(Error::HierarchyRequest)
+ }
+ }
+
+ self.delete_first_section_of_type(atom);
+
+ let node = self.upcast::<Node>();
+
+ if let Some(section) = section {
+ let reference_element = node.child_elements().find(reference_predicate);
+ let reference_node = reference_element.r().map(|e| e.upcast());
+
+ try!(node.InsertBefore(section.upcast(), reference_node));
+ }
+
+ Ok(())
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-createthead
+ // https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
+ fn create_section_of_type(&self, atom: &Atom) -> Root<HTMLTableSectionElement> {
+ if let Some(section) = self.get_first_section_of_type(atom) {
+ return section
+ }
+
+ let section = HTMLTableSectionElement::new(atom.clone(),
+ None,
+ document_from_node(self).r());
+ match atom {
+ &atom!("thead") => self.SetTHead(Some(&section)),
+ &atom!("tfoot") => self.SetTFoot(Some(&section)),
+ _ => unreachable!("unexpected section type")
+ }.expect("unexpected section type");
+
+ section
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletethead
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot
+ fn delete_first_section_of_type(&self, atom: &Atom) {
+ if let Some(thead) = self.get_first_section_of_type(atom) {
+ thead.upcast::<Node>().remove_self();
+ }
+ }
}
impl HTMLTableElementMethods for HTMLTableElement {
@@ -119,6 +187,83 @@ impl HTMLTableElementMethods for HTMLTableElement {
}
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-thead
+ fn GetTHead(&self) -> Option<Root<HTMLTableSectionElement>> {
+ self.get_first_section_of_type(&atom!("thead"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-thead
+ fn SetTHead(&self, thead: Option<&HTMLTableSectionElement>) -> ErrorResult {
+ self.set_first_section_of_type(&atom!("thead"), thead, |n| {
+ !n.is::<HTMLTableCaptionElement>() && !n.is::<HTMLTableColElement>()
+ })
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-createthead
+ fn CreateTHead(&self) -> Root<HTMLTableSectionElement> {
+ self.create_section_of_type(&atom!("thead"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletethead
+ fn DeleteTHead(&self) {
+ self.delete_first_section_of_type(&atom!("thead"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-tfoot
+ fn GetTFoot(&self) -> Option<Root<HTMLTableSectionElement>> {
+ self.get_first_section_of_type(&atom!("tfoot"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-tfoot
+ fn SetTFoot(&self, tfoot: Option<&HTMLTableSectionElement>) -> ErrorResult {
+ self.set_first_section_of_type(&atom!("tfoot"), tfoot, |n| {
+ if n.is::<HTMLTableCaptionElement>() || n.is::<HTMLTableColElement>() {
+ return false;
+ }
+
+ if n.is::<HTMLTableSectionElement>() {
+ let name = n.local_name();
+ if name == &atom!("thead") || name == &atom!("tbody") {
+ return false;
+ }
+
+ }
+
+ true
+ })
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-createtfoot
+ fn CreateTFoot(&self) -> Root<HTMLTableSectionElement> {
+ self.create_section_of_type(&atom!("tfoot"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-deletetfoot
+ fn DeleteTFoot(&self) {
+ self.delete_first_section_of_type(&atom!("tfoot"))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-table-tbodies
+ fn TBodies(&self) -> Root<HTMLCollection> {
+ #[derive(JSTraceable)]
+ struct TBodiesFilter;
+ impl CollectionFilter for TBodiesFilter {
+ fn filter(&self, elem: &Element, root: &Node) -> bool {
+ elem.is::<HTMLTableSectionElement>()
+ && elem.local_name() == &atom!("tbody")
+ && elem.upcast::<Node>().GetParentNode().r() == Some(root)
+ }
+ }
+
+ self.tbodies.or_init(|| {
+ let window = window_from_node(self);
+ let filter = box TBodiesFilter;
+ HTMLCollection::create(window.r(), self.upcast(), filter)
+ })
+ }
+
+
// https://html.spec.whatwg.org/multipage/#dom-table-createtbody
fn CreateTBody(&self) -> Root<HTMLTableSectionElement> {
let tbody = HTMLTableSectionElement::new(atom!("tbody"),
diff --git a/components/script/dom/htmltablerowelement.rs b/components/script/dom/htmltablerowelement.rs
index be0a9c9f5fb..bb83e00b0db 100644
--- a/components/script/dom/htmltablerowelement.rs
+++ b/components/script/dom/htmltablerowelement.rs
@@ -4,7 +4,9 @@
use cssparser::RGBA;
use dom::attr::AttrValue;
+use dom::bindings::codegen::Bindings::HTMLTableElementBinding::HTMLTableElementMethods;
use dom::bindings::codegen::Bindings::HTMLTableRowElementBinding::{self, HTMLTableRowElementMethods};
+use dom::bindings::codegen::Bindings::HTMLTableSectionElementBinding::HTMLTableSectionElementMethods;
use dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use dom::bindings::error::{ErrorResult, Fallible};
use dom::bindings::inheritance::Castable;
@@ -14,7 +16,9 @@ use dom::element::{Element, RawLayoutElementHelpers};
use dom::htmlcollection::{CollectionFilter, HTMLCollection};
use dom::htmlelement::HTMLElement;
use dom::htmltabledatacellelement::HTMLTableDataCellElement;
+use dom::htmltableelement::HTMLTableElement;
use dom::htmltableheadercellelement::HTMLTableHeaderCellElement;
+use dom::htmltablesectionelement::HTMLTableSectionElement;
use dom::node::{Node, window_from_node};
use dom::virtualmethods::VirtualMethods;
use string_cache::Atom;
@@ -52,6 +56,14 @@ impl HTMLTableRowElement {
document,
HTMLTableRowElementBinding::Wrap)
}
+
+ /// Determine the index for this `HTMLTableRowElement` within the given
+ /// `HTMLCollection`. Returns `-1` if not found within collection.
+ fn row_index(&self, collection: Root<HTMLCollection>) -> i32 {
+ collection.elements_iter()
+ .position(|elem| (&elem as &Element) == self.upcast())
+ .map_or(-1, |i| i as i32)
+ }
}
impl HTMLTableRowElementMethods for HTMLTableRowElement {
@@ -87,6 +99,42 @@ impl HTMLTableRowElementMethods for HTMLTableRowElement {
|| self.Cells(),
|n| n.is::<HTMLTableDataCellElement>())
}
+
+ // https://html.spec.whatwg.org/multipage/#dom-tr-rowindex
+ fn RowIndex(&self) -> i32 {
+ let parent = match self.upcast::<Node>().GetParentNode() {
+ Some(parent) => parent,
+ None => return -1,
+ };
+ if let Some(table) = parent.downcast::<HTMLTableElement>() {
+ return self.row_index(table.Rows());
+ }
+ if !parent.is::<HTMLTableSectionElement>() {
+ return -1;
+ }
+ let grandparent = match parent.upcast::<Node>().GetParentNode() {
+ Some(parent) => parent,
+ None => return -1,
+ };
+ grandparent.downcast::<HTMLTableElement>()
+ .map_or(-1, |table| self.row_index(table.Rows()))
+ }
+
+ // https://html.spec.whatwg.org/multipage/#dom-tr-sectionrowindex
+ fn SectionRowIndex(&self) -> i32 {
+ let parent = match self.upcast::<Node>().GetParentNode() {
+ Some(parent) => parent,
+ None => return -1,
+ };
+ let collection = if let Some(table) = parent.downcast::<HTMLTableElement>() {
+ table.Rows()
+ } else if let Some(table_section) = parent.downcast::<HTMLTableSectionElement>() {
+ table_section.Rows()
+ } else {
+ return -1;
+ };
+ self.row_index(collection)
+ }
}
pub trait HTMLTableRowElementLayoutHelpers {
diff --git a/components/script/dom/performancetiming.rs b/components/script/dom/performancetiming.rs
index c9f2458de3e..02da92f3b89 100644
--- a/components/script/dom/performancetiming.rs
+++ b/components/script/dom/performancetiming.rs
@@ -76,6 +76,16 @@ impl PerformanceTimingMethods for PerformanceTiming {
fn DomComplete(&self) -> u64 {
self.document.get_dom_complete()
}
+
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-loadEventStart
+ fn LoadEventStart(&self) -> u64 {
+ self.document.get_load_event_start()
+ }
+
+ // https://w3c.github.io/navigation-timing/#widl-PerformanceTiming-loadEventEnd
+ fn LoadEventEnd(&self) -> u64 {
+ self.document.get_load_event_end()
+ }
}
diff --git a/components/script/dom/webglprogram.rs b/components/script/dom/webglprogram.rs
index 996e6eb4cee..d288e9422c4 100644
--- a/components/script/dom/webglprogram.rs
+++ b/components/script/dom/webglprogram.rs
@@ -167,6 +167,17 @@ impl WebGLProgram {
WebGLActiveInfo::new(self.global().r(), size, ty, DOMString::from(name)))
}
+ /// glGetActiveAttrib
+ pub fn get_active_attrib(&self, index: u32) -> WebGLResult<Root<WebGLActiveInfo>> {
+ let (sender, receiver) = ipc::channel().unwrap();
+ self.renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::GetActiveAttrib(self.id, index, sender)))
+ .unwrap();
+
+ receiver.recv().unwrap().map(|(size, ty, name)|
+ WebGLActiveInfo::new(self.global().r(), size, ty, DOMString::from(name)))
+ }
+
/// glGetAttribLocation
pub fn get_attrib_location(&self, name: DOMString) -> WebGLResult<Option<i32>> {
if name.len() > MAX_UNIFORM_AND_ATTRIBUTE_LEN {
diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs
index 920fd91bbad..4c6996cbb90 100644
--- a/components/script/dom/webglrenderingcontext.rs
+++ b/components/script/dom/webglrenderingcontext.rs
@@ -31,7 +31,7 @@ use js::jsapi::{JSContext, JSObject, RootedValue};
use js::jsval::{BooleanValue, DoubleValue, Int32Value, JSVal, NullValue, UndefinedValue};
use net_traits::image::base::PixelFormat;
use net_traits::image_cache_thread::ImageResponse;
-use offscreen_gl_context::GLContextAttributes;
+use offscreen_gl_context::{GLContextAttributes, GLLimits};
use script_traits::ScriptMsg as ConstellationMsg;
use std::cell::Cell;
use util::str::DOMString;
@@ -71,6 +71,8 @@ pub struct WebGLRenderingContext {
reflector_: Reflector,
#[ignore_heap_size_of = "Defined in ipc-channel"]
ipc_renderer: IpcSender<CanvasMsg>,
+ #[ignore_heap_size_of = "Defined in offscreen_gl_context"]
+ limits: GLLimits,
canvas: JS<HTMLCanvasElement>,
#[ignore_heap_size_of = "Defined in webrender_traits"]
last_error: Cell<Option<WebGLError>>,
@@ -95,10 +97,11 @@ impl WebGLRenderingContext {
.unwrap();
let result = receiver.recv().unwrap();
- result.map(|ipc_renderer| {
+ result.map(|(ipc_renderer, context_limits)| {
WebGLRenderingContext {
reflector_: Reflector::new(),
ipc_renderer: ipc_renderer,
+ limits: context_limits,
canvas: JS::from_ref(canvas),
last_error: Cell::new(None),
texture_unpacking_settings: Cell::new(CONVERT_COLORSPACE),
@@ -139,6 +142,9 @@ impl WebGLRenderingContext {
}
pub fn webgl_error(&self, err: WebGLError) {
+ // TODO(emilio): Add useful debug messages to this
+ warn!("WebGL error: {:?}, previous error was {:?}", err, self.last_error.get());
+
// If an error has been detected no further errors must be
// recorded until `getError` has been called
if self.last_error.get().is_none() {
@@ -155,7 +161,7 @@ impl WebGLRenderingContext {
if let Some(texture) = texture {
handle_potential_webgl_error!(self, texture.tex_parameter(target, name, value));
} else {
- return self.webgl_error(InvalidOperation);
+ self.webgl_error(InvalidOperation)
}
}
@@ -164,6 +170,10 @@ impl WebGLRenderingContext {
}
fn vertex_attrib(&self, indx: u32, x: f32, y: f32, z: f32, w: f32) {
+ if indx > self.limits.max_vertex_attribs {
+ return self.webgl_error(InvalidValue);
+ }
+
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::VertexAttrib(indx, x, y, z, w)))
.unwrap();
@@ -680,6 +690,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9
fn CreateShader(&self, shader_type: u32) -> Option<Root<WebGLShader>> {
+ match shader_type {
+ constants::VERTEX_SHADER | constants::FRAGMENT_SHADER => {},
+ _ => {
+ self.webgl_error(InvalidEnum);
+ return None;
+ }
+ }
WebGLShader::maybe_new(self.global().r(), self.ipc_renderer.clone(), shader_type)
}
@@ -737,13 +754,13 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
if first < 0 || count < 0 {
- self.webgl_error(InvalidValue);
- } else {
- self.ipc_renderer
- .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count)))
- .unwrap();
- self.mark_as_dirty();
+ return self.webgl_error(InvalidValue);
}
+
+ self.ipc_renderer
+ .send(CanvasMsg::WebGL(WebGLCommand::DrawArrays(mode, first, count)))
+ .unwrap();
+ self.mark_as_dirty();
},
_ => self.webgl_error(InvalidEnum),
}
@@ -790,6 +807,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn EnableVertexAttribArray(&self, attrib_id: u32) {
+ if attrib_id > self.limits.max_vertex_attribs {
+ return self.webgl_error(InvalidValue);
+ }
+
self.ipc_renderer
.send(CanvasMsg::WebGL(WebGLCommand::EnableVertexAttribArray(attrib_id)))
.unwrap()
@@ -807,6 +828,17 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
}
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
+ fn GetActiveAttrib(&self, program: Option<&WebGLProgram>, index: u32) -> Option<Root<WebGLActiveInfo>> {
+ program.and_then(|p| match p.get_active_attrib(index) {
+ Ok(ret) => Some(ret),
+ Err(error) => {
+ self.webgl_error(error);
+ None
+ },
+ })
+ }
+
+ // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn GetAttribLocation(&self, program: Option<&WebGLProgram>, name: DOMString) -> i32 {
if let Some(program) = program {
handle_potential_webgl_error!(self, program.get_attrib_location(name), None).unwrap_or(-1)
@@ -1188,7 +1220,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
self.vertex_attrib(indx, x, 0f32, 0f32, 1f32)
}
- #[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttrib1fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) {
@@ -1206,7 +1237,6 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
self.vertex_attrib(indx, x, y, 0f32, 1f32)
}
- #[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttrib2fv(&self, _cx: *mut JSContext, indx: u32, data: *mut JSObject) {
if let Some(data_vec) = array_buffer_view_to_vec_checked::<f32>(data) {
@@ -1257,6 +1287,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext {
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10
fn VertexAttribPointer(&self, attrib_id: u32, size: i32, data_type: u32,
normalized: bool, stride: i32, offset: i64) {
+ if attrib_id > self.limits.max_vertex_attribs {
+ return self.webgl_error(InvalidValue);
+ }
+
if let constants::FLOAT = data_type {
let msg = CanvasMsg::WebGL(
WebGLCommand::VertexAttribPointer2f(attrib_id, size, normalized, stride, offset as u32));
diff --git a/components/script/dom/webglshader.rs b/components/script/dom/webglshader.rs
index 804dc3cdcf8..495417065d7 100644
--- a/components/script/dom/webglshader.rs
+++ b/components/script/dom/webglshader.rs
@@ -101,6 +101,7 @@ impl WebGLShader {
&BuiltInResources::default()).unwrap();
match validator.compile_and_translate(&[source]) {
Ok(translated_source) => {
+ debug!("Shader translated: {}", translated_source);
// NOTE: At this point we should be pretty sure that the compilation in the paint thread
// will succeed.
// It could be interesting to retrieve the info log from the paint thread though
diff --git a/components/script/dom/webidls/CSSStyleDeclaration.webidl b/components/script/dom/webidls/CSSStyleDeclaration.webidl
index dba69a515b0..10cf77ccc83 100644
--- a/components/script/dom/webidls/CSSStyleDeclaration.webidl
+++ b/components/script/dom/webidls/CSSStyleDeclaration.webidl
@@ -310,4 +310,5 @@ partial interface CSSStyleDeclaration {
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString flexDirection;
[SetterThrows, TreatNullAs=EmptyString] attribute DOMString flex-direction;
+ [SetterThrows, TreatNullAs=EmptyString] attribute DOMString order;
};
diff --git a/components/script/dom/webidls/HTMLBaseElement.webidl b/components/script/dom/webidls/HTMLBaseElement.webidl
index 5c59c62f9be..549a6df1004 100644
--- a/components/script/dom/webidls/HTMLBaseElement.webidl
+++ b/components/script/dom/webidls/HTMLBaseElement.webidl
@@ -5,6 +5,6 @@
// https://html.spec.whatwg.org/multipage/#htmlbaseelement
interface HTMLBaseElement : HTMLElement {
- // attribute DOMString href;
- // attribute DOMString target;
+ attribute DOMString href;
+// attribute DOMString target;
};
diff --git a/components/script/dom/webidls/HTMLHRElement.webidl b/components/script/dom/webidls/HTMLHRElement.webidl
index f203527b2bf..e3ba6113748 100644
--- a/components/script/dom/webidls/HTMLHRElement.webidl
+++ b/components/script/dom/webidls/HTMLHRElement.webidl
@@ -10,7 +10,7 @@ interface HTMLHRElement : HTMLElement {
// https://html.spec.whatwg.org/multipage/#HTMLHRElement-partial
partial interface HTMLHRElement {
- // attribute DOMString align;
+ attribute DOMString align;
attribute DOMString color;
// attribute boolean noShade;
// attribute DOMString size;
diff --git a/components/script/dom/webidls/HTMLImageElement.webidl b/components/script/dom/webidls/HTMLImageElement.webidl
index 34cd6f5d645..69bd2f7d4c1 100644
--- a/components/script/dom/webidls/HTMLImageElement.webidl
+++ b/components/script/dom/webidls/HTMLImageElement.webidl
@@ -9,7 +9,7 @@ interface HTMLImageElement : HTMLElement {
attribute DOMString alt;
attribute DOMString src;
// attribute DOMString srcset;
- // attribute DOMString crossOrigin;
+ attribute DOMString crossOrigin;
attribute DOMString useMap;
attribute boolean isMap;
attribute unsigned long width;
@@ -17,7 +17,7 @@ interface HTMLImageElement : HTMLElement {
readonly attribute unsigned long naturalWidth;
readonly attribute unsigned long naturalHeight;
readonly attribute boolean complete;
-
+ readonly attribute DOMString currentSrc;
// also has obsolete members
};
@@ -32,3 +32,9 @@ partial interface HTMLImageElement {
[TreatNullAs=EmptyString] attribute DOMString border;
};
+
+// https://drafts.csswg.org/cssom-view/#extensions-to-the-htmlimageelement-interface
+partial interface HTMLImageElement {
+ // readonly attribute long x;
+ // readonly attribute long y;
+};
diff --git a/components/script/dom/webidls/HTMLInputElement.webidl b/components/script/dom/webidls/HTMLInputElement.webidl
index 2e1c6215f2b..66907c5cd23 100644
--- a/components/script/dom/webidls/HTMLInputElement.webidl
+++ b/components/script/dom/webidls/HTMLInputElement.webidl
@@ -5,13 +5,13 @@
// https://html.spec.whatwg.org/multipage/#htmlinputelement
interface HTMLInputElement : HTMLElement {
- // attribute DOMString accept;
- // attribute DOMString alt;
+ attribute DOMString accept;
+ attribute DOMString alt;
// attribute DOMString autocomplete;
// attribute boolean autofocus;
attribute boolean defaultChecked;
attribute boolean checked;
- // attribute DOMString dirName;
+ attribute DOMString dirName;
attribute boolean disabled;
readonly attribute HTMLFormElement? form;
//readonly attribute FileList? files;
@@ -24,21 +24,21 @@ interface HTMLInputElement : HTMLElement {
attribute boolean indeterminate;
// attribute DOMString inputMode;
//readonly attribute HTMLElement? list;
- // attribute DOMString max;
+ attribute DOMString max;
[SetterThrows]
attribute long maxLength;
- // attribute DOMString min;
+ attribute DOMString min;
// attribute long minLength;
- // attribute boolean multiple;
+ attribute boolean multiple;
attribute DOMString name;
- // attribute DOMString pattern;
+ attribute DOMString pattern;
attribute DOMString placeholder;
attribute boolean readOnly;
- // attribute boolean required;
+ attribute boolean required;
[SetterThrows]
attribute unsigned long size;
- // attribute DOMString src;
- // attribute DOMString step;
+ attribute DOMString src;
+ attribute DOMString step;
attribute DOMString type;
attribute DOMString defaultValue;
[TreatNullAs=EmptyString, SetterThrows]
diff --git a/components/script/dom/webidls/HTMLTableElement.webidl b/components/script/dom/webidls/HTMLTableElement.webidl
index 2697f4c1e93..af95685b5b5 100644
--- a/components/script/dom/webidls/HTMLTableElement.webidl
+++ b/components/script/dom/webidls/HTMLTableElement.webidl
@@ -8,13 +8,15 @@ interface HTMLTableElement : HTMLElement {
attribute HTMLTableCaptionElement? caption;
HTMLElement createCaption();
void deleteCaption();
- // attribute HTMLTableSectionElement? tHead;
- //HTMLElement createTHead();
- //void deleteTHead();
- // attribute HTMLTableSectionElement? tFoot;
- //HTMLElement createTFoot();
- //void deleteTFoot();
- //readonly attribute HTMLCollection tBodies;
+ [SetterThrows]
+ attribute HTMLTableSectionElement? tHead;
+ HTMLTableSectionElement createTHead();
+ void deleteTHead();
+ [SetterThrows]
+ attribute HTMLTableSectionElement? tFoot;
+ HTMLTableSectionElement createTFoot();
+ void deleteTFoot();
+ readonly attribute HTMLCollection tBodies;
HTMLTableSectionElement createTBody();
readonly attribute HTMLCollection rows;
//HTMLElement insertRow(optional long index = -1);
diff --git a/components/script/dom/webidls/HTMLTableRowElement.webidl b/components/script/dom/webidls/HTMLTableRowElement.webidl
index 66538630c9d..fe6c93e6be5 100644
--- a/components/script/dom/webidls/HTMLTableRowElement.webidl
+++ b/components/script/dom/webidls/HTMLTableRowElement.webidl
@@ -5,8 +5,8 @@
// https://html.spec.whatwg.org/multipage/#htmltablerowelement
interface HTMLTableRowElement : HTMLElement {
- //readonly attribute long rowIndex;
- //readonly attribute long sectionRowIndex;
+ readonly attribute long rowIndex;
+ readonly attribute long sectionRowIndex;
readonly attribute HTMLCollection cells;
[Throws]
HTMLElement insertCell(optional long index = -1);
diff --git a/components/script/dom/webidls/PerformanceTiming.webidl b/components/script/dom/webidls/PerformanceTiming.webidl
index a016f2b1616..7a2fdaebec0 100644
--- a/components/script/dom/webidls/PerformanceTiming.webidl
+++ b/components/script/dom/webidls/PerformanceTiming.webidl
@@ -27,6 +27,6 @@ interface PerformanceTiming {
readonly attribute unsigned long long domContentLoadedEventStart;
readonly attribute unsigned long long domContentLoadedEventEnd;
readonly attribute unsigned long long domComplete;
- /* readonly attribute unsigned long long loadEventStart;
- readonly attribute unsigned long long loadEventEnd; */
+ readonly attribute unsigned long long loadEventStart;
+ readonly attribute unsigned long long loadEventEnd;
};
diff --git a/components/script/dom/webidls/WebGLRenderingContext.webidl b/components/script/dom/webidls/WebGLRenderingContext.webidl
index 7be7a82d41e..d2c93d9a3c5 100644
--- a/components/script/dom/webidls/WebGLRenderingContext.webidl
+++ b/components/script/dom/webidls/WebGLRenderingContext.webidl
@@ -567,7 +567,7 @@ interface WebGLRenderingContextBase
void generateMipmap(GLenum target);
- //WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, GLuint index);
+ WebGLActiveInfo? getActiveAttrib(WebGLProgram? program, GLuint index);
WebGLActiveInfo? getActiveUniform(WebGLProgram? program, GLuint index);
//sequence<WebGLShader>? getAttachedShaders(WebGLProgram? program);
diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs
index 59ec9db7b4b..e92c7abbcab 100644
--- a/components/script/dom/websocket.rs
+++ b/components/script/dom/websocket.rs
@@ -10,7 +10,7 @@ use dom::bindings::codegen::Bindings::WebSocketBinding;
use dom::bindings::codegen::Bindings::WebSocketBinding::{BinaryType, WebSocketMethods};
use dom::bindings::codegen::UnionTypes::StringOrStringSequence;
use dom::bindings::conversions::{ToJSValConvertible};
-use dom::bindings::error::{Error, Fallible};
+use dom::bindings::error::{Error, Fallible, ErrorResult};
use dom::bindings::global::GlobalRef;
use dom::bindings::inheritance::Castable;
use dom::bindings::js::Root;
@@ -385,7 +385,7 @@ impl WebSocketMethods for WebSocket {
}
// https://html.spec.whatwg.org/multipage/#dom-websocket-send
- fn Send(&self, data: USVString) -> Fallible<()> {
+ fn Send(&self, data: USVString) -> ErrorResult {
let data_byte_len = data.0.as_bytes().len() as u64;
let send_data = try!(self.send_impl(data_byte_len));
@@ -400,7 +400,7 @@ impl WebSocketMethods for WebSocket {
}
// https://html.spec.whatwg.org/multipage/#dom-websocket-send
- fn Send_(&self, blob: &Blob) -> Fallible<()> {
+ fn Send_(&self, blob: &Blob) -> ErrorResult {
/* As per https://html.spec.whatwg.org/multipage/#websocket
the buffered amount needs to be clamped to u32, even though Blob.Size() is u64
@@ -420,7 +420,7 @@ impl WebSocketMethods for WebSocket {
}
// https://html.spec.whatwg.org/multipage/#dom-websocket-close
- fn Close(&self, code: Option<u16>, reason: Option<USVString>) -> Fallible<()>{
+ fn Close(&self, code: Option<u16>, reason: Option<USVString>) -> ErrorResult {
if let Some(code) = code {
//Fail if the supplied code isn't normal and isn't reserved for libraries, frameworks, and applications
if code != close_code::NORMAL && (code < 3000 || code > 4999) {
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index da415c5d0f2..8a3affefe06 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -1383,6 +1383,7 @@ impl Window {
pipelineid: id,
script_chan: Arc::new(Mutex::new(control_chan)),
};
+ let current_time = time::get_time();
let win = box Window {
eventtarget: EventTarget::new_inherited(),
script_chan: script_chan,
@@ -1402,7 +1403,7 @@ impl Window {
devtools_chan: devtools_chan,
browsing_context: Default::default(),
performance: Default::default(),
- navigation_start: time::get_time().sec as u64,
+ navigation_start: (current_time.sec * 1000 + current_time.nsec as i64 / 1000000) as u64,
navigation_start_precise: time::precise_time_ns() as f64,
screen: Default::default(),
session_storage: Default::default(),
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 1d7c2bffd34..8d6716201af 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -828,6 +828,12 @@ impl XMLHttpRequestMethods for XMLHttpRequest {
// https://xhr.spec.whatwg.org/#the-responsexml-attribute
fn GetResponseXML(&self) -> Fallible<Option<Root<Document>>> {
+ // TODO(#2823): Until [Exposed] is implemented, this attribute needs to return null
+ // explicitly in the worker scope.
+ if let GlobalRoot::Worker(_) = self.global() {
+ return Ok(None);
+ }
+
match self.response_type.get() {
XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Document => {
// Step 3
diff --git a/components/script/lib.rs b/components/script/lib.rs
index d3913865070..e525a62b70d 100644
--- a/components/script/lib.rs
+++ b/components/script/lib.rs
@@ -90,6 +90,7 @@ pub mod dom;
pub mod layout_interface;
mod mem;
mod network_listener;
+pub mod origin;
pub mod page;
pub mod parse;
pub mod reporter;
diff --git a/components/script/origin.rs b/components/script/origin.rs
new file mode 100644
index 00000000000..096ffbbd6fb
--- /dev/null
+++ b/components/script/origin.rs
@@ -0,0 +1,73 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use std::cell::RefCell;
+use std::rc::Rc;
+use url::{OpaqueOrigin, Origin as UrlOrigin};
+use url::{Url, Host};
+
+/// A representation of an [origin](https://html.spec.whatwg.org/multipage/#origin-2).
+#[derive(HeapSizeOf)]
+pub struct Origin {
+ #[ignore_heap_size_of = "Rc<T> has unclear ownership semantics"]
+ inner: Rc<RefCell<UrlOrigin>>,
+}
+
+// We can't use RefCell inside JSTraceable, but Origin doesn't contain JS values and
+// DOMRefCell makes it much harder to write unit tests (due to setting up required TLS).
+no_jsmanaged_fields!(Origin);
+
+impl Origin {
+ /// Create a new origin comprising a unique, opaque identifier.
+ pub fn opaque_identifier() -> Origin {
+ let opaque = UrlOrigin::UID(OpaqueOrigin::new());
+ Origin {
+ inner: Rc::new(RefCell::new(opaque)),
+ }
+ }
+
+ /// Create a new origin for the given URL.
+ pub fn new(url: &Url) -> Origin {
+ Origin {
+ inner: Rc::new(RefCell::new(url.origin())),
+ }
+ }
+
+ pub fn set(&self, origin: UrlOrigin) {
+ *self.inner.borrow_mut() = origin;
+ }
+
+ /// Does this origin represent a host/scheme/port tuple?
+ pub fn is_scheme_host_port_tuple(&self) -> bool {
+ match *self.inner.borrow() {
+ UrlOrigin::Tuple(..) => true,
+ UrlOrigin::UID(..) => false,
+ }
+ }
+
+ /// Return the host associated with this origin.
+ pub fn host(&self) -> Option<Host> {
+ match *self.inner.borrow() {
+ UrlOrigin::Tuple(_, ref host, _) => Some(host.clone()),
+ UrlOrigin::UID(..) => None,
+ }
+ }
+
+ /// https://html.spec.whatwg.org/multipage/#same-origin
+ pub fn same_origin(&self, other: &Origin) -> bool {
+ *self.inner.borrow() == *other.inner.borrow()
+ }
+
+ pub fn copy(&self) -> Origin {
+ Origin {
+ inner: Rc::new(RefCell::new(self.inner.borrow().clone())),
+ }
+ }
+
+ pub fn alias(&self) -> Origin {
+ Origin {
+ inner: self.inner.clone(),
+ }
+ }
+}
diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs
index 509a7e93e71..6147fc8bd2b 100644
--- a/components/script/script_runtime.rs
+++ b/components/script/script_runtime.rs
@@ -13,6 +13,8 @@ use js::glue::CollectServoSizes;
use js::jsapi::{DisableIncrementalGC, GCDescription, GCProgress};
use js::jsapi::{JSContext, JS_GetRuntime, JSRuntime, JSTracer, SetDOMCallbacks, SetGCSliceCallback};
use js::jsapi::{JSGCInvocationKind, JSGCStatus, JS_AddExtraGCRootsTracer, JS_SetGCCallback};
+use js::jsapi::{JSGCMode, JSGCParamKey, JS_SetGCParameter, JS_SetGlobalJitCompilerOption};
+use js::jsapi::{JSJitCompilerOption, JS_SetOffthreadIonCompilationEnabled, JS_SetParallelParsingEnabled};
use js::jsapi::{JSObject, RuntimeOptionsRef, SetPreserveWrapperCallback};
use js::rust::Runtime;
use libc;
@@ -130,6 +132,181 @@ pub fn new_rt_and_cx() -> Runtime {
if let Some(val) = get_pref("js.ion.enabled").as_boolean() {
rt_opts.set_ion_(val);
}
+ if let Some(val) = get_pref("js.asmjs.enabled").as_boolean() {
+ rt_opts.set_asmJS_(val);
+ }
+ if let Some(val) = get_pref("js.strict.enabled").as_boolean() {
+ rt_opts.set_extraWarnings_(val);
+ }
+ // TODO: handle js.strict.debug.enabled
+ // TODO: handle js.throw_on_asmjs_validation_failure (needs new Spidermonkey)
+ if let Some(val) = get_pref("js.native_regexp.enabled").as_boolean() {
+ rt_opts.set_nativeRegExp_(val);
+ }
+ if let Some(val) = get_pref("js.parallel_parsing.enabled").as_boolean() {
+ unsafe { JS_SetParallelParsingEnabled(runtime.rt(), val); }
+ }
+ if let Some(val) = get_pref("js.offthread_compilation_enabled").as_boolean() {
+ unsafe { JS_SetOffthreadIonCompilationEnabled(runtime.rt(), val); }
+ }
+ if let Some(val) = get_pref("js.baseline.unsafe_eager_compilation.enabled").as_boolean() {
+ let trigger: i32 = if val {
+ 0
+ } else {
+ -1
+ };
+ unsafe {
+ JS_SetGlobalJitCompilerOption(runtime.rt(),
+ JSJitCompilerOption::JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
+ trigger as u32);
+ }
+ }
+ if let Some(val) = get_pref("js.ion.unsafe_eager_compilation.enabled").as_boolean() {
+ let trigger: i64 = if val {
+ 0
+ } else {
+ -1
+ };
+ unsafe {
+ JS_SetGlobalJitCompilerOption(runtime.rt(),
+ JSJitCompilerOption::JSJITCOMPILER_ION_WARMUP_TRIGGER,
+ trigger as u32);
+ }
+ }
+ // TODO: handle js.discard_system_source.enabled
+ // TODO: handle js.asyncstack.enabled (needs new Spidermonkey)
+ // TODO: handle js.throw_on_debugee_would_run (needs new Spidermonkey)
+ // TODO: handle js.dump_stack_on_debugee_would_run (needs new Spidermonkey)
+ if let Some(val) = get_pref("js.werror.enabled").as_boolean() {
+ rt_opts.set_werror_(val);
+ }
+ // TODO: handle js.shared_memory.enabled
+ if let Some(val) = get_pref("js.mem.high_water_mark").as_i64() {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_MALLOC_BYTES, val as u32 * 1024 * 1024);
+ }
+ }
+ if let Some(val) = get_pref("js.mem.max").as_i64() {
+ let max = if val <= 0 || val >= 0x1000 {
+ -1
+ } else {
+ val * 1024 * 1024
+ };
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_BYTES, max as u32);
+ }
+ }
+ // NOTE: This is disabled above, so enabling it here will do nothing for now.
+ if let Some(val) = get_pref("js.mem.gc.incremental.enabled").as_boolean() {
+ let compartment = if let Some(val) = get_pref("js.mem.gc.per_compartment.enabled").as_boolean() {
+ val
+ } else {
+ false
+ };
+ let mode = if val {
+ JSGCMode::JSGC_MODE_INCREMENTAL
+ } else if compartment {
+ JSGCMode::JSGC_MODE_COMPARTMENT
+ } else {
+ JSGCMode::JSGC_MODE_GLOBAL
+ };
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MODE, mode as u32);
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.incremental.slice_ms").as_i64() {
+ if val >= 0 && val < 100000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_SLICE_TIME_BUDGET, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.compacting.enabled").as_boolean() {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_COMPACTING_ENABLED, val as u32);
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.high_frequency_time_limit_ms").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_TIME_LIMIT, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.dynamic_mark_slice.enabled").as_boolean() {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_MARK_SLICE, val as u32);
+ }
+ }
+ // TODO: handle js.mem.gc.refresh_frame_slices.enabled
+ if let Some(val) = get_pref("js.mem.gc.dynamic_heap_growth.enabled").as_boolean() {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DYNAMIC_HEAP_GROWTH, val as u32);
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.low_frequency_heap_growth").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_LOW_FREQUENCY_HEAP_GROWTH, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.high_frequency_heap_growth_min").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.high_frequency_heap_growth_max").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.high_frequency_low_limit_mb").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_LOW_LIMIT, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.high_frequency_high_limit_mb").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_HIGH_FREQUENCY_HIGH_LIMIT, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.allocation_threshold_mb").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_ALLOCATION_THRESHOLD, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.decommit_threshold_mb").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_DECOMMIT_THRESHOLD, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.empty_chunk_count_min").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MIN_EMPTY_CHUNK_COUNT, val as u32);
+ }
+ }
+ }
+ if let Some(val) = get_pref("js.mem.gc.empty_chunk_count_max").as_i64() {
+ if val >= 0 && val < 10000 {
+ unsafe {
+ JS_SetGCParameter(runtime.rt(), JSGCParamKey::JSGC_MAX_EMPTY_CHUNK_COUNT, val as u32);
+ }
+ }
+ }
runtime
}
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index b9027c96390..7cb24e110bc 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -52,7 +52,8 @@ use hyper::mime::{Mime, SubLevel, TopLevel};
use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER;
use js::jsapi::{DOMProxyShadowsResult, HandleId, HandleObject, RootedValue};
-use js::jsapi::{JSAutoRequest, JSContext, JS_SetWrapObjectCallbacks, JSTracer};
+use js::jsapi::{JSAutoRequest, JS_SetWrapObjectCallbacks};
+use js::jsapi::{JSContext, JSTracer};
use js::jsval::UndefinedValue;
use js::rust::Runtime;
use layout_interface::{ReflowQueryType};
diff --git a/components/script_traits/script_msg.rs b/components/script_traits/script_msg.rs
index 7c82de027bf..10bb4864c4b 100644
--- a/components/script_traits/script_msg.rs
+++ b/components/script_traits/script_msg.rs
@@ -14,7 +14,7 @@ use euclid::size::Size2D;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::{Failure, NavigationDirection, PipelineId};
use msg::constellation_msg::{LoadData, SubpageId};
-use offscreen_gl_context::GLContextAttributes;
+use offscreen_gl_context::{GLContextAttributes, GLLimits};
use style_traits::cursor::Cursor;
use style_traits::viewport::ViewportConstraints;
use url::Url;
@@ -43,8 +43,8 @@ pub enum ScriptMsg {
/// Requests that a new WebGL thread be created. (This is done in the constellation because
/// WebGL uses the GPU and we don't want to give untrusted content access to the GPU.)
CreateWebGLPaintThread(Size2D<i32>,
- GLContextAttributes,
- IpcSender<Result<IpcSender<CanvasMsg>, String>>),
+ GLContextAttributes,
+ IpcSender<Result<(IpcSender<CanvasMsg>, GLLimits), String>>),
/// Dispatched after the DOM load event has fired on a document
/// Causes a `load` event to be dispatched to any enclosing frame context element
/// for the given pipeline.
diff --git a/components/servo/Cargo.lock b/components/servo/Cargo.lock
index 4a782120ee1..73bf74a008c 100644
--- a/components/servo/Cargo.lock
+++ b/components/servo/Cargo.lock
@@ -18,8 +18,8 @@ dependencies = [
"gfx_tests 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin_app 0.0.1",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"layout 0.0.1",
"layout_tests 0.0.1",
@@ -49,15 +49,6 @@ dependencies = [
]
[[package]]
-name = "advapi32-sys"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "aho-corasick"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -92,6 +83,15 @@ dependencies = [
]
[[package]]
+name = "arrayvec"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "nodrop 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "aster"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -119,10 +119,10 @@ dependencies = [
[[package]]
name = "bincode"
-version = "0.5.0"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -155,11 +155,6 @@ source = "git+https://github.com/browserhtml/browserhtml?branch=gh-pages#0ca5084
[[package]]
name = "byteorder"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "byteorder"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -172,7 +167,7 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -192,7 +187,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -251,7 +246,7 @@ name = "cmake"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -302,8 +297,8 @@ dependencies = [
"gfx 0.0.1",
"gfx_traits 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -413,7 +408,7 @@ version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -432,7 +427,7 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"msg 0.0.1",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -658,12 +653,8 @@ dependencies = [
[[package]]
name = "gcc"
-version = "0.3.17"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
name = "gdi32-sys"
@@ -695,9 +686,9 @@ dependencies = [
"harfbuzz-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -714,7 +705,7 @@ dependencies = [
"servo-skia 0.20130412.6 (registry+https://github.com/rust-lang/crates.io-index)",
"simd 0.1.0 (git+https://github.com/huonw/simd)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -729,7 +720,7 @@ name = "gfx_tests"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"style 0.0.1",
]
@@ -751,11 +742,11 @@ dependencies = [
[[package]]
name = "gif"
-version = "0.7.0"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lzw 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -890,7 +881,7 @@ dependencies = [
"phf 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -918,30 +909,31 @@ dependencies = [
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "image"
-version = "0.7.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gif 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gif 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "jpeg-decoder 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jpeg-decoder 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "immeta"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -965,12 +957,12 @@ dependencies = [
[[package]]
name = "ipc-channel"
-version = "0.2.1"
-source = "git+https://github.com/servo/ipc-channel#f85a07bdb2615e439bee7308d37266ac3dd23708"
+version = "0.2.2"
+source = "git+https://github.com/servo/ipc-channel#e43fb22c431740a9bc54ce96caebd0e67d1a0586"
dependencies = [
- "bincode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -980,10 +972,10 @@ dependencies = [
[[package]]
name = "jpeg-decoder"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1058,7 +1050,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layout_traits 0.0.1",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1075,7 +1067,7 @@ dependencies = [
"serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1098,7 +1090,7 @@ name = "layout_traits"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"msg 0.0.1",
"net_traits 0.0.1",
"profile_traits 0.0.1",
@@ -1112,7 +1104,7 @@ dependencies = [
[[package]]
name = "lazy_static"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1139,7 +1131,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1156,7 +1148,7 @@ name = "libz-sys"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1171,7 +1163,7 @@ dependencies = [
[[package]]
name = "lzw"
-version = "0.9.0"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1240,7 +1232,7 @@ name = "miniz-sys"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1263,7 +1255,7 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1283,8 +1275,8 @@ dependencies = [
"devtools_traits 0.0.1",
"flate2 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "immeta 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "immeta 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1295,11 +1287,12 @@ dependencies = [
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"threadpool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1322,13 +1315,13 @@ dependencies = [
"devtools_traits 0.0.1",
"flate2 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"msg 0.0.1",
"net 0.0.1",
"net_traits 0.0.1",
"plugins 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
]
@@ -1340,9 +1333,9 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -1350,7 +1343,7 @@ dependencies = [
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1361,6 +1354,14 @@ dependencies = [
]
[[package]]
+name = "nodrop"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "num"
version = "0.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1406,6 +1407,11 @@ dependencies = [
]
[[package]]
+name = "odds"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "offscreen_gl_context"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1428,8 +1434,8 @@ version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys-extras 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1452,7 +1458,7 @@ name = "openssl-sys-extras"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1561,7 +1567,7 @@ name = "profile"
version = "0.0.1"
dependencies = [
"hbs-pow 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
@@ -1578,7 +1584,7 @@ version = "0.0.1"
dependencies = [
"energy-monitor 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"energymon 0.2.0 (git+https://github.com/energymon/energymon-rust.git)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1712,8 +1718,8 @@ dependencies = [
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"html5ever 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"js 0.1.2 (git+https://github.com/servo/rust-mozjs)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1735,15 +1741,15 @@ dependencies = [
"selectors 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
"xml5ever 0.1.1 (git+https://github.com/Ygg01/xml5ever)",
]
@@ -1752,7 +1758,9 @@ name = "script_tests"
version = "0.0.1"
dependencies = [
"msg 0.0.1",
+ "plugins 0.0.1",
"script 0.0.1",
+ "url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
]
@@ -1767,7 +1775,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -1795,7 +1803,7 @@ dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quickersort 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1884,7 +1892,7 @@ dependencies = [
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1893,7 +1901,7 @@ dependencies = [
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-kbd 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "wayland-window 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-dl 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1922,7 +1930,7 @@ name = "shared_library"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1956,13 +1964,13 @@ dependencies = [
[[package]]
name = "string_cache"
-version = "0.2.11"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"debug_unreachable 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_generator 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1980,7 +1988,7 @@ dependencies = [
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1990,7 +1998,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2007,7 +2015,7 @@ dependencies = [
"msg 0.0.1",
"plugins 0.0.1",
"selectors 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"style_traits 0.0.1",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2022,7 +2030,7 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
@@ -2038,7 +2046,7 @@ dependencies = [
name = "task_info"
version = "0.0.1"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -2051,12 +2059,13 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "1.1.3"
+version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2103,8 +2112,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
-version = "1.0.1"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "unicode-bidi"
@@ -2184,10 +2196,10 @@ dependencies = [
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"js 0.1.2 (git+https://github.com/servo/rust-mozjs)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2197,7 +2209,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2244,7 +2256,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2263,16 +2275,16 @@ version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-window"
-version = "0.2.2"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2293,8 +2305,8 @@ version = "0.0.1"
dependencies = [
"compositing 0.0.1",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -2319,8 +2331,8 @@ dependencies = [
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2339,7 +2351,7 @@ dependencies = [
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2347,17 +2359,17 @@ dependencies = [
[[package]]
name = "websocket"
-version = "0.16.1"
+version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2424,7 +2436,7 @@ dependencies = [
"phf 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml
index f412b16af0a..a06e3093031 100644
--- a/components/servo/Cargo.toml
+++ b/components/servo/Cargo.toml
@@ -19,7 +19,7 @@ doc = false
bench = false
[dev-dependencies]
-image = "0.7"
+image = "0.9"
[dev-dependencies.gfx_tests]
path = "../../tests/unit/gfx"
diff --git a/components/servo/lib.rs b/components/servo/lib.rs
index 6ddcd58222a..47c66b97590 100644
--- a/components/servo/lib.rs
+++ b/components/servo/lib.rs
@@ -81,8 +81,8 @@ use profile_traits::mem;
use profile_traits::time;
use std::rc::Rc;
use std::sync::mpsc::Sender;
-use util::opts;
use util::resource_files::resources_dir_path;
+use util::{opts, prefs};
pub use gleam::gl;
@@ -251,6 +251,7 @@ pub fn run_content_process(token: String) {
let unprivileged_content = unprivileged_content_receiver.recv().unwrap();
opts::set_defaults(unprivileged_content.opts());
+ prefs::extend_prefs(unprivileged_content.prefs());
// Enter the sandbox if necessary.
if opts::get().sandbox {
@@ -275,7 +276,8 @@ pub unsafe extern fn __errno_location() -> *mut i32 {
#[cfg(not(target_os = "windows"))]
fn create_sandbox() {
- ChildSandbox::new(sandboxing::content_process_sandbox_profile()).activate().unwrap();
+ ChildSandbox::new(sandboxing::content_process_sandbox_profile()).activate()
+ .expect("Failed to activate sandbox!");
}
#[cfg(target_os = "windows")]
diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml
index 82284240a26..6aee2f66cfd 100644
--- a/components/style/Cargo.toml
+++ b/components/style/Cargo.toml
@@ -31,7 +31,7 @@ euclid = {version = "0.6.4", features = ["plugins"]}
fnv = "1.0"
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-lazy_static = "0.1.10"
+lazy_static = "0.1.16"
log = "0.3.5"
matches = "0.1"
num = "0.1.24"
@@ -40,7 +40,6 @@ selectors = {version = "0.5", features = ["heap_size", "unstable"]}
serde = {version = "0.7", features = ["nightly"]}
serde_macros = "0.7"
smallvec = "0.1"
-string_cache = {version = "0.2.11", features = ["heap_size"]}
+string_cache = {version = "0.2.12", features = ["heap_size"]}
time = "0.1"
url = {version = "0.5.7", features = ["heap_size"]}
-
diff --git a/components/style/animation.rs b/components/style/animation.rs
index a7622c90f34..9c0242aa971 100644
--- a/components/style/animation.rs
+++ b/components/style/animation.rs
@@ -24,7 +24,7 @@ use properties::longhands::transition_timing_function::computed_value::{Transiti
use properties::longhands::vertical_align::computed_value::T as VerticalAlign;
use properties::longhands::visibility::computed_value::T as Visibility;
use properties::longhands::z_index::computed_value::T as ZIndex;
-use properties::style_struct_traits::TBox;
+use properties::style_struct_traits::Box;
use properties::{ComputedValues, ServoComputedValues};
use std::cmp::Ordering;
use std::iter::repeat;
diff --git a/components/style/build.rs b/components/style/build.rs
index 88e301b6bba..4f7eaf76013 100644
--- a/components/style/build.rs
+++ b/components/style/build.rs
@@ -50,8 +50,8 @@ import sys
from mako.template import Template
from mako import exceptions
try:
- print(Template(filename=os.environ['TEMPLATE'], input_encoding='utf8').render(PRODUCT=os.environ['PRODUCT'])
- .encode('utf8'))
+ template = Template(open(os.environ['TEMPLATE'], 'rb').read(), input_encoding='utf8')
+ print(template.render(PRODUCT=os.environ['PRODUCT']).encode('utf8'))
except:
sys.stderr.write(exceptions.text_error_template().render().encode('utf8'))
sys.exit(1)
diff --git a/components/style/properties.mako.rs b/components/style/properties.mako.rs
index f3c2f512cf8..ecbfe5af015 100644
--- a/components/style/properties.mako.rs
+++ b/components/style/properties.mako.rs
@@ -9,6 +9,7 @@
// can be escaped. In the above example, Vec<<&Foo> achieves the desired result of Vec<&Foo>.
use std::ascii::AsciiExt;
+use std::boxed::Box as StdBox;
use std::collections::HashSet;
use std::fmt;
use std::intrinsics;
@@ -16,7 +17,8 @@ use std::mem;
use std::sync::Arc;
use app_units::Au;
-use cssparser::{Parser, Color, RGBA, AtRuleParser, DeclarationParser, Delimiter,
+use cssparser::Color as CSSParserColor;
+use cssparser::{Parser, RGBA, AtRuleParser, DeclarationParser, Delimiter,
DeclarationListParser, parse_important, ToCss, TokenSerializationType};
use error_reporting::ParseErrorReporter;
use url::Url;
@@ -143,6 +145,9 @@ def new_style_struct(name, is_inherited, gecko_name=None, additional_methods=Non
THIS_STYLE_STRUCT = style_struct
return ""
+def active_style_structs():
+ return filter(lambda s: s.additional_methods or s.longhands, STYLE_STRUCTS)
+
def switch_to_style_struct(name):
global THIS_STYLE_STRUCT
@@ -202,8 +207,9 @@ pub mod longhands {
use properties::longhands;
use properties::property_bit_field::PropertyBitField;
use properties::{ComputedValues, ServoComputedValues, PropertyDeclaration};
- use properties::style_struct_traits::T${THIS_STYLE_STRUCT.trait_name};
+ use properties::style_struct_traits::${THIS_STYLE_STRUCT.trait_name};
use properties::style_structs;
+ use std::boxed::Box as StdBox;
use std::collections::HashMap;
use std::sync::Arc;
use values::computed::{TContext, ToComputedValue};
@@ -217,7 +223,7 @@ pub mod longhands {
context: &mut computed::Context<C>,
seen: &mut PropertyBitField,
cacheable: &mut bool,
- error_reporter: &mut Box<ParseErrorReporter + Send>) {
+ error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
let declared_value = match *declaration {
PropertyDeclaration::${property.camel_case}(ref declared_value) => {
declared_value
@@ -538,7 +544,6 @@ pub mod longhands {
%>
pub use self::computed_value::T as SpecifiedValue;
use values::computed::{Context, ComputedValueAsSpecified};
- use properties::style_struct_traits::TInheritedText;
pub mod computed_value {
#[allow(non_camel_case_types)]
@@ -590,7 +595,7 @@ pub mod longhands {
context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
- _error_reporter: &mut Box<ParseErrorReporter + Send>) {
+ _error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
longhands::_servo_display_for_hypothetical_box::derive_from_display(context);
longhands::_servo_text_decorations_in_effect::derive_from_display(context);
}
@@ -907,7 +912,11 @@ pub mod longhands {
// CSS 2.1, Section 11 - Visual effects
// Non-standard, see https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-box#Specifications
- ${single_keyword("-servo-overflow-clip-box", "padding-box content-box", internal=True)}
+ ${single_keyword("-servo-overflow-clip-box", "padding-box content-box", products="servo",
+ internal=True)}
+
+ ${single_keyword("overflow-clip-box", "padding-box content-box", products="gecko",
+ internal=True)}
// FIXME(pcwalton, #2742): Implement scrolling for `scroll` and `auto`.
${single_keyword("overflow-x", "visible hidden scroll auto")}
@@ -950,6 +959,16 @@ pub mod longhands {
}
</%self:longhand>
+ // CSSOM View Module
+ // https://www.w3.org/TR/cssom-view-1/
+ ${single_keyword("scroll-behavior", "auto smooth", products="gecko")}
+
+ // Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type-x
+ ${single_keyword("scroll-snap-type-x", "none mandatory proximity", products="gecko")}
+
+ // Non-standard: https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-snap-type-y
+ ${single_keyword("scroll-snap-type-y", "none mandatory proximity", products="gecko")}
+
${switch_to_style_struct("InheritedBox")}
// TODO: collapse. Well, do tables first.
@@ -1352,6 +1371,12 @@ pub mod longhands {
// CSS 2.1, Section 13 - Paged media
+ ${switch_to_style_struct("Box")}
+
+ ${single_keyword("page-break-after", "auto always avoid left right", products="gecko")}
+ ${single_keyword("page-break-before", "auto always avoid left right", products="gecko")}
+ ${single_keyword("page-break-inside", "auto avoid", products="gecko")}
+
// CSS 2.1, Section 14 - Colors and Backgrounds
${new_style_struct("Background", is_inherited=False, gecko_name="nsStyleBackground")}
@@ -1681,7 +1706,8 @@ pub mod longhands {
"longhands::color::computed_value::T")])}
<%self:raw_longhand name="color">
- use cssparser::{Color, RGBA};
+ use cssparser::Color as CSSParserColor;
+ use cssparser::RGBA;
use values::specified::{CSSColor, CSSRGBA};
impl ToComputedValue for SpecifiedValue {
@@ -1705,8 +1731,8 @@ pub mod longhands {
-> Result<DeclaredValue<SpecifiedValue>, ()> {
let value = try!(CSSColor::parse(input));
let rgba = match value.parsed {
- Color::RGBA(rgba) => rgba,
- Color::CurrentColor => return Ok(DeclaredValue::Inherit)
+ CSSParserColor::RGBA(rgba) => rgba,
+ CSSParserColor::CurrentColor => return Ok(DeclaredValue::Inherit)
};
Ok(DeclaredValue::Value(CSSRGBA {
parsed: rgba,
@@ -2024,6 +2050,8 @@ pub mod longhands {
"normal ultra-condensed extra-condensed condensed semi-condensed semi-expanded \
expanded extra-expanded ultra-expanded")}
+ ${single_keyword("font-kerning", "auto none normal", products="gecko")}
+
// CSS 2.1, Section 16 - Text
${switch_to_style_struct("InheritedText")}
@@ -2229,7 +2257,6 @@ pub mod longhands {
use cssparser::ToCss;
use std::fmt;
use values::computed::ComputedValueAsSpecified;
- use properties::style_struct_traits::TInheritedText;
impl ComputedValueAsSpecified for SpecifiedValue {}
@@ -2307,11 +2334,14 @@ pub mod longhands {
context: &mut computed::Context<C>,
_seen: &mut PropertyBitField,
_cacheable: &mut bool,
- _error_reporter: &mut Box<ParseErrorReporter + Send>) {
+ _error_reporter: &mut StdBox<ParseErrorReporter + Send>) {
longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context);
}
</%self:longhand>
+ ${single_keyword("text-decoration-style", "-moz-none solid double dotted dashed wavy",
+ products="gecko")}
+
${switch_to_style_struct("InheritedText")}
<%self:longhand name="-servo-text-decorations-in-effect"
@@ -2320,7 +2350,7 @@ pub mod longhands {
use std::fmt;
use values::computed::ComputedValueAsSpecified;
- use properties::style_struct_traits::{TBox, TColor, TText};
+ use properties::style_struct_traits::{Box, Color, Text};
impl ComputedValueAsSpecified for SpecifiedValue {}
@@ -2437,6 +2467,16 @@ pub mod longhands {
${single_keyword("text-rendering", "auto optimizespeed optimizelegibility geometricprecision")}
+ // CSS Text Module Level 3
+ // https://www.w3.org/TR/css-text-3/
+ ${single_keyword("hyphens", "none manual auto", products="gecko")}
+
+ // CSS Ruby Layout Module Level 1
+ // https://www.w3.org/TR/css-ruby-1/
+ ${single_keyword("ruby-align", "start center space-between space-around", products="gecko")}
+
+ ${single_keyword("ruby-position", "over under", products="gecko")}
+
// CSS 2.1, Section 17 - Tables
${new_style_struct("Table", is_inherited=False, gecko_name="nsStyleTable")}
@@ -2539,8 +2579,11 @@ pub mod longhands {
}
</%self:longhand>
- // CSS 2.1, Section 18 - User interface
+ // CSS Fragmentation Module Level 3
+ // https://www.w3.org/TR/css-break-3/
+ ${switch_to_style_struct("Border")}
+ ${single_keyword("box-decoration-break", "slice clone", products="gecko")}
// CSS Writing Modes Level 3
// http://dev.w3.org/csswg/css-writing-modes/
@@ -2552,8 +2595,16 @@ pub mod longhands {
// FIXME(SimonSapin): initial (first) value should be 'mixed', when that's implemented
${single_keyword("text-orientation", "sideways sideways-left sideways-right", experimental=True)}
+ // CSS Color Module Level 4
+ // https://drafts.csswg.org/css-color/
+ ${single_keyword("color-adjust", "economy exact", products="gecko")}
+
// CSS Basic User Interface Module Level 3
// http://dev.w3.org/csswg/css-ui/
+ ${switch_to_style_struct("Box")}
+
+ ${single_keyword("resize", "none both horizontal vertical", products="gecko")}
+
${switch_to_style_struct("Position")}
${single_keyword("box-sizing", "content-box border-box")}
@@ -4160,6 +4211,8 @@ pub mod longhands {
${single_keyword("backface-visibility", "visible hidden")}
+ ${single_keyword("transform-box", "border-box fill-box view-box", products="gecko")}
+
${single_keyword("transform-style", "auto flat preserve-3d")}
<%self:longhand name="transform-origin">
@@ -4314,11 +4367,26 @@ pub mod longhands {
}
</%self:longhand>
+ // Compositing and Blending Level 1
+ // http://www.w3.org/TR/compositing-1/
+ ${single_keyword("isolation", "auto isolate", products="gecko")}
+
${single_keyword("mix-blend-mode",
"""normal multiply screen overlay darken lighten color-dodge
color-burn hard-light soft-light difference exclusion hue
saturation color luminosity""")}
+ // CSS Masking Module Level 1
+ // https://www.w3.org/TR/css-masking-1/
+ ${single_keyword("mask-type", "luminance alpha", products="gecko")}
+
+ // CSS Image Values and Replaced Content Module Level 3
+ // https://drafts.csswg.org/css-images-3/
+
+ ${switch_to_style_struct("Position")}
+
+ ${single_keyword("object-fit", "fill contain cover none scale-down", products="gecko")}
+
${switch_to_style_struct("InheritedBox")}
<%self:longhand name="image-rendering">
@@ -4906,6 +4974,65 @@ pub mod longhands {
// Flex container properties
${single_keyword("flex-direction", "row row-reverse column column-reverse", experimental=True)}
+
+ // https://drafts.csswg.org/css-flexbox/#propdef-order
+ <%self:longhand name="order">
+ use values::computed::ComputedValueAsSpecified;
+
+ impl ComputedValueAsSpecified for SpecifiedValue {}
+
+ pub type SpecifiedValue = computed_value::T;
+
+ pub mod computed_value {
+ pub type T = i32;
+ }
+
+ #[inline]
+ pub fn get_initial_value() -> computed_value::T {
+ 0
+ }
+
+ fn parse(_context: &ParserContext, input: &mut Parser) -> Result<SpecifiedValue, ()> {
+ specified::parse_integer(input)
+ }
+ </%self:longhand>
+
+ ${single_keyword("flex-wrap", "nowrap wrap wrap-reverse", products="gecko")}
+
+ // SVG 1.1 (Second Edition)
+ // https://www.w3.org/TR/SVG/
+ ${new_style_struct("SVG", is_inherited=True)}
+
+ // Section 10 - Text
+ ${single_keyword("dominant-baseline",
+ """auto use-script no-change reset-size ideographic alphabetic hanging
+ mathematical central middle text-after-edge text-before-edge""",
+ products="gecko")}
+
+ ${single_keyword("text-anchor", "start middle end", products="gecko")}
+
+ // Section 11 - Painting: Filling, Stroking and Marker Symbols
+ ${single_keyword("color-interpolation", "auto sRGB linearRGB", products="gecko")}
+
+ ${single_keyword("color-interpolation-filters", "auto sRGB linearRGB", products="gecko")}
+
+ ${single_keyword("fill-rule", "nonzero evenodd", products="gecko")}
+
+ ${single_keyword("shape-rendering", "auto optimizeSpeed crispEdges geometricPrecision",
+ products="gecko")}
+
+ ${single_keyword("stroke-linecap", "butt round square", products="gecko")}
+
+ ${single_keyword("stroke-linejoin", "miter round bevel", products="gecko")}
+
+ ${switch_to_style_struct("Effects")}
+
+ ${single_keyword("vector-effect", "none non-scaling-stroke", products="gecko")}
+
+ ${switch_to_style_struct("SVG")}
+
+ // Section 14 - Clipping, Masking and Compositing
+ ${single_keyword("clip-rule", "nonzero evenodd", products="gecko")}
}
@@ -5670,7 +5797,7 @@ mod property_bit_field {
value: &DeclaredValue<longhands::${property.ident}::SpecifiedValue>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
- error_reporter: &mut Box<ParseErrorReporter + Send>)
+ error_reporter: &mut StdBox<ParseErrorReporter + Send>)
where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>)
{
if let DeclaredValue::WithVariables {
@@ -5697,7 +5824,7 @@ mod property_bit_field {
from_shorthand: Option<Shorthand>,
custom_properties: &Option<Arc<::custom_properties::ComputedValuesMap>>,
f: F,
- error_reporter: &mut Box<ParseErrorReporter + Send>)
+ error_reporter: &mut StdBox<ParseErrorReporter + Send>)
where F: FnOnce(&DeclaredValue<longhands::${property.ident}::SpecifiedValue>) {
f(&
::custom_properties::substitute(css, first_token_type, custom_properties)
@@ -5747,13 +5874,13 @@ pub struct PropertyDeclarationBlock {
pub normal: Arc<Vec<PropertyDeclaration>>,
}
-pub fn parse_style_attribute(input: &str, base_url: &Url, error_reporter: Box<ParseErrorReporter + Send>)
+pub fn parse_style_attribute(input: &str, base_url: &Url, error_reporter: StdBox<ParseErrorReporter + Send>)
-> PropertyDeclarationBlock {
let context = ParserContext::new(Origin::Author, base_url, error_reporter);
parse_property_declaration_list(&context, &mut Parser::new(input))
}
-pub fn parse_one_declaration(name: &str, input: &str, base_url: &Url, error_reporter: Box<ParseErrorReporter + Send>)
+pub fn parse_one_declaration(name: &str, input: &str, base_url: &Url, error_reporter: StdBox<ParseErrorReporter + Send>)
-> Result<Vec<PropertyDeclaration>, ()> {
let context = ParserContext::new(Origin::Author, base_url, error_reporter);
let mut results = vec![];
@@ -6166,8 +6293,8 @@ impl PropertyDeclaration {
pub mod style_struct_traits {
use super::longhands;
- % for style_struct in STYLE_STRUCTS:
- pub trait T${style_struct.trait_name}: Clone {
+ % for style_struct in active_style_structs():
+ pub trait ${style_struct.trait_name}: Clone {
% for longhand in style_struct.longhands:
#[allow(non_snake_case)]
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T);
@@ -6187,7 +6314,7 @@ pub mod style_structs {
use super::longhands;
use std::hash::{Hash, Hasher};
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
% if style_struct.trait_name == "Font":
#[derive(Clone, HeapSizeOf, Debug)]
% else:
@@ -6213,7 +6340,7 @@ pub mod style_structs {
}
% endif
- impl super::style_struct_traits::T${style_struct.trait_name} for ${style_struct.servo_struct_name} {
+ impl super::style_struct_traits::${style_struct.trait_name} for ${style_struct.servo_struct_name} {
% for longhand in style_struct.longhands:
fn set_${longhand.ident}(&mut self, v: longhands::${longhand.ident}::computed_value::T) {
self.${longhand.ident} = v;
@@ -6303,8 +6430,8 @@ pub mod style_structs {
}
pub trait ComputedValues : Clone + Send + Sync + 'static {
- % for style_struct in STYLE_STRUCTS:
- type Concrete${style_struct.trait_name}: style_struct_traits::T${style_struct.trait_name};
+ % for style_struct in active_style_structs():
+ type Concrete${style_struct.trait_name}: style_struct_traits::${style_struct.trait_name};
% endfor
// Temporary bailout case for stuff we haven't made work with the trait
@@ -6318,7 +6445,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
shareable: bool,
writing_mode: WritingMode,
root_font_size: Au,
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
${style_struct.ident}: Arc<Self::Concrete${style_struct.trait_name}>,
% endfor
) -> Self;
@@ -6327,7 +6454,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
fn do_cascade_property<F: FnOnce(&Vec<Option<CascadePropertyFn<Self>>>)>(f: F);
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
fn clone_${style_struct.trait_name_lower}(&self) ->
Arc<Self::Concrete${style_struct.trait_name}>;
fn get_${style_struct.trait_name_lower}<'a>(&'a self) ->
@@ -6345,7 +6472,7 @@ pub trait ComputedValues : Clone + Send + Sync + 'static {
#[derive(Clone, HeapSizeOf)]
pub struct ServoComputedValues {
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>,
% endfor
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
@@ -6355,7 +6482,7 @@ pub struct ServoComputedValues {
}
impl ComputedValues for ServoComputedValues {
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
type Concrete${style_struct.trait_name} = style_structs::${style_struct.servo_struct_name};
% endfor
@@ -6366,7 +6493,7 @@ impl ComputedValues for ServoComputedValues {
shareable: bool,
writing_mode: WritingMode,
root_font_size: Au,
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.servo_struct_name}>,
% endfor
) -> Self {
@@ -6375,7 +6502,7 @@ impl ComputedValues for ServoComputedValues {
shareable: shareable,
writing_mode: writing_mode,
root_font_size: root_font_size,
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
${style_struct.ident}: ${style_struct.ident},
% endfor
}
@@ -6387,7 +6514,7 @@ impl ComputedValues for ServoComputedValues {
CASCADE_PROPERTY.with(|x| f(x));
}
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
#[inline]
fn clone_${style_struct.trait_name_lower}(&self) ->
Arc<Self::Concrete${style_struct.trait_name}> {
@@ -6430,10 +6557,10 @@ impl ServoComputedValues {
/// Usage example:
/// let top_color = style.resolve_color(style.Border.border_top_color);
#[inline]
- pub fn resolve_color(&self, color: Color) -> RGBA {
+ pub fn resolve_color(&self, color: CSSParserColor) -> RGBA {
match color {
- Color::RGBA(rgba) => rgba,
- Color::CurrentColor => self.get_color().color,
+ CSSParserColor::RGBA(rgba) => rgba,
+ CSSParserColor::CurrentColor => self.get_color().color,
}
}
@@ -6589,7 +6716,7 @@ impl ServoComputedValues {
pub fn computed_value_to_string(&self, name: &str) -> Result<String, ()> {
match name {
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
% for longhand in style_struct.longhands:
"${longhand.name}" => Ok(self.${style_struct.ident}.${longhand.ident}.to_css_string()),
% endfor
@@ -6606,7 +6733,7 @@ impl ServoComputedValues {
/// Return a WritingMode bitflags from the relevant CSS properties.
-pub fn get_writing_mode<S: style_struct_traits::TInheritedBox>(inheritedbox_style: &S) -> WritingMode {
+pub fn get_writing_mode<S: style_struct_traits::InheritedBox>(inheritedbox_style: &S) -> WritingMode {
use logical_geometry;
let mut flags = WritingMode::empty();
match inheritedbox_style.clone_direction() {
@@ -6643,7 +6770,7 @@ pub fn get_writing_mode<S: style_struct_traits::TInheritedBox>(inheritedbox_styl
/// The initial values for all style structs as defined by the specification.
lazy_static! {
pub static ref INITIAL_SERVO_VALUES: ServoComputedValues = ServoComputedValues {
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
${style_struct.ident}: Arc::new(style_structs::${style_struct.servo_struct_name} {
% for longhand in style_struct.longhands:
${longhand.ident}: longhands::${longhand.ident}::get_initial_value(),
@@ -6670,7 +6797,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
parent_style: &C,
cached_style: &C,
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
- mut error_reporter: Box<ParseErrorReporter + Send>)
+ mut error_reporter: StdBox<ParseErrorReporter + Send>)
-> C {
let mut context = computed::Context {
is_root_element: false,
@@ -6681,7 +6808,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
shareable,
WritingMode::empty(),
parent_style.root_font_size(),
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
% if style_struct.inherited:
parent_style
% else:
@@ -6698,13 +6825,13 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
// Declarations are already stored in reverse order.
for declaration in sub_list.declarations.iter() {
match *declaration {
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
% for property in style_struct.longhands:
% if property.derived_from is None:
PropertyDeclaration::${property.camel_case}(ref
${'_' if not style_struct.inherited else ''}declared_value)
=> {
- use properties::style_struct_traits::T${style_struct.trait_name};
+ use properties::style_struct_traits::${style_struct.trait_name};
% if style_struct.inherited:
if seen.get_${property.ident}() {
continue
@@ -6762,7 +6889,7 @@ fn cascade_with_cached_declarations<C: ComputedValues>(
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() {
- use properties::style_struct_traits::TFont;
+ use properties::style_struct_traits::Font;
context.mutate_style().mutate_font().compute_font_hash();
}
@@ -6775,11 +6902,11 @@ pub type CascadePropertyFn<C /*: ComputedValues */> =
context: &mut computed::Context<C>,
seen: &mut PropertyBitField,
cacheable: &mut bool,
- error_reporter: &mut Box<ParseErrorReporter + Send>);
+ error_reporter: &mut StdBox<ParseErrorReporter + Send>);
pub fn make_cascade_vec<C: ComputedValues>() -> Vec<Option<CascadePropertyFn<C>>> {
let mut result: Vec<Option<CascadePropertyFn<C>>> = Vec::new();
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
% for property in style_struct.longhands:
let discriminant;
unsafe {
@@ -6826,9 +6953,9 @@ pub fn cascade<C: ComputedValues>(
shareable: bool,
parent_style: Option<<&C>,
cached_style: Option<<&C>,
- mut error_reporter: Box<ParseErrorReporter + Send>)
+ mut error_reporter: StdBox<ParseErrorReporter + Send>)
-> (C, bool) {
- use properties::style_struct_traits::{TBorder, TBox, TColor, TFont, TOutline};
+ use properties::style_struct_traits::{Border, Box, Color, Font, Outline};
let initial_values = C::initial_values();
let (is_root_element, inherited_style) = match parent_style {
Some(parent_style) => (false, parent_style),
@@ -6874,7 +7001,7 @@ pub fn cascade<C: ComputedValues>(
shareable,
WritingMode::empty(),
inherited_style.root_font_size(),
- % for style_struct in STYLE_STRUCTS:
+ % for style_struct in active_style_structs():
% if style_struct.inherited:
inherited_style
% else:
@@ -7007,7 +7134,7 @@ pub fn cascade<C: ComputedValues>(
if seen.get_font_style() || seen.get_font_weight() || seen.get_font_stretch() ||
seen.get_font_family() {
- use properties::style_struct_traits::TFont;
+ use properties::style_struct_traits::Font;
style.mutate_font().compute_font_hash();
}
diff --git a/components/style/values.rs b/components/style/values.rs
index dff9f3935cd..754125bfc21 100644
--- a/components/style/values.rs
+++ b/components/style/values.rs
@@ -1437,7 +1437,7 @@ pub mod computed {
use app_units::Au;
use euclid::size::Size2D;
use properties::ComputedValues;
- use properties::style_struct_traits::TFont;
+ use properties::style_struct_traits::Font;
use std::fmt;
use super::AuExtensionMethods;
use super::specified::AngleOrCorner;
diff --git a/components/util/Cargo.toml b/components/util/Cargo.toml
index 07bb2a7f392..7a4bdf9379c 100644
--- a/components/util/Cargo.toml
+++ b/components/util/Cargo.toml
@@ -44,7 +44,7 @@ rustc-serialize = "0.3"
serde = "0.7"
serde_macros = "0.7"
smallvec = "0.1"
-string_cache = {version = "0.2.11", features = ["heap_size"]}
+string_cache = {version = "0.2.12", features = ["heap_size"]}
url = {version = "0.5.7", features = ["heap_size", "serde_serialization"]}
[target.x86_64-pc-windows-gnu.dependencies]
diff --git a/components/util/prefs.rs b/components/util/prefs.rs
index ff7fbbe5a7e..43286f2137f 100644
--- a/components/util/prefs.rs
+++ b/components/util/prefs.rs
@@ -19,10 +19,11 @@ lazy_static! {
};
}
-#[derive(PartialEq, Clone, Debug)]
+#[derive(PartialEq, Clone, Debug, Deserialize, Serialize)]
pub enum PrefValue {
Boolean(bool),
String(String),
+ Number(f64),
Missing
}
@@ -31,6 +32,9 @@ impl PrefValue {
let value = match data {
Json::Boolean(x) => PrefValue::Boolean(x),
Json::String(x) => PrefValue::String(x),
+ Json::F64(x) => PrefValue::Number(x),
+ Json::I64(x) => PrefValue::Number(x as f64),
+ Json::U64(x) => PrefValue::Number(x as f64),
_ => return Err(())
};
Ok(value)
@@ -53,6 +57,13 @@ impl PrefValue {
_ => None
}
}
+
+ pub fn as_i64(&self) -> Option<i64> {
+ match *self {
+ PrefValue::Number(x) => Some(x as i64),
+ _ => None,
+ }
+ }
}
impl ToJson for PrefValue {
@@ -63,13 +74,16 @@ impl ToJson for PrefValue {
},
PrefValue::String(ref x) => {
Json::String(x.clone())
- }
+ },
+ PrefValue::Number(x) => {
+ Json::F64(x)
+ },
PrefValue::Missing => Json::Null
}
}
}
-#[derive(Debug)]
+#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum Pref {
NoDefault(Arc<PrefValue>),
WithDefault(Arc<PrefValue>, Option<Arc<PrefValue>>)
@@ -136,13 +150,17 @@ pub fn read_prefs_from_file<T>(mut file: T)
Ok(x) => {
prefs.insert(name, x);
},
- Err(_) => println!("Ignoring non-boolean/string preference value for {:?}", name)
+ Err(_) => println!("Ignoring non-boolean/string/i64 preference value for {:?}", name),
}
}
}
Ok(prefs)
}
+pub fn get_cloned() -> HashMap<String, Pref> {
+ PREFS.lock().unwrap().clone()
+}
+
pub fn extend_prefs(extension: HashMap<String, Pref>) {
PREFS.lock().unwrap().extend(extension);
}
diff --git a/components/util/resource_files.rs b/components/util/resource_files.rs
index dcb9646f42c..9df1b2de89c 100644
--- a/components/util/resource_files.rs
+++ b/components/util/resource_files.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+use std::env;
use std::fs::File;
use std::io::{self, Read};
use std::path::PathBuf;
@@ -25,35 +26,35 @@ pub fn resources_dir_path() -> PathBuf {
#[cfg(not(target_os = "android"))]
pub fn resources_dir_path() -> PathBuf {
- use std::env;
+ let mut dir = CMD_RESOURCE_DIR.lock().unwrap();
+
+ if let Some(ref path) = *dir {
+ return PathBuf::from(path);
+ }
- match *CMD_RESOURCE_DIR.lock().unwrap() {
- Some(ref path) => PathBuf::from(path),
- None => {
- // FIXME: Find a way to not rely on the executable being
- // under `<servo source>[/$target_triple]/target/debug`
- // or `<servo source>[/$target_triple]/target/release`.
- let mut path = env::current_exe().expect("can't get exe path");
- // Follow symlink
- path = path.canonicalize().expect("path does not exist");
+ // FIXME: Find a way to not rely on the executable being
+ // under `<servo source>[/$target_triple]/target/debug`
+ // or `<servo source>[/$target_triple]/target/release`.
+ let mut path = env::current_exe().expect("can't get exe path");
+ // Follow symlink
+ path = path.canonicalize().expect("path does not exist");
+ path.pop();
+ path.push("resources");
+ if !path.is_dir() { // resources dir not in same dir as exe?
+ // exe is probably in target/{debug,release} so we need to go back to topdir
+ path.pop();
+ path.pop();
+ path.pop();
+ path.push("resources");
+ if !path.is_dir() {
+ // exe is probably in target/$target_triple/{debug,release} so go back one more
+ path.pop();
path.pop();
path.push("resources");
- if !path.is_dir() { // resources dir not in same dir as exe?
- // exe is probably in target/{debug,release} so we need to go back to topdir
- path.pop();
- path.pop();
- path.pop();
- path.push("resources");
- if !path.is_dir() {
- // exe is probably in target/$target_triple/{debug,release} so go back one more
- path.pop();
- path.pop();
- path.push("resources");
- }
- }
- path
}
}
+ *dir = Some(path.to_str().unwrap().to_owned());
+ path
}
pub fn read_resource_file(relative_path_components: &[&str]) -> io::Result<Vec<u8>> {
diff --git a/components/webdriver_server/Cargo.toml b/components/webdriver_server/Cargo.toml
index 547ae03fc8e..02b90a58fe3 100644
--- a/components/webdriver_server/Cargo.toml
+++ b/components/webdriver_server/Cargo.toml
@@ -24,7 +24,7 @@ path = "../util"
git = "https://github.com/servo/ipc-channel"
[dependencies]
-image = "0.7"
+image = "0.9"
log = "0.3.5"
hyper = "0.8"
rustc-serialize = "0.3.4"
diff --git a/ports/cef/Cargo.lock b/ports/cef/Cargo.lock
index d89aad3ae69..c15817549a0 100644
--- a/ports/cef/Cargo.lock
+++ b/ports/cef/Cargo.lock
@@ -33,15 +33,6 @@ dependencies = [
]
[[package]]
-name = "advapi32-sys"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "aho-corasick"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -76,6 +67,15 @@ dependencies = [
]
[[package]]
+name = "arrayvec"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "nodrop 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "aster"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -103,10 +103,10 @@ dependencies = [
[[package]]
name = "bincode"
-version = "0.5.0"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -139,11 +139,6 @@ source = "git+https://github.com/browserhtml/browserhtml?branch=gh-pages#0ca5084
[[package]]
name = "byteorder"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "byteorder"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -156,7 +151,7 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -176,7 +171,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -235,7 +230,7 @@ name = "cmake"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -271,8 +266,8 @@ dependencies = [
"gfx 0.0.1",
"gfx_traits 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -382,7 +377,7 @@ version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -401,7 +396,7 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"msg 0.0.1",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -586,12 +581,8 @@ dependencies = [
[[package]]
name = "gcc"
-version = "0.3.17"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
name = "gdi32-sys"
@@ -623,9 +614,9 @@ dependencies = [
"harfbuzz-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -642,7 +633,7 @@ dependencies = [
"servo-skia 0.20130412.6 (registry+https://github.com/rust-lang/crates.io-index)",
"simd 0.1.0 (git+https://github.com/huonw/simd)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -670,11 +661,11 @@ dependencies = [
[[package]]
name = "gif"
-version = "0.7.0"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lzw 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -809,7 +800,7 @@ dependencies = [
"phf 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -837,30 +828,31 @@ dependencies = [
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "image"
-version = "0.7.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gif 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gif 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "jpeg-decoder 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jpeg-decoder 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "immeta"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -884,12 +876,12 @@ dependencies = [
[[package]]
name = "ipc-channel"
-version = "0.2.1"
-source = "git+https://github.com/servo/ipc-channel#f85a07bdb2615e439bee7308d37266ac3dd23708"
+version = "0.2.2"
+source = "git+https://github.com/servo/ipc-channel#e43fb22c431740a9bc54ce96caebd0e67d1a0586"
dependencies = [
- "bincode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -899,10 +891,10 @@ dependencies = [
[[package]]
name = "jpeg-decoder"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -977,7 +969,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layout_traits 0.0.1",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -994,7 +986,7 @@ dependencies = [
"serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1010,7 +1002,7 @@ name = "layout_traits"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"msg 0.0.1",
"net_traits 0.0.1",
"profile_traits 0.0.1",
@@ -1024,7 +1016,7 @@ dependencies = [
[[package]]
name = "lazy_static"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1051,7 +1043,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1068,7 +1060,7 @@ name = "libz-sys"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1083,7 +1075,7 @@ dependencies = [
[[package]]
name = "lzw"
-version = "0.9.0"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1152,7 +1144,7 @@ name = "miniz-sys"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1175,7 +1167,7 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1195,8 +1187,8 @@ dependencies = [
"devtools_traits 0.0.1",
"flate2 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "immeta 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "immeta 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1207,11 +1199,12 @@ dependencies = [
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"threadpool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1233,9 +1226,9 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -1243,7 +1236,15 @@ dependencies = [
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "nodrop"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1292,6 +1293,11 @@ dependencies = [
]
[[package]]
+name = "odds"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "offscreen_gl_context"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1314,8 +1320,8 @@ version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys-extras 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1338,7 +1344,7 @@ name = "openssl-sys-extras"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1430,7 +1436,7 @@ name = "profile"
version = "0.0.1"
dependencies = [
"hbs-pow 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
@@ -1445,7 +1451,7 @@ dependencies = [
name = "profile_traits"
version = "0.0.1"
dependencies = [
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1579,8 +1585,8 @@ dependencies = [
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"html5ever 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"js 0.1.2 (git+https://github.com/servo/rust-mozjs)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1602,15 +1608,15 @@ dependencies = [
"selectors 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
"xml5ever 0.1.1 (git+https://github.com/Ygg01/xml5ever)",
]
@@ -1625,7 +1631,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -1653,7 +1659,7 @@ dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quickersort 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1710,7 +1716,7 @@ dependencies = [
"gfx 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
"glutin_app 0.0.1",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"layout 0.0.1",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1780,7 +1786,7 @@ dependencies = [
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1789,7 +1795,7 @@ dependencies = [
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-kbd 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "wayland-window 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-dl 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1818,7 +1824,7 @@ name = "shared_library"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1852,13 +1858,13 @@ dependencies = [
[[package]]
name = "string_cache"
-version = "0.2.11"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"debug_unreachable 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_generator 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1876,7 +1882,7 @@ dependencies = [
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1886,7 +1892,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1901,7 +1907,7 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
@@ -1917,7 +1923,7 @@ dependencies = [
name = "task_info"
version = "0.0.1"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1930,12 +1936,13 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "1.1.3"
+version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1982,8 +1989,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
-version = "1.0.1"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "unicode-bidi"
@@ -2063,10 +2073,10 @@ dependencies = [
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"js 0.1.2 (git+https://github.com/servo/rust-mozjs)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2076,7 +2086,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2112,7 +2122,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2131,16 +2141,16 @@ version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-window"
-version = "0.2.2"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2161,8 +2171,8 @@ version = "0.0.1"
dependencies = [
"compositing 0.0.1",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -2187,8 +2197,8 @@ dependencies = [
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2207,7 +2217,7 @@ dependencies = [
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2215,17 +2225,17 @@ dependencies = [
[[package]]
name = "websocket"
-version = "0.16.1"
+version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2292,7 +2302,7 @@ dependencies = [
"phf 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/ports/geckolib/Cargo.lock b/ports/geckolib/Cargo.lock
index 1922eb39a22..8516abbe295 100644
--- a/ports/geckolib/Cargo.lock
+++ b/ports/geckolib/Cargo.lock
@@ -8,14 +8,14 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
"selectors 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
@@ -41,10 +41,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bincode"
-version = "0.5.0"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -62,7 +62,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
-version = "0.4.2"
+version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -190,12 +190,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ipc-channel"
-version = "0.2.1"
-source = "git+https://github.com/servo/ipc-channel#f85a07bdb2615e439bee7308d37266ac3dd23708"
+version = "0.2.2"
+source = "git+https://github.com/servo/ipc-channel#e43fb22c431740a9bc54ce96caebd0e67d1a0586"
dependencies = [
- "bincode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -214,7 +214,7 @@ dependencies = [
[[package]]
name = "lazy_static"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -332,7 +332,7 @@ dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quickersort 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -365,13 +365,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "string_cache"
-version = "0.2.11"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"debug_unreachable 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_generator 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -389,7 +389,7 @@ dependencies = [
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -399,7 +399,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -414,7 +414,7 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
@@ -489,9 +489,9 @@ dependencies = [
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -501,7 +501,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml
index 32a0e650fc4..c9cb2f467ac 100644
--- a/ports/geckolib/Cargo.toml
+++ b/ports/geckolib/Cargo.toml
@@ -17,12 +17,12 @@ cssparser = {version = "0.5.4", features = ["heap_size", "serde-serialization"]}
euclid = {version = "0.6.4", features = ["plugins"]}
heapsize = "0.3.0"
heapsize_plugin = "0.1.2"
-lazy_static = "0.1"
+lazy_static = "0.1.16"
libc = "0.2"
num_cpus = "0.2.2"
selectors = {version = "0.5", features = ["heap_size", "unstable"]}
smallvec = "0.1"
-string_cache = {version = "0.2.11", features = ["heap_size", "unstable"]}
+string_cache = {version = "0.2.12", features = ["heap_size", "unstable"]}
url = {version = "0.5.7", features = ["heap_size", "query_encoding", "serde_serialization"]}
[dependencies.log]
diff --git a/ports/geckolib/properties.mako.rs b/ports/geckolib/properties.mako.rs
index e7fcb9ed216..4f74e767e7a 100644
--- a/ports/geckolib/properties.mako.rs
+++ b/ports/geckolib/properties.mako.rs
@@ -153,7 +153,7 @@ impl Debug for ${style_struct.gecko_ffi_name} {
</%def>
<%def name="raw_impl_trait(style_struct, skip_longhands=None, skip_additionals=None)">
-impl T${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
+impl ${style_struct.trait_name} for ${style_struct.gecko_struct_name} {
/*
* Manually-Implemented Methods.
*/
diff --git a/ports/gonk/Cargo.lock b/ports/gonk/Cargo.lock
index e7b83b55bfc..5aaedff2fa4 100644
--- a/ports/gonk/Cargo.lock
+++ b/ports/gonk/Cargo.lock
@@ -26,15 +26,6 @@ dependencies = [
]
[[package]]
-name = "advapi32-sys"
-version = "0.1.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "aho-corasick"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -69,6 +60,15 @@ dependencies = [
]
[[package]]
+name = "arrayvec"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "nodrop 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
name = "aster"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -96,10 +96,10 @@ dependencies = [
[[package]]
name = "bincode"
-version = "0.5.0"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -132,11 +132,6 @@ source = "git+https://github.com/browserhtml/browserhtml?branch=gh-pages#0ca5084
[[package]]
name = "byteorder"
-version = "0.4.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "byteorder"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -149,7 +144,7 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gfx_traits 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -169,7 +164,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -228,7 +223,7 @@ name = "cmake"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -264,8 +259,8 @@ dependencies = [
"gfx 0.0.1",
"gfx_traits 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"layout_traits 0.0.1",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -375,7 +370,7 @@ version = "0.0.1"
dependencies = [
"devtools_traits 0.0.1",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -394,7 +389,7 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"msg 0.0.1",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -589,12 +584,8 @@ dependencies = [
[[package]]
name = "gcc"
-version = "0.3.17"
+version = "0.3.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
name = "gdi32-sys"
@@ -626,9 +617,9 @@ dependencies = [
"harfbuzz-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -645,7 +636,7 @@ dependencies = [
"servo-skia 0.20130412.6 (registry+https://github.com/rust-lang/crates.io-index)",
"simd 0.1.0 (git+https://github.com/huonw/simd)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -673,11 +664,11 @@ dependencies = [
[[package]]
name = "gif"
-version = "0.7.0"
+version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lzw 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lzw 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -791,7 +782,7 @@ dependencies = [
"phf 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -819,30 +810,31 @@ dependencies = [
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "image"
-version = "0.7.0"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gif 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gif 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "jpeg-decoder 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "jpeg-decoder 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"png 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "immeta"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -866,12 +858,12 @@ dependencies = [
[[package]]
name = "ipc-channel"
-version = "0.2.1"
-source = "git+https://github.com/servo/ipc-channel#f85a07bdb2615e439bee7308d37266ac3dd23708"
+version = "0.2.2"
+source = "git+https://github.com/servo/ipc-channel#e43fb22c431740a9bc54ce96caebd0e67d1a0586"
dependencies = [
- "bincode 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bincode 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -881,10 +873,10 @@ dependencies = [
[[package]]
name = "jpeg-decoder"
-version = "0.1.2"
+version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -959,7 +951,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layout_traits 0.0.1",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -976,7 +968,7 @@ dependencies = [
"serde_json 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -992,7 +984,7 @@ name = "layout_traits"
version = "0.0.1"
dependencies = [
"gfx 0.0.1",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"msg 0.0.1",
"net_traits 0.0.1",
"profile_traits 0.0.1",
@@ -1006,7 +998,7 @@ dependencies = [
[[package]]
name = "lazy_static"
-version = "0.1.15"
+version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1033,7 +1025,7 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1050,7 +1042,7 @@ name = "libz-sys"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1065,7 +1057,7 @@ dependencies = [
[[package]]
name = "lzw"
-version = "0.9.0"
+version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -1134,7 +1126,7 @@ name = "miniz-sys"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1157,7 +1149,7 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"plugins 0.0.1",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1177,8 +1169,8 @@ dependencies = [
"devtools_traits 0.0.1",
"flate2 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "immeta 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "immeta 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"mime_guess 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1189,11 +1181,12 @@ dependencies = [
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"threadpool 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1215,9 +1208,9 @@ dependencies = [
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"plugins 0.0.1",
@@ -1225,7 +1218,15 @@ dependencies = [
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "nodrop"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "odds 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1274,6 +1275,11 @@ dependencies = [
]
[[package]]
+name = "odds"
+version = "0.2.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
name = "offscreen_gl_context"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1296,8 +1302,8 @@ version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys-extras 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1320,7 +1326,7 @@ name = "openssl-sys-extras"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1412,7 +1418,7 @@ name = "profile"
version = "0.0.1"
dependencies = [
"hbs-pow 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
@@ -1427,7 +1433,7 @@ dependencies = [
name = "profile_traits"
version = "0.0.1"
dependencies = [
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"plugins 0.0.1",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1561,8 +1567,8 @@ dependencies = [
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"html5ever 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "image 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "image 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"js 0.1.2 (git+https://github.com/servo/rust-mozjs)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1584,15 +1590,15 @@ dependencies = [
"selectors 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
"uuid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_traits 0.1.0 (git+https://github.com/servo/webrender_traits)",
- "websocket 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "websocket 0.16.2 (registry+https://github.com/rust-lang/crates.io-index)",
"xml5ever 0.1.1 (git+https://github.com/Ygg01/xml5ever)",
]
@@ -1607,7 +1613,7 @@ dependencies = [
"gfx_traits 0.0.1",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"net_traits 0.0.1",
@@ -1635,7 +1641,7 @@ dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quickersort 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1691,7 +1697,7 @@ dependencies = [
"gaol 0.0.1 (git+https://github.com/servo/gaol)",
"gfx 0.0.1",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"layers 0.2.4 (git+https://github.com/servo/rust-layers)",
"layout 0.0.1",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1760,7 +1766,7 @@ dependencies = [
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"objc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1769,7 +1775,7 @@ dependencies = [
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-kbd 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "wayland-window 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "wayland-window 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"x11-dl 2.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1798,7 +1804,7 @@ name = "shared_library"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1832,13 +1838,13 @@ dependencies = [
[[package]]
name = "string_cache"
-version = "0.2.11"
+version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"debug_unreachable 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_generator 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1856,7 +1862,7 @@ dependencies = [
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1866,7 +1872,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"style_traits 0.0.1",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1881,7 +1887,7 @@ dependencies = [
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"plugins 0.0.1",
@@ -1897,7 +1903,7 @@ dependencies = [
name = "task_info"
version = "0.0.1"
dependencies = [
- "gcc 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -1910,12 +1916,13 @@ dependencies = [
[[package]]
name = "tempfile"
-version = "1.1.3"
+version = "2.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1962,8 +1969,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
-version = "1.0.1"
+version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "rustc_version 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "unicode-bidi"
@@ -2043,10 +2053,10 @@ dependencies = [
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"heapsize_plugin 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"js 0.1.2 (git+https://github.com/servo/rust-mozjs)",
"kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2056,7 +2066,7 @@ dependencies = [
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2092,7 +2102,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2111,16 +2121,16 @@ version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dlib 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "wayland-window"
-version = "0.2.2"
+version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "tempfile 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tempfile 2.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"wayland-client 0.5.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2137,8 +2147,8 @@ dependencies = [
"fnv 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.1.0 (git+https://github.com/servo/rust-freetype)",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
- "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
+ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2157,7 +2167,7 @@ dependencies = [
"core-graphics 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
- "ipc-channel 0.2.1 (git+https://github.com/servo/ipc-channel)",
+ "ipc-channel 0.2.2 (git+https://github.com/servo/ipc-channel)",
"offscreen_gl_context 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_macros 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2165,17 +2175,17 @@ dependencies = [
[[package]]
name = "websocket"
-version = "0.16.1"
+version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.19 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "unicase 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.5.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2242,7 +2252,7 @@ dependencies = [
"phf 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_codegen 0.7.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
- "string_cache 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "string_cache 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tendril 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.34 (registry+https://github.com/rust-lang/crates.io-index)",
]
diff --git a/python/tidy.py b/python/tidy.py
index 6110a9ea4eb..e12eeb33e49 100644
--- a/python/tidy.py
+++ b/python/tidy.py
@@ -69,6 +69,8 @@ ignored_dirs = [
os.path.join(".", "."),
]
+spec_base_path = "components/script/dom/"
+
def is_iter_empty(iterator):
try:
@@ -221,7 +223,7 @@ def check_lock(file_name, contents):
raise StopIteration
# package names to be neglected (as named by cargo)
- exceptions = ["bitflags", "xml-rs", "byteorder"]
+ exceptions = ["bitflags", "xml-rs"]
import toml
content = toml.loads(contents)
@@ -525,10 +527,9 @@ def check_json(filename, contents):
def check_spec(file_name, lines):
- base_path = "components/script/dom/"
- if base_path not in file_name:
+ if spec_base_path not in file_name:
raise StopIteration
- file_name = os.path.relpath(os.path.splitext(file_name)[0], base_path)
+ file_name = os.path.relpath(os.path.splitext(file_name)[0], spec_base_path)
patt = re.compile("^\s*\/\/.+")
# Pattern representing a line with a macro
diff --git a/python/tidy_self_test/speclink.rs b/python/tidy_self_test/speclink.rs
new file mode 100644
index 00000000000..6c27a70a7d0
--- /dev/null
+++ b/python/tidy_self_test/speclink.rs
@@ -0,0 +1,9 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+impl SpecLinkMethods for SpecLink {
+ fn Test(&self) -> f32 {
+ 0
+ }
+}
diff --git a/python/tidy_self_test/tidy_self_test.py b/python/tidy_self_test/tidy_self_test.py
index d7666b58b73..e2a49f71a65 100644
--- a/python/tidy_self_test/tidy_self_test.py
+++ b/python/tidy_self_test/tidy_self_test.py
@@ -59,6 +59,11 @@ class CheckTidiness(unittest.TestCase):
self.assertEqual('use &[T] instead of &Vec<T>', errors.next()[2])
self.assertEqual('use &str instead of &String', errors.next()[2])
+ def test_spec_link(self):
+ tidy.spec_base_path = "python/tidy_self_test/"
+ errors = tidy.collect_errors_for_files(iterFile('speclink.rs'), [], [tidy.check_spec])
+ self.assertEqual('method declared in webidl is missing a comment with a specification link', errors.next()[2])
+
def test_webidl(self):
errors = tidy.collect_errors_for_files(iterFile('spec.webidl'), [tidy.check_webidl_spec], [])
self.assertEqual('No specification link found.', errors.next()[2])
diff --git a/resources/prefs.json b/resources/prefs.json
index 5a9b084a675..cf7cf17ee06 100644
--- a/resources/prefs.json
+++ b/resources/prefs.json
@@ -5,6 +5,41 @@
"gfx.webrender.enabled": false,
"js.baseline.enabled": true,
"js.ion.enabled": true,
+ "js.asmjs.enabled": true,
+ "js.strict.enabled": false,
+ "js.strict.debug.enabled": false,
+ "js.throw_on_asmjs_validation_failure.enabled": false,
+ "js.native_regexp.enabled": true,
+ "js.parallel_parsing.enabled": true,
+ "js.ion.offthread_compilation.enabled": true,
+ "js.baseline.unsafe_eager_compilation.enabled": false,
+ "js.ion.unsafe_eager_compilation.enabled": false,
+ "js.discard_system_source.enabled": false,
+ "js.asyncstack.enabled": false,
+ "js.throw_on_debuggee_would_run.enabled": false,
+ "js.dump_stack_on_debuggee_would_run.enabled": false,
+ "js.werror.enabled": false,
+ "js.strict.enabled": false,
+ "js.shared_memory.enabled": true,
+ "js.mem.high_water_mark": 128,
+ "js.mem.max": -1,
+ "js.mem.gc.per_compartment.enabled": true,
+ "js.mem.gc.incremental.enabled": true,
+ "js.mem.gc.incremental.slice_ms": 10,
+ "js.mem.gc.compacting.enabled": true,
+ "js.mem.gc.high_frequency_time_limit_ms": 1000,
+ "js.mem.gc.dynamic_mark_slice.enabled": true,
+ "js.mem.gc.refresh_frame_slices.enabled": true,
+ "js.mem.gc.dynamic_heap_growth.enabled": true,
+ "js.mem.gc.low_frequency_heap_growth": 150,
+ "js.mem.gc.high_frequency_heap_growth_min": 150,
+ "js.mem.gc.high_frequency_heap_growth_max": 300,
+ "js.mem.gc.high_frequency_low_limit_mb": 100,
+ "js.mem.gc.high_frequency_high_limit_mb": 500,
+ "js.mem.gc.allocation_threshold_mb": 30,
+ "js.mem.gc.decommit_threshold_mb": 32,
+ "js.mem.gc.empty_chunk_count_min": 1,
+ "js.mem.gc.empty_chunk_count_max": 30,
"layout.columns.enabled": false,
"layout.column-width.enabled": false,
"layout.column-count.enabled": false,
diff --git a/tests/html/nested-fixed-position.html b/tests/html/nested-fixed-position.html
new file mode 100644
index 00000000000..2810dbf8599
--- /dev/null
+++ b/tests/html/nested-fixed-position.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<body style="height: 2000px; background: linear-gradient(to bottom, white, black)">
+<div style="position: fixed; top: 0; right: 0; left: 0;">
+ <div style="position: absolute; left: 0; right: 0; height: 40px; overflow: hidden;">
+ This text should <em>not</em> scroll.
+ </div>
+</div>
diff --git a/tests/html/test_webgl_triangle.html b/tests/html/test_webgl_triangle.html
index 980049f4466..2386f3fa1bf 100644
--- a/tests/html/test_webgl_triangle.html
+++ b/tests/html/test_webgl_triangle.html
@@ -9,23 +9,25 @@
<canvas id="canvas" width="512" height="512"></canvas>
</div>
<script id="vertexshader" type="x-shader">
- attribute vec2 aVertexPosition;
- attribute vec4 aColour;
- varying vec4 aVertexColor;
+precision mediump float;
- void main() {
- aVertexColor = aColour;
- gl_Position = vec4(aVertexPosition, 0.0, 1.0);
- }
+attribute vec2 aVertexPosition;
+attribute vec4 aColour;
+varying vec4 aVertexColor;
+
+void main() {
+ aVertexColor = aColour;
+ gl_Position = vec4(aVertexPosition, 0.0, 1.0);
+}
</script>
<script id="fragmentshader" type="x-shader">
- precision mediump float;
+precision mediump float;
- varying vec4 aVertexColor;
+varying vec4 aVertexColor;
- void main() {
- gl_FragColor = aVertexColor;
- }
+void main() {
+ gl_FragColor = aVertexColor;
+}
</script>
<script type="text/javascript">
@@ -44,6 +46,9 @@
var v = document.getElementById("vertexshader").firstChild.nodeValue;
var f = document.getElementById("fragmentshader").firstChild.nodeValue;
+ console.log("vertex source: ", v);
+ console.log("fragment source: ", f);
+
var vs = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vs, v);
gl.compileShader(vs);
@@ -96,6 +101,7 @@
gl.vertexAttribPointer(program.aVertexPosition, itemSize, gl.FLOAT, false, 0, 0);
program.aColour = gl.getAttribLocation(program, "aColour");
+ console.log("aColour: " + program.aColour);
gl.enableVertexAttribArray(program.aColour);
gl.vertexAttribPointer(program.aColour, 4, gl.FLOAT, false, 0, 24);
diff --git a/tests/unit/net/fetch.rs b/tests/unit/net/fetch.rs
index 4b6eff5da69..b2353d33113 100644
--- a/tests/unit/net/fetch.rs
+++ b/tests/unit/net/fetch.rs
@@ -2,7 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-use hyper::header::{AccessControlAllowHeaders, AccessControlAllowOrigin};
+use hyper::header::{AccessControlAllowCredentials, AccessControlAllowHeaders, AccessControlAllowOrigin};
+use hyper::header::{AccessControlAllowMethods, AccessControlRequestHeaders, AccessControlRequestMethod};
use hyper::header::{CacheControl, ContentLanguage, ContentType, Expires, LastModified};
use hyper::header::{Headers, HttpDate, Location, SetCookie, Pragma};
use hyper::method::Method;
@@ -16,6 +17,7 @@ use net_traits::AsyncFetchListener;
use net_traits::request::{Origin, RedirectMode, Referer, Request, RequestMode};
use net_traits::response::{CacheState, Response, ResponseBody, ResponseType};
use std::rc::Rc;
+use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::mpsc::{Sender, channel};
use std::sync::{Arc, Mutex};
use time::{self, Duration};
@@ -137,6 +139,74 @@ fn test_fetch_data() {
}
#[test]
+fn test_cors_preflight_fetch() {
+ static ACK: &'static [u8] = b"ACK";
+ let state = Arc::new(AtomicUsize::new(0));
+ let handler = move |request: HyperRequest, mut response: HyperResponse| {
+ if request.method == Method::Options && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
+ assert!(request.headers.has::<AccessControlRequestMethod>());
+ assert!(request.headers.has::<AccessControlRequestHeaders>());
+ response.headers_mut().set(AccessControlAllowOrigin::Any);
+ response.headers_mut().set(AccessControlAllowCredentials);
+ response.headers_mut().set(AccessControlAllowMethods(vec![Method::Get]));
+ } else {
+ response.headers_mut().set(AccessControlAllowOrigin::Any);
+ response.send(ACK).unwrap();
+ }
+ };
+ let (mut server, url) = make_server(handler);
+
+ let origin = Origin::Origin(UrlOrigin::UID(OpaqueOrigin::new()));
+ let mut request = Request::new(url, Some(origin), false);
+ request.referer = Referer::NoReferer;
+ request.use_cors_preflight = true;
+ request.mode = RequestMode::CORSMode;
+ let wrapped_request = Rc::new(request);
+
+ let fetch_response = fetch(wrapped_request);
+ let _ = server.close();
+
+ assert!(!fetch_response.is_network_error());
+
+ match *fetch_response.body.lock().unwrap() {
+ ResponseBody::Done(ref body) => assert_eq!(&**body, ACK),
+ _ => panic!()
+ };
+}
+
+#[test]
+fn test_cors_preflight_fetch_network_error() {
+ static ACK: &'static [u8] = b"ACK";
+ let state = Arc::new(AtomicUsize::new(0));
+ let handler = move |request: HyperRequest, mut response: HyperResponse| {
+ if request.method == Method::Options && state.clone().fetch_add(1, Ordering::SeqCst) == 0 {
+ assert!(request.headers.has::<AccessControlRequestMethod>());
+ assert!(request.headers.has::<AccessControlRequestHeaders>());
+ response.headers_mut().set(AccessControlAllowOrigin::Any);
+ response.headers_mut().set(AccessControlAllowCredentials);
+ response.headers_mut().set(AccessControlAllowMethods(vec![Method::Get]));
+ } else {
+ response.headers_mut().set(AccessControlAllowOrigin::Any);
+ response.send(ACK).unwrap();
+ }
+ };
+ let (mut server, url) = make_server(handler);
+
+ let origin = Origin::Origin(UrlOrigin::UID(OpaqueOrigin::new()));
+ let mut request = Request::new(url, Some(origin), false);
+ *request.method.borrow_mut() = Method::Extension("CHICKEN".to_owned());
+ request.referer = Referer::NoReferer;
+ request.use_cors_preflight = true;
+ request.mode = RequestMode::CORSMode;
+ let wrapped_request = Rc::new(request);
+
+ let fetch_response = fetch(wrapped_request);
+ let _ = server.close();
+
+ assert!(fetch_response.is_network_error());
+}
+
+#[test]
fn test_fetch_response_is_basic_filtered() {
static MESSAGE: &'static [u8] = b"";
@@ -342,7 +412,7 @@ fn test_fetch_with_local_urls_only() {
assert!(server_response.is_network_error());
}
-fn test_fetch_redirect_count(message: &'static [u8], redirect_cap: u32) -> Response {
+fn setup_server_and_fetch(message: &'static [u8], redirect_cap: u32) -> Response {
let handler = move |request: HyperRequest, mut response: HyperResponse| {
@@ -382,7 +452,7 @@ fn test_fetch_redirect_count_ceiling() {
// how many redirects to cause
let redirect_cap = 20;
- let fetch_response = test_fetch_redirect_count(MESSAGE, redirect_cap);
+ let fetch_response = setup_server_and_fetch(MESSAGE, redirect_cap);
assert!(!fetch_response.is_network_error());
assert_eq!(fetch_response.response_type, ResponseType::Basic);
@@ -402,7 +472,7 @@ fn test_fetch_redirect_count_failure() {
// how many redirects to cause
let redirect_cap = 21;
- let fetch_response = test_fetch_redirect_count(MESSAGE, redirect_cap);
+ let fetch_response = setup_server_and_fetch(MESSAGE, redirect_cap);
assert!(fetch_response.is_network_error());
diff --git a/tests/unit/script/Cargo.toml b/tests/unit/script/Cargo.toml
index 8aa177e966b..b34cfb238f6 100644
--- a/tests/unit/script/Cargo.toml
+++ b/tests/unit/script/Cargo.toml
@@ -11,8 +11,14 @@ doctest = false
[dependencies.msg]
path = "../../../components/msg"
+[dependencies.plugins]
+path = "../../../components/plugins"
+
[dependencies.script]
path = "../../../components/script"
[dependencies.util]
path = "../../../components/util"
+
+[dependencies]
+url = {version = "0.5.8", features = ["heap_size"]}
diff --git a/tests/unit/script/lib.rs b/tests/unit/script/lib.rs
index 8270d8542d7..2dbbd16ea7a 100644
--- a/tests/unit/script/lib.rs
+++ b/tests/unit/script/lib.rs
@@ -2,10 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#![feature(plugin)]
+#![plugin(plugins)]
+
extern crate msg;
extern crate script;
+extern crate url;
extern crate util;
+#[cfg(test)] mod origin;
#[cfg(all(test, target_pointer_width = "64"))] mod size_of;
#[cfg(test)] mod textinput;
#[cfg(test)] mod dom {
diff --git a/tests/unit/script/origin.rs b/tests/unit/script/origin.rs
new file mode 100644
index 00000000000..81e5d538686
--- /dev/null
+++ b/tests/unit/script/origin.rs
@@ -0,0 +1,105 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+use script::origin::Origin;
+
+#[test]
+fn same_origin() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ let b = Origin::new(&url!("http://example.com/b.html"));
+ assert!(a.same_origin(&b));
+ assert_eq!(a.is_scheme_host_port_tuple(), true);
+}
+
+#[test]
+fn identical_origin() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ assert!(a.same_origin(&a));
+}
+
+#[test]
+fn cross_origin() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ let b = Origin::new(&url!("http://example.org/b.html"));
+ assert!(!a.same_origin(&b));
+}
+
+#[test]
+fn alias_same_origin() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ let b = Origin::new(&url!("http://example.com/b.html"));
+ let c = b.alias();
+ assert!(a.same_origin(&c));
+ assert!(b.same_origin(&b));
+ assert!(c.same_origin(&b));
+ assert_eq!(c.is_scheme_host_port_tuple(), true);
+}
+
+#[test]
+fn alias_cross_origin() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ let b = Origin::new(&url!("http://example.org/b.html"));
+ let c = b.alias();
+ assert!(!a.same_origin(&c));
+ assert!(b.same_origin(&c));
+ assert!(c.same_origin(&c));
+}
+
+#[test]
+fn alias_update_same_origin() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ let b = Origin::new(&url!("http://example.org/b.html"));
+ let c = b.alias();
+ b.set(url!("http://example.com/c.html").origin());
+ assert!(a.same_origin(&c));
+ assert!(b.same_origin(&c));
+ assert!(c.same_origin(&c));
+}
+
+#[test]
+fn alias_update_cross_origin() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ let b = Origin::new(&url!("http://example.com/b.html"));
+ let c = b.alias();
+ b.set(url!("http://example.org/c.html").origin());
+ assert!(!a.same_origin(&c));
+ assert!(b.same_origin(&c));
+ assert!(c.same_origin(&c));
+}
+
+#[test]
+fn alias_chain() {
+ let a = Origin::new(&url!("http://example.com/a.html"));
+ let b = Origin::new(&url!("http://example.com/b.html"));
+ let c = b.copy();
+ let d = c.alias();
+ let e = d.alias();
+ assert!(a.same_origin(&e));
+ assert!(b.same_origin(&e));
+ assert!(c.same_origin(&e));
+ assert!(d.same_origin(&e));
+ assert!(e.same_origin(&e));
+ c.set(url!("http://example.org/c.html").origin());
+ assert!(a.same_origin(&b));
+ assert!(!b.same_origin(&c));
+ assert!(c.same_origin(&d));
+ assert!(d.same_origin(&e));
+ assert!(!e.same_origin(&a));
+}
+
+#[test]
+fn opaque() {
+ let a = Origin::opaque_identifier();
+ let b = Origin::opaque_identifier();
+ assert!(!a.same_origin(&b));
+ assert_eq!(a.is_scheme_host_port_tuple(), false);
+}
+
+#[test]
+fn opaque_clone() {
+ let a = Origin::opaque_identifier();
+ let b = a.alias();
+ assert!(a.same_origin(&b));
+ assert_eq!(a.is_scheme_host_port_tuple(), false);
+}
diff --git a/tests/unit/style/Cargo.toml b/tests/unit/style/Cargo.toml
index 7bdd55375e9..45245ba9327 100644
--- a/tests/unit/style/Cargo.toml
+++ b/tests/unit/style/Cargo.toml
@@ -28,5 +28,5 @@ app_units = {version = "0.2.3", features = ["plugins"]}
cssparser = {version = "0.5.4", features = ["heap_size"]}
euclid = {version = "0.6.4", features = ["plugins"]}
selectors = {version = "0.5", features = ["heap_size"]}
-string_cache = {version = "0.2.11", features = ["heap_size"]}
+string_cache = {version = "0.2.12", features = ["heap_size"]}
url = {version = "0.5.7", features = ["heap_size"]}
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-inherit.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-inherit.htm.ini
deleted file mode 100644
index 7f4ce858805..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-inherit.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox_computedstyle_order-inherit.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-integer.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-integer.htm.ini
deleted file mode 100644
index 271332df7f3..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-integer.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox_computedstyle_order-integer.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-invalid.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-invalid.htm.ini
deleted file mode 100644
index 85c6209e778..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-invalid.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox_computedstyle_order-invalid.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-negative.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-negative.htm.ini
deleted file mode 100644
index 708b6da31ee..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order-negative.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox_computedstyle_order-negative.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order.htm.ini
deleted file mode 100644
index 5ed40787983..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/flexbox_computedstyle_order.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[flexbox_computedstyle_order.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata-css/css-flexbox-1_dev/html/order_value.htm.ini b/tests/wpt/metadata-css/css-flexbox-1_dev/html/order_value.htm.ini
deleted file mode 100644
index 7366f308aee..00000000000
--- a/tests/wpt/metadata-css/css-flexbox-1_dev/html/order_value.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[order_value.htm]
- type: testharness
- [CSS Flexible Box Test: order_check]
- expected: FAIL
-
diff --git a/tests/wpt/metadata-css/css21_dev/html4/max-width-110.htm.ini b/tests/wpt/metadata-css/css21_dev/html4/max-width-110.htm.ini
deleted file mode 100644
index bbc6b87885f..00000000000
--- a/tests/wpt/metadata-css/css21_dev/html4/max-width-110.htm.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[max-width-110.htm]
- type: reftest
- expected: FAIL
diff --git a/tests/wpt/metadata/MANIFEST.json b/tests/wpt/metadata/MANIFEST.json
index 2c18cb3f8ee..213cb9b5e5c 100644
--- a/tests/wpt/metadata/MANIFEST.json
+++ b/tests/wpt/metadata/MANIFEST.json
@@ -3656,6 +3656,46 @@
"url": "/FileAPI/url/url_xmlhttprequest_img.html"
},
{
+ "path": "compat/webkit-text-fill-color-property-001a.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001a.html"
+ },
+ {
+ "path": "compat/webkit-text-fill-color-property-001b.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001b.html"
+ },
+ {
+ "path": "compat/webkit-text-fill-color-property-001c.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001c.html"
+ },
+ {
+ "path": "compat/webkit-text-fill-color-property-001d.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001d.html"
+ },
+ {
"path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html",
"references": [
[
@@ -4976,6 +5016,16 @@
"url": "/html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html"
},
{
+ "path": "html/rendering/non-replaced-elements/the-hr-element-0/align.html",
+ "references": [
+ [
+ "/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/html/rendering/non-replaced-elements/the-hr-element-0/align.html"
+ },
+ {
"path": "html/rendering/non-replaced-elements/the-hr-element-0/color.html",
"references": [
[
@@ -5306,6 +5356,16 @@
"url": "/html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html"
},
{
+ "path": "html/semantics/links/linktypes/alternate-css.html",
+ "references": [
+ [
+ "/html/semantics/links/linktypes/alternate-css-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/html/semantics/links/linktypes/alternate-css.html"
+ },
+ {
"path": "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html",
"references": [
[
@@ -5566,26 +5626,6 @@
"url": "/html/semantics/text-level-semantics/the-wbr-element/wbr-element.html"
},
{
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html"
- },
- {
"path": "shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html",
"references": [
[
@@ -5606,16 +5646,6 @@
"url": "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html"
},
{
- "path": "shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html"
- },
- {
"path": "shadow-dom/untriaged/shadow-trees/shadow-root-001.html",
"references": [
[
@@ -13942,6 +13972,10 @@
"url": "/custom-elements/registering-custom-elements/unresolved-elements-interface-svg-element.html"
},
{
+ "path": "dom/collections/HTMLCollection-as-proto-length-get-throws.html",
+ "url": "/dom/collections/HTMLCollection-as-proto-length-get-throws.html"
+ },
+ {
"path": "dom/collections/HTMLCollection-empty-name.html",
"url": "/dom/collections/HTMLCollection-empty-name.html"
},
@@ -14406,6 +14440,14 @@
"url": "/dom/nodes/Element-getElementsByTagNameNS.html"
},
{
+ "path": "dom/nodes/Element-insertAdjacentElement.html",
+ "url": "/dom/nodes/Element-insertAdjacentElement.html"
+ },
+ {
+ "path": "dom/nodes/Element-insertAdjacentText.html",
+ "url": "/dom/nodes/Element-insertAdjacentText.html"
+ },
+ {
"path": "dom/nodes/Element-lastElementChild-svg.svg",
"url": "/dom/nodes/Element-lastElementChild-svg.svg"
},
@@ -14766,6 +14808,10 @@
"url": "/dom/nodes/prepend-on-Document.html"
},
{
+ "path": "dom/nodes/remove-unscopable.html",
+ "url": "/dom/nodes/remove-unscopable.html"
+ },
+ {
"path": "dom/nodes/rootNode.html",
"url": "/dom/nodes/rootNode.html"
},
@@ -19290,6 +19336,10 @@
"url": "/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml"
},
{
+ "path": "html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html",
+ "url": "/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html"
+ },
+ {
"path": "html/semantics/scripting-1/the-script-element/script-onload-string.html",
"url": "/html/semantics/scripting-1/the-script-element/script-onload-string.html"
},
@@ -20018,6 +20068,10 @@
"url": "/js/builtins/Object.prototype.seal.html"
},
{
+ "path": "js/builtins/Promise-incumbent-global.sub.html",
+ "url": "/js/builtins/Promise-incumbent-global.sub.html"
+ },
+ {
"path": "js/builtins/Promise-subclassing.html",
"url": "/js/builtins/Promise-subclassing.html"
},
@@ -27666,10 +27720,6 @@
"url": "/selection/Document-open.html"
},
{
- "path": "selection/collapse.html",
- "url": "/selection/collapse.html"
- },
- {
"path": "selection/collapseToStartEnd.html",
"url": "/selection/collapseToStartEnd.html"
},
@@ -27678,10 +27728,6 @@
"url": "/selection/deleteFromDocument.html"
},
{
- "path": "selection/extend.html",
- "url": "/selection/extend.html"
- },
- {
"path": "selection/getRangeAt.html",
"url": "/selection/getRangeAt.html"
},
@@ -27726,6 +27772,366 @@
"url": "/service-workers/cache-storage/serviceworker/credentials.html"
},
{
+ "path": "service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html",
+ "url": "/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html",
+ "url": "/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html",
+ "url": "/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html",
+ "url": "/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/activate-event-after-install-state-change.https.html",
+ "url": "/service-workers/service-worker/activate-event-after-install-state-change.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/activation-after-registration.https.html",
+ "url": "/service-workers/service-worker/activation-after-registration.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/active.https.html",
+ "url": "/service-workers/service-worker/active.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/appcache-ordering-main.https.html",
+ "url": "/service-workers/service-worker/appcache-ordering-main.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/claim-not-using-registration.https.html",
+ "url": "/service-workers/service-worker/claim-not-using-registration.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/claim-using-registration.https.html",
+ "url": "/service-workers/service-worker/claim-using-registration.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/clients-get-cross-origin.https.html",
+ "url": "/service-workers/service-worker/clients-get-cross-origin.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/clients-get.https.html",
+ "url": "/service-workers/service-worker/clients-get.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/clients-matchall-client-types.https.html",
+ "url": "/service-workers/service-worker/clients-matchall-client-types.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/clients-matchall-include-uncontrolled.https.html",
+ "url": "/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/clients-matchall.https.html",
+ "url": "/service-workers/service-worker/clients-matchall.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/controller-on-load.https.html",
+ "url": "/service-workers/service-worker/controller-on-load.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/controller-on-reload.https.html",
+ "url": "/service-workers/service-worker/controller-on-reload.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/extendable-event-async-waituntil.https.html",
+ "url": "/service-workers/service-worker/extendable-event-async-waituntil.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/extendable-event-waituntil.https.html",
+ "url": "/service-workers/service-worker/extendable-event-waituntil.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-canvas-tainting-cache.https.html",
+ "url": "/service-workers/service-worker/fetch-canvas-tainting-cache.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-canvas-tainting.https.html",
+ "url": "/service-workers/service-worker/fetch-canvas-tainting.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-cors-xhr.https.html",
+ "url": "/service-workers/service-worker/fetch-cors-xhr.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-csp.https.html",
+ "url": "/service-workers/service-worker/fetch-csp.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-event-after-navigation-within-page.https.html",
+ "url": "/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-event-async-respond-with.https.html",
+ "url": "/service-workers/service-worker/fetch-event-async-respond-with.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-event-network-error.https.html",
+ "url": "/service-workers/service-worker/fetch-event-network-error.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html",
+ "url": "/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-event.https.html",
+ "url": "/service-workers/service-worker/fetch-event.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-header-visibility.https.html",
+ "url": "/service-workers/service-worker/fetch-header-visibility.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-request-css-base-url.https.html",
+ "url": "/service-workers/service-worker/fetch-request-css-base-url.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-request-css-images.https.html",
+ "url": "/service-workers/service-worker/fetch-request-css-images.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-request-fallback.https.html",
+ "url": "/service-workers/service-worker/fetch-request-fallback.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-request-no-freshness-headers.https.html",
+ "url": "/service-workers/service-worker/fetch-request-no-freshness-headers.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-request-resources.https.html",
+ "url": "/service-workers/service-worker/fetch-request-resources.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-request-xhr.https.html",
+ "url": "/service-workers/service-worker/fetch-request-xhr.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-response-xhr.https.html",
+ "url": "/service-workers/service-worker/fetch-response-xhr.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/getregistration.https.html",
+ "url": "/service-workers/service-worker/getregistration.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/getregistrations.https.html",
+ "url": "/service-workers/service-worker/getregistrations.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/indexeddb.https.html",
+ "url": "/service-workers/service-worker/indexeddb.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/install-event-type.https.html",
+ "url": "/service-workers/service-worker/install-event-type.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/installing.https.html",
+ "url": "/service-workers/service-worker/installing.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/interfaces.https.html",
+ "url": "/service-workers/service-worker/interfaces.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/invalid-blobtype.https.html",
+ "url": "/service-workers/service-worker/invalid-blobtype.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/invalid-header.https.html",
+ "url": "/service-workers/service-worker/invalid-header.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/multiple-register.https.html",
+ "url": "/service-workers/service-worker/multiple-register.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/multiple-update.https.html",
+ "url": "/service-workers/service-worker/multiple-update.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/navigation-redirect.https.html",
+ "url": "/service-workers/service-worker/navigation-redirect.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/onactivate-script-error.https.html",
+ "url": "/service-workers/service-worker/onactivate-script-error.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/oninstall-script-error.https.html",
+ "url": "/service-workers/service-worker/oninstall-script-error.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/performance-timeline.https.html",
+ "url": "/service-workers/service-worker/performance-timeline.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/postmessage-msgport-to-client.https.html",
+ "url": "/service-workers/service-worker/postmessage-msgport-to-client.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/postmessage-to-client.https.html",
+ "url": "/service-workers/service-worker/postmessage-to-client.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/postmessage.https.html",
+ "url": "/service-workers/service-worker/postmessage.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/ready.https.html",
+ "url": "/service-workers/service-worker/ready.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/referer.https.html",
+ "url": "/service-workers/service-worker/referer.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/register-default-scope.https.html",
+ "url": "/service-workers/service-worker/register-default-scope.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/register-same-scope-different-script-url.https.html",
+ "url": "/service-workers/service-worker/register-same-scope-different-script-url.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/register-wait-forever-in-install-worker.https.html",
+ "url": "/service-workers/service-worker/register-wait-forever-in-install-worker.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/registration-end-to-end.https.html",
+ "url": "/service-workers/service-worker/registration-end-to-end.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/registration-events.https.html",
+ "url": "/service-workers/service-worker/registration-events.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/registration-iframe.https.html",
+ "url": "/service-workers/service-worker/registration-iframe.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/registration-service-worker-attributes.https.html",
+ "url": "/service-workers/service-worker/registration-service-worker-attributes.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/registration.https.html",
+ "url": "/service-workers/service-worker/registration.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/rejections.https.html",
+ "url": "/service-workers/service-worker/rejections.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/request-end-to-end.https.html",
+ "url": "/service-workers/service-worker/request-end-to-end.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/resource-timing.https.html",
+ "url": "/service-workers/service-worker/resource-timing.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/service-worker-csp-connect.https.html",
+ "url": "/service-workers/service-worker/service-worker-csp-connect.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/service-worker-csp-default.https.html",
+ "url": "/service-workers/service-worker/service-worker-csp-default.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/service-worker-csp-script.https.html",
+ "url": "/service-workers/service-worker/service-worker-csp-script.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/serviceworkerobject-scripturl.https.html",
+ "url": "/service-workers/service-worker/serviceworkerobject-scripturl.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/shared-worker-controlled.https.html",
+ "url": "/service-workers/service-worker/shared-worker-controlled.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/skip-waiting-installed.https.html",
+ "url": "/service-workers/service-worker/skip-waiting-installed.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/skip-waiting-using-registration.https.html",
+ "url": "/service-workers/service-worker/skip-waiting-using-registration.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/skip-waiting-without-client.https.html",
+ "url": "/service-workers/service-worker/skip-waiting-without-client.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/skip-waiting-without-using-registration.https.html",
+ "url": "/service-workers/service-worker/skip-waiting-without-using-registration.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/skip-waiting.https.html",
+ "url": "/service-workers/service-worker/skip-waiting.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/state.https.html",
+ "url": "/service-workers/service-worker/state.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/synced-state.https.html",
+ "url": "/service-workers/service-worker/synced-state.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/uncontrolled-page.https.html",
+ "url": "/service-workers/service-worker/uncontrolled-page.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/unregister-controller.https.html",
+ "url": "/service-workers/service-worker/unregister-controller.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/unregister-then-register-new-script.https.html",
+ "url": "/service-workers/service-worker/unregister-then-register-new-script.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/unregister-then-register.https.html",
+ "url": "/service-workers/service-worker/unregister-then-register.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/unregister.https.html",
+ "url": "/service-workers/service-worker/unregister.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/update-after-navigation-fetch-event.https.html",
+ "url": "/service-workers/service-worker/update-after-navigation-fetch-event.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/update-after-oneday.https.html",
+ "url": "/service-workers/service-worker/update-after-oneday.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/update.https.html",
+ "url": "/service-workers/service-worker/update.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/waiting.https.html",
+ "url": "/service-workers/service-worker/waiting.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/websocket.https.html",
+ "url": "/service-workers/service-worker/websocket.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/worker-interception.https.html",
+ "url": "/service-workers/service-worker/worker-interception.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/xhr.https.html",
+ "url": "/service-workers/service-worker/xhr.https.html"
+ },
+ {
"path": "shadow-dom/Element-interface-attachShadow.html",
"url": "/shadow-dom/Element-interface-attachShadow.html"
},
@@ -27742,26 +28148,10 @@
"url": "/shadow-dom/styles/shadow-cascade-order.html"
},
{
- "path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005.html"
- },
- {
"path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006.html",
"url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006.html"
},
{
- "path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/non-element-nodes-001.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/non-element-nodes-001.html"
- },
- {
"path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-001.html",
"url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-001.html"
},
@@ -27770,18 +28160,10 @@
"url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html"
},
{
- "path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-003.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-003.html"
- },
- {
"path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html",
"url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html"
},
{
- "path": "shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-002.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-002.html"
- },
- {
"path": "shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html",
"url": "/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html"
},
@@ -27810,10 +28192,6 @@
"url": "/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013.html"
},
{
- "path": "shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-014.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-014.html"
- },
- {
"path": "shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001.html",
"url": "/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001.html"
},
@@ -27834,38 +28212,6 @@
"url": "/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010.html"
},
{
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-001.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-002.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-002.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-003.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-003.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-005.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-005.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-006.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-006.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-001.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-002.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-002.html"
- },
- {
- "path": "shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-004.html",
- "url": "/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-004.html"
- },
- {
"path": "shadow-dom/untriaged/events/event-dispatch/test-001.html",
"url": "/shadow-dom/untriaged/events/event-dispatch/test-001.html"
},
@@ -27882,10 +28228,6 @@
"url": "/shadow-dom/untriaged/events/event-retargeting/test-001.html"
},
{
- "path": "shadow-dom/untriaged/events/event-retargeting/test-002.html",
- "url": "/shadow-dom/untriaged/events/event-retargeting/test-002.html"
- },
- {
"path": "shadow-dom/untriaged/events/event-retargeting/test-003.html",
"url": "/shadow-dom/untriaged/events/event-retargeting/test-003.html"
},
@@ -27994,70 +28336,10 @@
"url": "/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-002.html"
},
{
- "path": "shadow-dom/untriaged/shadow-trees/composition/test-001.html",
- "url": "/shadow-dom/untriaged/shadow-trees/composition/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-001.html",
- "url": "/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-002.html",
- "url": "/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-002.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/custom-pseudo-elements/test-001.html",
- "url": "/shadow-dom/untriaged/shadow-trees/custom-pseudo-elements/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-003.html",
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-003.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-003.html",
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-003.html"
- },
- {
"path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-004.html",
"url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-004.html"
},
{
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-005.html",
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-005.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/nested-shadow-trees/test-001.html",
- "url": "/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/rendering-shadow-trees/test-001.html",
- "url": "/shadow-dom/untriaged/shadow-trees/rendering-shadow-trees/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/reprojection/test-001.html",
- "url": "/shadow-dom/untriaged/shadow-trees/reprojection/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-001.html",
- "url": "/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-001.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-002.html",
- "url": "/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-002.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-003.html",
- "url": "/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-003.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-004.html",
- "url": "/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-004.html"
- },
- {
- "path": "shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-005.html",
- "url": "/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-005.html"
- },
- {
"path": "shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html",
"url": "/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html"
},
@@ -28118,14 +28400,6 @@
"url": "/shadow-dom/untriaged/styles/css-variables/test-001.html"
},
{
- "path": "shadow-dom/untriaged/styles/deep-combinator/deep-combinator-001.html",
- "url": "/shadow-dom/untriaged/styles/deep-combinator/deep-combinator-001.html"
- },
- {
- "path": "shadow-dom/untriaged/styles/shadow-pseudoelement/shadow-pseudoelement-001.html",
- "url": "/shadow-dom/untriaged/styles/shadow-pseudoelement/shadow-pseudoelement-001.html"
- },
- {
"path": "shadow-dom/untriaged/styles/test-001.html",
"url": "/shadow-dom/untriaged/styles/test-001.html"
},
@@ -28138,18 +28412,10 @@
"url": "/shadow-dom/untriaged/styles/test-005.html"
},
{
- "path": "shadow-dom/untriaged/styles/test-007.html",
- "url": "/shadow-dom/untriaged/styles/test-007.html"
- },
- {
"path": "shadow-dom/untriaged/styles/test-008.html",
"url": "/shadow-dom/untriaged/styles/test-008.html"
},
{
- "path": "shadow-dom/untriaged/styles/test-009.html",
- "url": "/shadow-dom/untriaged/styles/test-009.html"
- },
- {
"path": "shadow-dom/untriaged/styles/test-010.html",
"url": "/shadow-dom/untriaged/styles/test-010.html"
},
@@ -28410,6 +28676,14 @@
"url": "/web-animations/animatable/animate.html"
},
{
+ "path": "web-animations/animation-effect-timing/delay.html",
+ "url": "/web-animations/animation-effect-timing/delay.html"
+ },
+ {
+ "path": "web-animations/animation-effect-timing/direction.html",
+ "url": "/web-animations/animation-effect-timing/direction.html"
+ },
+ {
"path": "web-animations/animation-effect-timing/duration.html",
"url": "/web-animations/animation-effect-timing/duration.html"
},
@@ -28430,48 +28704,40 @@
"url": "/web-animations/animation-effect-timing/iterationStart.html"
},
{
- "path": "web-animations/animation-node/animation-node-after.html",
- "url": "/web-animations/animation-node/animation-node-after.html"
- },
- {
- "path": "web-animations/animation-node/animation-node-before.html",
- "url": "/web-animations/animation-node/animation-node-before.html"
- },
- {
- "path": "web-animations/animation-node/animation-node-next-sibling.html",
- "url": "/web-animations/animation-node/animation-node-next-sibling.html"
+ "path": "web-animations/animation-effect-timing/iterations.html",
+ "url": "/web-animations/animation-effect-timing/iterations.html"
},
{
- "path": "web-animations/animation-node/animation-node-parent.html",
- "url": "/web-animations/animation-node/animation-node-parent.html"
+ "path": "web-animations/animation-timeline/document-timeline.html",
+ "url": "/web-animations/animation-timeline/document-timeline.html"
},
{
- "path": "web-animations/animation-node/animation-node-previous-sibling.html",
- "url": "/web-animations/animation-node/animation-node-previous-sibling.html"
+ "path": "web-animations/animation-timeline/idlharness.html",
+ "url": "/web-animations/animation-timeline/idlharness.html"
},
{
- "path": "web-animations/animation-node/animation-node-remove.html",
- "url": "/web-animations/animation-node/animation-node-remove.html"
+ "path": "web-animations/animation/cancel.html",
+ "url": "/web-animations/animation/cancel.html"
},
{
- "path": "web-animations/animation-node/animation-node-replace.html",
- "url": "/web-animations/animation-node/animation-node-replace.html"
+ "path": "web-animations/animation/constructor.html",
+ "url": "/web-animations/animation/constructor.html"
},
{
- "path": "web-animations/animation-node/idlharness.html",
- "url": "/web-animations/animation-node/idlharness.html"
+ "path": "web-animations/animation/finish.html",
+ "url": "/web-animations/animation/finish.html"
},
{
- "path": "web-animations/animation-timeline/document-timeline.html",
- "url": "/web-animations/animation-timeline/document-timeline.html"
+ "path": "web-animations/animation/play.html",
+ "url": "/web-animations/animation/play.html"
},
{
- "path": "web-animations/animation-timeline/idlharness.html",
- "url": "/web-animations/animation-timeline/idlharness.html"
+ "path": "web-animations/animation/playState.html",
+ "url": "/web-animations/animation/playState.html"
},
{
- "path": "web-animations/animation/constructor.html",
- "url": "/web-animations/animation/constructor.html"
+ "path": "web-animations/animation/playbackRate.html",
+ "url": "/web-animations/animation/playbackRate.html"
},
{
"path": "web-animations/keyframe-effect/constructor.html",
@@ -34514,6 +34780,16 @@
"url": "/selection/addRange.html"
},
{
+ "path": "selection/collapse.html",
+ "timeout": "long",
+ "url": "/selection/collapse.html"
+ },
+ {
+ "path": "selection/extend.html",
+ "timeout": "long",
+ "url": "/selection/extend.html"
+ },
+ {
"path": "service-workers/cache-storage/common.https.html",
"timeout": "long",
"url": "/service-workers/cache-storage/common.https.html"
@@ -34644,6 +34920,41 @@
"url": "/service-workers/cache-storage/worker/cache-storage.https.html"
},
{
+ "path": "service-workers/service-worker/fetch-event-redirect.https.html",
+ "timeout": "long",
+ "url": "/service-workers/service-worker/fetch-event-redirect.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-frame-resource.https.html",
+ "timeout": "long",
+ "url": "/service-workers/service-worker/fetch-frame-resource.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-mixed-content-to-inscope.https.html",
+ "timeout": "long",
+ "url": "/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-mixed-content-to-outscope.https.html",
+ "timeout": "long",
+ "url": "/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-request-redirect.https.html",
+ "timeout": "long",
+ "url": "/service-workers/service-worker/fetch-request-redirect.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/fetch-waits-for-activate.https.html",
+ "timeout": "long",
+ "url": "/service-workers/service-worker/fetch-waits-for-activate.https.html"
+ },
+ {
+ "path": "service-workers/service-worker/register-closed-window.https.html",
+ "timeout": "long",
+ "url": "/service-workers/service-worker/register-closed-window.https.html"
+ },
+ {
"path": "websockets/binary/002.html",
"timeout": "long",
"url": "/websockets/binary/002.html"
@@ -34749,5443 +35060,22 @@
"local_changes": {
"deleted": [],
"items": {
- "reftest": {
- "2dcontext/building-paths/canvas_complexshapes_arcto_001.htm": [
- {
- "path": "2dcontext/building-paths/canvas_complexshapes_arcto_001.htm",
- "references": [
- [
- "/2dcontext/building-paths/canvas_complexshapes_arcto_001-ref.htm",
- "=="
- ]
- ],
- "url": "/2dcontext/building-paths/canvas_complexshapes_arcto_001.htm"
- }
- ],
- "2dcontext/building-paths/canvas_complexshapes_beziercurveto_001.htm": [
- {
- "path": "2dcontext/building-paths/canvas_complexshapes_beziercurveto_001.htm",
- "references": [
- [
- "/2dcontext/building-paths/canvas_complexshapes_beziercurveto_001-ref.htm",
- "=="
- ]
- ],
- "url": "/2dcontext/building-paths/canvas_complexshapes_beziercurveto_001.htm"
- }
- ],
- "2dcontext/compositing/canvas_compositing_globalcompositeoperation_001.htm": [
- {
- "path": "2dcontext/compositing/canvas_compositing_globalcompositeoperation_001.htm",
- "references": [
- [
- "/2dcontext/compositing/canvas_compositing_globalcompositeoperation_001-ref.htm",
- "=="
- ]
- ],
- "url": "/2dcontext/compositing/canvas_compositing_globalcompositeoperation_001.htm"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_1.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_1.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_1_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_1.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_10.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_10.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_10_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_10.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_11.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_11.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_11_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_11.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_12.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_12.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_12_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_12.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_2.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_2.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_2_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_2.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_3.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_3.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_3_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_3.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_4.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_4.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_4_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_4.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_5.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_5.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_5_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_5.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_6.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_6.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_6_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_6.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_7.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_7.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_7_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_7.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_8.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_8.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_8_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_8.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_9.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_canvas_9.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_9_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_canvas_9.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_1.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_1.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_1_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_1.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_10.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_10.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_10_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_10.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_11.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_11.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_11_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_11.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_12.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_12.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_12_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_12.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_13.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_13.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_13_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_13.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_2.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_2.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_2_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_2.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_3.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_3.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_3_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_3.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_4.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_4.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_4_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_4.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_5.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_5.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_5_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_5.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_6.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_6.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_6_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_6.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_7.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_7.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_7_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_7.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_8.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_8.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_8_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_8.html"
- }
- ],
- "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_9.html": [
- {
- "path": "2dcontext/drawing-images-to-the-canvas/drawimage_html_image_9.html",
- "references": [
- [
- "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_9_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/drawing-images-to-the-canvas/drawimage_html_image_9.html"
- }
- ],
- "2dcontext/line-styles/canvas_linestyles_linecap_001.htm": [
- {
- "path": "2dcontext/line-styles/canvas_linestyles_linecap_001.htm",
- "references": [
- [
- "/2dcontext/line-styles/canvas_linestyles_linecap_001-ref.htm",
- "=="
- ]
- ],
- "url": "/2dcontext/line-styles/canvas_linestyles_linecap_001.htm"
- }
- ],
- "2dcontext/line-styles/lineto_a.html": [
- {
- "path": "2dcontext/line-styles/lineto_a.html",
- "references": [
- [
- "/2dcontext/line-styles/lineto_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/line-styles/lineto_a.html"
- }
- ],
- "2dcontext/shadows/canvas_shadows_002.htm": [
- {
- "path": "2dcontext/shadows/canvas_shadows_002.htm",
- "references": [
- [
- "/2dcontext/shadows/canvas_shadows_002-ref.htm",
- "=="
- ]
- ],
- "url": "/2dcontext/shadows/canvas_shadows_002.htm"
- }
- ],
- "2dcontext/the-canvas-state/canvas_state_restore_001.htm": [
- {
- "path": "2dcontext/the-canvas-state/canvas_state_restore_001.htm",
- "references": [
- [
- "/2dcontext/the-canvas-state/canvas_state_restore_001-ref.htm",
- "=="
- ]
- ],
- "url": "/2dcontext/the-canvas-state/canvas_state_restore_001.htm"
- }
- ],
- "2dcontext/transformations/canvas_transformations_reset_001.html": [
- {
- "path": "2dcontext/transformations/canvas_transformations_reset_001.html",
- "references": [
- [
- "/2dcontext/transformations/canvas_transformations_reset_001-ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/transformations/canvas_transformations_reset_001.html"
- }
- ],
- "2dcontext/transformations/canvas_transformations_scale_001.htm": [
- {
- "path": "2dcontext/transformations/canvas_transformations_scale_001.htm",
- "references": [
- [
- "/2dcontext/transformations/canvas_transformations_scale_001-ref.htm",
- "=="
- ]
- ],
- "url": "/2dcontext/transformations/canvas_transformations_scale_001.htm"
- }
- ],
- "2dcontext/transformations/transform_a.html": [
- {
- "path": "2dcontext/transformations/transform_a.html",
- "references": [
- [
- "/2dcontext/transformations/transform_ref.html",
- "=="
- ]
- ],
- "url": "/2dcontext/transformations/transform_a.html"
- }
- ],
- "FileAPI/url/url_xmlhttprequest_img.html": [
- {
- "path": "FileAPI/url/url_xmlhttprequest_img.html",
- "references": [
- [
- "/FileAPI/url/url_xmlhttprequest_img-ref.html",
- "=="
- ]
- ],
- "url": "/FileAPI/url/url_xmlhttprequest_img.html"
- }
- ],
- "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html": [
- {
- "path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html",
- "references": [
- [
- "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag-ref.html",
- "=="
- ]
- ],
- "url": "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html"
- }
- ],
- "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-custom-tag.html": [
- {
- "path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-custom-tag.html",
- "references": [
- [
- "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-custom-tag-ref.html",
- "=="
- ]
- ],
- "url": "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-custom-tag.html"
- }
- ],
- "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-type-extension.html": [
- {
- "path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-type-extension.html",
- "references": [
- [
- "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-type-extension-ref.html",
- "=="
- ]
- ],
- "url": "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-registered-type-extension.html"
- }
- ],
- "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-type-extension.html": [
- {
- "path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-type-extension.html",
- "references": [
- [
- "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-type-extension-ref.html",
- "=="
- ]
- ],
- "url": "/custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-type-extension.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-EN-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-EN-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-EN-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-EN-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-EN-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-EN-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-EN-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-EN-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-N-EN-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-N-EN-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-N-EN-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-N-EN-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-N-EN-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-N-EN-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-N-EN-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-N-EN-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-N-EN.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-N-EN.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-N-EN.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-N-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-N-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-N-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-N-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-N-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-N-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-N-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-N-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-bdi-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-bdi-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-bdi-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-bdi-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-bdi-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-bdi-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-bdi-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-bdi-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-dir-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-dir-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-dir-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-dir-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-dir-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-dir-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-dir-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-dir-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-script-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-script-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-script-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-script-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-script-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-script-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-script-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-script-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-style-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-style-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-style-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-style-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-style-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-style-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-style-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-style-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-textarea-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-textarea-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-textarea-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-textarea-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-contained-textarea-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-contained-textarea-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-contained-textarea-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-contained-textarea-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-EN-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-EN-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-EN-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-EN-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-EN-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-EN-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-EN-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-EN-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-N-EN-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-N-EN-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-N-EN-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-N-EN-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-N-EN-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-N-EN-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-N-EN-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-N-EN-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-N-EN.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-N-EN.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-N-EN-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-N-EN.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-N-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-N-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-N-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-N-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-N-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-N-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-N-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-N-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-EN-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-EN-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-EN-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-EN-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-EN-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-EN-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-EN-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-EN-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-N-EN.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-N-EN.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-N-EN.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-N-L.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-N-L.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-N-L-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-N-L.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-N-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-N-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-N-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-N-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-input-script-R.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-input-script-R.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-input-script-R-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-input-script-R.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-isolate.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-isolate.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-isolate-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-isolate.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-pre-N-EN.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-pre-N-EN.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-pre-N-EN-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-pre-N-EN.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-pre-mixed.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-pre-mixed.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-pre-mixed-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-pre-mixed.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-textarea-N-EN.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-textarea-N-EN.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-textarea-N-EN-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-textarea-N-EN.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-textarea-mixed.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-textarea-mixed.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-textarea-mixed-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-textarea-mixed.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs.html"
- }
- ],
- "html/dom/elements/global-attributes/dir_auto-textarea-script-mixed.html": [
- {
- "path": "html/dom/elements/global-attributes/dir_auto-textarea-script-mixed.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed.html"
- }
- ],
- "html/dom/elements/global-attributes/lang-xmllang-01.html": [
- {
- "path": "html/dom/elements/global-attributes/lang-xmllang-01.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/lang-xmllang-01-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/lang-xmllang-01.html"
- }
- ],
- "html/dom/elements/global-attributes/lang-xyzzy.html": [
- {
- "path": "html/dom/elements/global-attributes/lang-xyzzy.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/lang-xyzzy-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/lang-xyzzy.html"
- }
- ],
- "html/dom/elements/global-attributes/style-01.html": [
- {
- "path": "html/dom/elements/global-attributes/style-01.html",
- "references": [
- [
- "/html/dom/elements/global-attributes/style-01-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/global-attributes/style-01.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002a-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002b-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002c-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-003-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-003-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-003-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-004-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-004-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-004-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-005-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-005-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-005-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006c-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-007-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-007-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-007-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-008-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-008-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-008-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008c.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009b-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html"
- }
- ],
- "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html": [
- {
- "path": "html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html",
- "references": [
- [
- "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009b-ref.html",
- "=="
- ]
- ],
- "url": "/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html"
- }
- ],
- "html/editing/the-hidden-attribute/hidden-2.svg": [
- {
- "path": "html/editing/the-hidden-attribute/hidden-2.svg",
- "references": [
- [
- "/html/editing/the-hidden-attribute/hidden-2-ref.svg",
- "=="
- ]
- ],
- "url": "/html/editing/the-hidden-attribute/hidden-2.svg"
- }
- ],
- "html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type.html": [
- {
- "path": "html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type.html",
- "references": [
- [
- "/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type.html"
- }
- ],
- "html/rendering/bindings/the-select-element-0/option-label.html": [
- {
- "path": "html/rendering/bindings/the-select-element-0/option-label.html",
- "references": [
- [
- "/html/rendering/bindings/the-select-element-0/option-label-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/bindings/the-select-element-0/option-label.html"
- }
- ],
- "html/rendering/bindings/the-textarea-element-0/cols-default.html": [
- {
- "path": "html/rendering/bindings/the-textarea-element-0/cols-default.html",
- "references": [
- [
- "/html/rendering/bindings/the-textarea-element-0/textarea-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/bindings/the-textarea-element-0/cols-default.html"
- }
- ],
- "html/rendering/bindings/the-textarea-element-0/cols-zero.html": [
- {
- "path": "html/rendering/bindings/the-textarea-element-0/cols-zero.html",
- "references": [
- [
- "/html/rendering/bindings/the-textarea-element-0/textarea-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/bindings/the-textarea-element-0/cols-zero.html"
- }
- ],
- "html/rendering/bindings/the-textarea-element-0/rows-default.html": [
- {
- "path": "html/rendering/bindings/the-textarea-element-0/rows-default.html",
- "references": [
- [
- "/html/rendering/bindings/the-textarea-element-0/textarea-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/bindings/the-textarea-element-0/rows-default.html"
- }
- ],
- "html/rendering/bindings/the-textarea-element-0/rows-zero.html": [
- {
- "path": "html/rendering/bindings/the-textarea-element-0/rows-zero.html",
- "references": [
- [
- "/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/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",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/flow-content-0/figure.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/li-type-supported-xhtml.xhtml": [
- {
- "path": "html/rendering/non-replaced-elements/lists/li-type-supported-xhtml.xhtml",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/li-type-supported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/li-type-supported-xhtml.xhtml"
- }
- ],
- "html/rendering/non-replaced-elements/lists/li-type-supported.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/li-type-supported.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/li-type-supported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/li-type-supported.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-supported-xhtml.xhtml": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-supported-xhtml.xhtml",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-supported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-supported-xhtml.xhtml"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-supported.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-supported.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-supported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-supported.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-circle.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-circle.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-circle.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-roman.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-roman.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-roman.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-none.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-none.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-none.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-round.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-round.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-round.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-square.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-square.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-square.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-alpha.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-alpha.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-alpha.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-roman.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-roman.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-roman.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-supported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-supported.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-supported.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-supported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-supported.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html"
- }
- ],
- "html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html": [
- {
- "path": "html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html"
- }
- ],
- "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html": [
- {
- "path": "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html"
- }
- ],
- "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-q.html": [
- {
- "path": "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-q.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-q.html"
- }
- ],
- "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-s.html": [
- {
- "path": "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-s.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-s.html"
- }
- ],
- "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-x.xhtml": [
- {
- "path": "html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-x.xhtml",
- "references": [
- [
- "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-x.xhtml"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-border-1.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-border-1.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-border-1-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-border-1.html"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-border-2.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-border-2.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-border-2-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-border-2.html"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-cell-width-s.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-cell-width-s.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-cell-width-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-cell-width-s.html"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-cell-width.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-cell-width.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-cell-width-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-cell-width.html"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-layout.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-layout.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-layout-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-layout.html"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-width-150percent.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-width-150percent.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-width-150percent-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-width-150percent.html"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-width-s.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-width-s.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-width-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-width-s.html"
- }
- ],
- "html/rendering/non-replaced-elements/tables/table-width.html": [
- {
- "path": "html/rendering/non-replaced-elements/tables/table-width.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/tables/table-width-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/tables/table-width.html"
- }
- ],
- "html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html": [
- {
- "path": "html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/the-fieldset-element-0/ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html"
- }
- ],
- "html/rendering/non-replaced-elements/the-hr-element-0/color.html": [
- {
- "path": "html/rendering/non-replaced-elements/the-hr-element-0/color.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/the-hr-element-0/color-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/the-hr-element-0/color.html"
- }
- ],
- "html/rendering/non-replaced-elements/the-hr-element-0/width.html": [
- {
- "path": "html/rendering/non-replaced-elements/the-hr-element-0/width.html",
- "references": [
- [
- "/html/rendering/non-replaced-elements/the-hr-element-0/width-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/the-hr-element-0/width.html"
- }
- ],
- "html/rendering/non-replaced-elements/the-page/body_text_00ffff.xhtml": [
- {
- "path": "html/rendering/non-replaced-elements/the-page/body_text_00ffff.xhtml",
- "references": [
- [
- "/html/rendering/non-replaced-elements/the-page/body_text_00ffff-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/non-replaced-elements/the-page/body_text_00ffff.xhtml"
- }
- ],
- "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim.html": [
- {
- "path": "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim.html",
- "references": [
- [
- "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim.html"
- }
- ],
- "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border_percent.xhtml": [
- {
- "path": "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border_percent.xhtml",
- "references": [
- [
- "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border-ref.xhtml",
- "=="
- ]
- ],
- "url": "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border_percent.xhtml"
- }
- ],
- "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml": [
- {
- "path": "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml",
- "references": [
- [
- "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml",
- "=="
- ]
- ],
- "url": "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml"
- }
- ],
- "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_pixel.xhtml": [
- {
- "path": "html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_pixel.xhtml",
- "references": [
- [
- "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml",
- "=="
- ]
- ],
- "url": "/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_pixel.xhtml"
- }
- ],
- "html/rendering/replaced-elements/images/space.html": [
- {
- "path": "html/rendering/replaced-elements/images/space.html",
- "references": [
- [
- "/html/rendering/replaced-elements/images/space-ref.html",
- "=="
- ]
- ],
- "url": "/html/rendering/replaced-elements/images/space.html"
- }
- ],
- "html/semantics/document-metadata/the-style-element/html_style_in_comment.xhtml": [
- {
- "path": "html/semantics/document-metadata/the-style-element/html_style_in_comment.xhtml",
- "references": [
- [
- "/html/semantics/document-metadata/the-style-element/html_style_in_comment-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/document-metadata/the-style-element/html_style_in_comment.xhtml"
- }
- ],
- "html/semantics/embedded-content/the-audio-element/audio_001.htm": [
- {
- "path": "html/semantics/embedded-content/the-audio-element/audio_001.htm",
- "references": [
- [
- "/html/semantics/embedded-content/the-audio-element/audio_content-ref.htm",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-audio-element/audio_001.htm"
- }
- ],
- "html/semantics/embedded-content/the-audio-element/audio_002.htm": [
- {
- "path": "html/semantics/embedded-content/the-audio-element/audio_002.htm",
- "references": [
- [
- "/html/semantics/embedded-content/the-audio-element/audio_content-ref.htm",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-audio-element/audio_002.htm"
- }
- ],
- "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html": [
- {
- "path": "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html",
- "references": [
- [
- "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html"
- }
- ],
- "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html": [
- {
- "path": "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html",
- "references": [
- [
- "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html"
- }
- ],
- "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-03.html": [
- {
- "path": "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-03.html",
- "references": [
- [
- "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-03.html"
- }
- ],
- "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html": [
- {
- "path": "html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html",
- "references": [
- [
- "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html"
- }
- ],
- "html/semantics/embedded-content/the-video-element/video_content_image.htm": [
- {
- "path": "html/semantics/embedded-content/the-video-element/video_content_image.htm",
- "references": [
- [
- "/html/semantics/embedded-content/the-video-element/video_content-ref.htm",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-video-element/video_content_image.htm"
- }
- ],
- "html/semantics/embedded-content/the-video-element/video_content_text.htm": [
- {
- "path": "html/semantics/embedded-content/the-video-element/video_content_text.htm",
- "references": [
- [
- "/html/semantics/embedded-content/the-video-element/video_content-ref.htm",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-video-element/video_content_text.htm"
- }
- ],
- "html/semantics/embedded-content/the-video-element/video_dynamic_poster_absolute.htm": [
- {
- "path": "html/semantics/embedded-content/the-video-element/video_dynamic_poster_absolute.htm",
- "references": [
- [
- "/html/semantics/embedded-content/the-video-element/video_dynamic_poster-ref.htm",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-video-element/video_dynamic_poster_absolute.htm"
- }
- ],
- "html/semantics/embedded-content/the-video-element/video_dynamic_poster_relative.htm": [
- {
- "path": "html/semantics/embedded-content/the-video-element/video_dynamic_poster_relative.htm",
- "references": [
- [
- "/html/semantics/embedded-content/the-video-element/video_dynamic_poster-ref.htm",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-video-element/video_dynamic_poster_relative.htm"
- }
- ],
- "html/semantics/embedded-content/the-video-element/video_initially_paused.html": [
- {
- "path": "html/semantics/embedded-content/the-video-element/video_initially_paused.html",
- "references": [
- [
- "/html/semantics/embedded-content/the-video-element/video_initially_paused-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/embedded-content/the-video-element/video_initially_paused.html"
- }
- ],
- "html/semantics/forms/the-input-element/image01.html": [
- {
- "path": "html/semantics/forms/the-input-element/image01.html",
- "references": [
- [
- "/html/semantics/forms/the-input-element/image01-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/forms/the-input-element/image01.html"
- }
- ],
- "html/semantics/forms/the-textarea-element/textarea-newline-bidi.html": [
- {
- "path": "html/semantics/forms/the-textarea-element/textarea-newline-bidi.html",
- "references": [
- [
- "/html/semantics/forms/the-textarea-element/textarea-newline-bidi-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/forms/the-textarea-element/textarea-newline-bidi.html"
- }
- ],
- "html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html": [
- {
- "path": "html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html",
- "references": [
- [
- "/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html"
- }
- ],
- "html/semantics/grouping-content/the-ol-element/reversed-2.html": [
- {
- "path": "html/semantics/grouping-content/the-ol-element/reversed-2.html",
- "references": [
- [
- "/html/semantics/grouping-content/the-ol-element/reversed-2-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/grouping-content/the-ol-element/reversed-2.html"
- }
- ],
- "html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html": [
- {
- "path": "html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html",
- "references": [
- [
- "/html/semantics/grouping-content/the-pre-element/pre-newline-bidi-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html"
- }
- ],
- "html/semantics/links/linktypes/alternate-css.html": [
- {
- "path": "html/semantics/links/linktypes/alternate-css.html",
- "references": [
- [
- "/html/semantics/links/linktypes/alternate-css-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/links/linktypes/alternate-css.html"
- }
- ],
- "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html": [
- {
- "path": "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html",
- "references": [
- [
- "/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html"
- }
- ],
- "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html": [
- {
- "path": "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html",
- "references": [
- [
- "/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html"
- }
- ],
- "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html": [
- {
- "path": "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html",
- "references": [
- [
- "/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdo-element/bdo-child.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdo-element/bdo-child.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdo-element/bdo-child.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdo-element/bdo-ltr.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdo-element/bdo-ltr.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdo-element/bdo-ltr.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdo-element/bdo-override.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdo-element/bdo-override.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdo-element/bdo-override.html"
- }
- ],
- "html/semantics/text-level-semantics/the-bdo-element/bidi-001.html": [
- {
- "path": "html/semantics/text-level-semantics/the-bdo-element/bidi-001.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-bdo-element/bidi-001.html"
- }
- ],
- "html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors.html": [
- {
- "path": "html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors.html"
- }
- ],
- "html/semantics/text-level-semantics/the-br-element/br-bidi.html": [
- {
- "path": "html/semantics/text-level-semantics/the-br-element/br-bidi.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-br-element/br-bidi-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-br-element/br-bidi.html"
- }
- ],
- "html/semantics/text-level-semantics/the-wbr-element/wbr-element.html": [
- {
- "path": "html/semantics/text-level-semantics/the-wbr-element/wbr-element.html",
- "references": [
- [
- "/html/semantics/text-level-semantics/the-wbr-element/wbr-element-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/text-level-semantics/the-wbr-element/wbr-element.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/shadow-root-001.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/shadow-root-001.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/shadow-root-001-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/shadow-root-001.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/shadow-root-002.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/shadow-root-002.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/shadow-root-002-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/shadow-root-002.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/text-decoration-001.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/text-decoration-001.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/text-decoration-001.html"
- }
- ],
- "shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html": [
- {
- "path": "shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html",
- "references": [
- [
- "/shadow-dom/untriaged/styles/not-apply-in-shadow-root-001-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_completely_move_up.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_down.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_up.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_up.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_up-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/2_cues_overlapping_partially_move_up.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/2_tracks.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/2_tracks.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/2_tracks-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/2_tracks.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/3_tracks.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/3_tracks.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/3_tracks-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/3_tracks.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_end.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_end.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_end-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_end.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_end_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_end_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_end_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_middle.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_middle.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_middle-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_middle.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_middle_position_50.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_middle_position_50.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_50-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_50.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_middle_position_gt_50.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_middle_position_gt_50.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_gt_50-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_gt_50.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50_size_gt_maximum_size.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50_size_gt_maximum_size.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50_size_gt_maximum_size-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_middle_position_lt_50_size_gt_maximum_size.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_middle_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_middle_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_middle_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_middle_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_start.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_start.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_start-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_start.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/align_start_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/align_start_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/align_start_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/audio_has_no_subtitles.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/audio_has_no_subtitles.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/audio_has_no_subtitles-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/audio_has_no_subtitles.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/basic.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/basic.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/basic-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/basic.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/bidi_ruby.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/u002E_LF_u05D0.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/u002E_LF_u05D0.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_LF_u05D0-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_LF_u05D0.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2028_u05D0.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2028_u05D0.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2028_u05D0-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2028_u05D0.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2029_u05D0.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2029_u05D0.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2029_u05D0-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/u002E_u2029_u05D0.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/u0041_first.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/u0041_first.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/u0041_first-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/u0041_first.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/u05D0_first.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/u05D0_first.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/u05D0_first-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/u05D0_first.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/u0628_first.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/u0628_first.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/u0628_first-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/u0628_first.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/bidi/u06E9_no_strong_dir.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/bidi/u06E9_no_strong_dir.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/bidi/u06E9_no_strong_dir-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/bidi/u06E9_no_strong_dir.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/cue_too_long.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/cue_too_long.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/cue_too_long-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/cue_too_long.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/decode_escaped_entities.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/decode_escaped_entities.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/decode_escaped_entities-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/decode_escaped_entities.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/disable_controls_reposition.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size_while_paused.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size_while_paused.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size_while_paused-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_align_position_line_size_while_paused.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_line.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text_while_paused.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text_while_paused.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text_while_paused-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/dom_override_cue_text_while_paused.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/dom_override_remove_cue_while_paused.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/dom_override_remove_cue_while_paused.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/dom_override_remove_cue_while_paused-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/dom_override_remove_cue_while_paused.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/enable_controls_reposition.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/enable_controls_reposition.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/enable_controls_reposition-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/enable_controls_reposition.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/evil/9_cues_overlapping_completely_all_cues_have_same_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/evil/media_404_omit_subtitles.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/evil/media_404_omit_subtitles.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/evil/media_404_omit_subtitles-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/evil/media_404_omit_subtitles.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/evil/media_height_19.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/evil/media_height_19.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/evil/media_height_19-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/evil/media_height_19.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/evil/single_quote.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/evil/single_quote.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/evil/single_quote-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/evil/single_quote.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/evil/size_90.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/evil/size_90.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/evil/size_90-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/evil/size_90.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/evil/size_99.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/evil/size_99.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/evil/size_99-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/evil/size_99.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_-2_wrapped_cue_grow_upwards.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_-2_wrapped_cue_grow_upwards.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_-2_wrapped_cue_grow_upwards-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_-2_wrapped_cue_grow_upwards.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_0_is_top.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_0_is_top.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_0_is_top-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_0_is_top.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_1_wrapped_cue_grow_downwards.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_50_percent.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_50_percent.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_50_percent-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_50_percent.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap_move_up.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap_move_up.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap_move_up-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_integer_and_percent_mixed_overlap_move_up.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap_move_up.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap_move_up.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap_move_up-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/line_percent_and_integer_mixed_overlap_move_up.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/media_height400_with_controls.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/media_height400_with_controls.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/media_height400_with_controls-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/media_height400_with_controls.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/media_with_controls.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/media_with_controls.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/media_with_controls-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/media_with_controls.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/navigate_cue_position.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/navigate_cue_position.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/navigate_cue_position-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/navigate_cue_position.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/one_line_cue_plus_wrapped_cue.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/one_line_cue_plus_wrapped_cue.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/one_line_cue_plus_wrapped_cue-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/one_line_cue_plus_wrapped_cue.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/repaint.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/repaint.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/repaint-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/repaint.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand_css_relative_url.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand_css_relative_url.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand_css_relative_url-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/background_shorthand_css_relative_url.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hex.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hex.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hex-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hex.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hsla.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hsla.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hsla-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_hsla.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_rgba.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_rgba.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_rgba-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/color_rgba.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/cue_selector_single_colon.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/cue_selector_single_colon.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/cue_selector_single_colon-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/cue_selector_single_colon.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/font_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/inherit_values_from_media_element.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/inherit_values_from_media_element.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/inherit_values_from_media_element-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/inherit_values_from_media_element.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/outline_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline_underline_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline_underline_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline_underline_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_overline_underline_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_underline.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_underline.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_underline-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-decoration_underline.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-shadow.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-shadow.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-shadow-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/text-shadow.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_normal_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_normal_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_normal_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_normal_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_nowrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_nowrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_nowrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_nowrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-line_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-line_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-line_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-line_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-wrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue/white-space_pre_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_box.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_box.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_box-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_box.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand_css_relative_url.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand_css_relative_url.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand_css_relative_url-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/background_shorthand_css_relative_url.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_animation_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_animation_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_animation_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_animation_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_background_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_color.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_color.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_color-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_color.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_font_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_namespace.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_namespace.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_namespace-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_namespace.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_outline_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-decoration_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-decoration_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-decoration_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-decoration_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-shadow.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-shadow.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-shadow-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_text-shadow.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_future.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_future.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_future-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_future.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_past.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_past.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_past-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_timestamp_past.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_transition_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_transition_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_transition_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_transition_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_normal_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_normal_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_normal_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_normal_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_nowrap.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_nowrap.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_nowrap-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_nowrap.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-line_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-line_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-line_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-line_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-wrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-wrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-wrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre-wrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_white-space_pre_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class_object_specific_selector.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class_object_specific_selector.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class_object_specific_selector-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/bold_object/bold_with_class_object_specific_selector.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_animation_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_animation_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_animation_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_animation_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_background_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_color.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_color.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_color-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_color.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_font_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_namespace.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_namespace.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_namespace-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_namespace.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_outline_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-decoration_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-decoration_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-decoration_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-decoration_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-shadow.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-shadow.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-shadow-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_text-shadow.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_past.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_past.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_past-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_past.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_transition_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_transition_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_transition_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_transition_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_normal_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_nowrap.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_nowrap.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_nowrap-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_nowrap.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-line_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre-wrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_white-space_pre_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class_object_specific_selector.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class_object_specific_selector.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class_object_specific_selector-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_with_class_object_specific_selector.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hex.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hex.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hex-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hex.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hsla.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hsla.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hsla-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_hsla.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_rgba.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_rgba.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_rgba-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/color_rgba.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/cue_func_selector_single_colon.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/cue_func_selector_single_colon.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/cue_func_selector_single_colon-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/cue_func_selector_single_colon.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/font_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/id_color.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/id_color.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/id_color-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/id_color.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/inherit_values_from_media_element.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/inherit_values_from_media_element.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/inherit_values_from_media_element-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/inherit_values_from_media_element.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_animation_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_animation_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_animation_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_animation_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_background_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_color.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_color.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_color-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_color.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_font_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_namespace.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_namespace.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_namespace-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_namespace.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_outline_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-decoration_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-decoration_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-decoration_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-decoration_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-shadow.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-shadow.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-shadow-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_text-shadow.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_future.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_future.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_future-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_future.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_past.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_past.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_past-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_timestamp_past.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_transition_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_transition_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_transition_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_transition_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_normal_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_normal_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_normal_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_normal_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_nowrap.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_nowrap.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_nowrap-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_nowrap.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-line_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-line_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-line_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-line_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre-wrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_white-space_pre_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class_object_specific_selector.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class_object_specific_selector.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class_object_specific_selector-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/italic_object/italic_with_class_object_specific_selector.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_allowed_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_allowed_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_allowed_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_allowed_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_root_selector.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_root_selector.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_root_selector-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/not_root_selector.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/outline_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_namespace.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_namespace.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_namespace-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_namespace.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_selector.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_selector.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_selector-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/root_selector.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline_underline_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline_underline_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline_underline_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_overline_underline_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_underline.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_underline.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_underline-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-decoration_underline.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-shadow.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-shadow.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-shadow-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/text-shadow.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/type_selector_root.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/type_selector_root.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/type_selector_root-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/type_selector_root.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_animation_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_animation_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_animation_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_animation_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_background_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_color.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_color.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_color-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_color.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_font_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_namespace.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_namespace.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_namespace-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_namespace.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_outline_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-decoration_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-decoration_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-decoration_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-decoration_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-shadow.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-shadow.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-shadow-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_text-shadow.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_future.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_future.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_future-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_future.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_past.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_past.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_past-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_timestamp_past.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_transition_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_transition_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_transition_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_transition_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_normal_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_normal_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_normal_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_normal_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_nowrap.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_nowrap.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_nowrap-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_nowrap.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-line_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-line_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-line_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-line_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre-wrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_white-space_pre_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/underline_object/underline_with_class_object_specific_selector.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_animation_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_animation_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_animation_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_animation_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_background_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_color.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_color.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_color-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_color.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_font_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_namespace.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_namespace.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_namespace-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_namespace.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_properties.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_properties.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_properties-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_properties.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_shorthand.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_shorthand.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_shorthand-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_outline_shorthand.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-decoration_line-through.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-decoration_line-through.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-decoration_line-through-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-decoration_line-through.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-shadow.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-shadow.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-shadow-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_text-shadow.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_future.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_future.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_future-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_future.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_past.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_past.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_past-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_timestamp_past.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_transition_with_timestamp.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_transition_with_timestamp.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_transition_with_timestamp-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_transition_with_timestamp.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_voice_attribute.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_voice_attribute.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_voice_attribute-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_voice_attribute.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_normal_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_normal_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_normal_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_normal_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_nowrap.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_nowrap.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_nowrap-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_nowrap.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-line_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-line_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-line_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-line_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre-wrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_white-space_pre_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class_object_specific_selector.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class_object_specific_selector.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class_object_specific_selector-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/voice_object/voice_with_class_object_specific_selector.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_normal_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_normal_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_normal_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_normal_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_nowrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_nowrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_nowrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_nowrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-line_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-line_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-line_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-line_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-wrap_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-wrap_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-wrap_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-wrap_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre_wrapped.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre_wrapped.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre_wrapped-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/white-space_pre_wrapped.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/bold_object_default_font-style.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/bold_object_default_font-style.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/bold_object_default_font-style-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/bold_object_default_font-style.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/inherit_as_default_value_inherits_values_from_media_element.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/italic_object_default_font-style.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/selectors/default_styles/underline_object_default_font-style.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/size_50.html": [
- {
- "path": "webvtt/rendering/cues-with-video/processing-model/size_50.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/size_50-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/size_50.html"
- }
- ],
- "webvtt/rendering/cues-with-video/processing-model/too_many_cues.html": [
+ "testharness": {
+ "html/semantics/tabular-data/the-table-element/tFoot.html": [
{
- "path": "webvtt/rendering/cues-with-video/processing-model/too_many_cues.html",
- "references": [
- [
- "/webvtt/rendering/cues-with-video/processing-model/too_many_cues-ref.html",
- "=="
- ]
- ],
- "url": "/webvtt/rendering/cues-with-video/processing-model/too_many_cues.html"
+ "path": "html/semantics/tabular-data/the-table-element/tFoot.html",
+ "url": "/html/semantics/tabular-data/the-table-element/tFoot.html"
}
],
- "webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html": [
+ "html/semantics/tabular-data/the-table-element/tHead.html": [
{
- "path": "webvtt/rendering/cues-with-video/processing-model/too_many_cues_wrapped.html",
- "references": [
- [
- "/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"
- }
- ]
- },
- "testharness": {
- "html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html": [
- {
- "path": "html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html",
- "url": "/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html"
+ "path": "html/semantics/tabular-data/the-table-element/tHead.html",
+ "url": "/html/semantics/tabular-data/the-table-element/tHead.html"
}
]
}
},
- "reftest_nodes": {
- "html/semantics/links/linktypes/alternate-css-ref.html": [
- {
- "path": "html/semantics/links/linktypes/alternate-css-ref.html",
- "references": [
- [
- "/html/semantics/links/linktypes/alternate-css-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/links/linktypes/alternate-css-ref.html"
- }
- ],
- "html/semantics/links/linktypes/alternate-css.html": [
- {
- "path": "html/semantics/links/linktypes/alternate-css.html",
- "references": [
- [
- "/html/semantics/links/linktypes/alternate-css-ref.html",
- "=="
- ]
- ],
- "url": "/html/semantics/links/linktypes/alternate-css.html"
- }
- ]
- }
+ "reftest_nodes": {}
},
"reftest_nodes": {
"2dcontext/building-paths/canvas_complexshapes_arcto_001.htm": [
@@ -40632,6 +35522,54 @@
"url": "/FileAPI/url/url_xmlhttprequest_img.html"
}
],
+ "compat/webkit-text-fill-color-property-001a.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-001a.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001a.html"
+ }
+ ],
+ "compat/webkit-text-fill-color-property-001b.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-001b.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001b.html"
+ }
+ ],
+ "compat/webkit-text-fill-color-property-001c.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-001c.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001c.html"
+ }
+ ],
+ "compat/webkit-text-fill-color-property-001d.html": [
+ {
+ "path": "compat/webkit-text-fill-color-property-001d.html",
+ "references": [
+ [
+ "/compat/webkit-text-fill-color-property-001-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/compat/webkit-text-fill-color-property-001d.html"
+ }
+ ],
"custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html": [
{
"path": "custom-elements/registering-custom-elements/unresolved-element-pseudoclass/unresolved-element-pseudoclass-css-test-custom-tag.html",
@@ -42756,6 +37694,18 @@
"url": "/html/rendering/non-replaced-elements/the-fieldset-element-0/min-width-not-important.html"
}
],
+ "html/rendering/non-replaced-elements/the-hr-element-0/align.html": [
+ {
+ "path": "html/rendering/non-replaced-elements/the-hr-element-0/align.html",
+ "references": [
+ [
+ "/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/html/rendering/non-replaced-elements/the-hr-element-0/align.html"
+ }
+ ],
"html/rendering/non-replaced-elements/the-hr-element-0/color.html": [
{
"path": "html/rendering/non-replaced-elements/the-hr-element-0/color.html",
@@ -43260,6 +38210,30 @@
"url": "/html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html"
}
],
+ "html/semantics/links/linktypes/alternate-css-ref.html": [
+ {
+ "path": "html/semantics/links/linktypes/alternate-css-ref.html",
+ "references": [
+ [
+ "/html/semantics/links/linktypes/alternate-css-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/html/semantics/links/linktypes/alternate-css-ref.html"
+ }
+ ],
+ "html/semantics/links/linktypes/alternate-css.html": [
+ {
+ "path": "html/semantics/links/linktypes/alternate-css.html",
+ "references": [
+ [
+ "/html/semantics/links/linktypes/alternate-css-ref.html",
+ "=="
+ ]
+ ],
+ "url": "/html/semantics/links/linktypes/alternate-css.html"
+ }
+ ],
"html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html": [
{
"path": "html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html",
@@ -43572,30 +38546,6 @@
"url": "/html/semantics/text-level-semantics/the-wbr-element/wbr-element.html"
}
],
- "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html"
- }
- ],
- "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html"
- }
- ],
"shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html": [
{
"path": "shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html",
@@ -43620,18 +38570,6 @@
"url": "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html"
}
],
- "shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html": [
- {
- "path": "shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html",
- "references": [
- [
- "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002-ref.html",
- "=="
- ]
- ],
- "url": "/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html"
- }
- ],
"shadow-dom/untriaged/shadow-trees/shadow-root-001.html": [
{
"path": "shadow-dom/untriaged/shadow-trees/shadow-root-001.html",
@@ -46333,7 +41271,7 @@
}
]
},
- "rev": "15ad8eaadd91425cc9331b2e658d4c2796ae5ad8",
+ "rev": "d011702f368b88b3bae86e7a8fd2ddd22e18b33c",
"url_base": "/",
"version": 3
}
diff --git a/tests/wpt/metadata/XMLHttpRequest/data-uri.htm.ini b/tests/wpt/metadata/XMLHttpRequest/data-uri.htm.ini
index fff1641f7eb..a26e5693e32 100644
--- a/tests/wpt/metadata/XMLHttpRequest/data-uri.htm.ini
+++ b/tests/wpt/metadata/XMLHttpRequest/data-uri.htm.ini
@@ -1,6 +1,5 @@
[data-uri.htm]
type: testharness
-
[XHR method GET with charset text/html;charset=UTF-8]
expected: FAIL
diff --git a/tests/wpt/metadata/XMLHttpRequest/open-url-base-inserted.htm.ini b/tests/wpt/metadata/XMLHttpRequest/open-url-base-inserted.htm.ini
deleted file mode 100644
index 9e24c9d78d0..00000000000
--- a/tests/wpt/metadata/XMLHttpRequest/open-url-base-inserted.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[open-url-base-inserted.htm]
- type: testharness
- [XMLHttpRequest: open() resolving URLs - insert ]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-value.htm.ini b/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-value.htm.ini
deleted file mode 100644
index d04386464d1..00000000000
--- a/tests/wpt/metadata/XMLHttpRequest/setrequestheader-bogus-value.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[setrequestheader-bogus-value.htm]
- type: testharness
- [XMLHttpRequest: setRequestHeader() value argument checks 4]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/dom/collections/HTMLCollection-as-proto-length-get-throws.html.ini b/tests/wpt/metadata/dom/collections/HTMLCollection-as-proto-length-get-throws.html.ini
new file mode 100644
index 00000000000..0e56cb9f2f3
--- /dev/null
+++ b/tests/wpt/metadata/dom/collections/HTMLCollection-as-proto-length-get-throws.html.ini
@@ -0,0 +1,5 @@
+[HTMLCollection-as-proto-length-get-throws.html]
+ type: testharness
+ [HTMLcollection as a prototype should not allow getting .length on the base object]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/dom/interfaces.html.ini b/tests/wpt/metadata/dom/interfaces.html.ini
index 0c273da2dfb..4cdad8a3627 100644
--- a/tests/wpt/metadata/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/dom/interfaces.html.ini
@@ -207,3 +207,9 @@
[Node interface: document.createComment("abc") must inherit property "rootNode" with the proper type (16)]
expected: FAIL
+ [Element interface: element must inherit property "query" with the proper type (36)]
+ expected: FAIL
+
+ [Element interface: element must inherit property "queryAll" with the proper type (37)]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/dom/nodes/Document-getElementsByTagName.html.ini b/tests/wpt/metadata/dom/nodes/Document-getElementsByTagName.html.ini
index 849409e0fe6..3abe2d9b08f 100644
--- a/tests/wpt/metadata/dom/nodes/Document-getElementsByTagName.html.ini
+++ b/tests/wpt/metadata/dom/nodes/Document-getElementsByTagName.html.ini
@@ -3,3 +3,9 @@
[Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)]
expected: FAIL
+ [Element in non-HTML namespace, prefix, lowercase name]
+ expected: FAIL
+
+ [Element in non-HTML namespace, prefix, uppercase name]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/dom/nodes/Element-classlist.html.ini b/tests/wpt/metadata/dom/nodes/Element-classlist.html.ini
new file mode 100644
index 00000000000..3f1125fd479
--- /dev/null
+++ b/tests/wpt/metadata/dom/nodes/Element-classlist.html.ini
@@ -0,0 +1,8 @@
+[Element-classlist.html]
+ type: testharness
+ [.contains(empty_string) must return false]
+ expected: FAIL
+
+ [.contains(string_with_spaces) must return false]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/dom/nodes/Element-getElementsByTagName.html.ini b/tests/wpt/metadata/dom/nodes/Element-getElementsByTagName.html.ini
index 5cda7ac70ed..55701c6264d 100644
--- a/tests/wpt/metadata/dom/nodes/Element-getElementsByTagName.html.ini
+++ b/tests/wpt/metadata/dom/nodes/Element-getElementsByTagName.html.ini
@@ -3,3 +3,9 @@
[Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)]
expected: FAIL
+ [Element in non-HTML namespace, prefix, lowercase name]
+ expected: FAIL
+
+ [Element in non-HTML namespace, prefix, uppercase name]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/dom/nodes/case.html.ini b/tests/wpt/metadata/dom/nodes/case.html.ini
new file mode 100644
index 00000000000..e7dd2689077
--- /dev/null
+++ b/tests/wpt/metadata/dom/nodes/case.html.ini
@@ -0,0 +1,17 @@
+[case.html]
+ type: testharness
+ [getElementsByTagName a:abc]
+ expected: FAIL
+
+ [getElementsByTagName a:Abc]
+ expected: FAIL
+
+ [getElementsByTagName a:ABC]
+ expected: FAIL
+
+ [getElementsByTagName a:ä]
+ expected: FAIL
+
+ [getElementsByTagName a:Ä]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/dom/nodes/getElementsByClassName-20.htm.ini b/tests/wpt/metadata/dom/nodes/getElementsByClassName-20.htm.ini
deleted file mode 100644
index b3ae75b2960..00000000000
--- a/tests/wpt/metadata/dom/nodes/getElementsByClassName-20.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[getElementsByClassName-20.htm]
- type: testharness
- [get elements in document then add element to collection]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/dom/nodes/getElementsByClassName-22.htm.ini b/tests/wpt/metadata/dom/nodes/getElementsByClassName-22.htm.ini
deleted file mode 100644
index edb0b18eec8..00000000000
--- a/tests/wpt/metadata/dom/nodes/getElementsByClassName-22.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[getElementsByClassName-22.htm]
- type: testharness
- [move item in collection order]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/dom/nodes/getElementsByClassName-25.htm.ini b/tests/wpt/metadata/dom/nodes/getElementsByClassName-25.htm.ini
deleted file mode 100644
index b75ced052c3..00000000000
--- a/tests/wpt/metadata/dom/nodes/getElementsByClassName-25.htm.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[getElementsByClassName-25.htm]
- type: testharness
- [verify spacing is handled correctly]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/dom/nodes/remove-unscopable.html.ini b/tests/wpt/metadata/dom/nodes/remove-unscopable.html.ini
new file mode 100644
index 00000000000..bd66b155deb
--- /dev/null
+++ b/tests/wpt/metadata/dom/nodes/remove-unscopable.html.ini
@@ -0,0 +1,5 @@
+[remove-unscopable.html]
+ type: testharness
+ [remove() should be unscopable]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/domparsing/DOMParser-parseFromString-html.html.ini b/tests/wpt/metadata/domparsing/DOMParser-parseFromString-html.html.ini
deleted file mode 100644
index 8b137891791..00000000000
--- a/tests/wpt/metadata/domparsing/DOMParser-parseFromString-html.html.ini
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tests/wpt/metadata/encoding/api-basics.html.ini b/tests/wpt/metadata/encoding/api-basics.html.ini
index eb82a3047c9..df28ac82e8a 100644
--- a/tests/wpt/metadata/encoding/api-basics.html.ini
+++ b/tests/wpt/metadata/encoding/api-basics.html.ini
@@ -12,3 +12,12 @@
[Encode/decode round trip: utf-16]
expected: FAIL
+ [Decode sample: utf-16le]
+ expected: FAIL
+
+ [Decode sample: utf-16be]
+ expected: FAIL
+
+ [Decode sample: utf-16]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/encoding/textdecoder-streaming.html.ini b/tests/wpt/metadata/encoding/textdecoder-streaming.html.ini
index 401997d8036..72333e5be3a 100644
--- a/tests/wpt/metadata/encoding/textdecoder-streaming.html.ini
+++ b/tests/wpt/metadata/encoding/textdecoder-streaming.html.ini
@@ -18,3 +18,30 @@
[Streaming decode: utf-16be, 5 byte window]
expected: FAIL
+ [Streaming decode: utf-8, 1 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-8, 2 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-8, 3 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-8, 4 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-8, 5 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-16le, 2 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-16le, 4 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-16be, 2 byte window]
+ expected: FAIL
+
+ [Streaming decode: utf-16be, 4 byte window]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini b/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini
new file mode 100644
index 00000000000..1e475829d28
--- /dev/null
+++ b/tests/wpt/metadata/encoding/textencoder-constructor-non-utf.html.ini
@@ -0,0 +1,119 @@
+[textencoder-constructor-non-utf.html]
+ type: testharness
+ [Encoding argument not considered for encode: ibm866]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-2]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-3]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-4]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-5]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-6]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-7]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-8]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-8-i]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-10]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-13]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-14]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-15]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-8859-16]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: koi8-r]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: koi8-u]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: macintosh]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-874]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1250]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1251]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1252]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1253]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1254]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1255]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1256]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1257]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: windows-1258]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: x-mac-cyrillic]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: gbk]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: gb18030]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: big5]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: euc-jp]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: iso-2022-jp]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: shift_jis]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: euc-kr]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: replacement]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: utf-16be]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: utf-16le]
+ expected: FAIL
+
+ [Encoding argument not considered for encode: x-user-defined]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/hr-time/test_cross_frame_start.html.ini b/tests/wpt/metadata/hr-time/test_cross_frame_start.html.ini
deleted file mode 100644
index 78f8aef8a7d..00000000000
--- a/tests/wpt/metadata/hr-time/test_cross_frame_start.html.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[test_cross_frame_start.html]
- type: testharness
- [Child created at least 1 second after parent]
- expected: FAIL
-
- [Child and parent time bases are correct]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain.html.ini b/tests/wpt/metadata/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain.html.ini
deleted file mode 100644
index 4adc32981f0..00000000000
--- a/tests/wpt/metadata/html/browsers/origin/relaxing-the-same-origin-restriction/document_domain.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[document_domain.html]
- type: testharness
- [new document]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/dom/interfaces.html.ini b/tests/wpt/metadata/html/dom/interfaces.html.ini
index c8e6d7591c4..5af57f14c88 100644
--- a/tests/wpt/metadata/html/dom/interfaces.html.ini
+++ b/tests/wpt/metadata/html/dom/interfaces.html.ini
@@ -1977,15 +1977,9 @@
[HTMLHtmlElement interface: document.createElement("html") must inherit property "version" with the proper type (0)]
expected: FAIL
- [HTMLBaseElement interface: attribute href]
- expected: FAIL
-
[HTMLBaseElement interface: attribute target]
expected: FAIL
- [HTMLBaseElement interface: document.createElement("base") must inherit property "href" with the proper type (0)]
- expected: FAIL
-
[HTMLBaseElement interface: document.createElement("base") must inherit property "target" with the proper type (1)]
expected: FAIL
@@ -2148,18 +2142,12 @@
[HTMLParagraphElement interface: document.createElement("p") must inherit property "align" with the proper type (0)]
expected: FAIL
- [HTMLHRElement interface: attribute align]
- expected: FAIL
-
[HTMLHRElement interface: attribute noShade]
expected: FAIL
[HTMLHRElement interface: attribute size]
expected: FAIL
- [HTMLHRElement interface: document.createElement("hr") must inherit property "align" with the proper type (0)]
- expected: FAIL
-
[HTMLHRElement interface: document.createElement("hr") must inherit property "noShade" with the proper type (2)]
expected: FAIL
@@ -2325,12 +2313,6 @@
[HTMLImageElement interface: attribute sizes]
expected: FAIL
- [HTMLImageElement interface: attribute crossOrigin]
- expected: FAIL
-
- [HTMLImageElement interface: attribute currentSrc]
- expected: FAIL
-
[HTMLImageElement interface: attribute lowsrc]
expected: FAIL
@@ -2340,12 +2322,6 @@
[HTMLImageElement interface: document.createElement("img") must inherit property "sizes" with the proper type (3)]
expected: FAIL
- [HTMLImageElement interface: document.createElement("img") must inherit property "crossOrigin" with the proper type (4)]
- expected: FAIL
-
- [HTMLImageElement interface: document.createElement("img") must inherit property "currentSrc" with the proper type (12)]
- expected: FAIL
-
[HTMLImageElement interface: document.createElement("img") must inherit property "lowsrc" with the proper type (14)]
expected: FAIL
@@ -2355,12 +2331,6 @@
[HTMLImageElement interface: new Image() must inherit property "sizes" with the proper type (3)]
expected: FAIL
- [HTMLImageElement interface: new Image() must inherit property "crossOrigin" with the proper type (4)]
- expected: FAIL
-
- [HTMLImageElement interface: new Image() must inherit property "currentSrc" with the proper type (12)]
- expected: FAIL
-
[HTMLImageElement interface: new Image() must inherit property "lowsrc" with the proper type (14)]
expected: FAIL
@@ -4158,27 +4128,6 @@
[HTMLAreaElement interface: document.createElement("area") must inherit property "noHref" with the proper type (10)]
expected: FAIL
- [HTMLTableElement interface: attribute tHead]
- expected: FAIL
-
- [HTMLTableElement interface: operation createTHead()]
- expected: FAIL
-
- [HTMLTableElement interface: operation deleteTHead()]
- expected: FAIL
-
- [HTMLTableElement interface: attribute tFoot]
- expected: FAIL
-
- [HTMLTableElement interface: operation createTFoot()]
- expected: FAIL
-
- [HTMLTableElement interface: operation deleteTFoot()]
- expected: FAIL
-
- [HTMLTableElement interface: attribute tBodies]
- expected: FAIL
-
[HTMLTableElement interface: operation insertRow(long)]
expected: FAIL
@@ -4212,27 +4161,6 @@
[HTMLTableElement interface: attribute cellSpacing]
expected: FAIL
- [HTMLTableElement interface: document.createElement("table") must inherit property "tHead" with the proper type (3)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "createTHead" with the proper type (4)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "deleteTHead" with the proper type (5)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "tFoot" with the proper type (6)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "createTFoot" with the proper type (7)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "deleteTFoot" with the proper type (8)]
- expected: FAIL
-
- [HTMLTableElement interface: document.createElement("table") must inherit property "tBodies" with the proper type (9)]
- expected: FAIL
-
[HTMLTableElement interface: document.createElement("table") must inherit property "insertRow" with the proper type (12)]
expected: FAIL
@@ -4380,12 +4308,6 @@
[HTMLTableSectionElement interface: document.createElement("tfoot") must inherit property "vAlign" with the proper type (6)]
expected: FAIL
- [HTMLTableRowElement interface: attribute rowIndex]
- expected: FAIL
-
- [HTMLTableRowElement interface: attribute sectionRowIndex]
- expected: FAIL
-
[HTMLTableRowElement interface: attribute align]
expected: FAIL
@@ -4398,12 +4320,6 @@
[HTMLTableRowElement interface: attribute vAlign]
expected: FAIL
- [HTMLTableRowElement interface: document.createElement("tr") must inherit property "rowIndex" with the proper type (0)]
- expected: FAIL
-
- [HTMLTableRowElement interface: document.createElement("tr") must inherit property "sectionRowIndex" with the proper type (1)]
- expected: FAIL
-
[HTMLTableRowElement interface: document.createElement("tr") must inherit property "align" with the proper type (5)]
expected: FAIL
@@ -4545,21 +4461,12 @@
[HTMLFormElement interface: document.createElement("form") must inherit property "requestAutocomplete" with the proper type (17)]
expected: FAIL
- [HTMLInputElement interface: attribute accept]
- expected: FAIL
-
- [HTMLInputElement interface: attribute alt]
- expected: FAIL
-
[HTMLInputElement interface: attribute autocomplete]
expected: FAIL
[HTMLInputElement interface: attribute autofocus]
expected: FAIL
- [HTMLInputElement interface: attribute dirName]
- expected: FAIL
-
[HTMLInputElement interface: attribute files]
expected: FAIL
@@ -4572,30 +4479,9 @@
[HTMLInputElement interface: attribute list]
expected: FAIL
- [HTMLInputElement interface: attribute max]
- expected: FAIL
-
- [HTMLInputElement interface: attribute min]
- expected: FAIL
-
[HTMLInputElement interface: attribute minLength]
expected: FAIL
- [HTMLInputElement interface: attribute multiple]
- expected: FAIL
-
- [HTMLInputElement interface: attribute pattern]
- expected: FAIL
-
- [HTMLInputElement interface: attribute required]
- expected: FAIL
-
- [HTMLInputElement interface: attribute src]
- expected: FAIL
-
- [HTMLInputElement interface: attribute step]
- expected: FAIL
-
[HTMLInputElement interface: attribute valueAsDate]
expected: FAIL
@@ -4650,21 +4536,12 @@
[HTMLInputElement interface: attribute useMap]
expected: FAIL
- [HTMLInputElement interface: document.createElement("input") must inherit property "accept" with the proper type (0)]
- expected: FAIL
-
- [HTMLInputElement interface: document.createElement("input") must inherit property "alt" with the proper type (1)]
- expected: FAIL
-
[HTMLInputElement interface: document.createElement("input") must inherit property "autocomplete" with the proper type (2)]
expected: FAIL
[HTMLInputElement interface: document.createElement("input") must inherit property "autofocus" with the proper type (3)]
expected: FAIL
- [HTMLInputElement interface: document.createElement("input") must inherit property "dirName" with the proper type (6)]
- expected: FAIL
-
[HTMLInputElement interface: document.createElement("input") must inherit property "files" with the proper type (9)]
expected: FAIL
@@ -4677,30 +4554,9 @@
[HTMLInputElement interface: document.createElement("input") must inherit property "list" with the proper type (18)]
expected: FAIL
- [HTMLInputElement interface: document.createElement("input") must inherit property "max" with the proper type (19)]
- expected: FAIL
-
- [HTMLInputElement interface: document.createElement("input") must inherit property "min" with the proper type (21)]
- expected: FAIL
-
[HTMLInputElement interface: document.createElement("input") must inherit property "minLength" with the proper type (22)]
expected: FAIL
- [HTMLInputElement interface: document.createElement("input") must inherit property "multiple" with the proper type (23)]
- expected: FAIL
-
- [HTMLInputElement interface: document.createElement("input") must inherit property "pattern" with the proper type (25)]
- expected: FAIL
-
- [HTMLInputElement interface: document.createElement("input") must inherit property "required" with the proper type (28)]
- expected: FAIL
-
- [HTMLInputElement interface: document.createElement("input") must inherit property "src" with the proper type (30)]
- expected: FAIL
-
- [HTMLInputElement interface: document.createElement("input") must inherit property "step" with the proper type (31)]
- expected: FAIL
-
[HTMLInputElement interface: document.createElement("input") must inherit property "valueAsDate" with the proper type (35)]
expected: FAIL
diff --git a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini
index 32ed9423826..94df1baae7b 100644
--- a/tests/wpt/metadata/html/dom/reflection-embedded.html.ini
+++ b/tests/wpt/metadata/html/dom/reflection-embedded.html.ini
@@ -594,213 +594,12 @@
[img.crossOrigin: IDL get with DOM attribute unset]
expected: FAIL
- [img.crossOrigin: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "anonymous" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "xanonymous" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "anonymous\\0" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "nonymous" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "ANONYMOUS" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "use-credentials" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "xuse-credentials" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "use-credentials\\0" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "se-credentials" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: setAttribute() to "USE-CREDENTIALS" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
[img.crossOrigin: IDL set to undefined followed by getAttribute()]
expected: FAIL
[img.crossOrigin: IDL set to undefined followed by IDL get]
expected: FAIL
- [img.crossOrigin: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to true followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to false followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "\\0" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to object "test-valueOf" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "anonymous" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "xanonymous" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "xanonymous" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "anonymous\\0" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "anonymous\\0" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "nonymous" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "nonymous" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "ANONYMOUS" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "ANONYMOUS" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "use-credentials" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "xuse-credentials" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "xuse-credentials" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "use-credentials\\0" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "use-credentials\\0" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "se-credentials" followed by getAttribute()]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "se-credentials" followed by IDL get]
- expected: FAIL
-
- [img.crossOrigin: IDL set to "USE-CREDENTIALS" followed by IDL get]
- expected: FAIL
-
[img.width: IDL set to 1 followed by IDL get]
expected: FAIL
@@ -21882,9 +21681,6 @@
[video.height: IDL set to 4294967295 followed by IDL get]
expected: FAIL
- [img.crossOrigin: IDL set to "" followed by IDL get]
- expected: FAIL
-
[img.crossOrigin: IDL set to null followed by getAttribute()]
expected: FAIL
@@ -21894,3 +21690,6 @@
[audio.crossOrigin: IDL set to null followed by getAttribute()]
expected: FAIL
+ [img.crossOrigin: IDL set to null followed by IDL get]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/html/dom/reflection-forms.html.ini b/tests/wpt/metadata/html/dom/reflection-forms.html.ini
index fa017c0014a..84f4224e156 100644
--- a/tests/wpt/metadata/html/dom/reflection-forms.html.ini
+++ b/tests/wpt/metadata/html/dom/reflection-forms.html.ini
@@ -3633,264 +3633,6 @@
[input.tabIndex: IDL set to -2147483648 followed by getAttribute()]
expected: FAIL
- [input.accept: typeof IDL attribute]
- expected: FAIL
-
- [input.accept: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.accept: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.accept: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to true followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to false followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [input.accept: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.accept: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.alt: typeof IDL attribute]
- expected: FAIL
-
- [input.alt: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.alt: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.alt: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to true followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to false followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [input.alt: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.alt: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
[input.autofocus: typeof IDL attribute]
expected: FAIL
@@ -3999,135 +3741,6 @@
[input.autofocus: IDL set to object "test-valueOf" followed by IDL get]
expected: FAIL
- [input.dirName: typeof IDL attribute]
- expected: FAIL
-
- [input.dirName: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.dirName: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.dirName: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to true followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to false followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [input.dirName: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.dirName: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
[input.formEnctype: IDL get with DOM attribute unset]
expected: FAIL
@@ -4728,624 +4341,12 @@
[input.inputMode: IDL set to "URL" followed by IDL get]
expected: FAIL
- [input.max: typeof IDL attribute]
- expected: FAIL
-
- [input.max: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.max: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.max: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to true followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to false followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [input.max: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.max: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.min: typeof IDL attribute]
- expected: FAIL
-
- [input.min: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.min: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.min: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to true followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to false followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [input.min: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.min: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.multiple: typeof IDL attribute]
- expected: FAIL
-
- [input.multiple: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.multiple: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to " foo " followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.multiple: setAttribute() to "multiple" followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to "" followed by hasAttribute()]
- expected: FAIL
-
- [input.multiple: IDL set to "" followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to " foo " followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to undefined followed by hasAttribute()]
- expected: FAIL
-
- [input.multiple: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to null followed by hasAttribute()]
- expected: FAIL
-
- [input.multiple: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to false followed by hasAttribute()]
- expected: FAIL
-
- [input.multiple: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to NaN followed by hasAttribute()]
- expected: FAIL
-
- [input.multiple: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.multiple: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.pattern: typeof IDL attribute]
- expected: FAIL
-
- [input.pattern: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.pattern: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.pattern: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to true followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to false followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [input.pattern: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.pattern: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.required: typeof IDL attribute]
- expected: FAIL
-
- [input.required: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.required: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to " foo " followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.required: setAttribute() to "required" followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to "" followed by hasAttribute()]
- expected: FAIL
-
- [input.required: IDL set to "" followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to " foo " followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to undefined followed by hasAttribute()]
- expected: FAIL
-
- [input.required: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to null followed by hasAttribute()]
- expected: FAIL
-
- [input.required: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to false followed by hasAttribute()]
- expected: FAIL
-
- [input.required: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to NaN followed by hasAttribute()]
- expected: FAIL
-
- [input.required: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.required: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.src: typeof IDL attribute]
- expected: FAIL
-
- [input.src: IDL get with DOM attribute unset]
- expected: FAIL
-
[input.src: setAttribute() to "" followed by IDL get]
expected: FAIL
[input.src: setAttribute() to " foo " followed by IDL get]
expected: FAIL
- [input.src: setAttribute() to "http://site.example/" followed by IDL get]
- expected: FAIL
-
[input.src: setAttribute() to "//site.example/path???@#l" followed by IDL get]
expected: FAIL
@@ -5391,237 +4392,57 @@
[input.src: setAttribute() to object "test-valueOf" followed by IDL get]
expected: FAIL
- [input.src: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to "" followed by IDL get]
expected: FAIL
- [input.src: IDL set to " foo " followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to " foo " followed by IDL get]
expected: FAIL
- [input.src: IDL set to "http://site.example/" followed by getAttribute()]
- expected: FAIL
-
- [input.src: IDL set to "//site.example/path???@#l" followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to "//site.example/path???@#l" followed by IDL get]
expected: FAIL
- [input.src: IDL set to "\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f " followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to "\\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f " followed by IDL get]
expected: FAIL
- [input.src: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to undefined followed by IDL get]
expected: FAIL
- [input.src: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to 7 followed by IDL get]
expected: FAIL
- [input.src: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to 1.5 followed by IDL get]
expected: FAIL
- [input.src: IDL set to true followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to true followed by IDL get]
expected: FAIL
- [input.src: IDL set to false followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to false followed by IDL get]
expected: FAIL
- [input.src: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to object "[object Object\]" followed by IDL get]
expected: FAIL
- [input.src: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to NaN followed by IDL get]
expected: FAIL
- [input.src: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to Infinity followed by IDL get]
expected: FAIL
- [input.src: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to -Infinity followed by IDL get]
expected: FAIL
- [input.src: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to "\\0" followed by IDL get]
expected: FAIL
- [input.src: IDL set to null followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to null followed by IDL get]
expected: FAIL
- [input.src: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
[input.src: IDL set to object "test-toString" followed by IDL get]
expected: FAIL
[input.src: IDL set to object "test-valueOf" followed by IDL get]
expected: FAIL
- [input.step: typeof IDL attribute]
- expected: FAIL
-
- [input.step: IDL get with DOM attribute unset]
- expected: FAIL
-
- [input.step: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.step: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to true followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to false followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to null followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [input.step: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [input.step: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
[input.align: typeof IDL attribute]
expected: FAIL
diff --git a/tests/wpt/metadata/html/dom/reflection-grouping.html.ini b/tests/wpt/metadata/html/dom/reflection-grouping.html.ini
index 20cacc5dc08..7ecf978bf18 100644
--- a/tests/wpt/metadata/html/dom/reflection-grouping.html.ini
+++ b/tests/wpt/metadata/html/dom/reflection-grouping.html.ini
@@ -1317,135 +1317,6 @@
[hr.tabIndex: IDL set to -2147483648 followed by getAttribute()]
expected: FAIL
- [hr.align: typeof IDL attribute]
- expected: FAIL
-
- [hr.align: IDL get with DOM attribute unset]
- expected: FAIL
-
- [hr.align: setAttribute() to "" followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to undefined followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to 7 followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to 1.5 followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to true followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to false followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to NaN followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to Infinity followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to -Infinity followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to "\\0" followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to null followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [hr.align: setAttribute() to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to "" followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo " followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to undefined followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to undefined followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to 7 followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to 7 followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to 1.5 followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to 1.5 followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to true followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to true followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to false followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to false followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to object "[object Object\]" followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to object "[object Object\]" followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to NaN followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to NaN followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to Infinity followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to Infinity followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to -Infinity followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to -Infinity followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to "\\0" followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to null followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to null followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to object "test-toString" followed by getAttribute()]
- expected: FAIL
-
- [hr.align: IDL set to object "test-toString" followed by IDL get]
- expected: FAIL
-
- [hr.align: IDL set to object "test-valueOf" followed by IDL get]
- expected: FAIL
-
[hr.noShade: typeof IDL attribute]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_empty.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_empty.html.ini
deleted file mode 100644
index 68bff358e19..00000000000
--- a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_empty.html.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[base_href_empty.html]
- type: testharness
- [The value of the href attribute must be the document's address if it is empty]
- expected: FAIL
-
- [The src attribute of the img element must relative to document's address]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html.ini
deleted file mode 100644
index 4bf60923372..00000000000
--- a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[base_href_specified.sub.html]
- type: testharness
- [The href attribute of the base element is specified]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_unspecified.html.ini b/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_unspecified.html.ini
deleted file mode 100644
index b782c6c77c4..00000000000
--- a/tests/wpt/metadata/html/semantics/document-metadata/the-base-element/base_href_unspecified.html.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[base_href_unspecified.html]
- type: testharness
- [The value of the href attribute must be the document's address if it is unspecified]
- expected: FAIL
-
- [The src attribute of the img element must relative to document's address]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini
index bb5e3f9274f..24774d34ea0 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html.ini
@@ -1,14 +1,5 @@
[parse-a-srcset-attribute.html]
type: testharness
- [""]
- expected: FAIL
-
- [","]
- expected: FAIL
-
- [",,,"]
- expected: FAIL
-
[" data:,a 1x "]
expected: FAIL
@@ -114,267 +105,27 @@
["data:,a, data:,b ()"]
expected: FAIL
- ["data:,a (, data:,b"]
- expected: FAIL
-
["data:,a /*, data:,b, data:,c */"]
expected: FAIL
["data:,a //, data:,b"]
expected: FAIL
- ["data:,a foo"]
- expected: FAIL
-
- ["data:,a foo foo"]
- expected: FAIL
-
- ["data:,a foo 1x"]
- expected: FAIL
-
- ["data:,a foo 1x foo"]
- expected: FAIL
-
- ["data:,a foo 1w"]
- expected: FAIL
-
- ["data:,a foo 1w foo"]
- expected: FAIL
-
- ["data:,a 1x 1x"]
- expected: FAIL
-
- ["data:,a 1w 1w"]
- expected: FAIL
-
- ["data:,a 1w 1x"]
- expected: FAIL
-
- ["data:,a 1x 1w"]
- expected: FAIL
-
["data:,a 1w 1h"]
expected: FAIL
["data:,a 1h 1w"]
expected: FAIL
- ["data:,a 1h 1h"]
- expected: FAIL
-
- ["data:,a 1h 1x"]
- expected: FAIL
-
- ["data:,a 1h 1w 1x"]
- expected: FAIL
-
- ["data:,a 1x 1w 1h"]
- expected: FAIL
-
["data:,a 1w"]
expected: FAIL
- ["data:,a 1h"]
- expected: FAIL
-
- ["data:,a 1h foo"]
- expected: FAIL
-
- ["data:,a foo 1h"]
- expected: FAIL
-
- ["data:,a 0w"]
- expected: FAIL
-
- ["data:,a -1w"]
- expected: FAIL
-
- ["data:,a 1w -1w"]
- expected: FAIL
-
- ["data:,a 1.0w"]
- expected: FAIL
-
- ["data:,a 1w 1.0w"]
- expected: FAIL
-
- ["data:,a 1e0w"]
- expected: FAIL
-
- ["data:,a 1w 1e0w"]
- expected: FAIL
-
- ["data:,a 1www"]
- expected: FAIL
-
- ["data:,a 1w 1www"]
- expected: FAIL
-
- ["data:,a +1w"]
- expected: FAIL
-
- ["data:,a 1w +1w"]
- expected: FAIL
-
- ["data:,a 1W"]
- expected: FAIL
-
- ["data:,a 1w 1W"]
- expected: FAIL
-
- ["data:,a Infinityw"]
- expected: FAIL
-
- ["data:,a 1w Infinityw"]
- expected: FAIL
-
- ["data:,a NaNw"]
- expected: FAIL
-
- ["data:,a 1w NaNw"]
- expected: FAIL
-
- ["data:,a 0x1w"]
- expected: FAIL
-
- ["data:,a 0X1w"]
- expected: FAIL
-
- ["data:,a 1\\x01w" (trailing U+0001)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+00A0)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+1680)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2000)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2001)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2002)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2003)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2004)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2005)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2006)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2007)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2008)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+2009)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+200A)]
- expected: FAIL
-
- ["data:,a 1‌w" (trailing U+200C)]
- expected: FAIL
-
- ["data:,a 1‍w" (trailing U+200D)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+202F)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+205F)]
- expected: FAIL
-
- ["data:,a 1 w" (trailing U+3000)]
- expected: FAIL
-
- ["data:,a 1w" (trailing U+FEFF)]
- expected: FAIL
-
- ["data:,a \\x011w" (leading U+0001)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+00A0)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+1680)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2000)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2001)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2002)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2003)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2004)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2005)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2006)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2007)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2008)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+2009)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+200A)]
- expected: FAIL
-
- ["data:,a ‌1w" (leading U+200C)]
- expected: FAIL
-
- ["data:,a ‍1w" (leading U+200D)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+202F)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+205F)]
- expected: FAIL
-
- ["data:,a  1w" (leading U+3000)]
- expected: FAIL
-
- ["data:,a 1w" (leading U+FEFF)]
- expected: FAIL
-
["data:,a 0x"]
expected: FAIL
["data:,a -0x"]
expected: FAIL
- ["data:,a 1x -0x"]
- expected: FAIL
-
- ["data:,a -1x"]
- expected: FAIL
-
- ["data:,a 1x -1x"]
- expected: FAIL
-
["data:,a 1e0x"]
expected: FAIL
@@ -387,324 +138,12 @@
["data:,a 1.5e1x"]
expected: FAIL
- ["data:,a -x"]
- expected: FAIL
-
- ["data:,a .x"]
- expected: FAIL
-
- ["data:,a -.x"]
- expected: FAIL
-
- ["data:,a 1.x"]
- expected: FAIL
-
["data:,a .5x"]
expected: FAIL
["data:,a .5e1x"]
expected: FAIL
- ["data:,a 1x 1.5e1x"]
- expected: FAIL
-
- ["data:,a 1x 1e1.5x"]
- expected: FAIL
-
["data:,a 1.0x"]
expected: FAIL
- ["data:,a 1x 1.0x"]
- expected: FAIL
-
- ["data:,a +1x"]
- expected: FAIL
-
- ["data:,a 1X"]
- expected: FAIL
-
- ["data:,a Infinityx"]
- expected: FAIL
-
- ["data:,a NaNx"]
- expected: FAIL
-
- ["data:,a 0x1x"]
- expected: FAIL
-
- ["data:,a 0X1x"]
- expected: FAIL
-
- ["data:,a 1\\x01x" (trailing U+0001)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+00A0)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+1680)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2000)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2001)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2002)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2003)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2004)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2005)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2006)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2007)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2008)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+2009)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+200A)]
- expected: FAIL
-
- ["data:,a 1‌x" (trailing U+200C)]
- expected: FAIL
-
- ["data:,a 1‍x" (trailing U+200D)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+202F)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+205F)]
- expected: FAIL
-
- ["data:,a 1 x" (trailing U+3000)]
- expected: FAIL
-
- ["data:,a 1x" (trailing U+FEFF)]
- expected: FAIL
-
- ["data:,a \\x011x" (leading U+0001)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+00A0)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+1680)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2000)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2001)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2002)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2003)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2004)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2005)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2006)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2007)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2008)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+2009)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+200A)]
- expected: FAIL
-
- ["data:,a ‌1x" (leading U+200C)]
- expected: FAIL
-
- ["data:,a ‍1x" (leading U+200D)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+202F)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+205F)]
- expected: FAIL
-
- ["data:,a  1x" (leading U+3000)]
- expected: FAIL
-
- ["data:,a 1x" (leading U+FEFF)]
- expected: FAIL
-
- ["data:,a 1w 0h"]
- expected: FAIL
-
- ["data:,a 1w -1h"]
- expected: FAIL
-
- ["data:,a 1w 1.0h"]
- expected: FAIL
-
- ["data:,a 1w 1e0h"]
- expected: FAIL
-
- ["data:,a 1w 1hhh"]
- expected: FAIL
-
- ["data:,a 1w +1h"]
- expected: FAIL
-
- ["data:,a 1w 1H"]
- expected: FAIL
-
- ["data:,a 1w Infinityh"]
- expected: FAIL
-
- ["data:,a 1w NaNh"]
- expected: FAIL
-
- ["data:,a 0x1h"]
- expected: FAIL
-
- ["data:,a 0X1h"]
- expected: FAIL
-
- ["data:,a 1w 1\\x01h" (trailing U+0001)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+00A0)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+1680)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2000)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2001)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2002)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2003)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2004)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2005)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2006)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2007)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2008)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+2009)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+200A)]
- expected: FAIL
-
- ["data:,a 1w 1‌h" (trailing U+200C)]
- expected: FAIL
-
- ["data:,a 1w 1‍h" (trailing U+200D)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+202F)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+205F)]
- expected: FAIL
-
- ["data:,a 1w 1 h" (trailing U+3000)]
- expected: FAIL
-
- ["data:,a 1w 1h" (trailing U+FEFF)]
- expected: FAIL
-
- ["data:,a 1w \\x011h" (leading U+0001)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+00A0)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+1680)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2000)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2001)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2002)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2003)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2004)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2005)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2006)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2007)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2008)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+2009)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+200A)]
- expected: FAIL
-
- ["data:,a 1w ‌1h" (leading U+200C)]
- expected: FAIL
-
- ["data:,a 1w ‍1h" (leading U+200D)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+202F)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+205F)]
- expected: FAIL
-
- ["data:,a 1w  1h" (leading U+3000)]
- expected: FAIL
-
- ["data:,a 1w 1h" (leading U+FEFF)]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini
index 7748cf097bb..8af7b4f8c78 100644
--- a/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini
+++ b/tests/wpt/metadata/html/semantics/embedded-content/the-img-element/update-the-source-set.html.ini
@@ -1,17 +1,8 @@
[update-the-source-set.html]
type: testharness
- [<img data-expect="">]
- expected: FAIL
-
[<img src="" data-expect="">]
expected: FAIL
- [<img src="data:,a" data-expect="data:,a">]
- expected: FAIL
-
- [<img srcset="" src="data:,a" data-expect="data:,a">]
- expected: FAIL
-
[<img srcset="data:,b" src="data:,a" data-expect="data:,b">]
expected: FAIL
@@ -48,42 +39,6 @@
[<img srcset="data:,a" data-expect="data:,a">]
expected: FAIL
- [<picture>foo<img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><!--foo--><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><br><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><p></p><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><video><source srcset="data:,b"></video><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><span><source srcset="data:,b"></span><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><img src="data:,a"><img src="data:,b" data-expect="data:,b"></picture>]
- expected: FAIL
-
- [<picture><source><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source src="data:,b"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset=""><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset=", ,"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b 1x 1x"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
[<picture><source srcset="data:,b" media=""><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
@@ -93,33 +48,12 @@
[<picture><source srcset="data:,b" media="all and (min-width:0)"><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
- [<picture><source srcset="data:,b" media="all and !"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" media="all and (!)"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" media="not all"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" media="not all and (min-width:0)"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
[<picture><source srcset="data:,b" media="not all and (max-width:0)"><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
- [<picture><source srcset="data:,b" media="not all and !"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" media="not all and (!)"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
[<picture><source srcset="data:,b" media="all, !"><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
- [<picture><source srcset="data:,b" media=","><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
[<picture><source srcset="data:,b" media=", all"><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
@@ -162,108 +96,12 @@
[<picture><source srcset="data:,b" type="image/x-icon"><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
- [<picture><source srcset="data:,b" type="text/xml"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="text/html"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="text/plain"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="text/css"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="video/mp4"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="video/ogg"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="video/webm"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="unknown/unknown"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="application/octet-stream"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="application/x-shockwave-flash"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="image\\gif"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="gif"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type=".gif"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="*"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="*/*"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="image/*"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type=","><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="image/gif, image/png"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="image/gif image/png"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b" type="image/foobarbaz"><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
- [<picture><img src="data:,a" data-expect="data:,a">foo</picture>]
- expected: FAIL
-
- [<picture><img src="data:,a" data-expect="data:,a"><br></picture>]
- expected: FAIL
-
- [<picture><img src="data:,a" data-expect="data:,a"><!--foo--></picture>]
- expected: FAIL
-
- [<picture><img src="data:,a" data-expect="data:,a"><img src="data:,b"></picture>]
- expected: FAIL
-
- [<picture><img data-expect=""><img src="data:,b"></picture>]
- expected: FAIL
-
- [<picture><img src="data:,a" data-expect="data:,a"><source srcset="data:,b"></picture>]
- expected: FAIL
-
- [<picture><img data-expect=""><source srcset="data:,b"></picture>]
- expected: FAIL
-
- [<picture><span><source srcset="data:,b"><img data-expect=""></span></picture>]
- expected: FAIL
-
- [<picture><span><source srcset="data:,b"><img src="data:,a" data-expect="data:,a"></span></picture>]
- expected: FAIL
-
- [<picture><source srcset="data:,b"><span><img src="data:,a" data-expect="data:,a"></span></picture>]
- expected: FAIL
-
[<picture><source srcset="data:,b"><img data-expect="data:,b"></picture>]
expected: FAIL
- [<picture><svg><source srcset="data:,b"></source></svg><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
[<picture><svg></svg><source srcset="data:,b"><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
- [<picture><svg><font></font><source srcset="data:,b"></source></svg><img src="data:,a" data-expect="data:,a"></picture>]
- expected: FAIL
-
[<picture><svg><!--<font face> tag breaks out of svg--><font face=""></font><source srcset="data:,b"></source></svg><img src="data:,a" data-expect="data:,b"></picture>]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini
index 20bc5a747e9..8764534b310 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/datetime.html.ini
@@ -1,74 +1,29 @@
[datetime.html]
type: testharness
- [[date\] The min attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[date\] The max attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[date\] The step attribute must be expressed in seconds]
- expected: FAIL
-
[[date\] stepUp method support on input 'date' element]
expected: FAIL
[[date\] stepDown method support on input 'date' element]
expected: FAIL
- [[time\] The min attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[time\] The max attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[time\] The step attribute must be expressed in seconds]
- expected: FAIL
-
[[time\] stepUp method support on input 'time' element]
expected: FAIL
[[time\] stepDown method support on input 'time' element]
expected: FAIL
- [[datetime\] The min attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[datetime\] The max attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[datetime\] The step attribute must be expressed in seconds]
- expected: FAIL
-
[[datetime\] stepUp method support on input 'datetime' element]
expected: FAIL
[[datetime\] stepDown method support on input 'datetime' element]
expected: FAIL
- [[month\] The min attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[month\] The max attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[month\] The step attribute must be expressed in seconds]
- expected: FAIL
-
[[month\] stepUp method support on input 'month' element]
expected: FAIL
[[month\] stepDown method support on input 'month' element]
expected: FAIL
- [[week\] The min attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[week\] The max attribute must have a value that is a valid global date and time string]
- expected: FAIL
-
- [[week\] The step attribute must be expressed in seconds]
- expected: FAIL
-
[[week\] stepUp method support on input 'week' element]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/email.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/email.html.ini
index 9b416594a19..c0017e10a70 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/email.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/email.html.ini
@@ -1,8 +1,5 @@
[email.html]
type: testharness
- [single_email doesn't have the multiple attribute]
- expected: FAIL
-
[value should be sanitized: strip line breaks]
expected: FAIL
@@ -12,9 +9,6 @@
[When the multiple attribute is removed, the user agent must run the value sanitization algorithm]
expected: FAIL
- [multiple_email has the multiple attribute]
- expected: FAIL
-
[run the value sanitization algorithm after setting a new value]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini
index 5b161f4a92e..cf323449f7b 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/range.html.ini
@@ -1,11 +1,5 @@
[range.html]
type: testharness
- [min attribute support on input element]
- expected: FAIL
-
- [max attribute support on input element]
- expected: FAIL
-
[Illegal value of min attribute]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini b/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini
index b2368ef46ea..d6b334e84f2 100644
--- a/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini
+++ b/tests/wpt/metadata/html/semantics/forms/the-input-element/time.html.ini
@@ -1,23 +1,5 @@
[time.html]
type: testharness
- [step attribute on default value check]
- expected: FAIL
-
- [max attribute on default value check]
- expected: FAIL
-
- [min attribute on default value check]
- expected: FAIL
-
- [max attribute support on input element]
- expected: FAIL
-
- [min attribute support on input element]
- expected: FAIL
-
- [step attribute support on input element]
- expected: FAIL
-
[stepUp function support on input Element]
expected: FAIL
diff --git a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/rowIndex.html.ini b/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/rowIndex.html.ini
deleted file mode 100644
index 040144197ea..00000000000
--- a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/rowIndex.html.ini
+++ /dev/null
@@ -1,38 +0,0 @@
-[rowIndex.html]
- type: testharness
- [HTMLTableRowElement.rowIndex]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 1]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 2]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 3]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 4]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 5]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 6]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 7]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 8]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 9]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 10]
- expected: FAIL
-
- [HTMLTableRowElement.rowIndex 11]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html.ini b/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html.ini
deleted file mode 100644
index 11bf47c819b..00000000000
--- a/tests/wpt/metadata/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html.ini
+++ /dev/null
@@ -1,59 +0,0 @@
-[sectionRowIndex.html]
- type: testharness
- [Row in thead in HTML]
- expected: FAIL
-
- [Row in implicit tbody in HTML]
- expected: FAIL
-
- [Other row in implicit tbody in HTML]
- expected: FAIL
-
- [Row in explicit tbody in HTML]
- expected: FAIL
-
- [Row in tfoot in HTML]
- expected: FAIL
-
- [Row in thead in nested table in HTML]
- expected: FAIL
-
- [Row in implicit tbody in nested table in HTML]
- expected: FAIL
-
- [Row in explicit tbody in nested table in HTML]
- expected: FAIL
-
- [Row in script-created table]
- expected: FAIL
-
- [Row in script-created div in table]
- expected: FAIL
-
- [Row in script-created thead in table]
- expected: FAIL
-
- [Row in script-created tbody in table]
- expected: FAIL
-
- [Row in script-created tfoot in table]
- expected: FAIL
-
- [Row in script-created tr in tbody in table]
- expected: FAIL
-
- [Row in script-created td in tr in tbody in table]
- expected: FAIL
-
- [Row in script-created nested table]
- expected: FAIL
-
- [Row in script-created thead in nested table]
- expected: FAIL
-
- [Row in script-created tbody in nested table]
- expected: FAIL
-
- [Row in script-created tfoot in nested table]
- expected: FAIL
-
diff --git a/tests/wpt/metadata/mozilla-sync b/tests/wpt/metadata/mozilla-sync
index a5890f0d625..042374c3deb 100644
--- a/tests/wpt/metadata/mozilla-sync
+++ b/tests/wpt/metadata/mozilla-sync
@@ -1 +1 @@
-0397e2a24d3e5c988b089ef100002397f4cabdfa \ No newline at end of file
+f9608022caf7f223dfdfe960c31fb5fe7eb0d1f1 \ No newline at end of file
diff --git a/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini b/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini
index 3054ff5b380..1733d692fa9 100644
--- a/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini
+++ b/tests/wpt/metadata/url/a-element-xhtml.xhtml.ini
@@ -792,3 +792,9 @@
[Parsing: <h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg> against <about:blank>]
expected: FAIL
+ [Parsing: <?a=b&c=d> against <http://example.org/foo/bar>]
+ expected: FAIL
+
+ [Parsing: <??a=b&c=d> against <http://example.org/foo/bar>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/url/a-element.html.ini b/tests/wpt/metadata/url/a-element.html.ini
index b4f11adcb34..f4a3706ae28 100644
--- a/tests/wpt/metadata/url/a-element.html.ini
+++ b/tests/wpt/metadata/url/a-element.html.ini
@@ -792,3 +792,9 @@
[Parsing: <h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg> against <about:blank>]
expected: FAIL
+ [Parsing: <?a=b&c=d> against <http://example.org/foo/bar>]
+ expected: FAIL
+
+ [Parsing: <??a=b&c=d> against <http://example.org/foo/bar>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/url/url-constructor.html.ini b/tests/wpt/metadata/url/url-constructor.html.ini
index e9f116005c1..04058f5ebbd 100644
--- a/tests/wpt/metadata/url/url-constructor.html.ini
+++ b/tests/wpt/metadata/url/url-constructor.html.ini
@@ -198,3 +198,15 @@
[Parsing: <h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg> against <about:blank>]
expected: FAIL
+ [URL.searchParams updating, clearing]
+ expected: FAIL
+
+ [URL.searchParams and URL.search setters, update propagation]
+ expected: FAIL
+
+ [Parsing: <?a=b&c=d> against <http://example.org/foo/bar>]
+ expected: FAIL
+
+ [Parsing: <??a=b&c=d> against <http://example.org/foo/bar>]
+ expected: FAIL
+
diff --git a/tests/wpt/metadata/workers/semantics/xhr/001.html.ini b/tests/wpt/metadata/workers/semantics/xhr/001.html.ini
deleted file mode 100644
index 67f5d9b0879..00000000000
--- a/tests/wpt/metadata/workers/semantics/xhr/001.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[001.html]
- type: testharness
- expected: CRASH
diff --git a/tests/wpt/metadata/workers/semantics/xhr/002.html.ini b/tests/wpt/metadata/workers/semantics/xhr/002.html.ini
deleted file mode 100644
index 33350a42d01..00000000000
--- a/tests/wpt/metadata/workers/semantics/xhr/002.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[002.html]
- type: testharness
- expected: TIMEOUT
- [sync XMLHttpRequest in dedicated worker]
- expected: TIMEOUT
-
diff --git a/tests/wpt/mozilla/meta/MANIFEST.json b/tests/wpt/mozilla/meta/MANIFEST.json
index 0e0e983b54f..3a382bae04b 100644
--- a/tests/wpt/mozilla/meta/MANIFEST.json
+++ b/tests/wpt/mozilla/meta/MANIFEST.json
@@ -2423,6 +2423,18 @@
"url": "/_mozilla/css/inline_element_border_a.html"
}
],
+ "css/inline_font_size_zero_a.html": [
+ {
+ "path": "css/inline_font_size_zero_a.html",
+ "references": [
+ [
+ "/_mozilla/css/inline_font_size_zero_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/inline_font_size_zero_a.html"
+ }
+ ],
"css/inline_hypothetical_box_a.html": [
{
"path": "css/inline_hypothetical_box_a.html",
@@ -3167,6 +3179,54 @@
"url": "/_mozilla/css/marker_block_direction_placement_a.html"
}
],
+ "css/max_inline_block_size.html": [
+ {
+ "path": "css/max_inline_block_size.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size.html"
+ }
+ ],
+ "css/max_inline_block_size_canvas.html": [
+ {
+ "path": "css/max_inline_block_size_canvas.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size_canvas.html"
+ }
+ ],
+ "css/max_inline_block_size_image.html": [
+ {
+ "path": "css/max_inline_block_size_image.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size_image.html"
+ }
+ ],
+ "css/max_inline_block_size_ref.html": [
+ {
+ "path": "css/max_inline_block_size_ref.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size_ref.html"
+ }
+ ],
"css/max_width_float_simple_a.html": [
{
"path": "css/max_width_float_simple_a.html",
@@ -5733,6 +5793,12 @@
]
},
"testharness": {
+ "css/flex-item-assign-inline-size.html": [
+ {
+ "path": "css/flex-item-assign-inline-size.html",
+ "url": "/_mozilla/css/flex-item-assign-inline-size.html"
+ }
+ ],
"css/float_relative_to_position.html": [
{
"path": "css/float_relative_to_position.html",
@@ -6483,6 +6549,12 @@
"url": "/_mozilla/mozilla/webgl/get_supported_extensions.html"
}
],
+ "mozilla/webgl/invalid_vertex_attributes.html": [
+ {
+ "path": "mozilla/webgl/invalid_vertex_attributes.html",
+ "url": "/_mozilla/mozilla/webgl/invalid_vertex_attributes.html"
+ }
+ ],
"mozilla/websocket_connection_fail.html": [
{
"path": "mozilla/websocket_connection_fail.html",
@@ -8941,6 +9013,18 @@
"url": "/_mozilla/css/inline_element_border_a.html"
}
],
+ "css/inline_font_size_zero_a.html": [
+ {
+ "path": "css/inline_font_size_zero_a.html",
+ "references": [
+ [
+ "/_mozilla/css/inline_font_size_zero_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/inline_font_size_zero_a.html"
+ }
+ ],
"css/inline_hypothetical_box_a.html": [
{
"path": "css/inline_hypothetical_box_a.html",
@@ -9685,6 +9769,54 @@
"url": "/_mozilla/css/marker_block_direction_placement_a.html"
}
],
+ "css/max_inline_block_size.html": [
+ {
+ "path": "css/max_inline_block_size.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size.html"
+ }
+ ],
+ "css/max_inline_block_size_canvas.html": [
+ {
+ "path": "css/max_inline_block_size_canvas.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size_canvas.html"
+ }
+ ],
+ "css/max_inline_block_size_image.html": [
+ {
+ "path": "css/max_inline_block_size_image.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size_image.html"
+ }
+ ],
+ "css/max_inline_block_size_ref.html": [
+ {
+ "path": "css/max_inline_block_size_ref.html",
+ "references": [
+ [
+ "/_mozilla/css/max_inline_block_size_ref.html",
+ "=="
+ ]
+ ],
+ "url": "/_mozilla/css/max_inline_block_size_ref.html"
+ }
+ ],
"css/max_width_float_simple_a.html": [
{
"path": "css/max_width_float_simple_a.html",
diff --git a/tests/wpt/mozilla/meta/mozilla/preferences.html.ini b/tests/wpt/mozilla/meta/mozilla/preferences.html.ini
index 69e87de33ec..dad937dd5a9 100644
--- a/tests/wpt/mozilla/meta/mozilla/preferences.html.ini
+++ b/tests/wpt/mozilla/meta/mozilla/preferences.html.ini
@@ -1,10 +1,3 @@
[preferences.html]
type: testharness
- prefs: [
- dom.testbinding.preference_value.falsy:false,
- dom.testbinding.preference_value.truthy:true,
- dom.testbinding.preference_value.string_empty:,
- dom.testbinding.preference_value.string_test:test,
- dom.testbinding.preference_value.space_string_test:test1 test2,
- dom.testbinding.preference_value.quote_string_test:"test1 test2",
- ]
+ prefs: [dom.testbinding.preference_value.falsy:false, dom.testbinding.preference_value.truthy:true, dom.testbinding.preference_value.string_empty:, dom.testbinding.preference_value.string_test:test, dom.testbinding.preference_value.space_string_test:test1 test2, dom.testbinding.preference_value.quote_string_test:"test1 test2"]
diff --git a/tests/wpt/mozilla/tests/css/250x250_green.png b/tests/wpt/mozilla/tests/css/250x250_green.png
new file mode 100644
index 00000000000..586ef3d69d6
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/250x250_green.png
Binary files differ
diff --git a/tests/wpt/mozilla/tests/css/flex-item-assign-inline-size.html b/tests/wpt/mozilla/tests/css/flex-item-assign-inline-size.html
new file mode 100644
index 00000000000..a6f0dd15169
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/flex-item-assign-inline-size.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Test inline size against percentage</title>
+<style>
+#container {
+ width: 500px;
+ height: 500px;
+ background: white;
+}
+#container > div {
+ display: flex;
+ background: red;
+}
+#container > div > div {
+ background: green;
+}
+#flex-container0 {
+ flex-direction: column;
+ height: 20%;
+ width: 10%;
+}
+#flex-item0 {
+ width: 10%;
+}
+#flex-container1 {
+ flex-direction: row;
+ height: 20%;
+ width: 10%;
+}
+#flex-item1 {
+ width: 10%;
+ background: green;
+}
+</style>
+ </head>
+ <body>
+ <div id="container">
+ <div id="flex-container0">
+ <div id="flex-item0">
+ </div>
+ </div>
+ <div id="flex-container1">
+ <div id="flex-item1">
+ </div>
+ </div>
+ </div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ var flex_container0 = document.getElementById("flex-container0");
+ var flex_item0 = document.getElementById("flex-item0");
+
+ var flex_container1 = document.getElementById("flex-container1");
+ var flex_item1 = document.getElementById("flex-item1");
+
+ assert_equals(flex_container0.clientWidth, 50);
+ assert_equals(flex_item0.clientWidth, 5);
+
+ assert_equals(flex_container1.clientWidth, 50);
+ assert_equals(flex_item1.clientWidth, 5);
+});
+</script>
+</body>
+</html>
diff --git a/tests/wpt/mozilla/tests/css/inline_font_size_zero_a.html b/tests/wpt/mozilla/tests/css/inline_font_size_zero_a.html
new file mode 100644
index 00000000000..aface0759c0
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/inline_font_size_zero_a.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title></title>
+<link rel="match" href="inline_font_size_zero_ref.html">
+<div style="width: 600px; font-size: 0;">
+ <div style="display: inline-block; width: 200px; background: blue; height: 50px;"></div>
+ <div style="display: inline-block; width: 400px; background: green; height: 50px;"></div>
+</div>
+
diff --git a/tests/wpt/mozilla/tests/css/inline_font_size_zero_ref.html b/tests/wpt/mozilla/tests/css/inline_font_size_zero_ref.html
new file mode 100644
index 00000000000..c370413deee
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/inline_font_size_zero_ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title></title>
+<div style="width: 600px;">
+ <div style="display: inline-block; width: 200px; background: blue; height: 50px;"></div><!--
+ --><div style="display: inline-block; width: 400px; background: green; height: 50px;"></div>
+</div>
+
+
diff --git a/tests/wpt/mozilla/tests/css/max_inline_block_size.html b/tests/wpt/mozilla/tests/css/max_inline_block_size.html
new file mode 100644
index 00000000000..f0f23893143
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/max_inline_block_size.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Max inline-block size inside another inline-block element</title>
+<link rel="match" href="max_inline_block_size_ref.html">
+<style>
+html, body { margin: 0; padding: 0; }
+
+div { display: inline-block; }
+
+#a {
+ background: red;
+}
+
+#b {
+ background: rgb(0, 255, 0);
+ width: 500px;
+ max-width: 250px;
+ height: 250px;
+}
+</style>
+<div id="a"><div id="b"></div></div>
diff --git a/tests/wpt/mozilla/tests/css/max_inline_block_size_canvas.html b/tests/wpt/mozilla/tests/css/max_inline_block_size_canvas.html
new file mode 100644
index 00000000000..48cd896a2b7
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/max_inline_block_size_canvas.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Max inline-block size inside another inline-block element</title>
+<link rel="match" href="max_inline_block_size_ref.html">
+<style>
+html, body { margin: 0; padding: 0; }
+
+div, canvas { display: inline-block; }
+
+#a {
+ background: red;
+}
+
+#c {
+ max-width: 250px;
+ height: 250px;
+}
+</style>
+<div id="a"><canvas width="500" height="250" id="c"></canvas></div>
+<script>
+ var c = document.getElementById("c").getContext("2d");
+ c.fillStyle = "rgb(0, 255, 0)";
+ c.fillRect(0, 0, c.canvas.width, c.canvas.height);
+</script>
diff --git a/tests/wpt/mozilla/tests/css/max_inline_block_size_image.html b/tests/wpt/mozilla/tests/css/max_inline_block_size_image.html
new file mode 100644
index 00000000000..283bbd43256
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/max_inline_block_size_image.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Max inline-block size inside another inline-block element</title>
+<link rel="match" href="max_inline_block_size_ref.html">
+<style>
+html, body { margin: 0; padding: 0; }
+
+div, img { display: inline-block; }
+
+#a {
+ background: red;
+}
+
+#b {
+ max-width: 250px;
+}
+</style>
+<div id="a"><img id="b" width="500" height="250" src="250x250_green.png"></div>
diff --git a/tests/wpt/mozilla/tests/css/max_inline_block_size_ref.html b/tests/wpt/mozilla/tests/css/max_inline_block_size_ref.html
new file mode 100644
index 00000000000..7fa1370faf7
--- /dev/null
+++ b/tests/wpt/mozilla/tests/css/max_inline_block_size_ref.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Max inline-block size inside another inline-block element</title>
+<link rel="match" href="max_inline_block_size_ref.html">
+<style>
+html, body { margin: 0; padding: 0; }
+
+div { display: inline-block; }
+
+#a {
+ background: red;
+}
+
+#b {
+ background: rgb(0, 255, 0);
+ width: 250px;
+ height: 250px;
+}
+</style>
+<div id="a"><div id="b"></div></div>
diff --git a/tests/wpt/mozilla/tests/mozilla/webgl/invalid_vertex_attributes.html b/tests/wpt/mozilla/tests/mozilla/webgl/invalid_vertex_attributes.html
new file mode 100644
index 00000000000..ed132004abf
--- /dev/null
+++ b/tests/wpt/mozilla/tests/mozilla/webgl/invalid_vertex_attributes.html
@@ -0,0 +1,60 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Validation of out-of-bounds vertex attributes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script id="shader-fs" type="x-shader/x-fragment">
+precision mediump float;
+void main() {
+ gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
+}
+</script>
+<script id="shader-vs" type="x-shader/x-vertex">
+void main() {
+
+}
+</script>
+<script type="application/x-javascript">
+ function getShader(gl, id) {
+ var shaderScript = document.getElementById(id);
+ if (!shaderScript)
+ return null;
+ var type = (shaderScript.getAttribute('type') == "x-shader/x-fragment") ?
+ gl.FRAGMENT_SHADER : gl.VERTEX_SHADER;
+ var shader = gl.createShader(type);
+ gl.shaderSource(shader, shaderScript.textContent);
+ gl.compileShader(shader);
+ assert_true(!!gl.getShaderParameter(shader, gl.COMPILE_STATUS), shaderScript.textContent + '\n' + gl.getShaderInfoLog(shader));
+ return shader;
+ }
+ </script>
+ <canvas id="canvas"></canvas>
+ <script>
+ test(function() {
+ var canvas = document.getElementById("canvas");
+ var gl = canvas.getContext("experimental-webgl");
+ assert_true(!!gl);
+
+ var shaderProgram = gl.createProgram();
+ var vertexShader = getShader(gl, "shader-vs");
+ gl.attachShader(shaderProgram, vertexShader);
+ var fragmentShader = getShader(gl, "shader-fs");
+ gl.attachShader(shaderProgram, fragmentShader);
+ gl.linkProgram(shaderProgram);
+ gl.useProgram(shaderProgram);
+ assert_true(gl.getError() == gl.NO_ERROR);
+
+ // -1 is what it's returned from a not found attribute.
+ gl.enableVertexAttribArray(-1);
+ assert_true(gl.getError() == gl.INVALID_VALUE);
+ assert_true(gl.getError() == gl.NO_ERROR);
+
+ gl.vertexAttribPointer(-1, 2, gl.FLOAT, false, 0, 0);
+ assert_true(gl.getError() == gl.INVALID_VALUE);
+ assert_true(gl.getError() == gl.NO_ERROR);
+
+ gl.vertexAttrib1f(-1, 3.0);
+ assert_true(gl.getError() == gl.INVALID_VALUE);
+ });
+ </script>
+</html>
diff --git a/tests/wpt/web-platform-tests/XMLHttpRequest/setrequestheader-bogus-value.htm b/tests/wpt/web-platform-tests/XMLHttpRequest/setrequestheader-bogus-value.htm
index 3d23e164bc0..c3aa076c971 100644
--- a/tests/wpt/web-platform-tests/XMLHttpRequest/setrequestheader-bogus-value.htm
+++ b/tests/wpt/web-platform-tests/XMLHttpRequest/setrequestheader-bogus-value.htm
@@ -12,16 +12,20 @@
<script>
function try_value(value) {
test(function() {
- var client = new XMLHttpRequest()
- client.open("GET", "...")
- assert_throws("SyntaxError", function() { client.setRequestHeader("x-test", value) }, ' given value ' + value+', ')
- })
+ var client = new XMLHttpRequest();
+ client.open("GET", "...");
+ assert_throws("SyntaxError", function() { client.setRequestHeader("x-test", value) }, ' given value ' + value+', ');
+ });
}
- try_value("t\rt")
- try_value("t\nt")
+ try_value("t\rt");
+ try_value("t\nt");
try_value("t\bt");
try_value("\x7f");
- try_value("テスト")
+ test(function() {
+ var client = new XMLHttpRequest();
+ client.open("GET", "...");
+ assert_throws(new TypeError(), function() { client.setRequestHeader("x-test", "テスト") }, ' given value テスト,');
+ });
test(function() {
var client = new XMLHttpRequest()
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001-ref.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001-ref.html
new file mode 100644
index 00000000000..8d9b8cc22e7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color: untouched</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<div style="color: green">These texts should be green</div>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001a.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001a.html
new file mode 100644
index 00000000000..363f5608efa
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001a.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color: green</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of texts should be green">
+<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
+<div style="-webkit-text-fill-color: green;">These texts should be green</div>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001b.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001b.html
new file mode 100644
index 00000000000..3b9a68cf777
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001b.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color: green</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of texts should be green">
+<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
+<div style="color: red; -webkit-text-fill-color: green;">These texts should be green</div>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001c.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001c.html
new file mode 100644
index 00000000000..54d60076230
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001c.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color: green</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of texts should be green">
+<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
+<div style="color: red; -webkit-text-fill-color: green;">These texts <span style="color: red">should be green</span></div>
diff --git a/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001d.html b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001d.html
new file mode 100644
index 00000000000..a38653944a5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/compat/webkit-text-fill-color-property-001d.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>webkit-text-fill-color: green</title>
+<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
+<meta name="assert" content="The color of texts should be green">
+<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
+<div style="color: transparent; -webkit-text-fill-color: green;">These texts should be green</div>
diff --git a/tests/wpt/web-platform-tests/dom/collections/HTMLCollection-as-proto-length-get-throws.html b/tests/wpt/web-platform-tests/dom/collections/HTMLCollection-as-proto-length-get-throws.html
new file mode 100644
index 00000000000..225c9e61a38
--- /dev/null
+++ b/tests/wpt/web-platform-tests/dom/collections/HTMLCollection-as-proto-length-get-throws.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Make sure browsers throw when getting .length on some random object whose proto is an HTMLCollection</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+test(function() {
+ var obj = Object.create(document.getElementsByTagName("script"));
+ assert_throws(new TypeError(), function() {
+ obj.length;
+ });
+}, "HTMLcollection as a prototype should not allow getting .length on the base object")
+</script>
diff --git a/tests/wpt/web-platform-tests/dom/interfaces.html b/tests/wpt/web-platform-tests/dom/interfaces.html
index 0efb52fd497..45dd97e2f50 100644
--- a/tests/wpt/web-platform-tests/dom/interfaces.html
+++ b/tests/wpt/web-platform-tests/dom/interfaces.html
@@ -310,6 +310,9 @@ interface Element : Node {
HTMLCollection getElementsByTagName(DOMString localName);
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
HTMLCollection getElementsByClassName(DOMString classNames);
+
+ Element? insertAdjacentElement(DOMString where, Element element); // historical
+ void insertAdjacentText(DOMString where, DOMString data); // historical
};
interface NamedNodeMap {
diff --git a/tests/wpt/web-platform-tests/dom/nodes/Document-Element-getElementsByTagName.js b/tests/wpt/web-platform-tests/dom/nodes/Document-Element-getElementsByTagName.js
index cc2b73646ef..3d206062d3a 100644
--- a/tests/wpt/web-platform-tests/dom/nodes/Document-Element-getElementsByTagName.js
+++ b/tests/wpt/web-platform-tests/dom/nodes/Document-Element-getElementsByTagName.js
@@ -127,17 +127,19 @@ function test_getElementsByTagName(context, element) {
test(function() {
var t = element.appendChild(document.createElementNS("test", "te:st"))
this.add_cleanup(function() {element.removeChild(t)})
- assert_array_equals(context.getElementsByTagName("st"), [t])
+ assert_array_equals(context.getElementsByTagName("st"), [])
assert_array_equals(context.getElementsByTagName("ST"), [])
+ assert_array_equals(context.getElementsByTagName("te:st"), [t])
+ assert_array_equals(context.getElementsByTagName("te:ST"), [])
}, "Element in non-HTML namespace, prefix, lowercase name")
test(function() {
var t = element.appendChild(document.createElementNS("test", "te:ST"))
this.add_cleanup(function() {element.removeChild(t)})
- assert_array_equals(context.getElementsByTagName("ST"), [t])
assert_array_equals(context.getElementsByTagName("st"), [])
+ assert_array_equals(context.getElementsByTagName("ST"), [])
assert_array_equals(context.getElementsByTagName("te:st"), [])
- assert_array_equals(context.getElementsByTagName("te:ST"), [])
+ assert_array_equals(context.getElementsByTagName("te:ST"), [t])
}, "Element in non-HTML namespace, prefix, uppercase name")
test(function() {
diff --git a/tests/wpt/web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml b/tests/wpt/web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml
index e3aae85704d..2ae90748c2f 100644
--- a/tests/wpt/web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml
+++ b/tests/wpt/web-platform-tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml
@@ -37,17 +37,19 @@ test(function() {
test(function() {
var t = document.body.appendChild(document.createElementNS("test", "te:st"))
this.add_cleanup(function() {document.body.removeChild(t)})
- assert_array_equals(document.getElementsByTagName("st"), [t])
+ assert_array_equals(document.getElementsByTagName("st"), [])
assert_array_equals(document.getElementsByTagName("ST"), [])
+ assert_array_equals(document.getElementsByTagName("te:st"), [t])
+ assert_array_equals(document.getElementsByTagName("te:ST"), [])
}, "Element in non-HTML namespace, prefix, lowercase name")
test(function() {
var t = document.body.appendChild(document.createElementNS("test", "te:ST"))
this.add_cleanup(function() {document.body.removeChild(t)})
- assert_array_equals(document.getElementsByTagName("ST"), [t])
+ assert_array_equals(document.getElementsByTagName("ST"), [])
assert_array_equals(document.getElementsByTagName("st"), [])
assert_array_equals(document.getElementsByTagName("te:st"), [])
- assert_array_equals(document.getElementsByTagName("te:ST"), [])
+ assert_array_equals(document.getElementsByTagName("te:ST"), [t])
}, "Element in non-HTML namespace, prefix, uppercase name")
test(function() {
diff --git a/tests/wpt/web-platform-tests/dom/nodes/Element-classlist.html b/tests/wpt/web-platform-tests/dom/nodes/Element-classlist.html
index cad3669da11..d3d6deb040c 100644
--- a/tests/wpt/web-platform-tests/dom/nodes/Element-classlist.html
+++ b/tests/wpt/web-platform-tests/dom/nodes/Element-classlist.html
@@ -66,8 +66,8 @@ test(function () {
assert_equals( elem.classList.toString(), ' ', 'explicit' );
}, 'classList should contain initial markup whitespace');
test(function () {
- assert_throws( 'SYNTAX_ERR', function () { elem.classList.contains(''); } );
-}, '.contains(empty_string) must throw a SYNTAX_ERR');
+ assert_false( elem.classList.contains('') );
+}, '.contains(empty_string) must return false');
test(function () {
assert_throws( 'SYNTAX_ERR', function () { elem.classList.add(''); } );
}, '.add(empty_string) must throw a SYNTAX_ERR');
@@ -85,8 +85,8 @@ test(function () {
assert_throws( 'SYNTAX_ERR', function () { elem.classList.replace('', ''); } );
}, '.replace with empty_string must throw a SYNTAX_ERR');
test(function () {
- assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.contains('a b'); } );
-}, '.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
+ assert_false( elem.classList.contains('a b') );
+}, '.contains(string_with_spaces) must return false');
test(function () {
assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.add('a b'); } );
}, '.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
diff --git a/tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentElement.html b/tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentElement.html
new file mode 100644
index 00000000000..d03e56680d4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentElement.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<meta charset=utf-8>
+<title></title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+
+<div id="target"></div>
+<div id="parent"><span id=target2></span></div>
+<div id="log" style="visibility:visible"></div>
+<span id="test1"></span>
+<span id="test2"></span>
+<span id="test3"></span>
+<span id="test4"></span>
+<script>
+var target = document.getElementById("target");
+var target2 = document.getElementById("target2");
+
+test(function() {
+ assert_throws("SyntaxError", function() {
+ target.insertAdjacentElement("test", document.getElementById("test1"))
+ });
+
+ assert_throws("SyntaxError", function() {
+ target2.insertAdjacentElement("test", document.getElementById("test1"))
+ });
+}, "Inserting to an invalid location should cause a Syntax Error exception")
+
+test(function() {
+ var el = target.insertAdjacentElement("beforebegin", document.getElementById("test1"));
+ assert_equals(target.previousSibling.id, "test1");
+ assert_equals(el.id, "test1");
+
+ el = target2.insertAdjacentElement("beforebegin", document.getElementById("test1"));
+ assert_equals(target2.previousSibling.id, "test1");
+ assert_equals(el.id, "test1");
+}, "Inserted element should be target element's previous sibling for 'beforebegin' case")
+
+test(function() {
+ var el = target.insertAdjacentElement("afterbegin", document.getElementById("test2"));
+ assert_equals(target.firstChild.id, "test2");
+ assert_equals(el.id, "test2");
+
+ el = target2.insertAdjacentElement("afterbegin", document.getElementById("test2"));
+ assert_equals(target2.firstChild.id, "test2");
+ assert_equals(el.id, "test2");
+}, "Inserted element should be target element's first child for 'afterbegin' case")
+
+test(function() {
+ var el = target.insertAdjacentElement("beforeend", document.getElementById("test3"));
+ assert_equals(target.lastChild.id, "test3");
+ assert_equals(el.id, "test3");
+
+ el = target2.insertAdjacentElement("beforeend", document.getElementById("test3"));
+ assert_equals(target2.lastChild.id, "test3");
+ assert_equals(el.id, "test3");
+}, "Inserted element should be target element's last child for 'beforeend' case")
+
+test(function() {
+ var el = target.insertAdjacentElement("afterend", document.getElementById("test4"));
+ assert_equals(target.nextSibling.id, "test4");
+ assert_equals(el.id, "test4");
+
+ el = target2.insertAdjacentElement("afterend", document.getElementById("test4"));
+ assert_equals(target2.nextSibling.id, "test4");
+ assert_equals(el.id, "test4");
+}, "Inserted element should be target element's next sibling for 'afterend' case")
+
+test(function() {
+ var docElement = document.documentElement;
+ docElement.style.visibility="hidden";
+
+ assert_throws("HierarchyRequestError", function() {
+ var el = docElement.insertAdjacentElement("beforebegin", document.getElementById("test1"));
+ assert_equals(el, null);
+ });
+
+ var el = docElement.insertAdjacentElement("afterbegin", document.getElementById("test2"));
+ assert_equals(docElement.firstChild.id, "test2");
+ assert_equals(el.id, "test2");
+
+ el = docElement.insertAdjacentElement("beforeend", document.getElementById("test3"));
+ assert_equals(docElement.lastChild.id, "test3");
+ assert_equals(el.id, "test3");
+
+ assert_throws("HierarchyRequestError", function() {
+ var el = docElement.insertAdjacentElement("afterend", document.getElementById("test4"));
+ assert_equals(el, null);
+ });
+}, "Adding more than one child to document should cause a HierarchyRequestError exception")
+
+</script>
diff --git a/tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentText.html b/tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentText.html
new file mode 100644
index 00000000000..0fafabb519a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/dom/nodes/Element-insertAdjacentText.html
@@ -0,0 +1,76 @@
+<!doctype html>
+<meta charset=utf-8>
+<title></title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body style="visibility:hidden">
+<div id="target"></div>
+<div id="parent"><span id=target2></span></div>
+<div id="log" style="visibility:visible"></div>
+</body>
+<script>
+var target = document.getElementById("target");
+var target2 = document.getElementById("target2");
+
+test(function() {
+ assert_throws("SyntaxError", function() {
+ target.insertAdjacentText("test", "text")
+ });
+
+ assert_throws("SyntaxError", function() {
+ target2.insertAdjacentText("test", "test")
+ });
+}, "Inserting to an invalid location should cause a Syntax Error exception")
+
+test(function() {
+ target.insertAdjacentText("beforebegin", "test1");
+ assert_equals(target.previousSibling.nodeValue, "test1");
+
+ target2.insertAdjacentText("beforebegin", "test1");
+ assert_equals(target2.previousSibling.nodeValue, "test1");
+}, "Inserted text node should be target element's previous sibling for 'beforebegin' case")
+
+test(function() {
+ target.insertAdjacentText("afterbegin", "test2");
+ assert_equals(target.firstChild.nodeValue, "test2");
+
+ target2.insertAdjacentText("afterbegin", "test2");
+ assert_equals(target2.firstChild.nodeValue, "test2");
+}, "Inserted text node should be target element's first child for 'afterbegin' case")
+
+test(function() {
+ target.insertAdjacentText("beforeend", "test3");
+ assert_equals(target.lastChild.nodeValue, "test3");
+
+ target2.insertAdjacentText("beforeend", "test3");
+ assert_equals(target2.lastChild.nodeValue, "test3");
+}, "Inserted text node should be target element's last child for 'beforeend' case")
+
+test(function() {
+ target.insertAdjacentText("afterend", "test4");
+ assert_equals(target.nextSibling.nodeValue, "test4");
+
+ target2.insertAdjacentText("afterend", "test4");
+ assert_equals(target.nextSibling.nodeValue, "test4");
+}, "Inserted text node should be target element's next sibling for 'afterend' case")
+
+test(function() {
+ var docElement = document.documentElement;
+ docElement.style.visibility="hidden";
+
+ assert_throws("HierarchyRequestError", function() {
+ docElement.insertAdjacentText("beforebegin", "text1")
+ });
+
+ docElement.insertAdjacentText("afterbegin", "test2");
+ assert_equals(docElement.firstChild.nodeValue, "test2");
+
+ docElement.insertAdjacentText("beforeend", "test3");
+ assert_equals(docElement.lastChild.nodeValue, "test3");
+
+ assert_throws("HierarchyRequestError", function() {
+ docElement.insertAdjacentText("afterend", "test4")
+ });
+}, "Adding more than one child to document should cause a HierarchyRequestError exception")
+
+</script>
diff --git a/tests/wpt/web-platform-tests/dom/nodes/case.js b/tests/wpt/web-platform-tests/dom/nodes/case.js
index fb28b9514a3..8c2da4a44af 100644
--- a/tests/wpt/web-platform-tests/dom/nodes/case.js
+++ b/tests/wpt/web-platform-tests/dom/nodes/case.js
@@ -73,6 +73,13 @@ function ascii_lowercase(input) {
});
}
+function get_qualified_name(el) {
+ if (el.prefix) {
+ return el.prefix + ":" + el.localName;
+ }
+ return el.localName;
+}
+
function test_create_element(name) {
var node = document.createElement(name);
assert_equals(node.localName, expected_case(name));
@@ -133,9 +140,9 @@ function test_get_elements_tag_name(elements_to_create, search_string) {
var expected = Array.prototype.filter.call(container.childNodes,
function(node) {
if (is_html && node.namespaceURI === "http://www.w3.org/1999/xhtml") {
- return node.localName === expected_case(search_string);
+ return get_qualified_name(node) === expected_case(search_string);
} else {
- return node.localName === search_string;
+ return get_qualified_name(node) === search_string;
}
});
document.documentElement.appendChild(container);
diff --git a/tests/wpt/web-platform-tests/dom/nodes/remove-unscopable.html b/tests/wpt/web-platform-tests/dom/nodes/remove-unscopable.html
new file mode 100644
index 00000000000..120ae813205
--- /dev/null
+++ b/tests/wpt/web-platform-tests/dom/nodes/remove-unscopable.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset=utf-8>
+<title></title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="testDiv" onclick="result1 = remove; result2 = this.remove;"></div>
+<script>
+var remove = "Hello there";
+var result1;
+var result2;
+test(function() {
+ assert_true(Element.prototype[Symbol.unscopables].remove);
+ var div = document.querySelector("#testDiv");
+ div.dispatchEvent(new Event("click"));
+ assert_equals(typeof result1, "string");
+ assert_equals(typeof result2, "function");
+}, "remove() should be unscopable")
+</script>
diff --git a/tests/wpt/web-platform-tests/encoding/api-basics.html b/tests/wpt/web-platform-tests/encoding/api-basics.html
index 084575655c9..83670ce7dc3 100644
--- a/tests/wpt/web-platform-tests/encoding/api-basics.html
+++ b/tests/wpt/web-platform-tests/encoding/api-basics.html
@@ -15,13 +15,11 @@ test(function() {
}, 'Default inputs');
-function testEncodeDecodeSample(encoding, string, bytes) {
+function testDecodeSample(encoding, string, bytes) {
test(function() {
- var encoded = new TextEncoder(encoding).encode(string);
- assert_array_equals([].slice.call(encoded), bytes);
assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes)), string);
assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes).buffer), string);
- }, 'Encode/decode round trip: ' + encoding);
+ }, 'Decode sample: ' + encoding);
}
// z (ASCII U+007A), cent (Latin-1 U+00A2), CJK water (BMP U+6C34),
@@ -29,25 +27,29 @@ function testEncodeDecodeSample(encoding, string, bytes) {
// byte-swapped BOM (non-character U+FFFE)
var sample = 'z\xA2\u6C34\uD834\uDD1E\uF8FF\uDBFF\uDFFD\uFFFE';
-testEncodeDecodeSample(
- 'utf-8',
- sample,
- [0x7A, 0xC2, 0xA2, 0xE6, 0xB0, 0xB4, 0xF0, 0x9D, 0x84, 0x9E, 0xEF, 0xA3, 0xBF, 0xF4, 0x8F, 0xBF, 0xBD, 0xEF, 0xBF, 0xBE]
-);
-
-testEncodeDecodeSample(
+test(function() {
+ var encoding = 'utf-8';
+ var string = sample;
+ var bytes = [0x7A, 0xC2, 0xA2, 0xE6, 0xB0, 0xB4, 0xF0, 0x9D, 0x84, 0x9E, 0xEF, 0xA3, 0xBF, 0xF4, 0x8F, 0xBF, 0xBD, 0xEF, 0xBF, 0xBE];
+ var encoded = new TextEncoder().encode(string);
+ assert_array_equals([].slice.call(encoded), bytes);
+ assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes)), string);
+ assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes).buffer), string);
+}, 'Encode/decode round trip: utf-8');
+
+testDecodeSample(
'utf-16le',
sample,
[0x7A, 0x00, 0xA2, 0x00, 0x34, 0x6C, 0x34, 0xD8, 0x1E, 0xDD, 0xFF, 0xF8, 0xFF, 0xDB, 0xFD, 0xDF, 0xFE, 0xFF]
);
-testEncodeDecodeSample(
+testDecodeSample(
'utf-16be',
sample,
[0x00, 0x7A, 0x00, 0xA2, 0x6C, 0x34, 0xD8, 0x34, 0xDD, 0x1E, 0xF8, 0xFF, 0xDB, 0xFF, 0xDF, 0xFD, 0xFF, 0xFE]
);
-testEncodeDecodeSample(
+testDecodeSample(
'utf-16',
sample,
[0x7A, 0x00, 0xA2, 0x00, 0x34, 0x6C, 0x34, 0xD8, 0x1E, 0xDD, 0xFF, 0xF8, 0xFF, 0xDB, 0xFD, 0xDF, 0xFE, 0xFF]
diff --git a/tests/wpt/web-platform-tests/encoding/api-invalid-label.html b/tests/wpt/web-platform-tests/encoding/api-invalid-label.html
index ff037173a11..f15c184aa89 100644
--- a/tests/wpt/web-platform-tests/encoding/api-invalid-label.html
+++ b/tests/wpt/web-platform-tests/encoding/api-invalid-label.html
@@ -24,10 +24,6 @@ setup(function() {
tests.forEach(function(input) {
test(function() {
- assert_throws(new RangeError(), function() { new TextEncoder(input); });
- }, 'Invalid label ' + format_value(input) + ' should be rejected by TextEncoder.');
-
- test(function() {
assert_throws(new RangeError(), function() { new TextDecoder(input); });
}, 'Invalid label ' + format_value(input) + ' should be rejected by TextDecoder.');
});
diff --git a/tests/wpt/web-platform-tests/encoding/api-replacement-encodings.html b/tests/wpt/web-platform-tests/encoding/api-replacement-encodings.html
index ef0cdb88ec0..2dffd72e7b4 100644
--- a/tests/wpt/web-platform-tests/encoding/api-replacement-encodings.html
+++ b/tests/wpt/web-platform-tests/encoding/api-replacement-encodings.html
@@ -6,7 +6,6 @@
<script>
test(function() {
- assert_throws(new RangeError(), function() { new TextEncoder('replacement'); });
assert_throws(new RangeError(), function() { new TextDecoder('replacement'); });
}, 'The "replacement" label should not be a known encoding.');
@@ -16,7 +15,6 @@ encodings_table.forEach(function(section) {
}).forEach(function(encoding) {
encoding.labels.forEach(function(label) {
test(function() {
- assert_throws(new RangeError(), function() { new TextEncoder(label); });
assert_throws(new RangeError(), function() { new TextDecoder(label); });
}, 'Label for "replacement" should be rejected by API: ' + label);
});
diff --git a/tests/wpt/web-platform-tests/encoding/idlharness.html b/tests/wpt/web-platform-tests/encoding/idlharness.html
index ce44f6d3e0b..c010df3fafa 100644
--- a/tests/wpt/web-platform-tests/encoding/idlharness.html
+++ b/tests/wpt/web-platform-tests/encoding/idlharness.html
@@ -38,7 +38,7 @@ interface TextDecoder {
// 8.2 Interface TextDecoder
-[Constructor(optional DOMString utfLabel = "utf-8"),
+[Constructor,
Exposed=Window,Worker]
interface TextEncoder {
readonly attribute DOMString encoding;
diff --git a/tests/wpt/web-platform-tests/encoding/textdecoder-streaming.html b/tests/wpt/web-platform-tests/encoding/textdecoder-streaming.html
index d514a180648..211b3c00918 100644
--- a/tests/wpt/web-platform-tests/encoding/textdecoder-streaming.html
+++ b/tests/wpt/web-platform-tests/encoding/textdecoder-streaming.html
@@ -5,12 +5,23 @@
<script src="resources/encodings.js"></script>
<script>
-var string = '\\x00123ABCabc\\x80\\xFF\\u0100\\u1000\\uFFFD\\uD800\\uDC00\\uDBFF\\uDFFF';
+var string = '\x00123ABCabc\x80\xFF\u0100\u1000\uFFFD\uD800\uDC00\uDBFF\uDFFF';
+var octets = {
+ 'utf-16le': [0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42,0x00,
+ 0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF,0x00,
+ 0x00,0x01,0x00,0x10,0xFD,0xFF,0x00,0xD8,0x00,0xDC,0xFF,0xDB,
+ 0xFF,0xDF],
+ 'utf-16be': [0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42,
+ 0x00,0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF,
+ 0x01,0x00,0x10,0x00,0xFF,0xFD,0xD8,0x00,0xDC,0x00,0xDB,0xFF,
+ 0xDF,0xFF]
+};
utf_encodings.forEach(function (encoding) {
for (var len = 1; len <= 5; ++len) {
test(function() {
- var encoded = new TextEncoder(encoding).encode(string);
+ var encoded = octets[encoding] ||
+ new TextEncoder(encoding).encode(string);
var out = '';
var decoder = new TextDecoder(encoding);
diff --git a/tests/wpt/web-platform-tests/encoding/textencoder-constructor-non-utf.html b/tests/wpt/web-platform-tests/encoding/textencoder-constructor-non-utf.html
index 82ad56bc46f..f5c2ea54509 100644
--- a/tests/wpt/web-platform-tests/encoding/textencoder-constructor-non-utf.html
+++ b/tests/wpt/web-platform-tests/encoding/textencoder-constructor-non-utf.html
@@ -6,20 +6,16 @@
<script>
encodings_table.forEach(function(section) {
- section.encodings.filter(function(encoding) {
- return encoding.name !== 'replacement';
- }).forEach(function(encoding) {
- if (utf_encodings.indexOf(encoding.name) !== -1) {
+ section.encodings.forEach(function(encoding) {
+ if (encoding.name !== 'replacement') {
test(function() {
assert_equals(new TextDecoder(encoding.name).encoding, encoding.name);
- assert_equals(new TextEncoder(encoding.name).encoding, encoding.name);
- }, 'UTF encodings are supported for encode and decode: ' + encoding.name);
- } else {
- test(function() {
- assert_equals(new TextDecoder(encoding.name).encoding, encoding.name);
- assert_throws(new RangeError(), function() { new TextEncoder(encoding.name); });
- }, 'Non-UTF encodings supported only for decode, not encode: ' + encoding.name);
+ }, 'Encoding argument supported for decode: ' + encoding.name);
}
+
+ test(function() {
+ assert_equals(new TextEncoder(encoding.name).encoding, 'utf-8');
+ }, 'Encoding argument not considered for encode: ' + encoding.name);
});
});
diff --git a/tests/wpt/web-platform-tests/fetch/api/policies/referrer-origin.js b/tests/wpt/web-platform-tests/fetch/api/policies/referrer-origin.js
index 3eb414b2fe4..8f63072ff21 100644
--- a/tests/wpt/web-platform-tests/fetch/api/policies/referrer-origin.js
+++ b/tests/wpt/web-platform-tests/fetch/api/policies/referrer-origin.js
@@ -3,14 +3,14 @@ if (this.document === undefined) {
importScripts("../resources/utils.js");
}
-var origin = "http://{{host}}:{{ports[http][0]}}";
+var referrerOrigin = "http://{{host}}:{{ports[http][0]}}/";
var fetchedUrl = RESOURCES_DIR + "inspect-headers.py?headers=referer";
promise_test(function(test) {
return fetch(fetchedUrl).then(function(resp) {
assert_equals(resp.status, 200, "HTTP status is 200");
assert_equals(resp.type , "basic", "Response's type is basic");
- assert_equals(resp.headers.get("x-request-referer"), origin, "request's referrer is " + origin);
+ assert_equals(resp.headers.get("x-request-referer"), referrerOrigin, "request's referrer is " + referrerOrigin);
});
}, "Request's referrer is origin");
diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html
new file mode 100644
index 00000000000..9e4283e208e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html
@@ -0,0 +1,31 @@
+
+<!doctype html>
+<meta charset=utf-8>
+<style>
+.hr {
+ color: gray;
+ border-style: inset;
+ border-width: 1px;
+ margin: 0.5em auto;
+ width: 100px;
+}
+
+.left {
+ margin-left: 0;
+}
+
+.right {
+ margin-right: 0;
+}
+</style>
+<div class='hr'></div>
+<div class='hr left'></div>
+<div class='hr'></div>
+<div class='hr right'></div>
+<div class='hr'></div>
+
+<div class='hr'></div>
+<div class='hr left'></div>
+<div class='hr'></div>
+<div class='hr right'></div>
+<div class='hr'></div>
diff --git a/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html
new file mode 100644
index 00000000000..1657f2458d0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="match" href="align-ref.html">
+<style>
+hr {
+ width: 100px;
+}
+</style>
+
+<hr align=>
+<hr align=left>
+<hr align=center>
+<hr align=right>
+<hr align=foobar>
+
+<script>
+// Test the IDL attribute
+const values = ['', 'left', 'center', 'right', 'foobar'];
+values.forEach(value => {
+ const hr = document.createElement('hr');
+ hr.align = value;
+ document.body.appendChild(hr);
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js
index 07c44f00ea6..9b7fca0502c 100644
--- a/tests/wpt/web-platform-tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js
+++ b/tests/wpt/web-platform-tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js
@@ -29,8 +29,8 @@ if (window.location.search) {
}
var testContainer = document.querySelector('#testContainer');
-var outerWidth = testContainer.getBoundingClientRect().width;
-var outerHeight = testContainer.getBoundingClientRect().height;
+var testContainerWidth = testContainer.getBoundingClientRect().width;
+var testContainerHeight = testContainer.getBoundingClientRect().height;
SVGSizing.doCombinationTest(
[["placeholder", [ null ]],
@@ -45,7 +45,8 @@ SVGSizing.doCombinationTest(
var testData = new SVGSizing.TestData(config);
var expectedRect =
- testData.computeInlineReplacedSize(outerWidth, outerHeight);
+ testData.computeInlineReplacedSize(testContainerWidth,
+ testContainerHeight);
var svgElement = testData.buildSVGOrPlaceholder();
var container =
testData.buildContainer(svgElement);
diff --git a/tests/wpt/web-platform-tests/html/resources/common.js b/tests/wpt/web-platform-tests/html/resources/common.js
index 0f2bfb1e21a..5d3afd64faf 100644
--- a/tests/wpt/web-platform-tests/html/resources/common.js
+++ b/tests/wpt/web-platform-tests/html/resources/common.js
@@ -157,10 +157,6 @@ function assert_nodelist_contents_equal_noorder(actual, expected, message) {
}
}
-function isVisible(el) {
- return el.offsetTop != 0;
-}
-
function isVoidElement(elementName) {
return HTML5_VOID_ELEMENTS.indexOf(elementName) >= 0;
}
diff --git a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tFoot.html b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tFoot.html
new file mode 100644
index 00000000000..52c6972fefd
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tFoot.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>tFoot tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<table id="t">
+<caption id="tcaption"></caption><thead id="thead"></thead><tbody id="tbody1"></tbody><tbody id="tbody2"></tbody><tfoot id="tfoot1"></tfoot><tfoot id="tfoot2"></tfoot><tfoot id="tfoot3"></tfoot></table>
+<script>
+test(function() {
+ var t = document.getElementById("t");
+ var tfoot1 = document.getElementById("tfoot1");
+
+ assert_equals(t.tFoot, tfoot1);
+
+ var tfoot2 = document.getElementById("tfoot2");
+ t.tFoot = null;
+
+ assert_equals(t.tFoot, tfoot2);
+
+ var tfoot3 = document.getElementById("tfoot3");
+ t.deleteTFoot();
+
+ assert_equals(t.tFoot, tfoot3);
+
+ var tfoot = t.createTFoot();
+ assert_equals(t.tFoot, tfoot);
+ assert_equals(tfoot, tfoot3);
+
+ t.deleteTFoot();
+ assert_equals(t.tFoot, null);
+
+ var tbody2 = document.getElementById("tbody2");
+
+ tfoot = t.createTFoot();
+ assert_equals(t.tFoot, tfoot);
+
+ assert_equals(t.tFoot.previousSibling, tbody2);
+ assert_equals(t.tFoot.nextSibling, null);
+
+ assert_throws(new TypeError(), function(){
+ t.tFoot = document.createElement("div");
+ });
+
+ assert_throws("HierarchyRequestError", function(){
+ t.tFoot = document.createElement("thead");
+ });
+})
+</script>
diff --git a/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tHead.html b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tHead.html
new file mode 100644
index 00000000000..ea2ebf1281d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/html/semantics/tabular-data/the-table-element/tHead.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>tHead tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<table id="t">
+<caption id="tcaption"></caption><thead id="thead1"></thead><thead id="thead2"></thead><thead id="thead3"></thead><tbody id="tbody1"></tbody><tbody id="tbody2"></tbody><tfoot id="tfoot"></tfoot>
+</table>
+<table>
+<thead id="t2thead">
+<td>
+<table id="t2">
+</table>
+</table>
+<script>
+test(function() {
+ var t = document.getElementById("t");
+ var thead1 = document.getElementById("thead1");
+
+ assert_equals(t.tHead, thead1);
+
+ var thead2 = document.getElementById("thead2");
+ t.tHead = null;
+
+ assert_equals(t.tHead, thead2);
+
+ var thead3 = document.getElementById("thead3");
+ t.deleteTHead();
+
+ assert_equals(t.tHead, thead3);
+
+ var thead = t.createTHead();
+ assert_equals(t.tHead, thead);
+ assert_equals(thead, thead3);
+
+ t.deleteTHead();
+ assert_equals(t.tHead, null);
+
+ var tcaption = document.getElementById("tcaption");
+ var tbody1 = document.getElementById("tbody1");
+
+ thead = t.createTHead();
+ assert_equals(t.tHead, thead);
+
+ assert_equals(t.tHead.previousSibling, tcaption);
+ assert_equals(t.tHead.nextSibling, tbody1);
+
+ assert_throws(new TypeError(), function(){
+ t.tHead = document.createElement("div");
+ });
+
+ assert_throws("HierarchyRequestError", function(){
+ t.tHead = document.createElement("tbody");
+ });
+
+});
+
+test(function() {
+ var t2 = document.getElementById("t2");
+ var t2thead = document.getElementById("t2thead");
+
+ assert_throws("HierarchyRequestError", function() {
+ t2.tHead = t2thead;
+ });
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subframe.sub.html b/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subframe.sub.html
new file mode 100644
index 00000000000..dde0ac953ef
--- /dev/null
+++ b/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subframe.sub.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<iframe src="{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}{{location[path]}}/../Promise-incumbent-global-subsubframe.sub.html"></iframe>
+<script>
+ document.domain = "{{host}}";
+ onmessage = function(e) {
+ if (e.data == "start") {
+ frames[0].Promise.resolve().then(frames[0].postMessage.bind(frames[0], "start", "*"));
+ } else {
+ parent.postMessage(e.data, "*");
+ }
+ }
+</script>
diff --git a/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subsubframe.sub.html b/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subsubframe.sub.html
new file mode 100644
index 00000000000..9edd9d278ab
--- /dev/null
+++ b/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global-subsubframe.sub.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<script>
+ document.domain = "{{host}}";
+ onmessage = function (e) {
+ parent.postMessage(
+ {
+ actual: e.origin,
+ expected: "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}",
+ reason: "Incumbent should have been the caller of then()"
+ },
+ "*");
+ }
+</script>
diff --git a/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global.sub.html b/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global.sub.html
new file mode 100644
index 00000000000..6ae0a9fe5e8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/js/builtins/Promise-incumbent-global.sub.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset=utf-8>
+<title></title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe src="{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}{{location[path]}}/../Promise-incumbent-global-subframe.sub.html"></iframe>
+<script>
+
+var t = async_test("Check the incumbent global Promise callbacks are called with");
+
+onload = t.step_func(function() {
+ onmessage = t.step_func_done(function(e) {
+ var d = e.data;
+ assert_equals(d.actual, d.expected, d.reason);
+ });
+
+ frames[0].postMessage("start", "*");
+});
+
+</script>
diff --git a/tests/wpt/web-platform-tests/lint.whitelist b/tests/wpt/web-platform-tests/lint.whitelist
index 8828f8b3a4e..2ab4b9d8513 100644
--- a/tests/wpt/web-platform-tests/lint.whitelist
+++ b/tests/wpt/web-platform-tests/lint.whitelist
@@ -105,6 +105,9 @@ W3C-TEST.ORG:subresource-integrity/refresh-header.js.headers
# semi-legitimate use of console.*
CONSOLE:streams/resources/test-utils.js
+CONSOLE:service-workers/service-worker/resources/navigation-redirect-other-origin.html
+CONSOLE:service-workers/service-worker/navigation-redirect.https.html
+CONSOLE:service-workers/service-worker/resources/clients-get-other-origin.html
# Lint doesn't know about sub.svg I guess
PARSE-FAILED:content-security-policy/svg/including.sub.svg
diff --git a/tests/wpt/web-platform-tests/selection/collapse.html b/tests/wpt/web-platform-tests/selection/collapse.html
index f1268f9f391..530158a05bb 100644
--- a/tests/wpt/web-platform-tests/selection/collapse.html
+++ b/tests/wpt/web-platform-tests/selection/collapse.html
@@ -1,5 +1,6 @@
<!doctype html>
<title>Selection.collapse() tests</title>
+<meta name=timeout content=long>
<div id=log></div>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
diff --git a/tests/wpt/web-platform-tests/selection/extend.html b/tests/wpt/web-platform-tests/selection/extend.html
index bc8fe2cf3d0..e00f8c401a9 100644
--- a/tests/wpt/web-platform-tests/selection/extend.html
+++ b/tests/wpt/web-platform-tests/selection/extend.html
@@ -1,6 +1,7 @@
<!doctype html>
<title>Selection extend() tests</title>
<meta charset=utf-8>
+<meta name=timeout content=long>
<body>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html
new file mode 100644
index 00000000000..3e3cc8b2b08
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/close.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>ServiceWorkerGlobalScope: close operation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../resources/test-helpers.sub.js"></script>
+<script>
+
+service_worker_test(
+ 'resources/close-worker.js', 'ServiceWorkerGlobalScope: close operation');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html
new file mode 100644
index 00000000000..f0dad6a7b28
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/registration-attribute.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>ServiceWorkerGlobalScope: registration</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../resources/test-helpers.sub.js'></script>
+<script>
+
+promise_test(function(t) {
+ var script = 'resources/registration-attribute-worker.js';
+ var scope = 'resources/scope/registration-attribute';
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ var expected_events_seen = [
+ 'updatefound',
+ 'install',
+ 'statechange(installed)',
+ 'statechange(activating)',
+ 'activate',
+ 'statechange(activated)',
+ 'fetch',
+ ];
+
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ expected_events_seen.toString(),
+ 'Service Worker should respond to fetch');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify registration attribute on ServiceWorkerGlobalScope');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js
new file mode 100644
index 00000000000..a1342b187b3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/close-worker.js
@@ -0,0 +1,8 @@
+importScripts('../../resources/interfaces.js');
+importScripts('../../resources/worker-testharness.js');
+
+test(function() {
+ assert_throws({name: 'InvalidAccessError'}, function() {
+ self.close();
+ });
+}, 'ServiceWorkerGlobalScope close operation');
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js
new file mode 100644
index 00000000000..c98acbcfb06
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/registration-attribute-worker.js
@@ -0,0 +1,132 @@
+importScripts('../../resources/test-helpers.sub.js');
+importScripts('../../resources/worker-testharness.js');
+
+var events_seen = [];
+
+assert_equals(
+ self.registration.scope,
+ normalizeURL('scope/registration-attribute'),
+ 'On worker script evaluation, registration attribute should be set');
+assert_equals(
+ self.registration.installing,
+ null,
+ 'On worker script evaluation, installing worker should be null');
+assert_equals(
+ self.registration.waiting,
+ null,
+ 'On worker script evaluation, waiting worker should be null');
+assert_equals(
+ self.registration.active,
+ null,
+ 'On worker script evaluation, active worker should be null');
+
+self.registration.addEventListener('updatefound', function() {
+ events_seen.push('updatefound');
+
+ assert_equals(
+ self.registration.scope,
+ normalizeURL('scope/registration-attribute'),
+ 'On updatefound event, registration attribute should be set');
+ assert_equals(
+ self.registration.installing.scriptURL,
+ normalizeURL('registration-attribute-worker.js'),
+ 'On updatefound event, installing worker should be set');
+ assert_equals(
+ self.registration.waiting,
+ null,
+ 'On updatefound event, waiting worker should be null');
+ assert_equals(
+ self.registration.active,
+ null,
+ 'On updatefound event, active worker should be null');
+
+ assert_equals(
+ self.registration.installing.state,
+ 'installing',
+ 'On updatefound event, worker should be in the installing state');
+
+ var worker = self.registration.installing;
+ self.registration.installing.addEventListener('statechange', function() {
+ events_seen.push('statechange(' + worker.state + ')');
+ });
+ });
+
+self.addEventListener('install', function(e) {
+ events_seen.push('install');
+
+ assert_equals(
+ self.registration.scope,
+ normalizeURL('scope/registration-attribute'),
+ 'On install event, registration attribute should be set');
+ assert_equals(
+ self.registration.installing.scriptURL,
+ normalizeURL('registration-attribute-worker.js'),
+ 'On install event, installing worker should be set');
+ assert_equals(
+ self.registration.waiting,
+ null,
+ 'On install event, waiting worker should be null');
+ assert_equals(
+ self.registration.active,
+ null,
+ 'On install event, active worker should be null');
+
+ assert_equals(
+ self.registration.installing.state,
+ 'installing',
+ 'On install event, worker should be in the installing state');
+ });
+
+self.addEventListener('activate', function(e) {
+ events_seen.push('activate');
+
+ assert_equals(
+ self.registration.scope,
+ normalizeURL('scope/registration-attribute'),
+ 'On activate event, registration attribute should be set');
+ assert_equals(
+ self.registration.installing,
+ null,
+ 'On activate event, installing worker should be null');
+ assert_equals(
+ self.registration.waiting,
+ null,
+ 'On activate event, waiting worker should be null');
+ assert_equals(
+ self.registration.active.scriptURL,
+ normalizeURL('registration-attribute-worker.js'),
+ 'On activate event, active worker should be set');
+
+ assert_equals(
+ self.registration.active.state,
+ 'activating',
+ 'On activate event, worker should be in the activating state');
+ });
+
+self.addEventListener('fetch', function(e) {
+ events_seen.push('fetch');
+
+ assert_equals(
+ self.registration.scope,
+ normalizeURL('scope/registration-attribute'),
+ 'On fetch event, registration attribute should be set');
+ assert_equals(
+ self.registration.installing,
+ null,
+ 'On fetch event, installing worker should be null');
+ assert_equals(
+ self.registration.waiting,
+ null,
+ 'On fetch event, waiting worker should be null');
+ assert_equals(
+ self.registration.active.scriptURL,
+ normalizeURL('registration-attribute-worker.js'),
+ 'On fetch event, active worker should be set');
+
+ assert_equals(
+ self.registration.active.state,
+ 'activated',
+ 'On fetch event, worker should be in the activated state');
+
+ e.respondWith(new Response(events_seen));
+ });
diff --git a/tests/wpt/metadata/html/browsers/history/the-location-interface/document_location.html.ini b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html
index e69de29bb2d..e69de29bb2d 100644
--- a/tests/wpt/metadata/html/browsers/history/the-location-interface/document_location.html.ini
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-controlling-worker.html
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js
new file mode 100644
index 00000000000..6cee5365428
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/unregister-worker.js
@@ -0,0 +1,23 @@
+function matchQuery(query) {
+ return self.location.href.indexOf(query) != -1;
+}
+
+if (matchQuery('?evaluation'))
+ self.registration.unregister();
+
+self.addEventListener('install', function(e) {
+ if (matchQuery('?install'))
+ self.registration.unregister();
+ });
+
+self.addEventListener('activate', function(e) {
+ if (matchQuery('?activate'))
+ self.registration.unregister();
+ });
+
+self.addEventListener('message', function(e) {
+ self.registration.unregister()
+ .then(function(result) {
+ e.data.port.postMessage({result: result});
+ });
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js
new file mode 100644
index 00000000000..63c4534b7ef
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.js
@@ -0,0 +1,25 @@
+importScripts('../../resources/test-helpers.sub.js');
+importScripts('../../resources/worker-testharness.js');
+
+var events_seen = [];
+
+self.registration.addEventListener('updatefound', function() {
+ events_seen.push('updatefound');
+ });
+
+self.addEventListener('activate', function(e) {
+ events_seen.push('activate');
+ });
+
+self.addEventListener('fetch', function(e) {
+ events_seen.push('fetch');
+ e.respondWith(new Response(events_seen));
+ });
+
+self.addEventListener('message', function(e) {
+ events_seen.push('message');
+ self.registration.update();
+ });
+
+// update() during the script evaluation should be ignored.
+self.registration.update();
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py
new file mode 100644
index 00000000000..5158bf25170
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/resources/update-worker.py
@@ -0,0 +1,14 @@
+import os
+import time
+
+def main(request, response):
+ # update() does not bypass cache so set the max-age to 0 such that update()
+ # can find a new version in the network.
+ headers = [('Cache-Control', 'max-age: 0'),
+ ('Content-Type', 'application/javascript')]
+ with open(os.path.join(os.path.dirname(__file__),
+ 'update-worker.js'), 'r') as file:
+ script = file.read()
+ # Return a different script for each access.
+ return headers, '// %s\n%s' % (time.time(), script)
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html
new file mode 100644
index 00000000000..31330918807
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/unregister.https.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<title>ServiceWorkerGlobalScope: unregister</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../resources/test-helpers.sub.js'></script>
+<script>
+
+promise_test(function(t) {
+ var script = 'resources/unregister-worker.js?evaluation';
+ var scope = 'resources/scope/unregister-on-script-evaluation';
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'redundant');
+ })
+ .then(function() {
+ return navigator.serviceWorker.getRegistration(scope);
+ })
+ .then(function(result) {
+ assert_equals(
+ result,
+ undefined,
+ 'After unregister(), the registration should not found');
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Unregister on script evaluation');
+
+promise_test(function(t) {
+ var script = 'resources/unregister-worker.js?install';
+ var scope = 'resources/scope/unregister-on-install-event';
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'redundant');
+ })
+ .then(function() {
+ return navigator.serviceWorker.getRegistration(scope);
+ })
+ .then(function(result) {
+ assert_equals(
+ result,
+ undefined,
+ 'After unregister(), the registration should not found');
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Unregister on installing event');
+
+promise_test(function(t) {
+ var script = 'resources/unregister-worker.js?activate';
+ var scope = 'resources/scope/unregister-on-activate-event';
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'redundant');
+ })
+ .then(function() {
+ return navigator.serviceWorker.getRegistration(scope);
+ })
+ .then(function(result) {
+ assert_equals(
+ result,
+ undefined,
+ 'After unregister(), the registration should not found');
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Unregister on activate event');
+
+promise_test(function(t) {
+ var script = 'resources/unregister-worker.js';
+ var scope = 'resources/unregister-controlling-worker.html';
+
+ var controller;
+ var frame;
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ controller = frame.contentWindow.navigator.serviceWorker.controller;
+
+ assert_equals(
+ controller.scriptURL,
+ normalizeURL(script),
+ 'Service worker should control a new document')
+
+ // Wait for the completion of unregister() on the worker.
+ var channel = new MessageChannel();
+ var promise = new Promise(function(resolve) {
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_true(e.data.result,
+ 'unregister() should successfully finish');
+ resolve();
+ });
+ });
+ controller.postMessage({port: channel.port2}, [channel.port2]);
+ return promise;
+ })
+ .then(function() {
+ return navigator.serviceWorker.getRegistration(scope);
+ })
+ .then(function(result) {
+ assert_equals(
+ result,
+ undefined,
+ 'After unregister(), the registration should not found');
+ assert_equals(
+ frame.contentWindow.navigator.serviceWorker.controller,
+ controller,
+ 'After unregister(), the worker should still control the document');
+ return with_iframe(scope);
+ })
+ .then(function(new_frame) {
+ assert_equals(
+ new_frame.contentWindow.navigator.serviceWorker.controller,
+ null,
+ 'After unregister(), the worker should not control a new document');
+
+ frame.remove();
+ new_frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Unregister controlling service worker');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html
new file mode 100644
index 00000000000..a9285a1c9e2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ServiceWorkerGlobalScope/update.https.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>ServiceWorkerGlobalScope: update</title>
+<script src='/resources/testharness.js'></script>
+<script src='/resources/testharnessreport.js'></script>
+<script src='../resources/test-helpers.sub.js'></script>
+<script>
+
+promise_test(function(t) {
+ var script = 'resources/update-worker.py';
+ var scope = 'resources/scope/update';
+ var registration;
+ var frame1;
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame1 = f;
+ registration.active.postMessage('update');
+ return wait_for_update(t, registration);
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame2) {
+ var expected_events_seen = [
+ 'updatefound', // by register().
+ 'activate',
+ 'fetch',
+ 'message',
+ 'updatefound', // by update() in the message handler.
+ 'fetch',
+ ];
+ assert_equals(
+ frame2.contentDocument.body.textContent,
+ expected_events_seen.toString(),
+ 'events seen by the worker');
+ frame1.remove();
+ frame2.remove();
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Update a registration on ServiceWorkerGlobalScope');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/activate-event-after-install-state-change.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/activate-event-after-install-state-change.https.html
new file mode 100644
index 00000000000..57fccf13712
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/activate-event-after-install-state-change.https.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>Service Worker: registration events</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/blank.html';
+ var registration;
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ var sw = registration.installing;
+
+ return new Promise(t.step_func(function(resolve) {
+ sw.onstatechange = t.step_func(function() {
+ if (sw.state === 'installed') {
+ assert_equals(registration.active, null,
+ 'installed event should be fired before activating service worker');
+ resolve();
+ }
+ });
+ }));
+ })
+ .then(function() {
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'installed event should be fired before activating service worker');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/activation-after-registration.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/activation-after-registration.https.html
new file mode 100644
index 00000000000..ff0990df6ba
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/activation-after-registration.https.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>Service Worker: Activation occurs after registration</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+var t = async_test('activation occurs after registration');
+t.step(function() {
+ var scope = 'resources/blank.html';
+ var registration;
+
+ service_worker_unregister_and_register(
+ t, 'resources/empty-worker.js', scope)
+ .then(function(r) {
+ registration = r;
+ assert_equals(
+ r.installing.state,
+ 'installing',
+ 'worker should be in the "installing" state upon registration');
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+});
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/active.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/active.https.html
new file mode 100644
index 00000000000..deee6a50ea0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/active.https.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>ServiceWorker: navigator.serviceWorker.active</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+// "active" is set
+async_test(function(t) {
+ var step = t.step_func.bind(t);
+ var url = 'resources/empty-worker.js';
+ var scope = 'resources/blank.html';
+ var frame;
+ var registration;
+
+ service_worker_unregister(t, scope)
+ .then(step(function() { return with_iframe(scope); }))
+ .then(step(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url, {scope: scope});
+ }))
+ .then(step(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activating');
+ }))
+ .then(step(function() {
+ var container = frame.contentWindow.navigator.serviceWorker;
+ assert_equals(
+ container.controller,
+ null,
+ 'On activating state a document should not have a controller');
+ assert_equals(
+ registration.active.scriptURL,
+ normalizeURL(url),
+ 'On activating state a document should have an active worker ');
+ assert_equals(
+ registration.waiting,
+ null,
+ 'On activating state a document should not have a waiting worker');
+ assert_equals(
+ registration.installing,
+ null,
+ 'On activating state a document should not have an installing ' +
+ 'worker');
+
+ // FIXME: Add a test for a frame created after installation.
+ // Should the existing frame ("frame") block activation?
+ }))
+ .then(step(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ }))
+ .catch(unreached_rejection(t));
+ }, 'active is set');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/appcache-ordering-main.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/appcache-ordering-main.https.html
new file mode 100644
index 00000000000..609d67e4504
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/appcache-ordering-main.https.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+
+var INSTALL_APPCACHE_URL = "resources/appcache-ordering.install.html";
+var IS_APPCACHED_URL = "resources/appcache-ordering.is-appcached.html";
+var SERVICE_WORKER_SCOPE = "resources/appcache-ordering";
+var SERVICE_WORKER_SCRIPT = "resources/empty-worker.js";
+
+var resolve_install_appcache = undefined;
+var reject_install_appcache = undefined;
+
+var frames = [];
+
+// Called by the INSTALL_APPCACHE_URL child frame.
+function notify_appcache_installed(success) {
+ if (success)
+ resolve_install_appcache();
+ else
+ reject_install_appcache();
+}
+
+function install_appcache() {
+ return new Promise(function(resolve, reject) {
+ var frame = document.createElement('iframe');
+ frames.push(frame);
+ frame.src = INSTALL_APPCACHE_URL;
+ document.body.appendChild(frame);
+ resolve_install_appcache = function() {
+ document.body.removeChild(frame);
+ resolve();
+ };
+ reject_install_appcache = function() {
+ document.body.removeChild(frame);
+ reject();
+ };
+ });
+}
+
+var resolve_is_appcached = undefined;
+
+// Called by the IS_APPCACHED_URL child frame.
+function notify_is_appcached(is) {
+ resolve_is_appcached(is);
+}
+
+function is_appcached() {
+ return new Promise(function(resolve) {
+ var frame = document.createElement('iframe');
+ frames.push(frame);
+ frame.src = IS_APPCACHED_URL;
+ document.body.appendChild(frame);
+ resolve_is_appcached = function(is) {
+ document.body.removeChild(frame);
+ resolve(is);
+ };
+ });
+}
+
+async_test(function(t) {
+ service_worker_unregister(t, SERVICE_WORKER_SCOPE)
+ .then(function() {
+ return install_appcache();
+ })
+ .then(function() {
+ return is_appcached();
+ })
+ .then(function(result) {
+ assert_true(result, 'appcache should initially be utilized');
+ return service_worker_unregister_and_register(
+ t, SERVICE_WORKER_SCRIPT, SERVICE_WORKER_SCOPE);
+ })
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return is_appcached();
+ })
+ .then(function(result) {
+ assert_false(result, 'but serviceworkers should take priority');
+ frames.forEach(function(f) { f.remove(); });
+ service_worker_unregister_and_done(t, SERVICE_WORKER_SCOPE);
+ })
+ .catch(unreached_rejection(t));
+ }, 'serviceworkers take priority over appcaches');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/claim-not-using-registration.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/claim-not-using-registration.https.html
new file mode 100644
index 00000000000..e18e061cd3c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/claim-not-using-registration.https.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<title>Service Worker: claim client not using registration</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+
+promise_test(function(t) {
+ var init_scope = 'resources/blank.html?not-using-init';
+ var claim_scope = 'resources/blank.html?not-using';
+ var init_worker_url = 'resources/empty.js';
+ var claim_worker_url = 'resources/claim-worker.js';
+ var claim_worker, claim_registration, frame1, frame2;
+ return service_worker_unregister_and_register(
+ t, init_worker_url, init_scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return Promise.all(
+ [with_iframe(init_scope), with_iframe(claim_scope)]);
+ })
+ .then(function(frames) {
+ frame1 = frames[0];
+ frame2 = frames[1];
+ assert_equals(
+ frame1.contentWindow.navigator.serviceWorker.controller.scriptURL,
+ normalizeURL(init_worker_url),
+ 'Frame1 controller should not be null');
+ assert_equals(
+ frame2.contentWindow.navigator.serviceWorker.controller, null,
+ 'Frame2 controller should be null');
+ return navigator.serviceWorker.register(claim_worker_url,
+ {scope: claim_scope});
+ })
+ .then(function(registration) {
+ claim_worker = registration.installing;
+ claim_registration = registration;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ var saw_controllerchanged = new Promise(function(resolve) {
+ frame2.contentWindow.navigator.serviceWorker.oncontrollerchange =
+ function() { resolve(); }
+ });
+ var channel = new MessageChannel();
+ var saw_message = new Promise(function(resolve) {
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data, 'PASS',
+ 'Worker call to claim() should fulfill.');
+ resolve();
+ });
+ });
+ claim_worker.postMessage({port: channel.port2}, [channel.port2]);
+ return Promise.all([saw_controllerchanged, saw_message]);
+ })
+ .then(function() {
+ assert_equals(
+ frame1.contentWindow.navigator.serviceWorker.controller.scriptURL,
+ normalizeURL(init_worker_url),
+ 'Frame1 should not be influenced');
+ assert_equals(
+ frame2.contentWindow.navigator.serviceWorker.controller.scriptURL,
+ normalizeURL(claim_worker_url),
+ 'Frame2 should be controlled by the new registration');
+ frame1.remove();
+ frame2.remove();
+ return claim_registration.unregister();
+ })
+ .then(function() {
+ return service_worker_unregister_and_done(t, init_scope);
+ });
+ }, 'Test claim client which is not using registration');
+
+promise_test(function(t) {
+ var scope = 'resources/blank.html?longer-matched';
+ var claim_scope = 'resources/blank.html?longer';
+ var claim_worker_url = 'resources/claim-worker.js';
+ var installing_worker_url = 'resources/empty-worker.js';
+ var frame, claim_worker;
+ return with_iframe(scope)
+ .then(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(
+ claim_worker_url, {scope: claim_scope});
+ })
+ .then(function(registration) {
+ claim_worker = registration.installing;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(
+ installing_worker_url, {scope: scope});
+ })
+ .then(function() {
+ var channel = new MessageChannel();
+ var saw_message = new Promise(function(resolve) {
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data, 'PASS',
+ 'Worker call to claim() should fulfill.');
+ resolve();
+ });
+ });
+ claim_worker.postMessage({port: channel.port2}, [channel.port2]);
+ return saw_message;
+ })
+ .then(function() {
+ assert_equals(
+ frame.contentWindow.navigator.serviceWorker.controller, null,
+ 'Frame should not be claimed when a longer-matched ' +
+ 'registration exists');
+ frame.remove();
+ return service_worker_unregister(t, claim_scope);
+ })
+ .then(function() {
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Test claim client when there\'s a longer-matched registration not ' +
+ 'already used by the page');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/claim-using-registration.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/claim-using-registration.https.html
new file mode 100644
index 00000000000..640b0be3e50
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/claim-using-registration.https.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<title>Service Worker: claim client using registration</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var scope = 'resources/';
+ var frame_url = 'resources/blank.html?using-different-registration';
+ var url1 = 'resources/empty.js';
+ var url2 = 'resources/claim-worker.js';
+ var worker, sw_registration, frame;
+ return service_worker_unregister_and_register(t, url1, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(frame_url);
+ })
+ .then(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url2, {scope: frame_url});
+ })
+ .then(function(registration) {
+ worker = registration.installing;
+ sw_registration = registration;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ var saw_controllerchanged = new Promise(function(resolve) {
+ frame.contentWindow.navigator.serviceWorker.oncontrollerchange =
+ function() { resolve(); }
+ });
+ var channel = new MessageChannel();
+ var saw_message = new Promise(function(resolve) {
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data, 'PASS',
+ 'Worker call to claim() should fulfill.');
+ resolve();
+ });
+ });
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ return Promise.all([saw_controllerchanged, saw_message]);
+ })
+ .then(function() {
+ assert_equals(
+ frame.contentWindow.navigator.serviceWorker.controller.scriptURL,
+ normalizeURL(url2),
+ 'Frame1 controller scriptURL should be changed to url2');
+ frame.remove();
+ return sw_registration.unregister();
+ })
+ .then(function() {
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Test worker claims client which is using another registration');
+
+promise_test(function(t) {
+ var scope = 'resources/blank.html?using-same-registration';
+ var url1 = 'resources/empty.js';
+ var url2 = 'resources/claim-worker.js';
+ var frame, worker;
+ return service_worker_unregister_and_register(t, url1, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url2, {scope: scope});
+ })
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ var channel = new MessageChannel();
+ var saw_message = new Promise(function(resolve) {
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data, 'FAIL: exception: InvalidStateError',
+ 'Worker call to claim() should reject with ' +
+ 'InvalidStateError');
+ resolve();
+ });
+ });
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ return saw_message;
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Test for the waiting worker claims a client which is using the the ' +
+ 'same registration');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/clients-get-cross-origin.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-get-cross-origin.https.html
new file mode 100644
index 00000000000..3413acbf9d5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-get-cross-origin.https.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>Service Worker: Clients.get across origins</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var host_info = get_host_info();
+
+var scope = 'resources/blank.html?clients-get';
+var t = async_test('Test Clients.get() cross origin');
+var other_origin_iframe = host_info['HTTPS_REMOTE_ORIGIN'] + base_path() +
+ 'resources/clients-get-other-origin.html';
+var myOriginClientId;
+t.step(function() {
+ service_worker_unregister_and_register(
+ t, 'resources/clients-get-worker.js', scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame1) {
+ myOriginClientId = frame1.contentDocument.body.textContent;
+ return with_iframe(other_origin_iframe);
+ })
+ .then(function(frame2) {
+ window.addEventListener('message', on_message_other_origin, false);
+ frame2.contentWindow.postMessage(
+ {clientId: myOriginClientId,
+ message: 'get_client_id'},
+ host_info['HTTPS_REMOTE_ORIGIN']);
+ })
+ .catch(unreached_rejection(t));
+ });
+
+function on_message_other_origin(e) {
+ assert_equals(e.data.result, undefined);
+ t.done();
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/clients-get.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-get.https.html
new file mode 100644
index 00000000000..af38502dd9f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-get.https.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<title>Service Worker: Clients.get</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var host_info = get_host_info();
+
+var scope = 'resources/clients-get-frame.html';
+var t = async_test('Test Clients.get()');
+var clientIds = [];
+var frame;
+t.step(function() {
+ service_worker_unregister_and_register(
+ t, 'resources/clients-get-worker.js', scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope + '#1');
+ })
+ .then(function(frame1) {
+ frame1.focus();
+ return wait_for_clientId();
+ })
+ .then(function(clientId) {
+ clientIds.push(clientId);
+ return with_iframe(scope + '#2');
+ })
+ .then(function(frame2) {
+ frame = frame2;
+ return wait_for_clientId();
+ })
+ .then(function(clientId) {
+ clientIds.push(clientId);
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(on_message);
+ frame.contentWindow.navigator.serviceWorker.controller.postMessage(
+ {port:channel.port2, clientIds:clientIds,
+ message: 'get_client_ids'}, [channel.port2]);
+ })
+ .catch(unreached_rejection(t));
+ });
+
+function wait_for_clientId() {
+ return new Promise(function(resolve, reject) {
+ function get_client_id(e) {
+ window.removeEventListener("message", get_client_id);
+ resolve(e.data.clientId);
+ }
+ window.addEventListener("message", get_client_id, false);
+ });
+}
+
+var expected = [
+ /* visibilityState, focused, url, frameType */
+ ['visible', true, new URL(scope + '#1', location).toString(), 'nested'],
+ ['visible', false, new URL(scope + '#2', location).toString(), 'nested'],
+ undefined
+];
+
+function on_message(e) {
+ assert_equals(e.data.length, 3);
+ assert_array_equals(e.data[0], expected[0]);
+ assert_array_equals(e.data[1], expected[1]);
+ assert_equals(e.data[2], expected[2]);
+ service_worker_unregister_and_done(t, scope);
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-client-types.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-client-types.https.html
new file mode 100644
index 00000000000..3645e86354d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-client-types.https.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<title>Service Worker: Clients.matchAll with various clientTypes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var scope = 'resources/clients-matchall-client-types';
+var iframe_url = scope + '-iframe.html';
+var shared_worker_url = scope + '-shared-worker.js';
+
+/* visibilityState, focused, url, frameType */
+var expected_without_type = [
+ ['visible', true, new URL(iframe_url, location).href, 'nested']
+];
+var expected_with_window = [
+ ['visible', true, new URL(iframe_url, location).href, 'nested']
+];
+var expected_with_shared_worker = [
+ [,,new URL(shared_worker_url, location).href, 'none']
+];
+var expected_with_all = [
+ ['visible', true, new URL(iframe_url, location).href, 'nested'],
+ [,,new URL(shared_worker_url, location).href, 'none']
+];
+
+function test_matchall(frame, expected, query_options) {
+ // Make sure the frame gets focus.
+ frame.focus();
+ expected.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
+ return new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(e) {
+ assert_equals(e.data.length, expected.length);
+ for (var i = 0; i < e.data.length; i++)
+ assert_array_equals(e.data[i], expected[i]);
+ resolve();
+ };
+ frame.contentWindow.navigator.serviceWorker.controller.postMessage(
+ {port:channel.port2, options:query_options},
+ [channel.port2]);
+ });
+}
+
+promise_test(function(t) {
+ var frame;
+ return service_worker_unregister_and_register(
+ t, 'resources/clients-matchall-worker.js', scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(iframe_url); })
+ .then(function(f) {
+ frame = f;
+ return new Promise(function(resolve, reject) {
+ var w = new SharedWorker(shared_worker_url);
+ w.port.onmessage = resolve;
+ });
+ })
+ .then(function() {
+ return test_matchall(frame, expected_without_type, {});
+ })
+ .then(function() {
+ return test_matchall(frame, expected_with_window, {type:'window'});
+ })
+ //.then(function() {
+ // return test_matchall(frame, expected_with_shared_worker,
+ // {type:'sharedworker'});
+ // })
+ //.then(function() {
+ // return test_matchall(frame, expected_with_all, {type:'all'});
+ // })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify matchAll() with various client types');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html
new file mode 100644
index 00000000000..9285aef970f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall-include-uncontrolled.https.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<title>Service Worker: Clients.matchAll with includeUncontrolled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var base_url = 'resources/blank.html'; // This is out-of-scope.
+var scope = base_url + '?clients-matchAll-includeUncontrolled';
+var frames = [];
+
+// Creates 3 iframes, 2 for in-scope and 1 for out-of-scope.
+// The frame opened for scope + '#2' is returned via a promise.
+function create_iframes(scope) {
+ return with_iframe(base_url)
+ .then(function(frame0) {
+ frames.push(frame0);
+ return with_iframe(scope + '#1');
+ })
+ .then(function(frame1) {
+ frames.push(frame1);
+ return with_iframe(scope + '#2');
+ })
+ .then(function(frame2) {
+ frames.push(frame2);
+ return frame2;
+ })
+}
+
+var expected_without_include_uncontrolled = [
+ /* visibilityState, focused, url, frameType */
+ ['visible', false, new URL(scope + '#1', location).toString(), 'nested'],
+ ['visible', true, new URL(scope + '#2', location).toString(), 'nested']
+];
+
+var expected_with_include_uncontrolled = [
+ /* visibilityState, focused, url, frameType */
+ ['visible', true, location.href, 'top-level'],
+ ['visible', false, new URL(scope + '#1', location).toString(), 'nested'],
+ ['visible', true, new URL(scope + '#2', location).toString(), 'nested'],
+ ['visible', false, new URL(base_url, location).toString(), 'nested']
+];
+
+function test_matchall(frame, expected, query_options) {
+ // Make sure we have focus for '#2' frame and its parent window.
+ frame.focus();
+ frame.contentWindow.focus();
+ expected.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
+ return new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(e) {
+ // Ignore hidden clients which may be coming from background tabs, or
+ // clients unrelated to this test.
+ var data = e.data.filter(function(info) {
+ return info[0] == 'visible' &&
+ info[2].indexOf('service-worker') > -1;
+ });
+ data.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
+ assert_equals(data.length, expected.length);
+ for (var i = 0; i < data.length; i++)
+ assert_array_equals(data[i], expected[i]);
+ resolve(frame);
+ };
+ frame.contentWindow.navigator.serviceWorker.controller.postMessage(
+ {port:channel.port2, options:query_options},
+ [channel.port2]);
+ });
+}
+
+// Run clients.matchAll without and with includeUncontrolled=true.
+// (We want to run the two tests sequentially in the same async_test
+// so that we can use the same set of iframes without intefering each other.
+async_test(function(t) {
+ service_worker_unregister_and_register(
+ t, 'resources/clients-matchall-worker.js', scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return create_iframes(scope); })
+ .then(function(frame) {
+ return test_matchall(frame, expected_without_include_uncontrolled);
+ })
+ .then(function(frame) {
+ return test_matchall(frame, expected_with_include_uncontrolled,
+ {includeUncontrolled:true});
+ })
+ .then(function() {
+ frames.forEach(function(f) { f.remove() });
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify matchAll() respect includeUncontrolled');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall.https.html
new file mode 100644
index 00000000000..12e3da4e61f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/clients-matchall.https.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Service Worker: Clients.matchAll</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var scope = 'resources/blank.html?clients-matchAll';
+var t = async_test('Test Clients.matchAll()');
+var frames = [];
+t.step(function() {
+ service_worker_unregister_and_register(
+ t, 'resources/clients-matchall-worker.js', scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope + '#1'); })
+ .then(function(frame1) {
+ frames.push(frame1);
+ frame1.focus();
+ return with_iframe(scope + '#2');
+ })
+ .then(function(frame2) {
+ frames.push(frame2);
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(onMessage);
+ frame2.contentWindow.navigator.serviceWorker.controller.postMessage(
+ {port:channel.port2}, [channel.port2]);
+ })
+ .catch(unreached_rejection(t));
+ });
+
+var expected = [
+ /* visibilityState, focused, url, frameType */
+ ['visible', true, new URL(scope + '#1', location).toString(), 'nested'],
+ ['visible', false, new URL(scope + '#2', location).toString(), 'nested']
+];
+
+function onMessage(e) {
+ assert_equals(e.data.length, 2);
+ assert_array_equals(e.data[0], expected[0]);
+ assert_array_equals(e.data[1], expected[1]);
+ frames.forEach(function(f) { f.remove(); });
+ service_worker_unregister_and_done(t, scope);
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-load.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-load.https.html
new file mode 100644
index 00000000000..ff3b7ce04f4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-load.https.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Service Worker: Controller on load</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+var t = async_test('controller is set for a controlled document');
+t.step(function() {
+ var url = 'resources/empty-worker.js';
+ var scope = 'resources/blank.html';
+ var registration;
+ var controller;
+ var frame;
+ service_worker_unregister_and_register(t, url, scope)
+ .then(t.step_func(function(swr) {
+ registration = swr;
+ return wait_for_state(t, registration.installing, 'activated');
+ }))
+ .then(t.step_func(function() {
+ return with_iframe(scope)
+ }))
+ .then(t.step_func(function(f) {
+ frame = f;
+ var w = frame.contentWindow;
+ controller = w.navigator.serviceWorker.controller;
+ assert_true(controller instanceof w.ServiceWorker,
+ 'controller should be a ServiceWorker object');
+ assert_equals(controller.scriptURL, normalizeURL(url));
+
+ // objects from different windows should not be equal
+ assert_not_equals(controller, registration.active);
+
+ return w.navigator.serviceWorker.getRegistration();
+ }))
+ .then(t.step_func(function(frameRegistration) {
+ // SW objects from same window should be equal
+ assert_equals(frameRegistration.active, controller);
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ }))
+ .catch(unreached_rejection(t));
+ });
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-reload.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-reload.https.html
new file mode 100644
index 00000000000..4490c707963
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/controller-on-reload.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<title>Service Worker: Controller on reload</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+promise_test(function(t) {
+ var scope = 'resources/blank.html';
+ var frame;
+ var registration;
+ var controller;
+ return service_worker_unregister(t, scope)
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.navigator.serviceWorker.register(
+ 'resources/empty-worker.js', {scope: scope});
+ })
+ .then(function(swr) {
+ registration = swr;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ var w = frame.contentWindow;
+ assert_equals(w.navigator.serviceWorker.controller, null,
+ 'controller should be null until the document is ' +
+ 'reloaded');
+ return new Promise(function(resolve) {
+ frame.onload = function() { resolve(); }
+ w.location.reload();
+ });
+ })
+ .then(function() {
+ var w = frame.contentWindow;
+ controller = w.navigator.serviceWorker.controller;
+ assert_true(controller instanceof w.ServiceWorker,
+ 'controller should be a ServiceWorker object upon reload');
+
+ // objects from separate windows should not be equal
+ assert_not_equals(controller, registration.active);
+
+ return w.navigator.serviceWorker.getRegistration();
+ })
+ .then(function(frameRegistration) {
+ assert_equals(frameRegistration.active, controller);
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'controller is set upon reload after registration');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html
new file mode 100644
index 00000000000..c06bf84ab2d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-async-waituntil.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+promise_test(function(t) {
+ var script = 'resources/extendable-event-async-waituntil.js';
+ var scope = 'resources/async-waituntil';
+ var worker;
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() {
+ var channel = new MessageChannel();
+ var saw_message = new Promise(function(resolve) {
+ channel.port1.onmessage = function(e) { resolve(e.data); }
+ });
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ return saw_message;
+ })
+ .then(function(message) {
+ assert_equals(message, 'PASS');
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Calling waitUntil asynchronously throws an exception');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-waituntil.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-waituntil.https.html
new file mode 100644
index 00000000000..003e703b1f3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/extendable-event-waituntil.https.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<title>ExtendableEvent: waitUntil</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+function runTest(test, scope, onRegister) {
+ var script = 'resources/extendable-event-waituntil.js?' + scope;
+ service_worker_unregister_and_register(test, script, scope)
+ .then(function(registration) {
+ onRegister(registration.installing);
+ });
+}
+
+// Sends a SYN to the worker and asynchronously listens for an ACK; sets
+// |obj.synced| to true once ack'd.
+function syncWorker(test, worker, obj) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = test.step_func(function(e) {
+ var message = e.data;
+ assert_equals(message, 'SYNC',
+ 'Should receive sync message from worker.');
+ obj.synced = true;
+ channel.port1.postMessage('ACK');
+ });
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+}
+
+async_test(function(t) {
+ // Passing scope as the test switch for worker script.
+ var scope = 'resources/install-fulfilled';
+ var onRegister = function(worker) {
+ var obj = {};
+ wait_for_state(t, worker, 'installed')
+ .then(function() {
+ assert_true(
+ obj.synced,
+ 'state should be "installed" after the waitUntil promise ' +
+ 'for "oninstall" is fulfilled.');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ syncWorker(t, worker, obj);
+ };
+ runTest(t, scope, onRegister);
+ }, 'Test install event waitUntil fulfilled');
+
+async_test(function(t) {
+ var scope = 'resources/install-multiple-fulfilled';
+ var onRegister = function(worker) {
+ var obj1 = {};
+ var obj2 = {};
+ wait_for_state(t, worker, 'installed')
+ .then(function() {
+ assert_true(
+ obj1.synced && obj2.synced,
+ 'state should be "installed" after all waitUntil promises ' +
+ 'for "oninstall" are fulfilled.');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ syncWorker(t, worker, obj1);
+ syncWorker(t, worker, obj2);
+ };
+ runTest(t, scope, onRegister);
+ }, 'Test ExtendableEvent multiple waitUntil fulfilled.');
+
+async_test(function(t) {
+ var scope = 'resources/install-reject-precedence';
+ var onRegister = function(worker) {
+ wait_for_state(t, worker, 'redundant')
+ .then(function() {
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ };
+ runTest(t, scope, onRegister);
+ }, 'Test ExtendableEvent waitUntil reject precedence.');
+
+async_test(function(t) {
+ var scope = 'resources/activate-fulfilled';
+ var onRegister = function(worker) {
+ var obj = {};
+ wait_for_state(t, worker, 'activating')
+ .then(function() {
+ syncWorker(t, worker, obj);
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() {
+ assert_true(
+ obj.synced,
+ 'state should be "activated" after the waitUntil promise ' +
+ 'for "onactivate" is fulfilled.');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ };
+ runTest(t, scope, onRegister);
+ }, 'Test activate event waitUntil fulfilled');
+
+async_test(function(t) {
+ var scope = 'resources/install-rejected';
+ var onRegister = function(worker) {
+ wait_for_state(t, worker, 'redundant')
+ .then(function() {
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ };
+ runTest(t, scope, onRegister);
+ }, 'Test install event waitUntil rejected');
+
+async_test(function(t) {
+ var scope = 'resources/activate-rejected';
+ var onRegister = function(worker) {
+ wait_for_state(t, worker, 'activated')
+ .then(function() {
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ };
+ runTest(t, scope, onRegister);
+ }, 'Test activate event waitUntil rejected.');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html
new file mode 100644
index 00000000000..fdb64e15d66
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting-cache.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>Service Worker: canvas tainting of the fetched image using cached responses</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<body>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-canvas-tainting-iframe.html?cache';
+ var SCRIPT = 'resources/fetch-rewrite-worker.js';
+ var host_info = get_host_info();
+
+ login_https(t)
+ .then(function() {
+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
+ })
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ return new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ });
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify canvas tainting of fetched image in a Service Worker');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html
new file mode 100644
index 00000000000..bb75473926f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-canvas-tainting.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>Service Worker: canvas tainting of the fetched image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<body>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-canvas-tainting-iframe.html';
+ var SCRIPT = 'resources/fetch-rewrite-worker.js';
+ var host_info = get_host_info();
+
+ login_https(t)
+ .then(function() {
+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
+ })
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ return new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ });
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify canvas tainting of fetched image in a Service Worker');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-cors-xhr.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-cors-xhr.https.html
new file mode 100644
index 00000000000..3b1f1d6bc32
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-cors-xhr.https.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>Service Worker: CORS XHR of fetch()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<body>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-cors-xhr-iframe.html';
+ var SCRIPT = 'resources/fetch-rewrite-worker.js';
+ var host_info = get_host_info();
+
+ login_https(t)
+ .then(function() {
+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
+ })
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ return new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ });
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify CORS XHR of fetch() in a Service Worker');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-csp.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-csp.https.html
new file mode 100644
index 00000000000..bdb56c213af
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-csp.https.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>Service Worker: CSP control of fetch()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-csp-iframe.html';
+ var SCRIPT = 'resources/fetch-rewrite-worker.js';
+ var host_info = get_host_info();
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ return new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ });
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify CSP control of fetch() in a Service Worker');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html
new file mode 100644
index 00000000000..dce1f794fab
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-after-navigation-within-page.https.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<title>ServiceWorker: navigator.serviceWorker.waiting</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+
+promise_test(function(t) {
+ var scope =
+ 'resources/fetch-event-after-navigation-within-page-iframe.html' +
+ '?hashchange';
+ var worker = 'resources/simple-intercept-worker.js';
+ var frame;
+
+ return service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.fetch_url('simple.txt');
+ })
+ .then(function(response) {
+ assert_equals(response, 'intercepted by service worker');
+ frame.contentWindow.location.hash = 'foo';
+ return frame.contentWindow.fetch_url('simple.txt');
+ })
+ .then(function(response) {
+ assert_equals(response, 'intercepted by service worker');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Service Worker should respond to fetch event after the hash changes');
+
+promise_test(function(t) {
+ var scope =
+ 'resources/fetch-event-after-navigation-within-page-iframe.html' +
+ '?pushState';
+ var worker = 'resources/simple-intercept-worker.js';
+ var frame;
+
+ return service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.fetch_url('simple.txt');
+ })
+ .then(function(response) {
+ assert_equals(response, 'intercepted by service worker');
+ frame.contentWindow.history.pushState('', '', 'bar');
+ return frame.contentWindow.fetch_url('simple.txt');
+ })
+ .then(function(response) {
+ assert_equals(response, 'intercepted by service worker');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Service Worker should respond to fetch event after the pushState');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html
new file mode 100644
index 00000000000..912e709ca38
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-async-respond-with.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+promise_test(function(t) {
+ var script = 'resources/fetch-event-async-respond-with-worker.js';
+ var scope = 'resources/simple.html';
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ var channel = new MessageChannel();
+ var saw_message = new Promise(function(resolve) {
+ channel.port1.onmessage = function(e) { resolve(e.data); }
+ });
+ var worker = frame.contentWindow.navigator.serviceWorker.controller;
+
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ frame.remove();
+ return saw_message;
+ })
+ .then(function(message) {
+ assert_equals(message, 'PASS');
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Calling respondWith asynchronously throws an exception');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-network-error.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-network-error.https.html
new file mode 100644
index 00000000000..f6a3d0776e5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-network-error.https.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>Service Worker: Fetch event network error</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var resolve_test_done;
+
+var test_done_promise = new Promise(function(resolve) {
+ resolve_test_done = resolve;
+ });
+
+// Called by the child frame.
+function notify_test_done(result) {
+ resolve_test_done(result);
+}
+
+promise_test(function(t) {
+ var scope = 'resources/fetch-event-network-error-controllee-iframe.html';
+ var script = 'resources/fetch-event-network-error-worker.js';
+ var frame;
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ return test_done_promise;
+ })
+ .then(function(result) {
+ frame.remove();
+ assert_equals(result, 'PASS');
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Rejecting the fetch event or using preventDefault() causes a network ' +
+ 'error');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html
new file mode 100644
index 00000000000..556d04413fa
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-redirect.https.html
@@ -0,0 +1,997 @@
+<!DOCTYPE html>
+<title>Service Worker: Fetch Event Redirect Handling</title>
+<meta name=timeout content=long>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+
+// ------------------------
+// Utilities for testing non-navigation requests that are intercepted with
+// a redirect.
+
+var host_info = get_host_info();
+var worker = 'resources/fetch-rewrite-worker.js';
+var frameURL = host_info['HTTPS_ORIGIN'] + base_path() +
+ 'resources/fetch-event-redirect-iframe.html';
+var baseScope = 'resources/';
+var redirect = 'redirect.py';
+var success = base_path() + 'resources/success.py';
+
+function redirect_fetch_test(t, test) {
+ var scope = baseScope + test.name;
+ service_worker_unregister_and_register(t, worker, scope).then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ }).then(function() {
+ return with_iframe(scope + '?url=' + encodeURIComponent(frameURL));
+ }).then(function(frame) {
+ var hostKeySuffix = test['url_credentials'] ? '_WITH_CREDS' : '';
+
+ var acaorigin = '';
+ var host = host_info['HTTPS_ORIGIN' + hostKeySuffix];
+ if (test['redirect_dest'] === 'no-cors') {
+ host = host_info['HTTPS_REMOTE_ORIGIN' + hostKeySuffix]
+ } else if (test['redirect_dest'] === 'cors') {
+ acaorigin = '?ACAOrigin=' + encodeURIComponent(host_info['HTTPS_ORIGIN']);
+ host = host_info['HTTPS_REMOTE_ORIGIN' + hostKeySuffix]
+ }
+
+ var dest = '?Redirect=' + encodeURIComponent(host + success + acaorigin);
+
+ var expectedTypeParam = test['expected_type']
+ ? '&expected_type=' + test['expected_type']
+ : '';
+
+ var url = scope +
+ '?url=' + encodeURIComponent(redirect + dest) +
+ expectedTypeParam
+
+ var p = new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(e) {
+ frame.remove();
+ if (e.data.result === 'reject') {
+ reject(e.data.detail);
+ } else if (e.data.result === 'success') {
+ resolve(e.data.result);
+ } else {
+ resolve(e.data.detail);
+ }
+ };
+ frame.contentWindow.postMessage({
+ url: url,
+ request_init: test.request_init,
+ redirect_dest: test.redirect_dest,
+ }, '*', [channel.port2]);
+ });
+
+ if (test.should_reject) {
+ return assert_promise_rejects(p);
+ }
+
+ return p.then(function(result) {
+ if (result !== 'success') {
+ throw(new Error(result));
+ }
+ });
+ }).then(function() {
+ return service_worker_unregister_and_done(t, scope);
+ }).catch(unreached_rejection(t));
+}
+
+// ------------------------
+// Test every combination of:
+// - RequestMode (same-origin, cors, no-cors)
+// - RequestRedirect (manual, follow, error)
+// - redirect destination origin (same-origin, cors, no-cors)
+// - redirect destination credentials (no user/pass, user/pass)
+//
+// TODO: add navigation requests
+// TODO: add redirects to data URI and verify same-origin data-URL flag behavior
+// TODO: add test where original redirect URI is cross-origin
+// TODO: verify final method is correct for 301, 302, and 303
+// TODO: verify CORS redirect results in all further redirects being
+// considered cross origin
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-cors-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
+ 'same-origin without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-cors-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
+ 'no-cors without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-cors-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
+ 'cors without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-sameorigin-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'same-origin'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
+ 'same-origin without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-sameorigin-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'same-origin'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
+ 'no-cors without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-sameorigin-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'same-origin'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
+ 'cors without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-nocors-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'no-cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
+ 'same-origin without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-nocors-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'no-cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
+ 'no-cors without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-nocors-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'no-cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
+ 'cors without credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-cors-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
+ 'same-origin with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-cors-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
+ 'no-cors with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-cors-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
+ 'cors with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-sameorigin-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'same-origin'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
+ 'same-origin with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-sameorigin-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'same-origin'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
+ 'no-cors with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-sameorigin-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'same-origin'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
+ 'cors with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-nocors-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'no-cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
+ 'same-origin with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-nocors-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'no-cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
+ 'no-cors with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-manual-nocors-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'opaqueredirect',
+ request_init: {
+ redirect: 'manual',
+ mode: 'no-cors'
+ },
+ // should reject because only navigations can be intercepted with
+ // opaqueredirect responses
+ should_reject: true
+ });
+}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
+ 'cors with credentials should fail opaqueredirect interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-cors-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'basic',
+ request_init: {
+ redirect: 'follow',
+ mode: 'cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
+ 'same-origin without credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-cors-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'should-not-get-a-response',
+ request_init: {
+ redirect: 'follow',
+ mode: 'cors'
+ },
+ // should reject because CORS requests require CORS headers on cross-origin
+ // resources
+ should_reject: true
+ });
+}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
+ 'no-cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-cors-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'cors',
+ request_init: {
+ redirect: 'follow',
+ mode: 'cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
+ 'cors without credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-sameorigin-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'basic',
+ request_init: {
+ redirect: 'follow',
+ mode: 'same-origin'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
+ 'same-origin without credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-sameorigin-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'should-not-get-a-response',
+ request_init: {
+ redirect: 'follow',
+ mode: 'same-origin'
+ },
+ // should reject because same-origin requests cannot load cross-origin
+ // resources
+ should_reject: true
+ });
+}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
+ 'no-cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-sameorigin-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'should-not-get-a-response',
+ request_init: {
+ redirect: 'follow',
+ mode: 'same-origin'
+ },
+ // should reject because same-origin requests cannot load cross-origin
+ // resources
+ should_reject: true
+ });
+}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
+ 'cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-nocors-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'basic',
+ request_init: {
+ redirect: 'follow',
+ mode: 'no-cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
+ 'same-origin without credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-nocors-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'opaque',
+ request_init: {
+ redirect: 'follow',
+ mode: 'no-cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
+ 'no-cors without credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-nocors-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'opaque',
+ request_init: {
+ redirect: 'follow',
+ mode: 'no-cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
+ 'cors without credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-cors-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'basic',
+ request_init: {
+ redirect: 'follow',
+ mode: 'cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
+ 'same-origin with credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-cors-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'should-not-get-a-response',
+ request_init: {
+ redirect: 'follow',
+ mode: 'cors'
+ },
+ // should reject because CORS requests require CORS headers on cross-origin
+ // resources
+ should_reject: true
+ });
+}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
+ 'no-cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-cors-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'cors',
+ request_init: {
+ redirect: 'follow',
+ mode: 'cors'
+ },
+ // should reject because CORS requests do not allow user/pass entries in
+ // cross-origin URLs
+ // NOTE: https://github.com/whatwg/fetch/issues/112
+ should_reject: true
+ });
+}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
+ 'cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-sameorigin-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'basic',
+ request_init: {
+ redirect: 'follow',
+ mode: 'same-origin'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
+ 'same-origin with credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-sameorigin-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'should-not-get-a-response',
+ request_init: {
+ redirect: 'follow',
+ mode: 'same-origin'
+ },
+ // should reject because same-origin requests cannot load cross-origin
+ // resources
+ should_reject: true
+ });
+}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
+ 'no-cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-sameorigin-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'should-not-get-a-response',
+ request_init: {
+ redirect: 'follow',
+ mode: 'same-origin'
+ },
+ // should reject because same-origin requests cannot load cross-origin
+ // resources
+ should_reject: true
+ });
+}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
+ 'cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-nocors-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'basic',
+ request_init: {
+ redirect: 'follow',
+ mode: 'no-cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
+ 'same-origin with credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-nocors-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'opaque',
+ request_init: {
+ redirect: 'follow',
+ mode: 'no-cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
+ 'no-cors with credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-follow-nocors-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'opaque',
+ request_init: {
+ redirect: 'follow',
+ mode: 'no-cors'
+ },
+ should_reject: false
+ });
+}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
+ 'cors with credentials should succeed interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-cors-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
+ 'same-origin without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-cors-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
+ 'no-cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-cors-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
+ 'cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-sameorigin-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'same-origin'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
+ 'same-origin without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-sameorigin-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'same-origin'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
+ 'no-cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-sameorigin-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'same-origin'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
+ 'cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-nocors-redirects-to-sameorigin-nocreds',
+ redirect_dest: 'same-origin',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'no-cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
+ 'same-origin without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-nocors-redirects-to-nocors-nocreds',
+ redirect_dest: 'no-cors',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'no-cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
+ 'no-cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-nocors-redirects-to-cors-nocreds',
+ redirect_dest: 'cors',
+ url_credentials: false,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'no-cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
+ 'cors without credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-cors-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
+ 'same-origin with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-cors-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
+ 'no-cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-cors-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
+ 'cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-sameorigin-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'same-origin'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
+ 'same-origin with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-sameorigin-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'same-origin'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
+ 'no-cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-sameorigin-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'same-origin'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
+ 'cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-nocors-redirects-to-sameorigin-creds',
+ redirect_dest: 'same-origin',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'no-cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
+ 'same-origin with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-nocors-redirects-to-nocors-creds',
+ redirect_dest: 'no-cors',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'no-cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
+ 'no-cors with credentials should fail interception');
+
+async_test(function(t) {
+ redirect_fetch_test(t, {
+ name: 'nonav-error-nocors-redirects-to-cors-creds',
+ redirect_dest: 'cors',
+ url_credentials: true,
+ expected_type: 'error',
+ request_init: {
+ redirect: 'error',
+ mode: 'no-cors'
+ },
+ // should reject because requests with 'error' RequestRedirect cannot be
+ // redirected.
+ should_reject: true
+ });
+}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
+ 'cors with credentials should fail interception');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html
new file mode 100644
index 00000000000..5d3346e7b28
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event-respond-with-stops-propagation.https.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+promise_test(function(t) {
+ var script =
+ 'resources/fetch-event-respond-with-stops-propagation-worker.js';
+ var scope = 'resources/simple.html';
+
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ var channel = new MessageChannel();
+ var saw_message = new Promise(function(resolve) {
+ channel.port1.onmessage = function(e) { resolve(e.data); }
+ });
+ var worker = frame.contentWindow.navigator.serviceWorker.controller;
+
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ frame.remove();
+ return saw_message;
+ })
+ .then(function(message) {
+ assert_equals(message, 'PASS');
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'respondWith() invokes stopImmediatePropagation()');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html
new file mode 100644
index 00000000000..9869f3b2799
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-event.https.html
@@ -0,0 +1,466 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+var worker = 'resources/fetch-event-test-worker.js';
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?string';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ 'Test string',
+ 'Service Worker should respond to fetch with a test string');
+ assert_equals(
+ frame.contentDocument.contentType,
+ 'text/plain',
+ 'The content type of the response created with a string should be text/plain');
+ assert_equals(
+ frame.contentDocument.characterSet,
+ 'UTF-8',
+ 'The character set of the response created with a string should be UTF-8');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with string');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?blob';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ 'Test blob',
+ 'Service Worker should respond to fetch with a test string');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with blob body');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?referrer';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ 'Referrer: ' + document.location.href,
+ 'Service Worker should respond to fetch with the referrer URL');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with the referrer URL');
+
+function run_referrer_policy_tests(frame, referrer, href, origin) {
+ return frame.contentWindow.fetch('resources/simple.html?referrerFull',
+ {method: "GET", referrer: referrer})
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + href + '\n' +
+ 'ReferrerPolicy: no-referrer-when-downgrade',
+ 'Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present');
+ var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
+ '/resources/simple.html?referrerFull';
+ return frame.contentWindow.fetch(http_url,
+ {method: "GET", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: about:client\n' +
+ 'ReferrerPolicy: no-referrer-when-downgrade',
+ 'Service Worker should respond to fetch with no referrer when a member of RequestInit is present with an HTTP request');
+ return frame.contentWindow.fetch('resources/simple.html?referrerFull',
+ {referrerPolicy: "", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + href + '\n' +
+ 'ReferrerPolicy: no-referrer-when-downgrade',
+ 'Service Worker should respond to fetch with the referrer with ""');
+ var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
+ '/resources/simple.html?referrerFull';
+ return frame.contentWindow.fetch(http_url,
+ {referrerPolicy: "", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: about:client\n' +
+ 'ReferrerPolicy: no-referrer-when-downgrade',
+ 'Service Worker should respond to fetch with no referrer with ""');
+ return frame.contentWindow.fetch('resources/simple.html?referrerFull',
+ {referrerPolicy: "origin-only", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + origin + '/' + '\n' +
+ 'ReferrerPolicy: origin-only',
+ 'Service Worker should respond to fetch with the referrer origin with "origin-only" and a same origin request');
+ var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
+ '/resources/simple.html?referrerFull';
+ return frame.contentWindow.fetch(http_url,
+ {referrerPolicy: "origin-only", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + origin + '/' + '\n' +
+ 'ReferrerPolicy: origin-only',
+ 'Service Worker should respond to fetch with the referrer origin with "origin-only" and a cross origin request');
+ return frame.contentWindow.fetch('resources/simple.html?referrerFull',
+ {referrerPolicy: "origin-when-cross-origin", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + href + '\n' +
+ 'ReferrerPolicy: origin-when-cross-origin',
+ 'Service Worker should respond to fetch with the referrer URL with "origin-when-cross-origin" and a same origin request');
+ var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
+ '/resources/simple.html?referrerFull';
+ return frame.contentWindow.fetch(http_url,
+ {referrerPolicy: "origin-when-cross-origin", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + origin + '/' + '\n' +
+ 'ReferrerPolicy: origin-when-cross-origin',
+ 'Service Worker should respond to fetch with the referrer origin with "origin-when-cross-origin" and a cross origin request');
+ return frame.contentWindow.fetch('resources/simple.html?referrerFull',
+ {referrerPolicy: "no-referrer-when-downgrade", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + href + '\n' +
+ 'ReferrerPolicy: no-referrer-when-downgrade',
+ 'Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and a same origin request');
+ var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
+ '/resources/simple.html?referrerFull';
+ return frame.contentWindow.fetch(http_url,
+ {referrerPolicy: "no-referrer-when-downgrade", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: about:client\n' +
+ 'ReferrerPolicy: no-referrer-when-downgrade',
+ 'Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and an HTTP request');
+ var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
+ '/resources/simple.html?referrerFull';
+ return frame.contentWindow.fetch(http_url, {referrerPolicy: "unsafe-url", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: ' + href + '\n' +
+ 'ReferrerPolicy: unsafe-url',
+ 'Service Worker should respond to fetch with no referrer with "unsafe-url"');
+ return frame.contentWindow.fetch('resources/simple.html?referrerFull',
+ {referrerPolicy: "no-referrer", referrer: referrer});
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ assert_equals(
+ response_text,
+ 'Referrer: about:client\n' +
+ 'ReferrerPolicy: no-referrer',
+ 'Service Worker should respond to fetch with no referrer URL with "no-referrer"');
+ });
+}
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?referrerPolicy';
+ var frame;
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ 'ReferrerPolicy: no-referrer-when-downgrade',
+ 'Service Worker should respond to fetch with the default referrer policy');
+ // First, run the referrer policy tests without passing a referrer in RequestInit.
+ return run_referrer_policy_tests(frame, undefined, frame.contentDocument.location.href,
+ frame.contentDocument.location.origin);
+ })
+ .then(function() {
+ // Now, run the referrer policy tests while passing a referrer in RequestInit.
+ var referrer = get_host_info()['HTTPS_ORIGIN'] + base_path() + 'fake-referrer';
+ return run_referrer_policy_tests(frame, 'fake-referrer', referrer,
+ frame.contentDocument.location.origin);
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with the referrer URL');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?clientId';
+ var frame;
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ 'Client ID Not Found',
+ 'Service Worker should respond to fetch with a client id');
+ return frame.contentWindow.fetch('resources/other.html?clientId');
+ })
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ var new_client_id = response_text.substr(17);
+ assert_equals(
+ response_text.substr(0, 15),
+ 'Client ID Found',
+ 'Service Worker should respond to fetch with an existing client id');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with an existing client id');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?ignore';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(frame.contentDocument.body.textContent,
+ 'Here\'s a simple html file.\n',
+ 'Response should come from fallback to native fetch');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker does not respond to fetch event');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?null';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(frame.contentDocument.body.textContent,
+ '',
+ 'Response should be the empty string');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with null response body');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?fetch';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(frame.contentDocument.body.textContent,
+ 'Here\'s an other html file.\n',
+ 'Response should come from fetched other file');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker fetches other file in fetch event');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?form-post';
+ var frame_name = 'xhr-post-frame';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function(sw) {
+ return new Promise(function(resolve) {
+ var frame = document.createElement('iframe');
+ frame.name = frame_name;
+ document.body.appendChild(frame);
+ var form = document.createElement('form');
+ form.target = frame_name;
+ form.action = scope;
+ form.method = 'post';
+ var input1 = document.createElement('input');
+ input1.type = 'text';
+ input1.value = 'testValue1';
+ input1.name = 'testName1'
+ form.appendChild(input1);
+ var input2 = document.createElement('input');
+ input2.type = 'text';
+ input2.value = 'testValue2';
+ input2.name = 'testName2'
+ form.appendChild(input2);
+ document.body.appendChild(form);
+ frame.onload = function() {
+ document.body.removeChild(form);
+ resolve(frame);
+ };
+ form.submit();
+ });
+ })
+ .then(function(frame) {
+ assert_equals(frame.contentDocument.body.textContent,
+ 'POST:application/x-www-form-urlencoded:' +
+ 'testName1=testValue1&testName2=testValue2');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with POST form');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?multiple-respond-with';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ '(0)(1)[InvalidStateError](2)[InvalidStateError]',
+ 'Multiple calls of respondWith must throw InvalidStateErrors.');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Multiple calls of respondWith must throw InvalidStateErrors');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?used-check';
+ var first_frame;
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(frame) {
+ assert_equals(frame.contentDocument.body.textContent,
+ 'Here\'s an other html file.\n',
+ 'Response should come from fetched other file');
+ first_frame = frame;
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ // When we access to the scope in the second time, the content of the
+ // response is generated inside the ServiceWorker. The body contains
+ // the value of bodyUsed of the first response which is already
+ // consumed by FetchEvent.respondWith method.
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ 'bodyUsed: true',
+ 'event.respondWith must set the used flag.');
+ first_frame.remove();
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker event.respondWith must set the used flag');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?fragment-check';
+ var fragment = '#/some/fragment';
+ var first_frame;
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope + fragment); })
+ .then(function(frame) {
+ assert_equals(
+ frame.contentDocument.body.textContent,
+ 'Fragment Not Found',
+ 'Service worker should not expose URL fragments.');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker must not expose FetchEvent URL fragments.');
+
+async_test(function(t) {
+ var scope = 'resources/simple.html?cache';
+ var frame;
+ var cacheTypes = [
+ undefined, 'default', 'no-store', 'reload', 'no-cache', 'force-cache'
+ ];
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ var tests = cacheTypes.map(function(type) {
+ return new Promise(function(resolve) {
+ return frame.contentWindow.fetch(scope + '=' + type,
+ {cache: type})
+ .then(function(response) { return response.text(); })
+ .then(function(response_text) {
+ var expected = (type === undefined) ? 'default' : type;
+ assert_equals(response_text, expected,
+ 'Service Worker should respond to fetch with the correct type');
+ })
+ .then(resolve);
+ });
+ });
+ return Promise.all(tests);
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Service Worker responds to fetch event with the correct cache types');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-frame-resource.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-frame-resource.https.html
new file mode 100644
index 00000000000..cc1dac472bc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-frame-resource.https.html
@@ -0,0 +1,221 @@
+<!DOCTYPE html>
+<title>Service Worker: Fetch for the frame loading.</title>
+<meta name=timeout content=long>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+var worker = 'resources/fetch-rewrite-worker.js';
+var path = base_path() + 'resources/fetch-access-control.py';
+var host_info = get_host_info();
+
+if (window.testRunner) {
+ testRunner.setCanOpenWindows();
+}
+
+function getLoadedObject(win, contentFunc, closeFunc) {
+ return new Promise(function(resolve) {
+ function done(contentString) {
+ var result = null;
+ // fetch-access-control.py returns a string like "report( <json> )".
+ // Eval the returned string with a report functionto get the json
+ // object.
+ try {
+ function report(obj) { result = obj };
+ eval(contentString);
+ } catch(e) {
+ // just resolve null if we get unexpected page content
+ }
+ closeFunc(win);
+ resolve(result);
+ }
+
+ // We can't catch the network error on window. So we use the timer.
+ var timeout = setTimeout(function() {
+ // Failure pages are considered cross-origin in some browsers. This
+ // means you cannot even .resolve() the window because the check for
+ // the .then property will throw. Instead, treat cross-origin
+ // failure pages as the empty string which will fail to parse as the
+ // expected json result.
+ var content = '';
+ try {
+ content = contentFunc(win);
+ } catch(e) {
+ // use default empty string for cross-domain window
+ }
+ done(content);
+ }, 10000);
+
+ win.onload = function() {
+ clearTimeout(timeout);
+ var content = contentFunc(win);
+ done(content);
+ };
+ });
+}
+
+function getLoadedFrameAsObject(frame) {
+ return getLoadedObject(frame, function(f) {
+ return f.contentDocument.body.textContent;
+ }, function(f) {
+ f.parentNode.removeChild(f);
+ });
+}
+
+function getLoadedWindowAsObject(win) {
+ return getLoadedObject(win, function(w) {
+ return w.document.body.textContent
+ }, function(w) {
+ w.close();
+ });
+}
+
+async_test(function(t) {
+ var scope = 'resources/fetch-frame-resource/frame-basic';
+ var frame;
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ frame = document.createElement('iframe');
+ frame.src =
+ scope + '?url=' +
+ encodeURIComponent(host_info['HTTPS_ORIGIN'] + path);
+ document.body.appendChild(frame);
+ return getLoadedFrameAsObject(frame);
+ })
+ .then(function(result) {
+ assert_equals(
+ result.jsonpResult,
+ 'success',
+ 'Basic type response could be loaded in the iframe.');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Basic type response could be loaded in the iframe.');
+
+async_test(function(t) {
+ var scope = 'resources/fetch-frame-resource/frame-cors';
+ var frame;
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ frame = document.createElement('iframe');
+ frame.src =
+ scope + '?mode=cors&url=' +
+ encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path +
+ '?ACAOrigin=' + host_info['HTTPS_ORIGIN']);
+ document.body.appendChild(frame);
+ return getLoadedFrameAsObject(frame);
+ })
+ .then(function(result) {
+ assert_equals(
+ result.jsonpResult,
+ 'success',
+ 'CORS type response could be loaded in the iframe.');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'CORS type response could be loaded in the iframe.');
+
+async_test(function(t) {
+ var scope = 'resources/fetch-frame-resource/frame-opaque';
+ var frame;
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ frame = document.createElement('iframe');
+ frame.src =
+ scope + '?mode=no-cors&url=' +
+ encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path);
+ document.body.appendChild(frame);
+ return getLoadedFrameAsObject(frame);
+ })
+ .then(function(result) {
+ assert_equals(
+ result,
+ null,
+ 'Opaque type response could not be loaded in the iframe.');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Opaque type response could not be loaded in the iframe.');
+
+async_test(function(t) {
+ var scope = 'resources/fetch-frame-resource/window-basic';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ var win = window.open(
+ scope + '?url=' +
+ encodeURIComponent(host_info['HTTPS_ORIGIN'] + path));
+ return getLoadedWindowAsObject(win);
+ })
+ .then(function(result) {
+ assert_equals(
+ result.jsonpResult,
+ 'success',
+ 'Basic type response could be loaded in the new window.');
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Basic type response could be loaded in the new window.');
+
+async_test(function(t) {
+ var scope = 'resources/fetch-frame-resource/window-cors';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ var win = window.open(
+ scope + '?mode=cors&url=' +
+ encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path +
+ '?ACAOrigin=' + host_info['HTTPS_ORIGIN']));
+ return getLoadedWindowAsObject(win);
+ })
+ .then(function(result) {
+ assert_equals(
+ result.jsonpResult,
+ 'success',
+ 'CORS type response could be loaded in the new window.');
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'CORS type response could be loaded in the new window.');
+
+async_test(function(t) {
+ var scope = 'resources/fetch-frame-resource/window-opaque';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ var win = window.open(
+ scope + '?mode=no-cors&url=' +
+ encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path));
+ return getLoadedWindowAsObject(win);
+ })
+ .then(function(result) {
+ assert_equals(
+ result,
+ null,
+ 'Opaque type response could not be loaded in the new window.');
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Opaque type response could not be loaded in the new window.');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https.html
new file mode 100644
index 00000000000..36bf16f3279
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-header-visibility.https.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<title>Service Worker: Visibility of headers during fetch.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+ var worker = 'resources/fetch-rewrite-worker.js';
+ var path = base_path() + 'resources/fetch-access-control.py';
+ var host_info = get_host_info();
+ var frame;
+
+ async_test(function(t) {
+ var scope = 'resources/fetch-header-visibility-iframe.html';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ frame = document.createElement('iframe');
+ frame.src = scope;
+ document.body.appendChild(frame);
+
+ // Resolve a promise when we recieve 2 success messages
+ return new Promise(function(resolve, reject) {
+ var remaining = 4;
+ function onMessage(e) {
+ if (e.data == 'PASS') {
+ remaining--;
+ if (remaining == 0) {
+ resolve();
+ } else {
+ return;
+ }
+ } else {
+ reject(e.data);
+ }
+
+ window.removeEventListener('message', onMessage);
+ }
+ window.addEventListener('message', onMessage);
+ });
+ })
+ .then(function(result) {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Visibility of defaulted headers during interception');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html
new file mode 100644
index 00000000000..fb9fa9b7b71
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-inscope.https.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Service Worker: Mixed content of fetch()</title>
+<meta name=timeout content=long>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<body></body>
+<script>
+if (window.testRunner) {
+ // In Chromium we need to change the setting to disallow displaying insecure
+ // contents.
+ testRunner.overridePreference('WebKitAllowDisplayingInsecureContent', false);
+}
+
+async_test(function(t) {
+ var host_info = get_host_info();
+ window.addEventListener('message', t.step_func(on_message), false);
+ with_iframe(
+ host_info['HTTPS_ORIGIN'] + base_path() +
+ 'resources/fetch-mixed-content-iframe.html?target=inscope');
+ function on_message(e) {
+ assert_equals(e.data.results, 'finish');
+ t.done();
+ }
+ }, 'Verify Mixed content of fetch() in a Service Worker');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html
new file mode 100644
index 00000000000..cee89ce167d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-mixed-content-to-outscope.https.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Service Worker: Mixed content of fetch()</title>
+<meta name=timeout content=long>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<body></body>
+<script>
+if (window.testRunner) {
+ // In Chromium we need to change the setting to disallow displaying insecure
+ // contents.
+ testRunner.overridePreference('WebKitAllowDisplayingInsecureContent', false);
+}
+
+async_test(function(t) {
+ var host_info = get_host_info();
+ window.addEventListener('message', t.step_func(on_message), false);
+ with_iframe(
+ host_info['HTTPS_ORIGIN'] + base_path() +
+ 'resources/fetch-mixed-content-iframe.html?target=outscope');
+ function on_message(e) {
+ assert_equals(e.data.results, 'finish');
+ t.done();
+ }
+ }, 'Verify Mixed content of fetch() in a Service Worker');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-base-url.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-base-url.https.html
new file mode 100644
index 00000000000..0405ed70905
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-base-url.https.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<title>Service Worker: CSS's base URL must be the request URL even when fetched from other URL</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-request-css-base-url-iframe.html';
+ var SCRIPT = 'resources/fetch-request-css-base-url-worker.js';
+ var worker;
+ var testDonePromise;
+
+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ testDonePromise = new Promise(function(resolveTestDone) {
+ channel.port1.onmessage = t.step_func(function(msg) {
+ if (msg.data.ready) {
+ resolve();
+ return;
+ }
+ var result = msg.data;
+ var base = get_host_info()['HTTPS_ORIGIN'] + base_path();
+ assert_equals(
+ result.url,
+ base + 'resources/dummy.png',
+ 'The base URL while loading the images referred from CSS ' +
+ 'must be the request URL of CSS.');
+ assert_equals(
+ result.referrer,
+ base + 'resources/fetch-request-css-base-url-style.css',
+ 'While loading the image defined in CSS the referrer must ' +
+ 'be the request URL of CSS.');
+ resolveTestDone();
+ });
+ });
+ worker.postMessage(
+ {port: channel.port2}, [channel.port2]);
+ });
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(f) {
+ return testDonePromise.then(function() {
+ f.remove();
+ return service_worker_unregister_and_done(t, SCOPE);
+ });
+ })
+ .catch(unreached_rejection(t));
+ }, 'CSS\'s base URL must be the request URL even when fetched from other URL.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-images.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-images.https.html
new file mode 100644
index 00000000000..cbce7f19d71
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-css-images.https.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<title>Service Worker: FetchEvent for css image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+var url_count = 0;
+var expected_results = {};
+
+function css_image_test(frame, url, type, expexted_mode,
+ expected_credentials) {
+ var actual_url = url + (++url_count);
+ expected_results[actual_url] = {
+ url: actual_url,
+ mode: expexted_mode,
+ credentials: expected_credentials,
+ message: 'CSSImage load (url:' + actual_url + ' type:' + type + ')'
+ };
+ return frame.contentWindow.load_css_image(actual_url, type);
+}
+
+function css_image_set_test(frame, url, type, expexted_mode,
+ expected_credentials) {
+ var actual_url = url + (++url_count);
+ expected_results[actual_url] = {
+ url: actual_url,
+ mode: expexted_mode,
+ credentials: expected_credentials,
+ message: 'CSSImageSet load (url:' + actual_url + ' type:' + type + ')'
+ };
+ return frame.contentWindow.load_css_image_set(actual_url, type);
+}
+
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-request-resources-iframe.https.html';
+ var SCRIPT = 'resources/fetch-request-resources-worker.js';
+ var host_info = get_host_info();
+ var LOCAL_URL =
+ host_info['HTTPS_ORIGIN'] + base_path() + 'resources/dummy?test';
+ var REMOTE_URL =
+ host_info['HTTPS_REMOTE_ORIGIN'] + base_path() + 'resources/dummy?test';
+ var worker;
+ var frame;
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(msg) {
+ if (msg.data.ready) {
+ resolve();
+ return;
+ }
+ var result = msg.data;
+ var expected = expected_results[result.url];
+ if (!expected) {
+ return;
+ }
+ assert_equals(
+ result.mode, expected.mode,
+ 'mode of ' + expected.message + ' must be ' +
+ expected.mode + '.');
+ assert_equals(
+ result.credentials, expected.credentials,
+ 'credentials of ' + expected.message + ' must be ' +
+ expected.credentials + '.');
+ --url_count;
+ delete expected_results[result.url];
+ if (url_count == 0) {
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ }
+ });
+ worker.postMessage(
+ {port: channel.port2}, [channel.port2]);
+ });
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(f) {
+ frame = f;
+
+ css_image_test(f, LOCAL_URL, 'backgroundImage', 'no-cors', 'include');
+ css_image_test(f, REMOTE_URL, 'backgroundImage', 'no-cors', 'include');
+
+ css_image_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'same-origin');
+ css_image_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'same-origin');
+
+ css_image_set_test(f, LOCAL_URL, 'backgroundImage', 'no-cors', 'include');
+ css_image_set_test(f, REMOTE_URL, 'backgroundImage', 'no-cors', 'include');
+ css_image_set_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'same-origin');
+ css_image_set_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'same-origin');
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify FetchEvent for css images.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-fallback.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-fallback.https.html
new file mode 100644
index 00000000000..8290e21dd3e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-fallback.https.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<title>Service Worker: the fallback behavior of FetchEvent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+var expected_urls = [];
+
+function xhr_fail_test(frame, url) {
+ expected_urls.push(url);
+ return new Promise(function(resolve, reject) {
+ frame.contentWindow.xhr(url)
+ .then(function(){
+ reject(url + ' should fail.');
+ })
+ .catch(function(){
+ resolve();
+ });
+ });
+}
+
+function xhr_succeed_test(frame, url) {
+ expected_urls.push(url);
+ return new Promise(function(resolve, reject) {
+ frame.contentWindow.xhr(url)
+ .then(function(){
+ resolve();
+ })
+ .catch(function(){
+ reject(url + ' should succeed.');
+ });
+ });
+}
+
+async_test(function(t) {
+ var path = new URL(".", window.location).pathname;
+ var SCOPE = 'resources/fetch-request-fallback-iframe.html';
+ var SCRIPT = 'resources/fetch-request-fallback-worker.js';
+ var host_info = get_host_info();
+ var BASE_URL = host_info['HTTPS_ORIGIN'] +
+ path + 'resources/fetch-access-control.py?';
+ var OTHER_BASE_URL = host_info['HTTPS_REMOTE_ORIGIN'] +
+ path + 'resources/fetch-access-control.py?';
+ var REDIRECT_URL = host_info['HTTPS_ORIGIN'] +
+ path + 'resources/redirect.py?Redirect=';
+ var frame;
+ var worker;
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(f) {
+ frame = f;
+ return xhr_succeed_test(frame, BASE_URL);
+ })
+ .then(function(f) {
+ return xhr_fail_test(frame, OTHER_BASE_URL);
+ })
+ .then(function(f) {
+ return xhr_succeed_test(frame, OTHER_BASE_URL + 'ACAOrigin=*');
+ })
+ .then(function(f) {
+ return xhr_succeed_test(frame,
+ REDIRECT_URL + encodeURIComponent(BASE_URL));
+ })
+ .then(function() {
+ return xhr_fail_test(
+ frame,
+ REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL));
+ })
+ .then(function() {
+ return xhr_succeed_test(
+ frame,
+ REDIRECT_URL +
+ encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*'));
+ })
+ .then(function() {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(msg) {
+ frame.remove();
+ resolve(msg);
+ });
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ });
+ })
+ .then(function(msg) {
+ var requests = msg.data.requests;
+ assert_equals(requests.length, expected_urls.length + 1,
+ 'The count of the requests which are passed to the ' +
+ 'ServiceWorker must be correct.');
+ assert_equals(requests[0].url, new URL(SCOPE, location).toString(),
+ 'The first request to the SW must be the request for ' +
+ 'the page.');
+ assert_equals(requests[0].mode, 'navigate',
+ 'The mode of the first request to the SW must be ' +
+ 'navigate');
+ for (var i = 0; i < expected_urls.length; ++i) {
+ assert_equals(requests[i + 1].url, expected_urls[i],
+ 'The URL of the request which was passed from XHR ' +
+ 'to the ServiceWorker must be correct.');
+ assert_equals(requests[i + 1].mode, 'cors',
+ 'The mode of the request which was passed from XHR ' +
+ 'to the ServiceWorker must be cors.');
+ }
+ service_worker_unregister_and_done(t, SCOPE);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify the fallback behavior of FetchEvent');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https.html
new file mode 100644
index 00000000000..829b0cf2594
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-no-freshness-headers.https.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<title>Service Worker: the headers of FetchEvent shouldn't contain freshness headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-request-no-freshness-headers-iframe.html';
+ var SCRIPT = 'resources/fetch-request-no-freshness-headers-worker.js';
+ var worker;
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ return new Promise(function(resolve) {
+ frame.onload = function() {
+ resolve(frame);
+ };
+ frame.contentWindow.location.reload();
+ });
+ })
+ .then(function(frame) {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(msg) {
+ frame.remove();
+ resolve(msg);
+ });
+ worker.postMessage(
+ {port: channel.port2}, [channel.port2]);
+ });
+ })
+ .then(function(msg) {
+ var freshness_headers = {
+ 'if-none-match': true,
+ 'if-modified-since': true
+ };
+ msg.data.requests.forEach(t.step_func(function(request) {
+ request.headers.forEach(t.step_func(function(header) {
+ assert_false(
+ !!freshness_headers[header[0]],
+ header[0] + ' header must not be set in the ' +
+ 'FetchEvent\'s request. (url = ' + request.url + ')');
+ }));
+ }))
+ service_worker_unregister_and_done(t, SCOPE);
+ })
+ .catch(unreached_rejection(t));
+ }, 'The headers of FetchEvent shouldn\'t contain freshness headers.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-redirect.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-redirect.https.html
new file mode 100644
index 00000000000..fa937f2e189
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-redirect.https.html
@@ -0,0 +1,176 @@
+<!DOCTYPE html>
+<title>Service Worker: FetchEvent for resources</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+function assert_resolves(promise, description) {
+ return promise.catch(function(reason) {
+ throw new Error(description + ' - ' + reason.message);
+ });
+}
+
+function assert_rejects(promise, description) {
+ return promise.then(
+ function() { throw new Error(description); },
+ function() {});
+}
+
+function iframe_test(url, timeout_enabled) {
+ return new Promise(function(resolve, reject) {
+ var frame = document.createElement('iframe');
+ frame.src = url;
+ if (timeout_enabled) {
+ // We can't catch the network error on iframe. So we use the timer for
+ // failure detection.
+ var timer = setTimeout(function() {
+ reject(new Error('iframe load timeout'));
+ frame.remove();
+ }, 10000);
+ }
+ frame.onload = function() {
+ if (timeout_enabled)
+ clearTimeout(timer);
+ if (frame.contentDocument.body.textContent == 'Hello world\n')
+ resolve();
+ else
+ reject(new Error('content mismatch'));
+ frame.remove();
+ };
+ document.body.appendChild(frame);
+ });
+}
+
+promise_test(function(t) {
+ var SCOPE = 'resources/fetch-request-redirect-iframe.html';
+ var SCRIPT = 'resources/fetch-rewrite-worker.js';
+ var REDIRECT_URL = base_path() + 'resources/redirect.py?Redirect=';
+ var IMAGE_URL = base_path() + 'resources/square.png';
+ var AUDIO_URL = base_path() + 'resources/silence.oga';
+ var XHR_URL = base_path() + 'resources/simple.txt';
+ var HTML_URL = base_path() + 'resources/dummy.html';
+
+ var REDIRECT_TO_IMAGE_URL = REDIRECT_URL + encodeURIComponent(IMAGE_URL);
+ var REDIRECT_TO_AUDIO_URL = REDIRECT_URL + encodeURIComponent(AUDIO_URL);
+ var REDIRECT_TO_XHR_URL = REDIRECT_URL + encodeURIComponent(XHR_URL);
+ var REDIRECT_TO_HTML_URL = REDIRECT_URL + encodeURIComponent(HTML_URL);
+
+ var worker;
+ var frame;
+ return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(f) {
+ frame = f;
+ return Promise.all([
+ // XMLHttpRequest tests.
+ assert_resolves(frame.contentWindow.xhr(XHR_URL),
+ 'Normal XHR should succeed.'),
+ assert_resolves(frame.contentWindow.xhr(REDIRECT_TO_XHR_URL),
+ 'Redirected XHR should succeed.'),
+ assert_resolves(
+ frame.contentWindow.xhr(
+ './?url=' + encodeURIComponent(REDIRECT_TO_XHR_URL) +
+ '&redirect-mode=follow'),
+ 'Redirected XHR with Request.redirect=follow should succeed.'),
+ assert_rejects(
+ frame.contentWindow.xhr(
+ './?url=' + encodeURIComponent(REDIRECT_TO_XHR_URL) +
+ '&redirect-mode=error'),
+ 'Redirected XHR with Request.redirect=error should fail.'),
+ assert_rejects(
+ frame.contentWindow.xhr(
+ './?url=' + encodeURIComponent(REDIRECT_TO_XHR_URL) +
+ '&redirect-mode=manual'),
+ 'Redirected XHR with Request.redirect=manual should fail.'),
+
+ // Image loading tests.
+ assert_resolves(frame.contentWindow.load_image(IMAGE_URL),
+ 'Normal image resource should be loaded.'),
+ assert_resolves(
+ frame.contentWindow.load_image(REDIRECT_TO_IMAGE_URL),
+ 'Redirected image resource should be loaded.'),
+ assert_resolves(
+ frame.contentWindow.load_image(
+ './?url=' + encodeURIComponent(REDIRECT_TO_IMAGE_URL) +
+ '&redirect-mode=follow'),
+ 'Loading redirected image with Request.redirect=follow should' +
+ ' succeed.'),
+ assert_rejects(
+ frame.contentWindow.load_image(
+ './?url=' + encodeURIComponent(REDIRECT_TO_IMAGE_URL) +
+ '&redirect-mode=error'),
+ 'Loading redirected image with Request.redirect=error should ' +
+ 'fail.'),
+ assert_rejects(
+ frame.contentWindow.load_image(
+ './?url=' + encodeURIComponent(REDIRECT_TO_IMAGE_URL) +
+ '&redirect-mode=manual'),
+ 'Loading redirected image with Request.redirect=manual should' +
+ ' fail.'),
+
+ // Audio loading tests.
+ assert_resolves(frame.contentWindow.load_audio(AUDIO_URL),
+ 'Normal audio resource should be loaded.'),
+ assert_resolves(
+ frame.contentWindow.load_audio(REDIRECT_TO_AUDIO_URL),
+ 'Redirected audio resource should be loaded.'),
+ assert_resolves(
+ frame.contentWindow.load_audio(
+ './?url=' + encodeURIComponent(REDIRECT_TO_AUDIO_URL) +
+ '&redirect-mode=follow'),
+ 'Loading redirected audio with Request.redirect=follow should' +
+ ' succeed.'),
+ assert_rejects(
+ frame.contentWindow.load_audio(
+ './?url=' + encodeURIComponent(REDIRECT_TO_AUDIO_URL) +
+ '&redirect-mode=error'),
+ 'Loading redirected audio with Request.redirect=error should ' +
+ 'fail.'),
+ assert_rejects(
+ frame.contentWindow.load_audio(
+ './?url=' + encodeURIComponent(REDIRECT_TO_AUDIO_URL) +
+ '&redirect-mode=manual'),
+ 'Loading redirected audio with Request.redirect=manual should' +
+ ' fail.'),
+
+ // Iframe tests.
+ assert_resolves(iframe_test(HTML_URL),
+ 'Normal iframe loading should succeed.'),
+ assert_resolves(
+ iframe_test(REDIRECT_TO_HTML_URL),
+ 'Normal redirected iframe loading should succeed.'),
+ assert_resolves(
+ iframe_test(SCOPE + '?url=' +
+ encodeURIComponent(REDIRECT_TO_HTML_URL) +
+ '&redirect-mode=follow'),
+ 'Redirected iframe loading with Request.redirect=follow should'+
+ ' succeed.'),
+ assert_rejects(
+ iframe_test(SCOPE + '?url=' +
+ encodeURIComponent(REDIRECT_TO_HTML_URL) +
+ '&redirect-mode=error',
+ true /* timeout_enabled */),
+ 'Redirected iframe loading with Request.redirect=error should '+
+ 'fail.'),
+ assert_resolves(
+ iframe_test(SCOPE + '?url=' +
+ encodeURIComponent(REDIRECT_TO_HTML_URL) +
+ '&redirect-mode=manual',
+ true /* timeout_enabled */),
+ 'Redirected iframe loading with Request.redirect=manual should'+
+ ' succeed.'),
+ ]);
+ })
+ .then(function() {
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ }, 'Verify redirect mode of Fetch API and ServiceWorker FetchEvent.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html
new file mode 100644
index 00000000000..061add6f167
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-resources.https.html
@@ -0,0 +1,142 @@
+<!DOCTYPE html>
+<title>Service Worker: FetchEvent for resources</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+var url_count = 0;
+var expected_results = {};
+
+function image_test(frame, url, cross_origin, expexted_mode,
+ expected_credentials) {
+ var actual_url = url + (++url_count);
+ expected_results[actual_url] = {
+ cross_origin: cross_origin,
+ mode: expexted_mode,
+ credentials: expected_credentials,
+ message: 'Image load (url:' +
+ actual_url + ' cross_origin:' + cross_origin + ')'
+ };
+ return frame.contentWindow.load_image(actual_url, cross_origin);
+}
+
+function script_test(frame, url, cross_origin, expexted_mode,
+ expected_credentials) {
+ var actual_url = url + (++url_count);
+ expected_results[actual_url] = {
+ cross_origin: cross_origin,
+ mode: expexted_mode,
+ credentials: expected_credentials,
+ message: 'Script load (url:' +
+ actual_url + ' cross_origin:' + cross_origin + ')'
+ };
+ return frame.contentWindow.load_script(actual_url, cross_origin);
+}
+
+function css_test(frame, url, cross_origin, expexted_mode,
+ expected_credentials) {
+ var actual_url = url + (++url_count);
+ expected_results[actual_url] = {
+ cross_origin: cross_origin,
+ mode: expexted_mode,
+ credentials: expected_credentials,
+ message: 'CSS load (url:' +
+ actual_url + ' cross_origin:' + cross_origin + ')'
+ };
+ return frame.contentWindow.load_css(actual_url, cross_origin);
+}
+
+function font_face_test(frame, url, expexted_mode, expected_credentials) {
+ var actual_url = url + (++url_count);
+ expected_results[actual_url] = {
+ url: actual_url,
+ mode: expexted_mode,
+ credentials: expected_credentials,
+ message: 'FontFace load (url:' + actual_url + ')'
+ };
+ return frame.contentWindow.load_font(actual_url);
+}
+
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-request-resources-iframe.https.html';
+ var SCRIPT = 'resources/fetch-request-resources-worker.js';
+ var host_info = get_host_info();
+ var LOCAL_URL =
+ host_info['HTTPS_ORIGIN'] + base_path() + 'resources/dummy?test';
+ var REMOTE_URL =
+ host_info['HTTPS_REMOTE_ORIGIN'] + base_path() + 'resources/dummy?test';
+ var worker;
+ var frame;
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ worker = registration.installing;
+ return wait_for_state(t, worker, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(msg) {
+ if (msg.data.ready) {
+ resolve();
+ return;
+ }
+ var result = msg.data;
+ var expected = expected_results[result.url];
+ if (!expected) {
+ return;
+ }
+ assert_equals(
+ result.mode, expected.mode,
+ 'mode of ' + expected.message + ' must be ' +
+ expected.mode + '.');
+ assert_equals(
+ result.credentials, expected.credentials,
+ 'credentials of ' + expected.message + ' must be ' +
+ expected.credentials + '.');
+ --url_count;
+ delete expected_results[result.url];
+ if (url_count == 0) {
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ }
+ });
+ worker.postMessage(
+ {port: channel.port2}, [channel.port2]);
+ });
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(f) {
+ frame = f;
+
+ // TODO: Disable 'no-cors' tests for image until
+ // AsyncOpen2 and cookie policy is supported.
+ // image_test(f, LOCAL_URL, '', 'no-cors', 'include');
+ // image_test(f, REMOTE_URL, '', 'no-cors', 'include');
+ css_test(f, LOCAL_URL, '', 'no-cors', 'include');
+ css_test(f, REMOTE_URL, '', 'no-cors', 'include');
+
+ image_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+ image_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+ image_test(f, REMOTE_URL, 'anonymous', 'cors', 'omit');
+ image_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
+
+ script_test(f, LOCAL_URL, '', 'no-cors', 'include');
+ script_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+ script_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+ script_test(f, REMOTE_URL, '', 'no-cors', 'include');
+ script_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
+ script_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
+
+ css_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
+ css_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
+ css_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
+ css_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
+
+ font_face_test(f, LOCAL_URL, 'cors', 'same-origin');
+ font_face_test(f, REMOTE_URL, 'cors', 'same-origin');
+
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify FetchEvent for resources.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https.html
new file mode 100644
index 00000000000..1b80985a356
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-request-xhr.https.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<title>Service Worker: the body of FetchEvent using XMLHttpRequest</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-request-xhr-iframe.https.html';
+ var SCRIPT = 'resources/fetch-request-xhr-worker.js';
+ var host_info = get_host_info();
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ if (e.data.results === 'finish') {
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ } else if (e.data.results == 'equals') {
+ assert_equals(e.data.got, e.data.expected);
+ }
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify the body of FetchEvent using XMLHttpRequest');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-response-xhr.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-response-xhr.https.html
new file mode 100644
index 00000000000..8b66c605178
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-response-xhr.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Service Worker: the response of FetchEvent using XMLHttpRequest</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/fetch-response-xhr-iframe.https.html';
+ var SCRIPT = 'resources/fetch-response-xhr-worker.js';
+ var host_info = get_host_info();
+
+ window.addEventListener('message', t.step_func(on_message), false);
+ function on_message(e) {
+ assert_equals(e.data.results, 'foo, bar');
+ t.done();
+ }
+
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify the response of FetchEvent using XMLHttpRequest');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https.html
new file mode 100644
index 00000000000..304680c97e6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/fetch-waits-for-activate.https.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html>
+<title>Service Worker: Fetch Event Waits for Activate Event</title>
+<meta name=timeout content=long>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+
+var worker = 'resources/fetch-waits-for-activate-worker.js';
+var expected_url = normalizeURL(worker);
+var scope = 'resources/fetch-waits-for-activate/';
+
+async_test(function(t) {
+ var registration;
+ var frameLoadPromise;
+ var frame;
+ service_worker_unregister_and_register(t, worker, scope).then(function(reg) {
+ registration = reg;
+ return wait_for_state(t, reg.installing, 'activating');
+ }).then(function() {
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active worker should be present');
+ assert_equals(registration.active.state, 'activating',
+ 'active worker should be in activating state');
+
+ // This should block until we message the worker to tell it to complete
+ // the activate event.
+ frameLoadPromise = with_iframe(scope).then(function(f) {
+ frame = f;
+ });
+
+ // Wait some time to allow frame loading to proceed. It should not,
+ // however, if the fetch event is blocked on the activate. I don't
+ // see any way to force this race without a timeout, unfortunately.
+ return new Promise(function(resolve) {
+ setTimeout(resolve, 1000);
+ });
+ }).then(function() {
+ assert_equals(frame, undefined, 'frame should not be loaded');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active worker should be present');
+ assert_equals(registration.active.state, 'activating',
+ 'active worker should be in activating state');
+
+ // This signals the activate event to complete. The frame should now
+ // load.
+ registration.active.postMessage('GO');
+ return frameLoadPromise;
+ }).then(function() {
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller.scriptURL,
+ expected_url, 'frame should now be loaded and controlled');
+ assert_equals(registration.active.state, 'activated',
+ 'active worker should be in activated state');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ }).catch(unreached_rejection(t));
+}, 'Fetch events should wait for the activate event to complete.');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/getregistration.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/getregistration.https.html
new file mode 100644
index 00000000000..c86fda50d52
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/getregistration.https.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+async_test(function(t) {
+ var documentURL = 'no-such-worker';
+ navigator.serviceWorker.getRegistration(documentURL)
+ .then(function(value) {
+ assert_equals(value, undefined,
+ 'getRegistration should resolve with undefined');
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'getRegistration');
+
+async_test(function(t) {
+ var scope = 'resources/scope/getregistration/normal';
+ var registration;
+ service_worker_unregister_and_register(t, 'resources/empty-worker.js',
+ scope)
+ .then(function(r) {
+ registration = r;
+ return navigator.serviceWorker.getRegistration(scope);
+ })
+ .then(function(value) {
+ assert_equals(
+ value, registration,
+ 'getRegistration should resolve to the same registration object');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register then getRegistration');
+
+async_test(function(t) {
+ var scope = 'resources/scope/getregistration/url-with-fragment';
+ var documentURL = scope + '#ref';
+ var registration;
+ service_worker_unregister_and_register(t, 'resources/empty-worker.js',
+ scope)
+ .then(function(r) {
+ registration = r;
+ return navigator.serviceWorker.getRegistration(documentURL);
+ })
+ .then(function(value) {
+ assert_equals(
+ value, registration,
+ 'getRegistration should resolve to the same registration object');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register then getRegistration with a URL having a fragment');
+
+async_test(function(t) {
+ var documentURL = 'http://example.com/';
+ navigator.serviceWorker.getRegistration(documentURL)
+ .then(function() {
+ assert_unreached(
+ 'getRegistration with an out of origin URL should fail');
+ }, function(reason) {
+ assert_equals(
+ reason.name, 'SecurityError',
+ 'getRegistration with an out of origin URL should fail');
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'getRegistration with a cross origin URL');
+
+async_test(function(t) {
+ var scope = 'resources/scope/getregistration/register-unregister';
+ service_worker_unregister_and_register(t, 'resources/empty-worker.js',
+ scope)
+ .then(function(registration) {
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.getRegistration(scope);
+ })
+ .then(function(value) {
+ assert_equals(value, undefined,
+ 'getRegistration should resolve with undefined');
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register then Unregister then getRegistration');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/getregistrations.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/getregistrations.https.html
new file mode 100644
index 00000000000..86e8e1c283e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/getregistrations.https.html
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+<title>Service Worker: getRegistrations()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="../fetch/resources/fetch-test-helpers.sub.js"></script>
+<script>
+// Purge the existing registrations for the origin.
+// getRegistrations() is used in order to avoid adding additional complexity
+// e.g. adding an internal function.
+promise_test(function(t) {
+ return navigator.serviceWorker.getRegistrations()
+ .then(function(registrations) {
+ return registrations.reduce(function(sequence, registration) {
+ return sequence.then(function() {
+ return registration.unregister();
+ });
+ }, Promise.resolve());
+ });
+ }, 'Purge the existing registrations.');
+
+promise_test(function(t) {
+ return navigator.serviceWorker.getRegistrations()
+ .then(function(value) {
+ assert_array_equals(
+ value,
+ [],
+ 'getRegistrations should resolve with an empty array.');
+ });
+ }, 'getRegistrations');
+
+promise_test(function(t) {
+ var scope = 'resources/scope/getregistrations/normal';
+ var script = 'resources/empty-worker.js';
+ var registrations = [];
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(r) {
+ registrations.push(r);
+ return navigator.serviceWorker.getRegistrations();
+ })
+ .then(function(value) {
+ assert_array_equals(
+ value,
+ registrations,
+ 'getRegistrations should resolve with array of registrations.');
+ return service_worker_unregister(t, scope);
+ });
+ }, 'Register then getRegistrations');
+
+promise_test(function(t) {
+ var scope1 = 'resources/scope/getregistrations/scope1';
+ var scope2 = 'resources/scope/getregistrations/scope2';
+ var script = 'resources/empty-worker.js';
+ var registrations = [];
+ return service_worker_unregister_and_register(t, script, scope1)
+ .then(function(r) {
+ registrations.push(r);
+ return service_worker_unregister_and_register(t, script, scope2);
+ })
+ .then(function(r) {
+ registrations.push(r);
+ return navigator.serviceWorker.getRegistrations();
+ })
+ .then(function(value) {
+ assert_array_equals(
+ value,
+ registrations,
+ 'getRegistrations should resolve with array of registrations.');
+ return service_worker_unregister(t, scope1);
+ })
+ .then(function() {
+ return service_worker_unregister(t, scope2);
+ });
+ }, 'Register multiple times then getRegistrations');
+
+promise_test(function(t) {
+ var scope = 'resources/scope/getregistrations/register-unregister';
+ var script = 'resources/empty-worker.js';
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.getRegistrations();
+ })
+ .then(function(value) {
+ assert_array_equals(
+ value,
+ [],
+ 'getRegistrations should resolve with an empty array.');
+ });
+ }, 'Register then Unregister then getRegistrations');
+
+promise_test(function(t) {
+ var host_info = get_host_info();
+ // Rewrite the url to point to remote origin.
+ var frame_same_origin_url = new URL("resources/frame-for-getregistrations.html", window.location);
+ var frame_url = host_info['HTTPS_REMOTE_ORIGIN'] + frame_same_origin_url.pathname;
+ var scope = 'resources/scope-for-getregistrations';
+ var script = 'resources/empty-worker.js';
+ var frame;
+ var registrations = [];
+
+ // Loads an iframe and waits for 'ready' message from it to resolve promise.
+ // Caller is responsible for removing frame.
+ function with_iframe_ready(url) {
+ return new Promise(function(resolve) {
+ var frame = document.createElement('iframe');
+ frame.src = url;
+ window.addEventListener('message', function onMessage(e) {
+ window.removeEventListener('message', onMessage);
+ if (e.data == 'ready') {
+ resolve(frame);
+ }
+ });
+ document.body.appendChild(frame);
+ });
+ }
+
+ // We need this special frame loading function because the frame is going
+ // to register it's own service worker and there is the possibility that that
+ // register() finishes after the register() for the same domain later in the
+ // test. So we have to wait until the cross origin register() is done, and not
+ // just until the frame loads.
+ return with_iframe_ready(frame_url)
+ .then(function(f) {
+ frame = f;
+ return service_worker_unregister_and_register(t, script, scope);
+ })
+ .then(function(r) {
+ registrations.push(r);
+ return navigator.serviceWorker.getRegistrations();
+ })
+ .then(function(value) {
+ assert_array_equals(
+ value,
+ registrations,
+ 'getRegistrations should only return same origin registrations.');
+
+ var channel = new MessageChannel();
+ var resolve;
+ var p = new Promise(function(r) { resolve = r; });
+
+ channel.port1.onmessage = function(e) {
+ if (e.data == 'unregistered')
+ resolve();
+ };
+ frame.contentWindow.postMessage('unregister', '*', [channel.port2]);
+ return p;
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister(t, scope);
+ });
+ }, 'getRegistrations promise resolves only with same origin registrations.');
+
+done();
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/indexeddb.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/indexeddb.https.html
new file mode 100644
index 00000000000..4de2bc43e17
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/indexeddb.https.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Service Worker: Indexed DB</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+async_test(function(t) {
+ var scope = 'resources/blank.html';
+ service_worker_unregister_and_register(
+ t, 'resources/indexeddb-worker.js', scope)
+ .then(function(registration) {
+ var sw = registration.installing;
+ var messageChannel = new MessageChannel();
+ messageChannel.port1.onmessage = t.step_func(onMessage);
+ sw.postMessage({port: messageChannel.port2}, [messageChannel.port2]);
+ })
+ .catch(unreached_rejection(t));
+
+ function onMessage() {
+ var openRequest = indexedDB.open('db');
+ openRequest.onsuccess = t.step_func(function() {
+ var db = openRequest.result;
+ var tx = db.transaction('store');
+ var store = tx.objectStore('store');
+ var getRequest = store.get('key');
+ getRequest.onsuccess = t.step_func(function() {
+ assert_equals(
+ getRequest.result, 'value',
+ 'The get() result should match what the worker put().');
+ service_worker_unregister_and_done(t, scope);
+ });
+ });
+ }
+ }, 'Verify Indexed DB operation in a Service Worker');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/install-event-type.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/install-event-type.https.html
new file mode 100644
index 00000000000..7e74af85c3a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/install-event-type.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+function wait_for_install_event(worker) {
+ return new Promise(function(resolve) {
+ worker.addEventListener('statechange', function(event) {
+ if (worker.state == 'installed')
+ resolve(true);
+ else if (worker.state == 'redundant')
+ resolve(false);
+ });
+ });
+}
+
+promise_test(function(t) {
+ var script = 'resources/install-event-type-worker.js';
+ var scope = 'resources/install-event-type';
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_install_event(registration.installing);
+ })
+ .then(function(did_install) {
+ assert_true(did_install, 'The worker was installed');
+ })
+ }, 'install event type');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/installing.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/installing.https.html
new file mode 100644
index 00000000000..57d87811192
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/installing.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>ServiceWorker: navigator.serviceWorker.installing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+// "installing" is set
+async_test(function(t) {
+ var step = t.step_func.bind(t);
+ var url = 'resources/empty-worker.js';
+ var scope = 'resources/blank.html';
+ var frame;
+
+ service_worker_unregister(t, scope)
+ .then(step(function() { return with_iframe(scope); }))
+ .then(step(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url, {scope: scope});
+ }))
+ .then(step(function(registration) {
+ var container = frame.contentWindow.navigator.serviceWorker;
+ assert_equals(container.controller, null);
+ assert_equals(registration.active, null);
+ assert_equals(registration.waiting, null);
+ assert_equals(registration.installing.scriptURL, normalizeURL(url));
+
+ // FIXME: Add a test for a frame created after installation.
+ // Should the existing frame ("frame") block activation?
+ }))
+ .then(step(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ }))
+ .catch(unreached_rejection(t));
+}, 'installing is set');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/interfaces.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/interfaces.https.html
new file mode 100644
index 00000000000..403a005344e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/interfaces.https.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<title>Service Worker: Interfaces</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/interfaces.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+test(function() {
+ var EVENT_HANDLER = 'object';
+ verify_interface(
+ 'ServiceWorkerContainer', navigator.serviceWorker,
+ {
+ register: 'function',
+ getRegistration: 'function',
+ oncontrollerchange: EVENT_HANDLER
+ });
+ }, 'Interfaces and attributes of ServiceWorkerContainer');
+
+async_test(function(t) {
+ var EVENT_HANDLER = 'object';
+ var scope = 'resources/scope/interfaces-and-attributes';
+
+ service_worker_unregister_and_register(
+ t, 'resources/empty-worker.js', scope)
+ .then(function(registration) {
+ verify_interface(
+ 'ServiceWorkerRegistration', registration,
+ {
+ installing: 'object',
+ waiting: 'object',
+ active: 'object',
+ scope: 'string',
+ unregister: 'function',
+ onupdatefound: EVENT_HANDLER
+ });
+ verify_interface(
+ 'ServiceWorker', registration.installing,
+ {
+ scriptURL: 'string',
+ state: 'string',
+ onstatechange: EVENT_HANDLER
+ });
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Interfaces and attributes of ServiceWorker');
+
+service_worker_test(
+ 'resources/interfaces-worker.sub.js',
+ 'Interfaces and attributes in ServiceWorkerGlobalScope');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/invalid-blobtype.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/invalid-blobtype.https.html
new file mode 100644
index 00000000000..f1f2d1bdc61
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/invalid-blobtype.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Service Worker: respondWith with header value containing a null byte</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/invalid-blobtype-iframe.https.html';
+ var SCRIPT = 'resources/invalid-blobtype-worker.js';
+ var host_info = get_host_info();
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify the response of FetchEvent using XMLHttpRequest');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/invalid-header.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/invalid-header.https.html
new file mode 100644
index 00000000000..79469526493
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/invalid-header.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Service Worker: respondWith with header value containing a null byte</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/invalid-header-iframe.https.html';
+ var SCRIPT = 'resources/invalid-header-worker.js';
+ var host_info = get_host_info();
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify the response of FetchEvent using XMLHttpRequest');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/multiple-register.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/multiple-register.https.html
new file mode 100644
index 00000000000..1089cffda91
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/multiple-register.https.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+var worker_url = 'resources/empty-worker.js';
+
+async_test(function(t) {
+ var scope = 'resources/scope/subsequent-register-from-same-window';
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(worker_url, { scope: scope });
+ })
+ .then(function(new_registration) {
+ assert_equals(new_registration, registration,
+ 'register should resolve to the same registration');
+ assert_equals(new_registration.active, registration.active,
+ 'register should resolve to the same worker');
+ assert_equals(new_registration.active.state, 'activated',
+ 'the worker should be in state "activated"');
+ return registration.unregister();
+ })
+ .then(function() { t.done(); })
+ .catch(unreached_rejection(t));
+}, 'Subsequent registrations resolve to the same registration object');
+
+async_test(function(t) {
+ var scope = 'resources/scope/subsequent-register-from-different-iframe';
+ var frame;
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() { return with_iframe('resources/404.py'); })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.navigator.serviceWorker.register(
+ worker_url, { scope: scope });
+ })
+ .then(function(new_registration) {
+ assert_not_equals(
+ registration, new_registration,
+ 'register should resolve to a different registration');
+ assert_equals(
+ registration.scope, new_registration.scope,
+ 'registrations should have the same scope');
+
+ assert_equals(
+ registration.installing, null,
+ 'installing worker should be null');
+ assert_equals(
+ new_registration.installing, null,
+ 'installing worker should be null');
+ assert_equals(
+ registration.waiting, null,
+ 'waiting worker should be null')
+ assert_equals(
+ new_registration.waiting, null,
+ 'waiting worker should be null')
+
+ assert_not_equals(
+ registration.active, new_registration.active,
+ 'registration should have the different active worker');
+ assert_equals(
+ registration.active.scriptURL,
+ new_registration.active.scriptURL,
+ 'active workers should have the same script URL');
+ assert_equals(
+ registration.active.state,
+ new_registration.active.state,
+ 'active workers should be in the same state');
+
+ frame.remove();
+ return registration.unregister();
+ })
+ .then(function() { t.done(); })
+ .catch(unreached_rejection(t));
+}, 'Subsequent registrations from a different iframe resolve to the ' +
+ 'different registration object but they refer to the same ' +
+ 'registration and workers');
+
+async_test(function(t) {
+ var scope = 'resources/scope/concurrent-register';
+
+ service_worker_unregister(t, scope)
+ .then(function() {
+ var promises = [];
+ for (var i = 0; i < 10; ++i) {
+ promises.push(navigator.serviceWorker.register(worker_url,
+ { scope: scope }));
+ }
+ return Promise.all(promises);
+ })
+ .then(function(registrations) {
+ registrations.forEach(function(registration) {
+ assert_equals(registration, registrations[0],
+ 'register should resolve to the same registration');
+ });
+ return registrations[0].unregister();
+ })
+ .then(function() { t.done(); })
+ .catch(unreached_rejection(t));
+}, 'Concurrent registrations resolve to the same registration object');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/multiple-update.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/multiple-update.https.html
new file mode 100644
index 00000000000..84aac9583b9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/multiple-update.https.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<!-- In Bug 1217367, we will try to merge update events for same registration
+ if possible. This testcase is used to make sure the optimization algorithm
+ doesn't go wrong. -->
+<title>Service Worker: Trigger multiple updates</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+promise_test(function(t) {
+ var script = 'resources/update-nocookie-worker.py';
+ var scope = 'resources/scope/update';
+ var expected_url = normalizeURL(script);
+ var registration;
+
+ return service_worker_unregister_and_register(t, expected_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ // Test single update works before triggering multiple update events
+ return Promise.all([registration.update(),
+ wait_for_update(t, registration)]);
+ })
+ .then(function() {
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'new installing should be set after update resolves.');
+ assert_equals(registration.waiting, null,
+ 'waiting should still be null after update resolves.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update found.');
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing should be null after installing.');
+ if (registration.waiting) {
+ assert_equals(registration.waiting.scriptURL, expected_url,
+ 'waiting should be set after installing.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after installing.');
+ return wait_for_state(t, registration.waiting, 'activated');
+ }
+ })
+ .then(function() {
+ // Test triggering multiple update events at the same time.
+ var promiseList = [];
+ const burstUpdateCount = 10;
+ for (var i = 0; i < burstUpdateCount; i++) {
+ promiseList.push(registration.update());
+ }
+ promiseList.push(wait_for_update(t, registration));
+ return Promise.all(promiseList);
+ })
+ .then(function() {
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'new installing should be set after update resolves.');
+ assert_equals(registration.waiting, null,
+ 'waiting should still be null after update resolves.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update found.');
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing should be null after installing.');
+ if (registration.waiting) {
+ assert_equals(registration.waiting.scriptURL, expected_url,
+ 'waiting should be set after installing.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after installing.');
+ return wait_for_state(t, registration.waiting, 'activated');
+ }
+ })
+ .then(function() {
+ // Test update still works after handling update event burst.
+ return Promise.all([registration.update(),
+ wait_for_update(t, registration)]);
+ })
+ .then(function() {
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'new installing should be set after update resolves.');
+ assert_equals(registration.waiting, null,
+ 'waiting should be null after activated.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update found.');
+
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Trigger multiple updates.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html
new file mode 100644
index 00000000000..7b606cf0c3c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/navigation-redirect.https.html
@@ -0,0 +1,449 @@
+<!DOCTYPE html>
+<title>Service Worker: Navigation redirection</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+var host_info = get_host_info();
+
+// This test registers three Service Workers at SCOPE1, SCOPE2 and
+// OTHER_ORIGIN_SCOPE. And checks the redirected page's URL and the requests
+// which are intercepted by Service Worker while loading redirect page.
+var BASE_URL = host_info['HTTPS_ORIGIN'] + base_path();
+var OTHER_BASE_URL = host_info['HTTPS_REMOTE_ORIGIN'] + base_path();
+
+var SCOPE1 = BASE_URL + 'resources/navigation-redirect-scope1.py?';
+var SCOPE2 = BASE_URL + 'resources/navigation-redirect-scope2.py?';
+var OUT_SCOPE = BASE_URL + 'resources/navigation-redirect-out-scope.py?';
+var SCRIPT = 'resources/navigation-redirect-worker.js';
+
+var OTHER_ORIGIN_IFRAME_URL =
+ OTHER_BASE_URL + 'resources/navigation-redirect-other-origin.html';
+var OTHER_ORIGIN_SCOPE =
+ OTHER_BASE_URL + 'resources/navigation-redirect-scope1.py?';
+var OTHER_ORIGIN_OUT_SCOPE =
+ OTHER_BASE_URL + 'resources/navigation-redirect-out-scope.py?';
+
+var workers;
+var other_origin_frame;
+var setup_environment_promise;
+var message_resolvers = {};
+var next_message_id = 0;
+
+function setup_environment(t) {
+ if (setup_environment_promise)
+ return setup_environment_promise;
+ setup_environment_promise =
+ with_iframe(OTHER_ORIGIN_IFRAME_URL)
+ .then(function(f) {
+ // In this frame we register a Service Worker at OTHER_ORIGIN_SCOPE.
+ // And will use this frame to communicate with the worker.
+ other_origin_frame = f;
+ return Promise.all(
+ [service_worker_unregister_and_register(t, SCRIPT, SCOPE1),
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE2)]);
+ })
+ .then(function(registrations) {
+ add_completion_callback(function() {
+ registrations[0].unregister();
+ registrations[1].unregister();
+ send_to_iframe(other_origin_frame, 'unregister')
+ .then(function() { other_origin_frame.remove(); });
+ });
+ workers = registrations.map(get_effective_worker);
+ return Promise.all([
+ wait_for_state(t, workers[0], 'activated'),
+ wait_for_state(t, workers[1], 'activated'),
+ // This promise will resolve when |wait_for_worker_promise|
+ // in OTHER_ORIGIN_IFRAME_URL resolves.
+ send_to_iframe(other_origin_frame, 'wait_for_worker')]);
+ });
+ return setup_environment_promise;
+}
+
+function get_effective_worker(registration) {
+ if (registration.active)
+ return registration.active;
+ if (registration.waiting)
+ return registration.waiting;
+ if (registration.installing)
+ return registration.installing;
+}
+
+function check_all_intercepted_urls(expected_urls) {
+ var urls = [];
+ return get_intercepted_urls(workers[0])
+ .then(function(url) {
+ urls.push(url);
+ return get_intercepted_urls(workers[1]);
+ }).then(function(url) {
+ urls.push(url);
+ // Gets the request URLs which are intercepted by OTHER_ORIGIN_SCOPE's
+ // SW. This promise will resolve when get_intercepted_urls() in
+ // OTHER_ORIGIN_IFRAME_URL resolves.
+ return send_to_iframe(other_origin_frame, 'get_intercepted_urls');
+ }).then(function(url) {
+ urls.push(url);
+ return urls;
+ }).then(function(urls) {
+ assert_object_equals(
+ urls, expected_urls,
+ 'Intercepted URLs should match.');
+ });
+}
+
+function test_redirect(url, expected_last_url,
+ expected_intercepted_urls) {
+ var message_promise = new Promise(function(resolve) {
+ // A message which ID is 'last_url' will be sent from the iframe.
+ message_resolvers['last_url'] = resolve;
+ });
+ return with_iframe(url)
+ .then(function(f) {
+ f.remove();
+ return check_all_intercepted_urls(expected_intercepted_urls);
+ })
+ .then(function() { return message_promise; })
+ .then(function(last_url) {
+ assert_equals(
+ last_url, expected_last_url,
+ 'Last URL should match.');
+ });
+}
+
+window.addEventListener('message', on_message, false);
+
+function on_message(e) {
+ if (e.origin != host_info['HTTPS_REMOTE_ORIGIN'] &&
+ e.origin != host_info['HTTPS_ORIGIN'] ) {
+ console.error('invalid origin: ' + e.origin);
+ return;
+ }
+ var resolve = message_resolvers[e.data.id];
+ delete message_resolvers[e.data.id];
+ resolve(e.data.result);
+}
+
+function send_to_iframe(frame, message) {
+ var message_id = next_message_id++;
+ return new Promise(function(resolve) {
+ message_resolvers[message_id] = resolve;
+ frame.contentWindow.postMessage(
+ {id: message_id, message: message},
+ host_info['HTTPS_REMOTE_ORIGIN']);
+ });
+}
+
+function get_intercepted_urls(worker) {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(msg) { resolve(msg.data.urls); };
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ });
+}
+
+// Normal redirect.
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ OUT_SCOPE + 'url=' + encodeURIComponent(SCOPE1),
+ SCOPE1,
+ [[SCOPE1], [], []]);
+ });
+ }, 'Normal redirect to same-origin scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ OUT_SCOPE + 'url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE),
+ OTHER_ORIGIN_SCOPE,
+ [[], [], [OTHER_ORIGIN_SCOPE]]);
+ });
+ }, 'Normal redirect to other-origin scope.');
+
+// SW fallbacked redirect. SW doesn't handle the fetch request.
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'url=' + encodeURIComponent(OUT_SCOPE),
+ OUT_SCOPE,
+ [[SCOPE1 + 'url=' + encodeURIComponent(OUT_SCOPE)], [], []]);
+ });
+ }, 'SW-fallbacked redirect to same-origin out-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'url=' + encodeURIComponent(SCOPE1),
+ SCOPE1,
+ [[SCOPE1 + 'url=' + encodeURIComponent(SCOPE1)], [], []]);
+ });
+ }, 'SW-fallbacked redirect to same-origin same-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'url=' + encodeURIComponent(SCOPE2),
+ SCOPE2,
+ [[SCOPE1 + 'url=' + encodeURIComponent(SCOPE2)], [], []]);
+ });
+ }, 'SW-fallbacked redirect to same-origin other-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'url=' + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE),
+ OTHER_ORIGIN_OUT_SCOPE,
+ [[SCOPE1 + 'url=' + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)],
+ [],
+ []]);
+ });
+ }, 'SW-fallbacked redirect to other-origin out-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE),
+ OTHER_ORIGIN_SCOPE,
+ [[SCOPE1 + 'url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE)],
+ [],
+ []]);
+ });
+ }, 'SW-fallbacked redirect to other-origin in-scope.');
+
+// SW generated redirect.
+// SW: event.respondWith(Response.redirect(params['url']));
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE),
+ OUT_SCOPE,
+ [[SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OUT_SCOPE)], [], []]);
+ });
+ }, 'SW-generated redirect to same-origin out-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=gen&url=' + encodeURIComponent(SCOPE1),
+ SCOPE1,
+ [[SCOPE1 + 'sw=gen&url=' + encodeURIComponent(SCOPE1), SCOPE1],
+ [],
+ []]);
+ });
+ }, 'SW-generated redirect to same-origin same-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=gen&url=' + encodeURIComponent(SCOPE2),
+ SCOPE2,
+ [[SCOPE1 + 'sw=gen&url=' + encodeURIComponent(SCOPE2)],
+ [SCOPE2],
+ []]);
+ });
+ }, 'SW-generated redirect to same-origin other-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE),
+ OTHER_ORIGIN_OUT_SCOPE,
+ [[SCOPE1 + 'sw=gen&url=' +
+ encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)],
+ [],
+ []]);
+ });
+ }, 'SW-generated redirect to other-origin out-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE),
+ OTHER_ORIGIN_SCOPE,
+ [[SCOPE1 + 'sw=gen&url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE)],
+ [],
+ [OTHER_ORIGIN_SCOPE]]);
+ });
+ }, 'SW-generated redirect to other-origin in-scope.');
+
+// SW fetched redirect.
+// SW: event.respondWith(fetch(event.request));
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(OUT_SCOPE),
+ OUT_SCOPE,
+ [[SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(OUT_SCOPE)],
+ [],
+ []]);
+ });
+ }, 'SW-fetched redirect to same-origin out-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(SCOPE1),
+ SCOPE1,
+ [[SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(SCOPE1), SCOPE1],
+ [],
+ []]);
+ });
+ }, 'SW-fetched redirect to same-origin same-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(SCOPE2),
+ SCOPE2,
+ [[SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(SCOPE2)],
+ [SCOPE2],
+ []]);
+ });
+ }, 'SW-fetched redirect to same-origin other-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=fetch&url=' +
+ encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE),
+ OTHER_ORIGIN_OUT_SCOPE,
+ [[SCOPE1 + 'sw=fetch&url=' +
+ encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)],
+ [],
+ []]);
+ });
+ }, 'SW-fetched redirect to other-origin out-scope.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=fetch&url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE),
+ OTHER_ORIGIN_SCOPE,
+ [[SCOPE1 + 'sw=fetch&url=' +
+ encodeURIComponent(OTHER_ORIGIN_SCOPE)],
+ [],
+ [OTHER_ORIGIN_SCOPE]]);
+ });
+ }, 'SW-fetched redirect to other-origin in-scope.');
+
+// Opaque redirect.
+// SW: event.respondWith(fetch(
+// new Request(event.request.url, {redirect: 'manual'})));
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaque&url=' + encodeURIComponent(OUT_SCOPE),
+ OUT_SCOPE,
+ [[SCOPE1 + 'sw=opaque&url=' + encodeURIComponent(OUT_SCOPE)],
+ [],
+ []]);
+ });
+ }, 'Redirect to same-origin out-scope with opaque redirect response.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaque&url=' + encodeURIComponent(SCOPE1),
+ SCOPE1,
+ [[SCOPE1 + 'sw=opaque&url=' + encodeURIComponent(SCOPE1), SCOPE1],
+ [],
+ []]);
+ });
+ }, 'Redirect to same-origin same-scope with opaque redirect response.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaque&url=' + encodeURIComponent(SCOPE2),
+ SCOPE2,
+ [[SCOPE1 + 'sw=opaque&url=' + encodeURIComponent(SCOPE2)],
+ [SCOPE2],
+ []]);
+ });
+ }, 'Redirect to same-origin other-scope with opaque redirect response.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaque&url=' +
+ encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE),
+ OTHER_ORIGIN_OUT_SCOPE,
+ [[SCOPE1 + 'sw=opaque&url=' +
+ encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)],
+ [],
+ []]);
+ });
+ }, 'Redirect to other-origin out-scope with opaque redirect response.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaque&url=' + encodeURIComponent(OTHER_ORIGIN_SCOPE),
+ OTHER_ORIGIN_SCOPE,
+ [[SCOPE1 + 'sw=opaque&url=' +
+ encodeURIComponent(OTHER_ORIGIN_SCOPE)],
+ [],
+ [OTHER_ORIGIN_SCOPE]]);
+ });
+ }, 'Redirect to other-origin in-scope with opaque redirect response.');
+
+// Opaque redirect passed through Cache.
+// SW responds with an opaque redirectresponse from the Cache API.
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(OUT_SCOPE),
+ OUT_SCOPE,
+ [[SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(OUT_SCOPE)],
+ [],
+ []]);
+ });
+ },
+ 'Redirect to same-origin out-scope with opaque redirect response which ' +
+ 'is passed through Cache.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(SCOPE1),
+ SCOPE1,
+ [[SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(SCOPE1), SCOPE1],
+ [],
+ []]);
+ });
+ },
+ 'Redirect to same-origin same-scope with opaque redirect response which ' +
+ 'is passed through Cache.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(SCOPE2),
+ SCOPE2,
+ [[SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(SCOPE2)],
+ [SCOPE2],
+ []]);
+ });
+ },
+ 'Redirect to same-origin other-scope with opaque redirect response which ' +
+ 'is passed through Cache.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE),
+ OTHER_ORIGIN_OUT_SCOPE,
+ [[SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(OTHER_ORIGIN_OUT_SCOPE)],
+ [],
+ []]);
+ });
+ },
+ 'Redirect to other-origin out-scope with opaque redirect response which ' +
+ 'is passed through Cache.');
+promise_test(function(t) {
+ return setup_environment(t).then(function() {
+ return test_redirect(
+ SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(OTHER_ORIGIN_SCOPE),
+ OTHER_ORIGIN_SCOPE,
+ [[SCOPE1 + 'sw=opaqueThroughCache&url=' +
+ encodeURIComponent(OTHER_ORIGIN_SCOPE)],
+ [],
+ [OTHER_ORIGIN_SCOPE]]);
+ });
+ },
+ 'Redirect to other-origin in-scope with opaque redirect response which ' +
+ 'is passed through Cache.');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/onactivate-script-error.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/onactivate-script-error.https.html
new file mode 100644
index 00000000000..23a7f2c8686
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/onactivate-script-error.https.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+function wait_for_install(worker) {
+ return new Promise(function(resolve, reject) {
+ worker.addEventListener('statechange', function(event) {
+ if (worker.state == 'installed')
+ resolve();
+ else if (worker.state == 'redundant')
+ reject();
+ });
+ });
+}
+
+function wait_for_activate(worker) {
+ return new Promise(function(resolve, reject) {
+ worker.addEventListener('statechange', function(event) {
+ if (worker.state == 'activated')
+ resolve();
+ else if (worker.state == 'redundant')
+ reject();
+ });
+ });
+}
+
+function make_test(name, script) {
+ promise_test(function(t) {
+ var scope = script;
+ var registration;
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_install(registration.installing);
+ })
+ .then(function() {
+ // Activate should succeed regardless of script errors.
+ if (registration.active && registration.active.state == 'activated') {
+ return Promise.resolve();
+ } else if (registration.active) {
+ return wait_for_activate(registration.active);
+ }
+
+ return wait_for_activate(registration.waiting);
+ });
+ }, name);
+}
+
+[
+ {
+ name: 'activate handler throws an error',
+ script: 'resources/onactivate-throw-error-worker.js',
+ },
+ {
+ name: 'activate handler throws an error, error handler does not cancel',
+ script: 'resources/onactivate-throw-error-with-empty-onerror-worker.js',
+ },
+ {
+ name: 'activate handler dispatches an event that throws an error',
+ script: 'resources/onactivate-throw-error-from-nested-event-worker.js',
+ },
+ {
+ name: 'activate handler throws an error that is cancelled',
+ script: 'resources/onactivate-throw-error-then-cancel-worker.js',
+ },
+ {
+ name: 'activate handler throws an error and prevents default',
+ script: 'resources/onactivate-throw-error-then-prevent-default-worker.js',
+ }
+].forEach(function(test_case) {
+ make_test(test_case.name, test_case.script);
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/oninstall-script-error.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/oninstall-script-error.https.html
new file mode 100644
index 00000000000..a9ca19cab7f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/oninstall-script-error.https.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+function wait_for_install_event(worker) {
+ return new Promise(function(resolve) {
+ worker.addEventListener('statechange', function(event) {
+ if (worker.state == 'installed')
+ resolve(true);
+ else if (worker.state == 'redundant')
+ resolve(false);
+ });
+ });
+}
+
+function make_test(name, script, expect_install) {
+ promise_test(function(t) {
+ var scope = script;
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return wait_for_install_event(registration.installing);
+ })
+ .then(function(did_install) {
+ assert_equals(did_install, expect_install,
+ 'The worker was installed');
+ })
+ }, name);
+}
+
+[
+ {
+ name: 'install handler throws an error',
+ script: 'resources/oninstall-throw-error-worker.js',
+ expect_install: false
+ },
+ {
+ name: 'install handler throws an error, error handler does not cancel',
+ script: 'resources/oninstall-throw-error-with-empty-onerror-worker.js',
+ expect_install: false
+ },
+ {
+ name: 'install handler dispatches an event that throws an error',
+ script: 'resources/oninstall-throw-error-from-nested-event-worker.js',
+ expect_install: true
+ },
+
+ // The following two cases test what happens when the ServiceWorkerGlobalScope
+ // 'error' event handler cancels the resulting error event. Since the
+ // original 'install' event handler through, the installation should still
+ // be stopped in this case. See:
+ // https://github.com/slightlyoff/ServiceWorker/issues/778
+ {
+ name: 'install handler throws an error that is cancelled',
+ script: 'resources/oninstall-throw-error-then-cancel-worker.js',
+ expect_install: false
+ },
+ {
+ name: 'install handler throws an error and prevents default',
+ script: 'resources/oninstall-throw-error-then-prevent-default-worker.js',
+ expect_install: false
+ }
+].forEach(function(test_case) {
+ make_test(test_case.name, test_case.script, test_case.expect_install);
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/performance-timeline.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/performance-timeline.https.html
new file mode 100644
index 00000000000..182076baa98
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/performance-timeline.https.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+service_worker_test(
+ 'resources/performance-timeline-worker.js',
+ 'Test Performance Timeline API in Service Worker');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-msgport-to-client.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-msgport-to-client.https.html
new file mode 100644
index 00000000000..38b4f56e784
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-msgport-to-client.https.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<title>Service Worker: postMessage to Client</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var frame;
+var t = async_test('postMessage MessagePorts from ServiceWorker to Client');
+t.step(function() {
+ var scope = 'resources/blank.html'
+ service_worker_unregister_and_register(
+ t, 'resources/postmessage-msgport-to-client-worker.js', scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ var w = frame.contentWindow;
+ w.navigator.serviceWorker.onmessage = t.step_func(onMessage);
+ w.navigator.serviceWorker.controller.postMessage('ping');
+ })
+ .catch(unreached_rejection(t));
+
+ var result = [];
+ var expected = [
+ 'Acking value: 1',
+ 'Acking value: 2',
+ ];
+
+ function onMessage(e) {
+ var message = e.data;
+ if ('port' in message) {
+ var port = message.port;
+ port.postMessage({value: 1});
+ port.postMessage({value: 2});
+ port.postMessage({done: true});
+ } else if ('ack' in message) {
+ result.push(message.ack);
+ } else if ('done' in message) {
+ assert_array_equals(
+ result, expected,
+ 'Worker should post back expected values via MessagePort.');
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ } else {
+ assert_unreached('Got unexpected message from ServiceWorker');
+ }
+ }
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html
new file mode 100644
index 00000000000..a031ee2edf3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage-to-client.https.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<title>Service Worker: postMessage to Client</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var frame;
+var t = async_test('postMessage from ServiceWorker to Client');
+t.step(function() {
+ var scope = 'resources/blank.html';
+ var host_info = get_host_info();
+ var sw;
+ service_worker_unregister_and_register(
+ t, 'resources/postmessage-to-client-worker.js', scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ sw = frame.contentWindow.navigator.serviceWorker;
+ sw.onmessage = t.step_func(onMessage);
+ sw.controller.postMessage('ping');
+ })
+ .catch(unreached_rejection(t));
+
+ var result = [];
+ var expected = ['Sending message via clients'];
+
+ function onMessage(e) {
+ assert_equals(e.bubbles, false, 'message events should not bubble.');
+ assert_equals(e.cancelable, false, 'message events should not be cancelable.');
+ assert_equals(e.origin, host_info['HTTPS_ORIGIN'], 'message event\'s origin should be set correctly.');
+// XXXkhuey fixme!
+// assert_equals(e.source, sw.controller, 'source should be ServiceWorker.');
+
+ var message = e.data;
+ if (message === 'quit') {
+ assert_array_equals(result, expected,
+ 'Worker should post back expected messages.');
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ } else {
+ result.push(message);
+ }
+ }
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage.https.html
new file mode 100644
index 00000000000..a6f66517910
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/postmessage.https.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<title>Service Worker: postMessage</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+async_test(function(t) {
+ var scope = 'resources/blank.html';
+ var registration;
+ var worker;
+ service_worker_unregister_and_register(
+ t, 'resources/postmessage-worker.js', scope)
+ .then(function(r) {
+ registration = r;
+ worker = registration.installing;
+ var messageChannel = new MessageChannel();
+ messageChannel.port1.onmessage = t.step_func(onMessage);
+ worker.postMessage({port: messageChannel.port2},
+ [messageChannel.port2]);
+ worker.postMessage({value: 1});
+ worker.postMessage({value: 2});
+ worker.postMessage({done: true});
+ })
+ .catch(unreached_rejection(t));
+
+ var result = [];
+ var expected = [
+ 'Acking value: 1',
+ 'Acking value: 2',
+ ];
+
+ function onMessage(e) {
+ var message = e.data;
+ if (message === 'quit') {
+ assert_array_equals(result, expected,
+ 'Worker should post back expected values.');
+ postMessageToRedundantWorker();
+ } else {
+ result.push(message);
+ }
+ };
+
+ function postMessageToRedundantWorker() {
+ registration.unregister(scope)
+ .then(function() {
+ return wait_for_state(t, worker, 'redundant');
+ })
+ .then(function() {
+ assert_equals(worker.state, 'redundant');
+ assert_throws(
+ {name:'InvalidStateError'},
+ function() { worker.postMessage(''); },
+ 'Calling postMessage on a redundant ServiceWorker should ' +
+ 'throw InvalidStateError.');
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }
+ }, 'postMessage to a ServiceWorker (and back via MessagePort)');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/ready.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/ready.https.html
new file mode 100644
index 00000000000..ee6a97ca8fc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/ready.https.html
@@ -0,0 +1,172 @@
+<!DOCTYPE html>
+<title>Service Worker: navigator.serviceWorker.ready</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+test(function() {
+ var promise = navigator.serviceWorker.ready;
+ assert_equals(promise, navigator.serviceWorker.ready,
+ 'repeated access to ready without intervening ' +
+ 'registrations should return the same Promise object');
+ }, 'ready returns the same Promise object');
+
+async_test(function(t) {
+ with_iframe('resources/blank.html?uncontrolled')
+ .then(t.step_func(function(frame) {
+ var promise = frame.contentWindow.navigator.serviceWorker.ready;
+ assert_equals(Object.getPrototypeOf(promise),
+ frame.contentWindow.Promise.prototype,
+ 'the Promise should be in the context of the ' +
+ 'related document');
+ frame.remove();
+ t.done();
+ }));
+ }, 'ready returns a Promise object in the context of the related document');
+
+async_test(function(t) {
+ var url = 'resources/empty-worker.js';
+ var scope = 'resources/blank.html?ready-controlled';
+ var expected_url = normalizeURL(url);
+ var frame;
+
+ service_worker_unregister_and_register(t, url, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.navigator.serviceWorker.ready;
+ })
+ .then(function(registration) {
+ assert_equals(registration.installing, null,
+ 'installing should be null');
+ assert_equals(registration.waiting, null,
+ 'waiting should be null');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active after ready should not be null');
+ assert_equals(
+ frame.contentWindow.navigator.serviceWorker.controller.scriptURL,
+ expected_url,
+ 'controlled document should have a controller');
+
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'ready on a controlled document');
+
+async_test(function(t) {
+ var url = 'resources/empty-worker.js';
+ var scope = 'resources/blank.html?ready-potential-controlled';
+ var expected_url = normalizeURL(url);
+ var frame;
+
+ with_iframe(scope)
+ .then(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url, {scope:scope});
+ })
+ .then(function() {
+ return frame.contentWindow.navigator.serviceWorker.ready;
+ })
+ .then(function(registration) {
+ assert_equals(registration.installing, null,
+ 'installing should be null');
+ assert_equals(registration.waiting, null,
+ 'waiting should be null.')
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active after ready should not be null');
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
+ null,
+ 'uncontrolled document should not have a controller');
+
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'ready on a potential controlled document');
+
+async_test(function(t) {
+ var url = 'resources/empty-worker.js';
+ var matched_scope = 'resources/blank.html?ready-after-match';
+ var longer_matched_scope = 'resources/blank.html?ready-after-match-longer';
+ var frame, registration;
+
+ Promise.all([service_worker_unregister(t, matched_scope),
+ service_worker_unregister(t, longer_matched_scope)])
+ .then(function() {
+ return with_iframe(longer_matched_scope);
+ })
+ .then(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url, {scope: matched_scope});
+ })
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(
+ url, {scope: longer_matched_scope});
+ })
+ .then(function() {
+ return frame.contentWindow.navigator.serviceWorker.ready;
+ })
+ .then(function(r) {
+ assert_equals(r.scope, normalizeURL(longer_matched_scope),
+ 'longer matched registration should be returned');
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
+ null, 'controller should be null');
+ return registration.unregister();
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, longer_matched_scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'ready after a longer matched registration registered');
+
+async_test(function(t) {
+ var url = 'resources/empty-worker.js';
+ var matched_scope = 'resources/blank.html?ready-after-resolve';
+ var longer_matched_scope =
+ 'resources/blank.html?ready-after-resolve-longer';
+ var frame, registration;
+
+ service_worker_unregister_and_register(t, url, matched_scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(longer_matched_scope);
+ })
+ .then(function(f) {
+ frame = f;
+ return f.contentWindow.navigator.serviceWorker.ready;
+ })
+ .then(function(r) {
+ assert_equals(r.scope, normalizeURL(matched_scope),
+ 'matched registration should be returned');
+ return navigator.serviceWorker.register(
+ url, {scope: longer_matched_scope});
+ })
+ .then(function() {
+ return frame.contentWindow.navigator.serviceWorker.ready;
+ })
+ .then(function(r) {
+ assert_equals(r.scope, normalizeURL(matched_scope),
+ 'ready should only be resolved once');
+ return registration.unregister();
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, longer_matched_scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'access ready after it has been resolved');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/referer.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/referer.https.html
new file mode 100644
index 00000000000..9b3565329ec
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/referer.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Service Worker: check referer of fetch()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+async_test(function(t) {
+ var SCOPE = 'resources/referer-iframe.html';
+ var SCRIPT = 'resources/fetch-rewrite-worker.js';
+ var host_info = get_host_info();
+ service_worker_unregister_and_register(t, SCRIPT, SCOPE)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(SCOPE); })
+ .then(function(frame) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(function(e) {
+ assert_equals(e.data.results, 'finish');
+ frame.remove();
+ service_worker_unregister_and_done(t, SCOPE);
+ });
+ frame.contentWindow.postMessage({},
+ host_info['HTTPS_ORIGIN'],
+ [channel.port2]);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify the referer');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/register-closed-window.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/register-closed-window.https.html
new file mode 100644
index 00000000000..22135671625
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/register-closed-window.https.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Service Worker: Register() on Closed Window</title>
+<meta name=timeout content=long>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+
+var host_info = get_host_info();
+var frameURL = host_info['HTTPS_ORIGIN'] + base_path() +
+ 'resources/register-closed-window-iframe.html';
+
+async_test(function(t) {
+ var frame;
+ with_iframe(frameURL).then(function(f) {
+ frame = f;
+ return new Promise(function(resolve) {
+ window.addEventListener('message', function messageHandler(evt) {
+ window.removeEventListener('message', messageHandler);
+ resolve(evt.data);
+ });
+ frame.contentWindow.postMessage('START', '*');
+ });
+ }).then(function(result) {
+ assert_equals(result, 'OK', 'frame should complete without crashing');
+ frame.remove();
+ t.done();
+ }).catch(unreached_rejection(t));
+}, 'Call register() on ServiceWorkerContainer owned by closed window.');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/register-default-scope.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/register-default-scope.https.html
new file mode 100644
index 00000000000..dc136d4e8dd
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/register-default-scope.https.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<title>register() and scope</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var script_url = new URL(script, location.href);
+ var expected_scope = new URL('./', script_url).href;
+ return service_worker_unregister(t, expected_scope)
+ .then(function() {
+ return navigator.serviceWorker.register('resources/empty-worker.js');
+ }).then(function(registration) {
+ assert_equals(registration.scope, expected_scope,
+ 'The default scope should be URL("./", script_url)');
+ return registration.unregister();
+ }).then(function() {
+ t.done();
+ });
+ }, 'default scope');
+
+promise_test(function(t) {
+ // This script must be different than the 'default scope' test, or else
+ // the scopes will collide.
+ var script = 'resources/empty.js';
+ var script_url = new URL(script, location.href);
+ var expected_scope = new URL('./', script_url).href;
+ return service_worker_unregister(t, expected_scope)
+ .then(function() {
+ return navigator.serviceWorker.register('resources/empty.js',
+ { scope: undefined });
+ }).then(function(registration) {
+ assert_equals(registration.scope, expected_scope,
+ 'The default scope should be URL("./", script_url)');
+ return registration.unregister();
+ }).then(function() {
+ t.done();
+ });
+ }, 'undefined scope');
+
+promise_test(function(t) {
+ var script = 'resources/simple-fetch-worker.js';
+ var script_url = new URL(script, location.href);
+ var expected_scope = new URL('./', script_url).href;
+ return service_worker_unregister(t, expected_scope)
+ .then(function() {
+ return navigator.serviceWorker.register('resources/empty.js',
+ { scope: null });
+ })
+ .then(
+ function(registration) {
+ assert_unreached('register should fail');
+ service_worker_unregister_and_done(t, registration.scope);
+ },
+ function(error) {
+ assert_equals(error.name, 'SecurityError',
+ 'passing a null scope should be interpreted as ' +
+ 'scope="null" which violates the path restriction');
+ t.done();
+ });
+ }, 'null scope');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/register-same-scope-different-script-url.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/register-same-scope-different-script-url.https.html
new file mode 100644
index 00000000000..445be740951
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/register-same-scope-different-script-url.https.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var script1 = normalizeURL('resources/empty-worker.js');
+var script2 = normalizeURL('resources/empty-worker.js?new');
+
+async_test(function(t) {
+ var scope = 'resources/scope/register-new-script-concurrently';
+ var register_promise1;
+ var register_promise2;
+
+ service_worker_unregister(t, scope)
+ .then(function() {
+ register_promise1 = navigator.serviceWorker.register(script1,
+ {scope: scope});
+ register_promise2 = navigator.serviceWorker.register(script2,
+ {scope: scope});
+ return register_promise1;
+ })
+ .then(function(registration) {
+ assert_equals(registration.installing.scriptURL, script1,
+ 'on first register, first script should be installing');
+ assert_equals(registration.waiting, null,
+ 'on first register, waiting should be null');
+ assert_equals(registration.active, null,
+ 'on first register, active should be null');
+ return register_promise2;
+ })
+ .then(function(registration) {
+ assert_equals(
+ registration.installing.scriptURL, script2,
+ 'on second register, second script should be installing');
+ // Spec allows racing: the first register may have finished
+ // or the second one could have terminated the installing worker.
+ assert_true(registration.waiting == null ||
+ registration.waiting.scriptURL == script1,
+ 'on second register, .waiting should be null or the ' +
+ 'first script');
+ assert_true(registration.active == null ||
+ (registration.waiting == null &&
+ registration.active.scriptURL == script1),
+ 'on second register, .active should be null or the ' +
+ 'first script');
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register different scripts concurrently');
+
+async_test(function(t) {
+ var scope = 'resources/scope/register-then-register-new-script';
+ var registration;
+
+ service_worker_unregister_and_register(t, script1, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'on activated, installing should be null');
+ assert_equals(registration.waiting, null,
+ 'on activated, waiting should be null');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on activated, the first script should be active');
+ return navigator.serviceWorker.register(script2, {scope:scope});
+ })
+ .then(function(r) {
+ registration = r;
+ assert_equals(registration.installing.scriptURL, script2,
+ 'on second register, the second script should be ' +
+ 'installing');
+ assert_equals(registration.waiting, null,
+ 'on second register, waiting should be null');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on second register, the first script should be ' +
+ 'active');
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'on installed, installing should be null');
+ // Since the registration is not controlling any document, the new
+ // worker can immediately transition to active.
+ if (registration.waiting) {
+ assert_equals(registration.waiting.scriptURL, script2,
+ 'on installed, the second script may still be waiting');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on installed, the first script may be active');
+ } else {
+ assert_equals(registration.active.scriptURL, script2,
+ 'on installed, the second script may be active');
+ }
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register then register new script URL');
+
+async_test(function(t) {
+ var scope = 'resources/scope/register-then-register-new-script-404';
+ var registration;
+
+ service_worker_unregister_and_register(t, script1, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'on activated, installing should be null');
+ assert_equals(registration.waiting, null,
+ 'on activated, waiting should be null');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on activated, the first script should be active');
+ return navigator.serviceWorker.register('this-will-404.js',
+ {scope:scope});
+ })
+ .then(
+ function() { assert_unreached('register should reject'); },
+ function(error) {
+ assert_equals(registration.installing, null,
+ 'on rejected, installing should be null');
+ assert_equals(registration.waiting, null,
+ 'on rejected, waiting should be null');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on rejected, the first script should be active');
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register then register new script URL that 404s');
+
+async_test(function(t) {
+ var scope = 'resources/scope/register-then-register-new-script-reject-install';
+ var reject_script = normalizeURL('resources/reject-install-worker.js');
+ var registration;
+
+ service_worker_unregister_and_register(t, script1, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'on activated, installing should be null');
+ assert_equals(registration.waiting, null,
+ 'on activated, waiting should be null');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on activated, the first script should be active');
+ return navigator.serviceWorker.register(reject_script, {scope:scope});
+ })
+ .then(function(r) {
+ registration = r;
+ assert_equals(registration.installing.scriptURL, reject_script,
+ 'on update, the second script should be installing');
+ assert_equals(registration.waiting, null,
+ 'on update, waiting should be null');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on update, the first script should be active');
+ return wait_for_state(t, registration.installing, 'redundant');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'on redundant, installing should be null');
+ assert_equals(registration.waiting, null,
+ 'on redundant, waiting should be null');
+ assert_equals(registration.active.scriptURL, script1,
+ 'on redundant, the first script should be active');
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register then register new script that does not install');
+
+async_test(function(t) {
+ var scope = 'resources/scope/register-new-script-controller';
+ var iframe;
+ var registration;
+
+ service_worker_unregister_and_register(t, script1, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ iframe = frame;
+ return navigator.serviceWorker.register(script2, { scope: scope })
+ })
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ var sw_container = iframe.contentWindow.navigator.serviceWorker;
+ assert_equals(sw_container.controller.scriptURL, script1,
+ 'the old version should control the old doc');
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ var sw_container = frame.contentWindow.navigator.serviceWorker;
+ assert_equals(sw_container.controller.scriptURL, script1,
+ 'the old version should control a new doc');
+ var onactivated_promise = wait_for_state(t,
+ registration.waiting,
+ 'activated');
+ frame.remove();
+ iframe.remove();
+ return onactivated_promise;
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ var sw_container = frame.contentWindow.navigator.serviceWorker;
+ assert_equals(sw_container.controller.scriptURL, script2,
+ 'the new version should control a new doc');
+ frame.remove();
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register same-scope new script url effect on controller');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https.html
new file mode 100644
index 00000000000..348daccccdc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/register-wait-forever-in-install-worker.https.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Service Worker: Register wait-forever-in-install-worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var bad_script = 'resources/wait-forever-in-install-worker.js';
+ var good_script = 'resources/empty-worker.js';
+ var scope = 'resources/wait-forever-in-install-worker';
+ return navigator.serviceWorker.register(bad_script, {scope: scope})
+ .then(function(registration) {
+ assert_equals(registration.installing.scriptURL,
+ normalizeURL(bad_script));
+ return navigator.serviceWorker.register(good_script, {scope: scope});
+ })
+ .then(function(registration) {
+ assert_equals(registration.installing.scriptURL,
+ normalizeURL(good_script));
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'register worker that calls waitUntil with a promise that never ' +
+ 'resolves in oninstall');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/registration-end-to-end.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-end-to-end.https.html
new file mode 100644
index 00000000000..e92b6502f09
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-end-to-end.https.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<title>Service Worker: registration end-to-end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var t = async_test('Registration: end-to-end');
+t.step(function() {
+
+ var scope = 'resources/in-scope/';
+ var serviceWorkerStates = [];
+ var lastServiceWorkerState = '';
+ var receivedMessageFromPort = '';
+ var currentChangeCount = 0;
+
+ assert_true(navigator.serviceWorker instanceof ServiceWorkerContainer);
+ assert_equals(typeof navigator.serviceWorker.register, 'function');
+ assert_equals(typeof navigator.serviceWorker.getRegistration, 'function');
+
+ navigator.serviceWorker.oncurrentchange = function() {
+ ++currentChangeCount;
+ };
+
+ service_worker_unregister_and_register(
+ t, 'resources/end-to-end-worker.js', scope)
+ .then(onRegister)
+ .catch(unreached_rejection(t));
+
+ function sendMessagePort(worker, from) {
+ var messageChannel = new MessageChannel();
+ worker.postMessage({from:from, port:messageChannel.port2}, [messageChannel.port2]);
+ return messageChannel.port1;
+ }
+
+ function onRegister(registration) {
+ var sw = registration.installing;
+ serviceWorkerStates.push(sw.state);
+ lastServiceWorkerState = sw.state;
+
+ var sawMessage = new Promise(t.step_func(function(resolve) {
+ sendMessagePort(sw, 'registering doc').onmessage = t.step_func(function (e) {
+ receivedMessageFromPort = e.data;
+ resolve();
+ });
+ }));
+
+ var sawActive = new Promise(t.step_func(function(resolve) {
+ sw.onstatechange = t.step_func(function() {
+ serviceWorkerStates.push(sw.state);
+
+ switch (sw.state) {
+ case 'installed':
+ assert_equals(lastServiceWorkerState, 'installing');
+ break;
+ case 'activating':
+ assert_equals(lastServiceWorkerState, 'installed');
+ break;
+ case 'activated':
+ assert_equals(lastServiceWorkerState, 'activating');
+ break;
+ default:
+ // We won't see 'redundant' because onstatechange is
+ // overwritten before calling unregister.
+ assert_unreached('Unexpected state: ' + sw.state);
+ }
+
+ lastServiceWorkerState = sw.state;
+ if (sw.state === 'activated')
+ resolve();
+ });
+ }));
+
+ Promise.all([sawMessage, sawActive]).then(t.step_func(function() {
+ assert_array_equals(serviceWorkerStates,
+ ['installing', 'installed', 'activating', 'activated'],
+ 'Service worker should pass through all states');
+
+ assert_equals(currentChangeCount, 0,
+ 'Should not see current changes since document is out of scope');
+
+ assert_equals(receivedMessageFromPort, 'Ack for: registering doc');
+
+ var sawRedundant = new Promise(t.step_func(function(resolve) {
+ sw.onstatechange = t.step_func(function() {
+ assert_equals(sw.state, 'redundant');
+ resolve();
+ });
+ }));
+ registration.unregister();
+ sawRedundant.then(t.step_func(function() {
+ t.done();
+ }));
+ }));
+ }
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/registration-events.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-events.https.html
new file mode 100644
index 00000000000..972ce7410b9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-events.https.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Service Worker: registration events</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var t = async_test('Registration: events');
+t.step(function() {
+ var scope = 'resources/in-scope/';
+ service_worker_unregister_and_register(
+ t, 'resources/events-worker.js', scope)
+ .then(t.step_func(function(registration) {
+ onRegister(registration.installing);
+ }))
+ .catch(unreached_rejection(t));
+
+ function sendMessagePort(worker, from) {
+ var messageChannel = new MessageChannel();
+ worker.postMessage({from:from, port:messageChannel.port2}, [messageChannel.port2]);
+ return messageChannel.port1;
+ }
+
+ function onRegister(sw) {
+ sw.onstatechange = t.step_func(function() {
+ if (sw.state !== 'activated')
+ return;
+
+ sendMessagePort(sw, 'registering doc').onmessage = t.step_func(function (e) {
+ assert_array_equals(e.data.events,
+ ['install', 'activate'],
+ 'Worker should see install then activate events');
+ service_worker_unregister_and_done(t, scope);
+ });
+ });
+ }
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/registration-iframe.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-iframe.https.html
new file mode 100644
index 00000000000..fb60afe8497
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-iframe.https.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Service Worker: Registration for iframe</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+// Set script url and scope url relative to the calling frame's document's url.
+// Assert the implementation parses the urls against the calling frame's
+// document's url.
+async_test(function(t) {
+ var url = 'resources/blank.html';
+ var scope = 'resources/registration-for-iframe-from-calling-frame';
+ var parsed_scope = normalizeURL(scope);
+ var script = 'resources/empty-worker.js';
+ var parsed_script = normalizeURL(script);
+ var frame;
+ var registration;
+
+ service_worker_unregister(t, scope)
+ .then(function() { return with_iframe(url); })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.navigator.serviceWorker.register(
+ script,
+ { scope: scope });
+ })
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(
+ registration.scope, parsed_scope,
+ 'registration\'s scope must be the scope parsed against calling ' +
+ 'document\'s url');
+ assert_equals(
+ registration.active.scriptURL, parsed_script,
+ 'worker\'s script must be the url parsed against calling ' +
+ 'document\'s url');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Subframe\'s container\'s register method should use calling frame\'s ' +
+ 'document\'s url as a base url for parsing its script url and scope url ' +
+ '- normal case');
+
+// Set script url and scope url relative to the iframe's document's url.
+// Assert the implementation throws a NetworkError exception.
+async_test(function(t) {
+ var url = 'resources/blank.html';
+ var scope = 'registration-for-iframe-from-calling-frame';
+ var script = 'empty-worker.js';
+ var frame;
+ var registration;
+
+ service_worker_unregister(t, scope)
+ .then(function() { return with_iframe(url); })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.navigator.serviceWorker.register(
+ script,
+ { scope: scope });
+ })
+ .then(
+ function() {
+ assert_unreached('register() should reject');
+ },
+ function(e) {
+ assert_equals(e.name, 'TypeError');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Subframe\'s container\'s register method should use calling frame\'s ' +
+ 'document\'s url as a base url for parsing its script url and scope url ' +
+ '- error case');
+
+// Set the scope url to a non-subdirectory of the script url.
+// Assert the implementation throws a SecurityError exception.
+async_test(function(t) {
+ var url = 'resources/blank.html';
+ var scope = 'registration-for-iframe-from-calling-frame';
+ var script = 'resources/empty-worker.js';
+ var frame;
+ var registration;
+
+ service_worker_unregister(t, scope)
+ .then(function() { return with_iframe(url); })
+ .then(function(f) {
+ frame = f;
+ return frame.contentWindow.navigator.serviceWorker.register(
+ script,
+ { scope: scope });
+ })
+ .then(
+ function() {
+ assert_unreached('register() should reject');
+ },
+ function(e) {
+ assert_equals(e.name, 'SecurityError');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'A scope url should start with the given script url');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/registration-service-worker-attributes.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-service-worker-attributes.https.html
new file mode 100644
index 00000000000..a0dea5428db
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/registration-service-worker-attributes.https.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+async_test(function(t) {
+ var scope = 'resources/scope/installing-waiting-active-after-registration';
+ var worker_url = 'resources/empty-worker.js';
+ var expected_url = normalizeURL(worker_url);
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'installing before updatefound');
+ assert_equals(registration.waiting, null,
+ 'waiting before updatefound');
+ assert_equals(registration.active, null,
+ 'active before updatefound');
+ return wait_for_update(t, registration);
+ })
+ .then(function(worker) {
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'installing after updatefound');
+ assert_equals(registration.waiting, null,
+ 'waiting after updatefound');
+ assert_equals(registration.active, null,
+ 'active after updatefound');
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing after installed');
+ var newest = registration.waiting || registration.active;
+ assert_equals(newest.scriptURL, expected_url,
+ 'waiting or active after installed');
+ if (registration.waiting) {
+ return wait_for_state(t, registration.waiting, 'activated')
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing after activated');
+ assert_equals(registration.waiting, null,
+ 'waiting after activated');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active after activated');
+ });
+ }
+ })
+ .then(function() {
+ return Promise.all([
+ wait_for_state(t, registration.active, 'redundant'),
+ registration.unregister()
+ ]);
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing after redundant');
+ assert_equals(registration.waiting, null,
+ 'waiting after redundant');
+ // According to spec, Clear Registration runs Update State which is
+ // immediately followed by setting active to null, which means by the
+ // time the event loop turns and the Promise for statechange is
+ // resolved, this will be gone.
+ assert_equals(registration.active, null,
+ 'active should be null after redundant');
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'installing/waiting/active after registration');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/registration.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/registration.https.html
new file mode 100644
index 00000000000..ae9f85fb27c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/registration.https.html
@@ -0,0 +1,368 @@
+<!DOCTYPE html>
+<title>Service Worker: Registration</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var script = 'resources/registration-worker.js';
+ var scope = 'resources/registration/normal';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_true(registration instanceof ServiceWorkerRegistration,
+ 'Successfully registered.');
+ service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Registering normal scope');
+
+promise_test(function(t) {
+ var script = 'resources/registration-worker.js';
+ var scope = 'resources/registration/scope-with-fragment#ref';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_true(
+ registration instanceof ServiceWorkerRegistration,
+ 'Successfully registered.');
+ assert_equals(
+ registration.scope,
+ normalizeURL('resources/registration/scope-with-fragment'),
+ 'A fragment should be removed from scope')
+ service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Registering scope with fragment');
+
+promise_test(function(t) {
+ var script = 'resources/registration-worker.js';
+ var scope = 'resources/';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_true(registration instanceof ServiceWorkerRegistration,
+ 'Successfully registered.');
+ service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Registering same scope as the script directory');
+
+promise_test(function(t) {
+ var script = 'resources/registration-worker.js';
+ var scope = 'resources';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registering same scope as the script directory without the last ' +
+ 'slash should fail with SecurityError.');
+ }, 'Registering same scope as the script directory without the last slash');
+
+promise_test(function(t) {
+ var script = 'resources/registration-worker.js';
+ var scope = 'different-directory/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registration scope outside the script directory should fail ' +
+ 'with SecurityError.');
+ }, 'Registration scope outside the script directory');
+
+promise_test(function(t) {
+ var script = 'resources/registration-worker.js';
+ var scope = 'http://example.com/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registration scope outside domain should fail with SecurityError.');
+ }, 'Registering scope outside domain');
+
+promise_test(function(t) {
+ var script = 'http://example.com/worker.js';
+ var scope = 'http://example.com/scope/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registration script outside domain should fail with SecurityError.');
+ }, 'Registering script outside domain');
+
+promise_test(function(t) {
+ var script = 'resources/no-such-worker.js';
+ var scope = 'resources/scope/no-such-worker';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of non-existent script should fail.');
+ }, 'Registering non-existent script');
+
+promise_test(function(t) {
+ var script = 'resources/invalid-chunked-encoding.py';
+ var scope = 'resources/scope/invalid-chunked-encoding/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of invalid chunked encoding script should fail.');
+ }, 'Registering invalid chunked encoding script');
+
+promise_test(function(t) {
+ var script = 'resources/invalid-chunked-encoding-with-flush.py';
+ var scope = 'resources/scope/invalid-chunked-encoding-with-flush/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of invalid chunked encoding script should fail.');
+ }, 'Registering invalid chunked encoding script with flush');
+
+promise_test(function(t) {
+ var script = 'resources/mime-type-worker.py';
+ var scope = 'resources/scope/no-mime-type-worker/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registration of no MIME type script should fail.');
+ }, 'Registering script with no MIME type');
+
+promise_test(function(t) {
+ var script = 'resources/mime-type-worker.py?mime=text/plain';
+ var scope = 'resources/scope/bad-mime-type-worker/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registration of plain text script should fail.');
+ }, 'Registering script with bad MIME type');
+
+promise_test(function(t) {
+ var script = 'resources/redirect.py?Redirect=' +
+ encodeURIComponent('/resources/registration-worker.js');
+ var scope = 'resources/scope/redirect/';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registration of redirected script should fail.');
+ }, 'Registering redirected script');
+
+promise_test(function(t) {
+ var script = 'resources/malformed-worker.py?parse-error';
+ var scope = 'resources/scope/parse-error';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of script including parse error should fail.');
+ }, 'Registering script including parse error');
+
+promise_test(function(t) {
+ var script = 'resources/malformed-worker.py?undefined-error';
+ var scope = 'resources/scope/undefined-error';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of script including undefined error should fail.');
+ }, 'Registering script including undefined error');
+
+promise_test(function(t) {
+ var script = 'resources/malformed-worker.py?uncaught-exception';
+ var scope = 'resources/scope/uncaught-exception';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of script including uncaught exception should fail.');
+ }, 'Registering script including uncaught exception');
+
+promise_test(function(t) {
+ var script = 'resources/malformed-worker.py?caught-exception';
+ var scope = 'resources/scope/caught-exception';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_true(registration instanceof ServiceWorkerRegistration,
+ 'Successfully registered.');
+ service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Registering script including caught exception');
+
+promise_test(function(t) {
+ var script = 'resources/malformed-worker.py?import-malformed-script';
+ var scope = 'resources/scope/import-malformed-script';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of script importing malformed script should fail.');
+ }, 'Registering script importing malformed script');
+
+promise_test(function(t) {
+ var script = 'resources/malformed-worker.py?import-no-such-script';
+ var scope = 'resources/scope/import-no-such-script';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'Registration of script importing non-existent script should fail.');
+ }, 'Registering script importing non-existent script');
+
+promise_test(function(t) {
+ // URL-encoded full-width 'scope'.
+ var name = '%ef%bd%93%ef%bd%83%ef%bd%8f%ef%bd%90%ef%bd%85';
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/' + name + '/escaped-multibyte-character-scope';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_equals(
+ registration.scope,
+ normalizeURL(scope),
+ 'URL-encoded multibyte characters should be available.');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Scope including URL-encoded multibyte characters');
+
+promise_test(function(t) {
+ // Non-URL-encoded full-width "scope".
+ var name = String.fromCodePoint(0xff53, 0xff43, 0xff4f, 0xff50, 0xff45);
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/' + name + '/non-escaped-multibyte-character-scope';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_equals(
+ registration.scope,
+ normalizeURL(scope),
+ 'Non-URL-encoded multibyte characters should be available.');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Scope including non-escaped multibyte characters');
+
+promise_test(function(t) {
+ var script = 'resources%2fempty-worker.js';
+ var scope = 'resources/scope/encoded-slash-in-script-url';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'URL-encoded slash in the script URL should be rejected.');
+ }, 'Script URL including URL-encoded slash');
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/scope%2fencoded-slash-in-scope';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'URL-encoded slash in the scope should be rejected.');
+ }, 'Scope including URL-encoded slash');
+
+promise_test(function(t) {
+ var script = 'resources%5cempty-worker.js';
+ var scope = 'resources/scope/encoded-slash-in-script-url';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'URL-encoded backslash in the script URL should be rejected.');
+ }, 'Script URL including URL-encoded backslash');
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/scope%5cencoded-slash-in-scope';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ new TypeError(),
+ 'URL-encoded backslash in the scope should be rejected.');
+ }, 'Scope including URL-encoded backslash');
+
+promise_test(function(t) {
+ var script = 'resources/././empty-worker.js';
+ var scope = 'resources/scope/parent-reference-in-script-url';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_equals(
+ registration.installing.scriptURL,
+ normalizeURL('resources/empty-worker.js'),
+ 'Script URL including self-reference should be normalized.');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Script URL including self-reference');
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/././scope/self-reference-in-scope';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_equals(
+ registration.scope,
+ normalizeURL('resources/scope/self-reference-in-scope'),
+ 'Scope including self-reference should be normalized.');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Scope including self-reference');
+
+promise_test(function(t) {
+ var script = 'resources/../resources/empty-worker.js';
+ var scope = 'resources/scope/parent-reference-in-script-url';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_equals(
+ registration.installing.scriptURL,
+ normalizeURL('resources/empty-worker.js'),
+ 'Script URL including parent-reference should be normalized.');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Script URL including parent-reference');
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/../resources/scope/parent-reference-in-scope';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ assert_equals(
+ registration.scope,
+ normalizeURL('resources/scope/parent-reference-in-scope'),
+ 'Scope including parent-reference should be normalized.');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Scope including parent-reference');
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/../scope/parent-reference-in-scope';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Scope not under the script directory should be rejected.');
+ }, 'Scope including parent-reference and not under the script directory');
+
+promise_test(function(t) {
+ var script = 'resources////empty-worker.js';
+ var scope = 'resources/scope/consecutive-slashes-in-script-url';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Consecutive slashes in the script url should not be unified.');
+ }, 'Script URL including consecutive slashes');
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'resources/scope////consecutive-slashes-in-scope';
+ return navigator.serviceWorker.register(script, {scope: scope})
+ .then(function(registration) {
+ // Although consecutive slashes in the scope are not unified, the
+ // scope is under the script directory and registration should
+ // succeed.
+ assert_equals(
+ registration.scope,
+ normalizeURL(scope),
+ 'Should successfully be registered.');
+ service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Scope including consecutive slashes');
+
+promise_test(function(t) {
+ var script = 'filesystem:' + normalizeURL('resources/empty-worker.js');
+ var scope = 'resources/scope/filesystem-script-url';
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registering a script which has same-origin filesystem: URL should ' +
+ 'fail with SecurityError.');
+ }, 'Script URL is same-origin filesystem: URL');
+
+promise_test(function(t) {
+ var script = 'resources/empty-worker.js';
+ var scope = 'filesystem:' + normalizeURL('resources/scope/filesystem-scope-url');
+ return assert_promise_rejects(
+ navigator.serviceWorker.register(script, {scope: scope}),
+ 'SecurityError',
+ 'Registering with the scope that has same-origin filesystem: URL ' +
+ 'should fail with SecurityError.');
+ }, 'Scope URL is same-origin filesystem: URL');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/rejections.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/rejections.https.html
new file mode 100644
index 00000000000..8002ad9a81b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/rejections.https.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>Service Worker: Rejection Types</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+(function() {
+ var t = async_test('Rejections are DOMExceptions');
+ t.step(function() {
+
+ navigator.serviceWorker.register('http://example.com').then(
+ t.step_func(function() { assert_unreached('Registration should fail'); }),
+ t.step_func(function(reason) {
+ assert_true(reason instanceof DOMException);
+ assert_true(reason instanceof Error);
+ t.done();
+ }));
+ });
+}());
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/request-end-to-end.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/request-end-to-end.https.html
new file mode 100644
index 00000000000..c9c3b30464b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/request-end-to-end.https.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>Service Worker: Request end-to-end</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var t = async_test('Request: end-to-end');
+t.step(function() {
+ var url = 'resources/request-end-to-end-worker.js';
+ var scope = 'resources/blank.html';
+ var frames = [];
+
+ service_worker_unregister_and_register(t, url, scope)
+ .then(onRegister)
+ .catch(unreached_rejection(t));
+
+ function sendMessagePort(worker) {
+ var messageChannel = new MessageChannel();
+ worker.postMessage({port:messageChannel.port2}, [messageChannel.port2]);
+ return messageChannel.port1;
+ }
+
+ function onRegister(registration) {
+ var sw = registration.installing;
+ var port = sendMessagePort(sw);
+ port.addEventListener('message', t.step_func(function(event) {
+ onMessage(event);
+ }), false);
+ port.start();
+ sw.addEventListener('statechange', t.step_func(function(event) {
+ if (event.target.state == 'activated')
+ onActive();
+ }));
+ }
+
+ function onActive() {
+ with_iframe(scope).then(function(f) { frames.push(f); });
+ }
+
+ function onMessage(event) {
+ assert_equals(
+ event.data.url,
+ location.href.substring(0, location.href.lastIndexOf('/') + 1) +
+ scope,
+ 'request.url should be passed to onfetch event.');
+ assert_equals(event.data.mode, 'navigate',
+ 'request.mode should be passed to onfetch event.');
+ assert_equals(event.data.method, 'GET',
+ 'request.method should be passed to onfetch event.');
+ assert_equals(event.data.referrer, location.href,
+ 'request.referrer should be passed to onfetch event.');
+ assert_equals(event.data.headers['user-agent'], undefined,
+ 'Default User-Agent header should not be passed to onfetch event.')
+ assert_equals(event.data.errorNameWhileAppendingHeader, 'TypeError',
+ 'Appending a new header to the request must throw a ' +
+ 'TypeError.')
+ frames.forEach(function(f) { f.remove(); });
+ service_worker_unregister_and_done(t, scope);
+ }
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resource-timing.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resource-timing.https.html
new file mode 100644
index 00000000000..f33c41d715e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resource-timing.https.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+function resourceUrl(path) {
+ return get_host_info()['HTTP_ORIGIN'] + base_path() + path;
+}
+
+function verify(performance, resource, description) {
+ var entry = performance.getEntriesByName(resourceUrl(resource))[0];
+ assert_greater_than(entry.workerStart, 0, description);
+ assert_greater_than_equal(entry.workerStart, entry.startTime, description);
+ assert_less_than_equal(entry.workerStart, entry.fetchStart, description);
+ if (resource.indexOf('redirect.py') != -1) {
+ assert_less_than_equal(entry.workerStart, entry.redirectStart,
+ description);
+ } else {
+ assert_equals(entry.redirectStart, 0, description);
+ }
+}
+
+async_test(function(t) {
+ var worker_url = 'resources/resource-timing-worker.js';
+ var scope = 'resources/resource-timing-iframe.html';
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ var performance = frame.contentWindow.performance;
+ verify(performance, 'resources/dummy.js', 'Generated response');
+ verify(performance, 'resources/empty.js', 'Network fallback');
+ verify(performance, 'resources/redirect.py?Redirect=empty.js',
+ 'Redirect');
+ frame.remove();
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+}, 'Controlled resource loads');
+
+test(function() {
+ var url = resourceUrl('resources/test-helpers.sub.js');
+ var entry = window.performance.getEntriesByName(url)[0];
+ assert_equals(entry.workerStart, 0, 'Non-controlled');
+}, 'Non-controlled resource loads');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/404.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/404.py
new file mode 100644
index 00000000000..235a3d4ff0e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/404.py
@@ -0,0 +1,5 @@
+# iframe does not fire onload event if the response's content-type is not
+# text/plain or text/html so this script exists if you want to test a 404 load
+# in an iframe.
+def main(req, res):
+ return 404, [('Content-Type', 'text/plain')], "Page not found"
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.install.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.install.html
new file mode 100644
index 00000000000..428ad92c782
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.install.html
@@ -0,0 +1,26 @@
+<html manifest="appcache-ordering.manifest">
+<script>
+var handled = false;
+
+function installComplete() {
+ if (handled)
+ return;
+ handled = true;
+ window.parent.notify_appcache_installed(true);
+}
+
+function installFailed() {
+ if (handled)
+ return;
+ handled = true;
+ window.parent.notify_appcache_installed(false);
+}
+
+applicationCache.oncached = installComplete;
+applicationCache.onnoupdate = installComplete;
+applicationCache.onupdateready = installFailed;
+applicationCache.onerror = installFailed;
+applicationCache.onobsolete = installFailed;
+
+</script>
+</html>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.html
new file mode 100644
index 00000000000..485ab177197
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.html
@@ -0,0 +1,13 @@
+<html> <!-- Intentionally does NOT include a manifest attribute -->
+<body>
+<!-- This should FALLBACK to ordering.is_appcached.js as specified in manifest
+ when the appcache is present -->
+<script src="appcache-ordering.is-appcached404.js"></script>
+<script>
+
+// If the script of the fallback resource loaded, is_appcached will be defined.
+window.parent.notify_is_appcached(typeof is_appcached != 'undefined');
+
+</script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.js
new file mode 100644
index 00000000000..a562b6f1c3c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.is-appcached.js
@@ -0,0 +1 @@
+var is_appcached = true;
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.manifest b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.manifest
new file mode 100644
index 00000000000..0deed0e91a8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/appcache-ordering.manifest
@@ -0,0 +1,7 @@
+CACHE MANIFEST
+
+appcache-ordering.is-appcached.html
+
+FALLBACK:
+appcache-ordering.is-appcached404.js appcache-ordering.is-appcached.js
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/blank.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/blank.html
new file mode 100644
index 00000000000..a3c3a4689a6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/blank.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<title>Empty doc</title>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/claim-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/claim-worker.js
new file mode 100644
index 00000000000..317feb1a02d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/claim-worker.js
@@ -0,0 +1,14 @@
+self.addEventListener('message', function(event) {
+ self.clients.claim()
+ .then(function(result) {
+ if (result !== undefined) {
+ event.data.port.postMessage(
+ 'FAIL: claim() should be resolved with undefined');
+ return;
+ }
+ event.data.port.postMessage('PASS');
+ })
+ .catch(function(error) {
+ event.data.port.postMessage('FAIL: exception: ' + error.name);
+ });
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-frame.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-frame.html
new file mode 100644
index 00000000000..27143d4b99b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-frame.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script>
+
+ fetch("clientId")
+ .then(function(response) {
+ return response.text();
+ })
+ .then(function(text) {
+ parent.postMessage({clientId: text}, "*");
+ });
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-other-origin.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-other-origin.html
new file mode 100644
index 00000000000..cbd3dcc6f3b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-other-origin.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<script src="get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js"></script>
+<script>
+var host_info = get_host_info();
+var SCOPE = 'blank.html?clients-get';
+var SCRIPT = 'clients-get-worker.js';
+
+var registration;
+var worker;
+var wait_for_worker_promise = navigator.serviceWorker.getRegistration(SCOPE)
+ .then(function(reg) {
+ if (reg)
+ return reg.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(SCRIPT, {scope: SCOPE});
+ })
+ .then(function(reg) {
+ registration = reg;
+ worker = reg.installing;
+ return new Promise(function(resolve) {
+ worker.addEventListener('statechange', function() {
+ if (worker.state == 'activated')
+ resolve();
+ });
+ });
+ });
+
+function send_result(result) {
+ window.parent.postMessage(
+ {result: result},
+ host_info['HTTPS_ORIGIN']);
+}
+
+window.addEventListener("message", on_message, false);
+
+function on_message(e) {
+ if (e.origin != host_info['HTTPS_ORIGIN']) {
+ console.error('invalid origin: ' + e.origin);
+ return;
+ }
+ if (e.data.message == 'get_client_id') {
+ var otherOriginClientId = e.data.clientId;
+ wait_for_worker_promise
+ .then(function() {
+ return with_iframe(SCOPE);
+ })
+ .then(function(iframe) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(e) {
+ navigator.serviceWorker.getRegistration(SCOPE)
+ .then(function(reg) {
+ reg.unregister();
+ send_result(e.data);
+ });
+ };
+ iframe.contentWindow.navigator.serviceWorker.controller.postMessage(
+ {port:channel.port2, clientId: otherOriginClientId,
+ message: 'get_other_client_id'}, [channel.port2]);
+ })
+ }
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js
new file mode 100644
index 00000000000..9ac2c226458
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-get-worker.js
@@ -0,0 +1,53 @@
+self.onfetch = function(e) {
+ if (e.request.url.indexOf("clients-get-frame.html") >= 0) {
+ if (e.clientId === null) {
+ e.respondWith(fetch(e.request));
+ } else {
+ e.respondWith(Response.error());
+ }
+ return;
+ }
+ e.respondWith(new Response(e.clientId));
+};
+
+self.onmessage = function(e) {
+ var port = e.data.port;
+ if (e.data.message == 'get_client_ids') {
+ var clientIds = e.data.clientIds;
+ var message = [];
+
+ Promise.all(
+ clientIds.map(function(clientId) {
+ return self.clients.get(clientId);
+ }).concat(self.clients.get("invalid-id"))
+ ).then(function(clients) {
+ clients.forEach(function(client) {
+ if (client instanceof Client) {
+ message.push([client.visibilityState,
+ client.focused,
+ client.url,
+ client.frameType]);
+ } else {
+ message.push(client);
+ }
+ });
+ port.postMessage(message);
+ });
+ } else if (e.data.message == 'get_other_client_id') {
+ var clientId = e.data.clientId;
+ var message;
+
+ self.clients.get(clientId)
+ .then(function(client) {
+ if (client instanceof Client) {
+ message = [client.visibilityState,
+ client.focused,
+ client.url,
+ client.frameType];
+ } else {
+ message = client;
+ }
+ port.postMessage(message);
+ });
+ }
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html
new file mode 100644
index 00000000000..51b4dca0314
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-iframe.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>Empty doc</title>
+<!--
+ Change the page URL using the History API to ensure that ServiceWorkerClient
+ uses the creation URL.
+-->
+<body onload="history.pushState({}, 'title', 'new-url.html')">
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js
new file mode 100644
index 00000000000..1ae72fb8944
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-client-types-shared-worker.js
@@ -0,0 +1,4 @@
+onconnect = function(e) {
+ var port = e.ports[0];
+ port.postMessage('started');
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-worker.js
new file mode 100644
index 00000000000..f0ae90d8142
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/clients-matchall-worker.js
@@ -0,0 +1,24 @@
+self.onmessage = function(e) {
+ var port = e.data.port;
+ var options = e.data.options;
+
+ self.clients.matchAll(options).then(function(clients) {
+ var message = [];
+ clients.forEach(function(client) {
+ var frame_type = client.frameType;
+ if (client.url.indexOf('clients-matchall-include-uncontrolled.https.html') > -1 &&
+ client.frameType == 'auxiliary') {
+ // The test tab might be opened using window.open() by the test framework.
+ // In that case, just pretend it's top-level!
+ frame_type = 'top-level';
+ }
+ message.push([client.visibilityState,
+ client.focused,
+ client.url,
+ frame_type]);
+ });
+ // Sort by url
+ message.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
+ port.postMessage(message);
+ });
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js
new file mode 100644
index 00000000000..82b24459b4f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-shared-worker-interceptor.js
@@ -0,0 +1,7 @@
+var worker_text = 'onconnect = function(e) { e.ports[0].postMessage("worker loading intercepted by service worker"); };';
+
+self.onfetch = function(event) {
+ if (event.request.url.indexOf('dummy-shared-worker.js') != -1)
+ event.respondWith(new Response(worker_text));
+};
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-interceptor.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-interceptor.js
new file mode 100644
index 00000000000..43244e1d993
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-interceptor.js
@@ -0,0 +1,21 @@
+importScripts('get-host-info.sub.js');
+
+var worker_text = 'postMessage("worker loading intercepted by service worker"); ';
+
+self.onfetch = function(event) {
+ if (event.request.url.indexOf('synthesized') != -1) {
+ event.respondWith(new Response(worker_text));
+ } else if (event.request.url.indexOf('same-origin') != -1) {
+ event.respondWith(fetch('dummy-worker-script.py'));
+ } else if (event.request.url.indexOf('cors') != -1) {
+ var path = (new URL('dummy-worker-script.py', self.location)).pathname;
+ var url = get_host_info()['HTTPS_REMOTE_ORIGIN'] + path;
+ var mode = "no-cors";
+ if (event.request.url.indexOf('no-cors') == -1) {
+ url += '?ACAOrigin=*';
+ mode = "cors";
+ }
+ event.respondWith(fetch(url, { mode: mode }));
+ }
+};
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-script.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-script.py
new file mode 100644
index 00000000000..6f40b5ed605
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy-worker-script.py
@@ -0,0 +1,9 @@
+def main(request, response):
+ headers = []
+
+ if "ACAOrigin" in request.GET:
+ for item in request.GET["ACAOrigin"].split(","):
+ headers.append(("Access-Control-Allow-Origin", item))
+
+ return headers, "postMessage('dummy-worker-script loaded');"
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.html
new file mode 100644
index 00000000000..12a179980df
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<body>Hello world
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.txt b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.txt
new file mode 100644
index 00000000000..802992c4220
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/dummy.txt
@@ -0,0 +1 @@
+Hello world
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/empty-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/empty-worker.js
new file mode 100644
index 00000000000..49ceb2648a9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/empty-worker.js
@@ -0,0 +1 @@
+// Do nothing.
diff --git a/tests/wpt/mozilla/meta/mozilla/windowproxy.html.ini b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/empty.js
index e69de29bb2d..e69de29bb2d 100644
--- a/tests/wpt/mozilla/meta/mozilla/windowproxy.html.ini
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/empty.js
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/end-to-end-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/end-to-end-worker.js
new file mode 100644
index 00000000000..d45a50556a9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/end-to-end-worker.js
@@ -0,0 +1,7 @@
+onmessage = function(e) {
+ var message = e.data;
+ if (typeof message === 'object' && 'port' in message) {
+ var response = 'Ack for: ' + message.from;
+ message.port.postMessage(response);
+ }
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/events-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/events-worker.js
new file mode 100644
index 00000000000..80a2188677b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/events-worker.js
@@ -0,0 +1,12 @@
+var eventsSeen = [];
+
+function handler(event) { eventsSeen.push(event.type); }
+
+['activate', 'install'].forEach(function(type) {
+ self.addEventListener(type, handler);
+ });
+
+onmessage = function(e) {
+ var message = e.data;
+ message.port.postMessage({events: eventsSeen});
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js
new file mode 100644
index 00000000000..d77238d9397
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-async-waituntil.js
@@ -0,0 +1,20 @@
+var result = 'FAIL: did not throw.';
+
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage(result);
+ });
+
+self.addEventListener('install', function(event) {
+ self.installEvent = event;
+ });
+
+self.addEventListener('activate', function(event) {
+ try {
+ self.installEvent.waitUntil(new Promise(function(){}));
+ } catch (error) {
+ if (error.name == 'InvalidStateError')
+ result = 'PASS';
+ else
+ result = 'FAIL: unexpected exception: ' + error;
+ }
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-waituntil.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-waituntil.js
new file mode 100644
index 00000000000..48fdf1b99fd
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/extendable-event-waituntil.js
@@ -0,0 +1,75 @@
+var pendingPorts = [];
+var portResolves = [];
+
+onmessage = function(e) {
+ var message = e.data;
+ if ('port' in message) {
+ var resolve = self.portResolves.shift();
+ if (resolve)
+ resolve(message.port);
+ else
+ self.pendingPorts.push(message.port);
+ }
+};
+
+function fulfillPromise() {
+ return new Promise(function(resolve) {
+ // Make sure the oninstall/onactivate callback returns first.
+ Promise.resolve().then(function() {
+ var port = self.pendingPorts.shift();
+ if (port)
+ resolve(port);
+ else
+ self.portResolves.push(resolve);
+ });
+ }).then(function(port) {
+ port.postMessage('SYNC');
+ return new Promise(function(resolve) {
+ port.onmessage = function(e) {
+ if (e.data == 'ACK')
+ resolve();
+ };
+ });
+ });
+}
+
+function rejectPromise() {
+ return new Promise(function(resolve, reject) {
+ // Make sure the oninstall/onactivate callback returns first.
+ Promise.resolve().then(reject);
+ });
+}
+
+function stripScopeName(url) {
+ return url.split('/').slice(-1)[0];
+}
+
+oninstall = function(e) {
+ switch (stripScopeName(self.location.href)) {
+ case 'install-fulfilled':
+ e.waitUntil(fulfillPromise());
+ break;
+ case 'install-rejected':
+ e.waitUntil(rejectPromise());
+ break;
+ case 'install-multiple-fulfilled':
+ e.waitUntil(fulfillPromise());
+ e.waitUntil(fulfillPromise());
+ break;
+ case 'install-reject-precedence':
+ e.waitUntil(fulfillPromise());
+ e.waitUntil(rejectPromise());
+ break;
+ }
+};
+
+onactivate = function(e) {
+ switch (stripScopeName(self.location.href)) {
+ case 'activate-fulfilled':
+ e.waitUntil(fulfillPromise());
+ break;
+ case 'activate-rejected':
+ e.waitUntil(rejectPromise());
+ break;
+ }
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fail-on-fetch-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fail-on-fetch-worker.js
new file mode 100644
index 00000000000..517f289fbc8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fail-on-fetch-worker.js
@@ -0,0 +1,5 @@
+importScripts('worker-testharness.js');
+
+this.addEventListener('fetch', function(event) {
+ event.respondWith(new Response('ERROR'));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control-login.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control-login.html
new file mode 100644
index 00000000000..0ffab1af598
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control-login.html
@@ -0,0 +1,16 @@
+<script>
+// Set authentication info
+window.addEventListener("message", function(evt) {
+ var port = evt.ports[0];
+ document.cookie = 'cookie=' + evt.data.cookie;
+ var xhr = new XMLHttpRequest();
+ xhr.addEventListener('load', function() {
+ port.postMessage({msg: 'LOGIN FINISHED'});
+ }, false);
+ xhr.open('GET',
+ './fetch-access-control.py?Auth',
+ true,
+ evt.data.username, evt.data.password);
+ xhr.send();
+ }, false);
+</script> \ No newline at end of file
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py
new file mode 100644
index 00000000000..862718ad03f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-access-control.py
@@ -0,0 +1,69 @@
+import base64
+import json
+
+def main(request, response):
+ headers = []
+ headers.append(('X-ServiceWorker-ServerHeader', 'SetInTheServer'))
+
+ if "ACAOrigin" in request.GET:
+ for item in request.GET["ACAOrigin"].split(","):
+ headers.append(("Access-Control-Allow-Origin", item))
+
+ for suffix in ["Headers", "Methods", "Credentials"]:
+ query = "ACA%s" % suffix
+ header = "Access-Control-Allow-%s" % suffix
+ if query in request.GET:
+ headers.append((header, request.GET[query]))
+
+ if "ACEHeaders" in request.GET:
+ headers.append(("Access-Control-Expose-Headers", request.GET[query]))
+
+ if ("Auth" in request.GET and not request.auth.username) or "AuthFail" in request.GET:
+ status = 401
+ headers.append(('WWW-Authenticate', 'Basic realm="Restricted"'))
+ body = 'Authentication canceled'
+ return status, headers, body
+
+ if "PNGIMAGE" in request.GET:
+ headers.append(("Content-Type", "image/png"))
+ body = base64.decodestring("iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1B"
+ "AACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAhSURBVDhPY3wro/KfgQLABKXJBqMG"
+ "jBoAAqMGDLwBDAwAEsoCTFWunmQAAAAASUVORK5CYII=")
+ return headers, body
+
+
+ username = request.auth.username if request.auth.username else "undefined"
+ password = request.auth.password if request.auth.username else "undefined"
+ cookie = request.cookies['cookie'].value if 'cookie' in request.cookies else "undefined"
+
+ files = []
+ for key, values in request.POST.iteritems():
+ assert len(values) == 1
+ value = values[0]
+ if not hasattr(value, "file"):
+ continue
+ data = value.file.read()
+ files.append({"key": key,
+ "name": value.file.name,
+ "type": value.type,
+ "error": 0, #TODO,
+ "size": len(data),
+ "content": data})
+
+ get_data = {key:request.GET[key] for key,value in request.GET.iteritems()}
+ post_data = {key:request.POST[key] for key,value in request.POST.iteritems()
+ if not hasattr(request.POST[key], "file")}
+ headers_data = {key:request.headers[key] for key,value in request.headers.iteritems()}
+
+ data = {"jsonpResult": "success",
+ "method": request.method,
+ "headers": headers_data,
+ "body": request.body,
+ "files": files,
+ "GET": get_data,
+ "POST": post_data,
+ "username": username,
+ "password": password,
+ "cookie": cookie}
+
+ return headers, "report( %s )" % json.dumps(data)
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html
new file mode 100644
index 00000000000..0bd6b6f07c3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-canvas-tainting-iframe.html
@@ -0,0 +1,277 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var image_path = base_path() + 'fetch-access-control.py?PNGIMAGE';
+var host_info = get_host_info();
+var params = get_query_params(location.href);
+
+var NOT_TAINTED = 'NOT_TAINTED';
+var TAINTED = 'TAINTED';
+var LOAD_ERROR = 'LOAD_ERROR';
+
+function get_query_params(url) {
+ var search = (new URL(url)).search;
+ if (!search) {
+ return {};
+ }
+ var ret = {};
+ var params = search.substring(1).split('&');
+ params.forEach(function(param) {
+ var element = param.split('=');
+ ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]);
+ });
+ return ret;
+}
+
+function create_test_case_promise(url, cross_origin) {
+ return new Promise(function(resolve) {
+ var img = new Image();
+ if (cross_origin != '') {
+ img.crossOrigin = cross_origin;
+ }
+ img.onload = function() {
+ try {
+ var canvas = document.createElement('canvas');
+ canvas.width = 100;
+ canvas.height = 100;
+ var context = canvas.getContext('2d');
+ context.drawImage(img, 0, 0);
+ context.getImageData(0, 0, 100, 100);
+ resolve(NOT_TAINTED);
+ } catch (e) {
+ resolve(TAINTED);
+ }
+ };
+ img.onerror = function() {
+ resolve(LOAD_ERROR);
+ }
+ img.src = url;
+ });
+}
+
+function create_test_promise(url, cross_origin, expected_result) {
+ if (params['cache']) {
+ url += "&cache";
+ }
+
+ return new Promise(function(resolve, reject) {
+ create_test_case_promise(url, cross_origin)
+ .then(function(result) {
+ if (result == expected_result) {
+ resolve();
+ } else {
+ reject('Result of url:' + url + ' ' +
+ ' cross_origin: ' + cross_origin + ' must be ' +
+ expected_result + ' but ' + result);
+ }
+ })
+ });
+}
+
+window.addEventListener('message', function(evt) {
+ var port = evt.ports[0];
+ var image_url = host_info['HTTPS_ORIGIN'] + image_path;
+ var remote_image_url = host_info['HTTPS_REMOTE_ORIGIN'] + image_path;
+ Promise.all([
+ // Reject tests
+ create_test_promise(image_url + '&reject', '', LOAD_ERROR),
+ create_test_promise(image_url + '&reject', 'anonymous', LOAD_ERROR),
+ create_test_promise(
+ image_url + '&reject', 'use-credentials', LOAD_ERROR),
+ // Fallback tests
+ create_test_promise(
+ image_url + '&ignore',
+ '',
+ NOT_TAINTED),
+ create_test_promise(
+ remote_image_url + '&ignore',
+ '',
+ TAINTED),
+ create_test_promise(
+ remote_image_url + '&ignore',
+ 'anonymous',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] +
+ '&ignore',
+ 'anonymous',
+ NOT_TAINTED),
+ create_test_promise(
+ remote_image_url + '&ignore',
+ 'use-credentials',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] +
+ '&ignore',
+ 'use-credentials',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url + '&ACAOrigin=' + host_info['HTTPS_ORIGIN'] +
+ '&ACACredentials=true&ignore',
+ 'use-credentials',
+ NOT_TAINTED),
+
+ // Credential test (fallback)
+ create_test_promise(
+ image_url + '&Auth&ignore',
+ '',
+ NOT_TAINTED),
+ create_test_promise(
+ remote_image_url + '&Auth&ignore',
+ '',
+ TAINTED),
+ create_test_promise(
+ remote_image_url + '&Auth&ignore',
+ 'anonymous',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url + '&Auth&ignore',
+ 'use-credentials',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] +
+ '&ignore',
+ 'use-credentials',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url + '&Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] +
+ '&ACACredentials=true&ignore',
+ 'use-credentials',
+ NOT_TAINTED),
+
+ // Basic response
+ create_test_promise(
+ image_url +
+ '&mode=same-origin&url=' + encodeURIComponent(image_url),
+ '',
+ NOT_TAINTED),
+ create_test_promise(
+ image_url +
+ '&mode=same-origin&url=' + encodeURIComponent(image_url),
+ 'anonymous',
+ NOT_TAINTED),
+ create_test_promise(
+ image_url +
+ '&mode=same-origin&url=' + encodeURIComponent(image_url),
+ 'use-credentials',
+ NOT_TAINTED),
+ create_test_promise(
+ remote_image_url +
+ '&mode=same-origin&url=' + encodeURIComponent(image_url),
+ '',
+ TAINTED),
+ create_test_promise(
+ remote_image_url +
+ '&mode=same-origin&url=' + encodeURIComponent(image_url),
+ 'anonymous',
+ NOT_TAINTED),
+ create_test_promise(
+ remote_image_url +
+ '&mode=same-origin&url=' + encodeURIComponent(image_url),
+ 'use-credentials',
+ NOT_TAINTED),
+
+ // Opaque response
+ create_test_promise(
+ image_url +
+ '&mode=no-cors&url=' + encodeURIComponent(remote_image_url),
+ '',
+ TAINTED),
+ create_test_promise(
+ image_url +
+ '&mode=no-cors&url=' + encodeURIComponent(remote_image_url),
+ 'anonymous',
+ LOAD_ERROR),
+ create_test_promise(
+ image_url +
+ '&mode=no-cors&url=' + encodeURIComponent(remote_image_url),
+ 'use-credentials',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url +
+ '&mode=no-cors&url=' + encodeURIComponent(remote_image_url),
+ '',
+ TAINTED),
+ create_test_promise(
+ remote_image_url +
+ '&mode=no-cors&url=' + encodeURIComponent(remote_image_url),
+ 'anonymous',
+ LOAD_ERROR),
+ create_test_promise(
+ remote_image_url +
+ '&mode=no-cors&url=' + encodeURIComponent(remote_image_url),
+ 'use-credentials',
+ LOAD_ERROR),
+
+ // CORS response
+ create_test_promise(
+ image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(remote_image_url +
+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ '',
+ NOT_TAINTED),
+ create_test_promise(
+ image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(remote_image_url +
+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ 'anonymous',
+ NOT_TAINTED),
+ create_test_promise(
+ image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(remote_image_url +
+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ 'use-credentials',
+ LOAD_ERROR), // We expect LOAD_ERROR since the server doesn't respond
+ // with an Access-Control-Allow-Credentials header.
+ create_test_promise(
+ image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(
+ remote_image_url +
+ '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ 'use-credentials',
+ NOT_TAINTED),
+ create_test_promise(
+ remote_image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(remote_image_url +
+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ '',
+ TAINTED), // We expect TAINTED since the default origin behavior here
+ // is taint, and it doesn't matter what kind of fetch the
+ // SW performs.
+ create_test_promise(
+ remote_image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(remote_image_url +
+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ 'anonymous',
+ NOT_TAINTED),
+ create_test_promise(
+ remote_image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(remote_image_url +
+ '&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ 'use-credentials',
+ LOAD_ERROR), // We expect LOAD_ERROR since the server doesn't respond
+ // with an Access-Control-Allow-Credentials header.
+ create_test_promise(
+ remote_image_url +
+ '&mode=cors&url=' +
+ encodeURIComponent(
+ remote_image_url +
+ '&ACACredentials=true&ACAOrigin=' + host_info['HTTPS_ORIGIN']),
+ 'use-credentials',
+ NOT_TAINTED)
+ ])
+ .then(function() {
+ port.postMessage({results: 'finish'});
+ })
+ .catch(function(e) {
+ port.postMessage({results: 'failure:' + e});
+ });
+ }, false);
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html
new file mode 100644
index 00000000000..48f618397c5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-cors-xhr-iframe.html
@@ -0,0 +1,210 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var path = base_path() + 'fetch-access-control.py';
+var host_info = get_host_info();
+var SUCCESS = 'SUCCESS';
+var FAIL = 'FAIL';
+
+function create_test_case_promise(url, with_credentials) {
+ return new Promise(function(resolve) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ if (xhr.status == 200) {
+ resolve(SUCCESS);
+ } else {
+ resolve("STATUS" + xhr.status);
+ }
+ }
+ xhr.onerror = function() {
+ resolve(FAIL);
+ }
+ xhr.responseType = 'text';
+ xhr.withCredentials = with_credentials;
+ xhr.open('GET', url, true);
+ xhr.send();
+ });
+}
+
+
+function create_test_promise(url, with_credentials, expected_result) {
+ return new Promise(function(resolve, reject) {
+ create_test_case_promise(url, with_credentials)
+ .then(function(result) {
+ if (result == expected_result) {
+ resolve();
+ } else {
+ reject('Result of url:' + url + ' ' +
+ ' with_credentials: ' + with_credentials + ' must be ' +
+ expected_result + ' but ' + result);
+ }
+ })
+ });
+}
+
+function create_serial_promise(test_cases) {
+ var promise = Promise.resolve();
+ test_cases.forEach(function(test_case) {
+ promise = promise.then(function() {
+ return create_test_promise(test_case[0], test_case[1], test_case[2]);
+ });
+ });
+ return promise;
+}
+
+window.addEventListener('message', function(evt) {
+ var port = evt.ports[0];
+ var url = host_info['HTTPS_ORIGIN'] + path;
+ var remote_url = host_info['HTTPS_REMOTE_ORIGIN'] + path;
+ // If the 4th value of the item of TEST_CASES is true, the test case outputs
+ // warning messages. So such tests must be executed in serial to match the
+ // expected output text.
+ var TEST_CASES = [
+ // Reject tests
+ [url + '?reject', false, FAIL],
+ [url + '?reject', true, FAIL],
+ [remote_url + '?reject', false, FAIL],
+ [remote_url + '?reject', true, FAIL],
+ // Event handler exception tests
+ [url + '?throw', false, FAIL],
+ [url + '?throw', true, FAIL],
+ [remote_url + '?throw', false, FAIL],
+ [remote_url + '?throw', true, FAIL],
+ // Reject(resolve-null) tests
+ [url + '?resolve-null', false, FAIL],
+ [url + '?resolve-null', true, FAIL],
+ [remote_url + '?resolve-null', false, FAIL],
+ [remote_url + '?resolve-null', true, FAIL],
+ // Fallback tests
+ [url + '?ignore', false, SUCCESS],
+ [url + '?ignore', true, SUCCESS],
+ [remote_url + '?ignore', false, FAIL, true], // Executed in serial.
+ [remote_url + '?ignore', true, FAIL, true], // Executed in serial.
+ [
+ remote_url + '?ACAOrigin=' + host_info['HTTPS_ORIGIN'] + '&ignore',
+ false, SUCCESS
+ ],
+ [
+ remote_url + '?ACAOrigin=' + host_info['HTTPS_ORIGIN'] + '&ignore',
+ true, FAIL, true // Executed in serial.
+ ],
+ [
+ remote_url + '?ACAOrigin=' + host_info['HTTPS_ORIGIN'] +
+ '&ACACredentials=true&ignore',
+ true, SUCCESS
+ ],
+ // Credential test (fallback)
+ [url + '?Auth&ignore', false, SUCCESS],
+ [url + '?Auth&ignore', true, SUCCESS],
+ [remote_url + '?Auth&ignore', false, FAIL, true], // Executed in serial.
+ [remote_url + '?Auth&ignore', true, FAIL, true], // Executed in serial.
+ [
+ remote_url + '?Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + '&ignore',
+ false, 'STATUS401'
+ ],
+ [
+ remote_url + '?Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] + '&ignore',
+ true, FAIL, true // Executed in serial.
+ ],
+ [
+ remote_url + '?Auth&ACAOrigin=' + host_info['HTTPS_ORIGIN'] +
+ '&ACACredentials=true&ignore',
+ true, SUCCESS
+ ],
+ // Basic response
+ [
+ url + '?mode=same-origin&url=' + encodeURIComponent(url),
+ false, SUCCESS
+ ],
+ [
+ url + '?mode=same-origin&url=' + encodeURIComponent(url),
+ false, SUCCESS
+ ],
+ [
+ remote_url + '?mode=same-origin&url=' + encodeURIComponent(url),
+ false, SUCCESS
+ ],
+ [
+ remote_url + '?mode=same-origin&url=' + encodeURIComponent(url),
+ false, SUCCESS
+ ],
+ // Opaque response
+ [
+ url + '?mode=no-cors&url=' + encodeURIComponent(remote_url),
+ false, FAIL
+ ],
+ [
+ url + '?mode=no-cors&url=' + encodeURIComponent(remote_url),
+ false, FAIL
+ ],
+ [
+ remote_url + '?mode=no-cors&url=' + encodeURIComponent(remote_url),
+ false, FAIL
+ ],
+ [
+ remote_url + '?mode=no-cors&url=' + encodeURIComponent(remote_url),
+ false, FAIL
+ ],
+ // CORS response
+ [
+ url + '?mode=cors&url=' +
+ encodeURIComponent(remote_url + '?ACAOrigin=' +
+ host_info['HTTPS_ORIGIN']),
+ false, SUCCESS
+ ],
+ [
+ url + '?mode=cors&url=' +
+ encodeURIComponent(remote_url + '?ACAOrigin=' +
+ host_info['HTTPS_ORIGIN']),
+ true, FAIL
+ ],
+ [
+ url + '?mode=cors&url=' +
+ encodeURIComponent(remote_url + '?ACAOrigin=' +
+ host_info['HTTPS_ORIGIN'] +
+ '&ACACredentials=true'),
+ true, SUCCESS
+ ],
+ [
+ remote_url + '?mode=cors&url=' +
+ encodeURIComponent(remote_url + '?ACAOrigin=' +
+ host_info['HTTPS_ORIGIN']),
+ false, SUCCESS
+ ],
+ [
+ remote_url +
+ '?mode=cors&url=' +
+ encodeURIComponent(remote_url + '?ACAOrigin=' +
+ host_info['HTTPS_ORIGIN']),
+ true, FAIL
+ ],
+ [
+ remote_url +
+ '?mode=cors&url=' +
+ encodeURIComponent(remote_url + '?ACAOrigin=' +
+ host_info['HTTPS_ORIGIN'] +
+ '&ACACredentials=true'),
+ true, SUCCESS
+ ]
+ ];
+ var promises = [];
+ var serial_tests = [];
+ for (var i = 0; i < TEST_CASES.length ; ++i) {
+ if (!TEST_CASES[i][3]) {
+ promises.push(create_test_promise(TEST_CASES[i][0],
+ TEST_CASES[i][1],
+ TEST_CASES[i][2]));
+ } else {
+ serial_tests.push(TEST_CASES[i]);
+ }
+ }
+ promises.push(create_serial_promise(serial_tests));
+ Promise.all(promises)
+ .then(function() {
+ port.postMessage({results: 'finish'});
+ })
+ .catch(function(e) {
+ port.postMessage({results: 'failure:' + e});
+ });
+ }, false);
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html
new file mode 100644
index 00000000000..cf7175bc83d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html
@@ -0,0 +1,72 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var image_path = base_path() + 'fetch-access-control.py?PNGIMAGE';
+var host_info = get_host_info();
+var results = '';
+var port = undefined;
+
+function test1() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ test2();
+ };
+ img.onerror = function() {
+ results += 'FAIL(1)';
+ test2();
+ };
+ img.src = host_info['HTTPS_ORIGIN'] + image_path;
+}
+
+function test2() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ results += 'FAIL(2)';
+ test3();
+ };
+ img.onerror = function() {
+ test3();
+ };
+ img.src = host_info['HTTPS_REMOTE_ORIGIN'] + image_path;
+}
+
+function test3() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ test4();
+ };
+ img.onerror = function() {
+ results += 'FAIL(3)';
+ test4();
+ };
+ img.src = './dummy?url=' +
+ encodeURIComponent(host_info['HTTPS_ORIGIN'] + image_path);
+}
+
+function test4() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ results += 'FAIL(4)';
+ finish();
+ };
+ img.onerror = function() {
+ finish();
+ };
+ img.src = './dummy?mode=no-cors&url=' +
+ encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + image_path);
+}
+
+function finish() {
+ results += 'finish';
+ port.postMessage({results: results});
+}
+
+window.addEventListener('message', function(evt) {
+ port = evt.ports[0];
+ test1();
+ }, false);
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers
new file mode 100644
index 00000000000..300efe049b5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-csp-iframe.html.sub.headers
@@ -0,0 +1 @@
+Content-Security-Policy: img-src https://{{host}}:{{ports[https][0]}}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html
new file mode 100644
index 00000000000..bf8a6d5ce51
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-after-navigation-within-page-iframe.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<script>
+function fetch_url(url) {
+ return new Promise(function(resolve, reject) {
+ var request = new XMLHttpRequest();
+ request.addEventListener('load', function(event) {
+ if (request.status == 200)
+ resolve(request.response);
+ else
+ reject(new Error('fetch_url: ' + request.statusText + " : " + url));
+ });
+ request.addEventListener('error', function(event) {
+ reject(new Error('fetch_url encountered an error: ' + url));
+ });
+ request.addEventListener('abort', function(event) {
+ reject(new Error('fetch_url was aborted: ' + url));
+ });
+ request.open('GET', url);
+ request.send();
+ });
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js
new file mode 100644
index 00000000000..7f66d20dfc2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-async-respond-with-worker.js
@@ -0,0 +1,19 @@
+var result;
+
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage(result);
+ });
+
+self.addEventListener('fetch', function(event) {
+ setTimeout(function() {
+ try {
+ event.respondWith(new Response());
+ result = 'FAIL: did not throw';
+ } catch (error) {
+ if (error.name == 'InvalidStateError')
+ result = 'PASS';
+ else
+ result = 'FAIL: Unexpected exception: ' + error;
+ }
+ }, 0);
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html
new file mode 100644
index 00000000000..a4c9307e745
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-controllee-iframe.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<script>
+function fetch_url(url) {
+ return new Promise(function(resolve, reject) {
+ var request = new XMLHttpRequest();
+ request.addEventListener('load', function(event) {
+ resolve();
+ });
+ request.addEventListener('error', function(event) {
+ reject();
+ });
+ request.open('GET', url);
+ request.send();
+ });
+}
+
+function make_test(testcase) {
+ var name = testcase.name;
+ return fetch_url(window.location.href + '?' + name)
+ .then(
+ function() {
+ if (testcase.expect_load)
+ return Promise.resolve();
+ return Promise.reject(new Error(
+ name + ': expected network error but loaded'));
+ },
+ function() {
+ if (!testcase.expect_load)
+ return Promise.resolve();
+ return Promise.reject(new Error(
+ name + ': expected to load but got network error'));
+ });
+}
+
+function run_tests() {
+ var tests = [
+ { name: 'prevent-default-and-respond-with', expect_load: true },
+ { name: 'prevent-default', expect_load: false },
+ { name: 'reject', expect_load: false },
+ { name: 'unused-body', expect_load: true },
+ { name: 'used-body', expect_load: false },
+ { name: 'unused-fetched-body', expect_load: true },
+ { name: 'used-fetched-body', expect_load: false }
+ ].map(make_test);
+
+ Promise.all(tests)
+ .then(function() {
+ window.parent.notify_test_done('PASS');
+ })
+ .catch(function(error) {
+ window.parent.notify_test_done('FAIL: ' + error.message);
+ });
+}
+
+if (!navigator.serviceWorker.controller)
+ window.parent.notify_done('FAIL: no controller');
+else
+ run_tests();
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-worker.js
new file mode 100644
index 00000000000..52d4c8e860b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-network-error-worker.js
@@ -0,0 +1,46 @@
+// Test that multiple fetch handlers do not confuse the implementation.
+self.addEventListener('fetch', function(event) {});
+
+self.addEventListener('fetch', function(event) {
+ var testcase = new URL(event.request.url).search;
+ switch (testcase) {
+ case '?reject':
+ event.respondWith(Promise.reject());
+ break;
+ case '?prevent-default':
+ event.preventDefault();
+ break;
+ case '?prevent-default-and-respond-with':
+ event.preventDefault();
+ break;
+ case '?unused-body':
+ event.respondWith(new Response('body'));
+ break;
+ case '?used-body':
+ var res = new Response('body');
+ res.text();
+ event.respondWith(res);
+ break;
+ case '?unused-fetched-body':
+ event.respondWith(fetch('other.html').then(function(res){
+ return res;
+ }));
+ break;
+ case '?used-fetched-body':
+ event.respondWith(fetch('other.html').then(function(res){
+ res.text();
+ return res;
+ }));
+ break;
+ }
+ });
+
+self.addEventListener('fetch', function(event) {});
+
+self.addEventListener('fetch', function(event) {
+ var testcase = new URL(event.request.url).search;
+ if (testcase == '?prevent-default-and-respond-with')
+ event.respondWith(new Response('responding!'));
+ });
+
+self.addEventListener('fetch', function(event) {});
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-redirect-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-redirect-iframe.html
new file mode 100644
index 00000000000..499e9677569
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-redirect-iframe.html
@@ -0,0 +1,20 @@
+<script>
+window.addEventListener('message', function(evt) {
+ var port = evt.ports[0];
+ var data = evt.data;
+ fetch(new Request(data.url, data.request_init)).then(function(response) {
+ if (data.request_init.mode === 'no-cors' && data.redirect_dest != 'same-origin') {
+ if (response.type === 'opaque') {
+ return {result: 'success', detail: ''};
+ } else {
+ return {result: 'failure', detail: 'expected opaque response'};
+ }
+ }
+ return response.json();
+ }).then(function(body) {
+ port.postMessage({result: body.result, detail: body.detail});
+ }).catch(function(e) {
+ port.postMessage({result: 'reject', detail: e.toString()});
+ });
+});
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js
new file mode 100644
index 00000000000..18da049d69f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-respond-with-stops-propagation-worker.js
@@ -0,0 +1,15 @@
+var result = null;
+
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage(result);
+ });
+
+self.addEventListener('fetch', function(event) {
+ if (!result)
+ result = 'PASS';
+ event.respondWith(new Response());
+ });
+
+self.addEventListener('fetch', function(event) {
+ result = 'FAIL: fetch event propagated';
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js
new file mode 100644
index 00000000000..5180c30f7d4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-event-test-worker.js
@@ -0,0 +1,131 @@
+function handleString(event) {
+ event.respondWith(new Response('Test string'));
+}
+
+function handleBlob(event) {
+ event.respondWith(new Response(new Blob(['Test blob'])));
+}
+
+function handleReferrer(event) {
+ event.respondWith(new Response(new Blob(
+ ['Referrer: ' + event.request.referrer])));
+}
+
+function handleReferrerPolicy(event) {
+ event.respondWith(new Response(new Blob(
+ ['ReferrerPolicy: ' + event.request.referrerPolicy])));
+}
+
+function handleReferrerFull(event) {
+ event.respondWith(new Response(new Blob(
+ ['Referrer: ' + event.request.referrer + '\n' +
+ 'ReferrerPolicy: ' + event.request.referrerPolicy])));
+}
+
+function handleClientId(event) {
+ var body;
+ if (event.clientId !== null) {
+ body = 'Client ID Found: ' + event.clientId;
+ } else {
+ body = 'Client ID Not Found';
+ }
+ event.respondWith(new Response(body));
+}
+
+function handleNullBody(event) {
+ event.respondWith(new Response());
+}
+
+function handleFetch(event) {
+ event.respondWith(fetch('other.html'));
+}
+
+function handleFormPost(event) {
+ event.respondWith(new Promise(function(resolve) {
+ event.request.text()
+ .then(function(result) {
+ resolve(new Response(event.request.method + ':' +
+ event.request.headers.get('Content-Type') + ':' +
+ result));
+ });
+ }));
+}
+
+function handleMultipleRespondWith(event) {
+ var logForMultipleRespondWith = '';
+ for (var i = 0; i < 3; ++i) {
+ logForMultipleRespondWith += '(' + i + ')';
+ try {
+ event.respondWith(new Promise(function(resolve) {
+ setTimeout(function() {
+ resolve(new Response(logForMultipleRespondWith));
+ }, 0);
+ }));
+ } catch (e) {
+ logForMultipleRespondWith += '[' + e.name + ']';
+ }
+ }
+}
+
+var lastResponseForUsedCheck = undefined;
+
+function handleUsedCheck(event) {
+ if (!lastResponseForUsedCheck) {
+ event.respondWith(fetch('other.html').then(function(response) {
+ lastResponseForUsedCheck = response;
+ return response;
+ }));
+ } else {
+ event.respondWith(new Response(
+ 'bodyUsed: ' + lastResponseForUsedCheck.bodyUsed));
+ }
+}
+
+function handleFragmentCheck(event) {
+ var body;
+ if (event.request.url.indexOf('#') === -1) {
+ body = 'Fragment Not Found';
+ } else {
+ body = 'Fragment Found';
+ }
+ event.respondWith(new Response(body));
+}
+
+function handleCache(event) {
+ event.respondWith(new Response(event.request.cache));
+}
+
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ var handlers = [
+ { pattern: '?string', fn: handleString },
+ { pattern: '?blob', fn: handleBlob },
+ { pattern: '?referrerFull', fn: handleReferrerFull },
+ { pattern: '?referrerPolicy', fn: handleReferrerPolicy },
+ { pattern: '?referrer', fn: handleReferrer },
+ { pattern: '?clientId', fn: handleClientId },
+ { pattern: '?ignore', fn: function() {} },
+ { pattern: '?null', fn: handleNullBody },
+ { pattern: '?fetch', fn: handleFetch },
+ { pattern: '?form-post', fn: handleFormPost },
+ { pattern: '?multiple-respond-with', fn: handleMultipleRespondWith },
+ { pattern: '?used-check', fn: handleUsedCheck },
+ { pattern: '?fragment-check', fn: handleFragmentCheck },
+ { pattern: '?cache', fn: handleCache },
+ ];
+
+ var handler = null;
+ for (var i = 0; i < handlers.length; ++i) {
+ if (url.indexOf(handlers[i].pattern) != -1) {
+ handler = handlers[i];
+ break;
+ }
+ }
+
+ if (handler) {
+ handler.fn(event);
+ } else {
+ event.respondWith(new Response(new Blob(
+ ['Service Worker got an unexpected request: ' + url])));
+ }
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-header-visibility-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-header-visibility-iframe.html
new file mode 100644
index 00000000000..e0f32f75477
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-header-visibility-iframe.html
@@ -0,0 +1,66 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+ var host_info = get_host_info();
+ var uri = document.location + '?check-ua-header';
+
+ var headers = new Headers();
+ headers.set('User-Agent', 'custom_ua');
+
+ // Check the custom UA case
+ fetch(uri, { headers: headers }).then(function(response) {
+ return response.text();
+ }).then(function(text) {
+ if (text == 'custom_ua') {
+ parent.postMessage('PASS', '*');
+ } else {
+ parent.postMessage('withUA FAIL - expected "custom_ua", got "' + text + '"', '*');
+ }
+ }).catch(function(err) {
+ parent.postMessage('withUA FAIL - unexpected error: ' + err, '*');
+ });
+
+ // Check the default UA case
+ fetch(uri, {}).then(function(response) {
+ return response.text();
+ }).then(function(text) {
+ if (text == 'NO_UA') {
+ parent.postMessage('PASS', '*');
+ } else {
+ parent.postMessage('noUA FAIL - expected "NO_UA", got "' + text + '"', '*');
+ }
+ }).catch(function(err) {
+ parent.postMessage('noUA FAIL - unexpected error: ' + err, '*');
+ });
+
+ var uri = document.location + '?check-accept-header';
+ var headers = new Headers();
+ headers.set('Accept', 'hmm');
+
+ // Check for custom accept header
+ fetch(uri, { headers: headers }).then(function(response) {
+ return response.text();
+ }).then(function(text) {
+ if (text === headers.get('Accept')) {
+ parent.postMessage('PASS', '*');
+ } else {
+ parent.postMessage('custom accept FAIL - expected ' + headers.get('Accept') +
+ ' got "' + text + '"', '*');
+ }
+ }).catch(function(err) {
+ parent.postMessage('custom accept FAIL - unexpected error: ' + err, '*');
+ });
+
+ // Check for default accept header
+ fetch(uri).then(function(response) {
+ return response.text();
+ }).then(function(text) {
+ if (text === '*/*') {
+ parent.postMessage('PASS', '*');
+ } else {
+ parent.postMessage('accept FAIL - expected */* got "' + text + '"', '*');
+ }
+ }).catch(function(err) {
+ parent.postMessage('accept FAIL - unexpected error: ' + err, '*');
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html
new file mode 100644
index 00000000000..a7db229cecc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-inscope.html
@@ -0,0 +1,71 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var image_path = base_path() + 'fetch-access-control.py?PNGIMAGE';
+var host_info = get_host_info();
+var results = '';
+
+function test1() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ test2();
+ };
+ img.onerror = function() {
+ results += 'FAIL(1)';
+ test2();
+ };
+ img.src = './dummy?url=' +
+ encodeURIComponent(host_info['HTTPS_ORIGIN'] + image_path);
+}
+
+function test2() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ test3();
+ };
+ img.onerror = function() {
+ results += 'FAIL(2)';
+ test3();
+ };
+ img.src = './dummy?mode=no-cors&url=' +
+ encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + image_path);
+}
+
+function test3() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ results += 'FAIL(3)';
+ test4();
+ };
+ img.onerror = function() {
+ test4();
+ };
+ img.src = './dummy?mode=no-cors&url=' +
+ encodeURIComponent(host_info['HTTP_ORIGIN'] + image_path);
+}
+
+function test4() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ results += 'FAIL(4)';
+ finish();
+ };
+ img.onerror = function() {
+ finish();
+ };
+ img.src = './dummy?mode=no-cors&url=' +
+ encodeURIComponent(host_info['HTTP_REMOTE_ORIGIN'] + image_path);
+}
+
+function finish() {
+ results += 'finish';
+ window.parent.postMessage({results: results}, host_info['HTTPS_ORIGIN']);
+}
+</script>
+
+<body onload='test1();'>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html
new file mode 100644
index 00000000000..cec00cb25e4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe-inscope-to-outscope.html
@@ -0,0 +1,80 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var image_path = base_path() + 'fetch-access-control.py?PNGIMAGE';
+var host_info = get_host_info();
+var results = '';
+
+function test1() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ test2();
+ };
+ img.onerror = function() {
+ results += 'FAIL(1)';
+ test2();
+ };
+ img.src = host_info['HTTPS_ORIGIN'] + image_path;
+}
+
+function test2() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ test3();
+ };
+ img.onerror = function() {
+ results += 'FAIL(2)';
+ test3();
+ };
+ img.src = host_info['HTTPS_REMOTE_ORIGIN'] + image_path;
+}
+
+function test3() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ results += 'FAIL(3)';
+ test4();
+ };
+ img.onerror = function() {
+ test4();
+ };
+ img.src = host_info['HTTP_ORIGIN'] + image_path;
+}
+
+function test4() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ results += 'FAIL(4)';
+ test5();
+ };
+ img.onerror = function() {
+ test5();
+ };
+ img.src = host_info['HTTP_REMOTE_ORIGIN'] + image_path;
+}
+
+function test5() {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = function() {
+ finish();
+ };
+ img.onerror = function() {
+ results += 'FAIL(5)';
+ finish();
+ };
+ img.src = './dummy?generate-png';
+}
+
+function finish() {
+ results += 'finish';
+ window.parent.postMessage({results: results}, host_info['HTTPS_ORIGIN']);
+}
+</script>
+
+<body onload='test1();'>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe.html
new file mode 100644
index 00000000000..961fd2ab699
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-mixed-content-iframe.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var params = get_query_params(location.href);
+var SCOPE = 'fetch-mixed-content-iframe-inscope-to-' + params['target'] + '.html';
+var URL = 'fetch-rewrite-worker.js';
+var host_info = get_host_info();
+
+window.addEventListener('message', on_message, false);
+
+navigator.serviceWorker.getRegistration(SCOPE)
+ .then(function(registration) {
+ if (registration)
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(URL, {scope: SCOPE});
+ })
+ .then(function(registration) {
+ return new Promise(function(resolve) {
+ registration.addEventListener('updatefound', function() {
+ resolve(registration.installing);
+ });
+ });
+ })
+ .then(function(worker) {
+ worker.addEventListener('statechange', on_state_change);
+ })
+ .catch(function(reason) {
+ window.parent.postMessage({results: 'FAILURE: ' + reason.message},
+ host_info['HTTPS_ORIGIN']);
+ });
+
+function on_state_change(event) {
+ if (event.target.state != 'activated')
+ return;
+ var frame = document.createElement('iframe');
+ frame.src = SCOPE;
+ document.body.appendChild(frame);
+}
+
+function on_message(e) {
+ navigator.serviceWorker.getRegistration(SCOPE)
+ .then(function(registration) {
+ if (registration)
+ return registration.unregister();
+ })
+ .then(function() {
+ window.parent.postMessage(e.data, host_info['HTTPS_ORIGIN']);
+ })
+ .catch(function(reason) {
+ window.parent.postMessage({results: 'FAILURE: ' + reason.message},
+ host_info['HTTPS_ORIGIN']);
+ });
+}
+
+function get_query_params(url) {
+ var search = (new URL(url)).search;
+ if (!search) {
+ return {};
+ }
+ var ret = {};
+ var params = search.substring(1).split('&');
+ params.forEach(function(param) {
+ var element = param.split('=');
+ ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]);
+ });
+ return ret;
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html
new file mode 100644
index 00000000000..0edf2e7f965
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-iframe.html
@@ -0,0 +1 @@
+<link href="./fetch-request-css-base-url-style.css" rel="stylesheet" type="text/css">
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-style.css b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-style.css
new file mode 100644
index 00000000000..7643f667adb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-style.css
@@ -0,0 +1 @@
+body { background-image: url("./dummy.png");}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js
new file mode 100644
index 00000000000..0d9244ec75c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-css-base-url-worker.js
@@ -0,0 +1,27 @@
+importScripts('../resources/get-host-info.sub.js');
+importScripts('test-helpers.sub.js');
+
+var port = undefined;
+
+self.onmessage = function(e) {
+ var message = e.data;
+ if ('port' in message) {
+ port = message.port;
+ port.postMessage({ready: true});
+ }
+};
+
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ if (url.indexOf('fetch-request-css-base-url-style.css') != -1) {
+ event.respondWith(fetch(
+ get_host_info()['HTTPS_REMOTE_ORIGIN'] + base_path() +
+ 'fetch-request-css-base-url-style.css',
+ {mode: 'no-cors'}));
+ } else if (url.indexOf('dummy.png') != -1) {
+ port.postMessage({
+ url: event.request.url,
+ referrer: event.request.referrer
+ });
+ }
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-iframe.html
new file mode 100644
index 00000000000..f00d24e37a8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-iframe.html
@@ -0,0 +1,15 @@
+<script>
+function xhr(url) {
+ return new Promise(function(resolve, reject) {
+ var request = new XMLHttpRequest();
+ request.addEventListener(
+ 'error',
+ function(event) { reject(event); });
+ request.addEventListener(
+ 'load',
+ function(event) { resolve(request.response); });
+ request.open('GET', url);
+ request.send();
+ });
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-worker.js
new file mode 100644
index 00000000000..3b028b24bde
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-fallback-worker.js
@@ -0,0 +1,13 @@
+var requests = [];
+
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage({requests: requests});
+ requests = [];
+ });
+
+self.addEventListener('fetch', function(event) {
+ requests.push({
+ url: event.request.url,
+ mode: event.request.mode
+ });
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html
new file mode 100644
index 00000000000..68a1a868760
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-iframe.html
@@ -0,0 +1 @@
+<script src="empty.js"></script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js
new file mode 100644
index 00000000000..2bd59d73922
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-no-freshness-headers-worker.js
@@ -0,0 +1,18 @@
+var requests = [];
+
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage({requests: requests});
+ });
+
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ var headers = [];
+ for (var header of event.request.headers) {
+ headers.push(header);
+ }
+ requests.push({
+ url: url,
+ headers: headers
+ });
+ event.respondWith(fetch(event.request));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html
new file mode 100644
index 00000000000..ffd76bfc499
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-redirect-iframe.html
@@ -0,0 +1,35 @@
+<script>
+function xhr(url) {
+ return new Promise(function(resolve, reject) {
+ var request = new XMLHttpRequest();
+ request.addEventListener(
+ 'error',
+ function(event) { reject(event); });
+ request.addEventListener(
+ 'load',
+ function(event) { resolve(request.response); });
+ request.open('GET', url);
+ request.send();
+ });
+}
+
+function load_image(url) {
+ return new Promise(function(resolve, reject) {
+ var img = document.createElement('img');
+ document.body.appendChild(img);
+ img.onload = resolve;
+ img.onerror = reject;
+ img.src = url;
+ });
+}
+
+function load_audio(url) {
+ return new Promise(function(resolve, reject) {
+ var audio = document.createElement('audio');
+ document.body.appendChild(audio);
+ audio.oncanplay = resolve;
+ audio.onerror = reject;
+ audio.src = url;
+ });
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html
new file mode 100644
index 00000000000..cadbff45cae
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-iframe.https.html
@@ -0,0 +1,51 @@
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<body>
+<script>
+
+function load_image(url, cross_origin) {
+ var img = document.createElement('img');
+ if (cross_origin != '') {
+ img.crossOrigin = cross_origin;
+ }
+ img.src = url;
+}
+
+function load_script(url, cross_origin) {
+ var script = document.createElement('script');
+ script.src = url;
+ if (cross_origin != '') {
+ script.crossOrigin = cross_origin;
+ }
+ document.body.appendChild(script);
+}
+
+function load_css(url, cross_origin) {
+ var link = document.createElement('link');
+ link.rel = 'stylesheet'
+ link.href = url;
+ link.type = 'text/css';
+ if (cross_origin != '') {
+ link.crossOrigin = cross_origin;
+ }
+ document.body.appendChild(link);
+}
+
+function load_font(url) {
+ var fontFace = new FontFace('test', 'url(' + url + ')');
+ fontFace.load();
+}
+
+function load_css_image(url, type) {
+ var div = document.createElement('div');
+ document.body.appendChild(div);
+ div.style[type] = 'url(' + url + ')';
+}
+
+function load_css_image_set(url, type) {
+ var div = document.createElement('div');
+ document.body.appendChild(div);
+ div.style[type] = '-webkit-image-set(url(' + url + ') 1x)';
+}
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-worker.js
new file mode 100644
index 00000000000..9ec1dc62822
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-resources-worker.js
@@ -0,0 +1,23 @@
+var requests = [];
+var port = undefined;
+
+self.onmessage = function(e) {
+ var message = e.data;
+ if ('port' in message) {
+ port = message.port;
+ port.postMessage({ready: true});
+ }
+};
+
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ if (url.indexOf('dummy?test') == -1) {
+ return;
+ }
+ port.postMessage({
+ url: url,
+ mode: event.request.mode,
+ credentials: event.request.credentials
+ });
+ event.respondWith(Promise.reject());
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
new file mode 100644
index 00000000000..26c6b734467
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-iframe.https.html
@@ -0,0 +1,179 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var port;
+var host_info = get_host_info();
+
+function assert_equals(a, b) {
+ port.postMessage({results: 'equals', got: a, expected: b});
+}
+
+function get_boundary(headers) {
+ var reg = new RegExp('multipart\/form-data; boundary=(.*)');
+ for (var i = 0; i < headers.length; ++i) {
+ if (headers[i][0] != 'content-type') {
+ continue;
+ }
+ var regResult = reg.exec(headers[i][1]);
+ if (!regResult) {
+ continue;
+ }
+ return regResult[1];
+ }
+ return '';
+}
+
+function create_file_system_file(file_name, data) {
+ return new Promise(function(resolve, reject) {
+ webkitRequestFileSystem(TEMPORARY, 1024, function(fs) {
+ fs.root.getFile(
+ file_name, {create: true, exclusive: true},
+ function(fileEntry) {
+ fileEntry.createWriter(function(fileWriter) {
+ fileWriter.onwriteend = function(e) {
+ fileEntry.file(function(file) { resolve(file); });
+ };
+ var blob = new Blob([data], {type: 'text/plain'});
+ fileWriter.write(blob);
+ });
+ }, function(e) { reject(e); });
+ }, function(e) { reject(e); });
+ });
+}
+
+function xhr_send(url_base, method, data, with_credentials) {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ resolve(JSON.parse(xhr.response));
+ };
+ xhr.onerror = function() {
+ reject('XHR should succeed.');
+ };
+ xhr.responseType = 'text';
+ if (with_credentials) {
+ xhr.withCredentials = true;
+ }
+ xhr.open(method, url_base + '/dummy?test', true);
+ xhr.send(data);
+ });
+}
+
+function string_test() {
+ return xhr_send(host_info['HTTPS_ORIGIN'], 'POST', 'test string', false)
+ .then(function(response) {
+ assert_equals(response.method, 'POST');
+ assert_equals(response.body, 'test string');
+ });
+}
+
+function blob_test() {
+ return xhr_send(host_info['HTTPS_ORIGIN'], 'POST', new Blob(['test blob']),
+ false)
+ .then(function(response) {
+ assert_equals(response.method, 'POST');
+ assert_equals(response.body, 'test blob');
+ });
+}
+
+function custom_method_test() {
+ return xhr_send(host_info['HTTPS_ORIGIN'], 'XXX', 'test string xxx', false)
+ .then(function(response) {
+ assert_equals(response.method, 'XXX');
+ assert_equals(response.body, 'test string xxx');
+ });
+}
+
+function options_method_test() {
+ return xhr_send(host_info['HTTPS_ORIGIN'], 'OPTIONS', 'test string xxx', false)
+ .then(function(response) {
+ assert_equals(response.method, 'OPTIONS');
+ assert_equals(response.body, 'test string xxx');
+ });
+}
+
+function form_data_test() {
+ var formData = new FormData();
+ formData.append('sample string', '1234567890');
+ formData.append('sample blob', new Blob(['blob content']));
+ formData.append('sample file', new File(['file content'], 'file.dat'));
+ return xhr_send(host_info['HTTPS_ORIGIN'], 'POST', formData, false)
+ .then(function(response) {
+ assert_equals(response.method, 'POST');
+ var boundary = get_boundary(response.headers);
+ var expected_body =
+ '--' + boundary + '\r\n' +
+ 'Content-Disposition: form-data; name="sample string"\r\n' +
+ '\r\n' +
+ '1234567890\r\n' +
+ '--' + boundary + '\r\n' +
+ 'Content-Disposition: form-data; name="sample blob"; ' +
+ 'filename="blob"\r\n' +
+ 'Content-Type: application/octet-stream\r\n' +
+ '\r\n' +
+ 'blob content\r\n' +
+ '--' + boundary + '\r\n' +
+ 'Content-Disposition: form-data; name="sample file"; ' +
+ 'filename="file.dat"\r\n' +
+ 'Content-Type: application/octet-stream\r\n' +
+ '\r\n' +
+ 'file content\r\n' +
+ '--' + boundary + '--\r\n';
+ assert_equals(response.body, expected_body);
+ });
+}
+
+function mode_credentials_test() {
+ return xhr_send(host_info['HTTPS_ORIGIN'], 'GET', '', false)
+ .then(function(response){
+ assert_equals(response.mode, 'cors');
+ assert_equals(response.credentials, 'same-origin');
+ return xhr_send(host_info['HTTPS_ORIGIN'], 'GET', '', true);
+ })
+ .then(function(response){
+ assert_equals(response.mode, 'cors');
+ assert_equals(response.credentials, 'include');
+ return xhr_send(host_info['HTTPS_REMOTE_ORIGIN'], 'GET', '', false);
+ })
+ .then(function(response){
+ assert_equals(response.mode, 'cors');
+ assert_equals(response.credentials, 'same-origin');
+ return xhr_send(host_info['HTTPS_REMOTE_ORIGIN'], 'GET', '', true);
+ })
+ .then(function(response){
+ assert_equals(response.mode, 'cors');
+ assert_equals(response.credentials, 'include');
+ });
+}
+
+function data_url_test() {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ resolve(xhr.response);
+ };
+ xhr.onerror = function() {
+ reject('XHR should succeed.');
+ };
+ xhr.responseType = 'text';
+ xhr.open('GET', 'data:text/html,Foobar', true);
+ xhr.send();
+ })
+ .then(function(data) {
+ assert_equals(data, 'Foobar');
+ });
+}
+
+window.addEventListener('message', function(evt) {
+ port = evt.ports[0];
+ string_test()
+ .then(blob_test)
+ .then(custom_method_test)
+ .then(options_method_test)
+ .then(form_data_test)
+ .then(mode_credentials_test)
+ .then(data_url_test)
+ .then(function() { port.postMessage({results: 'finish'}); })
+ .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js
new file mode 100644
index 00000000000..91b3abb14d9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-request-xhr-worker.js
@@ -0,0 +1,22 @@
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ if (url.indexOf('dummy?test') == -1) {
+ return;
+ }
+ event.respondWith(new Promise(function(resolve) {
+ var headers = [];
+ for (var header of event.request.headers) {
+ headers.push(header);
+ }
+ event.request.text()
+ .then(function(result) {
+ resolve(new Response(JSON.stringify({
+ method: event.request.method,
+ mode: event.request.mode,
+ credentials: event.request.credentials,
+ headers: headers,
+ body: result
+ })));
+ });
+ }));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html
new file mode 100644
index 00000000000..3391381e38a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-iframe.https.html
@@ -0,0 +1,35 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var host_info = get_host_info();
+
+function xhr_send(method, data) {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ resolve(xhr);
+ };
+ xhr.onerror = function() {
+ reject('XHR should succeed.');
+ };
+ xhr.responseType = 'text';
+ xhr.open(method, './dummy?test', true);
+ xhr.send(data);
+ });
+}
+
+function coalesce_headers_test() {
+ return xhr_send('POST', 'test string')
+ .then(function(xhr) {
+ window.parent.postMessage({results: xhr.getResponseHeader('foo')},
+ host_info['HTTPS_ORIGIN']);
+ });
+}
+
+window.addEventListener('message', function(evt) {
+ var port = evt.ports[0];
+ coalesce_headers_test()
+ .then(function() { port.postMessage({results: 'finish'}); })
+ .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-worker.js
new file mode 100644
index 00000000000..465fbc91baa
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-response-xhr-worker.js
@@ -0,0 +1,12 @@
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ if (url.indexOf('dummy?test') == -1) {
+ return;
+ }
+ event.respondWith(new Promise(function(resolve) {
+ var headers = new Headers;
+ headers.append('foo', 'foo');
+ headers.append('foo', 'bar');
+ resolve(new Response('hello world', {'headers': headers}));
+ }));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js
new file mode 100644
index 00000000000..3929f2cccf1
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-rewrite-worker.js
@@ -0,0 +1,118 @@
+function get_query_params(url) {
+ var search = (new URL(url)).search;
+ if (!search) {
+ return {};
+ }
+ var ret = {};
+ var params = search.substring(1).split('&');
+ params.forEach(function(param) {
+ var element = param.split('=');
+ ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]);
+ });
+ return ret;
+}
+
+function get_request_init(base, params) {
+ var init = {};
+ init['method'] = params['method'] || base['method'];
+ init['mode'] = params['mode'] || base['mode'];
+ if (init['mode'] == 'navigate') {
+ init['mode'] = 'same-origin';
+ }
+ init['credentials'] = params['credentials'] || base['credentials'];
+ init['redirect'] = params['redirect-mode'] || base['redirect'];
+ return init;
+}
+
+self.addEventListener('fetch', function(event) {
+ var params = get_query_params(event.request.url);
+ var init = get_request_init(event.request, params);
+ var url = params['url'];
+ if (params['ignore']) {
+ return;
+ }
+ if (params['throw']) {
+ throw new Error('boom');
+ }
+ if (params['reject']) {
+ event.respondWith(new Promise(function(resolve, reject) {
+ reject();
+ }));
+ return;
+ }
+ if (params['resolve-null']) {
+ event.respondWith(new Promise(function(resolve) {
+ resolve(null);
+ }));
+ return;
+ }
+ if (params['generate-png']) {
+ var binary = atob(
+ 'iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAA' +
+ 'RnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAAhSURBVDhPY3wro/Kf' +
+ 'gQLABKXJBqMGjBoAAqMGDLwBDAwAEsoCTFWunmQAAAAASUVORK5CYII=');
+ var array = new Uint8Array(binary.length);
+ for(var i = 0; i < binary.length; i++) {
+ array[i] = binary.charCodeAt(i);
+ };
+ event.respondWith(new Response(new Blob([array], {type: 'image/png'})));
+ return;
+ }
+ if (params['check-ua-header']) {
+ var ua = event.request.headers.get('User-Agent');
+ if (ua) {
+ // We have a user agent!
+ event.respondWith(new Response(new Blob([ua])));
+ } else {
+ // We don't have a user-agent!
+ event.respondWith(new Response(new Blob(["NO_UA"])));
+ }
+ return;
+ }
+ if (params['check-accept-header']) {
+ var accept = event.request.headers.get('Accept');
+ if (accept) {
+ event.respondWith(new Response(accept));
+ } else {
+ event.respondWith(new Response('NO_ACCEPT'));
+ }
+ }
+ event.respondWith(new Promise(function(resolve, reject) {
+ var request = event.request;
+ if (url) {
+ request = new Request(url, init);
+ }
+ fetch(request).then(function(response) {
+ var expectedType = params['expected_type'];
+ if (expectedType && response.type !== expectedType) {
+ // Resolve a JSON object with a failure instead of rejecting
+ // in order to distinguish this from a NetworkError, which
+ // may be expected even if the type is correct.
+ resolve(new Response(JSON.stringify({
+ result: 'failure',
+ detail: 'got ' + response.type + ' Response.type instead of ' +
+ expectedType
+ })));
+ }
+
+ if (params['cache']) {
+ var cacheName = "cached-fetches-" + Date.now();
+ var cache;
+ var cachedResponse;
+ return self.caches.open(cacheName).then(function(opened) {
+ cache = opened;
+ return cache.put(request, response);
+ }).then(function() {
+ return cache.match(request);
+ }).then(function(cached) {
+ cachedResponse = cached;
+ return self.caches.delete(cacheName);
+ }).then(function() {
+ resolve(cachedResponse);
+ });
+ } else {
+ resolve(response);
+ }
+ }, reject)
+ }));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js
new file mode 100644
index 00000000000..66f3e593619
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/fetch-waits-for-activate-worker.js
@@ -0,0 +1,17 @@
+var activatePromiseResolve;
+
+addEventListener('activate', function(evt) {
+ evt.waitUntil(new Promise(function(resolve) {
+ activatePromiseResolve = resolve;
+ }));
+});
+
+addEventListener('message', function(evt) {
+ if (typeof activatePromiseResolve === 'function') {
+ activatePromiseResolve();
+ }
+});
+
+addEventListener('fetch', function(evt) {
+ evt.respondWith(new Response('Hello world'));
+});
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/frame-for-getregistrations.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/frame-for-getregistrations.html
new file mode 100644
index 00000000000..7fc35f18914
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/frame-for-getregistrations.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Service Worker: frame for getRegistrations()</title>
+<script>
+var scope = 'scope-for-getregistrations';
+var script = 'empty-worker.js';
+var registration;
+
+navigator.serviceWorker.register(script, { scope: scope })
+ .then(function(r) { registration = r; window.parent.postMessage('ready', '*'); })
+
+self.onmessage = function(e) {
+ if (e.data == 'unregister') {
+ registration.unregister()
+ .then(function() {
+ e.ports[0].postMessage('unregistered');
+ });
+ }
+};
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/get-host-info.sub.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/get-host-info.sub.js
new file mode 100644
index 00000000000..b64334df667
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/get-host-info.sub.js
@@ -0,0 +1,26 @@
+function get_host_info() {
+ var ORIGINAL_HOST = '127.0.0.1';
+ var REMOTE_HOST = 'localhost';
+ var UNAUTHENTICATED_HOST = 'example.test';
+ var HTTP_PORT = 8000;
+ var HTTPS_PORT = 8443;
+ try {
+ // In W3C test, we can get the hostname and port number in config.json
+ // using wptserve's built-in pipe.
+ // http://wptserve.readthedocs.org/en/latest/pipes.html#built-in-pipes
+ HTTP_PORT = eval('{{ports[http][0]}}');
+ HTTPS_PORT = eval('{{ports[https][0]}}');
+ ORIGINAL_HOST = eval('\'{{host}}\'');
+ REMOTE_HOST = 'www1.' + ORIGINAL_HOST;
+ } catch (e) {
+ }
+ return {
+ HTTP_ORIGIN: 'http://' + ORIGINAL_HOST + ':' + HTTP_PORT,
+ HTTPS_ORIGIN: 'https://' + ORIGINAL_HOST + ':' + HTTPS_PORT,
+ HTTPS_ORIGIN_WITH_CREDS: 'https://foo:bar@' + ORIGINAL_HOST + ':' + HTTPS_PORT,
+ HTTP_REMOTE_ORIGIN: 'http://' + REMOTE_HOST + ':' + HTTP_PORT,
+ HTTPS_REMOTE_ORIGIN: 'https://' + REMOTE_HOST + ':' + HTTPS_PORT,
+ HTTPS_REMOTE_ORIGIN_WITH_CREDS: 'https://foo:bar@' + REMOTE_HOST + ':' + HTTPS_PORT,
+ UNAUTHENTICATED_ORIGIN: 'http://' + UNAUTHENTICATED_HOST + ':' + HTTP_PORT
+ };
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/indexeddb-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/indexeddb-worker.js
new file mode 100644
index 00000000000..ef89550b3e0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/indexeddb-worker.js
@@ -0,0 +1,26 @@
+var port;
+self.addEventListener('message', function(e) {
+ var message = e.data;
+ if ('port' in message)
+ doIndexedDBTest(message.port);
+ });
+
+function doIndexedDBTest(port) {
+ var delete_request = indexedDB.deleteDatabase('db');
+ delete_request.onsuccess = function() {
+ var open_request = indexedDB.open('db');
+ open_request.onupgradeneeded = function() {
+ var db = open_request.result;
+ db.createObjectStore('store');
+ };
+ open_request.onsuccess = function() {
+ var db = open_request.result;
+ var tx = db.transaction('store', 'readwrite');
+ var store = tx.objectStore('store');
+ store.put('value', 'key');
+ tx.oncomplete = function() {
+ port.postMessage('done');
+ };
+ };
+ };
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/install-event-type-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/install-event-type-worker.js
new file mode 100644
index 00000000000..d729afa090c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/install-event-type-worker.js
@@ -0,0 +1,8 @@
+importScripts('worker-testharness.js');
+
+self.oninstall = function(event) {
+ assert_true(event instanceof ExtendableEvent);
+ assert_equals(event.type, 'install');
+ assert_false(event.cancelable);
+ assert_false(event.bubbles);
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js
new file mode 100644
index 00000000000..2ed7ef4bdf6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces-worker.sub.js
@@ -0,0 +1,108 @@
+importScripts('interfaces.js');
+importScripts('worker-testharness.js');
+importScripts('../resources/testharness-helpers.js');
+
+var EVENT_HANDLER = 'object';
+
+test(function() {
+ verify_interface('ServiceWorkerGlobalScope',
+ self,
+ {
+ clients: 'object',
+ close: 'function',
+ registration: 'object',
+ skipWaiting: 'function',
+
+ onactivate: EVENT_HANDLER,
+ onfetch: EVENT_HANDLER,
+ oninstall: EVENT_HANDLER,
+ onmessage: EVENT_HANDLER
+ });
+ }, 'ServiceWorkerGlobalScope');
+
+test(function() {
+ verify_interface('Clients',
+ self.clients,
+ {
+ claim: 'function',
+ matchAll: 'function'
+ });
+ }, 'Clients');
+
+test(function() {
+ verify_interface('Client');
+ // FIXME: Get an instance and test it, or ensure property exists on
+ // prototype.
+ }, 'Client');
+
+test(function() {
+ verify_interface('WindowClient');
+ // FIXME: Get an instance and test it, or ensure property exists on
+ // prototype.
+ }, 'WindowClient');
+
+test(function() {
+ verify_interface('CacheStorage',
+ self.caches,
+ {
+ match: 'function',
+ has: 'function',
+ open: 'function',
+ delete: 'function',
+ keys: 'function'
+ });
+ }, 'CacheStorage');
+
+promise_test(function(t) {
+ return create_temporary_cache(t)
+ .then(function(cache) {
+ verify_interface('Cache',
+ cache,
+ {
+ match: 'function',
+ matchAll: 'function',
+ add: 'function',
+ addAll: 'function',
+ put: 'function',
+ delete: 'function',
+ keys: 'function'
+ });
+ });
+ }, 'Cache');
+
+test(function() {
+ var req = new Request('http://{{host}}/',
+ {method: 'POST',
+ headers: [['Content-Type', 'Text/Html']]});
+ assert_equals(
+ new ExtendableEvent('ExtendableEvent').type,
+ 'ExtendableEvent', 'Type of ExtendableEvent should be ExtendableEvent');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req}).type,
+ 'FetchEvent', 'Type of FetchEvent should be FetchEvent');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req}).cancelable,
+ false, 'Default FetchEvent.cancelable should be false');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req}).bubbles,
+ false, 'Default FetchEvent.bubbles should be false');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req}).clientId,
+ null, 'Default FetchEvent.clientId should be null');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req}).isReload,
+ false, 'Default FetchEvent.isReload should be false');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req, cancelable: false}).cancelable,
+ false, 'FetchEvent.cancelable should be false');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req, clientId : 'test-client-id'}).clientId, 'test-client-id',
+ 'FetchEvent.clientId with option {clientId : "test-client-id"} should be "test-client-id"');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request: req, isReload : true}).isReload, true,
+ 'FetchEvent.isReload with option {isReload : true} should be true');
+ assert_equals(
+ new FetchEvent('FetchEvent', {request : req, isReload : true}).request.url,
+ 'http://{{host}}/',
+ 'FetchEvent.request.url should return the value it was initialized to');
+ }, 'Event constructors');
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces.js
new file mode 100644
index 00000000000..eb00df65ff3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/interfaces.js
@@ -0,0 +1,15 @@
+function verify_interface(name, instance, attributes) {
+ assert_true(name in self,
+ name + ' should be an defined type');
+ if (instance) {
+ assert_true(instance instanceof self[name],
+ instance + ' should be an instance of ' + name);
+ Object.keys(attributes || {}).forEach(function(attribute) {
+ var type = attributes[attribute];
+ assert_true(attribute in instance,
+ attribute + ' should be an attribute of ' + name);
+ assert_equals(typeof instance[attribute], type,
+ attribute + ' should be of type ' + type);
+ });
+ }
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html
new file mode 100644
index 00000000000..f111bd9244e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-iframe.https.html
@@ -0,0 +1,29 @@
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+
+function xhr_send(method, data) {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ if (xhr.getResponseHeader('Content-Type') !== null) {
+ reject('Content-Type must be null.');
+ }
+ resolve();
+ };
+ xhr.onerror = function() {
+ reject('XHR must succeed.');
+ };
+ xhr.responseType = 'text';
+ xhr.open(method, './dummy?test', true);
+ xhr.send(data);
+ });
+}
+
+
+window.addEventListener('message', function(evt) {
+ var port = evt.ports[0];
+ xhr_send('POST', 'test string')
+ .then(function() { port.postMessage({results: 'finish'}); })
+ .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-worker.js
new file mode 100644
index 00000000000..93f496ef44e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-blobtype-worker.js
@@ -0,0 +1,10 @@
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ if (url.indexOf('dummy?test') == -1) {
+ return;
+ }
+ event.respondWith(new Promise(function(resolve) {
+ // null byte in blob type
+ resolve(new Response(new Blob([],{type: 'a\0b'})));
+ }));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py
new file mode 100644
index 00000000000..c91250a9d1f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding-with-flush.py
@@ -0,0 +1,11 @@
+import time
+def main(request, response):
+ response.headers.set("Content-Type", "application/javascript")
+ response.headers.set("Transfer-encoding", "chunked")
+ response.write_status_headers()
+
+ time.sleep(1)
+ response.explicit_flush = True
+
+ response.writer.write("XX\r\n\r\n")
+ response.writer.flush()
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding.py
new file mode 100644
index 00000000000..ae2c1f21b2e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-chunked-encoding.py
@@ -0,0 +1,2 @@
+def main(request, response):
+ return [("Content-Type", "application/javascript"), ("Transfer-encoding", "chunked")], "XX\r\n\r\n"
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-iframe.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-iframe.https.html
new file mode 100644
index 00000000000..19f302c3510
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-iframe.https.html
@@ -0,0 +1,26 @@
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+
+function xhr_send(method, data) {
+ return new Promise(function(resolve, reject) {
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() {
+ reject('XHR must fail.');
+ };
+ xhr.onerror = function() {
+ resolve();
+ };
+ xhr.responseType = 'text';
+ xhr.open(method, './dummy?test', true);
+ xhr.send(data);
+ });
+}
+
+
+window.addEventListener('message', function(evt) {
+ var port = evt.ports[0];
+ xhr_send('POST', 'test string')
+ .then(function() { port.postMessage({results: 'finish'}); })
+ .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-worker.js
new file mode 100644
index 00000000000..31e7f29d06f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/invalid-header-worker.js
@@ -0,0 +1,12 @@
+self.addEventListener('fetch', function(event) {
+ var url = event.request.url;
+ if (url.indexOf('dummy?test') == -1) {
+ return;
+ }
+ event.respondWith(new Promise(function(resolve) {
+ var headers = new Headers;
+ headers.append('foo', 'foo');
+ headers.append('foo', 'b\0r'); // header value with a null byte
+ resolve(new Response('hello world', {'headers': headers}));
+ }));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/load_worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/load_worker.js
new file mode 100644
index 00000000000..2c80f25a3db
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/load_worker.js
@@ -0,0 +1,29 @@
+self.onmessage = function (evt) {
+ if (evt.data == "xhr") {
+ var xhr = new XMLHttpRequest();
+ xhr.open("GET", "synthesized-response.txt", true);
+ xhr.responseType = "text";
+ xhr.send();
+ xhr.onload = function (evt) {
+ postMessage(xhr.responseText);
+ };
+ xhr.onerror = function() {
+ postMessage("XHR failed!");
+ };
+ } else if (evt.data == "fetch") {
+ fetch("synthesized-response.txt")
+ .then(function(response) {
+ return response.text();
+ })
+ .then(function(data) {
+ postMessage(data);
+ })
+ .catch(function(error) {
+ postMessage("Fetch failed!");
+ });
+ } else if (evt.data == "importScripts") {
+ importScripts("synthesized-response.js");
+ } else {
+ throw "Unexpected message! " + evt.data;
+ }
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/malformed-worker.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/malformed-worker.py
new file mode 100644
index 00000000000..501521ff3e3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/malformed-worker.py
@@ -0,0 +1,10 @@
+def main(request, response):
+ headers = [("Content-Type", "application/javascript")]
+
+ body = {'parse-error': 'var foo = function() {;',
+ 'undefined-error': 'foo.bar = 42;',
+ 'uncaught-exception': 'throw new DOMException("AbortError");',
+ 'caught-exception': 'try { throw new Error; } catch(e) {}',
+ 'import-malformed-script': 'importScripts("malformed-worker.py?parse-error");',
+ 'import-no-such-script': 'importScripts("no-such-script.js");'}[request.url_parts.query]
+ return headers, body
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/mime-type-worker.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/mime-type-worker.py
new file mode 100644
index 00000000000..a16684de5cb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/mime-type-worker.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ if 'mime' in request.GET:
+ return [('Content-Type', request.GET['mime'])], ""
+ return [], ""
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html
new file mode 100644
index 00000000000..c1441ba685a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-other-origin.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<script src="get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js"></script>
+<script>
+var host_info = get_host_info();
+var SCOPE = 'navigation-redirect-scope1.py';
+var SCRIPT = 'navigation-redirect-worker.js';
+
+var registration;
+var worker;
+var wait_for_worker_promise = navigator.serviceWorker.getRegistration(SCOPE)
+ .then(function(reg) {
+ if (reg)
+ return reg.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(SCRIPT, {scope: SCOPE});
+ })
+ .then(function(reg) {
+ registration = reg;
+ worker = reg.installing;
+ return new Promise(function(resolve) {
+ worker.addEventListener('statechange', function() {
+ if (worker.state == 'activated')
+ resolve();
+ });
+ });
+ });
+
+function send_result(message_id, result) {
+ window.parent.postMessage(
+ {id: message_id, result: result},
+ host_info['HTTPS_ORIGIN']);
+}
+
+function get_intercepted_urls(worker) {
+ return new Promise(function(resolve) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(msg) { resolve(msg.data.urls); };
+ worker.postMessage({port: channel.port2}, [channel.port2]);
+ });
+}
+
+window.addEventListener('message', on_message, false);
+
+function on_message(e) {
+ if (e.origin != host_info['HTTPS_ORIGIN']) {
+ console.error('invalid origin: ' + e.origin);
+ return;
+ }
+ if (e.data.message == 'wait_for_worker') {
+ wait_for_worker_promise.then(function() { send_result(e.data.id, 'ok'); });
+ } else if (e.data.message == 'get_intercepted_urls') {
+ get_intercepted_urls(worker)
+ .then(function(urls) {
+ send_result(e.data.id, urls);
+ });
+ } else if (e.data.message == 'unregister') {
+ registration.unregister()
+ .then(function() {
+ send_result(e.data.id, 'ok');
+ });
+ }
+}
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py
new file mode 100644
index 00000000000..4b40762d89f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-out-scope.py
@@ -0,0 +1,15 @@
+def main(request, response):
+ if "url" in request.GET:
+ headers = [("Location", request.GET["url"])]
+ return 302, headers, ''
+
+ return [], '''
+<!DOCTYPE html>
+<script>
+ window.parent.postMessage(
+ {
+ id: 'last_url',
+ result: location.href
+ }, '*');
+</script>
+'''
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py
new file mode 100644
index 00000000000..4b40762d89f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope1.py
@@ -0,0 +1,15 @@
+def main(request, response):
+ if "url" in request.GET:
+ headers = [("Location", request.GET["url"])]
+ return 302, headers, ''
+
+ return [], '''
+<!DOCTYPE html>
+<script>
+ window.parent.postMessage(
+ {
+ id: 'last_url',
+ result: location.href
+ }, '*');
+</script>
+'''
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py
new file mode 100644
index 00000000000..4b40762d89f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-scope2.py
@@ -0,0 +1,15 @@
+def main(request, response):
+ if "url" in request.GET:
+ headers = [("Location", request.GET["url"])]
+ return 302, headers, ''
+
+ return [], '''
+<!DOCTYPE html>
+<script>
+ window.parent.postMessage(
+ {
+ id: 'last_url',
+ result: location.href
+ }, '*');
+</script>
+'''
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-worker.js
new file mode 100644
index 00000000000..cb15b3ff113
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/navigation-redirect-worker.js
@@ -0,0 +1,75 @@
+// We store an empty response for each fetch event request we see
+// in this Cache object so we can get the list of urls in the
+// message event.
+var cacheName = 'urls-' + self.registration.scope;
+
+var waitUntilPromiseList = [];
+
+self.addEventListener('message', function(event) {
+ var urls;
+ event.waitUntil(Promise.all(waitUntilPromiseList).then(function() {
+ waitUntilPromiseList = [];
+ return caches.open(cacheName);
+ }).then(function(cache) {
+ return cache.keys();
+ }).then(function(requestList) {
+ urls = requestList.map(function(request) { return request.url; });
+ return caches.delete(cacheName);
+ }).then(function() {
+ event.data.port.postMessage({urls: urls});
+ }));
+ });
+
+function get_query_params(url) {
+ var search = (new URL(url)).search;
+ if (!search) {
+ return {};
+ }
+ var ret = {};
+ var params = search.substring(1).split('&');
+ params.forEach(function(param) {
+ var element = param.split('=');
+ ret[decodeURIComponent(element[0])] = decodeURIComponent(element[1]);
+ });
+ return ret;
+}
+
+self.addEventListener('fetch', function(event) {
+ var waitUntilPromise = caches.open(cacheName).then(function(cache) {
+ return cache.put(event.request, new Response());
+ });
+ event.waitUntil(waitUntilPromise);
+
+ var params = get_query_params(event.request.url);
+ if (!params['sw']) {
+ // To avoid races, add the waitUntil() promise to our global list.
+ // If we get a message event before we finish here, it will wait
+ // these promises to complete before proceeding to read from the
+ // cache.
+ waitUntilPromiseList.push(waitUntilPromise);
+ return;
+ }
+
+ event.respondWith(waitUntilPromise.then(function() {
+ if (params['sw'] == 'gen') {
+ return Response.redirect(params['url']);
+ } else if (params['sw'] == 'fetch') {
+ return fetch(event.request);
+ } else if (params['sw'] == 'opaque') {
+ return fetch(new Request(event.request.url, {redirect: 'manual'}));
+ } else if (params['sw'] == 'opaqueThroughCache') {
+ var url = event.request.url;
+ var cache;
+ return caches.delete(url)
+ .then(function() { return self.caches.open(url); })
+ .then(function(c) {
+ cache = c;
+ return fetch(new Request(url, {redirect: 'manual'}));
+ })
+ .then(function(res) { return cache.put(event.request, res); })
+ .then(function() { return cache.match(url); });
+ }
+
+ // unexpected... trigger an interception failure
+ }));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js
new file mode 100644
index 00000000000..7c97014fd04
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-from-nested-event-worker.js
@@ -0,0 +1,13 @@
+var max_nesting_level = 8;
+
+self.addEventListener('message', function(event) {
+ var level = event.data;
+ if (level < max_nesting_level)
+ dispatchEvent(new MessageEvent('message', { data: level + 1 }));
+ throw Error('error at level ' + level);
+ });
+
+self.addEventListener('activate', function(event) {
+ dispatchEvent(new MessageEvent('message', { data: 1 }));
+ });
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js
new file mode 100644
index 00000000000..0bd9d318b24
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-cancel-worker.js
@@ -0,0 +1,3 @@
+self.onerror = function(event) { return true; };
+
+self.addEventListener('activate', function(event) { throw new Error(); });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js
new file mode 100644
index 00000000000..d56c9511391
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-then-prevent-default-worker.js
@@ -0,0 +1,7 @@
+// Ensure we can handle multiple error handlers. One error handler
+// calling preventDefault should cause the event to be treated as
+// handled.
+self.addEventListener('error', function(event) {});
+self.addEventListener('error', function(event) { event.preventDefault(); });
+self.addEventListener('error', function(event) {});
+self.addEventListener('activate', function(event) { throw new Error(); });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js
new file mode 100644
index 00000000000..eb12ae862c5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-with-empty-onerror-worker.js
@@ -0,0 +1,2 @@
+self.addEventListener('error', function(event) {});
+self.addEventListener('activate', function(event) { throw new Error(); });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-worker.js
new file mode 100644
index 00000000000..1e88ac5c4e7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/onactivate-throw-error-worker.js
@@ -0,0 +1,7 @@
+// Ensure we can handle multiple activate handlers. One handler throwing an
+// error should cause the event dispatch to be treated as having unhandled
+// errors.
+self.addEventListener('activate', function(event) {});
+self.addEventListener('activate', function(event) {});
+self.addEventListener('activate', function(event) { throw new Error(); });
+self.addEventListener('activate', function(event) {});
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js
new file mode 100644
index 00000000000..6729ab61a37
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-from-nested-event-worker.js
@@ -0,0 +1,12 @@
+var max_nesting_level = 8;
+
+self.addEventListener('message', function(event) {
+ var level = event.data;
+ if (level < max_nesting_level)
+ dispatchEvent(new MessageEvent('message', { data: level + 1 }));
+ throw Error('error at level ' + level);
+ });
+
+self.addEventListener('install', function(event) {
+ dispatchEvent(new MessageEvent('message', { data: 1 }));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js
new file mode 100644
index 00000000000..c2c499ab1a3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-cancel-worker.js
@@ -0,0 +1,3 @@
+self.onerror = function(event) { return true; };
+
+self.addEventListener('install', function(event) { throw new Error(); });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js
new file mode 100644
index 00000000000..7667c2781d0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-then-prevent-default-worker.js
@@ -0,0 +1,7 @@
+// Ensure we can handle multiple error handlers. One error handler
+// calling preventDefault should cause the event to be treated as
+// handled.
+self.addEventListener('error', function(event) {});
+self.addEventListener('error', function(event) { event.preventDefault(); });
+self.addEventListener('error', function(event) {});
+self.addEventListener('install', function(event) { throw new Error(); });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js
new file mode 100644
index 00000000000..8f56d1bf149
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-with-empty-onerror-worker.js
@@ -0,0 +1,2 @@
+self.addEventListener('error', function(event) {});
+self.addEventListener('install', function(event) { throw new Error(); });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-worker.js
new file mode 100644
index 00000000000..cc2f6d7e5e7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/oninstall-throw-error-worker.js
@@ -0,0 +1,7 @@
+// Ensure we can handle multiple install handlers. One handler throwing an
+// error should cause the event dispatch to be treated as having unhandled
+// errors.
+self.addEventListener('install', function(event) {});
+self.addEventListener('install', function(event) {});
+self.addEventListener('install', function(event) { throw new Error(); });
+self.addEventListener('install', function(event) {});
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/other.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/other.html
new file mode 100644
index 00000000000..b9f35043877
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/other.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<title>Other</title>
+Here's an other html file.
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/override_assert_object_equals.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/override_assert_object_equals.js
new file mode 100644
index 00000000000..835046d472b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/override_assert_object_equals.js
@@ -0,0 +1,58 @@
+// .body attribute of Request and Response object are experimental feture. It is
+// enabled when --enable-experimental-web-platform-features flag is set.
+// Touching this attribute can change the behavior of the objects. To avoid
+// touching it while comparing the objects in LayoutTest, we overwrite
+// assert_object_equals method.
+
+(function() {
+ var original_assert_object_equals = self.assert_object_equals;
+ function _brand(object) {
+ return Object.prototype.toString.call(object).match(/^\[object (.*)\]$/)[1];
+ }
+ var assert_request_equals = function(actual, expected, prefix) {
+ if (typeof actual !== 'object') {
+ assert_equals(actual, expected, prefix);
+ return;
+ }
+ assert_true(actual instanceof Request, prefix);
+ assert_true(expected instanceof Request, prefix);
+ assert_equals(actual.bodyUsed, expected.bodyUsed, prefix + '.bodyUsed');
+ assert_equals(actual.method, expected.method, prefix + '.method');
+ assert_equals(actual.url, expected.url, prefix + '.url');
+ original_assert_object_equals(actual.headers, expected.headers,
+ prefix + '.headers');
+ assert_equals(actual.context, expected.context, prefix + '.context');
+ assert_equals(actual.referrer, expected.referrer, prefix + '.referrer');
+ assert_equals(actual.mode, expected.mode, prefix + '.mode');
+ assert_equals(actual.credentials, expected.credentials,
+ prefix + '.credentials');
+ assert_equals(actual.cache, expected.cache, prefix + '.cache');
+ };
+ var assert_response_equals = function(actual, expected, prefix) {
+ if (typeof actual !== 'object') {
+ assert_equals(actual, expected, prefix);
+ return;
+ }
+ assert_true(actual instanceof Response, prefix);
+ assert_true(expected instanceof Response, prefix);
+ assert_equals(actual.bodyUsed, expected.bodyUsed, prefix + '.bodyUsed');
+ assert_equals(actual.type, expected.type, prefix + '.type');
+ assert_equals(actual.url, expected.url, prefix + '.url');
+ assert_equals(actual.status, expected.status, prefix + '.status');
+ assert_equals(actual.statusText, expected.statusText,
+ prefix + '.statusText');
+ original_assert_object_equals(actual.headers, expected.headers,
+ prefix + '.headers');
+ };
+ var assert_object_equals = function(actual, expected, description) {
+ var prefix = (description ? description + ': ' : '') + _brand(expected);
+ if (expected instanceof Request) {
+ assert_request_equals(actual, expected, prefix);
+ } else if (expected instanceof Response) {
+ assert_response_equals(actual, expected, prefix);
+ } else {
+ original_assert_object_equals(actual, expected, description);
+ }
+ };
+ self.assert_object_equals = assert_object_equals;
+})();
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/performance-timeline-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/performance-timeline-worker.js
new file mode 100644
index 00000000000..6f7df75e921
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/performance-timeline-worker.js
@@ -0,0 +1,58 @@
+importScripts('/resources/testharness.js');
+
+promise_test(function(test) {
+ var durationMsec = 100;
+ // There are limits to our accuracy here. Timers may fire up to a
+ // millisecond early due to platform-dependent rounding. In addition
+ // the performance API introduces some rounding as well to prevent
+ // timing attacks.
+ var accuracy = 1.5;
+ return new Promise(function(resolve) {
+ performance.mark('startMark');
+ setTimeout(resolve, durationMsec);
+ }).then(function() {
+ performance.mark('endMark');
+ performance.measure('measure', 'startMark', 'endMark');
+ var startMark = performance.getEntriesByName('startMark')[0];
+ var endMark = performance.getEntriesByName('endMark')[0];
+ var measure = performance.getEntriesByType('measure')[0];
+ assert_equals(measure.startTime, startMark.startTime);
+ assert_approx_equals(endMark.startTime - startMark.startTime,
+ measure.duration, 0.001);
+ assert_greater_than(measure.duration, durationMsec - accuracy);
+ assert_equals(performance.getEntriesByType('mark').length, 2);
+ assert_equals(performance.getEntriesByType('measure').length, 1);
+ performance.clearMarks('startMark');
+ performance.clearMeasures('measure');
+ assert_equals(performance.getEntriesByType('mark').length, 1);
+ assert_equals(performance.getEntriesByType('measure').length, 0);
+ });
+ }, 'User Timing');
+
+promise_test(function(test) {
+ return fetch('dummy.txt')
+ .then(function(resp) {
+ return resp.text();
+ })
+ .then(function(text) {
+ var expectedResources = ['testharness.js', 'dummy.txt'];
+ assert_equals(performance.getEntriesByType('resource').length, expectedResources.length);
+ for (var i = 0; i < expectedResources.length; i++) {
+ var entry = performance.getEntriesByType('resource')[i];
+ assert_true(entry.name.endsWith(expectedResources[i]));
+ assert_equals(entry.workerStart, 0);
+ assert_greater_than(entry.startTime, 0);
+ assert_greater_than(entry.responseEnd, entry.startTime);
+ }
+ return new Promise(function(resolve) {
+ performance.onresourcetimingbufferfull = resolve;
+ performance.setResourceTimingBufferSize(expectedResources.length);
+ });
+ })
+ .then(function() {
+ performance.clearResourceTimings();
+ assert_equals(performance.getEntriesByType('resource').length, 0);
+ })
+ }, 'Resource Timing');
+
+done();
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js
new file mode 100644
index 00000000000..3475321f4a6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-msgport-to-client-worker.js
@@ -0,0 +1,20 @@
+self.onmessage = function(e) {
+ self.clients.matchAll().then(function(clients) {
+ clients.forEach(function(client) {
+ var messageChannel = new MessageChannel();
+ messageChannel.port1.onmessage =
+ onMessageViaMessagePort.bind(null, client);
+ client.postMessage({port: messageChannel.port2},
+ [messageChannel.port2]);
+ });
+ });
+};
+
+function onMessageViaMessagePort(client, e) {
+ var message = e.data;
+ if ('value' in message) {
+ client.postMessage({ack: 'Acking value: ' + message.value});
+ } else if ('done' in message) {
+ client.postMessage({done: true});
+ }
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-to-client-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-to-client-worker.js
new file mode 100644
index 00000000000..290a4a9b3e9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-to-client-worker.js
@@ -0,0 +1,10 @@
+self.onmessage = function(e) {
+ self.clients.matchAll().then(function(clients) {
+ clients.forEach(function(client) {
+ client.postMessage('Sending message via clients');
+ if (!Array.isArray(clients))
+ client.postMessage('clients is not an array');
+ client.postMessage('quit');
+ });
+ });
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-worker.js
new file mode 100644
index 00000000000..858cf04267c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/postmessage-worker.js
@@ -0,0 +1,19 @@
+var port;
+
+// Exercise the 'onmessage' handler:
+self.onmessage = function(e) {
+ var message = e.data;
+ if ('port' in message) {
+ port = message.port;
+ }
+};
+
+// And an event listener:
+self.addEventListener('message', function(e) {
+ var message = e.data;
+ if ('value' in message) {
+ port.postMessage('Acking value: ' + message.value);
+ } else if ('done' in message) {
+ port.postMessage('quit');
+ }
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect.py
new file mode 100644
index 00000000000..20521b00c9c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/redirect.py
@@ -0,0 +1,25 @@
+def main(request, response):
+ if 'Status' in request.GET:
+ status = int(request.GET["Status"])
+ else:
+ status = 302
+
+ headers = []
+
+ url = request.GET['Redirect']
+ headers.append(("Location", url))
+
+ if "ACAOrigin" in request.GET:
+ for item in request.GET["ACAOrigin"].split(","):
+ headers.append(("Access-Control-Allow-Origin", item))
+
+ for suffix in ["Headers", "Methods", "Credentials"]:
+ query = "ACA%s" % suffix
+ header = "Access-Control-Allow-%s" % suffix
+ if query in request.GET:
+ headers.append((header, request.GET[query]))
+
+ if "ACEHeaders" in request.GET:
+ headers.append(("Access-Control-Expose-Headers", request.GET["ACEHeaders"]))
+
+ return status, headers, ""
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/referer-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/referer-iframe.html
new file mode 100644
index 00000000000..31cadcd2c7a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/referer-iframe.html
@@ -0,0 +1,39 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js"></script>
+<script>
+function check_referer(url, expected_referer) {
+ return fetch(url)
+ .then(function(res) { return res.json(); })
+ .then(function(headers) {
+ if (headers['referer'] === expected_referer) {
+ return Promise.resolve();
+ } else {
+ return Promise.reject('Referer for ' + url + ' must be ' +
+ expected_referer + ' but got ' +
+ headers['referer']);
+ }
+ });
+}
+
+window.addEventListener('message', function(evt) {
+ var host_info = get_host_info();
+ var port = evt.ports[0];
+ check_referer('request-headers.py?ignore=true',
+ host_info['HTTPS_ORIGIN'] +
+ base_path() + 'referer-iframe.html')
+ .then(function() {
+ return check_referer(
+ 'request-headers.py',
+ host_info['HTTPS_ORIGIN'] +
+ base_path() + 'fetch-rewrite-worker.js');
+ })
+ .then(function() {
+ return check_referer(
+ 'request-headers.py?url=request-headers.py',
+ host_info['HTTPS_ORIGIN'] +
+ base_path() + 'fetch-rewrite-worker.js');
+ })
+ .then(function() { port.postMessage({results: 'finish'}); })
+ .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
+ });
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/register-closed-window-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/register-closed-window-iframe.html
new file mode 100644
index 00000000000..ed743ea056e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/register-closed-window-iframe.html
@@ -0,0 +1,16 @@
+<html>
+<head>
+<script>
+window.addEventListener('message', function(evt) {
+ if (evt.data === 'START') {
+ var w = window.open('./');
+ var sw = w.navigator.serviceWorker;
+ w.close();
+ w = null;
+ sw.register('doesntmatter.js');
+ parent.postMessage('OK', '*');
+ }
+});
+</script>
+</head>
+</html>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/registration-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/registration-worker.js
new file mode 100644
index 00000000000..44d1d2774a2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/registration-worker.js
@@ -0,0 +1 @@
+// empty for now
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/reject-install-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/reject-install-worker.js
new file mode 100644
index 00000000000..41f07fd5db8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/reject-install-worker.js
@@ -0,0 +1,3 @@
+self.oninstall = function(event) {
+ event.waitUntil(Promise.reject());
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-end-to-end-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-end-to-end-worker.js
new file mode 100644
index 00000000000..323c7f24367
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-end-to-end-worker.js
@@ -0,0 +1,32 @@
+var port = undefined;
+
+onmessage = function(e) {
+ var message = e.data;
+ if (typeof message === 'object' && 'port' in message) {
+ port = message.port;
+ }
+};
+
+onfetch = function(e) {
+ var headers = {};
+ var errorNameWhileAppendingHeader;
+ for (var header of e.request.headers) {
+ var key = header[0], value = header[1];
+ headers[key] = value;
+ }
+ var errorNameWhileAddingHeader = '';
+ try {
+ e.request.headers.append('Test-Header', 'TestValue');
+ } catch (e) {
+ errorNameWhileAppendingHeader = e.name;
+ }
+ port.postMessage({
+ url: e.request.url,
+ mode: e.request.mode,
+ method: e.request.method,
+ referrer: e.request.referrer,
+ headers: headers,
+ headerSize: e.request.headers.size,
+ errorNameWhileAppendingHeader: errorNameWhileAppendingHeader
+ });
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-headers.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-headers.py
new file mode 100644
index 00000000000..29897f4ecff
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/request-headers.py
@@ -0,0 +1,6 @@
+import json
+
+def main(request, response):
+ data = {key:request.headers[key] for key,value in request.headers.iteritems()}
+
+ return [("Content-Type", "application/json")], json.dumps(data)
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.html
new file mode 100644
index 00000000000..2af6793696b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-iframe.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<script src="empty.js"></script>
+<script src="dummy.js"></script>
+<script src="redirect.py?Redirect=empty.js"></script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js
new file mode 100644
index 00000000000..481a6536afc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/resource-timing-worker.js
@@ -0,0 +1,5 @@
+self.addEventListener('fetch', function(event) {
+ if (event.request.url.indexOf('dummy.js') != -1) {
+ event.respondWith(new Response());
+ }
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/service-worker-csp-worker.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/service-worker-csp-worker.py
new file mode 100644
index 00000000000..4e5c6f3b6ea
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/service-worker-csp-worker.py
@@ -0,0 +1,153 @@
+bodyDefault = '''
+importScripts('worker-testharness.js');
+importScripts('test-helpers.sub.js');
+importScripts('../resources/get-host-info.sub.js');
+
+var host_info = get_host_info();
+
+test(function() {
+ var import_script_failed = false;
+ try {
+ importScripts(host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'empty.js');
+ } catch(e) {
+ import_script_failed = true;
+ }
+ assert_true(import_script_failed,
+ 'Importing the other origins script should fail.');
+ }, 'importScripts test for default-src');
+
+async_test(function(t) {
+ fetch(host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'fetch-access-control.py?ACAOrigin=*',
+ {mode: 'cors'})
+ .then(function(response){
+ assert_unreached('fetch should fail.');
+ }, function(){
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Fetch test for default-src');
+
+async_test(function(t) {
+ var REDIRECT_URL = host_info.HTTPS_ORIGIN +
+ base_path() + 'redirect.py?Redirect=';
+ var OTHER_BASE_URL = host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'fetch-access-control.py?'
+ fetch(REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*'),
+ {mode: 'cors'})
+ .then(function(response){
+ assert_unreached('Redirected fetch should fail.');
+ }, function(){
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Redirected fetch test for default-src');'''
+
+bodyScript = '''
+importScripts('worker-testharness.js');
+importScripts('test-helpers.sub.js');
+importScripts('../resources/get-host-info.sub.js');
+
+var host_info = get_host_info();
+
+test(function() {
+ var import_script_failed = false;
+ try {
+ importScripts(host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'empty.js');
+ } catch(e) {
+ import_script_failed = true;
+ }
+ assert_true(import_script_failed,
+ 'Importing the other origins script should fail.');
+ }, 'importScripts test for script-src');
+
+async_test(function(t) {
+ fetch(host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'fetch-access-control.py?ACAOrigin=*',
+ {mode: 'cors'})
+ .then(function(response){
+ t.done();
+ }, function(){
+ assert_unreached('fetch should not fail.');
+ })
+ .catch(unreached_rejection(t));
+ }, 'Fetch test for script-src');
+
+async_test(function(t) {
+ var REDIRECT_URL = host_info.HTTPS_ORIGIN +
+ base_path() + 'redirect.py?Redirect=';
+ var OTHER_BASE_URL = host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'fetch-access-control.py?'
+ fetch(REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*'),
+ {mode: 'cors'})
+ .then(function(response){
+ t.done();
+ }, function(){
+ assert_unreached('Redirected fetch should not fail.');
+ })
+ .catch(unreached_rejection(t));
+ }, 'Redirected fetch test for script-src');'''
+
+bodyConnect = '''
+importScripts('worker-testharness.js');
+importScripts('test-helpers.sub.js');
+importScripts('../resources/get-host-info.sub.js');
+
+var host_info = get_host_info();
+
+test(function() {
+ var import_script_failed = false;
+ try {
+ importScripts(host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'empty.js');
+ } catch(e) {
+ import_script_failed = true;
+ }
+ assert_false(import_script_failed,
+ 'Importing the other origins script should not fail.');
+ }, 'importScripts test for connect-src');
+
+async_test(function(t) {
+ fetch(host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'fetch-access-control.py?ACAOrigin=*',
+ {mode: 'cors'})
+ .then(function(response){
+ assert_unreached('fetch should fail.');
+ }, function(){
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Fetch test for connect-src');
+
+async_test(function(t) {
+ var REDIRECT_URL = host_info.HTTPS_ORIGIN +
+ base_path() + 'redirect.py?Redirect=';
+ var OTHER_BASE_URL = host_info.HTTPS_REMOTE_ORIGIN +
+ base_path() + 'fetch-access-control.py?'
+ fetch(REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*'),
+ {mode: 'cors'})
+ .then(function(response){
+ assert_unreached('Redirected fetch should fail.');
+ }, function(){
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Redirected fetch test for connect-src');'''
+
+def main(request, response):
+ headers = []
+ headers.append(('Content-Type', 'application/javascript'))
+ directive = request.GET['directive']
+ body = 'ERROR: Unknown directive'
+ if directive == 'default':
+ headers.append(('Content-Security-Policy', "default-src 'self'"))
+ body = bodyDefault
+ elif directive == 'script':
+ headers.append(('Content-Security-Policy', "script-src 'self'"))
+ body = bodyScript
+ elif directive == 'connect':
+ headers.append(('Content-Security-Policy', "connect-src 'self'"))
+ body = bodyConnect
+ return headers, body
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-controlled.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-controlled.js
new file mode 100644
index 00000000000..1ccc2fe3bdb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-controlled.js
@@ -0,0 +1,8 @@
+onconnect = function(e) {
+ var port = e.ports[0];
+ var xhr = new XMLHttpRequest();
+ xhr.onload = function() { port.postMessage(this.responseText); };
+ xhr.onerror = function(e) { port.postMessage(e); };
+ xhr.open('GET', 'dummy.txt?simple', true);
+ xhr.send();
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-import.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-import.js
new file mode 100644
index 00000000000..7c554bd7415
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/shared-worker-import.js
@@ -0,0 +1 @@
+importScripts('import-dummy-shared-worker.js');
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/silence.oga b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/silence.oga
new file mode 100644
index 00000000000..af591880436
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/silence.oga
Binary files differ
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js
new file mode 100644
index 00000000000..f8b5f8c5cb7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple-intercept-worker.js
@@ -0,0 +1,5 @@
+self.onfetch = function(event) {
+ if (event.request.url.indexOf('simple') != -1)
+ event.respondWith(
+ new Response(new Blob(['intercepted by service worker'])));
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.html
new file mode 100644
index 00000000000..0c3e3e78707
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<title>Simple</title>
+Here's a simple html file.
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.txt b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.txt
new file mode 100644
index 00000000000..9e3cb91fb9b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/simple.txt
@@ -0,0 +1 @@
+a simple text file
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-installed-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-installed-worker.js
new file mode 100644
index 00000000000..bf582c77074
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-installed-worker.js
@@ -0,0 +1,24 @@
+self.state = 'starting';
+
+self.addEventListener('install', function() {
+ self.state = 'installing';
+ });
+
+self.addEventListener('message', function(event) {
+ var port = event.data.port;
+ if (self.state !== 'installing') {
+ port.postMessage('FAIL: Worker should be waiting in installed state');
+ return;
+ }
+ self.skipWaiting()
+ .then(function(result) {
+ if (result !== undefined) {
+ port.postMessage('FAIL: Promise should be resolved with undefined');
+ return;
+ }
+ port.postMessage('PASS');
+ })
+ .catch(function(e) {
+ port.postMessage('FAIL: unexpected exception: ' + e);
+ });
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-worker.js
new file mode 100644
index 00000000000..1d6bcb39faf
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/skip-waiting-worker.js
@@ -0,0 +1,25 @@
+importScripts('worker-testharness.js');
+
+promise_test(function() {
+ // wait for the worker to reach "installing" state, otherwise skipWaiting()
+ // will fail. Bug 1228277
+ return new Promise(function(res, rej) {
+ oninstall = res;
+ }).then(() => skipWaiting())
+ .then(function(result) {
+ assert_equals(result, undefined,
+ 'Promise should be resolved with undefined');
+ })
+ .then(function() {
+ var promises = [];
+ for (var i = 0; i < 8; ++i)
+ promises.push(self.skipWaiting());
+ return Promise.all(promises);
+ })
+ .then(function(results) {
+ results.forEach(function(r) {
+ assert_equals(r, undefined,
+ 'Promises should be resolved with undefined');
+ });
+ });
+ }, 'skipWaiting');
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/square.png b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/square.png
new file mode 100644
index 00000000000..01c9666a8de
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/square.png
Binary files differ
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/success.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/success.py
new file mode 100644
index 00000000000..bcbb487d2b2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/success.py
@@ -0,0 +1,8 @@
+def main(request, response):
+ headers = []
+
+ if "ACAOrigin" in request.GET:
+ for item in request.GET["ACAOrigin"].split(","):
+ headers.append(("Access-Control-Allow-Origin", item))
+
+ return headers, "{ \"result\": \"success\" }"
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js
new file mode 100644
index 00000000000..b0ffbd40625
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/test-helpers.sub.js
@@ -0,0 +1,227 @@
+// Adapter for testharness.js-style tests with Service Workers
+
+function service_worker_unregister_and_register(test, url, scope) {
+ if (!scope || scope.length == 0)
+ return Promise.reject(new Error('tests must define a scope'));
+
+ var options = { scope: scope };
+ return service_worker_unregister(test, scope)
+ .then(function() {
+ return navigator.serviceWorker.register(url, options);
+ })
+ .catch(unreached_rejection(test,
+ 'unregister and register should not fail'));
+}
+
+// This unregisters the registration that precisely matches scope. Use this
+// when unregistering by scope. If no registration is found, it just resolves.
+function service_worker_unregister(test, scope) {
+ var absoluteScope = (new URL(scope, window.location).href);
+ return navigator.serviceWorker.getRegistration(scope)
+ .then(function(registration) {
+ if (registration && registration.scope === absoluteScope)
+ return registration.unregister();
+ })
+ .catch(unreached_rejection(test, 'unregister should not fail'));
+}
+
+function service_worker_unregister_and_done(test, scope) {
+ return service_worker_unregister(test, scope)
+ .then(test.done.bind(test));
+}
+
+function unreached_fulfillment(test, prefix) {
+ return test.step_func(function(result) {
+ var error_prefix = prefix || 'unexpected fulfillment';
+ assert_unreached(error_prefix + ': ' + result);
+ });
+}
+
+// Rejection-specific helper that provides more details
+function unreached_rejection(test, prefix) {
+ return test.step_func(function(error) {
+ var reason = error.message || error.name || error;
+ var error_prefix = prefix || 'unexpected rejection';
+ assert_unreached(error_prefix + ': ' + reason);
+ });
+}
+
+// Adds an iframe to the document and returns a promise that resolves to the
+// iframe when it finishes loading. The caller is responsible for removing the
+// iframe later if needed.
+function with_iframe(url) {
+ return new Promise(function(resolve) {
+ var frame = document.createElement('iframe');
+ frame.src = url;
+ frame.onload = function() { resolve(frame); };
+ document.body.appendChild(frame);
+ });
+}
+
+function normalizeURL(url) {
+ return new URL(url, self.location).toString().replace(/#.*$/, '');
+}
+
+function wait_for_update(test, registration) {
+ if (!registration || registration.unregister == undefined) {
+ return Promise.reject(new Error(
+ 'wait_for_update must be passed a ServiceWorkerRegistration'));
+ }
+
+ return new Promise(test.step_func(function(resolve) {
+ registration.addEventListener('updatefound', test.step_func(function() {
+ resolve(registration.installing);
+ }));
+ }));
+}
+
+function wait_for_state(test, worker, state) {
+ if (!worker || worker.state == undefined) {
+ return Promise.reject(new Error(
+ 'wait_for_state must be passed a ServiceWorker'));
+ }
+ if (worker.state === state)
+ return Promise.resolve(state);
+
+ if (state === 'installing') {
+ switch (worker.state) {
+ case 'installed':
+ case 'activating':
+ case 'activated':
+ case 'redundant':
+ return Promise.reject(new Error(
+ 'worker is ' + worker.state + ' but waiting for ' + state));
+ }
+ }
+
+ if (state === 'installed') {
+ switch (worker.state) {
+ case 'activating':
+ case 'activated':
+ case 'redundant':
+ return Promise.reject(new Error(
+ 'worker is ' + worker.state + ' but waiting for ' + state));
+ }
+ }
+
+ if (state === 'activating') {
+ switch (worker.state) {
+ case 'activated':
+ case 'redundant':
+ return Promise.reject(new Error(
+ 'worker is ' + worker.state + ' but waiting for ' + state));
+ }
+ }
+
+ if (state === 'activated') {
+ switch (worker.state) {
+ case 'redundant':
+ return Promise.reject(new Error(
+ 'worker is ' + worker.state + ' but waiting for ' + state));
+ }
+ }
+
+ return new Promise(test.step_func(function(resolve) {
+ worker.addEventListener('statechange', test.step_func(function() {
+ if (worker.state === state)
+ resolve(state);
+ }));
+ }));
+}
+
+// Declare a test that runs entirely in the ServiceWorkerGlobalScope. The |url|
+// is the service worker script URL. This function:
+// - Instantiates a new test with the description specified in |description|.
+// The test will succeed if the specified service worker can be successfully
+// registered and installed.
+// - Creates a new ServiceWorker registration with a scope unique to the current
+// document URL. Note that this doesn't allow more than one
+// service_worker_test() to be run from the same document.
+// - Waits for the new worker to begin installing.
+// - Imports tests results from tests running inside the ServiceWorker.
+function service_worker_test(url, description) {
+ // If the document URL is https://example.com/document and the script URL is
+ // https://example.com/script/worker.js, then the scope would be
+ // https://example.com/script/scope/document.
+ var scope = new URL('scope' + window.location.pathname,
+ new URL(url, window.location)).toString();
+ promise_test(function(test) {
+ return service_worker_unregister_and_register(test, url, scope)
+ .then(function(registration) {
+ add_completion_callback(function() {
+ registration.unregister();
+ });
+ return wait_for_update(test, registration)
+ .then(function(worker) {
+ return fetch_tests_from_worker(worker);
+ });
+ });
+ }, description);
+}
+
+function base_path() {
+ return location.pathname.replace(/\/[^\/]*$/, '/');
+}
+
+function test_login(test, origin, username, password, cookie) {
+ return new Promise(function(resolve, reject) {
+ with_iframe(
+ origin + base_path() +
+ 'resources/fetch-access-control-login.html')
+ .then(test.step_func(function(frame) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = test.step_func(function() {
+ frame.remove();
+ resolve();
+ });
+ frame.contentWindow.postMessage(
+ {username: username, password: password, cookie: cookie},
+ origin, [channel.port2]);
+ }));
+ });
+}
+
+function test_websocket(test, frame, url) {
+ return new Promise(function(resolve, reject) {
+ var ws = new frame.contentWindow.WebSocket(url, ['echo', 'chat']);
+ var openCalled = false;
+ ws.addEventListener('open', test.step_func(function(e) {
+ assert_equals(ws.readyState, 1, "The WebSocket should be open");
+ openCalled = true;
+ ws.close();
+ }), true);
+
+ ws.addEventListener('close', test.step_func(function(e) {
+ assert_true(openCalled, "The WebSocket should be closed after being opened");
+ resolve();
+ }), true);
+
+ ws.addEventListener('error', reject);
+ });
+}
+
+function login(test) {
+ return test_login(test, 'http://{{domains[www1]}}:{{ports[http][0]}}',
+ 'username1', 'password1', 'cookie1')
+ .then(function() {
+ return test_login(test, 'http://{{host}}:{{ports[http][0]}}',
+ 'username2', 'password2', 'cookie2');
+ });
+}
+
+function login_https(test) {
+ return test_login(test, 'https://{{domains[www1]}}:{{ports[https][0]}}',
+ 'username1s', 'password1s', 'cookie1')
+ .then(function() {
+ return test_login(test, 'https://{{host}}:{{ports[https][0]}}',
+ 'username2s', 'password2s', 'cookie2');
+ });
+}
+
+function websocket(test, frame) {
+ return test_websocket(test, frame, get_websocket_url());
+}
+
+function get_websocket_url() {
+ return 'wss://{{host}}:{{ports[wss][0]}}/echo';
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/testharness-helpers.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/testharness-helpers.js
new file mode 100644
index 00000000000..4d7af1ff9ca
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/testharness-helpers.js
@@ -0,0 +1,163 @@
+/*
+ * testharness-helpers contains various useful extensions to testharness.js to
+ * allow them to be used across multiple tests before they have been
+ * upstreamed. This file is intended to be usable from both document and worker
+ * environments, so code should for example not rely on the DOM.
+ */
+
+// Returns a promise that fulfills after the provided |promise| is fulfilled.
+// The |test| succeeds only if |promise| rejects with an exception matching
+// |code|. Accepted values for |code| follow those accepted for assert_throws().
+// The optional |description| describes the test being performed.
+//
+// E.g.:
+// assert_promise_rejects(
+// new Promise(...), // something that should throw an exception.
+// 'NotFoundError',
+// 'Should throw NotFoundError.');
+//
+// assert_promise_rejects(
+// new Promise(...),
+// new TypeError(),
+// 'Should throw TypeError');
+function assert_promise_rejects(promise, code, description) {
+ return promise.then(
+ function() {
+ throw 'assert_promise_rejects: ' + description + ' Promise did not reject.';
+ },
+ function(e) {
+ if (code !== undefined) {
+ assert_throws(code, function() { throw e; }, description);
+ }
+ });
+}
+
+// Asserts that two objects |actual| and |expected| are weakly equal under the
+// following definition:
+//
+// |a| and |b| are weakly equal if any of the following are true:
+// 1. If |a| is not an 'object', and |a| === |b|.
+// 2. If |a| is an 'object', and all of the following are true:
+// 2.1 |a.p| is weakly equal to |b.p| for all own properties |p| of |a|.
+// 2.2 Every own property of |b| is an own property of |a|.
+//
+// This is a replacement for the the version of assert_object_equals() in
+// testharness.js. The latter doesn't handle own properties correctly. I.e. if
+// |a.p| is not an own property, it still requires that |b.p| be an own
+// property.
+//
+// Note that |actual| must not contain cyclic references.
+self.assert_object_equals = function(actual, expected, description) {
+ var object_stack = [];
+
+ function _is_equal(actual, expected, prefix) {
+ if (typeof actual !== 'object') {
+ assert_equals(actual, expected, prefix);
+ return;
+ }
+ assert_true(typeof expected === 'object', prefix);
+ assert_equals(object_stack.indexOf(actual), -1,
+ prefix + ' must not contain cyclic references.');
+
+ object_stack.push(actual);
+
+ Object.getOwnPropertyNames(expected).forEach(function(property) {
+ assert_own_property(actual, property, prefix);
+ _is_equal(actual[property], expected[property],
+ prefix + '.' + property);
+ });
+ Object.getOwnPropertyNames(actual).forEach(function(property) {
+ assert_own_property(expected, property, prefix);
+ });
+
+ object_stack.pop();
+ }
+
+ function _brand(object) {
+ return Object.prototype.toString.call(object).match(/^\[object (.*)\]$/)[1];
+ }
+
+ _is_equal(actual, expected,
+ (description ? description + ': ' : '') + _brand(expected));
+};
+
+// Equivalent to assert_in_array, but uses a weaker equivalence relation
+// (assert_object_equals) than '==='.
+function assert_object_in_array(actual, expected_array, description) {
+ assert_true(expected_array.some(function(element) {
+ try {
+ assert_object_equals(actual, element);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }), description);
+}
+
+// Assert that the two arrays |actual| and |expected| contain the same set of
+// elements as determined by assert_object_equals. The order is not significant.
+//
+// |expected| is assumed to not contain any duplicates as determined by
+// assert_object_equals().
+function assert_array_equivalent(actual, expected, description) {
+ assert_true(Array.isArray(actual), description);
+ assert_equals(actual.length, expected.length, description);
+ expected.forEach(function(expected_element) {
+ // assert_in_array treats the first argument as being 'actual', and the
+ // second as being 'expected array'. We are switching them around because
+ // we want to be resilient against the |actual| array containing
+ // duplicates.
+ assert_object_in_array(expected_element, actual, description);
+ });
+}
+
+// Asserts that two arrays |actual| and |expected| contain the same set of
+// elements as determined by assert_object_equals(). The corresponding elements
+// must occupy corresponding indices in their respective arrays.
+function assert_array_objects_equals(actual, expected, description) {
+ assert_true(Array.isArray(actual), description);
+ assert_equals(actual.length, expected.length, description);
+ actual.forEach(function(value, index) {
+ assert_object_equals(value, expected[index],
+ description + ' : object[' + index + ']');
+ });
+}
+
+// Asserts that |object| that is an instance of some interface has the attribute
+// |attribute_name| following the conditions specified by WebIDL, but it's
+// acceptable that the attribute |attribute_name| is an own property of the
+// object because we're in the middle of moving the attribute to a prototype
+// chain. Once we complete the transition to prototype chains,
+// assert_will_be_idl_attribute must be replaced with assert_idl_attribute
+// defined in testharness.js.
+//
+// FIXME: Remove assert_will_be_idl_attribute once we complete the transition
+// of moving the DOM attributes to prototype chains. (http://crbug.com/43394)
+function assert_will_be_idl_attribute(object, attribute_name, description) {
+ assert_true(typeof object === "object", description);
+
+ assert_true("hasOwnProperty" in object, description);
+
+ // Do not test if |attribute_name| is not an own property because
+ // |attribute_name| is in the middle of the transition to a prototype
+ // chain. (http://crbug.com/43394)
+
+ assert_true(attribute_name in object, description);
+}
+
+// Stringifies a DOM object. This function stringifies not only own properties
+// but also DOM attributes which are on a prototype chain. Note that
+// JSON.stringify only stringifies own properties.
+function stringifyDOMObject(object)
+{
+ function deepCopy(src) {
+ if (typeof src != "object")
+ return src;
+ var dst = Array.isArray(src) ? [] : {};
+ for (var property in src) {
+ dst[property] = deepCopy(src[property]);
+ }
+ return dst;
+ }
+ return JSON.stringify(deepCopy(object));
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/unregister-controller-page.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/unregister-controller-page.html
new file mode 100644
index 00000000000..18a95ee892b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/unregister-controller-page.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<script>
+function fetch_url(url) {
+ return new Promise(function(resolve, reject) {
+ var request = new XMLHttpRequest();
+ request.addEventListener('load', function(event) {
+ if (request.status == 200)
+ resolve(request.response);
+ else
+ reject(Error(request.statusText));
+ });
+ request.open('GET', url);
+ request.send();
+ });
+}
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-nocookie-worker.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-nocookie-worker.py
new file mode 100644
index 00000000000..0f09b7e32c0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-nocookie-worker.py
@@ -0,0 +1,15 @@
+import time
+
+def main(request, response):
+ # no-cache itself to ensure the user agent finds a new version for each update.
+ headers = [('Cache-Control', 'no-cache, must-revalidate'),
+ ('Pragma', 'no-cache')]
+
+ # Set a normal mimetype.
+ content_type = 'application/javascript'
+
+ headers.append(('Content-Type', content_type))
+ # Return a different script for each access. Use .time() and .clock() for
+ # best time resolution across different platforms.
+ return headers, '// %s %s' % (time.time(), time.clock())
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-worker.py b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-worker.py
new file mode 100644
index 00000000000..bc9b32ad3e6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update-worker.py
@@ -0,0 +1,46 @@
+import time
+
+def main(request, response):
+ # Set mode to 'init' for initial fetch.
+ mode = 'init'
+ if 'mode' in request.cookies:
+ mode = request.cookies['mode'].value
+
+ # no-cache itself to ensure the user agent finds a new version for each update.
+ headers = [('Cache-Control', 'no-cache, must-revalidate'),
+ ('Pragma', 'no-cache')]
+
+ content_type = ''
+ extra_body = ''
+
+ if mode == 'init':
+ # Set a normal mimetype.
+ # Set cookie value to 'normal' so the next fetch will work in 'normal' mode.
+ content_type = 'application/javascript'
+ response.set_cookie('mode', 'normal')
+ elif mode == 'normal':
+ # Set a normal mimetype.
+ # Set cookie value to 'error' so the next fetch will work in 'error' mode.
+ content_type = 'application/javascript'
+ response.set_cookie('mode', 'error');
+ elif mode == 'error':
+ # Set a disallowed mimetype.
+ # Set cookie value to 'syntax-error' so the next fetch will work in 'syntax-error' mode.
+ content_type = 'text/html'
+ response.set_cookie('mode', 'syntax-error');
+ elif mode == 'syntax-error':
+ # Set cookie value to 'throw-install' so the next fetch will work in 'throw-install' mode.
+ content_type = 'application/javascript'
+ response.set_cookie('mode', 'throw-install');
+ extra_body = 'badsyntax(isbad;'
+ elif mode == 'throw-install':
+ # Unset and delete cookie to clean up the test setting.
+ content_type = 'application/javascript'
+ response.delete_cookie('mode')
+ extra_body = "addEventListener('install', function(e) { throw new Error('boom'); });"
+
+ headers.append(('Content-Type', content_type))
+ # Return a different script for each access. Use .time() and .clock() for
+ # best time resolution across different platforms.
+ return headers, '/* %s %s */ %s' % (time.time(), time.clock(), extra_body)
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update/update-after-oneday.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update/update-after-oneday.https.html
new file mode 100644
index 00000000000..9d4c9827218
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/update/update-after-oneday.https.html
@@ -0,0 +1,8 @@
+<body>
+<script>
+function load_image(url) {
+ var img = document.createElement('img');
+ img.src = url;
+}
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/wait-forever-in-install-worker.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/wait-forever-in-install-worker.js
new file mode 100644
index 00000000000..32349594cc3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/wait-forever-in-install-worker.js
@@ -0,0 +1,3 @@
+self.addEventListener('install', function(event) {
+ event.waitUntil(new Promise(function() {}));
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/websocket.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/websocket.js
new file mode 100644
index 00000000000..fc6abd283a0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/websocket.js
@@ -0,0 +1,7 @@
+self.urls = [];
+self.addEventListener('fetch', function(event) {
+ self.urls.push(event.request.url);
+ });
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage({urls: self.urls});
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-interception-iframe.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-interception-iframe.https.html
new file mode 100644
index 00000000000..12a461ea5db
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-interception-iframe.https.html
@@ -0,0 +1,39 @@
+<script src="../resources/get-host-info.sub.js"></script>
+<script src="test-helpers.sub.js?pipe=sub"></script>
+<script>
+var host_info = get_host_info();
+
+function boilerplate_test(msg) {
+ return new Promise(function(resolve, reject) {
+ var worker = new Worker("load_worker.js");
+ worker.onmessage = function(e) { resolve(e.data) };
+ worker.onerror = function(e) { reject(e) };
+ worker.postMessage(msg);
+ })
+ .then(function(data) {
+ window.parent.postMessage({results: data}, host_info['HTTPS_ORIGIN']);
+ });
+}
+
+function xhr_test() {
+ return boilerplate_test("xhr");
+}
+
+function fetch_test() {
+ return boilerplate_test("fetch");
+}
+
+function importScripts_test() {
+ return boilerplate_test("importScripts");
+}
+
+window.addEventListener('message', function(evt) {
+ var port = evt.ports[0];
+ xhr_test()
+ .then(fetch_test)
+ .then(importScripts_test)
+ .then(function() { port.postMessage({results: 'finish'}); })
+ .catch(function(e) { port.postMessage({results: 'failure:' + e}); });
+ });
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-load-interceptor.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-load-interceptor.js
new file mode 100644
index 00000000000..960c6328ce5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-load-interceptor.js
@@ -0,0 +1,13 @@
+importScripts('get-host-info.sub.js');
+
+var response_text = "This load was successfully intercepted.";
+var response_script = "postMessage(\"This load was successfully intercepted.\");";
+
+self.onfetch = function(event) {
+ var url = event.request.url;
+ if (url.indexOf("synthesized-response.txt") != -1) {
+ event.respondWith(new Response(response_text));
+ } else if (url.indexOf("synthesized-response.js") != -1) {
+ event.respondWith(new Response(response_script));
+ }
+};
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-testharness.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-testharness.js
new file mode 100644
index 00000000000..fdf5868e33e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/worker-testharness.js
@@ -0,0 +1,49 @@
+/*
+ * worker-test-harness should be considered a temporary polyfill around
+ * testharness.js for supporting Service Worker based tests. It should not be
+ * necessary once the test harness is able to drive worker based tests natively.
+ * See https://github.com/w3c/testharness.js/pull/82 for status of effort to
+ * update upstream testharness.js. Once the upstreaming is complete, tests that
+ * reference worker-test-harness should be updated to directly import
+ * testharness.js.
+ */
+
+importScripts('/resources/testharness.js');
+
+(function() {
+ var next_cache_index = 1;
+
+ // Returns a promise that resolves to a newly created Cache object. The
+ // returned Cache will be destroyed when |test| completes.
+ function create_temporary_cache(test) {
+ var uniquifier = String(++next_cache_index);
+ var cache_name = self.location.pathname + '/' + uniquifier;
+
+ test.add_cleanup(function() {
+ self.caches.delete(cache_name);
+ });
+
+ return self.caches.delete(cache_name)
+ .then(function() {
+ return self.caches.open(cache_name);
+ });
+ }
+
+ self.create_temporary_cache = create_temporary_cache;
+})();
+
+// Runs |test_function| with a temporary unique Cache passed in as the only
+// argument. The function is run as a part of Promise chain owned by
+// promise_test(). As such, it is expected to behave in a manner identical (with
+// the exception of the argument) to a function passed into promise_test().
+//
+// E.g.:
+// cache_test(function(cache) {
+// // Do something with |cache|, which is a Cache object.
+// }, "Some Cache test");
+function cache_test(test_function, description) {
+ promise_test(function(test) {
+ return create_temporary_cache(test)
+ .then(test_function);
+ }, description);
+}
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/resources/xhr.js b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/xhr.js
new file mode 100644
index 00000000000..387c4a48ed5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/resources/xhr.js
@@ -0,0 +1,6 @@
+self.addEventListener('activate', function(event) {
+ event.waitUntil(clients.claim());
+ });
+self.addEventListener('message', function(event) {
+ event.data.port.postMessage({xhr: !!("XMLHttpRequest" in self)});
+ });
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-connect.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-connect.https.html
new file mode 100644
index 00000000000..226f4a40e4e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-connect.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Service Worker: CSP connect directive for ServiceWorker script</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+service_worker_test(
+ 'resources/service-worker-csp-worker.py?directive=connect',
+ 'CSP test for connect-src in ServiceWorkerGlobalScope');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-default.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-default.https.html
new file mode 100644
index 00000000000..1d4e7624d86
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-default.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Service Worker: CSP default directive for ServiceWorker script</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+service_worker_test(
+ 'resources/service-worker-csp-worker.py?directive=default',
+ 'CSP test for default-src in ServiceWorkerGlobalScope');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-script.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-script.https.html
new file mode 100644
index 00000000000..14c2eb72bdc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/service-worker-csp-script.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Service Worker: CSP script directive for ServiceWorker script</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+service_worker_test(
+ 'resources/service-worker-csp-worker.py?directive=script',
+ 'CSP test for script-src in ServiceWorkerGlobalScope');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/serviceworkerobject-scripturl.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/serviceworkerobject-scripturl.https.html
new file mode 100644
index 00000000000..95587a5a42d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/serviceworkerobject-scripturl.https.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>ServiceWorker object: scriptURL property</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+function url_test(name, url) {
+ var scope = 'resources/scope/' + name;
+ async_test(function(t) {
+ var expectedURL = (new URL(url, window.location)).toString();
+ service_worker_unregister_and_register(t, url, scope)
+ .then(function(registration) {
+ var worker = registration.installing;
+ assert_equals(worker.scriptURL, expectedURL,
+ 'Returned ServiceWorker object should have scriptURL');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify the scriptURL property: ' + name);
+}
+
+url_test('relative', 'resources/empty-worker.js');
+url_test('absolute', (new URL('./resources/empty-worker.js', window.location)).href);
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/shared-worker-controlled.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/shared-worker-controlled.https.html
new file mode 100644
index 00000000000..33d52e01199
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/shared-worker-controlled.https.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<title>Service Worker: controlling a SharedWorker</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+promise_test(function(t) {
+ var shared_worker = 'resources/shared-worker-controlled.js';
+ var service_worker = 'resources/simple-intercept-worker.js';
+ var scope = shared_worker;
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ var w = new SharedWorker(shared_worker);
+ w.port.onmessage = function(e) {
+ resolve(e.data);
+ }
+ });
+ })
+ .then(function(data) {
+ assert_equals(data, 'intercepted by service worker');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify subresource loads in SharedWorker are controlled by a Service Worker');
+
+promise_test(function(t) {
+ var shared_worker = 'resources/dummy-shared-worker.js';
+ var service_worker = 'resources/dummy-shared-worker-interceptor.js';
+ var scope = shared_worker;
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ var w = new SharedWorker(shared_worker);
+ w.port.onmessage = function(e) {
+ resolve(e.data);
+ }
+ });
+ })
+ .then(function(data) {
+ assert_equals(data, 'worker loading intercepted by service worker');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify SharedWorker construction is controlled by a Service Worker');
+
+promise_test(function(t) {
+ var shared_worker = 'resources/shared-worker-import.js';
+ var service_worker = 'resources/dummy-shared-worker-interceptor.js';
+ var scope = shared_worker;
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ var w = new SharedWorker(shared_worker);
+ w.port.onmessage = function(e) {
+ resolve(e.data);
+ }
+ });
+ })
+ .then(function(data) {
+ assert_equals(data, 'worker loading intercepted by service worker');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify importScripts from SharedWorker is controlled by a Service Worker');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-installed.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-installed.https.html
new file mode 100644
index 00000000000..42e4000b1f6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-installed.https.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<title>Service Worker: Skip waiting installed worker</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var scope = 'resources/blank.html';
+ var url1 = 'resources/empty.js';
+ var url2 = 'resources/skip-waiting-installed-worker.js';
+ var frame, frame_sw, service_worker, registration, onmessage, oncontrollerchanged;
+ var saw_message = new Promise(function(resolve) {
+ onmessage = function(e) {
+ var message = e.data;
+ assert_equals(
+ message, 'PASS',
+ 'skipWaiting promise should be resolved with undefined');
+
+ assert_equals(registration.active.scriptURL, normalizeURL(url2),
+ "skipWaiting should make worker become active");
+ resolve();
+ };
+ });
+ var saw_controllerchanged = new Promise(function(resolve) {
+ oncontrollerchanged = function() {
+ assert_equals(
+ frame_sw.controller.scriptURL, normalizeURL(url2),
+ 'Controller scriptURL should change to the second one');
+ resolve();
+ };
+ });
+ return service_worker_unregister_and_register(t, url1, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ frame_sw = f.contentWindow.navigator.serviceWorker;
+ assert_equals(
+ frame_sw.controller.scriptURL, normalizeURL(url1),
+ 'Document controller scriptURL should equal to the first one');
+ frame_sw.oncontrollerchange = t.step_func(oncontrollerchanged);
+ return navigator.serviceWorker.register(url2, {scope: scope});
+ })
+ .then(function(r) {
+ registration = r;
+ service_worker = r.installing;
+ return wait_for_state(t, service_worker, 'installed');
+ })
+ .then(function() {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(onmessage);
+ service_worker.postMessage({port: channel.port2}, [channel.port2]);
+ return Promise.all([saw_message, saw_controllerchanged]);
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Test skipWaiting when a installed worker is waiting');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html
new file mode 100644
index 00000000000..5f84f0b8eda
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-using-registration.https.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<title>Service Worker: Skip waiting using registration</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var scope = 'resources/blank.html';
+ var url1 = 'resources/empty.js';
+ var url2 = 'resources/skip-waiting-worker.js';
+ var frame, frame_sw, sw_registration, oncontrollerchanged;
+ var saw_controllerchanged = new Promise(function(resolve) {
+ oncontrollerchanged = function(e) {
+ assert_equals(e.type, 'controllerchange',
+ 'Event name should be "controllerchange"');
+ assert_true(
+ e.target instanceof frame.contentWindow.ServiceWorkerContainer,
+ 'Event target should be a ServiceWorkerContainer');
+ assert_equals(e.target.controller.state, 'activating',
+ 'Controller state should be activating');
+ assert_equals(
+ frame_sw.controller.scriptURL, normalizeURL(url2),
+ 'Controller scriptURL should change to the second one');
+ resolve();
+ };
+ });
+ return service_worker_unregister_and_register(t, url1, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ frame_sw = f.contentWindow.navigator.serviceWorker;
+ assert_equals(
+ frame_sw.controller.scriptURL, normalizeURL(url1),
+ 'Document controller scriptURL should equal to the first one');
+ frame_sw.oncontrollerchange = t.step_func(oncontrollerchanged);
+ return navigator.serviceWorker.register(url2, {scope: scope});
+ })
+ .then(function(registration) {
+ sw_registration = registration;
+ add_completion_callback(function() {
+ frame.remove();
+ registration.unregister();
+ });
+ return saw_controllerchanged;
+ })
+ .then(function() {
+ assert_not_equals(sw_registration.active, null,
+ 'Registration active worker should not be null');
+ fetch_tests_from_worker(sw_registration.active);
+ });
+ }, 'Test skipWaiting while a client is using the registration');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-client.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-client.https.html
new file mode 100644
index 00000000000..38fca172604
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-client.https.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>Service Worker: Skip waiting without client</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+service_worker_test(
+ 'resources/skip-waiting-worker.js',
+ 'Test single skipWaiting() when no client attached');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html
new file mode 100644
index 00000000000..2535ffe09fc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting-without-using-registration.https.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>Service Worker: Skip waiting without using registration</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var scope = 'resources/blank.html';
+ var url = 'resources/skip-waiting-worker.js';
+ var frame, frame_sw, sw_registration;
+
+ return service_worker_unregister(t, scope)
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ frame_sw = f.contentWindow.navigator.serviceWorker;
+ assert_equals(frame_sw.controller, null,
+ 'Document controller should be null');
+ return navigator.serviceWorker.register(url, {scope: scope});
+ })
+ .then(function(registration) {
+ sw_registration = registration;
+ add_completion_callback(function() {
+ frame.remove();
+ registration.unregister();
+ });
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(frame_sw.controller, null,
+ 'Document controller should still be null');
+ assert_not_equals(sw_registration.active, null,
+ 'Registration active worker should not be null');
+ fetch_tests_from_worker(sw_registration.active);
+ });
+ }, 'Test skipWaiting while a client is not being controlled');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting.https.html
new file mode 100644
index 00000000000..7c1c41f3f75
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/skip-waiting.https.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<title>Service Worker: Skip waiting</title>
+<script src="/resources/testharness.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var scope = 'resources/blank.html';
+ var url1 = 'resources/empty.js';
+ var url2 = 'resources/empty-worker.js';
+ var url3 = 'resources/skip-waiting-worker.js';
+ var frame, sw_registration, activated_worker, waiting_worker;
+ return service_worker_unregister_and_register(t, url1, scope)
+ .then(function(registration) {
+ sw_registration = registration;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url2, {scope: scope});
+ })
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ activated_worker = sw_registration.active;
+ waiting_worker = sw_registration.waiting;
+ assert_equals(activated_worker.scriptURL, normalizeURL(url1),
+ 'Worker with url1 should be activated');
+ assert_equals(waiting_worker.scriptURL, normalizeURL(url2),
+ 'Worker with url2 should be waiting');
+ return navigator.serviceWorker.register(url3, {scope: scope});
+ })
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(activated_worker.state, 'redundant',
+ 'Worker with url1 should be redundant');
+ assert_equals(waiting_worker.state, 'redundant',
+ 'Worker with url2 should be redundant');
+ assert_equals(sw_registration.active.scriptURL, normalizeURL(url3),
+ 'Worker with url3 should be activated');
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Test skipWaiting with both active and waiting workers');
+
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/state.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/state.https.html
new file mode 100644
index 00000000000..3810362e053
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/state.https.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+(function () {
+ var t = async_test('Service Worker state property and "statechange" event');
+ var currentState = 'test-is-starting';
+ var scope = 'resources/state/';
+
+ service_worker_unregister_and_register(
+ t, 'resources/empty-worker.js', scope)
+ .then(t.step_func(function(registration) {
+ var sw = registration.installing;
+ sw.addEventListener('statechange', t.step_func(onStateChange(sw)));
+ assert_equals(sw.state, 'installing',
+ 'the service worker should be in "installing" state.');
+ checkStateTransition(sw.state);
+ }))
+ .catch(unreached_rejection(t));
+
+ function checkStateTransition(newState) {
+ switch (currentState) {
+ case 'test-is-starting':
+ break; // anything goes
+ case 'installing':
+ assert_in_array(newState, ['installed', 'redundant']);
+ break;
+ case 'installed':
+ assert_in_array(newState, ['activating', 'redundant']);
+ break;
+ case 'activating':
+ assert_in_array(newState, ['activated', 'redundant']);
+ break;
+ case 'activated':
+ assert_equals(newState, 'redundant');
+ break;
+ case 'redundant':
+ assert_unreached('a ServiceWorker should not transition out of ' +
+ 'the "redundant" state');
+ break;
+ default:
+ assert_unreached('should not transition into unknown state "' +
+ newState + '"');
+ break;
+ }
+ currentState = newState;
+ }
+
+ function onStateChange(expectedTarget) {
+ return function(event) {
+ assert_true(event.target instanceof ServiceWorker,
+ 'the target of the statechange event should be a ' +
+ 'ServiceWorker.');
+ assert_equals(event.target, expectedTarget,
+ 'the target of the statechange event should be ' +
+ 'the installing ServiceWorker');
+ assert_equals(event.type, 'statechange',
+ 'the type of the event should be "statechange".');
+
+ checkStateTransition(event.target.state);
+
+ if (event.target.state == 'activated')
+ service_worker_unregister_and_done(t, scope);
+ };
+ }
+}());
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/synced-state.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/synced-state.https.html
new file mode 100644
index 00000000000..d842378be75
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/synced-state.https.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<title>ServiceWorker: worker objects have synced state</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+// Tests that ServiceWorker objects representing the same Service Worker
+// entity have the same state. JS object equality is not tested, since the spec
+// does not require it.
+promise_test(function(t) {
+ var scope = 'resources/synced-state';
+ var script = 'resources/empty-worker.js';
+ return service_worker_unregister_and_register(t, script, scope)
+ .then(function(registration) {
+ return new Promise(function(resolve) {
+ var step = 0;
+ registration.installing.addEventListener('statechange',
+ function(e) {
+ step++;
+ if (step == 1) {
+ assert_equals(e.currentTarget.state, 'installed',
+ 'original SW should be installed');
+ assert_equals(registration.installing, null,
+ 'in installed, .installing should be null');
+ // The Activate algorithm may have cleared the waiting worker
+ // by now.
+ if (registration.waiting) {
+ assert_equals(registration.waiting.state, 'installed',
+ 'in installed, .waiting should be installed');
+ assert_equals(registration.active, null,
+ 'in installed, .active should be null');
+ } else {
+ assert_equals(registration.active.state, 'activating',
+ 'in installed, .active should be activating');
+ }
+ } else if (step == 2) {
+ assert_equals(e.currentTarget.state, 'activating',
+ 'original SW should be activating');
+ assert_equals(registration.installing, null,
+ 'in activating, .installing should be null');
+ assert_equals(registration.waiting, null,
+ 'in activating, .waiting should be null');
+ assert_equals(
+ registration.active.state, 'activating',
+ 'in activating, .active should be activating');
+ } else if (step == 3) {
+ assert_equals(e.currentTarget.state, 'activated',
+ 'original SW should be activated');
+ assert_equals(registration.installing, null,
+ 'in activated, .installing should be null');
+ assert_equals(registration.waiting, null,
+ 'in activated, .waiting should be null');
+ assert_equals(registration.active.state, 'activated',
+ 'in activated .active should be activated');
+ resolve();
+ }
+ })
+ })
+ })
+ .then(function() {
+ return service_worker_unregister_and_done(t, scope);
+ });
+ }, 'worker objects for the same entity have the same state');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/uncontrolled-page.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/uncontrolled-page.https.html
new file mode 100644
index 00000000000..a9523a54cdc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/uncontrolled-page.https.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<title>Service Worker: Registration</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+function fetch_url(url) {
+ return new Promise(function(resolve, reject) {
+ var request = new XMLHttpRequest();
+ request.addEventListener('load', function(event) {
+ if (request.status == 200)
+ resolve(request.response);
+ else
+ reject(Error(request.statusText));
+ });
+ request.open('GET', url);
+ request.send();
+ });
+}
+var worker = 'resources/fail-on-fetch-worker.js';
+
+async_test(function(t) {
+ var scope = 'resources/scope/uncontrolled-page/';
+ service_worker_unregister_and_register(t, worker, scope)
+ .then(function(reg) {
+ return wait_for_state(t, reg.installing, 'activated');
+ })
+ .then(function() {
+ return fetch_url('resources/simple.txt');
+ })
+ .then(function(text) {
+ assert_equals(text, 'a simple text file\n');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(t.step_func(function(reason) {
+ assert_unreached(reason.message);
+ }));
+ }, 'Fetch events should not go through uncontrolled page.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-controller.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-controller.https.html
new file mode 100644
index 00000000000..3bf4cff7200
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-controller.https.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var worker_url = 'resources/simple-intercept-worker.js';
+
+async_test(function(t) {
+ var scope =
+ 'resources/unregister-controller-page.html?load-before-unregister';
+ var frame_window;
+ var controller;
+ var registration;
+ var frame;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ frame_window = frame.contentWindow;
+ controller = frame_window.navigator.serviceWorker.controller;
+ assert_true(controller instanceof frame_window.ServiceWorker,
+ 'document should load with a controller');
+ return registration.unregister();
+ })
+ .then(function() {
+ assert_equals(frame_window.navigator.serviceWorker.controller,
+ controller,
+ 'unregistration should not modify controller');
+ return frame_window.fetch_url('simple.txt');
+ })
+ .then(function(response) {
+ assert_equals(response, 'intercepted by service worker',
+ 'controller should intercept requests');
+ frame.remove();
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister does not affect existing controller');
+
+async_test(function(t) {
+ var scope =
+ 'resources/unregister-controller-page.html?load-after-unregister';
+ var registration;
+ var frame;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return registration.unregister();
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ var frame_window = frame.contentWindow;
+ assert_equals(frame_window.navigator.serviceWorker.controller, null,
+ 'document should not have a controller');
+ return frame_window.fetch_url('simple.txt');
+ })
+ .then(function(response) {
+ assert_equals(response, 'a simple text file\n',
+ 'requests should not be intercepted');
+ frame.remove();
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister prevents control of subsequent navigations');
+
+async_test(function(t) {
+ var scope =
+ 'resources/scope/no-new-controllee-even-if-registration-is-still-used';
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ return registration.unregister();
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
+ null,
+ 'document should not have a controller');
+ frame.remove();
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister prevents new controllee even if registration is still in use');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html
new file mode 100644
index 00000000000..385430c2d8e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register-new-script.https.html
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var worker_url = 'resources/empty-worker.js';
+
+async_test(function(t) {
+ var scope = 'resources/scope/unregister-then-register-new-script-that-exists';
+ var new_worker_url = worker_url + '?new';
+ var iframe;
+ var registration;
+ var new_registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ iframe = frame;
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(new_worker_url,
+ { scope: scope });
+ })
+ .then(function(r) {
+ new_registration = r;
+ assert_equals(registration.installing.scriptURL,
+ normalizeURL(new_worker_url),
+ 'before activated registration.installing');
+ assert_equals(registration.waiting, null,
+ 'before activated registration.waiting');
+ assert_equals(registration.active.scriptURL, normalizeURL(worker_url),
+ 'before activated registration.active');
+ assert_equals(new_registration.installing.scriptURL,
+ normalizeURL(new_worker_url),
+ 'before activated new_registration.installing');
+ assert_equals(new_registration.waiting, null,
+ 'before activated new_registration.waiting');
+ assert_equals(new_registration.active.scriptURL,
+ normalizeURL(worker_url),
+ 'before activated new_registration.active');
+ iframe.remove();
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(new_registration.installing, null,
+ 'after activated new_registration.installing');
+ assert_equals(new_registration.waiting, null,
+ 'after activated new_registration.waiting');
+ assert_equals(new_registration.active.scriptURL,
+ normalizeURL(new_worker_url),
+ 'after activated new_registration.active');
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ assert_equals(
+ frame.contentWindow.navigator.serviceWorker.controller.scriptURL,
+ normalizeURL(new_worker_url),
+ 'the new worker should control a new document');
+ frame.remove();
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+}, 'Registering a new script URL while an unregistered registration is in use');
+
+async_test(function(t) {
+ var scope = 'resources/scope/unregister-then-register-new-script-that-404s';
+ var iframe;
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ iframe = frame;
+ return registration.unregister();
+ })
+ .then(function() {
+ var promise = navigator.serviceWorker.register('this-will-404',
+ { scope: scope });
+ iframe.remove();
+ return promise;
+ })
+ .then(
+ function() {
+ assert_unreached('register should reject the promise');
+ },
+ function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
+ null,
+ 'document should not load with a controller');
+ frame.remove();
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+}, 'Registering a new script URL that 404s does not resurrect an ' +
+ 'unregistered registration');
+
+async_test(function(t) {
+ var scope = 'resources/scope/unregister-then-register-reject-install-worker';
+ var iframe;
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ iframe = frame;
+ return registration.unregister();
+ })
+ .then(function() {
+ var promise = navigator.serviceWorker.register(
+ 'resources/reject-install-worker.js', { scope: scope });
+ iframe.remove();
+ return promise;
+ })
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'redundant');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ assert_equals(frame.contentWindow.navigator.serviceWorker.controller,
+ null,
+ 'document should not load with a controller');
+ frame.remove();
+ return registration.unregister();
+ })
+ .then(function() {
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Registering a new script URL that fails to install does not resurrect ' +
+ 'an unregistered registration');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register.https.html
new file mode 100644
index 00000000000..d75904d158f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister-then-register.https.html
@@ -0,0 +1,129 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+var worker_url = 'resources/empty-worker.js';
+
+async_test(function(t) {
+ var scope = 'resources/scope/re-register-resolves-to-new-value';
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(worker_url, { scope: scope });
+ })
+ .then(function(new_registration) {
+ assert_not_equals(registration, new_registration,
+ 'register should resolve to a new value');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister then register resolves to a new value');
+
+async_test(function(t) {
+ var scope = 'resources/scope/re-register-while-old-registration-in-use';
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(worker_url, { scope: scope });
+ })
+ .then(function(new_registration) {
+ assert_equals(registration, new_registration,
+ 'new registration should resolve to the same registration');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister then register resolves to the original value if the ' +
+ 'registration is in use.');
+
+async_test(function(t) {
+ var scope = 'resources/scope/re-register-does-not-affect-existing-controllee';
+ var iframe;
+ var registration;
+ var controller;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ iframe = frame;
+ controller = iframe.contentWindow.navigator.serviceWorker.controller;
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(worker_url, { scope: scope });
+ })
+ .then(function(registration) {
+ assert_equals(registration.installing, null,
+ 'installing version is null');
+ assert_equals(registration.waiting, null, 'waiting version is null');
+ assert_equals(
+ iframe.contentWindow.navigator.serviceWorker.controller,
+ controller,
+ 'the worker from the first registration is the controller');
+ iframe.remove();
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister then register does not affect existing controllee');
+
+async_test(function(t) {
+ var scope = 'resources/scope/resurrection';
+ var iframe;
+ var registration;
+
+ service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ iframe = frame;
+ return registration.unregister();
+ })
+ .then(function() {
+ return navigator.serviceWorker.register(worker_url, { scope: scope });
+ })
+ .then(function() {
+ iframe.remove();
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ // FIXME: When crbug.com/400602 is fixed, assert that controller
+ // equals the original worker.
+ assert_not_equals(
+ frame.contentWindow.navigator.serviceWorker.controller, null,
+ 'document should have a controller');
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister then register resurrects the registration');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/unregister.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister.https.html
new file mode 100644
index 00000000000..492aecb21a8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/unregister.https.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+async_test(function(t) {
+ var scope = 'resources/scope/unregister-twice';
+ var registration;
+ navigator.serviceWorker.register('resources/empty-worker.js',
+ {scope: scope})
+ .then(function(r) {
+ registration = r;
+ return registration.unregister();
+ })
+ .then(function() {
+ return registration.unregister();
+ })
+ .then(function(value) {
+ assert_equals(value, false,
+ 'unregistering twice should resolve with false');
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Unregister twice');
+
+async_test(function(t) {
+ var scope = 'resources/scope/successful-unregister/';
+ navigator.serviceWorker.register('resources/empty-worker.js',
+ {scope: scope})
+ .then(function(registration) {
+ return registration.unregister();
+ })
+ .then(function(value) {
+ assert_equals(value, true,
+ 'unregistration should resolve with true');
+ t.done();
+ })
+ .catch(unreached_rejection(t));
+ }, 'Register then unregister');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https.html
new file mode 100644
index 00000000000..04cd9960fc6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/update-after-navigation-fetch-event.https.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>Service Worker: Update should be triggered after a navigation fetch event.</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var script = 'resources/update-nocookie-worker.py';
+ var scope = 'resources/scope/update';
+ var parsed_url = normalizeURL(script);
+ var registration;
+ var frame;
+
+ return service_worker_unregister_and_register(t, parsed_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ // Navigation to the iframe.
+ return with_iframe(scope);
+ })
+ .then(function(f) {
+ frame = f;
+ // Navigation fetch event should trigger update.
+ return wait_for_update(t, registration);
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Update should be triggered after a navigation fetch event.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/update-after-oneday.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/update-after-oneday.https.html
new file mode 100644
index 00000000000..151a59ebc3f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/update-after-oneday.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- This test requires browser to treat all registrations are older than 24 hours.
+ Preference 'dom.serviceWorkers.testUpdateOverOneDay' should be enabled during
+ the execution of the test -->
+<title>Service Worker: Functional events should trigger update if last update time is over 24 hours</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+
+promise_test(function(t) {
+ var script = 'resources/update-nocookie-worker.py';
+ var scope = 'resources/update/update-after-oneday.https.html';
+ var expected_url = normalizeURL(script);
+ var registration;
+ var frame;
+
+ return service_worker_unregister_and_register(t, expected_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ return wait_for_update(t, registration);
+ })
+ .then(function() {
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'new installing should be set after update resolves.');
+ assert_equals(registration.waiting, null,
+ 'waiting should still be null after update resolves.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update found.');
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ // Trigger a non-navigation fetch event
+ frame.contentWindow.load_image(normalizeURL('resources/update/dummy'));
+ return wait_for_update(t, registration);
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ }, 'Update should be triggered after a functional event when last update time is over 24 hours');
+
+</script>
+
+
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/update.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/update.https.html
new file mode 100644
index 00000000000..8b41e52d8b8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/update.https.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<title>Service Worker: Registration update()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/testharness-helpers.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<script>
+promise_test(function(t) {
+ var scope = 'resources/simple.txt';
+ var worker_url = 'resources/update-worker.py';
+ var expected_url = normalizeURL(worker_url);
+ var registration;
+ var iframe;
+ return service_worker_unregister_and_register(t, worker_url, scope)
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing should be null in the initial state.');
+ assert_equals(registration.waiting, null,
+ 'waiting should be null in the initial state.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should exist in the initial state.');
+ // A new worker (generated by update-worker.py) should be found.
+ // The returned promise should resolve when a new worker script is
+ // fetched and starts installing.
+ return Promise.all([registration.update(),
+ wait_for_update(t, registration)]);
+ })
+ .then(function() {
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'new installing should be set after update resolves.');
+ assert_equals(registration.waiting, null,
+ 'waiting should still be null after update resolves.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update found.');
+ return wait_for_state(t, registration.installing, 'installed');
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing should be null after installing.');
+ if (registration.waiting) {
+ assert_equals(registration.waiting.scriptURL, expected_url,
+ 'waiting should be set after installing.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after installing.');
+ return wait_for_state(t, registration.waiting, 'activated');
+ }
+ })
+ .then(function() {
+ assert_equals(registration.installing, null,
+ 'installing should be null after activated.');
+ assert_equals(registration.waiting, null,
+ 'waiting should be null after activated.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'new worker should be promoted to active.');
+ })
+ .then(function() {
+ // A new worker(generated by update-worker.py) should be found.
+ // The returned promise should reject as update-worker.py sets the
+ // mimetype to a disallowed value for this attempt.
+ return registration.update();
+ })
+ .then(
+ function() { assert_unreached("update() should reject."); },
+ function(e) {
+ assert_throws('SecurityError', function() { throw e; },
+ 'Using a disallowed mimetype should make update() ' +
+ 'promise reject with a SecurityError.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update failure.');
+
+ // A new worker(generated by update-worker.py) should be found.
+ // The returned promise should reject as update-worker.py returns
+ // a worker script with a syntax error.
+ return registration.update();
+ })
+ .then(
+ function() { assert_unreached("update() should reject."); },
+ function(e) {
+ assert_throws({name: 'TypeError'}, function () { throw e; },
+ 'A script syntax error should make update() ' +
+ 'promise reject with a TypeError.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update failure.');
+
+ // A new worker(generated by update-worker.py) should be found.
+ // The returned promise should not reject, even though
+ // update-worker.py returns a worker script that throws in the
+ // install event handler.
+ return Promise.all([registration.update(),
+ wait_for_update(t, registration)]);
+ })
+ .then(function() {
+ assert_equals(registration.installing.scriptURL, expected_url,
+ 'new installing should be set after update resolves.');
+ assert_equals(registration.waiting, null,
+ 'waiting should be null after activated.');
+ assert_equals(registration.active.scriptURL, expected_url,
+ 'active should still exist after update found.');
+
+ // We need to hold a client alive so that unregister() below doesn't
+ // remove the registration before update() has had a chance to look
+ // at the pending uninstall flag.
+ return with_iframe(scope);
+ })
+ .then(function(frame) {
+ iframe = frame;
+
+ return assert_promise_rejects(
+ Promise.all([registration.unregister(), registration.update()]),
+ new TypeError(),
+ 'Calling update() while the uninstalling flag is set' +
+ 'should return a promise that rejects with an ' +
+ 'InvalidStateError.');
+ })
+ .then(function() {
+ iframe.remove();
+ return t.done();
+ });
+ }, 'Update a registration.');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/waiting.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/waiting.https.html
new file mode 100644
index 00000000000..eff9c80a4f6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/waiting.https.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>ServiceWorker: navigator.serviceWorker.waiting</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+// "waiting" is set
+async_test(function(t) {
+ var step = t.step_func.bind(t);
+ var url = 'resources/empty-worker.js';
+ var scope = 'resources/blank.html';
+ var frame;
+ var registration;
+
+ service_worker_unregister(t, scope)
+ .then(function() { return with_iframe(scope); })
+ .then(function(f) {
+ frame = f;
+ return navigator.serviceWorker.register(url, {scope: scope});
+ })
+ .then(function(r) {
+ registration = r;
+ return wait_for_state(t, r.installing, 'installed');
+ }, unreached_rejection(t, 'Registration should not fail'))
+ .then(function() {
+ var controller = frame.contentWindow.navigator.serviceWorker.controller;
+ assert_equals(controller, null);
+ // Nothing in the spec prohibits a worker from going to active
+ // immediately.
+ // Step 26 of the [[Install]] algorithm
+ // "If registration's waiting worker waitingWorker is not null and
+ // waitingWorker's skip waiting flag is not set, invoke Activate
+ // algorithm, or its equivalent, with registration as its argument."
+ var w = registration.waiting || registration.active;
+ assert_equals(w.scriptURL, normalizeURL(url));
+ assert_equals(registration.installing, null);
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ });
+}, 'waiting or active is set');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/websocket.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/websocket.https.html
new file mode 100644
index 00000000000..3dfa6e51497
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/websocket.https.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<title>Service Worker: WebSocket handshake channel is not intercepted</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+
+async_test(function(t) {
+ var path = new URL(".", window.location).pathname
+ var url = 'resources/websocket.js';
+ var scope = 'resources/blank.html?websocket';
+ var host_info = get_host_info();
+ var frameURL = host_info['HTTPS_ORIGIN'] + path + scope;
+ var frame;
+
+ service_worker_unregister_and_register(t, url, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(frameURL); })
+ .then(function(f) {
+ frame = f;
+ return websocket(t, frame);
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ function onMessage(e) {
+ for (var url in e.data.urls) {
+ assert_equals(url.indexOf(get_websocket_url()), -1,
+ "Observed an unexpected FetchEvent for the WebSocket handshake");
+ }
+ t.done();
+ }
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(onMessage);
+ frame.contentWindow.navigator.serviceWorker.controller.postMessage({port: channel.port2}, [channel.port2]);
+ });
+ })
+ .then(function() {
+ frame.remove();
+ return service_worker_unregister_and_done(t, scope);
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify WebSocket handshake channel does not get intercepted');
+</script>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/worker-interception.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/worker-interception.https.html
new file mode 100644
index 00000000000..3ec66a54b6e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/worker-interception.https.html
@@ -0,0 +1,155 @@
+<!DOCTYPE html>
+<title>Service Worker: intercepting Worker script loads</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/test-helpers.sub.js"></script>
+<body>
+<script>
+promise_test(function(t) {
+ var worker_url = 'resources/dummy-synthesized-worker.js';
+ var service_worker = 'resources/dummy-worker-interceptor.js';
+ var scope = worker_url;
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ var w = new Worker(worker_url);
+ w.onmessage = function(e) {
+ resolve(e.data);
+ }
+
+ w.onerror = function(e) {
+ reject(e.message);
+ }
+ });
+ })
+ .then(function(data) {
+ assert_equals(data, 'worker loading intercepted by service worker');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify worker script from uncontrolled document is intercepted by Service Worker');
+
+promise_test(function(t) {
+ var worker_url = 'resources/dummy-same-origin-worker.js';
+ var service_worker = 'resources/dummy-worker-interceptor.js';
+ var scope = worker_url;
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ var w = new Worker(worker_url);
+ w.onmessage = function(e) {
+ resolve(e.data);
+ }
+
+ w.onerror = function(e) {
+ reject(e.message);
+ }
+ });
+ })
+ .then(function(data) {
+ assert_equals(data, 'dummy-worker-script loaded');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify worker script intercepted by same-origin response succeeds');
+
+promise_test(function(t) {
+ var worker_url = 'resources/dummy-cors-worker.js';
+ var service_worker = 'resources/dummy-worker-interceptor.js';
+ var scope = worker_url;
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ var w = new Worker(worker_url);
+ w.onmessage = function(e) {
+ resolve(e.data);
+ }
+
+ w.onerror = function(e) {
+ reject(e.message);
+ }
+ });
+ })
+ .then(function(data) {
+ assert_equals(data, 'dummy-worker-script loaded');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify worker script intercepted by cors response succeeds');
+
+promise_test(function(t) {
+ var worker_url = 'resources/dummy-no-cors-worker.js';
+ var service_worker = 'resources/dummy-worker-interceptor.js';
+ var scope = worker_url;
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() {
+ return new Promise(function(resolve, reject) {
+ var w = new Worker(worker_url);
+ w.onmessage = function(e) {
+ resolve(e.data);
+ }
+
+ w.onerror = function(e) {
+ reject(e);
+ return true;
+ }
+ });
+ })
+ .then(function(data) {
+ assert_unreached('intercepted no-cors worker load should fail');
+ service_worker_unregister_and_done(t, scope);
+ })
+ .catch(function(e) {
+ assert_true(true, 'intercepted no-cors worker load should fail');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify worker script intercepted by no-cors cross-origin response fails');
+
+promise_test(function(t) {
+ var subdoc_url = 'resources/worker-interception-iframe.https.html?bypass';
+ var service_worker = 'resources/worker-load-interceptor.js';
+ var scope = 'resources/';
+
+ window.addEventListener('message', t.step_func(on_message), false);
+ function on_message(e) {
+ assert_equals(e.data.results, "This load was successfully intercepted.");
+ t.done();
+ }
+
+ return service_worker_unregister_and_register(t, service_worker, scope)
+ .then(function(r) {
+ return wait_for_state(t, r.installing, 'activated');
+ })
+ .then(function() { return with_iframe(subdoc_url); })
+ .then(function(frame) {
+ return new Promise(function(resolve, reject) {
+ var channel = new MessageChannel();
+ channel.port1.onmessage = function(e) {
+ frame.remove();
+ resolve(e.data);
+ }
+
+ frame.contentWindow.postMessage("GO", "*", [channel.port2]);
+ });
+ })
+ .then(function(data) {
+ assert_equals(data.results, 'finish');
+ service_worker_unregister_and_done(t, scope);
+ });
+ }, 'Verify worker loads from controlled document are intercepted by Service Worker');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/service-workers/service-worker/xhr.https.html b/tests/wpt/web-platform-tests/service-workers/service-worker/xhr.https.html
new file mode 100644
index 00000000000..776e61db16d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/service-workers/service-worker/xhr.https.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>Service Worker: XHR doesn't exist</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/get-host-info.sub.js"></script>
+<script src="resources/test-helpers.sub.js?pipe=sub"></script>
+<script>
+
+async_test(function(t) {
+ var path = new URL(".", window.location).pathname
+ var url = 'resources/xhr.js';
+ var scope = 'resources/blank.html?xhr';
+ var host_info = get_host_info();
+ var frameURL = host_info['HTTPS_ORIGIN'] + path + scope;
+
+ service_worker_unregister_and_register(t, url, scope)
+ .then(function(registration) {
+ return wait_for_state(t, registration.installing, 'activated');
+ })
+ .then(function() { return with_iframe(frameURL); })
+ .then(function(frame) {
+ return new Promise(function(resolve, reject) {
+ function onMessage(e) {
+ assert_false(e.data.xhr);
+ frame.remove();
+ service_worker_unregister_and_done(t, scope);
+ }
+ var channel = new MessageChannel();
+ channel.port1.onmessage = t.step_func(onMessage);
+ frame.contentWindow.navigator.serviceWorker.controller.postMessage({port: channel.port2}, [channel.port2]);
+ })
+ })
+ .catch(unreached_rejection(t));
+ }, 'Verify XHR does not exist');
+</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/resources/shadow-dom-utils.js b/tests/wpt/web-platform-tests/shadow-dom/resources/shadow-dom-utils.js
new file mode 100644
index 00000000000..e00d4d14675
--- /dev/null
+++ b/tests/wpt/web-platform-tests/shadow-dom/resources/shadow-dom-utils.js
@@ -0,0 +1,154 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+
+/*
+Distributed under both the W3C Test Suite License [1] and the W3C
+3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
+policies and contribution forms [3].
+
+[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
+[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
+[3] http://www.w3.org/2004/10/27-testcases
+*/
+
+"use strict";
+
+// custom element is also allowed.
+var ATTACHSHADOW_SAFELISTED_ELEMENTS = [
+ 'article',
+ 'aside',
+ 'blockquote',
+ 'body',
+ 'div',
+ 'footer',
+ 'h1',
+ 'h2',
+ 'h3',
+ 'h4',
+ 'h5',
+ 'h6',
+ 'header',
+ 'nav',
+ 'p',
+ 'section',
+ 'span'
+];
+
+var HTML5_ELEMENT_NAMES = [
+ 'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio',
+ 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button',
+ 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'command',
+ 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt',
+ 'em', 'embed',
+ 'fieldset', 'figcaption', 'figure', 'footer', 'form',
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr',
+ 'html',
+ 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen',
+ 'label', 'legend', 'li', 'link',
+ 'map', 'mark', 'menu', 'meta', 'meter',
+ 'nav', 'noscript',
+ 'object', 'ol', 'optgroup', 'option', 'output',
+ 'p', 'param', 'pre', 'progress',
+ 'q',
+ 'rp', 'rt', 'ruby',
+ 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span',
+ 'strong', 'style', 'sub',
+ 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time',
+ 'title', 'tr', 'track',
+ 'u', 'ul',
+ 'var', 'video',
+ 'wbr'
+];
+
+function unit(f) {
+ return function () {
+ var ctx = newContext();
+ try {
+ f(ctx);
+ } finally {
+ cleanContext(ctx);
+ }
+ }
+}
+
+function step_unit(f, ctx, t) {
+ return function () {
+ var done = false;
+ try {
+ f();
+ done = true;
+ } finally {
+ if (done) {
+ t.done();
+ }
+ cleanContext(ctx);
+ }
+ }
+}
+
+function assert_nodelist_contents_equal_noorder(actual, expected, message) {
+ assert_equals(actual.length, expected.length, message);
+ var used = [];
+ for (var i = 0; i < expected.length; i++) {
+ used.push(false);
+ }
+ for (i = 0; i < expected.length; i++) {
+ var found = false;
+ for (var j = 0; j < actual.length; j++) {
+ if (used[j] == false && expected[i] == actual[j]) {
+ used[j] = true;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ assert_unreached(message + ". Fail reason: element not found: " + expected[i]);
+ }
+ }
+}
+
+//Example taken from http://www.w3.org/TR/shadow-dom/#event-retargeting-example
+function createTestMediaPlayer(d) {
+ d.body.innerHTML = '' +
+ '<div id="player">' +
+ '<input type="checkbox" id="outside-control">' +
+ '<div id="player-shadow-host">' +
+ '</div>' +
+ '</div>';
+
+ var playerShadowRoot = d.querySelector('#player-shadow-host').createShadowRoot();
+ playerShadowRoot.innerHTML = '' +
+ '<div id="controls">' +
+ '<button class="play-button">PLAY</button>' +
+ '<div tabindex="0" id="timeline">' +
+ '<div id="timeline-shadow-host">' +
+ '</div>' +
+ '</div>' +
+ '<div class="volume-slider-container" id="volume-slider-container">' +
+ '<div tabindex="0" class="volume-slider" id="volume-slider">' +
+ '<div id="volume-shadow-host">' +
+ '</div>' +
+ '</div>' +
+ '</div>' +
+ '</div>';
+
+ var timeLineShadowRoot = playerShadowRoot.querySelector('#timeline-shadow-host').createShadowRoot();
+ timeLineShadowRoot.innerHTML = '<div class="slider-thumb" id="timeline-slider-thumb"></div>';
+
+ var volumeShadowRoot = playerShadowRoot.querySelector('#volume-shadow-host').createShadowRoot();
+ volumeShadowRoot.innerHTML = '<div class="slider-thumb" id="volume-slider-thumb"></div>';
+
+ return {
+ 'playerShadowRoot': playerShadowRoot,
+ 'timeLineShadowRoot': timeLineShadowRoot,
+ 'volumeShadowRoot': volumeShadowRoot
+ };
+}
+
+//FIXME This call of initKeyboardEvent works for WebKit-only.
+//See https://bugs.webkit.org/show_bug.cgi?id=16735
+// and https://bugs.webkit.org/show_bug.cgi?id=13368. Add check for browser here
+function fireKeyboardEvent(doc, element, key) {
+ var event = doc.createEvent('KeyboardEvent');
+ event.initKeyboardEvent("keydown", true, true, doc.defaultView, key, 0, false, false, false, false);
+ element.dispatchEvent(event);
+}
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html
deleted file mode 100644
index bb43206b9d0..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_02_01_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-aware-attributes">
-<meta name="assert" content="Extensions to Element Interface: pseudo of type DOMString attribute. Test getter when there is a custom pseudo-element associated with this element">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(function () {
-
- var d = newHTMLDocument();
-
- var widget = d.createElement('div');
- d.body.appendChild(widget);
-
- var s = widget.createShadowRoot();
-
- var thumb = d.createElement('span');
- thumb.innerHTML = 'This is a pseudo-element';
- thumb.pseudo = 'x-thumb';
- s.appendChild(thumb);
-
- var style = d.createElement('style');
- style.innerHTML = '' +
- 'div::x-thumb {' +
- 'font-size: 30px;' +
- '}';
- d.body.appendChild(style);
-
- assert_true(thumb.pseudo != null, 'attribute \'pseudo\' must not be null');
-
- assert_equals(thumb.pseudo, 'x-thumb', 'attribute \'pseudo\' must return ' +
- 'the current custom pseudo-element value')
-
-}, 'A_10_02_01_01_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005.html
deleted file mode 100644
index 1d52beca9ec..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005.html
+++ /dev/null
@@ -1,43 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_02_01_05</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-aware-attributes">
-<meta name="assert" content="Extensions to Element Interface: shadowRoot of type ShadowRoot">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(function () {
-
- var d = newHTMLDocument();
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- //old tree
- var s1 = host.createShadowRoot();
- //young tree
- var s2 = host.createShadowRoot();
-
- assert_equals(host.shadowRoot, s2, 'attribute shadowRoot must return the youngest tree that has ' +
- 'the context object as its shadow host');
-
-
-}, 'A_10_02_01_05_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006.html
index 3f3843f1947..7b5a08d3c33 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006.html
@@ -16,14 +16,14 @@ policies and contribution forms [3].
<meta name="assert" content="Extensions to Element Interface: shadowRoot of type ShadowRoot">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var host = d.createElement('div');
d.body.appendChild(host);
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001.html
deleted file mode 100644
index 23f27406c63..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001.html
+++ /dev/null
@@ -1,61 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: HTML elements can host shadow trees</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Mikhail Fursov" href="mailto:mfursov@unipro.ru">
-<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#partial-element-methods">
-<meta name="assert" content="All HTML elements must be able to host shadow trees.">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-// These elements does not support creating shadow root.
-// instead, NotSupportedError should be thrown.
-// http://w3c.github.io/webcomponents/spec/shadow/#widl-Element-createShadowRoot-ShadowRoot-ShadowRootInit-shadowRootInitDict
-var BLACK_LISTED_ELEMENTS = [
- "button",
- "details",
- "input",
- "marquee",
- "meter",
- "progress",
- "select",
- "textarea",
- "keygen"
-];
-
-function testElement(elementName) {
- var doc = document.implementation.createHTMLDocument('Test');
- var element = doc.createElement(elementName);
- doc.body.appendChild(element);
-
- var shadowRoot = element.createShadowRoot();
- assert_equals(shadowRoot.ownerDocument, doc);
-}
-
-var testParameters = HTML5_ELEMENT_NAMES.filter(function(name) {
- return BLACK_LISTED_ELEMENTS.indexOf(name) == -1;
-}).map(function (name) {
- return [
- 'Checks whether an element "' + name + '" can create a shadow root.',
- name
- ];
-});
-generate_tests(testElement, testParameters);
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/non-element-nodes-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/non-element-nodes-001.html
deleted file mode 100644
index 45ea0d5c71b..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/non-element-nodes-001.html
+++ /dev/null
@@ -1,104 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: Non-element node cannot be a shadow host</title>
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Mikhail Fursov" href="mailto:mfursov@unipro.ru">
-<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#partial-element-methods">
-<meta name="assert" content="Nodes, that are not elements, are not allowed to become shadow hosts.">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
-
-function createTextNode() {
- var doc = document.implementation.createHTMLDocument('Test Document');
- var node = doc.createTextNode('Text Node');
- doc.body.appendChild(node);
- return node;
-}
-
-function createCommentNode() {
- var doc = document.implementation.createHTMLDocument('Test Document');
- var node = doc.createComment('Comment Node');
- doc.body.appendChild(node);
- return node;
-}
-
-function createCDATASectionNode() {
- var doc = document.implementation.createDocument(XHTML_NAMESPACE, 'html');
- var node = doc.createCDATASection('CDATA Section Node');
- doc.documentElement.appendChild(node);
- return node;
-}
-
-function createAttributeNode() {
- var doc = document.implementation.createDocument(XHTML_NAMESPACE, 'html');
- var node = doc.createAttribute('attribute-node');
- doc.documentElement.setAttributeNode(node);
- return node;
-}
-
-function createDocumentFragmentNode() {
- var doc = document.implementation.createDocument(XHTML_NAMESPACE, 'html');
- var node = doc.createDocumentFragment();
- doc.documentElement.appendChild(node);
- return node;
-}
-
-function createProcessingInstructionNode() {
- var doc = document.implementation.createDocument(XHTML_NAMESPACE, 'html');
- var node = doc.createProcessingInstruction('processing-instruction-node', '');
- doc.documentElement.appendChild(node);
- return node;
-}
-
-function createDocumentNode() {
- return document.implementation.createDocument(XHTML_NAMESPACE, 'html');
-}
-
-var factories = [
- ['a text node', createTextNode],
- ['a comment node', createCommentNode],
- ['a CDATA section node', createCDATASectionNode],
- ['an attribute node', createAttributeNode],
- ['a document fragment node', createDocumentFragmentNode],
- ['a processing instruction node', createProcessingInstructionNode],
- ['a document node', createDocumentNode]
-];
-
-// Non-element nodes should not have createShadowRoot() method.
-var noCreateShadowRootTestParameters = factories.map(
- function (nameAndFactory) {
- var name = nameAndFactory[0];
- var factory = nameAndFactory[1];
- return [
- 'Checks whether ' + name + ' does not have createShadowRoot() ' +
- 'method.',
- factory
- ];
- });
-
-function testNoCreateShadowRoot(factory) {
- var node = factory();
- assert_equals(node.createShadowRoot, undefined);
-}
-
-generate_tests(testNoCreateShadowRoot, noCreateShadowRootTestParameters);
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-001.html
index 4645d55105a..d6077da9302 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-001.html
@@ -16,14 +16,14 @@ policies and contribution forms [3].
<meta name="assert" content="Extensions to Element Interface: createShadowRoot method creates new instance of Shadow root object">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var host = d.createElement('div');
d.body.appendChild(host);
@@ -31,7 +31,7 @@ test(function () {
var s = host.createShadowRoot();
assert_true(s instanceof ShadowRoot, 'createShadowRoot() method should create new instance ' +
- 'of ShadowRoot object');
+ 'of ShadowRoot object');
}, 'A_10_02_02_01_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html
index 30223725832..3a2e69165d8 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-002.html
@@ -16,14 +16,15 @@ policies and contribution forms [3].
<meta name="assert" content="Extensions to Element Interface: createShadowRoot method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
var host = d.createElement('div');
d.body.appendChild(host);
@@ -36,7 +37,7 @@ test(unit(function (ctx) {
// span should become invisible as shadow root content
assert_equals(span.offsetTop, 0, 'createShadowRoot() method should establish ' +
- 'the context object as the shadow host of the ShadowRoot object');
+ 'the context object as the shadow host of the ShadowRoot object');
}), 'A_10_02_02_02_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-003.html
deleted file mode 100644
index cbf22abac75..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-element-interface/methods/test-003.html
+++ /dev/null
@@ -1,55 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_02_02_03</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-aware-methods">
-<meta name="assert" content="Extensions to Element Interface: createShadowRoot method">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- var span = d.createElement('span');
- span.setAttribute('id', 'sp0');
- span.innerHTML = 'Some text';
- host.appendChild(span);
-
- //old tree
- var s1 = host.createShadowRoot();
- s1.innerHTML = '<span id="sp1">Span 1</span>';
- //young tree
- var s2 = host.createShadowRoot();
- s2.innerHTML = '<span id="sp2">Span 2</span>';
-
- // span should become invisible as shadow root content
- assert_equals(span.offsetTop, 0, 'Point 1:createShadowRoot() method should add ' +
- 'the ShadowRoot object at the top of the tree stack of its host');
- assert_equals(s1.querySelector('#sp1').offsetTop, 0, 'Point 2:createShadowRoot() method should add ' +
- 'the ShadowRoot object at the top of the tree stack of its host');
- assert_true(s2.querySelector('#sp2').offsetTop > 0, 'Point 3:createShadowRoot() method should add ' +
- 'the ShadowRoot object at the top of the tree stack of its host');
-
-
-}), 'A_10_02_02_03_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html
index 8558f24fd37..e859a847b34 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-001.html
@@ -13,15 +13,16 @@ policies and contribution forms [3].
<title>Shadow DOM Test - event path</title>
<link rel="author" title="Kazuhito Hokamura" href="mailto:k.hokamura@gmail.com">
<link rel="help" href="https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event">
-<meta name="assert" content="Extensions to Event Interface: event.path cross the shadow boundary">
+<meta name="assert" content="Extensions to Event Interface: event.deepPath() cross the shadow boundary">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
-var t = async_test('event.path cross the shadow boundary');
+var t = async_test('event.deepPath() cross the shadow boundary');
t.step(unit(function(ctx) {
var doc = newRenderedHTMLDocument(ctx);
@@ -34,14 +35,14 @@ t.step(unit(function(ctx) {
shadowRoot.appendChild(child);
child.addEventListener('click', t.step_func(function(e) {
- assert_equals(e.path.length, 7, 'path.length');
- assert_equals(e.path[0], child, 'path[0] should be child');
- assert_equals(e.path[1], shadowRoot, 'path[1] should be shadowRoot');
- assert_equals(e.path[2], host, 'path[2] should be host');
- assert_equals(e.path[3], doc.body, 'path[3] should be body');
- assert_equals(e.path[4], doc.documentElement, 'path[4] should be html');
- assert_equals(e.path[5], doc, 'path[5] should be document');
- assert_equals(e.path[6], ctx.iframes[0].contentWindow, 'path[6] should be window');
+ assert_equals(e.deepPath().length, 7, 'deepPath().length');
+ assert_equals(e.deepPath()[0], child, 'deepPath()[0] should be child');
+ assert_equals(e.deepPath()[1], shadowRoot, 'deepPath()[1] should be shadowRoot');
+ assert_equals(e.deepPath()[2], host, 'deepPath()[2] should be host');
+ assert_equals(e.deepPath()[3], doc.body, 'deepPath()[3] should be body');
+ assert_equals(e.deepPath()[4], doc.documentElement, 'deepPath()[4] should be html');
+ assert_equals(e.deepPath()[5], doc, 'deepPath()[5] should be document');
+ assert_equals(e.deepPath()[6], ctx.iframes[0].contentWindow, 'deepPath()[6] should be window');
t.done();
}));
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-002.html
deleted file mode 100644
index f22890403b9..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/extensions-to-event-interface/event-path-002.html
+++ /dev/null
@@ -1,46 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test - event path</title>
-<link rel="author" title="Kazuhito Hokamura" href="mailto:k.hokamura@gmail.com">
-<link rel="help" href="https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#extensions-to-event">
-<meta name="assert" content="Extensions to Event Interface: event.path is readonly">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var t = async_test('event.path is readonly');
-
-t.step(unit(function(ctx) {
- var doc = newRenderedHTMLDocument(ctx);
- var div = doc.createElement('div');
- doc.body.appendChild(div);
-
- div.addEventListener('click', t.step_func(function(e) {
- var obj = {};
- e.path = obj;
- assert_not_equals(e.path, obj);
-
- t.done();
- }));
-
- var event = doc.createEvent('HTMLEvents');
- event.initEvent('click', true, false);
- div.dispatchEvent(event);
-}));
-</script>
-</body>
-</html>
-
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html
index 492650e847b..d305d9b1894 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/activeElement-confirm-return-null.html
@@ -17,18 +17,19 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: confirm activeElement return null">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
assert_equals(s.activeElement, null, 'activeElement attribute of the ShadowRoot must return null if there\'s no focused element');
@@ -37,16 +38,16 @@ test(unit(function (ctx) {
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var inp = d.createElement('input');
- d.body.appendChild(inp);
+ var inp = d.createElement('input');
+ d.body.appendChild(inp);
- inp.focus();
+ inp.focus();
assert_equals(s.activeElement, null, 'activeElement attribute of the ShadowRoot must return null if there\'s no focused element in the shadow tree');
@@ -55,19 +56,19 @@ test(unit(function (ctx) {
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var inp = d.createElement('input');
- d.body.appendChild(inp);
+ var inp = d.createElement('input');
+ d.body.appendChild(inp);
- var inp2 = d.createElement('input');
- s.appendChild(inp2);
+ var inp2 = d.createElement('input');
+ s.appendChild(inp2);
- inp.focus();
+ inp.focus();
assert_equals(s.activeElement, null, 'activeElement attribute of the ShadowRoot must return null if there\'s no focused element in the shadow tree');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007.html
index b471be0208e..22052c343a3 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007.html
@@ -16,32 +16,33 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: readonly attribute Element? activeElement; actual value">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- host.setAttribute('id', 'shRoot');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ host.setAttribute('id', 'shRoot');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var inp = d.createElement('input');
- inp.setAttribute('type', 'text');
- inp.setAttribute('id', 'inpId');
- inp.setAttribute('value', 'Some text');
- s.appendChild(inp);
+ var inp = d.createElement('input');
+ inp.setAttribute('type', 'text');
+ inp.setAttribute('id', 'inpId');
+ inp.setAttribute('value', 'Some text');
+ s.appendChild(inp);
- inp.focus();
+ inp.focus();
assert_true(s.activeElement != null, 'Point 1: activeElement attribute of the ShadowRoot ' +
- 'must return the currently focused element in the shadow tree');
+ 'must return the currently focused element in the shadow tree');
assert_equals(s.activeElement.tagName, 'INPUT', 'Point 2: activeElement attribute of the ShadowRoot ' +
- 'must return the currently focused element in the shadow tree');
+ 'must return the currently focused element in the shadow tree');
}), 'A_10_01_01_03_01_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-009.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-009.html
index d97286f637d..ab3b314bcc3 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-009.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-009.html
@@ -16,25 +16,26 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: innerHTML of type DOMString; Test getter">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var span = d.createElement('span');
- span.innerHTML = 'Some text';
- s.appendChild(span);
+ var span = d.createElement('span');
+ span.innerHTML = 'Some text';
+ s.appendChild(span);
assert_equals(s.innerHTML.toLowerCase(), '<span>some text</span>',
- 'Wrong value of ShadowRoot innerHTML attribute');
+ 'Wrong value of ShadowRoot innerHTML attribute');
}), 'A_10_01_01_04_01_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-010.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-010.html
index bccc0539ffd..7ea514ec7c4 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-010.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-010.html
@@ -16,58 +16,59 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: innerHTML of type DOMString; Test setter">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var span = d.createElement('span');
- span.innerHTML = 'Some text';
- s.appendChild(span);
+ var span = d.createElement('span');
+ span.innerHTML = 'Some text';
+ s.appendChild(span);
- s.innerHTML = '<input type="text"><div>new text</div>';
+ s.innerHTML = '<input type="text"><div>new text</div>';
assert_equals(s.innerHTML.toLowerCase(), '<input type="text"><div>new text</div>',
- 'Wrong value of ShadowRoot innerHTML attribute');
+ 'Wrong value of ShadowRoot innerHTML attribute');
}), 'A_10_01_01_04_02_T01_01');
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var span = d.createElement('span');
- span.setAttribute('id', 'spanId');
- span.innerHTML = 'Some text';
- s.appendChild(span);
+ var span = d.createElement('span');
+ span.setAttribute('id', 'spanId');
+ span.innerHTML = 'Some text';
+ s.appendChild(span);
- s.innerHTML = '<input type="text" id="inputId"><div id="divId">new text</div>';
+ s.innerHTML = '<input type="text" id="inputId"><div id="divId">new text</div>';
assert_equals(s.querySelector('#spanId'), null, 'Point 1:innerHTML attribute must replace all content of ' +
- 'the ShadowRoot object');
+ 'the ShadowRoot object');
assert_true(s.querySelector('#inputId') != null, 'Point 2:innerHTML attribute must replace all content of ' +
- 'the ShadowRoot object');
+ 'the ShadowRoot object');
assert_equals(s.querySelector('#inputId').getAttribute('id'), 'inputId',
- 'Point 3:innerHTML attribute must replace all content of the ShadowRoot object');
+ 'Point 3:innerHTML attribute must replace all content of the ShadowRoot object');
assert_true(s.querySelector('#divId') != null, 'Point 3:innerHTML attribute must replace all content of ' +
- 'the ShadowRoot object');
- assert_equals(s.querySelector('#divId').getAttribute('id'), 'divId',
- 'Point 4:innerHTML attribute must replace all content of the ShadowRoot object');
+ 'the ShadowRoot object');
+ assert_equals(s.querySelector('#divId').getAttribute('id'), 'divId',
+ 'Point 4:innerHTML attribute must replace all content of the ShadowRoot object');
}), 'A_10_01_01_04_02_T01_02');
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-011.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-011.html
index 47f98988ac9..5b6ced6d1dc 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-011.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-011.html
@@ -16,20 +16,21 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: styleSheets of type StyleSheetList, readonly">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- assert_true(s.styleSheets != null, 'ShadowRoot styleSheets attribute shouldn\'t be null');
+ assert_true(s.styleSheets != null, 'ShadowRoot styleSheets attribute shouldn\'t be null');
assert_equals(s.styleSheets.length, 0, 'attribute must return the shadow root style sheets only');
}), 'A_10_01_01_05_01_T01');
@@ -37,16 +38,16 @@ test(unit(function (ctx) {
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var style = d.createElement('style');
- s.appendChild(style);
+ var style = d.createElement('style');
+ s.appendChild(style);
- assert_true(s.styleSheets != null, 'ShadowRoot styleSheets attribute shouldn\'t be null');
+ assert_true(s.styleSheets != null, 'ShadowRoot styleSheets attribute shouldn\'t be null');
assert_equals(s.styleSheets.length, 1, 'attribute must return the shadow root style sheets');
}), 'A_10_01_01_05_01_T02');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-012.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-012.html
index f8f067ffd08..43f024cc78d 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-012.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-012.html
@@ -16,21 +16,22 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: The nodeType attribute of a ShadowRoot instance must return DOCUMENT_FRAGMENT_NODE">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
assert_equals(s.nodeType, 11, 'The nodeType attribute of a ShadowRoot ' +
- 'instance must return DOCUMENT_FRAGMENT_NODE');
+ 'instance must return DOCUMENT_FRAGMENT_NODE');
}), 'A_10_01_01_06_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013.html
index f7f221ec265..55f4d94d9ae 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013.html
@@ -16,21 +16,22 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: The nodeName attribute of a ShadowRoot instance must return "#document-fragment".">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
assert_equals(s.nodeName, '#document-fragment', 'The nodeName attribute of a ShadowRoot instance ' +
- 'must return "#document-fragment".');
+ 'must return "#document-fragment".');
}), 'A_10_01_01_07_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-014.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-014.html
deleted file mode 100644
index fb411d98068..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-014.html
+++ /dev/null
@@ -1,48 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: ShadowRoot olderShadowRoot</title>
-<link rel="author" title="Kenji Baheux" href="mailto:kenjibaheux@google.com">
-<link rel="author" title="Kyohei Tsukuda" href="tsukuda.kyouhei@gmail.com">
-<link rel="help" href="http://w3c.github.io/webcomponents/spec/shadow/#widl-ShadowRoot-olderShadowRoot">
-<meta name="assert" content="The ShadowRoot element: olderShadowRoot attribute">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- // Shadow root and older Shadow root to play with
- var oldRoot = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<span id="spandex">This is a shadow root content</span>' +
- '<content><span id="contentId">This is the content fallback</span></content>';
- oldRoot.appendChild(div);
- var youngRoot = host.createShadowRoot();
-
- assert_equals(oldRoot.olderShadowRoot, null, 'If the context object is the oldest shadow root, return null');
- assert_equals(youngRoot.olderShadowRoot, oldRoot, 'Return the older shadow root relative to the context object');
-
-}), 'ShadowRoot.olderShadowRoot_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001.html
index e87ff419a65..892558af536 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001.html
@@ -16,14 +16,14 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: HTMLElement getElementById(DOMString elementId) method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var el = d.createElement('div');
d.body.appendChild(el);
@@ -35,9 +35,9 @@ test(function () {
s.appendChild(child);
assert_true(s.getElementById('span_id') != null, 'Point 1: ShadowRoot getElementById() ' +
- 'method should return child element');
+ 'method should return child element');
assert_equals(s.getElementById('span_id').getAttribute('id'), 'span_id', 'Point 2: ' +
- 'ShadowRoot getElementById() method should return child element');
+ 'ShadowRoot getElementById() method should return child element');
}, 'A_10_01_02_01_T01');
@@ -45,7 +45,7 @@ test(function () {
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var el = d.createElement('div');
d.body.appendChild(el);
@@ -53,7 +53,7 @@ test(function () {
var s = el.createShadowRoot();
assert_true(s.getElementById('span_id') == null, ' ShadowRoot getElementById() ' +
- 'method should return null if matching element not found');
+ 'method should return null if matching element not found');
}, 'A_10_01_02_01_T02');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004.html
index d0c4451cd68..70971553b8a 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-004.html
@@ -16,33 +16,34 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: Selection? getSelection() method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var span = d.createElement('span');
- span.innerHTML = 'Some text';
- s.appendChild(span);
+ var span = d.createElement('span');
+ span.innerHTML = 'Some text';
+ s.appendChild(span);
- var range = d.createRange();
- range.setStart(span.firstChild, 0);
- range.setEnd(span.firstChild, 3);
+ var range = d.createRange();
+ range.setStart(span.firstChild, 0);
+ range.setEnd(span.firstChild, 3);
- var selection = s.getSelection();
+ var selection = s.getSelection();
selection.removeAllRanges();
selection.addRange(range);
var sl = s.getSelection();
assert_equals(sl.toString(), 'Som', 'The getSelection() method of the shadow root object must return ' +
- 'the current selection in this shadow tree');
+ 'the current selection in this shadow tree');
}), 'A_10_01_02_04_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006.html
index 3b9fde76a37..46ab47faf17 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: Element? elementFromPoint(float x, float y) method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -29,10 +29,10 @@ test(function () {
d.body.appendChild(el);
try {
- el.elementFromPoint(1, 1);
- assert_true(false, 'TypeMismatchError should be thrown');
+ el.elementFromPoint(1, 1);
+ assert_true(false, 'TypeMismatchError should be thrown');
} catch(e) {
- assert_true(e instanceof TypeError, 'Wrong error type');
+ assert_true(e instanceof TypeError, 'Wrong error type');
}
}, 'A_10_01_02_06_01_T01');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007.html
index 120f207f77d..4bf5afb250a 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007.html
@@ -16,14 +16,14 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: Element? elementFromPoint(float x, float y) method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var el = d.createElement('div');
d.body.appendChild(el);
@@ -35,14 +35,14 @@ test(function () {
s.appendChild(span);
assert_equals(s.elementFromPoint(-1, 1), null, 'If x argument of elementFromPoint(x, y) is less ' +
- 'than zero then method shold return null');
+ 'than zero then method shold return null');
}, 'A_10_01_02_06_02_T01');
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var el = d.createElement('div');
d.body.appendChild(el);
@@ -54,7 +54,7 @@ test(function () {
s.appendChild(span);
assert_equals(s.elementFromPoint(1, -1), null, 'If y argument of elementFromPoint(x, y) is less ' +
- 'than zero then method shold return null');
+ 'than zero then method shold return null');
}, 'A_10_01_02_06_02_T02');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010.html
index b7b544735b7..129f316708f 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010.html
@@ -16,25 +16,26 @@ policies and contribution forms [3].
<meta name="assert" content="ShadowRoot Object: Invoking the cloneNode() method on a ShadowRoot instance must always throw a DATA_CLONE_ERR exception.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../../testcommon.js"></script>
+<script src="../../../../../html/resources/common.js"></script>
+<script src="../../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- try {
- s.cloneNode();
- assert_true(false, 'Invoking the cloneNode() method on a ShadowRoot instance must always ' +
- 'throw a DATA_CLONE_ERR exception.');
- } catch (e) {
- assert_equals(e.code, 25, 'Wrong exceprion type');
- }
+ try {
+ s.cloneNode();
+ assert_true(false, 'Invoking the cloneNode() method on a ShadowRoot instance must always ' +
+ 'throw a DATA_CLONE_ERR exception.');
+ } catch (e) {
+ assert_equals(e.code, 25, 'Wrong exceprion type');
+ }
}), 'A_10_01_02_09_T01');
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-001.html
deleted file mode 100644
index 2d53d51f539..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-001.html
+++ /dev/null
@@ -1,81 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_04_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#content-element">
-<meta name="assert" content="The content HTML element: fallback content">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content select=".clazz"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_true(s.querySelector('#spandex').offsetTop > 0, 'Fallback content should be rendered');
-
-}), 'A_10_04_01_T01');
-
-
-
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content select=".shadow"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_equals(s.querySelector('#spandex').offsetTop, 0, 'Fallback content should not be rendered');
-
-}), 'A_10_04_01_T02');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-002.html
deleted file mode 100644
index aa433babaa0..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-002.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_04_02</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#content-element">
-<meta name="assert" content="The content HTML element: select attribute">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content select=".shadow"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_equals(s.querySelector('#spandex').offsetTop, 0, 'Fallback content should not be rendered');
-
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 1: Element should not be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 2: Element should not be rendered');
- assert_equals(d.querySelector('#li6').offsetTop, 0, 'Point 3: Element should not be rendered');
-
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 11: Element should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 12: Element should be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 13: Element should be rendered');
-
-}), 'A_10_04_02_T01_01');
-
-
-
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content select=".shadow, #li4"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_equals(s.querySelector('#spandex').offsetTop, 0, 'Fallback content should not be rendered');
-
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 1: Element should not be rendered');
- assert_equals(d.querySelector('#li6').offsetTop, 0, 'Point 2: Element should not be rendered');
-
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 11: Element should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 12: Element should be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 13: Element should be rendered');
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 14: Element should be rendered');
-
-}), 'A_10_04_02_T01_02');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-003.html
deleted file mode 100644
index 7ab035ece47..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-003.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_04_03</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#content-element">
-<meta name="assert" content="The content HTML element: invalid select attribute">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content select="&@()"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_true(s.querySelector('#spandex').offsetTop > 0, 'Fallback content should be rendered');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0, 'Point 1: Element should not be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 2: Element should not be rendered');
- assert_equals(d.querySelector('#li3').offsetTop, 0, 'Point 3: Element should not be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 4: Element should not be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0, 'Point 5: Element should not be rendered');
- assert_equals(d.querySelector('#li6').offsetTop, 0, 'Point 6: Element should not be rendered');
-
-}), 'A_10_04_03_T01');
-
-
-test(unit(function (ctx) {
-
-var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content select=".shadow, &@()"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_true(s.querySelector('#spandex').offsetTop > 0, 'Fallback content should be rendered');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0, 'Point 1: Element should not be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 2: Element should not be rendered');
- assert_equals(d.querySelector('#li3').offsetTop, 0, 'Point 3: Element should not be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 4: Element should not be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0, 'Point 5: Element should not be rendered');
- assert_equals(d.querySelector('#li6').offsetTop, 0, 'Point 6: Element should not be rendered');
-
-}), 'A_10_04_03_T02');
-
-
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content select=".shadow, &@(), #li4"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_true(s.querySelector('#spandex').offsetTop > 0, 'Fallback content should be rendered');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0, 'Point 1: Element should not be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 2: Element should not be rendered');
- assert_equals(d.querySelector('#li3').offsetTop, 0, 'Point 3: Element should not be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 4: Element should not be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0, 'Point 5: Element should not be rendered');
- assert_equals(d.querySelector('#li6').offsetTop, 0, 'Point 6: Element should not be rendered');
-
-}), 'A_10_04_03_T03');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-005.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-005.html
deleted file mode 100644
index 00d8354c4d4..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-005.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_04_05</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#content-element">
-<meta name="assert" content="The content HTML element: reset-style-inheritance attribute">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul id="shHost">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
-
- var defHeight1 = d.querySelector('#li1').offsetHeight;
- var defHeight2 = d.querySelector('#li2').offsetHeight;
- var defHeight3 = d.querySelector('#li3').offsetHeight;
- var defHeight4 = d.querySelector('#li4').offsetHeight;
- var defHeight5 = d.querySelector('#li5').offsetHeight;
- var defHeight6 = d.querySelector('#li6').offsetHeight;
-
- assert_true(defHeight1 > 0, 'Point 1: Element height should be greater than zero');
- assert_true(defHeight2 > 0, 'Point 2: Element height should be greater than zero');
- assert_true(defHeight3 > 0, 'Point 3: Element height should be greater than zero');
- assert_true(defHeight4 > 0, 'Point 4: Element height should be greater than zero');
- assert_true(defHeight5 > 0, 'Point 5: Element height should be greater than zero');
- assert_true(defHeight6 > 0, 'Point 6: Element height should be greater than zero');
-
- var host = d.querySelector('#shHost');
-
- d.body.setAttribute('style', 'font-size: 30px');
-
- var height1 = d.querySelector('#li1').offsetHeight;
- var height2 = d.querySelector('#li2').offsetHeight;
- var height3 = d.querySelector('#li3').offsetHeight;
- var height4 = d.querySelector('#li4').offsetHeight;
- var height5 = d.querySelector('#li5').offsetHeight;
- var height6 = d.querySelector('#li6').offsetHeight;
-
-
- assert_true(height1 > defHeight1, 'Point 11: Element height should be changed');
- assert_true(height2 > defHeight2, 'Point 12: Element height should be changed');
- assert_true(height3 > defHeight3, 'Point 13: Element height should be changed');
- assert_true(height4 > defHeight4, 'Point 14: Element height should be changed');
- assert_true(height5 > defHeight5, 'Point 15: Element height should be changed');
- assert_true(height6 > defHeight6, 'Point 16: Element height should be changed');
-
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML ='<ul><content select=".shadow"></content></ul>';
- s.appendChild(div);
-
- assert_equals(d.querySelector('#li1').offsetHeight, height1, 'Point 21: Inherited ' +
- 'element style should be reset');
- assert_equals(d.querySelector('#li3').offsetHeight, height3, 'Point 22: Inherited ' +
- 'element style should be reset');
- assert_equals(d.querySelector('#li5').offsetHeight, height5, 'Point 23: Inherited ' +
- 'element style should be reset');
-
- assert_equals(d.querySelector('#li2').offsetHeight, 0, 'Point 24: Element shouldn\'t be rendered');
- assert_equals(d.querySelector('#li4').offsetHeight, 0, 'Point 25: Element shouldn\'t be rendered');
- assert_equals(d.querySelector('#li6').offsetHeight, 0, 'Point 26: Element shouldn\'t be rendered');
-
-}), 'A_10_04_05_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-006.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-006.html
deleted file mode 100644
index 54c6362a984..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-content-html-element/test-006.html
+++ /dev/null
@@ -1,93 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_04_06</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#content-element">
-<meta name="assert" content="The content HTML element: getDistributedNodes method">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content id="contentId" select=".clazz"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_equals(s.querySelector('#contentId').getDistributedNodes().length, 1,
- 'Fallback content should show up as distributed nodes');
-
- assert_equals(s.querySelector('#contentId').getDistributedNodes()[0].id, 'spandex',
- 'Fallback content should show up as distributed nodes');
-
-}), 'A_10_04_06_T01');
-
-
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul><content id="contentId" select=".shadow"><span id="spandex">This is fallback content</span></content></ul>';
- s.appendChild(div);
-
- assert_equals(s.querySelector('#contentId').getDistributedNodes().length, 3,
- 'Wrond distributed nodes collection size');
-
- assert_equals(s.querySelector('#contentId').getDistributedNodes()[0].getAttribute('id'), 'li1',
- 'Point 1: wrong element in distributed nodes collection');
- assert_equals(s.querySelector('#contentId').getDistributedNodes()[1].getAttribute('id'), 'li3',
- 'Point 2: wrong element in distributed nodes collection');
- assert_equals(s.querySelector('#contentId').getDistributedNodes()[2].getAttribute('id'), 'li5',
- 'Point 3: wrong element in distributed nodes collection');
-
-
-}), 'A_10_04_06_T02');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-001.html
deleted file mode 100644
index 2f8167294ec..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-001.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_05_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-element">
-<meta name="assert" content="The shadow HTML element: fallback content">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<span id="spandex">This is a shadow root content</span>' +
- '<shadow><span id="shadowId">This is a shadow fallback content</span></shadow>';
- s.appendChild(div);
-
- assert_true(s.querySelector('#shadowId').offsetTop == 0, 'Shadow fallback content should not be rendered in this case');
-
-}), 'A_10_05_01_T01');
-
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<span id="spandex">This is a shadow root content</span>' +
- '<content><span id="contentId">This is a content fallback</span></content>';
- s.appendChild(div);
-
- assert_true(s.querySelector('#contentId').offsetTop > 0, 'Fallback content should be rendered');
-
-}), 'A_10_05_01_T02');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-002.html
deleted file mode 100644
index 85f7f2b1b23..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-002.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_05_02</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-element">
-<meta name="assert" content="The shadow HTML element: shadow insertion point">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- //old tree
- var s1 = host.createShadowRoot();
- s1.innerHTML = '<span id="sp1">This is an old tree</span>';
- //young tree
- var s2 = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<span id="spandex">This is a shadow root content</span>' +
- '<shadow><span id="shadowId">This is a shadow fallback content</span></shadow>';
- s2.appendChild(div);
-
- assert_equals(s2.querySelector('#shadowId').offsetTop, 0, 'Fallback content should not be rendered');
- assert_true(s1.querySelector('#sp1').offsetTop > 0, 'Old tree should be rendered');
- assert_true(s2.querySelector('#spandex').offsetTop > 0, 'Element should be rendered');
-
-}), 'A_10_05_02_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-004.html
deleted file mode 100644
index 1ab2b7d2a9b..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/elements-and-dom-objects/the-shadow-html-element/test-004.html
+++ /dev/null
@@ -1,106 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_10_05_04</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-element">
-<meta name="assert" content="The shadow HTML element: no reset-style-inheritance attribute">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-// test no reset-style-inheritance
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul id="shHost">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
-
- var defHeight1 = d.querySelector('#li1').offsetHeight;
- var defHeight2 = d.querySelector('#li2').offsetHeight;
- var defHeight3 = d.querySelector('#li3').offsetHeight;
- var defHeight4 = d.querySelector('#li4').offsetHeight;
- var defHeight5 = d.querySelector('#li5').offsetHeight;
- var defHeight6 = d.querySelector('#li6').offsetHeight;
-
- assert_true(defHeight1 > 0, 'Point 1: Element height should be greater than zero');
- assert_true(defHeight2 > 0, 'Point 2: Element height should be greater than zero');
- assert_true(defHeight3 > 0, 'Point 3: Element height should be greater than zero');
- assert_true(defHeight4 > 0, 'Point 4: Element height should be greater than zero');
- assert_true(defHeight5 > 0, 'Point 5: Element height should be greater than zero');
- assert_true(defHeight6 > 0, 'Point 6: Element height should be greater than zero');
-
- var host = d.querySelector('#shHost');
-
- d.body.setAttribute('style', 'font-size: 30px');
-
- var height1 = d.querySelector('#li1').offsetHeight;
- var height2 = d.querySelector('#li2').offsetHeight;
- var height3 = d.querySelector('#li3').offsetHeight;
- var height4 = d.querySelector('#li4').offsetHeight;
- var height5 = d.querySelector('#li5').offsetHeight;
- var height6 = d.querySelector('#li6').offsetHeight;
-
-
- assert_true(height1 > defHeight1, 'Point 11: Element height should be changed');
- assert_true(height2 > defHeight2, 'Point 12: Element height should be changed');
- assert_true(height3 > defHeight3, 'Point 13: Element height should be changed');
- assert_true(height4 > defHeight4, 'Point 14: Element height should be changed');
- assert_true(height5 > defHeight5, 'Point 15: Element height should be changed');
- assert_true(height6 > defHeight6, 'Point 16: Element height should be changed');
-
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML ='<ul><content select=".shadow"></content></ul>';
- s.appendChild(div);
-
- assert_equals(d.querySelector('#li1').offsetHeight, height1, 'Point 21: Element height should not be changed');
- assert_equals(d.querySelector('#li3').offsetHeight, height3, 'Point 22: Element height should not be changed');
- assert_equals(d.querySelector('#li5').offsetHeight, height5, 'Point 23: Element height should not be changed');
-
- assert_equals(d.querySelector('#li2').offsetHeight, 0, 'Point 24: Element shouldn\'t be rendered');
- assert_equals(d.querySelector('#li4').offsetHeight, 0, 'Point 25: Element shouldn\'t be rendered');
- assert_equals(d.querySelector('#li6').offsetHeight, 0, 'Point 26: Element shouldn\'t be rendered');
-
- //Young tree
- var s2 = host.createShadowRoot();
-
- var div2 = d.createElement('div');
- div2.innerHTML = '<shadow></shadow>';
- s2.appendChild(div2);
-
- //styles should be reset
- assert_equals(d.querySelector('#li1').offsetHeight, height1, 'Point 31: Inherited ' +
- 'element style should not be reset');
- assert_equals(d.querySelector('#li3').offsetHeight, height3, 'Point 32: Inherited ' +
- 'element style should not be reset');
- assert_equals(d.querySelector('#li5').offsetHeight, height5, 'Point 33: Inherited ' +
- 'element style should not be reset');
-
-}), 'A_10_05_04_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-001.html
index 9e508c499b6..e10ef19b899 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Event Dispatch: At the time of event dispatch:The Event target and currentTarget attributes must return the relative target for the node on which event listeners are invoked">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -36,13 +37,13 @@ A_05_05_01_T01.step(unit(function (ctx) {
//For #volume-slider-thumb relative target #volume-slider-thumb
roots.volumeShadowRoot.querySelector('#volume-slider-thumb').addEventListener('click',
- A_05_05_01_T01.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider-thumb',
- 'Point 1: Wrong target');
- assert_equals(event.currentTarget.getAttribute('id'), 'volume-slider-thumb',
- 'Point 1: Wrong currentTarget');
- }), false);
+ A_05_05_01_T01.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider-thumb',
+ 'Point 1: Wrong target');
+ assert_equals(event.currentTarget.getAttribute('id'), 'volume-slider-thumb',
+ 'Point 1: Wrong currentTarget');
+ }), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ('click', true, false);
@@ -69,13 +70,13 @@ A_05_05_01_T02.step(unit(function (ctx) {
//For #volume-shadow-root relative target #volume-slider-thumb
roots.volumeShadowRoot.addEventListener('click',
- A_05_05_01_T02.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider-thumb',
- 'Wrong target');
- assert_true(event.currentTarget == roots.volumeShadowRoot,
- 'Wrong currentTarget');
- }), false);
+ A_05_05_01_T02.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider-thumb',
+ 'Wrong target');
+ assert_true(event.currentTarget == roots.volumeShadowRoot,
+ 'Wrong currentTarget');
+ }), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ('click', true, false);
@@ -102,19 +103,19 @@ A_05_05_01_T03.step(unit(function (ctx) {
//For #volume-slider relative target #volume-shadow-host
roots.playerShadowRoot.querySelector('#volume-slider').addEventListener('click',
- A_05_05_01_T03.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong target');
- assert_equals(event.currentTarget.getAttribute('id'), 'volume-slider',
- 'Wrong currentTarget');
- }), false);
+ A_05_05_01_T03.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong target');
+ assert_equals(event.currentTarget.getAttribute('id'), 'volume-slider',
+ 'Wrong currentTarget');
+ }), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ('click', true, false);
roots.volumeShadowRoot.querySelector('#volume-slider-thumb').dispatchEvent(event);
- assert_true(invoked, 'Event listener was not invoked');
+ assert_true(invoked, 'Event listener was not invoked');
A_05_05_01_T03.done();
}));
@@ -136,21 +137,21 @@ A_05_05_01_T04.step(unit(function (ctx) {
//For #volume-slider-container relative target #volume-shadow-host
roots.playerShadowRoot.querySelector('#volume-slider-container').addEventListener('click',
- A_05_05_01_T04.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong target');
- assert_equals(event.currentTarget.getAttribute('id'), 'volume-slider-container',
- 'Wrong currentTarget');
- }), false);
+ A_05_05_01_T04.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong target');
+ assert_equals(event.currentTarget.getAttribute('id'), 'volume-slider-container',
+ 'Wrong currentTarget');
+ }), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ('click', true, false);
roots.volumeShadowRoot.querySelector('#volume-slider-thumb').dispatchEvent(event);
- assert_true(invoked, 'Event listener was not invoked');
+ assert_true(invoked, 'Event listener was not invoked');
- A_05_05_01_T04.done();
+ A_05_05_01_T04.done();
}));
@@ -169,21 +170,21 @@ A_05_05_01_T05.step(unit(function (ctx) {
//For #controls relative target #volume-shadow-host
roots.playerShadowRoot.querySelector('#controls').addEventListener('click',
- A_05_05_01_T05.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong target');
- assert_equals(event.currentTarget.getAttribute('id'), 'controls',
- 'Wrong currentTarget');
- }), false);
+ A_05_05_01_T05.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong target');
+ assert_equals(event.currentTarget.getAttribute('id'), 'controls',
+ 'Wrong currentTarget');
+ }), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ('click', true, false);
roots.volumeShadowRoot.querySelector('#volume-slider-thumb').dispatchEvent(event);
- assert_true(invoked, 'Event listener was not invoked');
+ assert_true(invoked, 'Event listener was not invoked');
- A_05_05_01_T05.done();
+ A_05_05_01_T05.done();
}));
@@ -202,21 +203,21 @@ A_05_05_01_T06.step(unit(function (ctx) {
//For #player-shadow-host relative target #player-shadow-host
d.querySelector('#player-shadow-host').addEventListener('click',
- A_05_05_01_T06.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
- 'Wrong target');
- assert_equals(event.currentTarget.getAttribute('id'), 'player-shadow-host',
- 'Wrong currentTarget');
- }), false);
+ A_05_05_01_T06.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
+ 'Wrong target');
+ assert_equals(event.currentTarget.getAttribute('id'), 'player-shadow-host',
+ 'Wrong currentTarget');
+ }), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ('click', true, false);
roots.volumeShadowRoot.querySelector('#volume-slider-thumb').dispatchEvent(event);
- assert_true(invoked, 'Event listener was not invoked');
+ assert_true(invoked, 'Event listener was not invoked');
- A_05_05_01_T06.done();
+ A_05_05_01_T06.done();
}));
@@ -236,21 +237,21 @@ A_05_05_01_T07.step(unit(function (ctx) {
//For #player relative target #player-shadow-host
d.querySelector('#player').addEventListener('click',
- A_05_05_01_T07.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
- 'Wrong target');
- assert_equals(event.currentTarget.getAttribute('id'), 'player',
- 'Wrong currentTarget');
- }), false);
+ A_05_05_01_T07.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
+ 'Wrong target');
+ assert_equals(event.currentTarget.getAttribute('id'), 'player',
+ 'Wrong currentTarget');
+ }), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ('click', true, false);
roots.volumeShadowRoot.querySelector('#volume-slider-thumb').dispatchEvent(event);
- assert_true(invoked, 'Event listener was not invoked');
+ assert_true(invoked, 'Event listener was not invoked');
- A_05_05_01_T07.done();
+ A_05_05_01_T07.done();
}));
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-002.html
index 2c8fbab4ce4..8ea42cad733 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-002.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Event Dispatch: The MouseEvent relatedTarget attribute must return the adjusted related target">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -36,11 +37,11 @@ A_05_05_02_T01.step(unit(function (ctx) {
//For #volume-shadow-root adjusted related target #volume-shadow-root
roots.volumeShadowRoot.addEventListener('mouseover',
- A_05_05_02_T01.step_func(function(event) {
- invoked = true;
- assert_true(event.relatedTarget === roots.volumeShadowRoot,
- 'Wrong relatedTarget');
- }), false);
+ A_05_05_02_T01.step_func(function(event) {
+ invoked = true;
+ assert_true(event.relatedTarget === roots.volumeShadowRoot,
+ 'Wrong relatedTarget');
+ }), false);
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-003.html
index 6d217bb6db7..b0a5a30af5b 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-dispatch/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Event Path Trimming: In cases where both relatedTarget and target of a trusted event are part of the same shadow tree, the conforming UAs must stop events at the shadow root to avoid the appearance of spurious mouseover and mouseout events firing from the same node.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -44,20 +45,20 @@ A_05_05_03_T01.step(unit(function (ctx) {
s.appendChild(input2);
input1.addEventListener('focusin', A_05_05_03_T01.step_func(function(event) {
- assert_equals(event.deepPath.length, 7);
- assert_equals(event.deepPath[0].id, 'input1');
- assert_equals(event.deepPath[1].id, 'shadow');
- assert_equals(event.deepPath[2].id, 'host');
- assert_equals(event.deepPath[3].tagName, 'BODY');
- assert_equals(event.deepPath[4].tagName, 'HTML');
- assert_equals(event.deepPath[5], d);
- assert_equals(event.deepPath[6], ctx.iframes[0].contentWindow);
+ assert_equals(event.deepPath().length, 7);
+ assert_equals(event.deepPath()[0].id, 'input1');
+ assert_equals(event.deepPath()[1].id, 'shadow');
+ assert_equals(event.deepPath()[2].id, 'host');
+ assert_equals(event.deepPath()[3].tagName, 'BODY');
+ assert_equals(event.deepPath()[4].tagName, 'HTML');
+ assert_equals(event.deepPath()[5], d);
+ assert_equals(event.deepPath()[6], ctx.iframes[0].contentWindow);
}), false);
input2.addEventListener('focusin', A_05_05_03_T01.step_func(function(event) {
- assert_equals(event.deepPath.length, 2);
- assert_equals(event.deepPath[0].id, 'input2');
- assert_equals(event.deepPath[1].id, 'shadow');
+ assert_equals(event.deepPath().length, 2);
+ assert_equals(event.deepPath()[0].id, 'input2');
+ assert_equals(event.deepPath()[1].id, 'shadow');
A_05_05_03_T01.done();
}), false);
@@ -69,7 +70,7 @@ A_05_05_03_T01.step(unit(function (ctx) {
// In this case, original relatedTarget is #input1, and original target
// is #input2.
// It should be viewed outside the shadow as "target == relatedTarget"
- // after event retargeting, therefore, event.deepPath above the shadow
+ // after event retargeting, therefore, event.deepPath() above the shadow
// host will be trimmed.
// Expected event path for #input2:
// <input>, #shadow-root
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-001.html
index b0e0199dd1a..c40b5bfb04a 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-001.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="Event Retargeting:test that event.target is retargeted when event crosses shadow boundary and vice versa">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -31,23 +31,23 @@ A_05_01_01_T1.step(function () {
iframe.onload = A_05_01_01_T1.step_func(function () {
try {
- var d = iframe.contentDocument;
- var div = d.createElement('div');
- d.body.appendChild(div);
+ var d = iframe.contentDocument;
+ var div = d.createElement('div');
+ d.body.appendChild(div);
- var s = div.createShadowRoot();
+ var s = div.createShadowRoot();
- var div2 = d.createElement('div');
- s.appendChild(div2);
+ var div2 = d.createElement('div');
+ s.appendChild(div2);
- var inp = d.createElement('input');
- inp.setAttribute('type', 'text');
- inp.setAttribute('id', 'inpid');
- div2.appendChild(inp);
+ var inp = d.createElement('input');
+ inp.setAttribute('type', 'text');
+ inp.setAttribute('id', 'inpid');
+ div2.appendChild(inp);
- div2.addEventListener('click', A_05_01_01_T1.step_func(function (event) {
+ div2.addEventListener('click', A_05_01_01_T1.step_func(function (event) {
assert_equals(event.target.tagName, 'INPUT', 'Information about target of the event that ' +
- 'doesn\'t cross the shadow boundaries should not be adjusted');
+ 'doesn\'t cross the shadow boundaries should not be adjusted');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -72,24 +72,24 @@ A_05_01_01_T2.step(function () {
iframe.onload = A_05_01_01_T2.step_func(function () {
try {
- var d = iframe.contentDocument;
+ var d = iframe.contentDocument;
- var div = d.createElement('div');
- d.body.appendChild(div);
+ var div = d.createElement('div');
+ d.body.appendChild(div);
- var s = div.createShadowRoot();
+ var s = div.createShadowRoot();
- var div2 = d.createElement('div');
- s.appendChild(div2);
+ var div2 = d.createElement('div');
+ s.appendChild(div2);
- var inp = d.createElement('input');
- inp.setAttribute('type', 'text');
- inp.setAttribute('id', 'inpid');
- div2.appendChild(inp);
+ var inp = d.createElement('input');
+ inp.setAttribute('type', 'text');
+ inp.setAttribute('id', 'inpid');
+ div2.appendChild(inp);
- div.addEventListener('click', A_05_01_01_T2.step_func(function (event) {
+ div.addEventListener('click', A_05_01_01_T2.step_func(function (event) {
assert_equals(event.target.tagName, 'DIV', 'Information about event target crossing ' +
- 'the shadow boundaries should be adjusted');
+ 'the shadow boundaries should be adjusted');
}), false);
var event = d.createEvent('HTMLEvents');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-002.html
deleted file mode 100644
index 5550b85ad98..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-002.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_05_01_02</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#event-retargeting">
-<meta name="assert" content="Event Retargeting:Event retargeting for document nodes distributed among insertion points">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_05_01_02_T1 = async_test('A_05_01_02_T1');
-
-A_05_01_02_T1.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_05_01_02_T1.step_func(function () {
-
- try {
- var d = iframe.contentDocument;
-
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
-
- //make shadow subtree
- var div = document.createElement('div');
- div.innerHTML = '<ul id="ip_wrapper"><content select=".shadow"></content></ul>';
- s.appendChild(div);
-
- d.body.addEventListener('click', A_05_01_02_T1.step_func(function (event) {
- assert_equals(event.target.tagName, 'LI', 'Incorrect target');
- }), false);
-
- var event = d.createEvent('HTMLEvents');
- event.initEvent ("click", true, false);
- d.querySelector('#li3').dispatchEvent(event);
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_05_01_02_T1.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-003.html
index 2c469fdcc2f..a79b9cd3137 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Event Retargeting:Event retargeting for fallback content">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,16 +25,16 @@ policies and contribution forms [3].
var A_05_01_03_T01 = async_test('A_05_01_03_T01');
A_05_01_03_T01.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
d.body.innerHTML = '' +
- '<div id="main">' +
- '<div id="shadow-root">' +
- '<span>1</span>' +
- '<span>2</span>' +
- '<span>3</span>' +
- '</div>' +
- '</div>';
+ '<div id="main">' +
+ '<div id="shadow-root">' +
+ '<span>1</span>' +
+ '<span>2</span>' +
+ '<span>3</span>' +
+ '</div>' +
+ '</div>';
var ul = d.querySelector('#shadow-root');
var s = ul.createShadowRoot();
@@ -43,17 +44,17 @@ A_05_01_03_T01.step(unit(function (ctx) {
div.innerHTML = '<content select=".shadow"><span id="flbk">Fallback item</span></content>';
s.appendChild(div);
- d.body.addEventListener('click', A_05_01_03_T01.step_func(function (event) {
+ d.body.addEventListener('click', A_05_01_03_T01.step_func(function (event) {
assert_equals(event.target.getAttribute('id'), 'shadow-root', 'Information about ' +
- 'event target crossing the shadow boundaries should be adjusted for the fallback ' +
- 'content');
+ 'event target crossing the shadow boundaries should be adjusted for the fallback ' +
+ 'content');
}), false);
var event = d.createEvent('HTMLEvents');
event.initEvent ("click", true, false);
s.querySelector('#flbk').dispatchEvent(event);
- A_05_01_03_T01.done();
+ A_05_01_03_T01.done();
}));
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-004.html
index 7db6fa116fa..c91e25b7022 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-004.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/event-retargeting/test-004.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Event Retargeting:Retargeting algorithm">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,18 +25,18 @@ policies and contribution forms [3].
var A_05_01_04_T01 = async_test('A_05_01_04_T01');
A_05_01_04_T01.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
//see at http://www.w3.org/TR/shadow-dom/#event-retargeting-example
//For #volume-slider-thumb relative target is #volume-slider-thumb
roots.volumeShadowRoot.querySelector('#volume-slider-thumb').addEventListener('click',
- A_05_01_04_T01.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider-thumb',
- 'Wrong related target');
+ A_05_01_04_T01.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider-thumb',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -44,7 +45,7 @@ A_05_01_04_T01.step(unit(function (ctx) {
assert_true(invoked, 'Event listener was not invoked');
- A_05_01_04_T01.done();
+ A_05_01_04_T01.done();
}));
@@ -52,8 +53,8 @@ A_05_01_04_T01.step(unit(function (ctx) {
var A_05_01_04_T02 = async_test('A_05_01_04_T02');
A_05_01_04_T02.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -61,10 +62,10 @@ A_05_01_04_T02.step(unit(function (ctx) {
//For #volume-shadow-host relative target is #volume-shadow-host
roots.playerShadowRoot.querySelector('#volume-shadow-host').addEventListener('click',
- A_05_01_04_T02.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong related target');
+ A_05_01_04_T02.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -82,8 +83,8 @@ A_05_01_04_T02.step(unit(function (ctx) {
var A_05_01_04_T03 = async_test('A_05_01_04_T03');
A_05_01_04_T03.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -91,10 +92,10 @@ A_05_01_04_T03.step(unit(function (ctx) {
//For #volume-slider relative target is #volume-shadow-host
roots.playerShadowRoot.querySelector('#volume-slider').addEventListener('click',
- A_05_01_04_T03.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong related target');
+ A_05_01_04_T03.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -110,8 +111,8 @@ A_05_01_04_T03.step(unit(function (ctx) {
var A_05_01_04_T04 = async_test('A_05_01_04_T04');
A_05_01_04_T04.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -119,10 +120,10 @@ A_05_01_04_T04.step(unit(function (ctx) {
//For #volume-slider-container relative target is #volume-shadow-host
roots.playerShadowRoot.querySelector('#volume-slider-container').addEventListener('click',
- A_05_01_04_T04.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong related target');
+ A_05_01_04_T04.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -138,8 +139,8 @@ A_05_01_04_T04.step(unit(function (ctx) {
var A_05_01_04_T05 = async_test('A_05_01_04_T05');
A_05_01_04_T05.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -147,10 +148,10 @@ A_05_01_04_T05.step(unit(function (ctx) {
//For #controls relative target is #volume-shadow-host
roots.playerShadowRoot.querySelector('#controls').addEventListener('click',
- A_05_01_04_T05.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong related target');
+ A_05_01_04_T05.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -166,8 +167,8 @@ A_05_01_04_T05.step(unit(function (ctx) {
var A_05_01_04_T06 = async_test('A_05_01_04_T06');
A_05_01_04_T06.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -175,10 +176,10 @@ A_05_01_04_T06.step(unit(function (ctx) {
//For #player-shadow-host relative target is #player-shadow-host
roots.playerShadowRoot.addEventListener('click',
- A_05_01_04_T06.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
- 'Wrong related target');
+ A_05_01_04_T06.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-shadow-host',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -195,8 +196,8 @@ A_05_01_04_T06.step(unit(function (ctx) {
var A_05_01_04_T07 = async_test('A_05_01_04_T07');
A_05_01_04_T07.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -204,10 +205,10 @@ A_05_01_04_T07.step(unit(function (ctx) {
//For #player relative target is #player-shadow-host
d.querySelector('#player').addEventListener('click',
- A_05_01_04_T07.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
- 'Wrong related target');
+ A_05_01_04_T07.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -223,8 +224,8 @@ A_05_01_04_T07.step(unit(function (ctx) {
var A_05_01_04_T08 = async_test('A_05_01_04_T08');
A_05_01_04_T08.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -232,10 +233,10 @@ A_05_01_04_T08.step(unit(function (ctx) {
//For #volume-slider relative target is #volume-slider
roots.playerShadowRoot.querySelector('#volume-slider').addEventListener('click',
- A_05_01_04_T08.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider',
- 'Wrong related target');
+ A_05_01_04_T08.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -251,8 +252,8 @@ A_05_01_04_T08.step(unit(function (ctx) {
var A_05_01_04_T09 = async_test('A_05_01_04_T09');
A_05_01_04_T09.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -260,10 +261,10 @@ A_05_01_04_T09.step(unit(function (ctx) {
//For #volume-slider-container relative target is #volume-slider
roots.playerShadowRoot.querySelector('#volume-slider-container').addEventListener('click',
- A_05_01_04_T09.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider',
- 'Wrong related target');
+ A_05_01_04_T09.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -279,8 +280,8 @@ A_05_01_04_T09.step(unit(function (ctx) {
var A_05_01_04_T10 = async_test('A_05_01_04_T10');
A_05_01_04_T10.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -288,10 +289,10 @@ A_05_01_04_T10.step(unit(function (ctx) {
//For #controls relative target is #volume-slider
roots.playerShadowRoot.querySelector('#controls').addEventListener('click',
- A_05_01_04_T10.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider',
- 'Wrong related target');
+ A_05_01_04_T10.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -307,8 +308,8 @@ A_05_01_04_T10.step(unit(function (ctx) {
var A_05_01_04_T11 = async_test('A_05_01_04_T11');
A_05_01_04_T11.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -316,10 +317,10 @@ A_05_01_04_T11.step(unit(function (ctx) {
//For #player-shadow-root relative target is #volume-slider
roots.playerShadowRoot.addEventListener('click',
- A_05_01_04_T11.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider',
- 'Wrong related target');
+ A_05_01_04_T11.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
@@ -336,8 +337,8 @@ A_05_01_04_T11.step(unit(function (ctx) {
var A_05_01_04_T12 = async_test('A_05_01_04_T12');
A_05_01_04_T12.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var invoked = false;
+ var d = newRenderedHTMLDocument(ctx);
+ var invoked = false;
roots = createTestMediaPlayer(d);
//expected result of what relative target should be see
@@ -345,10 +346,10 @@ A_05_01_04_T12.step(unit(function (ctx) {
//For #player relative target is #player-shadow-host
d.querySelector('#player').addEventListener('click',
- A_05_01_04_T12.step_func(function (event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
- 'Wrong related target');
+ A_05_01_04_T12.step_func(function (event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'player-shadow-host',
+ 'Wrong related target');
}), false);
var event = d.createEvent('HTMLEvents');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-001.html
index 45b358e7763..cb7efec60f1 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-002.html
index a1c2106ffd5..cea27ce7dca 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-002.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-003.html
index 7f420ae46d2..edf525c5349 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-004.html
index b12de533d66..7f552b28efb 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-004.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-004.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-005.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-005.html
index 4f3bfe1af22..883165f0bcf 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-005.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-005.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-006.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-006.html
index e00c122b4ff..f51f2c4e4e0 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-006.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-006.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-007.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-007.html
index ad630d80997..49d3577a4e0 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-007.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-007.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-008.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-008.html
index 375dab6d2e1..430d8916fc1 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-008.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-008.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-009.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-009.html
index 86a17578a0f..2d5bebbeb54 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-009.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/events-created-by-users-do-not-stop/test-009.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="The following events must not be stopped at the nearest shadow boundary if created by users: abort, error, select, change, load, reset, resize, scroll, selectstart">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-001.html
index 254c34e358e..506315fd92e 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Retargeting focus events:The focus, DOMFocusIn, blur, and DOMFocusOut events must be treated in the same way as events with a relatedTarget, where the corresponding node that is losing focus as a result of target gaining focus or the node that is gaining focus, and thus causing the blurring of target acts as the related target">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -50,11 +51,11 @@ A_05_03_01_T01.step(unit(function (ctx) {
d.body.appendChild(inp2);
s.addEventListener('DOMFocusOut', A_05_03_01_T01.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadow tree: Wrong target');
+ assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadow tree: Wrong target');
}), false);
d.body.addEventListener('DOMFocusOut', A_05_03_01_T01.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'host', 'Inside shadow tree: Wrong target');
+ assert_equals(event.target.getAttribute('id'), 'host', 'Inside shadow tree: Wrong target');
}), false);
inp1.focus();
@@ -92,11 +93,11 @@ A_05_03_01_T02.step(unit(function (ctx) {
inp2.focus();
s.addEventListener('DOMFocusIn', A_05_03_01_T02.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadoe tree: Wrong target');
+ assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadoe tree: Wrong target');
}), false);
d.body.addEventListener('DOMFocusIn', A_05_03_01_T02.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'host', 'Outside shadow tree: Wrong target');
+ assert_equals(event.target.getAttribute('id'), 'host', 'Outside shadow tree: Wrong target');
}), false);
inp1.focus();
@@ -135,7 +136,7 @@ A_05_03_01_T03.step(unit(function (ctx) {
inp1.focus();
d.body.addEventListener('DOMFocusIn', A_05_03_01_T03.step_func(function(event) {
- assert_true(false, 'Event should be stopped at Shadow boundary');
+ assert_true(false, 'Event should be stopped at Shadow boundary');
}), false);
inp2.focus();
@@ -152,35 +153,35 @@ var A_05_03_01_T04 = async_test('A_05_03_01_T04');
A_05_03_01_T04.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- host.setAttribute('style', 'height:50%; width:100%');
- host.setAttribute('id', 'host');
- d.body.appendChild(host);
+ var host = d.createElement('div');
+ host.setAttribute('style', 'height:50%; width:100%');
+ host.setAttribute('id', 'host');
+ d.body.appendChild(host);
- //Shadow root to play with
- var s = host.createShadowRoot();
+ //Shadow root to play with
+ var s = host.createShadowRoot();
- var inp1 = d.createElement('input');
- inp1.setAttribute('id', 'inp1');
- inp1.setAttribute('type', 'checkbox');
- s.appendChild(inp1);
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('id', 'inp1');
+ inp1.setAttribute('type', 'checkbox');
+ s.appendChild(inp1);
- var inp2 = d.createElement('input');
- inp2.setAttribute('id', 'inp2');
- inp2.setAttribute('type', 'checkbox');
- s.appendChild(inp2);
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('id', 'inp2');
+ inp2.setAttribute('type', 'checkbox');
+ s.appendChild(inp2);
- inp1.focus();
+ inp1.focus();
- d.body.addEventListener('DOMFocusOut', A_05_03_01_T04.step_func(function(event) {
- assert_true(false, 'Event should be stopped at Shadow boundary');
- }), false);
+ d.body.addEventListener('DOMFocusOut', A_05_03_01_T04.step_func(function(event) {
+ assert_true(false, 'Event should be stopped at Shadow boundary');
+ }), false);
- inp2.focus();
+ inp2.focus();
- A_05_03_01_T04.done();
+ A_05_03_01_T04.done();
}));
@@ -192,63 +193,63 @@ var A_05_03_01_T05 = async_test('A_05_03_01_T05');
A_05_03_01_T05.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- host.setAttribute('id', 'host');
- d.body.appendChild(host);
+ var host = d.createElement('div');
+ host.setAttribute('id', 'host');
+ d.body.appendChild(host);
- var inp1 = d.createElement('input');
- inp1.setAttribute('id', 'inp1');
- inp1.setAttribute('type', 'checkbox');
- inp1.setAttribute('class', 'clazz1');
- host.appendChild(inp1);
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('id', 'inp1');
+ inp1.setAttribute('type', 'checkbox');
+ inp1.setAttribute('class', 'clazz1');
+ host.appendChild(inp1);
- var inp2 = d.createElement('input');
- inp2.setAttribute('id', 'inp2');
- inp2.setAttribute('type', 'checkbox');
- inp2.setAttribute('class', 'clazz2');
- host.appendChild(inp2);
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('id', 'inp2');
+ inp2.setAttribute('type', 'checkbox');
+ inp2.setAttribute('class', 'clazz2');
+ host.appendChild(inp2);
- var inp3 = d.createElement('input');
- inp3.setAttribute('id', 'inp3');
- inp3.setAttribute('type', 'checkbox');
- inp3.setAttribute('class', 'clazz1');
- host.appendChild(inp3);
+ var inp3 = d.createElement('input');
+ inp3.setAttribute('id', 'inp3');
+ inp3.setAttribute('type', 'checkbox');
+ inp3.setAttribute('class', 'clazz1');
+ host.appendChild(inp3);
- //Shadow root to play with
- var s = host.createShadowRoot();
+ //Shadow root to play with
+ var s = host.createShadowRoot();
- var shadowDiv = document.createElement('div');
- shadowDiv.innerHTML = '<content select=".clazz1"></content>';
- s.appendChild(shadowDiv);
+ var shadowDiv = document.createElement('div');
+ shadowDiv.innerHTML = '<content select=".clazz1"></content>';
+ s.appendChild(shadowDiv);
- //element outside the shadow tree
- var inp4 = d.createElement('input');
- inp4.setAttribute('id', 'inp4');
- inp4.setAttribute('type', 'checkbox');
- inp4.setAttribute('class', 'clazz1');
- d.body.appendChild(inp4);
+ //element outside the shadow tree
+ var inp4 = d.createElement('input');
+ inp4.setAttribute('id', 'inp4');
+ inp4.setAttribute('type', 'checkbox');
+ inp4.setAttribute('class', 'clazz1');
+ d.body.appendChild(inp4);
- inp1.focus();
+ inp1.focus();
- s.addEventListener('DOMFocusOut', A_05_03_01_T05.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadow tree: ' +
- 'Event for nodes, distributed ' +
- 'agains insertion points shouldn\'t be retargeted');
- }), false);
+ s.addEventListener('DOMFocusOut', A_05_03_01_T05.step_func(function(event) {
+ assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadow tree: ' +
+ 'Event for nodes, distributed ' +
+ 'agains insertion points shouldn\'t be retargeted');
+ }), false);
- d.body.addEventListener('DOMFocusOut', A_05_03_01_T05.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'inp1', 'Outside shadow tree: ' +
- 'Event for nodes, distributed ' +
- 'agains insertion points shouldn\'t be retargeted');
- }), false);
+ d.body.addEventListener('DOMFocusOut', A_05_03_01_T05.step_func(function(event) {
+ assert_equals(event.target.getAttribute('id'), 'inp1', 'Outside shadow tree: ' +
+ 'Event for nodes, distributed ' +
+ 'agains insertion points shouldn\'t be retargeted');
+ }), false);
- inp4.focus();
+ inp4.focus();
- A_05_03_01_T05.done();
+ A_05_03_01_T05.done();
}));
@@ -258,63 +259,63 @@ var A_05_03_01_T06 = async_test('A_05_03_01_T06');
A_05_03_01_T06.step(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- host.setAttribute('id', 'host');
- d.body.appendChild(host);
+ var host = d.createElement('div');
+ host.setAttribute('id', 'host');
+ d.body.appendChild(host);
- var inp1 = d.createElement('input');
- inp1.setAttribute('id', 'inp1');
- inp1.setAttribute('type', 'checkbox');
- inp1.setAttribute('class', 'clazz1');
- host.appendChild(inp1);
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('id', 'inp1');
+ inp1.setAttribute('type', 'checkbox');
+ inp1.setAttribute('class', 'clazz1');
+ host.appendChild(inp1);
- var inp2 = d.createElement('input');
- inp2.setAttribute('id', 'inp2');
- inp2.setAttribute('type', 'checkbox');
- inp2.setAttribute('class', 'clazz2');
- host.appendChild(inp2);
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('id', 'inp2');
+ inp2.setAttribute('type', 'checkbox');
+ inp2.setAttribute('class', 'clazz2');
+ host.appendChild(inp2);
- var inp3 = d.createElement('input');
- inp3.setAttribute('id', 'inp3');
- inp3.setAttribute('type', 'checkbox');
- inp3.setAttribute('class', 'clazz1');
- host.appendChild(inp3);
+ var inp3 = d.createElement('input');
+ inp3.setAttribute('id', 'inp3');
+ inp3.setAttribute('type', 'checkbox');
+ inp3.setAttribute('class', 'clazz1');
+ host.appendChild(inp3);
- //Shadow root to play with
- var s = host.createShadowRoot();
+ //Shadow root to play with
+ var s = host.createShadowRoot();
- var shadowDiv = document.createElement('div');
- shadowDiv.innerHTML = '<content select=".clazz1"></content>';
- s.appendChild(shadowDiv);
+ var shadowDiv = document.createElement('div');
+ shadowDiv.innerHTML = '<content select=".clazz1"></content>';
+ s.appendChild(shadowDiv);
- //element outside the shadow tree
- var inp4 = d.createElement('input');
- inp4.setAttribute('id', 'inp4');
- inp4.setAttribute('type', 'checkbox');
- inp4.setAttribute('class', 'clazz1');
- d.body.appendChild(inp4);
+ //element outside the shadow tree
+ var inp4 = d.createElement('input');
+ inp4.setAttribute('id', 'inp4');
+ inp4.setAttribute('type', 'checkbox');
+ inp4.setAttribute('class', 'clazz1');
+ d.body.appendChild(inp4);
- inp4.focus();
+ inp4.focus();
- s.addEventListener('DOMFocusIn', A_05_03_01_T06.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadow tree: ' +
- 'Event for nodes, distributed ' +
- 'agains insertion points shouldn\'t be retargeted');
- }), false);
+ s.addEventListener('DOMFocusIn', A_05_03_01_T06.step_func(function(event) {
+ assert_equals(event.target.getAttribute('id'), 'inp1', 'Inside shadow tree: ' +
+ 'Event for nodes, distributed ' +
+ 'agains insertion points shouldn\'t be retargeted');
+ }), false);
- d.body.addEventListener('DOMFocusIn', A_05_03_01_T05.step_func(function(event) {
- assert_equals(event.target.getAttribute('id'), 'inp1', 'Outside shadow tree: ' +
- 'Event for nodes, distributed ' +
- 'agains insertion points shouldn\'t be retargeted');
- }), false);
+ d.body.addEventListener('DOMFocusIn', A_05_03_01_T05.step_func(function(event) {
+ assert_equals(event.target.getAttribute('id'), 'inp1', 'Outside shadow tree: ' +
+ 'Event for nodes, distributed ' +
+ 'agains insertion points shouldn\'t be retargeted');
+ }), false);
- inp1.focus();
+ inp1.focus();
- A_05_03_01_T06.done();
+ A_05_03_01_T06.done();
}));
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-002.html
index 0129e9ce87c..0e22dd6fbd8 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-002.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Retargeting focus events:The blur event must be treated in the same way as events with a relatedTarget, where the node that is gaining focus causing the blurring of target acts as the related target">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -40,11 +41,11 @@ A_05_03_02_T01.step(unit(function (ctx) {
//For #volume-slider relative target is #volume-slider
roots.playerShadowRoot.querySelector('.volume-slider').addEventListener('blur',
- A_05_03_02_T01.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider',
- 'Wrong target');
- }), false);
+ A_05_03_02_T01.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider',
+ 'Wrong target');
+ }), false);
// move focus out of shadow tree. blur should be fired
d.querySelector('#outside-control').focus();
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-003.html
index 90191c46755..19e4b9967ce 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-focus-events/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Retargeting focus events:The focus event must be treated in the same way as events with a relatedTarget, where the corresponding node that is losing focus as a result of target gaining focus or the node that is gaining focus">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -40,11 +41,11 @@ A_05_03_03_T01.step(unit(function (ctx) {
//For #volume-slider relative target is #volume-slider
roots.playerShadowRoot.querySelector('.volume-slider').addEventListener('focus',
- A_05_03_03_T01.step_func(function(event) {
- invoked = true;
- assert_equals(event.target.getAttribute('id'), 'volume-slider',
- 'Wrong target');
- }), false);
+ A_05_03_03_T01.step_func(function(event) {
+ invoked = true;
+ assert_equals(event.target.getAttribute('id'), 'volume-slider',
+ 'Wrong target');
+ }), false);
roots.playerShadowRoot.querySelector('.volume-slider').focus();
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-001.html
index 8a31bea609e..a791b4ce046 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Retargeting relatedTarget:Event retargeting is a process of computing relative targets for each ancestor of the node at which the event is dispatched. A relative target is a DOM node that most accurately represents the target of a dispatched event at a given ancestor while maintaining the upper boundary encapsulation.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -46,11 +47,11 @@ A_05_02_01_T01.step(unit(function (ctx) {
s.appendChild(div2);
s.addEventListener('mouseover', A_05_02_01_T01.step_func(function(event) {
- assert_equals(event.relatedTarget.getAttribute('id'), 'div1', 'Wrong relatedTarget');
+ assert_equals(event.relatedTarget.getAttribute('id'), 'div1', 'Wrong relatedTarget');
}), false);
d.body.addEventListener('mouseover', A_05_02_01_T01.step_func(function(event) {
- assert_true(false, 'Event must be stopped at Shadow boundary');
+ assert_true(false, 'Event must be stopped at Shadow boundary');
}), false);
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-002.html
index 2c7c0cdd16b..317537d2f38 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-002.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Retargeting relatedTarget:For a given node, the relatedTarget must be changed to its ancestor (or self) that is in the same shadow tree as the node">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -46,7 +47,7 @@ A_05_02_02_T01.step(unit(function (ctx) {
d.body.appendChild(div2);
d.body.addEventListener('mouseover', A_05_02_02_T01.step_func(function(event) {
- assert_equals(event.relatedTarget.getAttribute('id'), 'host', 'Wrong related target');
+ assert_equals(event.relatedTarget.getAttribute('id'), 'host', 'Wrong related target');
}), false);
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-003.html
index e7539f7a77f..377550239b5 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/retargeting-relatedtarget/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Retargeting relatedTarget:Event listeners must not be invoked on a node for which the target and relatedTarget are the same.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -46,7 +47,7 @@ A_05_02_03_T01.step(unit(function (ctx) {
s.appendChild(div2);
s.addEventListener('mouseover', A_05_02_03_T01.step_func(function(event) {
- assert_true(false, 'Event listeners shouldn\'t be invoked if target and relatedTarget are the same');
+ assert_true(false, 'Event listeners shouldn\'t be invoked if target and relatedTarget are the same');
}), false);
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/test-001.html
index 552cfa6643c..cea9294c289 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/events/test-001.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="Events:The mutation event types must never be dispatched in a shadow DOM subtree.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -31,34 +31,34 @@ A_05_00_01_T1.step(function () {
iframe.onload = A_05_00_01_T1.step_func(function () {
try {
- var d = iframe.contentDocument;
+ var d = iframe.contentDocument;
- var div = d.createElement('div');
- d.body.appendChild(div);
+ var div = d.createElement('div');
+ d.body.appendChild(div);
- var s = div.createShadowRoot();
+ var s = div.createShadowRoot();
- var div2 = d.createElement('div');
- s.appendChild(div2);
+ var div2 = d.createElement('div');
+ s.appendChild(div2);
- var inp = d.createElement('input');
- inp.setAttribute('type', 'text');
- inp.setAttribute('id', 'inpid');
- div2.appendChild(inp);
+ var inp = d.createElement('input');
+ inp.setAttribute('type', 'text');
+ inp.setAttribute('id', 'inpid');
+ div2.appendChild(inp);
- div2.addEventListener('DOMAttrModified', A_05_00_01_T1.step_func(function (event) {
+ div2.addEventListener('DOMAttrModified', A_05_00_01_T1.step_func(function (event) {
assert_true(false, 'The mutation event types must never be dispatched in a shadow DOM subtree');
}), false);
- /*
- var attr = inp.getAttributeNode ("value");
+ /*
+ var attr = inp.getAttributeNode ("value");
var event = d.createEvent('MutationEvent');
event.initMutationEvent ("DOMAttrModified", true, true, attr, null, 'new value', "value", MutationEvent.MODIFICATION);
inp.dispatchEvent(event);
- */
- inp.value = 'new value';
- inp.setAttribute ("newAttr" , "firstValue");
- inp.setAttribute ("newAttr" , "secondValue");
- inp.removeAttribute ("newAttr");
+ */
+ inp.value = 'new value';
+ inp.setAttribute ("newAttr" , "firstValue");
+ inp.setAttribute ("newAttr" , "secondValue");
+ inp.removeAttribute ("newAttr");
} finally {
iframe.parentNode.removeChild(iframe);
}
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-001.html
index d8d8669354b..126876367a4 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements and Their Shadow Trees: If the element can have fallback content, UA should allow the shadow tree to contain at least one insertion point.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,15 +25,15 @@ policies and contribution forms [3].
//test iframe
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('iframe');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -46,15 +47,15 @@ test(unit(function (ctx) {
//test object
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('object');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -68,15 +69,15 @@ test(unit(function (ctx) {
//test video
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('video');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -90,15 +91,15 @@ test(unit(function (ctx) {
//test audio
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('audio');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -112,15 +113,15 @@ test(unit(function (ctx) {
//test canvas
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('canvas');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -134,7 +135,7 @@ test(unit(function (ctx) {
//test map
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
var img = d.createElement('img');
img.setAttribute('usemap', '#theMap');
@@ -143,14 +144,14 @@ test(unit(function (ctx) {
d.body.appendChild(img);
- // create element
+ // create element
var el = d.createElement('map');
el.setAttribute('name', 'theMap');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
@@ -165,15 +166,15 @@ test(unit(function (ctx) {
//test textarea
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('textarea');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -187,15 +188,15 @@ test(unit(function (ctx) {
//test progress
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('progress');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -209,15 +210,15 @@ test(unit(function (ctx) {
//test meter
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('meter');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-002.html
index ac32bc5f7c8..8c2c6575ae7 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-002.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements and Their Shadow Trees: Elements that have no fallback content should allow the shadow tree to contain no insertion points or an insertion point that matches nothing">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,9 +25,9 @@ policies and contribution forms [3].
//test img
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('img');
d.body.appendChild(el);
@@ -35,7 +36,7 @@ test(unit(function (ctx) {
s.innerHTML = '<content id="cont" select="#shadow"></content>';
assert_true(s.querySelector('#cont') != null, 'img should allow one insertion point ' +
- 'that matches nothing');
+ 'that matches nothing');
}), 'A_09_00_02_T01');
@@ -43,9 +44,9 @@ test(unit(function (ctx) {
//test embed
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('embed');
d.body.appendChild(el);
@@ -54,7 +55,7 @@ test(unit(function (ctx) {
s.innerHTML = '<content id="cont" select="#shadow"></content>';
assert_true(s.querySelector('#cont') != null, 'embed should allow one insertion point ' +
- 'that matches nothing');
+ 'that matches nothing');
}), 'A_09_00_02_T02');
@@ -62,9 +63,9 @@ test(unit(function (ctx) {
//test embed
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('input');
d.body.appendChild(el);
@@ -73,7 +74,7 @@ test(unit(function (ctx) {
s.innerHTML = '<content id="cont" select="#shadow"></content>';
assert_true(s.querySelector('#cont') != null, 'input should allow one insertion point ' +
- 'that matches nothing');
+ 'that matches nothing');
}), 'A_09_00_02_T03');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-003.html
index e44c45d1a98..fc52026f776 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements and Their Shadow Trees: Check that fieldset can contain at least two insertion points with matching criteria 'legend:first-of-type' and 'universal selector'">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,15 +25,15 @@ policies and contribution forms [3].
//test universal selector
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('fieldset');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
@@ -47,23 +48,23 @@ test(unit(function (ctx) {
//test legend:first-of-type
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('fieldset');
d.body.appendChild(el);
el.innerHTML = '' +
- '<legend>'
- '<span id="shadow">This is a node that should be distributed</span>' +
- '</legend>' +
- '<span id="flbk">Unlucky content</span>';
+ '<legend>'
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '</legend>' +
+ '<span id="flbk">Unlucky content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="legend:first-of-type"></content>';
assert_true(d.querySelector('#shadow').offsetTop > 0, 'fieldset should allow insertion point ' +
- 'with legend:first-of-type matching criteria');
+ 'with legend:first-of-type matching criteria');
assert_equals(d.querySelector('#flbk').offsetTop, 0, 'Fallback content shouldn\'t be rendered');
}), 'A_09_00_03_T02');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-004.html
index 3610c457440..8ac5371c532 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-004.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-and-their-shadow-trees/test-004.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements and Their Shadow Trees: Check that details can contain at least two insertion points with matching criteria 'summary:first-of-type' and 'universal selector'">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,16 +25,16 @@ policies and contribution forms [3].
//test universal selector
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- // create element
+ // create element
var el = d.createElement('details');
el.setAttribute('open', 'open');
d.body.appendChild(el);
el.innerHTML = '' +
- '<span id="shadow">This is a node that should be distributed</span>' +
- '<span id="flbk">This is a fallback content</span>';
+ '<span id="shadow">This is a node that should be distributed</span>' +
+ '<span id="flbk">This is a fallback content</span>';
var s = el.createShadowRoot();
s.innerHTML = '<content select="#shadow"></content>';
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-001.html
index 4b1015d99c3..99a4edc2963 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-001.html
@@ -16,14 +16,14 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements in shadow trees: Form elements and form-associated elements in shadow tree are not accessible using document DOM object's tree accessors">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
<script>
//test form-associated elements
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var form = d.createElement('form');
form.setAttribute('id', 'form_id');
@@ -42,14 +42,14 @@ test(function () {
s.appendChild(el);
assert_equals(d.querySelector('#' + tagName + '_id'), null, 'Form-associated element ' + tagName +
- ' in shadow tree must not be accessible using owner\'s document tree accessors');
+ ' in shadow tree must not be accessible using owner\'s document tree accessors');
});
}, 'A_08_02_01_T01');
//test form elements
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var form = d.createElement('form');
d.body.appendChild(form);
@@ -65,7 +65,7 @@ test(function () {
s.appendChild(el);
assert_equals(d.querySelector('#' + tagName + '_id'), null, 'Form element ' + tagName +
- ' in shadow tree must not be accessible using owner\'s document tree accessors');
+ ' in shadow tree must not be accessible using owner\'s document tree accessors');
});
}, 'A_08_02_01_T02');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-002.html
index 0c3984a2eac..e39ef062659 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-002.html
@@ -16,14 +16,14 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements in shadow trees: Form elements and form-associated elements in shadow tree must be accessible using shadow tree accessors">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
<script>
//test form-associated elements
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var form = d.createElement('form');
form.setAttribute('id', 'form_id');
@@ -42,16 +42,16 @@ test(function () {
s.appendChild(el);
assert_true(s.querySelector('#' + tagName + '_id') != null, 'Form-associated element ' + tagName +
- ' in shadow tree must be accessible shadow tree accessors');
+ ' in shadow tree must be accessible shadow tree accessors');
assert_equals(s.querySelector('#' + tagName + '_id').getAttribute('id'), tagName + '_id',
- 'Form-associated element ' + tagName + ' in shadow tree must be accessible shadow tree accessors');
+ 'Form-associated element ' + tagName + ' in shadow tree must be accessible shadow tree accessors');
});
}, 'A_08_02_02_T01');
//test form elements
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
var form = d.createElement('form');
d.body.appendChild(form);
@@ -67,16 +67,16 @@ test(function () {
s.appendChild(el);
assert_true(s.querySelector('#' + tagName + '_id') != null, 'Form-associated element ' + tagName +
- ' in shadow tree must be accessible shadow tree accessors');
+ ' in shadow tree must be accessible shadow tree accessors');
assert_equals(s.querySelector('#' + tagName + '_id').getAttribute('id'), tagName + '_id',
- 'Form element ' + tagName + ' in shadow tree must be accessible shadow tree accessors');
+ 'Form element ' + tagName + ' in shadow tree must be accessible shadow tree accessors');
});
}, 'A_08_02_02_T02');
//test distributed form elements
test(function () {
- var d = newHTMLDocument();
+ var d = newHTMLDocument();
HTML5_FORM_ASSOCIATED_ELEMENTS.forEach(function (tagName) {
@@ -91,10 +91,10 @@ test(function () {
div.appendChild(el);
var s = div.createShadowRoot();
- s.innerHTML = '<content select="' + tagName + '"></content>';
+ s.innerHTML = '<content select="' + tagName + '"></content>';
assert_true(s.querySelector('#' + tagName + '_id') == null, 'Distributed form-associated element ' + tagName +
- ' in shadow tree must not be accessible shadow tree accessors');
+ ' in shadow tree must not be accessible shadow tree accessors');
});
}, 'A_08_02_02_T03');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html
index 6b9c83ed8f5..c6dfbc4f08e 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/html-forms/test-003.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements in shadow trees: form should submit elements in shadow tree">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,24 +24,24 @@ policies and contribution forms [3].
var A_08_02_03_T01 = async_test('A_08_02_03_T01', { timeout: 5000 });
A_08_02_03_T01.checkIframeContent = A_08_02_03_T01.step_func(function () {
- //remember value to check before cleaning the context (it'll destroy the iframe)
- var valueToCheck = A_08_02_03_T01.iframe.contentWindow.document.URL;
- cleanContext(A_08_02_03_T01.ctx);
+ //remember value to check before cleaning the context (it'll destroy the iframe)
+ var valueToCheck = A_08_02_03_T01.iframe.contentWindow.document.URL;
+ cleanContext(A_08_02_03_T01.ctx);
- assert_true(valueToCheck.indexOf('inp1=value1') > 0,
- 'html form should submit all of its fields');
+ assert_true(valueToCheck.indexOf('inp1=value1') > 0,
+ 'html form should submit all of its fields');
- // Expected behavior is not quite clear. See https://www.w3.org/Bugs/Public/show_bug.cgi?id=20320
- assert_true(valueToCheck.indexOf('inp2=value2') > 0,
- 'html form should submit all of its fields including the shadow ones');
+ // Expected behavior is not quite clear. See https://www.w3.org/Bugs/Public/show_bug.cgi?id=20320
+ assert_true(valueToCheck.indexOf('inp2=value2') > 0,
+ 'html form should submit all of its fields including the shadow ones');
- A_08_02_03_T01.done();
+ A_08_02_03_T01.done();
});
A_08_02_03_T01.step(function () {
- A_08_02_03_T01.ctx = newContext();
+ A_08_02_03_T01.ctx = newContext();
var d = newRenderedHTMLDocument(A_08_02_03_T01.ctx);
//create iframe
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-001.html
index 52c689c1bd8..c0c6048f729 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-001.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements in shadow trees: base element must behave as inert, or not part of the document tree">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -24,20 +24,20 @@ policies and contribution forms [3].
var A_08_01_01_T01 = async_test('A_08_01_01_T01', { timeout: 5000 });
A_08_01_01_T01.checkIframeContent = A_08_01_01_T01.step_func(function () {
- //remember value to check before cleaning the context (it'll destroy the iframe)
- var valueToCheck = A_08_01_01_T01.iframe.contentWindow;
- cleanContext(A_08_01_01_T01.ctx);
+ //remember value to check before cleaning the context (it'll destroy the iframe)
+ var valueToCheck = A_08_01_01_T01.iframe.contentWindow;
+ cleanContext(A_08_01_01_T01.ctx);
- assert_equals(valueToCheck, null,
- 'base html element ih a shadow tree must beahve like inert one');
+ assert_equals(valueToCheck, null,
+ 'base html element ih a shadow tree must beahve like inert one');
- A_08_01_01_T01.done();
+ A_08_01_01_T01.done();
});
A_08_01_01_T01.step(function () {
- A_08_01_01_T01.ctx = newContext();
+ A_08_01_01_T01.ctx = newContext();
var d = newRenderedHTMLDocument(A_08_01_01_T01.ctx);
//create iframe
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-002.html
index b7c6399f5e0..918588b6746 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/html-elements-in-shadow-trees/inert-html-elements/test-002.html
@@ -16,26 +16,27 @@ policies and contribution forms [3].
<meta name="assert" content="HTML Elements in shadow trees: link element must behave as inert not as part of the document tree">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var link = d.createElement('link');
- link.setAttribute('rel', 'stylesheet');
+ var link = d.createElement('link');
+ link.setAttribute('rel', 'stylesheet');
- //create Shadow root
- var root = d.createElement('div');
- d.body.appendChild(root);
- var s = root.createShadowRoot();
+ //create Shadow root
+ var root = d.createElement('div');
+ d.body.appendChild(root);
+ var s = root.createShadowRoot();
- s.appendChild(link);
+ s.appendChild(link);
- assert_equals(d.styleSheets.length, 0, 'link element must behave as inert not as part of the document tree');
+ assert_equals(d.styleSheets.length, 0, 'link element must behave as inert not as part of the document tree');
}), 'A_08_01_02_T01');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/resources/bobs_page.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/resources/bobs_page.html
index c5b04eb1fb7..92dfb0d3c8c 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/resources/bobs_page.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/resources/bobs_page.html
@@ -2,34 +2,34 @@
<head>
</head>
<body>
- <ul class='stories'>
- <li id='li1'><a href='#1'>Link1</a></li>
- <li id='li2' title="li2"><a href='#2'>Link 2</a></li>
- <li id='li3' class='shadow'><a href='#3'>Link 3 Shadow</a></li>
- <li id='li4' class='shadow2'><a href='#4'>Link 4 Shadow 2</a></li>
- <li id='li5'><a id="a5" class="shadow" href='#5'>Link 5</a></li>
- <li id='li6' class='shadow'><a href='#5'>Link 6 Shadow</a></li>
- </ul>
- <div id="divid" class='breaking'>
- <span id='spandex'>Some text</span>
- <ul id="ul2">
- <li id='li11'>Item 11</li>
- <li id='li12'>Item 12</li>
- <li id='li13' class='shadow'>Item 13 Shadow</li>
- <li id='li14' class='shadow2'>Item 14 Shadow 2</li>
- <li id='li15'>Item 15</li>
- <li id='li16' class='shadow'>Item 16 Shadow</li>
- </ul>
- </div>
- <div id="links-wrapper">
- <a href='#10' id='link10'>Link 10</a>
- <a href='#11' id='link11'>Link 11</a>
- </div>
- <div id="inputs-wrapper">
- <input type='text' id='inp1' disabled/>
- <input type='text' id='inp2'/>
- <input type='checkbox' id='chb1' checked>
- <input type='checkbox' id='chb2'>
- </div>
+ <ul class='stories'>
+ <li id='li1'><a href='#1'>Link1</a></li>
+ <li id='li2' title="li2"><a href='#2'>Link 2</a></li>
+ <li id='li3' class='shadow'><a href='#3'>Link 3 Shadow</a></li>
+ <li id='li4' class='shadow2'><a href='#4'>Link 4 Shadow 2</a></li>
+ <li id='li5'><a id="a5" class="shadow" href='#5'>Link 5</a></li>
+ <li id='li6' class='shadow'><a href='#5'>Link 6 Shadow</a></li>
+ </ul>
+ <div id="divid" class='breaking'>
+ <span id='spandex'>Some text</span>
+ <ul id="ul2">
+ <li id='li11'>Item 11</li>
+ <li id='li12'>Item 12</li>
+ <li id='li13' class='shadow'>Item 13 Shadow</li>
+ <li id='li14' class='shadow2'>Item 14 Shadow 2</li>
+ <li id='li15'>Item 15</li>
+ <li id='li16' class='shadow'>Item 16 Shadow</li>
+ </ul>
+ </div>
+ <div id="links-wrapper">
+ <a href='#10' id='link10'>Link 10</a>
+ <a href='#11' id='link11'>Link 11</a>
+ </div>
+ <div id="inputs-wrapper">
+ <input type='text' id='inp1' disabled/>
+ <input type='text' id='inp2'/>
+ <input type='checkbox' id='chb1' checked>
+ <input type='checkbox' id='chb2'>
+ </div>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/composition/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/composition/test-001.html
deleted file mode 100644
index 0b26e163624..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/composition/test-001.html
+++ /dev/null
@@ -1,163 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_07_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#multiple-shadow-subtrees">
-<meta name="assert" content="Composition:Composition algorithm">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul id="host">' +
- '<li id="li1" class="shadow">' +
- '<a id="a11" class="cl1" href="#">Link11 Shadow</a>' +
- '<a id="a12" class="cl2" href="#">Link12 Shadow</a>' +
- '<a id="a13" class="cl1" href="#">Link13 Shadow</a>' +
- '</li>' +
- '<li id="li2">' +
- '<a id="a21" href="#">Link21</a><a id="a22" href="#">Link22</a>' +
- '</li>' +
- '<li id="li3" class="shadow">' +
- '<a id="a31" href="#">Link31 Shadow</a><a id="a32" href="#">Link32 Shadow</a>' +
- '</li>' +
- '<li id="li4" class="shadow2">' +
- '<a id="a41" href="#">Link41 Shadow 2</a><a id="a42" href="#">Link22 Shadow 2</a>' +
- '</li>' +
- '<li id="li5" class="shadow2">' +
- '<a id="a51" href="#">Link51 Shadow</a><a id="a52" href="#">Link52 Shadow 2</a>' +
- '</li>' +
- '</ul>';
-
- d.body.appendChild(div);
-
- //make nested shadow tree to check the reprojection
- var li1 = d.querySelector('#li1');
- var s = li1.createShadowRoot();
- var shadowLI1 = document.createElement('li');
- shadowLI1.innerHTML = '<content select=".cl1"></content>';
- s.appendChild(shadowLI1);
-
- //Shadow root to play with
- var ul = d.querySelector('#host');
-
- //make an old shadow tree
- var s2 = ul.createShadowRoot();
- var div2 = d.createElement('div');
- div2.innerHTML = '<ul><content select=".shadow2"></content></ul>';
- s2.appendChild(div2);
-
- // At this point visible: li4 and li5
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 1: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 2: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li1').offsetTop, 0, 'Point 3: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 4: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li3').offsetTop, 0, 'Point 5: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the nested tree
- assert_equals(d.querySelector('#a11').offsetTop, 0,
- 'Point 6: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a13').offsetTop, 0,
- 'Point 7: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 8: Aleady distributed nodes should behave like a shadow host child nodes');
-
-
-
- //make a young shadow tree
- var s3 = ul.createShadowRoot();
- var div3 = d.createElement('div');
- div3.innerHTML = '<ul><content select=".shadow"></content></ul>';
- s3.appendChild(div3);
-
- //At this point: li1 and li3 visible, others not
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 21: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 22: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 23: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 24: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0, 'Point 25: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (a11 and a13 visible, a12 not)
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 26: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 27: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 28: Aleady distributed nodes should behave like a shadow host child nodes');
-
- var shadow = d.createElement('shadow');
- s3.appendChild(shadow);
-
- //At this point: li1, li3, li4 and li5 visible li2 not
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 31: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 32: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 33: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 34: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 35: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (a11 and a13 visible, a12 not)
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 36: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 37: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 38: Aleady distributed nodes should behave like a shadow host child nodes');
-
- var shadow2 = d.createElement('shadow');
- s3.appendChild(shadow2);
-
- // Nothing should be changed
- //At this point: li1, li3, li4 and li5 visible li2 not
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 41: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 42: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 43: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 44: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 45: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (a11 and a13 visible, a12 not)
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 46: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 47: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 48: Aleady distributed nodes should behave like a shadow host child nodes');
-}), 'A_04_07_01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-001.html
deleted file mode 100644
index 839e5dfdab5..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-001.html
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_04_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Tetsuharu OHZEKI" href="mailto:saneyuki.snyk@gmail.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#distributed-pseudo-element">
-<meta name="assert" content="Matching Children, Distributed To Insertion Points">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_04_01_T1 = async_test('A_04_04_01_T01');
-
-A_04_04_01_T1.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_04_01_T1.step_func(function () {
- try {
- var d = iframe.contentDocument;
-
- //make shadow tree
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
- var subdiv1 = d.createElement('div');
- subdiv1.innerHTML = '<ul><content select="li"></content></ul>';
- s.appendChild(subdiv1);
-
- var shadowStyle = d.createElement('style');
- shadowStyle.innerHTML = '*::content .shadow { display:none; }';
- s.appendChild(shadowStyle);
-
- //The order of DOM elements should be the following:
- //li3, li6 - invisible. Other elements visible
- var li3 = d.querySelector('#li3');
- var li6 = d.querySelector('#li6');
- assert_equals(window.getComputedStyle(li3).display, "none",
- 'Point 1: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(window.getComputedStyle(li6).display, "none",
- 'Point 2: Elements that don\'t mach insertion point criteria participate in distribution');
-
- var li1 = d.querySelector('#li1');
- var li2 = d.querySelector('#li2');
- var li4 = d.querySelector('#li4');
- var li5 = d.querySelector('#li5');
- assert_not_equals(window.getComputedStyle(li1).display, "none",
- 'Point 3: ::content pseudo-element should be a valid insertion point matching criteria, element should be visible');
- assert_not_equals(window.getComputedStyle(li2).display, "none",
- 'Point 4: ::content pseudo-element should be a valid insertion point matching criteria, element should be visible');
- assert_not_equals(window.getComputedStyle(li4).display, "none",
- 'Point 5: ::content pseudo-element should be a valid insertion point matching criteria, element should be visible');
- assert_not_equals(window.getComputedStyle(li5).display, "none",
- 'Point 6: ::content pseudo-element should be a valid insertion point matching criteria, element should be visible');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_04_01_T1.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-002.html
deleted file mode 100644
index 4e656257d05..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/content-pseudo-element/test-002.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_04_01</title>
-<link rel="author" title="Tetsuharu OHZEKI" href="mailto:saneyuki.snyk@gmail.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#distributed-pseudo-element">
-<meta name="assert" content="::content pseudo-element, Relative Selector">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_04_01_T2 = async_test('A_04_04_01_T02');
-
-A_04_04_01_T2.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_04_01_T2.step_func(function () {
- try {
- var d = iframe.contentDocument;
-
- //make shadow tree
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
- var subdiv1 = d.createElement('div');
- subdiv1.innerHTML = '<ul><content select="li"></content></ul>';
- s.appendChild(subdiv1);
-
- var shadowStyle = d.createElement('style');
- shadowStyle.innerHTML = '*::content > .shadow { display:none; }';
- s.appendChild(shadowStyle);
-
- //The order of DOM elements should be the following:
- //li3, li6 - invisible. Other elements visible
- var li3 = d.querySelector('#li3');
- var li6 = d.querySelector('#li6');
- assert_equals(window.getComputedStyle(li3).display, "none",
- 'Point 1: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(window.getComputedStyle(li6).display, "none",
- 'Point 2: Elements that don\'t mach insertion point criteria participate in distribution');
-
- var a5 = d.querySelector('#a5');
- assert_not_equals(window.getComputedStyle(a5).display, "none",
- 'Point 3: ::content pseudo-element with relative selector should be a valid insertion point matching criteria, element should be visible');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_04_01_T2.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/custom-pseudo-elements/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/custom-pseudo-elements/test-001.html
deleted file mode 100644
index e963ba4bc8a..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/custom-pseudo-elements/test-001.html
+++ /dev/null
@@ -1,63 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_10_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#custom-pseudo-elements">
-<meta name="assert" content="Custom Pseudo-Elements: test valid pseudo-element">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-// Test fails. See https://bugs.webkit.org/show_bug.cgi?id=103973
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- var style = d.createElement('style');
- style.innerHTML = 'span {' +
- 'font-size: 10px;' +
- '}';
- d.head.appendChild(style);
-
- var widget = d.createElement('div');
- d.body.appendChild(widget);
-
- var s = widget.createShadowRoot();
-
- var thumb = d.createElement('span');
- thumb.innerHTML = 'This is a pseudo-element';
- //FIXME test works if prefixed version of API used.
- //In other words works if webkitPseudo property is used
- //thumb.webkitPseudo = 'x-thumb';
- thumb.pseudo = 'x-thumb';
- s.appendChild(thumb);
-
- var height = thumb.offsetHeight;
-
- assert_true(height > 0, 'Element should be rendered');
-
- style = d.createElement('style');
- style.innerHTML = 'div::x-thumb {' +
- 'font-size: 30px;' +
- '}';
- d.body.appendChild(style);
-
- assert_true(thumb.offsetHeight > height, 'Pseudo-element style should be applied');
-
-}), 'A_04_10_01_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001-ref.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001-ref.html
deleted file mode 100644
index e19d98845c3..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001-ref.html
+++ /dev/null
@@ -1,35 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: Distribution: Unordered list (Reference)</title>
-<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
-</head>
-<body>
-<p>
-You should see an unordered list below, consisting of ten elements
-each of which contains a capital letter ranging from "A" to "J",
-in alphabetical order.
-</p>
-<ul>
-<li>A</li>
-<li>B</li>
-<li>C</li>
-<li>D</li>
-<li>E</li>
-<li>F</li>
-<li>G</li>
-<li>H</li>
-<li>I</li>
-<li>J</li>
-</ul>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html
deleted file mode 100644
index 891b4248946..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-001.html
+++ /dev/null
@@ -1,47 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: Distribution: Unordered list</title>
-<link rel="match" href="distribution-001-ref.html">
-<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-trees">
-<meta name="assert" content="Lower-boundary Encapsulation: Each insertion point participates in distribution by providing a matching criteria for the child nodes. The matching criteria determines whether a given node could be distributed to a given insertion point.">
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<p>
-You should see an unordered list below, consisting of ten elements
-each of which contains a capital letter ranging from "A" to "J",
-in alphabetical order.
-</p>
-<ul id="list">
-<li>H</li>
-<li class="first">B</li>
-<li class="second">E</li>
-<li>I</li>
-<li class="first">C</li>
-</ul>
-<script>
-var shadowRoot = document.getElementById('list').createShadowRoot();
-shadowRoot.innerHTML =
- '<li>A</li>' +
- '<content select=".first"></content>' +
- '<li>D</li>' +
- '<content select=".second"></content>' +
- '<li>F</li>' +
- '<content select="img"></content>' +
- '<li>G</li>' +
- '<content></content>' +
- '<li>J</li>';
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002-ref.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002-ref.html
deleted file mode 100644
index 5114b64b4ea..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002-ref.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: Distribution: Ordered list (Reference)</title>
-<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
-<style>
-ol {
- list-style-type: decimal;
-}
-</style>
-</head>
-<body>
-<p>
-You should see an ordered list below, consisting of ten elements numbered
-from 1 through 10, and each line should contain a capital letter ranging from
-"A" to "J", in alphabetical order.
-</p>
-<ol>
-<li>A</li>
-<li>B</li>
-<li>C</li>
-<li>D</li>
-<li>E</li>
-<li>F</li>
-<li>G</li>
-<li>H</li>
-<li>I</li>
-<li>J</li>
-</ol>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html
deleted file mode 100644
index e0d93ad6f34..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-002.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: Distribution: Ordered list</title>
-<link rel="match" href="distribution-002-ref.html">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-trees">
-<meta name="assert" content="Lower-boundary Encapsulation: Each insertion point participates in distribution by providing a matching criteria for the child nodes. The matching criteria determines whether a given node could be distributed to a given insertion point.">
-<script src="../../testcommon.js"></script>
-<style>
-ol {
- list-style-type: decimal;
-}
-</style>
-</head>
-<body>
-<p>
-You should see an ordered list below, consisting of ten elements numbered
-from 1 through 10, and each line should contain a capital letter ranging from
-"A" to "J", in alphabetical order.
-</p>
-<ol id="list">
-<li>H</li>
-<li class="first">B</li>
-<li class="second">E</li>
-<li>I</li>
-<li class="first">C</li>
-</ol>
-<script>
-var shadowRoot = document.getElementById('list').createShadowRoot();
-shadowRoot.innerHTML =
- '<li>A</li>' +
- '<content select=".first"></content>' +
- '<li>D</li>' +
- '<content select=".second"></content>' +
- '<li>F</li>' +
- '<content select="img"></content>' +
- '<li>G</li>' +
- '<content></content>' +
- '<li>J</li>';
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-003.html
deleted file mode 100644
index 957030810e8..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/distribution-003.html
+++ /dev/null
@@ -1,74 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: Invariants after distribution</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#lower-boundary-encapsulation">
-<meta name="assert" content="Lower-boundary encapsulation: The distribution does not affect the state of the document tree or shadow trees">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var distributionTest = async_test(
- 'Distribution should not affect the state of the document trees and ' +
- 'the shadow trees.');
-
-distributionTest.step(function () {
- var shadowHost = document.createElement('ul');
- shadowHost.innerHTML =
- '<li class="first">host 1</li>' +
- '<li class="second">host 2</li>';
- shadowHost.style.visibility = 'hidden';
- document.body.appendChild(shadowHost);
- var host1 = shadowHost.querySelector('.first');
- var host2 = shadowHost.querySelector('.second');
-
- var shadowRoot = shadowHost.createShadowRoot();
- shadowRoot.innerHTML =
- '<li class="first">shadow 1</li>' +
- '<content select=".second"></content>' +
- '<li class="second">shadow 2</li>';
- var shadow1 = shadowRoot.querySelector('.first');
- var shadow2 = shadowRoot.querySelector('.second');
- var content = shadowRoot.querySelector('content');
-
- // Let the rendering happen.
- window.setTimeout(distributionTest.step_func(function () {
- assert_equals(host1.textContent, 'host 1');
- assert_equals(host2.textContent, 'host 2');
- assert_equals(shadow1.textContent, 'shadow 1');
- assert_equals(shadow2.textContent, 'shadow 2');
- assert_equals(content.textContent, '');
-
- assert_equals(shadowHost.children.length, 2);
- assert_equals(shadowHost.children[0], host1);
- assert_equals(shadowHost.children[1], host2);
- assert_equals(shadowRoot.children.length, 3);
- assert_equals(shadowRoot.children[0], shadow1);
- assert_equals(shadowRoot.children[1], content);
- assert_equals(shadowRoot.children[2], shadow2);
-
- assert_equals(host1.tagName, 'LI');
- assert_equals(shadow1.tagName, 'LI');
- assert_equals(content.tagName, 'CONTENT');
-
- document.body.removeChild(shadowHost);
- distributionTest.done();
- }), 0);
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-003.html
deleted file mode 100644
index cb377f39462..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-003.html
+++ /dev/null
@@ -1,130 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_02_03</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#lower-boundary-encapsulation">
-<meta name="assert" content="Lower-boundary encapsulation: The distribution is a result of executing a stable algorithm">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_02_03_T1 = async_test('A_04_02_03_T01');
-
-A_04_02_03_T1.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_02_03_T1.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
-
- //make shadow subtree
- var subdiv1 = document.createElement('div');
- subdiv1.innerHTML = '<ul><content select=".shadow"></content></ul>';
- s.appendChild(subdiv1);
-
- //The order of <li> elements at this point should be the following:
- //li3, li6, li11, li12, 1i13, li14, li15. Other elements (li1, li2, li4, li5) invisible
- assert_true(d.querySelector('#li3').offsetTop < d.querySelector('#li6').offsetTop,
- 'Point 1: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li6').offsetTop < d.querySelector('#li11').offsetTop,
- 'Point 2: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li11').offsetTop < d.querySelector('#li12').offsetTop,
- 'Point 3: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li12').offsetTop < d.querySelector('#li13').offsetTop,
- 'Point 4: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li13').offsetTop < d.querySelector('#li14').offsetTop,
- 'Point 5: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li14').offsetTop < d.querySelector('#li15').offsetTop,
- 'Point 6: Elements that mach insertion point criteria don\'t participate in distribution');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 7: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li2').offsetTop, 0,
- 'Point 8: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li4').offsetTop, 0,
- 'Point 9: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 10: Elements that don\'t mach insertion point criteria participate in distribution');
-
- var subdiv2 = document.createElement('div');
- subdiv2.innerHTML = '<ul><content select=".shadow2"></content></ul>';
- s.appendChild(subdiv2);
-
- // When class name changed distribution must reoccur
- //The order of <li> elements should now be the following:
- //li3, li6, li4, li11, li12, 1i13, li14, li15. Invisible: li1, li2, li5
- assert_true(d.querySelector('#li3').offsetTop < d.querySelector('#li6').offsetTop,
- 'Point 11: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li6').offsetTop < d.querySelector('#li4').offsetTop,
- 'Point 12: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li4').offsetTop < d.querySelector('#li11').offsetTop,
- 'Point 13: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li11').offsetTop < d.querySelector('#li12').offsetTop,
- 'Point 14: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li12').offsetTop < d.querySelector('#li13').offsetTop,
- 'Point 15: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li13').offsetTop < d.querySelector('#li14').offsetTop,
- 'Point 16: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li14').offsetTop < d.querySelector('#li15').offsetTop,
- 'Point 17: Elements that mach insertion point criteria don\'t participate in distribution');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 18: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li2').offsetTop, 0,
- 'Point 19: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 20: Elements that don\'t mach insertion point criteria participate in distribution');
-
- var subdiv3 = document.createElement('div');
- subdiv3.innerHTML = '<ul><content select=".shadow"></content></ul>';
- s.appendChild(subdiv3);
-
- //There should be no change. Order:
- //li3, li6, li4, li11, li12, 1i13, li14, li15. Invisible: li1, li2, li5
- assert_true(d.querySelector('#li3').offsetTop < d.querySelector('#li6').offsetTop,
- 'Point 21: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li6').offsetTop < d.querySelector('#li4').offsetTop,
- 'Point 22: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li4').offsetTop < d.querySelector('#li11').offsetTop,
- 'Point 23: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li11').offsetTop < d.querySelector('#li12').offsetTop,
- 'Point 24: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li12').offsetTop < d.querySelector('#li13').offsetTop,
- 'Point 25: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li13').offsetTop < d.querySelector('#li14').offsetTop,
- 'Point 26: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li14').offsetTop < d.querySelector('#li15').offsetTop,
- 'Point 27: Elements that mach insertion point criteria don\'t participate in distribution');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 28: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li2').offsetTop, 0,
- 'Point 29: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 30: Elements that don\'t mach insertion point criteria participate in distribution');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_02_03_T1.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-004.html
index de1b5404908..13fa063912f 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-004.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-004.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="Lower-boundary encapsulation: The distribution reoccurs whenever any variable affecting it is changed">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-005.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-005.html
deleted file mode 100644
index c3103a0f7c8..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/lower-boundary-encapsulation/test-005.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_02_05</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#lower-boundary-encapsulation">
-<meta name="assert" content="Lower-boundary encapsulation: An insertion point may be active or inactive. An active insertion point participates in the distribution process, whereas the inactive insertion does not">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_02_05_T1 = async_test('A_04_02_05_T01');
-
-A_04_02_05_T1.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_02_05_T1.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var ul = d.querySelector("ul.stories");
- var s = ul.createShadowRoot();
-
- //make shadow subtree
- var subdiv1 = document.createElement('div');
- subdiv1.innerHTML = "<ul><content select='.nobody'><span id='shadowspan'>Inactive insertion point</span></content></ul>";
- s.appendChild(subdiv1);
-
- assert_true(s.querySelector('#shadowspan').offsetTop > 0,
- 'Inactive insertion point should be in a fallback content');
-
- // All li1-li6 should be invisible, shadowspan visible
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 1: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li2').offsetTop, 0,
- 'Point 2: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li3').offsetTop, 0,
- 'Point 3: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li4').offsetTop, 0,
- 'Point 4: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 5: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li6').offsetTop, 0,
- 'Point 6: Elements that don\'t mach insertion point criteria participate in distribution');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_02_05_T1.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest-ref.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest-ref.html
index f4b8bab7602..3050cefe9d9 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest-ref.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest-ref.html
@@ -4,7 +4,7 @@
<meta charset="utf-8" >
<title>Shadow DOM Test Ref file - Tests nested shadow tree.</title>
<link rel="author" title="shingo.miyazawa" href="mailto:kumatronik@gmail.com" >
- <script src="../../testcommon.js"></script>
+ <script src="../../../../html/resources/common.js"></script>
<meta name="assert" content="nested shadow tree style is valid." >
<style>
#host {
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html
index 679b70f0dde..de9100bcb38 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/nested_tree_reftest.html
@@ -6,7 +6,7 @@
<link rel="match" href="nested_tree_reftest-ref.html" >
<link rel="author" title="shingo.miyazawa" href="mailto:kumatronik@gmail.com" >
<link rel="help" href="https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#nested-shadow-trees" >
- <script src="../../testcommon.js"></script>
+ <script src="../../../../html/resources/common.js"></script>
<meta name="assert" content="nested shadow tree style is valid." >
<style>
#host {
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/test-001.html
deleted file mode 100644
index 639143ee5a6..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/nested-shadow-trees/test-001.html
+++ /dev/null
@@ -1,98 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_08_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#nested-shadow-subtrees">
-<meta name="assert" content="Nested Shadow Subtrees:Any element in a shadow tree can be a shadow host, thus producing nested shadow trees">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_08_01_T1 = async_test('A_04_08_01_T01');
-
-A_04_08_01_T1.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_08_01_T1.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var ul = d.querySelector('ul.stories');
-
- //make a shadow subtree
- var s1 = ul.createShadowRoot();
- var subdiv1 = d.createElement('div');
- subdiv1.innerHTML = '<ul><content select=".shadow"></content></ul>' +
- '<div id="host_div">' +
- '<span id="sh_span">This span should be visible</span>' +
- '<ul id="host">' +
- '<li id="sh_li1">Shadow li 1</li>' +
- '<li id="sh_li2">Shadow li 2</li>' +
- '<li id="sh_li3" class="shadow2">Shadow li 3</li>' +
- '<li id="sh_li4">Shadow li 4</li>' +
- '<li id="sh_li5">Shadow li 5</li>' +
- '</ul>' +
- '</div>';
- s1.appendChild(subdiv1);
-
- //make nested shadow subtree
- var sh_ul = s1.querySelector('#host');
- var s2 = sh_ul.createShadowRoot();
- var subdiv2 = d.createElement('div');
- subdiv2.innerHTML = '<ul><content select=".shadow2"></content></ul>';
- s2.appendChild(subdiv2);
-
- //The order of DOM elements should be the following:
- //li4, li3 and sh_li3 visible. Other elements invisible
- assert_true(d.querySelector('#li3').offsetTop > 0,
- 'Point 1: Shadow tree should take part in the distribution');
- assert_true(d.querySelector('#li6').offsetTop > d.querySelector('#li3').offsetTop,
- 'Point 2: Shadow tree should take part in the distribution');
- assert_true(s1.querySelector('#sh_li3').offsetTop > 0,
- 'Nested shadow subtree should take part in the distribution');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 3: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li2').offsetTop, 0,
- 'Point 4: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li4').offsetTop, 0,
- 'Point 5: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 6: Elements that don\'t mach insertion point criteria participate in distribution');
-
- assert_equals(s1.querySelector('#sh_li1').offsetTop, 0,
- 'Point 7: Elements of the nested shadow subtree that don\'t mach insertion point criteria participate in distribution');
- assert_equals(s1.querySelector('#sh_li2').offsetTop, 0,
- 'Point 8: Elements of the nested shadow subtree that don\'t mach insertion point criteria participate in distribution');
- assert_equals(s1.querySelector('#sh_li4').offsetTop, 0,
- 'Point 9: Elements of the nested shadow subtree that don\'t mach insertion point criteria participate in distribution');
- assert_equals(s1.querySelector('#sh_li5').offsetTop, 0,
- 'Point 10: Elements of the nested shadow subtree that don\'t mach insertion point criteria participate in distribution');
-
- assert_true(s1.querySelector('#sh_span').offsetTop > 0,
- 'Shadow subtree elements that are not shadow host should take part in the distribution');
-
-
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_08_01_T1.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/rendering-shadow-trees/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/rendering-shadow-trees/test-001.html
deleted file mode 100644
index 567e71b5771..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/rendering-shadow-trees/test-001.html
+++ /dev/null
@@ -1,255 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_09_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#multiple-shadow-subtrees">
-<meta name="assert" content="Rendering Shadow DOM Subtrees:rendering algorithm">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul id="host">' +
- '<li id="li1" class="shadow">' +
- '<a id="a11" class="cl1" href="#">Link11 Shadow</a>' +
- '<a id="a12" class="cl2" href="#">Link12 Shadow</a>' +
- '<a id="a13" class="cl1" href="#">Link13 Shadow</a>' +
- '<a id="a14" class="cl3" href="#">Link14 Shadow</a>' +
- '</li>' +
- '<li id="li2">' +
- '<a id="a21" href="#">Link21</a><a id="a22" href="#">Link22</a>' +
- '</li>' +
- '<li id="li3" class="shadow">' +
- '<a id="a31" href="#">Link31 Shadow</a><a id="a32" href="#">Link32 Shadow</a>' +
- '</li>' +
- '<li id="li4" class="shadow2">' +
- '<a id="a41" href="#">Link41 Shadow 2</a><a id="a42" href="#">Link22 Shadow 2</a>' +
- '</li>' +
- '<li id="li5" class="shadow2">' +
- '<a id="a51" href="#">Link51 Shadow</a><a id="a52" href="#">Link52 Shadow 2</a>' +
- '</li>' +
- '</ul>';
-
- d.body.appendChild(div);
-
- //make nested shadow tree to check the reprojection
- var li1 = d.querySelector('#li1');
- var s = li1.createShadowRoot();
- var shadowLI1 = document.createElement('li');
- shadowLI1.innerHTML = '<content select=".cl1"></content>';
- s.appendChild(shadowLI1);
-
- //check the tree. a11 and a13 should be visible
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 1: Node that matches insertion point criteria should be rendered');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 2: Node that matches insertion point criteria should be rendered');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 3: Node that doesn\'t match insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#a14').offsetTop, 0,
- 'Point 4: Node that doesn\'t match insertion point criteria shouldn\'t be rendered');
-
-
- var shadowLI2 = document.createElement('li');
- shadowLI2.innerHTML = '<content select=".cl3"></content>';
- s.appendChild(shadowLI2);
-
- //At this point a11, a13 and a14 should be visible
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 11: Node that matches insertion point criteria should be rendered');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 12: Node that matches insertion point criteria should be rendered');
- assert_true(d.querySelector('#a14').offsetTop > d.querySelector('#a13').offsetTop,
- 'Point 13: Node that matches insertion point criteria should be rendered');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 14: Node that doesn\'t match insertion point criteria shouldn\'t be rendered');
-
-
- //Shadow root to play with
- var ul = d.querySelector('#host');
-
- //make an old shadow tree
- var s2 = ul.createShadowRoot();
- var div2 = d.createElement('div');
- div2.innerHTML = '<ul><content select=".shadow"></content></ul>';
- s2.appendChild(div2);
-
- // At this point visible: li1 and li3
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 21: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 22: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 23: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 24: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0, 'Point 25: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 26: Node that matches insertion point criteria should be rendered');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 27: Node that matches insertion point criteria should be rendered');
- assert_true(d.querySelector('#a14').offsetTop > d.querySelector('#a13').offsetTop,
- 'Point 28: Node that matches insertion point criteria should be rendered');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 29: Node that doesn\'t match insertion point criteria shouldn\'t be rendered');
-
-
-
- //make a young shadow tree
- var s3 = ul.createShadowRoot();
- var div3 = d.createElement('div');
- div3.innerHTML = '<ul><content select=".shadow2"></content></ul>';
- s3.appendChild(div3);
-
- //At this point: li4 and li5 visible, others not
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 31: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 32: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li1').offsetTop, 0, 'Point 33: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 34: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li3').offsetTop, 0, 'Point 35: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (all invisible)
- assert_equals(d.querySelector('#a11').offsetTop, 0,
- 'Point 36: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 37: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a13').offsetTop, 0,
- 'Point 38: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a14').offsetTop, 0,
- 'Point 39: Aleady distributed nodes should behave like a shadow host child nodes');
-
- var shadow = d.createElement('shadow');
- s3.appendChild(shadow);
-
- //At this point: li1, li3, li4 and li5 visible li2 not
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 41: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 42: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 43: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 44: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 45: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (a11, a13, a14 visible, a12 not)
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 46: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 47: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 48: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a14').offsetTop > 0,
- 'Point 49: Aleady distributed nodes should behave like a shadow host child nodes');
-
- var shadow2 = d.createElement('shadow');
- s3.appendChild(shadow2);
-
- // Nothing should be changed
- //At this point: li1, li3, li4 and li5 visible li2 not
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 51: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 52: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 53: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 54: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 55: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (a11 and a13 visible, a12 not)
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 56: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 57: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 58: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a14').offsetTop > 0,
- 'Point 59: Aleady distributed nodes should behave like a shadow host child nodes');
-
- //replace the nested tree by younger one
- var s4 = li1.createShadowRoot();
- var shadowLI4 = document.createElement('li');
- shadowLI4.innerHTML = '<content select=".cl2"></content>';
- s4.appendChild(shadowLI4);
-
- //At this point: li1, li3, li4 and li5 visible li2 not
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 61: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 62: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 63: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 64: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 65: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (a12 visible, others not)
- assert_equals(d.querySelector('#a11').offsetTop, 0,
- 'Point 66: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a12').offsetTop > 0,
- 'Point 67: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a13').offsetTop, 0,
- 'Point 68: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a14').offsetTop, 0,
- 'Point 69: Aleady distributed nodes should behave like a shadow host child nodes');
-
-
- //Let's check that if we add a shadow insertion point to the tree nothing is
- //changed in the nested three (old tree is still invisible)
- var shadow3 = d.createElement('shadow');
- s3.appendChild(shadow3);
-
- //At this point: li1, li3, li4 and li5 visible li2 not
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 61: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 62: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 63: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li4').offsetTop > 0, 'Point 64: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0, 'Point 65: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the reprojected nodes (a12 visible, others not)
- assert_equals(d.querySelector('#a11').offsetTop, 0,
- 'Point 66: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a12').offsetTop > 0,
- 'Point 67: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a13').offsetTop, 0,
- 'Point 68: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a14').offsetTop, 0,
- 'Point 69: Aleady distributed nodes should behave like a shadow host child nodes');
-}), 'A_04_09_01_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html
index 6f957709e9c..9d2eb43a352 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-001.html
@@ -17,7 +17,7 @@ policies and contribution forms [3].
<link rel="author" title="Hayato Ito" href="mailto:hayato@google.com">
<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#reprojection">
<meta name="assert" content="a node is distributed into more than one insertion point.">
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
<style>
.pass { color: green; }
</style>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002-ref.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002-ref.html
deleted file mode 100644
index 8e538c91e59..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002-ref.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<meta charset="utf-8">
-<title>Shadow DOM Test: Basic reprojection with a select attribute (reference)</title>
-<link rel="author" title="Anna Ogawa" href="mailto:anna.ogawa.0219@gmail.com">
-<link rel="author" title="Hayato Ito" href="mailto:hayato@google.com">
-<style>
-.pass { color: green; }
-</style>
-</head>
-<body>
-<p>You should see green text saying "Apple" below.</p>
-<div id="host">
- <div>Hello a Shadow Root2.</div>
- <div>
- <div class="pass">Apple.</div>
- </div>
-</div>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html
deleted file mode 100644
index 8cc408d8860..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/reprojection-002.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<!DOCTYPE html>
-<head>
-<meta charset="utf-8">
-<title>Shadow DOM Test - Tests a reprojection with a select attribute.</title>
-<link rel="match" href="reprojection-002-ref.html">
-<link rel="author" title="Anna Ogawa" href="mailto:anna.ogawa.0219@gmail.com">
-<link rel="author" title="Hayato Ito" href="mailto:hayato@google.com">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#reprojection">
-<meta name="assert" content="A node is distributed into more than one insertion point with a select attribute.">
-<script src="../../testcommon.js"></script>
-<style>
-.pass { color: green; }
-.fail { color: red; }
-</style>
-</head>
-<body>
-<p>You should see green text saying "Apple" below.</p>
-<div id="host">
- <div class="A pass">Apple.</div>
- <div class="B fail">Orange.</div>
-</div>
-<script>
- var shadowRoot = host.createShadowRoot();
- shadowRoot.innerHTML = '<div id="host2">Hello a Shadow Root.<content></content><div class="fail">Banana.</div></div>';
- var host2 = shadowRoot.getElementById("host2");
- var shadowRoot2 = host2.createShadowRoot();
- shadowRoot2.innerHTML = '<div>Hello a Shadow Root2.</div><div><content select=".A"></content></div>';
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/test-001.html
deleted file mode 100644
index 00a2a3e854a..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/reprojection/test-001.html
+++ /dev/null
@@ -1,175 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_06_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#reprojection">
-<meta name="assert" content="Reprojection: The nodes distributed into that insertion point must appear as if they were child nodes of the shadow host in the context of distribution within the shadow DOM subtree, hosted by said shadow host">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_06_01_T01 = async_test('A_04_06_01_T01');
-
-A_04_06_01_T01.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/blank.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_06_01_T01.step_func(function () {
- try {
- var d = iframe.contentDocument;
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul id="host">' +
- '<li id="li1" class="shadow">' +
- '<a id="a11" class="cl1" href="#">Link11 Shadow</a>' +
- '<a id="a12" class="cl2" href="#">Link12 Shadow</a>' +
- '<a id="a13" class="cl1" href="#">Link13 Shadow</a>' +
- '</li>' +
- '<li id="li2">' +
- '<a id="a21" href="#">Link21</a><a id="a22" href="#">Link22</a>' +
- '</li>' +
- '<li id="li3" class="shadow">' +
- '<a id="a31" href="#">Link31 Shadow</a><a id="a32" href="#">Link32 Shadow</a>' +
- '</li>' +
- '<li id="li4" class="shadow2">' +
- '<a id="a41" href="#">Link41 Shadow 2</a><a id="a42" href="#">Link22 Shadow 2</a>' +
- '</li>' +
- '<li id="li5" class="shadow2">' +
- '<a id="a51" href="#">Link51 Shadow</a><a id="a52" href="#">Link52 Shadow 2</a>' +
- '</li>' +
- '</ul>';
-
- d.body.appendChild(div);
-
- var li1 = d.querySelector('#li1');
- var s = li1.createShadowRoot();
- //make shadow subtree
- var shadowLI1 = document.createElement('li');
- shadowLI1.innerHTML = '<li><content select=".cl1"></content></li>';
- s.appendChild(shadowLI1);
-
- var ul = d.querySelector('#host');
- var s2 = ul.createShadowRoot();
- var div2 = document.createElement('div');
- div2.innerHTML = '<ul><content select=".shadow"></content></ul>';
- s2.appendChild(div2);
-
-
- assert_true(d.querySelector('#li1').offsetTop > 0, 'Point 1: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0, 'Point 2: Node that match insertion ' +
- 'point criteria should be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 3: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 4: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0, 'Point 5: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the nested tree
- assert_true(d.querySelector('#a11').offsetTop > 0,
- 'Point 6: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_true(d.querySelector('#a13').offsetTop > 0,
- 'Point 7: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 8: Aleady distributed nodes should behave like a shadow host child nodes');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_06_01_T01.done();
- });
-});
-
-
-
-var A_04_06_01_T02 = async_test('A_04_06_01_T02');
-
-A_04_06_01_T02.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/blank.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_06_01_T02.step_func(function () {
- try {
- var d = iframe.contentDocument;
-
- var div = d.createElement('div');
- div.innerHTML = '' +
- '<ul id="host">' +
- '<li id="li1" class="shadow">' +
- '<a id="a11" class="cl1" href="#">Link11 Shadow</a>' +
- '<a id="a12" class="cl2" href="#">Link12 Shadow</a>' +
- '<a id="a13" class="cl1" href="#">Link13 Shadow</a>' +
- '</li>' +
- '<li id="li2">' +
- '<a id="a21" href="#">Link21</a><a id="a22" href="#">Link22</a>' +
- '</li>' +
- '<li id="li3" class="shadow">' +
- '<a id="a31" href="#">Link31 Shadow</a><a id="a32" href="#">Link32 Shadow</a>' +
- '</li>' +
- '<li id="li4" class="shadow2">' +
- '<a id="a41" href="#">Link41 Shadow 2</a><a id="a42" href="#">Link22 Shadow 2</a>' +
- '</li>' +
- '<li id="li5" class="shadow2">' +
- '<a class="cl1" id="a51" href="#">Link51 Shadow</a><a id="a52" href="#">Link52 Shadow 2</a>' +
- '</li>' +
- '</ul>';
-
- d.body.appendChild(div);
-
- var li1 = d.querySelector('#li1');
- var s = li1.createShadowRoot();
- //make shadow subtree
- var shadowLI1 = document.createElement('li');
- shadowLI1.innerHTML = '<li><content select=".cl1"></content></li>';
- s.appendChild(shadowLI1);
-
- var ul = d.querySelector('#host');
- var s2 = ul.createShadowRoot();
- var div2 = document.createElement('div');
- div2.innerHTML = '<li><content select=".cl1"></content></li>';
- s2.appendChild(div2);
-
- // The second distribution shouldn't render anything
- assert_equals(d.querySelector('#li1').offsetTop, 0, 'Point 1: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li2').offsetTop, 0, 'Point 2: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li3').offsetTop, 0, 'Point 3: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li4').offsetTop, 0, 'Point 4: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0, 'Point 5: Node that doen\'t match ' +
- 'insertion point criteria shouldn\'t be rendered');
-
- //check the nested tree
- assert_equals(d.querySelector('#a11').offsetTop, 0,
- 'Point 6: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a13').offsetTop, 0,
- 'Point 7: Aleady distributed nodes should behave like a shadow host child nodes');
- assert_equals(d.querySelector('#a12').offsetTop, 0,
- 'Point 8: Aleady distributed nodes should behave like a shadow host child nodes');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_06_01_T02.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-001.html
deleted file mode 100644
index 86b1f2b96fc..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-001.html
+++ /dev/null
@@ -1,59 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_03_01</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#matching-insertion-points">
-<meta name="assert" content="Matching Insertion Points: A valid selector fragment may contain a type selector">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_03_01_T1 = async_test('A_04_03_01_T01');
-
-
-A_04_03_01_T1.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_03_01_T1.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var div = d.querySelector('#divid');
- var s = div.createShadowRoot();
-
- //make shadow subtree
- var subdiv1 = document.createElement('div');
- subdiv1.innerHTML = '<content select="span"></content>';
- s.appendChild(subdiv1);
-
- //The order of DOM elements should be the following:
- // <ul class='stories'>, <span>. Invisible: <ul id="ul2">
-
- assert_true(d.querySelector('ul.stories').offsetTop < d.querySelector('#spandex').offsetTop,
- 'A valid selector fragment may contain \'span\' type selector');
-
- assert_equals(d.querySelector('#ul2').offsetTop, 0,
- '<ul> element shouldn\'t match "span" type selector');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_03_01_T1.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-002.html
deleted file mode 100644
index cd5b59cdc11..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-002.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_03_02</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#matching-insertion-points">
-<meta name="assert" content="Matching Insertion Points: A valid selector fragment may contain an universal selector">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_03_02_T1 = async_test('A_04_03_02_T01');
-
-
-A_04_03_02_T1.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_03_02_T1.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
-
- //make shadow subtree
- var subdiv1 = document.createElement('div');
-
- // TODO add tests for namespace universal selector ns|*
- subdiv1.innerHTML = '<ul><content select="*"></content></ul>';
- s.appendChild(subdiv1);
-
- //The order of DOM elements should be the following:
- // li1-li6 should be visible and located on-order
- assert_true(d.querySelector('#li1').offsetTop < d.querySelector('#li2').offsetTop,
- 'Point 1: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li2').offsetTop < d.querySelector('#li3').offsetTop,
- 'Point 2: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li3').offsetTop < d.querySelector('#li4').offsetTop,
- 'Point 3: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li4').offsetTop < d.querySelector('#li5').offsetTop,
- 'Point 4: Elements that mach insertion point criteria don\'t participate in distribution');
- assert_true(d.querySelector('#li5').offsetTop < d.querySelector('#li6').offsetTop,
- 'Point 5: Elements that mach insertion point criteria don\'t participate in distribution');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_03_02_T1.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-003.html
deleted file mode 100644
index 8a25ebc5af2..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-003.html
+++ /dev/null
@@ -1,66 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_03_03</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#matching-insertion-points">
-<meta name="assert" content="Matching Insertion Points: A valid selector fragment may contain a class selector">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_03_03_T01 = async_test('A_04_03_03_T01');
-
-
-A_04_03_03_T01.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_03_03_T01.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
-
- //make shadow subtree
- var subdiv1 = document.createElement('div');
- subdiv1.innerHTML = '<ul><content select=".shadow"></content></ul>';
- s.appendChild(subdiv1);
-
- //The order of DOM elements should be the following:
- //li3, li6. Other elements invisible
- assert_true(d.querySelector('#li3').offsetTop < d.querySelector('#li6').offsetTop,
- 'Class name should be a valid insertion point matching criteria');
- assert_true(d.querySelector('#li3').offsetTop > 0,
- 'Class name should be a valid insertion point matching criteria, element should be visible');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 1: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li2').offsetTop, 0,
- 'Point 2: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li4').offsetTop, 0,
- 'Point 3: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 4: Elements that don\'t mach insertion point criteria participate in distribution');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_03_03_T01.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-004.html
deleted file mode 100644
index 8abcb7b7d9b..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-004.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_03_04</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#matching-insertion-points">
-<meta name="assert" content="Matching Insertion Points: A valid selector fragment may contain an ID selector">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_03_04_T01 = async_test('A_04_03_04_T01');
-
-A_04_03_04_T01.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_03_04_T01.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
-
- //make shadow subtree
- var subdiv1 = document.createElement('div');
- subdiv1.innerHTML = '<ul><content select="#li4"></content></ul>';
- s.appendChild(subdiv1);
-
- //The order of DOM elements should be the following:
- //li4. Other elements invisible
- assert_true(d.querySelector('#li4').offsetTop > 0,
- 'Class name should be a valid insertion point matching criteria, element should be visible');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 1: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li2').offsetTop, 0,
- 'Point 2: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li3').offsetTop, 0,
- 'Point 3: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 4: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li6').offsetTop, 0,
- 'Point 5: Elements that don\'t mach insertion point criteria participate in distribution');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_03_04_T01.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-005.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-005.html
deleted file mode 100644
index 5069f219bed..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/satisfying-matching-criteria/test-005.html
+++ /dev/null
@@ -1,65 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_04_03_05</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#matching-insertion-points">
-<meta name="assert" content="Matching Insertion Points: A valid selector fragment may contain an attribute selector">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-var A_04_03_05_T01 = async_test('A_04_03_05_T01');
-
-A_04_03_05_T01.step(function () {
- var iframe = document.createElement('iframe');
- iframe.src = '../../resources/bobs_page.html';
- document.body.appendChild(iframe);
-
- iframe.onload = A_04_03_05_T01.step_func(function () {
- try {
- var d = iframe.contentDocument;
- var ul = d.querySelector('ul.stories');
- var s = ul.createShadowRoot();
-
- //make shadow subtree
- var subdiv1 = document.createElement('div');
- subdiv1.innerHTML = '<ul><content select="li[title]"></content></ul>';
- s.appendChild(subdiv1);
-
- //The order of DOM elements should be the following:
- //li2. Other elements invisible
- assert_true(d.querySelector('#li2').offsetTop > 0,
- 'Attribute should be a valid insertion point matching criteria, element should be visible');
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 1: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li3').offsetTop, 0,
- 'Point 2: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li4').offsetTop, 0,
- 'Point 3: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 4: Elements that don\'t mach insertion point criteria participate in distribution');
- assert_equals(d.querySelector('#li6').offsetTop, 0,
- 'Point 5: Elements that don\'t mach insertion point criteria participate in distribution');
- } finally {
- iframe.parentNode.removeChild(iframe);
- }
- A_04_03_05_T01.done();
- });
-});
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-001.html
index 8ab15a1ac3e..fb228cda5dd 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-001.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-trees">
<meta name="assert" content="When a shadow root is attached, the shadow tree is rendered.">
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
<style>
p { color: black; }
* { color: red; }
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-002.html
index 23d0cdd30a2..ae2d98cf8e7 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/shadow-root-002.html
@@ -17,7 +17,7 @@ policies and contribution forms [3].
<link rel="author" title="Yuta Kitamura" href="mailto:yutak@google.com">
<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#shadow-trees">
<meta name="assert" content="On distribution, content element is replaced with the shadow host's children.">
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
<style>
p { color: black; }
.pass { color: green; }
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html
index db3eede5662..8c10d251557 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/text-decoration-001-ref.html
@@ -1,13 +1,13 @@
<!DOCTYPE html>
<html>
- <head>
- <meta charset="utf-8">
- <title>Shadow DOM Test</title>
- <link rel="author" title="Masaya Iseki" href="mailto:iseki.m.aa@gmail.com">
- </head>
- <body>
- <span>
- if NOT underlined, it is success.
- </span>
- </body>
+ <head>
+ <meta charset="utf-8">
+ <title>Shadow DOM Test</title>
+ <link rel="author" title="Masaya Iseki" href="mailto:iseki.m.aa@gmail.com">
+ </head>
+ <body>
+ <span>
+ if NOT underlined, it is success.
+ </span>
+ </body>
</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html
index cf23efe04c8..d22e6c49abf 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-001.html
@@ -19,7 +19,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The shadow nodes and named shadow elements are not accessible using shadow host's document DOM tree accessors.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -66,7 +66,6 @@ var HTML_CONTENT = [
'<embed></embed>',
'<form></form>',
'<script><' + '/script>',
- '<applet></applet>',
'</body>'
].join('\n');
@@ -91,7 +90,7 @@ function populateTestContentToShadowRoot(shadowRoot) {
function createDocumentForTesting() {
var doc = document.implementation.createHTMLDocument('');
populateTestContentToHostDocument(doc);
- var shadowRoot = doc.documentElement.createShadowRoot();
+ var shadowRoot = doc.body.attachShadow({mode: 'open'});
populateTestContentToShadowRoot(shadowRoot);
return doc;
}
@@ -121,13 +120,17 @@ test(function () {
test(function () {
var doc = document.implementation.createHTMLDocument('');
populateTestContentToHostDocument(doc);
- var shadowRoot = doc.documentElement.createShadowRoot();
+
+ // Note: this test is originally written to replace document.documentElement
+ // with shadow contents, but among Shadow DOM V1 allowed elements body is the
+ // most approximate to it, though some test may make lesser sense.
+ var shadowRoot = doc.body.attachShadow({mode: 'open'});
populateTestContentToShadowRoot(shadowRoot);
// Replace the content of <title> to distinguish elements in a host
// document and a shadow tree.
doc.getElementsByTagName('title')[0].textContent = 'Title of host document';
- shadowRoot.getElementsByTagName('title')[0].textContent =
+ shadowRoot.querySelector('title').textContent =
'Title of shadow tree';
assert_equals(doc.title, 'Title of host document');
@@ -165,7 +168,7 @@ test(function () {
generate_tests(
testHTMLCollection,
- ['anchors', 'applets', 'all'].map(
+ ['anchors', 'all'].map(
function (accessor) {
return [
'Elements in a shadow tree should not be accessible from ' +
@@ -213,7 +216,7 @@ test(function () {
var shadowRoot = doc.documentElement.createShadowRoot();
populateTestContentToShadowRoot(shadowRoot);
- shadowRoot.getElementsByTagName('p')[0].id = 'test-id';
+ shadowRoot.querySelectorAll('p')[0].id = 'test-id';
assert_equals(doc.getElementById('test-id'), null);
},
'Elements in a shadow tree should not be accessible from owner ' +
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002.html
index d0c00e8dd54..7a8f9f3d2b2 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002.html
@@ -18,7 +18,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The nodes are accessible using shadow root's DOM tree accessor methods.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -30,53 +30,33 @@ function assert_singleton_node_list(nodeList, expectedNode) {
test(function () {
var doc = document.implementation.createHTMLDocument('Test');
- var shadowRoot = doc.body.createShadowRoot();
+ var shadowRoot = doc.body.attachShadow({mode: 'open'});
var image = doc.createElement('img');
shadowRoot.appendChild(image);
- assert_singleton_node_list(shadowRoot.getElementsByTagName('img'), image);
+ assert_singleton_node_list(shadowRoot.querySelectorAll('img'), image);
},
'Elements in a shadow tree should be accessible via shadow root\'s ' +
- 'getElementsByTagName() DOM tree accessor.'
-);
-
-test(function () {
- var namespace = 'http://www.w3.org/1999/xhtml';
- var doc = document.implementation.createDocument(namespace, 'html');
- doc.documentElement.appendChild(doc.createElementNS(namespace, 'head'));
- var body = doc.createElementNS(namespace, 'body');
- var imageHost = doc.createElementNS(namespace, 'img');
- body.appendChild(imageHost);
- doc.documentElement.appendChild(body);
-
- var shadowRoot = body.createShadowRoot();
- var imageShadow = doc.createElementNS(namespace, 'img');
- shadowRoot.appendChild(imageShadow);
-
- assert_singleton_node_list(
- shadowRoot.getElementsByTagNameNS(namespace, 'img'), imageShadow);
-},
- 'Elements in a shadow tree should be accessible via shadow root\'s ' +
- 'getElementsByTagNameNS() DOM tree accessor.'
+ 'querySelectorAll() DOM tree accessor.'
);
test(function () {
var doc = document.implementation.createHTMLDocument('Test');
- var shadowRoot = doc.body.createShadowRoot();
+ var shadowRoot = doc.body.attachShadow({mode: 'open'});
var div = doc.createElement('div');
div.className = 'div-class';
shadowRoot.appendChild(div);
assert_singleton_node_list(
- shadowRoot.getElementsByClassName('div-class'), div);
+ shadowRoot.querySelectorAll('.div-class'), div);
},
- 'Elements in a shadow tree should be accessible via shadow root\'s ' +
- 'getElementsByClassName() DOM tree accessor.'
+ 'Elements with a specific class in a shadow tree should be accessible via' +
+ 'shadow root\'s querySelectorAll() DOM tree accessor.'
);
test(function () {
var doc = document.implementation.createHTMLDocument('Test');
- var shadowRoot = doc.body.createShadowRoot();
+ var shadowRoot = doc.body.attachShadow({mode: 'open'});
var div = doc.createElement('div');
div.id = 'div-id';
shadowRoot.appendChild(div);
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-001.html
index 64ccbcd6340..c643bc47605 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-001.html
@@ -19,7 +19,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The ownerDocument property of all nodes in shadow tree refers to the document of the shadow host.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-002.html
index bed33c2504a..0b4de7f7ffe 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/ownerdocument-002.html
@@ -19,7 +19,8 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The ownerDocument property of all nodes in shadow tree refers to the document of the shadow host.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -28,8 +29,8 @@ function testElement(elementName) {
var doc = document.implementation.createHTMLDocument('Test');
var element = doc.createElement(elementName);
doc.body.appendChild(element);
- var shadowRoot = element.createShadowRoot();
- HTML5_ELEMENT_NAMES.forEach(function (name) {
+ var shadowRoot = element.attachShadow({mode: 'open'});
+ ATTACHSHADOW_SAFELISTED_ELEMENTS.forEach(function (name) {
shadowRoot.appendChild(doc.createElement(name));
});
@@ -40,7 +41,7 @@ function testElement(elementName) {
}
}
-var testParameters = HTML5_ELEMENT_NAMES.map(function (name) {
+var testParameters = ATTACHSHADOW_SAFELISTED_ELEMENTS.map(function (name) {
return [
'ownerDocument property of any elements in a shadow tree should ' +
'match the document of the shadow host, when the host is a "' +
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-001.html
index c0a49289820..853d49ca75c 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-001.html
@@ -17,7 +17,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: Nodes in a shadow tree must not be accessible through selector APIs of owner document.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-002.html
index 3277418c547..176000658a1 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/selectors-api-002.html
@@ -18,7 +18,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: Nodes in a shadow tree must be accessible through selector APIs of the shadow root.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/shadow-root-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/shadow-root-001.html
index 42f465a855c..d1f838b2e63 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/shadow-root-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/shadow-root-001.html
@@ -18,7 +18,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The parentNode and parentElement attributes of the shadow root object must always return null.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-005.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-005.html
index 8738c7469af..6f59de686d0 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-005.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-005.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation:The nodes with a unique id and named elements are not addressable from any attributes of elements in shadow host's document">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-007.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-007.html
index 0c56b921fb2..97a8ab817bf 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-007.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-007.html
@@ -16,7 +16,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation:The nodes with a unique id and named elements are addressable from any attributes of elements in the same shadow DOM subtree">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-009.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-009.html
index d19d2e8f19f..5aa6b9218cd 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-009.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-009.html
@@ -18,7 +18,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: no nodes other than shadow root descendants are accessible with shadow root DOM tree accessor methods">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -53,10 +53,10 @@ A_04_01_09.setup = function () {
ctx.d = newHTMLDocument();
A_04_01_09.setupBlock(ctx, 'd', ctx.d.body);
- ctx.s1 = ctx.d_p1.createShadowRoot();
+ ctx.s1 = ctx.d_p1.attachShadow({mode: 'open'});
A_04_01_09.setupBlock(ctx, 's1', ctx.s1);
- ctx.s2 = ctx.s1_p1.createShadowRoot();
+ ctx.s2 = ctx.s1_p1.attachShadow({mode: 'open'});
A_04_01_09.setupBlock(ctx, 's2', ctx.s2);
assert_true(ctx.d_div1 != null, 'setup:d_div1');
@@ -69,78 +69,38 @@ A_04_01_09.setup = function () {
return ctx;
};
-//check getElementsByTagName
+//check querySelectorAll
test(function () {
var ctx = A_04_01_09.setup();
assert_nodelist_contents_equal_noorder(
- ctx.s1.getElementsByTagName('div'), [ctx.s1_div1, ctx.s1_div2],
+ ctx.s1.querySelectorAll('div'), [ctx.s1_div1, ctx.s1_div2],
'nodes, other than shadow root descendants, should not be accessible with ' +
'ShadowRoot.getElementsByTagName (s1)');
assert_nodelist_contents_equal_noorder(
- ctx.s2.getElementsByTagName('div'), [ctx.s2_div1, ctx.s2_div2],
+ ctx.s2.querySelectorAll('div'), [ctx.s2_div1, ctx.s2_div2],
'nodes, other than shadow root descendants, should not be accessible with ' +
'ShadowRoot.getElementsByTagName (s2)');
}, 'A_04_01_09_T01');
-// getElementsByTagNameNS
+//check querySelectorAll for class
test(function () {
var ctx = A_04_01_09.setup();
assert_nodelist_contents_equal_noorder(
- ctx.s1.getElementsByTagNameNS('*', 'div'), [ctx.s1_div1, ctx.s1_div2],
- 'nodes, other than shadow root descendants, should not be accessible with ' +
- 'ShadowRoot.getElementsByTagNameNS (s1)');
-
- assert_nodelist_contents_equal_noorder(
- ctx.s2.getElementsByTagNameNS('*', 'div'), [ctx.s2_div1, ctx.s2_div2],
- 'nodes, other than shadow root descendants, should not be accessible with ' +
- 'ShadowRoot.getElementsByTagNameNS (s2)');
-
-}, 'A_04_01_09_T02');
-
-//check getElementsByClassName
-test(function () {
- var ctx = A_04_01_09.setup();
-
- assert_nodelist_contents_equal_noorder(
- ctx.s1.getElementsByClassName('cls'), [ctx.s1_div1, ctx.s1_p1, ctx.s1_div2],
+ ctx.s1.querySelectorAll('.cls'), [ctx.s1_div1, ctx.s1_p1, ctx.s1_div2],
'nodes, other than shadow root descendants, should not be accessible with ' +
'ShadowRoot.getElementsByClassName (s1)');
assert_nodelist_contents_equal_noorder(
- ctx.s2.getElementsByClassName('cls'), [ctx.s2_div1, ctx.s2_p1, ctx.s2_div2],
+ ctx.s2.querySelectorAll('.cls'), [ctx.s2_div1, ctx.s2_p1, ctx.s2_div2],
'nodes, other than shadow root descendants, should not be accessible with ' +
'ShadowRoot.getElementsByClassName (s2)');
}, 'A_04_01_09_T03');
-// check getElementById
-test(function () {
- var ctx = A_04_01_09.setup();
-
- assert_equals(ctx.s1.getElementById('d_id1'), null, 'Expected no access to d_div1 from s1.getElementById()');
- assert_equals(ctx.s1.getElementById('d_id2'), null, 'Expected no access to d_div2 from s1.getElementById()');
- assert_equals(ctx.s2.getElementById('d_id1'), null, 'Expected no access to d_div1 from s2.getElementById()');
- assert_equals(ctx.s2.getElementById('d_id2'), null, 'Expected no access to d_div1 from s2.getElementById()');
-
-
- assert_equals(ctx.s1.getElementById('s1_id1'), ctx.s1_div1, 'Expected access to s1_div1 form s1.getElementById()');
- assert_equals(ctx.s1.getElementById('s1_id2'), ctx.s1_div2, 'Expected access to s1_div2 form s1.getElementById()');
- assert_equals(ctx.s2.getElementById('s2_id1'), ctx.s2_div1, 'Expected access to s2_div1 form s2.getElementById()');
- assert_equals(ctx.s2.getElementById('s2_id2'), ctx.s2_div2, 'Expected access to s2_div2 form s2.getElementById()');
-
-
- assert_equals(ctx.s1.getElementById('s2_id1'), null, 'Expected no access to s2_div1 form s1.getElementById()');
- assert_equals(ctx.s1.getElementById('s2_id2'), null, 'Expected no access to s2_div2 form s1.getElementById()');
- assert_equals(ctx.s2.getElementById('s1_id1'), null, 'Expected no access to s1_div1 form s2.getElementById()');
- assert_equals(ctx.s2.getElementById('s1_id2'), null, 'Expected no access to s1_div2 form s2.getElementById()');
-
-}, 'A_04_01_09_T04');
-
-
// check querySelector for id
test(function () {
var ctx = A_04_01_09.setup();
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html
index beee89e73f2..737494f3da6 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/test-011.html
@@ -16,48 +16,30 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation:The style sheets, represented by the shadow nodes are not accessible using shadow host document's CSSOM extensions">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
-// check that <style> element added to head is not exposed
-var A_04_01_11_T1 = async_test('A_04_01_11_T01');
-
-A_04_01_11_T1.step(function () {
- var ctx = newContext();
- var iframe = newIFrame(ctx, '../../resources/blank.html');
- iframe.onload = A_04_01_11_T1.step_func(step_unit(function () {
- var d = iframe.contentDocument;
- var initialStyleSheetsCount = d.styleSheets.length;
- var s = d.head.createShadowRoot();
- var style = d.createElement('style');
- s.appendChild(style);
- assert_equals(d.styleSheets.length, initialStyleSheetsCount, 'style elements in shadow DOM must not be exposed via ' +
- 'the document.styleSheets collection ');
-
- }, ctx, A_04_01_11_T1));
-});
-
-
// check that <link> element added to head is not exposed
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
- var initialStyleSheetsCount = d.styleSheets.length;
+ var d = newRenderedHTMLDocument(ctx);
+ var initialStyleSheetsCount = d.styleSheets.length;
- var link = d.createElement('link');
- link.setAttribute('rel', 'stylesheet');
- d.body.appendChild(link);
+ var link = d.createElement('link');
+ link.setAttribute('rel', 'stylesheet');
+ d.body.appendChild(link);
- //create Shadow root
- var root = d.createElement('div');
- d.body.appendChild(root);
- var s = root.createShadowRoot();
+ //create Shadow root
+ var root = d.createElement('div');
+ d.body.appendChild(root);
+ var s = root.createShadowRoot();
- s.appendChild(link);
+ s.appendChild(link);
- assert_equals(d.styleSheets.length, initialStyleSheetsCount, 'stylesheet link elements in shadow DOM must not be ' +
+ assert_equals(d.styleSheets.length, initialStyleSheetsCount, 'stylesheet link elements in shadow DOM must not be ' +
'exposed via the document.styleSheets collection');
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-001.html
index 5745ce8e836..4a83ff7e8d6 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-001.html
@@ -18,7 +18,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The nodes and named elements are not accessible from Window object named properties.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
@@ -42,49 +42,6 @@ test(function () {
'An iframe element in a shadow tree should not be accessible from ' +
'window\'s named properties with its "name" attribute value.'
);
-
-var frameTest = async_test(
- 'A frame element in a shadow tree should not be accessible from ' +
- 'window\'s named properties with its "name" attribute value.');
-
-frameTest.step(function () {
- // To test a document with frames, an iframe containing frames is created.
- var srcdoc = [
- '<!DOCTYPE html>',
- '<html>',
- '<head>',
- '<title>Frames Test</title>',
- '<script src="../../testcommon.js"><' + '/script>',
- '</head>',
- '<frameset id="host" cols="50%,*">',
- '<frame src="about:blank" name="host-frame1">',
- '<frame src="about:blank" name="host-frame2">',
- '</frameset>',
- '</html>'
- ].join('\n');
- var iframe = document.createElement('iframe');
- iframe.srcdoc = srcdoc;
- iframe.style.display = 'none';
-
- iframe.addEventListener('load', frameTest.step_func(function (event) {
- try {
- var doc = iframe.contentDocument;
- var win = iframe.contentWindow;
- var shadowRoot = doc.getElementById('host').createShadowRoot();
- shadowRoot.innerHTML =
- '<frame src="about:blank" name="shadow-frame1">\n' +
- '<frame src="about:blank" name="shadow-frame2">';
- assert_false('shadow-frame1' in win);
- assert_false('shadow-frame2' in win);
- frameTest.done();
- } finally {
- if (iframe.parentNode)
- iframe.parentNode.removeChild(iframe);
- }
- }));
-
- document.body.appendChild(iframe);
-});
</script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-002.html
index bb9f19765c2..d8c5aa48366 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-002.html
@@ -18,7 +18,7 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The nodes and named elements are not accessible from Window object named properties.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-003.html
index e2d91721e73..f08db94e317 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/shadow-trees/upper-boundary-encapsulation/window-named-properties-003.html
@@ -18,7 +18,8 @@ policies and contribution forms [3].
<meta name="assert" content="Upper-boundary encapsulation: The nodes and named elements are not accessible from Window object named properties.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/css-variables/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/css-variables/test-001.html
index 19066d4f597..44e84b56576 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/css-variables/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/css-variables/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="CSS variables: The shadow host styles being inherited by the children of the shadow root must also apply to CSS Variables.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -27,44 +28,44 @@ test(unit(function (ctx) {
var d = newRenderedHTMLDocument(ctx);
d.head.innerHtml = '' +
- '<style>' +
- 'body {font-size:10px;}' +
- '</style>';
+ '<style>' +
+ 'body {font-size:10px;}' +
+ '</style>';
- d.body.innerHTML =
- '<ul id="shHost">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
+ d.body.innerHTML =
+ '<ul id="shHost">' +
+ '<li id="li1" class="shadow">1</li>' +
+ '<li id="li2" class="shadow2">2</li>' +
+ '<li id="li3" class="shadow">3</li>' +
+ '<li id="li4">4</li>' +
+ '<li id="li5" class="shadow">5</li>' +
+ '<li id="li6" class="shadow2">6</li>' +
+ '</ul>';
- var host = d.querySelector('#shHost');
- var s = host.createShadowRoot();
+ var host = d.querySelector('#shHost');
+ var s = host.createShadowRoot();
- var div = d.createElement('div');
- div.innerHTML ='<ul><content select=".shadow"></content></ul>';
- s.appendChild(div);
+ var div = d.createElement('div');
+ div.innerHTML ='<ul><content select=".shadow"></content></ul>';
+ s.appendChild(div);
- var defHeight1 = d.querySelector('#li1').offsetHeight;
- var defHeight3 = d.querySelector('#li3').offsetHeight;
- var defHeight5 = d.querySelector('#li5').offsetHeight;
+ var defHeight1 = d.querySelector('#li1').offsetHeight;
+ var defHeight3 = d.querySelector('#li3').offsetHeight;
+ var defHeight5 = d.querySelector('#li5').offsetHeight;
- var style = d.createElement('style');
- style.innerHTML =':root {' +
- 'var-text-size: 30px;' +
- '}' +
- 'body {' +
- 'font-size: var(text-size);' +
- '}';
- s.appendChild(style);
+ var style = d.createElement('style');
+ style.innerHTML =':root {' +
+ 'var-text-size: 30px;' +
+ '}' +
+ 'body {' +
+ 'font-size: var(text-size);' +
+ '}';
+ s.appendChild(style);
- assert_true(d.querySelector('#li1').offsetHeight > defHeight1, 'Point 1: Element height should be changed');
- assert_true(d.querySelector('#li3').offsetHeight > defHeight3, 'Point 2: Element height should be changed');
- assert_true(d.querySelector('#li5').offsetHeight > defHeight5, 'Point 3: Element height should be changed');
+ assert_true(d.querySelector('#li1').offsetHeight > defHeight1, 'Point 1: Element height should be changed');
+ assert_true(d.querySelector('#li3').offsetHeight > defHeight3, 'Point 2: Element height should be changed');
+ assert_true(d.querySelector('#li5').offsetHeight > defHeight5, 'Point 3: Element height should be changed');
}), 'A_06_01_01_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/deep-combinator/deep-combinator-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/deep-combinator/deep-combinator-001.html
deleted file mode 100644
index a5ac473860b..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/deep-combinator/deep-combinator-001.html
+++ /dev/null
@@ -1,156 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: /deep/ combinator</title>
-<link rel="author" title="Kenji Baheux" href="mailto:kenjibaheux@google.com">
-<link rel="help" href="http://dev.w3.org/csswg/css-scoping/#deep-combinator">
-<meta name="assert" content="/deep/ should select through all Shadow trees">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- var outerhost = d.createElement('div');
- outerhost.setAttribute('id', 'foo-host');
- var span0 = d.createElement('span');
- span0.setAttribute('id', 'outer-host');
- outerhost.appendChild(span0);
-
- var outerroot = outerhost.createShadowRoot();
-
- var div1 = d.createElement('div');
- var span1 = d.createElement('span');
- span1.setAttribute('id', 'not-top');
- div1.appendChild(span1);
- outerroot.appendChild(div1);
-
- var span2 = d.createElement('span');
- span2.setAttribute('id', 'top');
- outerroot.appendChild(span2);
-
-
- var innerhost = d.createElement('div');
- innerhost.setAttribute('id', 'bar-host');
- var span3 = d.createElement('span');
- span3.setAttribute('id', 'inner-host');
- innerhost.appendChild(span3);
-
- var innerroot = innerhost.createShadowRoot();
-
- var span4 = d.createElement('span');
- span4.setAttribute('id', 'nested');
- innerroot.appendChild(span4);
- outerroot.appendChild(innerhost);
-
- d.body.appendChild(outerhost);
-
-
- assert_equals(d.querySelectorAll('#foo-host /deep/ span').length, 5, 'Point 1: match only direct children of the outer shadow tree');
- assert_equals(d.querySelectorAll('#foo-host /deep/ span')[0], span1, 'Point 2: incorrect match');
- assert_equals(d.querySelectorAll('#foo-host /deep/ span')[1], span2, 'Point 3: incorrect match');
- assert_equals(d.querySelectorAll('#foo-host /deep/ span')[2], span4, 'Point 4: incorrect match');
- assert_equals(d.querySelectorAll('#foo-host /deep/ span')[3], span3, 'Point 5: incorrect match');
- assert_equals(d.querySelectorAll('#foo-host /deep/ span')[4], span0, 'Point 6: incorrect match');
- }), 'SD_SHADOW_DEEP_QUERYSELECTOR_T1');
-
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- var outerhost = d.createElement('div');
- outerhost.setAttribute('id', 'foo-host');
- var span0 = d.createElement('span');
- span0.setAttribute('id', 'outer-host');
- outerhost.appendChild(span0);
-
- var s1 = outerhost.createShadowRoot();
-
- var div1 = d.createElement('div');
- var span1 = d.createElement('span');
- span1.setAttribute('id', 'not-top');
- div1.appendChild(span1);
- s1.appendChild(div1);
-
- var span2 = d.createElement('span');
- span2.setAttribute('id', 'top');
- s1.appendChild(span2);
-
-
- var innerhost = d.createElement('div');
- innerhost.setAttribute('id', 'bar-host');
- var span3 = d.createElement('span');
- span3.setAttribute('id', 'inner-host');
- innerhost.appendChild(span3);
-
- var s2 = innerhost.createShadowRoot();
-
- var span4 = d.createElement('span');
- span4.setAttribute('id', 'nested');
- s2.appendChild(span4);
- s1.appendChild(innerhost);
-
- d.body.appendChild(outerhost);
-
-
- assert_equals(s1.querySelectorAll('* /deep/ span').length, 3, 'Point 1: match only in the inner shadow tree');
- assert_equals(s1.querySelectorAll('* /deep/ span')[0], span1, 'Point 2: incorrect match');
- assert_equals(s1.querySelectorAll('* /deep/ span')[1], span4, 'Point 4: incorrect match');
- assert_equals(s1.querySelectorAll('* /deep/ span')[2], span3, 'Point 5: incorrect match');
- }), 'SD_SHADOW_DEEP_QUERYSELECTOR_T2');
-
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- var outerhost = d.createElement('div');
- outerhost.setAttribute('id', 'foo-host');
- var span0 = d.createElement('span');
- span0.setAttribute('id', 'outer-host');
- outerhost.appendChild(span0);
-
- var s1 = outerhost.createShadowRoot();
-
- var div1 = d.createElement('div');
- var span1 = d.createElement('span');
- span1.setAttribute('id', 'not-top');
- div1.appendChild(span1);
- s1.appendChild(div1);
-
- var span2 = d.createElement('span');
- span2.setAttribute('id', 'top');
- s1.appendChild(span2);
-
-
- var innerhost = d.createElement('div');
- innerhost.setAttribute('id', 'bar-host');
- var span3 = d.createElement('span');
- span3.setAttribute('id', 'inner-host');
- innerhost.appendChild(span3);
-
- var s2 = innerhost.createShadowRoot();
-
- var span4 = d.createElement('span');
- span4.setAttribute('id', 'nested');
- s2.appendChild(span4);
- s1.appendChild(innerhost);
-
- d.body.appendChild(outerhost);
-
-
- assert_equals(s2.querySelectorAll('* /deep/ span').length, 0, 'Point 1: no match');
- }), 'SD_SHADOW_DEEP_QUERYSELECTOR_T3');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html
index abef32a1811..01db057ae2e 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/not-apply-in-shadow-root-001.html
@@ -15,7 +15,7 @@ policies and contribution forms [3].
<link rel="author" title="Kazuhito Hokamura" href="mailto:k.hokamura@gmail.com">
<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#styles">
<meta name="assert" content="Styles: CSS rules declared in an enclosing tree must not apply in a shadow tree if apply-author-styles flag is not set.">
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
<style>
div {
width: 100px;
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/shadow-pseudoelement/shadow-pseudoelement-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/shadow-pseudoelement/shadow-pseudoelement-001.html
deleted file mode 100644
index 0edc78e8afd..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/shadow-pseudoelement/shadow-pseudoelement-001.html
+++ /dev/null
@@ -1,150 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: ::shadow pseudo element</title>
-<link rel="author" title="Kenji Baheux" href="mailto:kenjibaheux@google.com">
-<link rel="help" href="http://dev.w3.org/csswg/css-scoping/#shadow-pseudoelement">
-<meta name="assert" content="::shadow should match a shadow root">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- var outerhost = d.createElement('div');
- outerhost.setAttribute('id', 'foo-host');
- var span0 = d.createElement('span');
- span0.setAttribute('id', 'outer-host');
- outerhost.appendChild(span0);
-
- var s1 = outerhost.createShadowRoot();
-
- var div1 = d.createElement('div');
- var span1 = d.createElement('span');
- span1.setAttribute('id', 'not-top');
- div1.appendChild(span1);
- s1.appendChild(div1);
-
- var span2 = d.createElement('span');
- span2.setAttribute('id', 'top');
- s1.appendChild(span2);
-
-
- var innerhost = d.createElement('div');
- innerhost.setAttribute('id', 'bar-host');
- var span3 = d.createElement('span');
- span3.setAttribute('id', 'inner-host');
- innerhost.appendChild(span3);
-
- var s2 = innerhost.createShadowRoot();
-
- var span4 = d.createElement('span');
- span4.setAttribute('id', 'nested');
- s2.appendChild(span4);
- s1.appendChild(innerhost);
-
- d.body.appendChild(outerhost);
-
- assert_equals(d.querySelectorAll('#foo-host::shadow span').length, 3, 'Point 1: match only direct children of the outer shadow tree');
- assert_equals(d.querySelectorAll('#foo-host::shadow span')[0], span1, 'Point 2: incorrect match');
- assert_equals(d.querySelectorAll('#foo-host::shadow span')[1], span2, 'Point 3: incorrect match');
- assert_equals(d.querySelectorAll('#foo-host::shadow span')[2], span3, 'Point 4: incorrect match');
- }), 'SD_SHADOW_PSEUDOELEMENT_QUERYSELECTOR_T1');
-
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- var outerhost = d.createElement('div');
- outerhost.setAttribute('id', 'foo-host');
- var span0 = d.createElement('span');
- span0.setAttribute('id', 'outer-host');
- outerhost.appendChild(span0);
-
- var s1 = outerhost.createShadowRoot();
-
- var div1 = d.createElement('div');
- var span1 = d.createElement('span');
- span1.setAttribute('id', 'not-top');
- div1.appendChild(span1);
- s1.appendChild(div1);
-
- var span2 = d.createElement('span');
- span2.setAttribute('id', 'top');
- s1.appendChild(span2);
-
-
- var innerhost = d.createElement('div');
- innerhost.setAttribute('id', 'bar-host');
- var span3 = d.createElement('span');
- span3.setAttribute('id', 'inner-host');
- innerhost.appendChild(span3);
-
- var s2 = innerhost.createShadowRoot();
-
- var span4 = d.createElement('span');
- span4.setAttribute('id', 'nested');
- s2.appendChild(span4);
- s1.appendChild(innerhost);
-
- d.body.appendChild(outerhost);
-
- assert_equals(s1.querySelectorAll('*::shadow span').length, 1, 'Point 1: match only in the inner shadow tree');
- assert_equals(s1.querySelectorAll('*::shadow span')[0], span4, 'Point 2: incorrect match');
- }), 'SD_SHADOW_PSEUDOELEMENT_QUERYSELECTOR_T2');
-
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- var outerhost = d.createElement('div');
- outerhost.setAttribute('id', 'foo-host');
- var span0 = d.createElement('span');
- span0.setAttribute('id', 'outer-host');
- outerhost.appendChild(span0);
-
- var s1 = outerhost.createShadowRoot();
-
- var div1 = d.createElement('div');
- var span1 = d.createElement('span');
- span1.setAttribute('id', 'not-top');
- div1.appendChild(span1);
- s1.appendChild(div1);
-
- var span2 = d.createElement('span');
- span2.setAttribute('id', 'top');
- s1.appendChild(span2);
-
-
- var innerhost = d.createElement('div');
- innerhost.setAttribute('id', 'bar-host');
- var span3 = d.createElement('span');
- span3.setAttribute('id', 'inner-host');
- innerhost.appendChild(span3);
-
- var s2 = innerhost.createShadowRoot();
-
- var span4 = d.createElement('span');
- span4.setAttribute('id', 'nested');
- s2.appendChild(span4);
- s1.appendChild(innerhost);
-
- d.body.appendChild(outerhost);
-
- assert_equals(s2.querySelectorAll('*::shadow span').length, 0, 'Point 1: no match');
- }), 'SD_SHADOW_PSEUDOELEMENT_QUERYSELECTOR_T3');
-
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-001.html
index d7a59759ab8..681430a1427 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Styles: CSS rules declared in an enclosing tree must not apply in a shadow tree if apply-author-styles flag is set to false for this tree">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -27,25 +28,25 @@ test(unit(function (ctx) {
var d = newRenderedHTMLDocument(ctx);
d.head.innerHTML = '<style>' +
- '.invis {' +
- 'display:none;' +
- '}' +
- '</style>';
+ '.invis {' +
+ 'display:none;' +
+ '}' +
+ '</style>';
var host = d.createElement('div');
d.body.appendChild(host);
- //Shadow root to play with
- var s = host.createShadowRoot();
+ //Shadow root to play with
+ var s = host.createShadowRoot();
- var div1 = d.createElement('div');
- div1.innerHTML ='<span id="shd" class="invis">This is the shadow tree</span>';
- s.appendChild(div1);
+ var div1 = d.createElement('div');
+ div1.innerHTML ='<span id="shd" class="invis">This is the shadow tree</span>';
+ s.appendChild(div1);
- //apply-author-styles flag is false by default. Invisible style shouldn't be applied
- assert_true(s.querySelector('#shd').offsetTop > 0,
- 'CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
- 'if the apply-author-styles flag is set to false');
+ //apply-author-styles flag is false by default. Invisible style shouldn't be applied
+ assert_true(s.querySelector('#shd').offsetTop > 0,
+ 'CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
+ 'if the apply-author-styles flag is set to false');
}), 'A_06_00_01_T01');
@@ -57,115 +58,28 @@ test(unit(function (ctx) {
var d = newRenderedHTMLDocument(ctx);
d.head.innerHTML = '<style>' +
- '.invis {' +
- 'display:none;' +
- '}' +
- '</style>';
+ '.invis {' +
+ 'display:none;' +
+ '}' +
+ '</style>';
var host = d.createElement('div');
d.body.appendChild(host);
- //Shadow root to play with
- var s = host.createShadowRoot();
+ //Shadow root to play with
+ var s = host.createShadowRoot();
- var div1 = d.createElement('div');
- div1.innerHTML ='<span id="shd" class="invis">This is the shadow tree</span>';
- s.appendChild(div1);
+ var div1 = d.createElement('div');
+ div1.innerHTML ='<span id="shd" class="invis">This is the shadow tree</span>';
+ s.appendChild(div1);
- //apply-author-styles flag is set to false. Invisible style shouldn't be applied
- assert_true(s.querySelector('#shd').offsetTop > 0,
- 'CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
- 'if the apply-author-styles flag is set to false');
+ //apply-author-styles flag is set to false. Invisible style shouldn't be applied
+ assert_true(s.querySelector('#shd').offsetTop > 0,
+ 'CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
+ 'if the apply-author-styles flag is set to false');
}), 'A_06_00_01_T02');
-
-//test apply-author-styles flag in a nested tree (default value)
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.head.innerHTML = '<style>' +
- '.invis {' +
- 'display:none;' +
- '}' +
- '</style>';
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- //Shadow root to play with
- var s1 = host.createShadowRoot();
-
- var div1 = d.createElement('div');
- div1.innerHTML = '<span id="shd1" class="invis">This is an old shadow tree</span>';
- s1.appendChild(div1);
-
- //younger tree
- var s2 = host.createShadowRoot();
- var div1 = d.createElement('div');
- div1.innerHTML = '<span id="shd2" class="invis">This is a young shadow tree</span>' +
- '<shadow><span id="shd3" class="invis">This is the shadow tree fallback content</span></shadow>';
- s2.appendChild(div1);
-
-
- //apply-author-styles flag is false by default. Invisible style shouldn't be applied
- //shd1 and shd2 should be visible. sh3 not because the tree should be active
- assert_true(s1.querySelector('#shd1').offsetTop > 0,
- 'Point 1: CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
- 'if the apply-author-styles flag is set to false');
- assert_true(s2.querySelector('#shd2').offsetTop > 0,
- 'Point 2: CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
- 'if the apply-author-styles flag is set to false');
- assert_equals(s2.querySelector('#shd3').offsetTop, 0,
- 'Fallback content shouldn\'t be rendered for active tree');
-
-
-}), 'A_06_00_01_T03');
-
-
-//test apply-author-styles flag in a nested tree (set it)
-test(unit(function (ctx) {
-
- var d = newRenderedHTMLDocument(ctx);
-
- d.head.innerHTML = '<style>' +
- '.invis {' +
- 'display:none;' +
- '}' +
- '</style>';
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- //Shadow root to play with
- var s1 = host.createShadowRoot();
-
- var div1 = d.createElement('div');
- div1.innerHTML = '<span id="shd1" class="invis">This is an old shadow tree</span>';
- s1.appendChild(div1);
-
- //younger tree
- var s2 = host.createShadowRoot();
- var div1 = d.createElement('div');
- div1.innerHTML = '<span id="shd2" class="invis">This is a young shadow tree</span>' +
- '<shadow><span id="shd3" class="invis">This is the shadow tree fallback content</span></shadow>';
- s2.appendChild(div1);
-
-
- //apply-author-styles flag is set to false. Invisible style shouldn't be applied
- //shd1 and shd2 should be visible. sh3 not because the tree should be active
- assert_true(s1.querySelector('#shd1').offsetTop > 0,
- 'Point 1: CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
- 'if the apply-author-styles flag is set to false');
- assert_true(s2.querySelector('#shd2').offsetTop > 0,
- 'Point 2: CSS styles declared in enclosing tree must not be applied in a shadow tree ' +
- 'if the apply-author-styles flag is set to false');
- assert_equals(s2.querySelector('#shd3').offsetTop, 0,
- 'Fallback content shouldn\'t be rendered for active tree');
-
-
-}), 'A_06_00_01_T04');
</script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-003.html
index 7e18934d59c..bac7006a657 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="Styles: Each shadow root has an associated list of zero or more style sheets, named shadow root style sheets">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -42,7 +43,7 @@ test(unit(function (ctx) {
//Shadow root to play with
var s = host.createShadowRoot();
- assert_equals(s.styleSheets.length, 0, 'There should be no style sheets');
+ assert_equals(s.styleSheets.length, 0, 'There should be no style sheets');
}), 'A_06_00_03_T02');
//TODO Now this tests produces an error on Chromium because styleSheets.length
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-005.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-005.html
index f5eaeabb8a1..faba0a20a31 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-005.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-005.html
@@ -16,45 +16,46 @@ policies and contribution forms [3].
<meta name="assert" content="Styles:CSS rules declared in a shadow root style sheets must not apply in the document tree,">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
//check querySelector method
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
d.body.innerHTML =
- '<div>' +
- '<span class="invis" id="theTreeSpan">This is an element in the document tree</span>' +
- '</div>' +
- '<div id="sr">' +
- '</div>';
-
- var host = d.querySelector('#sr');
-
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var style = d.createElement('style');
- style.innerHTML ='.invis {display:none}';
- s.appendChild(style);
-
- var span = d.createElement('span');
- span.setAttribute('id', 'theShadowSpan');
- span.setAttribute('class', 'invis');
- s.appendChild(span);
-
- //theTreeSpan should be visible, theShadowSpan not
- assert_true(d.querySelector('#theTreeSpan').offsetTop > 0,
- 'CSS styles declared in shadow tree must not be applied to the elements ' +
- 'in the document tree');
-
- //theTreeSpan should be visible, theShadowSpan not
- assert_equals(s.querySelector('#theShadowSpan').offsetTop, 0,
- 'CSS styles declared in shadow tree must be applied to the element ' +
- 'in the same shadow tree');
+ '<div>' +
+ '<span class="invis" id="theTreeSpan">This is an element in the document tree</span>' +
+ '</div>' +
+ '<div id="sr">' +
+ '</div>';
+
+ var host = d.querySelector('#sr');
+
+ //Shadow root to play with
+ var s = host.createShadowRoot();
+
+ var style = d.createElement('style');
+ style.innerHTML ='.invis {display:none}';
+ s.appendChild(style);
+
+ var span = d.createElement('span');
+ span.setAttribute('id', 'theShadowSpan');
+ span.setAttribute('class', 'invis');
+ s.appendChild(span);
+
+ //theTreeSpan should be visible, theShadowSpan not
+ assert_true(d.querySelector('#theTreeSpan').offsetTop > 0,
+ 'CSS styles declared in shadow tree must not be applied to the elements ' +
+ 'in the document tree');
+
+ //theTreeSpan should be visible, theShadowSpan not
+ assert_equals(s.querySelector('#theShadowSpan').offsetTop, 0,
+ 'CSS styles declared in shadow tree must be applied to the element ' +
+ 'in the same shadow tree');
}), 'A_06_00_06_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-007.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-007.html
deleted file mode 100644
index d29f1f6c615..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-007.html
+++ /dev/null
@@ -1,133 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_06_00_08</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#styles">
-<meta name="assert" content="Styles:The @host @-rule matches a shadow host in the nesting tree.">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-// The some of the tests below fails.
-// See https://bugs.webkit.org/show_bug.cgi?id=103608
-
-
-
-//Test fails. See https://bugs.webkit.org/show_bug.cgi?id=103608
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- d.head.innerHTML = ':host {display:none;}';
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML ='<ul><content select=".shadow"></content></ul>';
- s.appendChild(div);
-
- //:host rule shouldn't take any effect
- assert_true(d.querySelector('#li1').offsetTop > 0,
- 'Point 1: element should be rendered');
- assert_true(d.querySelector('#li3').offsetTop > 0,
- 'Point 2: element should be rendered');
- assert_true(d.querySelector('#li5').offsetTop > 0,
- 'Point 3: element should be rendered');
-
-
-}), 'A_06_00_08_T01');
-
-//TODO (sgrekhov) Check the expected result at https://www.w3.org/Bugs/Public/show_bug.cgi?id=20150
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML ='<ul><content select=".shadow"></content></ul>';
- s.appendChild(div);
-
- var style = d.createElement('style');
- style.innerHTML = ':host ul {display:none;}';
- s.appendChild(style);
-
- assert_equals(d.querySelector('#li1').offsetTop, 0,
- 'Point 1: element should be rendered');
- assert_equals(d.querySelector('#li3').offsetTop, 0,
- 'Point 2: element should be rendered');
- assert_equals(d.querySelector('#li5').offsetTop, 0,
- 'Point 3: element should be rendered');
-
-
-}), 'A_06_00_08_T02');
-
-
-//Test fails. See https://bugs.webkit.org/show_bug.cgi?id=103608
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- host.className = 'gone';
- d.body.appendChild(host);
-
- //Older tree
- var s1 = host.createShadowRoot();
- var div1 = d.createElement('div');
- div1.innerHTML = '<span id="shd1">This is an old shadow tree</span>';
- s1.appendChild(div1);
-
- //Younger tree
- var s2 = host.createShadowRoot();
- var div1 = d.createElement('div');
- div1.innerHTML = '<span id="shd2">This is a young shadow tree</span>' +
- '<shadow><span id="shd3">This is the shadow tree fallback content</span></shadow>';
- s2.appendChild(div1);
-
- var style = d.createElement('style');
- style.innerHTML = ':host {display:none;}';
- s2.appendChild(style);
-
- assert_equals(s1.querySelector('#shd1').offsetTop, 0,
- 'Point 1: element should not be rendered');
-
-
-}), 'A_06_00_08_T03');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-008.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-008.html
index 7f9b0c7311b..733b80fe2aa 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-008.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-008.html
@@ -16,80 +16,41 @@ policies and contribution forms [3].
<meta name="assert" content="Styles:the styles of the shadow host are inherited by the children of the shadow root">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
d.body.innerHTML = '' +
- '<div id="shHost" style="font-size:10px">' +
- '<span id="spn1">This is a shadow host child</span>' +
- '</div>';
+ '<div id="shHost" style="font-size:10px">' +
+ '<span id="spn1">This is a shadow host child</span>' +
+ '</div>';
var host = d.querySelector('#shHost');
- var s = host.createShadowRoot();
+ var s = host.createShadowRoot();
- var div = d.createElement('div');
- div.innerHTML ='<span id="spn2">This is a shadow root child</span>';
- s.appendChild(div);
+ var div = d.createElement('div');
+ div.innerHTML ='<span id="spn2">This is a shadow root child</span>';
+ s.appendChild(div);
- assert_equals(d.querySelector('#spn1').offsetTop, 0,
- 'Element should not be rendered');
- assert_true(s.querySelector('#spn2').offsetTop > 0,
- 'Element should be rendered');
+ assert_equals(d.querySelector('#spn1').offsetTop, 0,
+ 'Element should not be rendered');
+ assert_true(s.querySelector('#spn2').offsetTop > 0,
+ 'Element should be rendered');
- var oldHeight = s.querySelector('#spn2').offsetHeight;
+ var oldHeight = s.querySelector('#spn2').offsetHeight;
- host.setAttribute('style', 'font-size:20px');
+ host.setAttribute('style', 'font-size:20px');
- assert_true(s.querySelector('#spn2').offsetHeight > oldHeight,
- 'Shadow host style must be aplied to the shadow root children');
+ assert_true(s.querySelector('#spn2').offsetHeight > oldHeight,
+ 'Shadow host style must be aplied to the shadow root children');
}), 'A_06_00_09_T01');
-
-
-
-
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls" style="font-size: 10px">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML ='<ul><content select=".shadow"></content></ul>';
- s.appendChild(div);
-
- var height1 = d.querySelector('#li1').offsetHeight;
- var height3 = d.querySelector('#li3').offsetHeight;
- var height5 = d.querySelector('#li5').offsetHeight;
-
- host.setAttribute('style', 'font-size: 20px');
-
- assert_true(d.querySelector('#li1').offsetHeight > height1,
- 'Point 1: Shadow host style must be aplied to the shadow root children');
- assert_true(d.querySelector('#li3').offsetHeight > height3,
- 'Point 2: Shadow host style must be aplied to the shadow root children');
- assert_true(d.querySelector('#li5').offsetHeight > height5,
- 'Point 3: Shadow host style must be aplied to the shadow root children');
-
-
-}), 'A_06_00_09_T02');
</script>
</body>
</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-009.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-009.html
deleted file mode 100644
index 63f6aa40a65..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-009.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE html>
-<!--
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
--->
-<html>
-<head>
-<title>Shadow DOM Test: A_06_00_10</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="help" href="http://www.w3.org/TR/2013/WD-shadow-dom-20130514/#styles">
-<meta name="assert" content="Styles:the styles of the insertion point nodes are inherited by those child nodes of the shadow host that are assigned to this insertion point">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-</head>
-<body>
-<div id="log"></div>
-<script>
-test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
-
- d.body.innerHTML =
- '<ul class="cls" style="font-size: 10px">' +
- '<li id="li1" class="shadow">1</li>' +
- '<li id="li2" class="shadow2">2</li>' +
- '<li id="li3" class="shadow">3</li>' +
- '<li id="li4">4</li>' +
- '<li id="li5" class="shadow">5</li>' +
- '<li id="li6" class="shadow2">6</li>' +
- '</ul>';
-
-
- var height1 = d.querySelector('#li1').offsetHeight;
- var height2 = d.querySelector('#li2').offsetHeight;
- var height3 = d.querySelector('#li3').offsetHeight;
- var height4 = d.querySelector('#li4').offsetHeight;
- var height5 = d.querySelector('#li5').offsetHeight;
- var height6 = d.querySelector('#li6').offsetHeight;
-
- assert_true(height1 > 0, 'Point 1: Element height should be greater than zero');
- assert_true(height2 > 0, 'Point 2: Element height should be greater than zero');
- assert_true(height3 > 0, 'Point 3: Element height should be greater than zero');
- assert_true(height4 > 0, 'Point 4: Element height should be greater than zero');
- assert_true(height5 > 0, 'Point 5: Element height should be greater than zero');
- assert_true(height6 > 0, 'Point 6: Element height should be greater than zero');
-
- var host = d.querySelector('.cls');
- //Shadow root to play with
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML ='<ul><content select=".shadow" style="font-size:20px"></content></ul>';
- s.appendChild(div);
-
-
- host.setAttribute('style', 'font-size: 20px');
-
- assert_true(d.querySelector('#li1').offsetHeight > height1,
- 'Point 11: Insertion point style must be aplied to the node distributed into this point');
- assert_true(d.querySelector('#li3').offsetHeight > height3,
- 'Point 12: Insertion point style must be aplied to the node distributed into this point');
- assert_true(d.querySelector('#li5').offsetHeight > height5,
- 'Point 13: Insertion point style must be aplied to the node distributed into this point');
-
-}), 'A_06_00_10_T01');
-</script>
-</body>
-</html>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-010.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-010.html
index 9da81ffd086..69a1c7bf196 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-010.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/styles/test-010.html
@@ -16,39 +16,40 @@ policies and contribution forms [3].
<meta name="assert" content="Styles:the styles of the shadow insertion point node are inherited by the child nodes of the shadow root of the shadow tree, distributed to this shadow insertion point">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
+<script src="../../../html/resources/common.js"></script>
+<script src="../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
// Test fails. See https://bugs.webkit.org/show_bug.cgi?id=103625
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
var host = d.createElement('div');
d.body.appendChild(host);
- //Old tree
- var s1 = host.createShadowRoot();
+ //Old tree
+ var s1 = host.createShadowRoot();
- var div1 = d.createElement('div');
- div1.setAttribute('style', 'font-size: 10px');
- div1.innerHTML = '<span id="shd1">This is an old shadow tree</span>';
- s1.appendChild(div1);
+ var div1 = d.createElement('div');
+ div1.setAttribute('style', 'font-size: 10px');
+ div1.innerHTML = '<span id="shd1">This is an old shadow tree</span>';
+ s1.appendChild(div1);
- var height1 = s1.querySelector('#shd1').offsetHeight;
+ var height1 = s1.querySelector('#shd1').offsetHeight;
- assert_true(height1 > 0, 'Element height should be greater than zero');
+ assert_true(height1 > 0, 'Element height should be greater than zero');
- //younger tree
- var s2 = host.createShadowRoot();
- var div2 = d.createElement('div');
- div2.innerHTML = '<shadow style="font-size:20px"></shadow>';
- s2.appendChild(div2);
+ //younger tree
+ var s2 = host.createShadowRoot();
+ var div2 = d.createElement('div');
+ div2.innerHTML = '<shadow style="font-size:20px"></shadow>';
+ s2.appendChild(div2);
- assert_true(s1.querySelector('#shd1').offsetHeight > height1,
- 'Shadow insertion point style must be aplied to the child nodes of ' +
- 'the shadow host that are assigned to this insertion point');
+ assert_true(s1.querySelector('#shd1').offsetHeight > height1,
+ 'Shadow insertion point style must be aplied to the child nodes of ' +
+ 'the shadow host that are assigned to this insertion point');
}), 'A_06_00_11_T01');
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/testcommon.js b/tests/wpt/web-platform-tests/shadow-dom/untriaged/testcommon.js
deleted file mode 100644
index cce78e9c2d8..00000000000
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/testcommon.js
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2012 Google Inc. All Rights Reserved.
-
-/*
-Distributed under both the W3C Test Suite License [1] and the W3C
-3-clause BSD License [2]. To contribute to a W3C Test Suite, see the
-policies and contribution forms [3].
-
-[1] http://www.w3.org/Consortium/Legal/2008/04-testsuite-license
-[2] http://www.w3.org/Consortium/Legal/2008/03-bsd-license
-[3] http://www.w3.org/2004/10/27-testcases
-*/
-
-"use strict";
-
-var HTML5_ELEMENT_NAMES = [
- 'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio',
- 'b', 'base', 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button',
- 'canvas', 'caption', 'cite', 'code', 'col', 'colgroup', 'command',
- 'datalist', 'dd', 'del', 'details', 'dfn', 'dialog', 'div', 'dl', 'dt',
- 'em', 'embed',
- 'fieldset', 'figcaption', 'figure', 'footer', 'form',
- 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr',
- 'html',
- 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen',
- 'label', 'legend', 'li', 'link',
- 'map', 'mark', 'menu', 'meta', 'meter',
- 'nav', 'noscript',
- 'object', 'ol', 'optgroup', 'option', 'output',
- 'p', 'param', 'pre', 'progress',
- 'q',
- 'rp', 'rt', 'ruby',
- 's', 'samp', 'script', 'section', 'select', 'small', 'source', 'span',
- 'strong', 'style', 'sub',
- 'table', 'tbody', 'td', 'textarea', 'tfoot', 'th', 'thead', 'time',
- 'title', 'tr', 'track',
- 'u', 'ul',
- 'var', 'video',
- 'wbr'
-];
-
-// http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#form-associated-element
-var HTML5_FORM_ASSOCIATED_ELEMENTS = ['button', 'fieldset', 'input', 'keygen', 'label',
- 'object', 'output', 'select', 'textarea'];
-
-// Whether to work around vendor prefixes.
-var USE_VENDOR_SPECIFIC_WORKAROUND = true;
-
-function activateVendorSpecificWorkaround() {
- if (Element.prototype.webkitCreateShadowRoot &&
- !Element.prototype.createShadowRoot) {
- Element.prototype.createShadowRoot =
- Element.prototype.webkitCreateShadowRoot;
-
- Object.defineProperty(Element.prototype, 'pseudo', {
- get: function () { return this.webkitPseudo; },
- set: function (value) { return this.webkitPseudo = value; }
- });
-
- Object.defineProperty(Element.prototype, 'shadowRoot', {
- get: function () { return this.webkitShadowRoot; }
- });
- }
-}
-
-if (USE_VENDOR_SPECIFIC_WORKAROUND)
- activateVendorSpecificWorkaround();
-
-// ----------------------------------------------------------------------------
-// Deprecated: The code below is preserved only for the existing tests that are
-// using it. Now vendor prefixes are handled in a way that does not require
-// manual intervention. New tests should just use unprefixed APIs and you
-// are all set.
-//
-// These functions will eventually be removed when no tests use them.
-
-function ShadowDomNotSupportedError() {
- this.message = "Shadow DOM is not supported";
-}
-
-// To allow using of both prefixed and non-prefixed API we do
-// the following hook
-function addPrefixed(element) {
- if (element && !element.pseudo) {
- Object.defineProperty(element, 'pseudo', {
- get: function () { return element.webkitPseudo; },
- set: function (value) { return element.webkitPseudo = value; }
- });
- }
-}
-
-function addDocumentPrefixed(d) {
- if (d) {
- if (d.body) {
- addPrefixed(d.body);
- }
- if (d.head) {
- addPrefixed(d.head);
- }
- if (d.documentElement) {
- addPrefixed(d.documentElement);
- }
- d.oldCreate = d.createElement;
- d.createElement = function(tagName) {
- var el = d.oldCreate(tagName);
- addPrefixed(el);
- return el;
- };
- }
-}
-
-
-function rethrowInternalErrors(e) {
- if (e instanceof ShadowDomNotSupportedError) {
- throw e;
- }
-
-}
-
-function newDocument() {
- var d = document.implementation.createDocument(
- 'http://www.w3.org/1999/xhtml', 'html');
- //FIXME remove the call below when non-prefixed API is used
- addDocumentPrefixed(d);
- return d;
-}
-
-function newHTMLDocument() {
- var d = document.implementation.createHTMLDocument('Test Document');
- //FIXME remove the call below when non-prefixed API is used
- addDocumentPrefixed(d);
- return d;
-}
-
-function newIFrame(ctx, src) {
- if (typeof(ctx) == 'undefined' || typeof (ctx.iframes) != 'object') {
- assert_unreached('Illegal context object in newIFrame');
- }
-
- var iframe = document.createElement('iframe');
- if (!ctx.debug) {
- iframe.style.display = 'none';
- }
- if (typeof(src) != 'undefined') {
- iframe.src = src;
- }
- document.body.appendChild(iframe);
- ctx.iframes.push(iframe);
-
- assert_true(typeof(iframe.contentWindow) != 'undefined'
- && typeof(iframe.contentWindow.document) != 'undefined'
- && iframe.contentWindow.document != document, 'Failed to create new rendered document'
- );
- return iframe;
-}
-function newRenderedHTMLDocument(ctx) {
- var frame = newIFrame(ctx);
- var d = frame.contentWindow.document;
- //FIXME remove the call below when non-prefixed API is used
- addDocumentPrefixed(d);
- return d;
-}
-
-// End deprecated.
-// ----------------------------------------------------------------------------
-
-function newContext() {
- return {iframes:[]};
-}
-
-function cleanContext(ctx) {
- if (!ctx.debug) {
- ctx.iframes.forEach(function (e) {
- e.parentNode.removeChild(e);
- });
- }
-}
-
-function unit(f) {
- return function () {
- var ctx = newContext();
- try {
- f(ctx);
- } finally {
- cleanContext(ctx);
- }
- }
-}
-
-function step_unit(f, ctx, t) {
- return function () {
- var done = false;
- try {
- f();
- done = true;
- } finally {
- if (done) {
- t.done();
- }
- cleanContext(ctx);
- }
- }
-}
-
-function assert_nodelist_contents_equal_noorder(actual, expected, message) {
- assert_equals(actual.length, expected.length, message);
- var used = [];
- for (var i = 0; i < expected.length; i++) {
- used.push(false);
- }
- for (i = 0; i < expected.length; i++) {
- var found = false;
- for (var j = 0; j < actual.length; j++) {
- if (used[j] == false && expected[i] == actual[j]) {
- used[j] = true;
- found = true;
- break;
- }
- }
- if (!found) {
- assert_unreached(message + ". Fail reason: element not found: " + expected[i]);
- }
- }
-}
-
-
-//Example taken from http://www.w3.org/TR/shadow-dom/#event-retargeting-example
-function createTestMediaPlayer(d) {
- d.body.innerHTML = '' +
- '<div id="player">' +
- '<input type="checkbox" id="outside-control">' +
- '<div id="player-shadow-host">' +
- '</div>' +
- '</div>';
-
- var playerShadowRoot = d.querySelector('#player-shadow-host').createShadowRoot();
- playerShadowRoot.innerHTML = '' +
- '<div id="controls">' +
- '<button class="play-button">PLAY</button>' +
- '<div tabindex="0" id="timeline">' +
- '<div id="timeline-shadow-host">' +
- '</div>' +
- '</div>' +
- '<div class="volume-slider-container" id="volume-slider-container">' +
- '<div tabindex="0" class="volume-slider" id="volume-slider">' +
- '<div id="volume-shadow-host">' +
- '</div>' +
- '</div>' +
- '</div>' +
- '</div>';
-
- var timeLineShadowRoot = playerShadowRoot.querySelector('#timeline-shadow-host').createShadowRoot();
- timeLineShadowRoot.innerHTML = '<div class="slider-thumb" id="timeline-slider-thumb"></div>';
-
- var volumeShadowRoot = playerShadowRoot.querySelector('#volume-shadow-host').createShadowRoot();
- volumeShadowRoot.innerHTML = '<div class="slider-thumb" id="volume-slider-thumb"></div>';
-
- return {
- 'playerShadowRoot': playerShadowRoot,
- 'timeLineShadowRoot': timeLineShadowRoot,
- 'volumeShadowRoot': volumeShadowRoot
- };
-}
-
-//FIXME This call of initKeyboardEvent works for WebKit-only.
-//See https://bugs.webkit.org/show_bug.cgi?id=16735
-// and https://bugs.webkit.org/show_bug.cgi?id=13368. Add check for browser here
-function fireKeyboardEvent(doc, element, key) {
- var event = doc.createEvent('KeyboardEvent');
- event.initKeyboardEvent("keydown", true, true, doc.defaultView, key, 0, false, false, false, false);
- element.dispatchEvent(event);
-}
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-001.html
index 25c548b0cb7..6d9850b3497 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-001.html
@@ -16,30 +16,31 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: each shadow root must also have an activeElement property to store the value of the focused element in the shadow tree.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var inp = d.createElement('input');
- inp.setAttribute('type', 'text');
- inp.setAttribute('id', 'inpId');
- inp.setAttribute('value', 'Some text');
- s.appendChild(inp);
+ var inp = d.createElement('input');
+ inp.setAttribute('type', 'text');
+ inp.setAttribute('id', 'inpId');
+ inp.setAttribute('value', 'Some text');
+ s.appendChild(inp);
- inp.focus();
+ inp.focus();
assert_equals(s.activeElement.tagName, 'INPUT', 'Point 1:activeElement property of shadow root ' +
- 'must return the value of the focused element in the shadow tree');
+ 'must return the value of the focused element in the shadow tree');
assert_equals(s.activeElement.getAttribute('id'), 'inpId', 'Point 2:activeElement property of shadow root ' +
- 'must return the value of the focused element in the shadow tree');
+ 'must return the value of the focused element in the shadow tree');
}), 'A_07_03_01_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-002.html
index 79081843569..9019760b7d8 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/active-element/test-002.html
@@ -16,31 +16,32 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: Document's activeElement property must be adjusted">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- host.setAttribute('id', 'shRoot');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ host.setAttribute('id', 'shRoot');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var inp = d.createElement('input');
- inp.setAttribute('type', 'text');
- inp.setAttribute('id', 'inpId');
- inp.setAttribute('value', 'Some text');
- s.appendChild(inp);
+ var inp = d.createElement('input');
+ inp.setAttribute('type', 'text');
+ inp.setAttribute('id', 'inpId');
+ inp.setAttribute('value', 'Some text');
+ s.appendChild(inp);
- inp.focus();
+ inp.focus();
assert_equals(d.activeElement.tagName, 'DIV', 'Point 1: document\'s activeElement property ' +
- 'must return adjusted the value of the focused element in the shadow tree');
+ 'must return adjusted the value of the focused element in the shadow tree');
assert_equals(d.activeElement.getAttribute('id'), 'shRoot', 'Point 2: document\'s activeElement property ' +
- 'must return adjusted the value of the focused element in the shadow tree');
+ 'must return adjusted the value of the focused element in the shadow tree');
}), 'A_07_03_02_T01');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/editing/inheritance-of-content-editable-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/editing/inheritance-of-content-editable-001.html
index c22aab32c86..52f53551c6e 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/editing/inheritance-of-content-editable-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/editing/inheritance-of-content-editable-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: Shadow trees must not be propagated contentEditable attribute from shadow host">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-001.html
index d751f47de7c..b19f10a9539 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-001.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: The navigation order within a shadow tree must be computed as a list of focusable elements in tree order as-rendered">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -25,60 +26,60 @@ var A_07_02_01_T01 = async_test('A_07_02_01_T01');
A_07_02_01_T01.step(unit(function (ctx) {
- var counter = 0;
+ var counter = 0;
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- chb1.setAttribute('id', 'chb1');
- chb1.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
- }), false);
- d.body.appendChild(chb1);
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ chb1.setAttribute('id', 'chb1');
+ chb1.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
+ }), false);
+ d.body.appendChild(chb1);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- inp1.setAttribute('value', 'Input 1');
- inp1.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
- }), false);
- s.appendChild(inp1);
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
+ }), false);
+ s.appendChild(inp1);
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- inp2.setAttribute('value', 'Input 2');
- inp2.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
- }), false);
- s.appendChild(inp2);
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
+ }), false);
+ s.appendChild(inp2);
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- chb2.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 4: wrong focus navigation order');
- }), false);
- d.body.appendChild(chb2);
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ chb2.addEventListener('focus', A_07_02_01_T01.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 4: wrong focus navigation order');
+ }), false);
+ d.body.appendChild(chb2);
- chb1.focus();
+ chb1.focus();
- //simulate TAB clicks
- fireKeyboardEvent(d, chb1, 'U+0009');
+ //simulate TAB clicks
+ fireKeyboardEvent(d, chb1, 'U+0009');
- fireKeyboardEvent(d, inp1, 'U+0009');
+ fireKeyboardEvent(d, inp1, 'U+0009');
- fireKeyboardEvent(d, inp2, 'U+0009');
+ fireKeyboardEvent(d, inp2, 'U+0009');
- fireKeyboardEvent(d, chb2, 'U+0009');
+ fireKeyboardEvent(d, chb2, 'U+0009');
- A_07_02_01_T01.done();
+ A_07_02_01_T01.done();
}));
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-002.html
index 17c52b314a9..e50d4f33462 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-002.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: The navigation order within a shadow tree must be computed as a list of focusable elements in tree order as-rendered with the exception of any elements, distributed its insertion points, and is called shadow DOM navigation order.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -26,99 +27,99 @@ var A_07_02_02_T02 = async_test('A_07_02_02_T02');
A_07_02_02_T01.step(unit(function (ctx) {
- var counter = 0;
-
- var expectations = [];
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- chb1.setAttribute('id', 'chb1');
- chb1.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
- assert_true(false, 'Element shouldn\'t be rendered');
- }), false);
- host.appendChild(chb1);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- chb2.setAttribute('class', 'shadow');
- chb2.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
- expectations[1] = true;
- }), false);
- expectations[1] = false;
- host.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- chb3.setAttribute('class', 'shadow');
- chb3.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
- expectations[2] = true;
- }), false);
- expectations[2] = false;
- host.appendChild(chb3);
-
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '<content select=".shadow"></content>';
- s.appendChild(div);
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- inp1.setAttribute('value', 'Input 1');
- inp1.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
- expectations[3] = false;
- }), false);
- expectations[3] = true;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- inp2.setAttribute('value', 'Input 2');
- inp2.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
- expectations[4] = false;
- }), false);
- expectations[4] = true;
- s.appendChild(inp2);
-
- var chb4 = d.createElement('input');
- chb4.setAttribute('type', 'checkbox');
- chb4.setAttribute('id', 'chb4');
- chb4.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 5: wrong focus navigation order');
- expectations[5] = true;
- }), false);
- expectations[5] = false;
- d.body.appendChild(chb4);
-
- chb2.focus();
-
- //simulate TAB clicks
- fireKeyboardEvent(d, chb2, 'U+0009');
-
- fireKeyboardEvent(d, chb3, 'U+0009');
-
- fireKeyboardEvent(d, inp1, 'U+0009');
-
- fireKeyboardEvent(d, inp2, 'U+0009');
-
- fireKeyboardEvent(d, chb4, 'U+0009');
-
- for (var i = 1; i < expectations.length; i++) {
- if (!expectations[i]) {
- assert_true(false, 'Point ' + i + ' event listener was not invoked');
- }
- }
+ var counter = 0;
+
+ var expectations = [];
+
+ var d = newRenderedHTMLDocument(ctx);
+
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ chb1.setAttribute('id', 'chb1');
+ chb1.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
+ assert_true(false, 'Element shouldn\'t be rendered');
+ }), false);
+ host.appendChild(chb1);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ chb2.setAttribute('class', 'shadow');
+ chb2.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
+ expectations[1] = true;
+ }), false);
+ expectations[1] = false;
+ host.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ chb3.setAttribute('class', 'shadow');
+ chb3.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
+ expectations[2] = true;
+ }), false);
+ expectations[2] = false;
+ host.appendChild(chb3);
+
+ var s = host.createShadowRoot();
+
+ var div = d.createElement('div');
+ div.innerHTML = '<content select=".shadow"></content>';
+ s.appendChild(div);
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
+ expectations[3] = false;
+ }), false);
+ expectations[3] = true;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
+ expectations[4] = false;
+ }), false);
+ expectations[4] = true;
+ s.appendChild(inp2);
+
+ var chb4 = d.createElement('input');
+ chb4.setAttribute('type', 'checkbox');
+ chb4.setAttribute('id', 'chb4');
+ chb4.addEventListener('focus', A_07_02_02_T01.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 5: wrong focus navigation order');
+ expectations[5] = true;
+ }), false);
+ expectations[5] = false;
+ d.body.appendChild(chb4);
+
+ chb2.focus();
+
+ //simulate TAB clicks
+ fireKeyboardEvent(d, chb2, 'U+0009');
+
+ fireKeyboardEvent(d, chb3, 'U+0009');
+
+ fireKeyboardEvent(d, inp1, 'U+0009');
+
+ fireKeyboardEvent(d, inp2, 'U+0009');
+
+ fireKeyboardEvent(d, chb4, 'U+0009');
+
+ for (var i = 1; i < expectations.length; i++) {
+ if (!expectations[i]) {
+ assert_true(false, 'Point ' + i + ' event listener was not invoked');
+ }
+ }
A_07_02_02_T01.done();
}));
@@ -127,108 +128,108 @@ A_07_02_02_T01.step(unit(function (ctx) {
A_07_02_02_T02.step(unit(function (ctx) {
- var counter = 0;
+ var counter = 0;
- var expectations = [];
+ var expectations = [];
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var chb0 = d.createElement('input');
- chb0.setAttribute('type', 'checkbox');
- chb0.setAttribute('id', 'chb0');
+ var chb0 = d.createElement('input');
+ chb0.setAttribute('type', 'checkbox');
+ chb0.setAttribute('id', 'chb0');
d.body.appendChild(chb0);
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- chb1.setAttribute('id', 'chb1');
- chb1.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
- assert_true(false, 'Element shouldn\'t be rendered');
- }), false);
- host.appendChild(chb1);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- chb2.setAttribute('class', 'shadow');
- chb2.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
- expectations[1] = true;
- }), false);
- expectations[1] = false;
- host.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- chb3.setAttribute('class', 'shadow');
- chb3.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 4: wrong focus navigation order');
- expectations[2] = true;
- }), false);
- expectations[2] = false;
- host.appendChild(chb3);
-
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '<content select=".shadow"></content>';
- s.appendChild(div);
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- inp1.setAttribute('value', 'Input 1');
- inp1.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
-
- expectations[3] = true;
- }), false);
- expectations[3] = false;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- inp2.setAttribute('value', 'Input 2');
- inp2.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
- expectations[4] = true;
- }), false);
- expectations[4] = false;
- s.appendChild(inp2);
-
- var chb4 = d.createElement('input');
- chb4.setAttribute('type', 'checkbox');
- chb4.setAttribute('id', 'chb4');
- chb4.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
- assert_equals(counter++, 4, 'Point 5: wrong focus navigation order');
- expectations[5] = true;
- }), false);
- expectations[5] = false;
- d.body.appendChild(chb4);
-
- chb0.focus();
-
- //simulate TAB clicks
- fireKeyboardEvent(d, inp1, 'U+0009');
-
- fireKeyboardEvent(d, inp2, 'U+0009');
-
- fireKeyboardEvent(d, chb2, 'U+0009');
-
- fireKeyboardEvent(d, chb3, 'U+0009');
-
- fireKeyboardEvent(d, chb4, 'U+0009');
-
- for (var i = 1; i < expectations.length; i++) {
- if (!expectations[i]) {
- assert_true(false, 'Point ' + i + ' event listener was not invoked');
- }
- }
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ chb1.setAttribute('id', 'chb1');
+ chb1.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
+ assert_true(false, 'Element shouldn\'t be rendered');
+ }), false);
+ host.appendChild(chb1);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ chb2.setAttribute('class', 'shadow');
+ chb2.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
+ expectations[1] = true;
+ }), false);
+ expectations[1] = false;
+ host.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ chb3.setAttribute('class', 'shadow');
+ chb3.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 4: wrong focus navigation order');
+ expectations[2] = true;
+ }), false);
+ expectations[2] = false;
+ host.appendChild(chb3);
+
+ var s = host.createShadowRoot();
+
+ var div = d.createElement('div');
+ div.innerHTML = '<content select=".shadow"></content>';
+ s.appendChild(div);
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
+
+ expectations[3] = true;
+ }), false);
+ expectations[3] = false;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
+ expectations[4] = true;
+ }), false);
+ expectations[4] = false;
+ s.appendChild(inp2);
+
+ var chb4 = d.createElement('input');
+ chb4.setAttribute('type', 'checkbox');
+ chb4.setAttribute('id', 'chb4');
+ chb4.addEventListener('focus', A_07_02_02_T02.step_func(function(event) {
+ assert_equals(counter++, 4, 'Point 5: wrong focus navigation order');
+ expectations[5] = true;
+ }), false);
+ expectations[5] = false;
+ d.body.appendChild(chb4);
+
+ chb0.focus();
+
+ //simulate TAB clicks
+ fireKeyboardEvent(d, inp1, 'U+0009');
+
+ fireKeyboardEvent(d, inp2, 'U+0009');
+
+ fireKeyboardEvent(d, chb2, 'U+0009');
+
+ fireKeyboardEvent(d, chb3, 'U+0009');
+
+ fireKeyboardEvent(d, chb4, 'U+0009');
+
+ for (var i = 1; i < expectations.length; i++) {
+ if (!expectations[i]) {
+ assert_true(false, 'Point ' + i + ' event listener was not invoked');
+ }
+ }
A_07_02_02_T02.done();
}));
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-003.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-003.html
index 46082347587..13ee0bdeaeb 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-003.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-003.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: For sequential focus navigation, the shadow DOM navigation order sequence must be inserted into the document navigation order in place of the shadow host as if the shadow host were assigned the value of auto for determining its position and shadow host is not focusable">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -25,99 +26,99 @@ var A_07_02_03_T01 = async_test('A_07_02_03_T01');
A_07_02_03_T01.step(unit(function (ctx) {
- var counter = 0;
-
- var invoked = [];
-
- var d = newRenderedHTMLDocument(ctx);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- // TODO according CSS3 nav-index is a replacement for tabindex
- //chb1.setAttribute('nav-index', '4');
- chb1.setAttribute('tabindex', '4');
- chb1.setAttribute('id', 'chb1');
- chb1.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 1: wrong focus navigation order');
- invoked[1] = true;
- }), false);
- invoked[1] = false;
- d.body.appendChild(chb1);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- //inp1.setAttribute('nav-index', '3');
- inp1.setAttribute('tabindex', '3');
- inp1.setAttribute('value', 'Input 1');
- inp1.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
- assert_equals(counter++, 4, 'Point 2: wrong focus navigation order');
- invoked[2] = true;
- }), false);
- invoked[2] = false;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- //inp2.setAttribute('nav-index', '2');
- inp2.setAttribute('tabindex', '2');
- inp2.setAttribute('value', 'Input 2');
- inp2.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 3: wrong focus navigation order');
- invoked[3] = true;
- }), false);
- invoked[3] = false;
- s.appendChild(inp2);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- //chb2.setAttribute('nav-index', '1');
- chb2.setAttribute('tabindex', '1');
- chb2.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 4: wrong focus navigation order');
- invoked[4] = true;
- }), false);
- invoked[4] = false;
- d.body.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- //chb3.setAttribute('nav-index', '5');
- chb3.setAttribute('tabindex', '5');
- chb3.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 5: wrong focus navigation order');
- invoked[5] = true;
- }), false);
- invoked[5] = false;
- d.body.appendChild(chb3);
-
- chb2.focus();
-
- //simulate TAB clicks. Expected order: chb2, chb1, chb3, inp2, inp1
- fireKeyboardEvent(d, chb2, 'U+0009');
-
- fireKeyboardEvent(d, chb1, 'U+0009');
-
- fireKeyboardEvent(d, chb3, 'U+0009');
-
- fireKeyboardEvent(d, inp2, 'U+0009');
-
- fireKeyboardEvent(d, inp1, 'U+0009');
-
- for (var i = 1; i < invoked.length; i++) {
- if (!invoked[i]) {
- assert_true(false, 'Piont ' + i + ' event listener was not invoked');
- }
- }
-
- A_07_02_03_T01.done();
+ var counter = 0;
+
+ var invoked = [];
+
+ var d = newRenderedHTMLDocument(ctx);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ // TODO according CSS3 nav-index is a replacement for tabindex
+ //chb1.setAttribute('nav-index', '4');
+ chb1.setAttribute('tabindex', '4');
+ chb1.setAttribute('id', 'chb1');
+ chb1.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 1: wrong focus navigation order');
+ invoked[1] = true;
+ }), false);
+ invoked[1] = false;
+ d.body.appendChild(chb1);
+
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ //inp1.setAttribute('nav-index', '3');
+ inp1.setAttribute('tabindex', '3');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
+ assert_equals(counter++, 4, 'Point 2: wrong focus navigation order');
+ invoked[2] = true;
+ }), false);
+ invoked[2] = false;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ //inp2.setAttribute('nav-index', '2');
+ inp2.setAttribute('tabindex', '2');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 3: wrong focus navigation order');
+ invoked[3] = true;
+ }), false);
+ invoked[3] = false;
+ s.appendChild(inp2);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ //chb2.setAttribute('nav-index', '1');
+ chb2.setAttribute('tabindex', '1');
+ chb2.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 4: wrong focus navigation order');
+ invoked[4] = true;
+ }), false);
+ invoked[4] = false;
+ d.body.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ //chb3.setAttribute('nav-index', '5');
+ chb3.setAttribute('tabindex', '5');
+ chb3.addEventListener('focus', A_07_02_03_T01.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 5: wrong focus navigation order');
+ invoked[5] = true;
+ }), false);
+ invoked[5] = false;
+ d.body.appendChild(chb3);
+
+ chb2.focus();
+
+ //simulate TAB clicks. Expected order: chb2, chb1, chb3, inp2, inp1
+ fireKeyboardEvent(d, chb2, 'U+0009');
+
+ fireKeyboardEvent(d, chb1, 'U+0009');
+
+ fireKeyboardEvent(d, chb3, 'U+0009');
+
+ fireKeyboardEvent(d, inp2, 'U+0009');
+
+ fireKeyboardEvent(d, inp1, 'U+0009');
+
+ for (var i = 1; i < invoked.length; i++) {
+ if (!invoked[i]) {
+ assert_true(false, 'Piont ' + i + ' event listener was not invoked');
+ }
+ }
+
+ A_07_02_03_T01.done();
}));
// test nodes, distributed into insertion points
@@ -125,111 +126,111 @@ var A_07_02_03_T02 = async_test('A_07_02_03_T02');
A_07_02_03_T02.step(unit(function (ctx) {
- var counter = 0;
-
- var invoked = [];
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- d.body.appendChild(host);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- chb1.setAttribute('id', 'chb1');
- chb1.setAttribute('tabindex', '1');
- chb1.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
- invoked[1] = true;
- }), false);
- invoked[1] = false;
- d.body.appendChild(chb1);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- chb2.setAttribute('class', 'shadow');
- chb2.setAttribute('tabindex', '3');
- chb2.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 2: wrong focus navigation order');
- invoked[2] = true;
- }), false);
- invoked[2] = false;
- host.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- chb3.setAttribute('class', 'shadow');
- chb3.setAttribute('tabindex', '2');
- chb3.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 3: wrong focus navigation order');
- invoked[3] = true;
- }), false);
- invoked[3] = false;
- host.appendChild(chb3);
-
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '<content select=".shadow"></content>';
- s.appendChild(div);
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- inp1.setAttribute('value', 'Input 1');
- inp1.setAttribute('tabindex', '4');
- inp1.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
- assert_equals(counter++, 4, 'Point 4: wrong focus navigation order');
- invoked[4] = true;
- }), false);
- invoked[4] = false;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- inp2.setAttribute('value', 'Input 2');
- inp2.setAttribute('tabindex', '5');
- inp2.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
- assert_equals(counter++, 5, 'Point 5: wrong focus navigation order');
- invoked[5] = true;
- }), false);
- invoked[5] = false;
- s.appendChild(inp2);
-
- var chb4 = d.createElement('input');
- chb4.setAttribute('type', 'checkbox');
- chb4.setAttribute('id', 'chb4');
- chb4.setAttribute('tabindex', '6');
- chb4.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 6: wrong focus navigation order');
- invoked[6] = true;
- }), false);
- invoked[6] = false;
- d.body.appendChild(chb4);
-
- chb1.focus();
-
- //simulate TAB clicks
- //Expected order: chb1, chb3, chb2, chb4, inp1, inp2
- fireKeyboardEvent(d, chb1, 'U+0009');
- fireKeyboardEvent(d, chb3, 'U+0009');
- fireKeyboardEvent(d, chb2, 'U+0009');
- fireKeyboardEvent(d, chb4, 'U+0009');
- fireKeyboardEvent(d, inp1, 'U+0009');
- fireKeyboardEvent(d, inp2, 'U+0009');
-
-
-
- for (var i = 1; i < invoked.length; i++) {
- if (!invoked[i]) {
- assert_true(false, 'Piont ' + i + ' event listener was not invoked');
- }
- }
-
- A_07_02_03_T02.done();
+ var counter = 0;
+
+ var invoked = [];
+
+ var d = newRenderedHTMLDocument(ctx);
+
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ chb1.setAttribute('id', 'chb1');
+ chb1.setAttribute('tabindex', '1');
+ chb1.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
+ invoked[1] = true;
+ }), false);
+ invoked[1] = false;
+ d.body.appendChild(chb1);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ chb2.setAttribute('class', 'shadow');
+ chb2.setAttribute('tabindex', '3');
+ chb2.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 2: wrong focus navigation order');
+ invoked[2] = true;
+ }), false);
+ invoked[2] = false;
+ host.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ chb3.setAttribute('class', 'shadow');
+ chb3.setAttribute('tabindex', '2');
+ chb3.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 3: wrong focus navigation order');
+ invoked[3] = true;
+ }), false);
+ invoked[3] = false;
+ host.appendChild(chb3);
+
+ var s = host.createShadowRoot();
+
+ var div = d.createElement('div');
+ div.innerHTML = '<content select=".shadow"></content>';
+ s.appendChild(div);
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.setAttribute('tabindex', '4');
+ inp1.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
+ assert_equals(counter++, 4, 'Point 4: wrong focus navigation order');
+ invoked[4] = true;
+ }), false);
+ invoked[4] = false;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.setAttribute('tabindex', '5');
+ inp2.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
+ assert_equals(counter++, 5, 'Point 5: wrong focus navigation order');
+ invoked[5] = true;
+ }), false);
+ invoked[5] = false;
+ s.appendChild(inp2);
+
+ var chb4 = d.createElement('input');
+ chb4.setAttribute('type', 'checkbox');
+ chb4.setAttribute('id', 'chb4');
+ chb4.setAttribute('tabindex', '6');
+ chb4.addEventListener('focus', A_07_02_03_T02.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 6: wrong focus navigation order');
+ invoked[6] = true;
+ }), false);
+ invoked[6] = false;
+ d.body.appendChild(chb4);
+
+ chb1.focus();
+
+ //simulate TAB clicks
+ //Expected order: chb1, chb3, chb2, chb4, inp1, inp2
+ fireKeyboardEvent(d, chb1, 'U+0009');
+ fireKeyboardEvent(d, chb3, 'U+0009');
+ fireKeyboardEvent(d, chb2, 'U+0009');
+ fireKeyboardEvent(d, chb4, 'U+0009');
+ fireKeyboardEvent(d, inp1, 'U+0009');
+ fireKeyboardEvent(d, inp2, 'U+0009');
+
+
+
+ for (var i = 1; i < invoked.length; i++) {
+ if (!invoked[i]) {
+ assert_true(false, 'Piont ' + i + ' event listener was not invoked');
+ }
+ }
+
+ A_07_02_03_T02.done();
}));
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-004.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-004.html
index 10b92659efe..30b08a314b1 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-004.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/focus-navigation/test-004.html
@@ -16,7 +16,8 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: For sequential focus navigation, the shadow DOM navigation order sequence must be inserted into the document navigation order immediately after the shadow host, if the shadow host is focusable;">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
@@ -25,101 +26,101 @@ var A_07_02_04_T01 = async_test('A_07_02_04_T01');
A_07_02_04_T01.step(unit(function (ctx) {
- var counter = 0;
-
- var invoked = [];
-
- var d = newRenderedHTMLDocument(ctx);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- // TODO according CSS3 nav-index is a replacement for tabindex
- //chb1.setAttribute('nav-index', '4');
- chb1.setAttribute('tabindex', '1');
- chb1.setAttribute('id', 'chb1');
- chb1.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
- invoked[1] = true;
- }), false);
- invoked[1] = false;
- d.body.appendChild(chb1);
-
- var host = d.createElement('div');
- //make shadow host focusable
- host.setAttribute('tabindex', '3');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- //inp1.setAttribute('nav-index', '3');
- inp1.setAttribute('tabindex', '2');
- inp1.setAttribute('value', 'Input 1');
- inp1.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 2: wrong focus navigation order');
- invoked[2] = true;
- }), false);
- invoked[2] = false;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- //inp2.setAttribute('nav-index', '2');
- inp2.setAttribute('tabindex', '1');
- inp2.setAttribute('value', 'Input 2');
- inp2.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
- invoked[3] = true;
- }), false);
- invoked[3] = false;
- s.appendChild(inp2);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- //chb2.setAttribute('nav-index', '1');
- chb2.setAttribute('tabindex', '2');
- chb2.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 4: wrong focus navigation order');
- invoked[4] = true;
- }), false);
- invoked[4] = false;
- d.body.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- //chb3.setAttribute('nav-index', '5');
- chb3.setAttribute('tabindex', '4');
- chb3.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
- assert_equals(counter++, 4, 'Point 5: wrong focus navigation order');
- invoked[5] = true;
- }), false);
- invoked[5] = false;
- d.body.appendChild(chb3);
-
- chb1.focus();
-
- //simulate TAB clicks. Expected order: chb1, chb2, inp2, inp1, chb3
- fireKeyboardEvent(d, chb1, 'U+0009');
-
- fireKeyboardEvent(d, chb2, 'U+0009');
-
- fireKeyboardEvent(d, inp2, 'U+0009');
-
- fireKeyboardEvent(d, inp1, 'U+0009');
-
- fireKeyboardEvent(d, chb3, 'U+0009');
-
- for (var i = 1; i < invoked.length; i++) {
- if (!invoked[i]) {
- assert_true(false, 'Piont ' + i + ' event listener was not invoked');
- }
- }
-
- A_07_02_04_T01.done();
+ var counter = 0;
+
+ var invoked = [];
+
+ var d = newRenderedHTMLDocument(ctx);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ // TODO according CSS3 nav-index is a replacement for tabindex
+ //chb1.setAttribute('nav-index', '4');
+ chb1.setAttribute('tabindex', '1');
+ chb1.setAttribute('id', 'chb1');
+ chb1.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
+ invoked[1] = true;
+ }), false);
+ invoked[1] = false;
+ d.body.appendChild(chb1);
+
+ var host = d.createElement('div');
+ //make shadow host focusable
+ host.setAttribute('tabindex', '3');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ //inp1.setAttribute('nav-index', '3');
+ inp1.setAttribute('tabindex', '2');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 2: wrong focus navigation order');
+ invoked[2] = true;
+ }), false);
+ invoked[2] = false;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ //inp2.setAttribute('nav-index', '2');
+ inp2.setAttribute('tabindex', '1');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
+ invoked[3] = true;
+ }), false);
+ invoked[3] = false;
+ s.appendChild(inp2);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ //chb2.setAttribute('nav-index', '1');
+ chb2.setAttribute('tabindex', '2');
+ chb2.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 4: wrong focus navigation order');
+ invoked[4] = true;
+ }), false);
+ invoked[4] = false;
+ d.body.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ //chb3.setAttribute('nav-index', '5');
+ chb3.setAttribute('tabindex', '4');
+ chb3.addEventListener('focus', A_07_02_04_T01.step_func(function(event) {
+ assert_equals(counter++, 4, 'Point 5: wrong focus navigation order');
+ invoked[5] = true;
+ }), false);
+ invoked[5] = false;
+ d.body.appendChild(chb3);
+
+ chb1.focus();
+
+ //simulate TAB clicks. Expected order: chb1, chb2, inp2, inp1, chb3
+ fireKeyboardEvent(d, chb1, 'U+0009');
+
+ fireKeyboardEvent(d, chb2, 'U+0009');
+
+ fireKeyboardEvent(d, inp2, 'U+0009');
+
+ fireKeyboardEvent(d, inp1, 'U+0009');
+
+ fireKeyboardEvent(d, chb3, 'U+0009');
+
+ for (var i = 1; i < invoked.length; i++) {
+ if (!invoked[i]) {
+ assert_true(false, 'Piont ' + i + ' event listener was not invoked');
+ }
+ }
+
+ A_07_02_04_T01.done();
}));
@@ -129,112 +130,112 @@ var A_07_02_04_T02 = async_test('A_07_02_04_T02');
A_07_02_04_T02.step(unit(function (ctx) {
- var counter = 0;
-
- var invoked = [];
-
- var d = newRenderedHTMLDocument(ctx);
-
- var host = d.createElement('div');
- host.setAttribute('tabindex', '3');
- d.body.appendChild(host);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- chb1.setAttribute('id', 'chb1');
- chb1.setAttribute('tabindex', '1');
- chb1.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
- invoked[1] = true;
- }), false);
- invoked[1] = false;
- d.body.appendChild(chb1);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- chb2.setAttribute('class', 'shadow');
- chb2.setAttribute('tabindex', '3');
- chb2.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
- assert_equals(counter++, 4, 'Point 2: wrong focus navigation order');
- invoked[2] = true;
- }), false);
- invoked[2] = false;
- host.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- chb3.setAttribute('class', 'shadow');
- chb3.setAttribute('tabindex', '2');
- chb3.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 3: wrong focus navigation order');
- invoked[3] = true;
- }), false);
- invoked[3] = false;
- host.appendChild(chb3);
-
- var s = host.createShadowRoot();
-
- var div = d.createElement('div');
- div.innerHTML = '<content select=".shadow"></content>';
- s.appendChild(div);
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- inp1.setAttribute('value', 'Input 1');
- inp1.setAttribute('tabindex', '4');
- inp1.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 4: wrong focus navigation order');
- invoked[4] = true;
- }), false);
- invoked[4] = false;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- inp2.setAttribute('value', 'Input 2');
- inp2.setAttribute('tabindex', '4');
- inp2.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
- assert_equals(counter++, 5, 'Point 5: wrong focus navigation order');
- invoked[5] = true;
- }), false);
- invoked[5] = false;
- d.body.appendChild(inp2);
-
- var chb4 = d.createElement('input');
- chb4.setAttribute('type', 'checkbox');
- chb4.setAttribute('id', 'chb4');
- chb4.setAttribute('tabindex', '2');
- chb4.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 6: wrong focus navigation order');
- invoked[6] = true;
- }), false);
- invoked[6] = false;
- d.body.appendChild(chb4);
-
- chb1.focus();
-
- //simulate TAB clicks
- //Expected order: chb1, chb3, chb4, chb2, inp1, inp2
- fireKeyboardEvent(d, chb1, 'U+0009');
- fireKeyboardEvent(d, chb3, 'U+0009');
- fireKeyboardEvent(d, chb4, 'U+0009');
- fireKeyboardEvent(d, chb2, 'U+0009');
- fireKeyboardEvent(d, inp1, 'U+0009');
- fireKeyboardEvent(d, inp2, 'U+0009');
-
-
-
- for (var i = 1; i < invoked.length; i++) {
- if (!invoked[i]) {
- assert_true(false, 'Point ' + i + ' event listener was not invoked');
- }
- }
-
- A_07_02_04_T02.done();
+ var counter = 0;
+
+ var invoked = [];
+
+ var d = newRenderedHTMLDocument(ctx);
+
+ var host = d.createElement('div');
+ host.setAttribute('tabindex', '3');
+ d.body.appendChild(host);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ chb1.setAttribute('id', 'chb1');
+ chb1.setAttribute('tabindex', '1');
+ chb1.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
+ invoked[1] = true;
+ }), false);
+ invoked[1] = false;
+ d.body.appendChild(chb1);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ chb2.setAttribute('class', 'shadow');
+ chb2.setAttribute('tabindex', '3');
+ chb2.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
+ assert_equals(counter++, 4, 'Point 2: wrong focus navigation order');
+ invoked[2] = true;
+ }), false);
+ invoked[2] = false;
+ host.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ chb3.setAttribute('class', 'shadow');
+ chb3.setAttribute('tabindex', '2');
+ chb3.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 3: wrong focus navigation order');
+ invoked[3] = true;
+ }), false);
+ invoked[3] = false;
+ host.appendChild(chb3);
+
+ var s = host.createShadowRoot();
+
+ var div = d.createElement('div');
+ div.innerHTML = '<content select=".shadow"></content>';
+ s.appendChild(div);
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.setAttribute('tabindex', '4');
+ inp1.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 4: wrong focus navigation order');
+ invoked[4] = true;
+ }), false);
+ invoked[4] = false;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.setAttribute('tabindex', '4');
+ inp2.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
+ assert_equals(counter++, 5, 'Point 5: wrong focus navigation order');
+ invoked[5] = true;
+ }), false);
+ invoked[5] = false;
+ d.body.appendChild(inp2);
+
+ var chb4 = d.createElement('input');
+ chb4.setAttribute('type', 'checkbox');
+ chb4.setAttribute('id', 'chb4');
+ chb4.setAttribute('tabindex', '2');
+ chb4.addEventListener('focus', A_07_02_04_T02.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 6: wrong focus navigation order');
+ invoked[6] = true;
+ }), false);
+ invoked[6] = false;
+ d.body.appendChild(chb4);
+
+ chb1.focus();
+
+ //simulate TAB clicks
+ //Expected order: chb1, chb3, chb4, chb2, inp1, inp2
+ fireKeyboardEvent(d, chb1, 'U+0009');
+ fireKeyboardEvent(d, chb3, 'U+0009');
+ fireKeyboardEvent(d, chb4, 'U+0009');
+ fireKeyboardEvent(d, chb2, 'U+0009');
+ fireKeyboardEvent(d, inp1, 'U+0009');
+ fireKeyboardEvent(d, inp2, 'U+0009');
+
+
+
+ for (var i = 1; i < invoked.length; i++) {
+ if (!invoked[i]) {
+ assert_true(false, 'Point ' + i + ' event listener was not invoked');
+ }
+ }
+
+ A_07_02_04_T02.done();
}));
@@ -244,90 +245,90 @@ var A_07_02_04_T03 = async_test('A_07_02_04_T03');
A_07_02_04_T03.step(unit(function (ctx) {
- var counter = 0;
-
- var invoked = [];
-
- var d = newRenderedHTMLDocument(ctx);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- chb1.setAttribute('tabindex', '3');
- chb1.setAttribute('id', 'chb1');
- chb1.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
- assert_equals(counter++, 4, 'Point 1: wrong focus navigation order');
- invoked[1] = true;
- }), false);
- invoked[1] = false;
- d.body.appendChild(chb1);
-
- var host = d.createElement('div');
- host.setAttribute('tabindex', '1');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- inp1.setAttribute('tabindex', '2');
- inp1.setAttribute('value', 'Input 1');
- inp1.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
- invoked[2] = true;
- }), false);
- invoked[2] = false;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- inp2.setAttribute('tabindex', '1');
- inp2.setAttribute('value', 'Input 2');
- inp2.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 3: wrong focus navigation order');
- invoked[3] = true;
- }), false);
- invoked[3] = false;
- s.appendChild(inp2);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- chb2.setAttribute('tabindex', '3');
- chb2.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 4: wrong focus navigation order');
- invoked[4] = true;
- }), false);
- invoked[4] = false;
- s.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- chb3.setAttribute('tabindex', '2');
- chb3.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 5: wrong focus navigation order');
- invoked[5] = true;
- }), false);
- invoked[5] = false;
- d.body.appendChild(chb3);
-
- host.focus();
-
- //simulate TAB clicks. Expected order: inp2, inp1, chb2, chb3, chb1
- fireKeyboardEvent(d, inp2, 'U+0009');
- fireKeyboardEvent(d, inp1, 'U+0009');
- fireKeyboardEvent(d, chb2, 'U+0009');
- fireKeyboardEvent(d, chb3, 'U+0009');
- fireKeyboardEvent(d, chb1, 'U+0009');
-
- for (var i = 1; i < invoked.length; i++) {
- if (!invoked[i]) {
- assert_true(false, 'Piont ' + i + ' event listener was not invoked');
- }
- }
-
- A_07_02_04_T03.done();
+ var counter = 0;
+
+ var invoked = [];
+
+ var d = newRenderedHTMLDocument(ctx);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ chb1.setAttribute('tabindex', '3');
+ chb1.setAttribute('id', 'chb1');
+ chb1.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
+ assert_equals(counter++, 4, 'Point 1: wrong focus navigation order');
+ invoked[1] = true;
+ }), false);
+ invoked[1] = false;
+ d.body.appendChild(chb1);
+
+ var host = d.createElement('div');
+ host.setAttribute('tabindex', '1');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ inp1.setAttribute('tabindex', '2');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 2: wrong focus navigation order');
+ invoked[2] = true;
+ }), false);
+ invoked[2] = false;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ inp2.setAttribute('tabindex', '1');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 3: wrong focus navigation order');
+ invoked[3] = true;
+ }), false);
+ invoked[3] = false;
+ s.appendChild(inp2);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ chb2.setAttribute('tabindex', '3');
+ chb2.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 4: wrong focus navigation order');
+ invoked[4] = true;
+ }), false);
+ invoked[4] = false;
+ s.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ chb3.setAttribute('tabindex', '2');
+ chb3.addEventListener('focus', A_07_02_04_T03.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 5: wrong focus navigation order');
+ invoked[5] = true;
+ }), false);
+ invoked[5] = false;
+ d.body.appendChild(chb3);
+
+ host.focus();
+
+ //simulate TAB clicks. Expected order: inp2, inp1, chb2, chb3, chb1
+ fireKeyboardEvent(d, inp2, 'U+0009');
+ fireKeyboardEvent(d, inp1, 'U+0009');
+ fireKeyboardEvent(d, chb2, 'U+0009');
+ fireKeyboardEvent(d, chb3, 'U+0009');
+ fireKeyboardEvent(d, chb1, 'U+0009');
+
+ for (var i = 1; i < invoked.length; i++) {
+ if (!invoked[i]) {
+ assert_true(false, 'Piont ' + i + ' event listener was not invoked');
+ }
+ }
+
+ A_07_02_04_T03.done();
}));
@@ -336,90 +337,90 @@ var A_07_02_04_T04 = async_test('A_07_02_04_T04');
A_07_02_04_T04.step(unit(function (ctx) {
- var counter = 0;
-
- var invoked = [];
-
- var d = newRenderedHTMLDocument(ctx);
-
- var chb1 = d.createElement('input');
- chb1.setAttribute('type', 'checkbox');
- chb1.setAttribute('tabindex', '1');
- chb1.setAttribute('id', 'chb1');
- chb1.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
- assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
- invoked[1] = true;
- }), false);
- invoked[1] = false;
- d.body.appendChild(chb1);
-
- var host = d.createElement('div');
- host.setAttribute('tabindex', '3');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
-
- var inp1 = d.createElement('input');
- inp1.setAttribute('type', 'text');
- inp1.setAttribute('id', 'shInp1');
- inp1.setAttribute('tabindex', '2');
- inp1.setAttribute('value', 'Input 1');
- inp1.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
- assert_equals(counter++, 3, 'Point 2: wrong focus navigation order');
- invoked[2] = true;
- }), false);
- invoked[2] = false;
- s.appendChild(inp1);
-
- var inp2 = d.createElement('input');
- inp2.setAttribute('type', 'text');
- inp2.setAttribute('id', 'shInp2');
- inp2.setAttribute('tabindex', '1');
- inp2.setAttribute('value', 'Input 2');
- inp2.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
- assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
- invoked[3] = true;
- }), false);
- invoked[3] = false;
- s.appendChild(inp2);
-
- var chb2 = d.createElement('input');
- chb2.setAttribute('type', 'checkbox');
- chb2.setAttribute('id', 'chb2');
- chb2.setAttribute('tabindex', '3');
- chb2.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
- assert_equals(counter++, 4, 'Point 4: wrong focus navigation order');
- invoked[4] = true;
- }), false);
- invoked[4] = false;
- s.appendChild(chb2);
-
- var chb3 = d.createElement('input');
- chb3.setAttribute('type', 'checkbox');
- chb3.setAttribute('id', 'chb3');
- chb3.setAttribute('tabindex', '2');
- chb3.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
- assert_equals(counter++, 1, 'Point 5: wrong focus navigation order');
- invoked[5] = true;
- }), false);
- invoked[5] = false;
- d.body.appendChild(chb3);
-
- chb1.focus();
-
- //simulate TAB clicks. Expected order: inp2, inp1, chb2, chb3, chb1
- fireKeyboardEvent(d, chb1, 'U+0009');
- fireKeyboardEvent(d, chb3, 'U+0009');
- fireKeyboardEvent(d, inp2, 'U+0009');
- fireKeyboardEvent(d, inp1, 'U+0009');
- fireKeyboardEvent(d, chb2, 'U+0009');
-
- for (var i = 1; i < invoked.length; i++) {
- if (!invoked[i]) {
- assert_true(false, 'Piont ' + i + ' event listener was not invoked');
- }
- }
-
- A_07_02_04_T04.done();
+ var counter = 0;
+
+ var invoked = [];
+
+ var d = newRenderedHTMLDocument(ctx);
+
+ var chb1 = d.createElement('input');
+ chb1.setAttribute('type', 'checkbox');
+ chb1.setAttribute('tabindex', '1');
+ chb1.setAttribute('id', 'chb1');
+ chb1.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
+ assert_equals(counter++, 0, 'Point 1: wrong focus navigation order');
+ invoked[1] = true;
+ }), false);
+ invoked[1] = false;
+ d.body.appendChild(chb1);
+
+ var host = d.createElement('div');
+ host.setAttribute('tabindex', '3');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
+
+ var inp1 = d.createElement('input');
+ inp1.setAttribute('type', 'text');
+ inp1.setAttribute('id', 'shInp1');
+ inp1.setAttribute('tabindex', '2');
+ inp1.setAttribute('value', 'Input 1');
+ inp1.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
+ assert_equals(counter++, 3, 'Point 2: wrong focus navigation order');
+ invoked[2] = true;
+ }), false);
+ invoked[2] = false;
+ s.appendChild(inp1);
+
+ var inp2 = d.createElement('input');
+ inp2.setAttribute('type', 'text');
+ inp2.setAttribute('id', 'shInp2');
+ inp2.setAttribute('tabindex', '1');
+ inp2.setAttribute('value', 'Input 2');
+ inp2.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
+ assert_equals(counter++, 2, 'Point 3: wrong focus navigation order');
+ invoked[3] = true;
+ }), false);
+ invoked[3] = false;
+ s.appendChild(inp2);
+
+ var chb2 = d.createElement('input');
+ chb2.setAttribute('type', 'checkbox');
+ chb2.setAttribute('id', 'chb2');
+ chb2.setAttribute('tabindex', '3');
+ chb2.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
+ assert_equals(counter++, 4, 'Point 4: wrong focus navigation order');
+ invoked[4] = true;
+ }), false);
+ invoked[4] = false;
+ s.appendChild(chb2);
+
+ var chb3 = d.createElement('input');
+ chb3.setAttribute('type', 'checkbox');
+ chb3.setAttribute('id', 'chb3');
+ chb3.setAttribute('tabindex', '2');
+ chb3.addEventListener('focus', A_07_02_04_T04.step_func(function(event) {
+ assert_equals(counter++, 1, 'Point 5: wrong focus navigation order');
+ invoked[5] = true;
+ }), false);
+ invoked[5] = false;
+ d.body.appendChild(chb3);
+
+ chb1.focus();
+
+ //simulate TAB clicks. Expected order: inp2, inp1, chb2, chb3, chb1
+ fireKeyboardEvent(d, chb1, 'U+0009');
+ fireKeyboardEvent(d, chb3, 'U+0009');
+ fireKeyboardEvent(d, inp2, 'U+0009');
+ fireKeyboardEvent(d, inp1, 'U+0009');
+ fireKeyboardEvent(d, chb2, 'U+0009');
+
+ for (var i = 1; i < invoked.length; i++) {
+ if (!invoked[i]) {
+ assert_true(false, 'Piont ' + i + ' event listener was not invoked');
+ }
+ }
+
+ A_07_02_04_T04.done();
}));
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-001.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-001.html
index 29c2b368f7c..d156338b4c2 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-001.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-001.html
@@ -16,62 +16,63 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: Selection, returned by the window.getSelection() method must never return a selection within a shadow tree">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.createShadowRoot();
- var span = d.createElement('span');
- span.innerHTML = 'Some text';
- s.appendChild(span);
+ var span = d.createElement('span');
+ span.innerHTML = 'Some text';
+ s.appendChild(span);
- var range = d.createRange();
- range.setStart(span.firstChild, 0);
- range.setEnd(span.firstChild, 3);
+ var range = d.createRange();
+ range.setStart(span.firstChild, 0);
+ range.setEnd(span.firstChild, 3);
- var selection = window.getSelection();
+ var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
var sl = window.getSelection();
assert_equals(sl.toString(), '', 'window.getSelection() method must never return a selection ' +
- 'within a shadow tree');
+ 'within a shadow tree');
}), 'A_07_07_01_T01');
// test distributed nodes
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
+ var host = d.createElement('div');
+ d.body.appendChild(host);
- var span = d.createElement('span');
- span.innerHTML = 'Some text';
- host.appendChild(span);
+ var span = d.createElement('span');
+ span.innerHTML = 'Some text';
+ host.appendChild(span);
- var s = host.createShadowRoot();
- s.innerHTML = '<content select="span"></content>';
+ var s = host.createShadowRoot();
+ s.innerHTML = '<content select="span"></content>';
- var range = d.createRange();
- range.setStart(span.firstChild, 0);
- range.setEnd(span.firstChild, 3);
+ var range = d.createRange();
+ range.setStart(span.firstChild, 0);
+ range.setEnd(span.firstChild, 3);
- var selection = window.getSelection();
+ var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
var sl = window.getSelection();
assert_equals(sl.toString(), '', 'window.getSelection() method must never return a selection ' +
- 'within a shadow tree');
+ 'within a shadow tree');
}), 'A_07_07_01_T02');
</script>
diff --git a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html
index c566ea6aa02..76ff0f5dd68 100644
--- a/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html
+++ b/tests/wpt/web-platform-tests/shadow-dom/untriaged/user-interaction/ranges-and-selections/test-002.html
@@ -16,62 +16,64 @@ policies and contribution forms [3].
<meta name="assert" content="User Interaction: The getSelection() method of the shadow root object must return the current selection in this shadow tree.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
-<script src="../../testcommon.js"></script>
+<script src="../../../../html/resources/common.js"></script>
+<script src="../../../resources/shadow-dom-utils.js"></script>
</head>
<body>
<div id="log"></div>
<script>
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
- var s = host.createShadowRoot();
+ var host = d.createElement('div');
+ d.body.appendChild(host);
+ var s = host.attachShadow({mode: 'open'});
- var span = d.createElement('span');
- span.innerHTML = 'Some text';
- s.appendChild(span);
+ var span = d.createElement('span');
+ span.innerHTML = 'Some text';
+ s.appendChild(span);
- var range = d.createRange();
- range.setStart(span.firstChild, 0);
- range.setEnd(span.firstChild, 3);
+ var range = d.createRange();
+ range.setStart(span.firstChild, 0);
+ range.setEnd(span.firstChild, 3);
- var selection = window.getSelection();
+ var selection = d.defaultView.getSelection();
selection.removeAllRanges();
selection.addRange(range);
var sl = s.getSelection();
assert_equals(sl.toString(), 'Som', 'The getSelection() method of the shadow root object must return ' +
- 'the current selection in this shadow tree');
+ 'the current selection in this shadow tree');
}), 'A_07_01_02_T01');
//test distributed nodes
test(unit(function (ctx) {
- var d = newRenderedHTMLDocument(ctx);
+ var d = newRenderedHTMLDocument(ctx);
- var host = d.createElement('div');
- d.body.appendChild(host);
+ var host = d.createElement('div');
+ d.body.appendChild(host);
- var span = d.createElement('span');
- span.innerHTML = 'Some text';
- host.appendChild(span);
+ var span = d.createElement('span');
+ span.innerHTML = 'Some text';
+ span.setAttribute('slot', 'slot');
+ host.appendChild(span);
- var s = host.createShadowRoot();
- s.innerHTML = '<content select="span"></content>';
+ var s = host.attachShadow({mode: 'open'});
+ s.innerHTML = '<slot name="slot"></slot>';
- var range = d.createRange();
- range.setStart(span.firstChild, 0);
- range.setEnd(span.firstChild, 3);
+ var range = d.createRange();
+ range.setStart(span.firstChild, 0);
+ range.setEnd(span.firstChild, 3);
- var selection = window.getSelection();
+ var selection = d.defaultView.getSelection();
selection.removeAllRanges();
selection.addRange(range);
var sl = s.getSelection();
assert_equals(sl.toString(), 'Som', 'The getSelection() method of the shadow root object must return ' +
- 'the current selection in this shadow tree');
+ 'the current selection in this shadow tree');
}), 'A_07_07_02_T02');
</script>
diff --git a/tests/wpt/web-platform-tests/tools/.gitmodules b/tests/wpt/web-platform-tests/tools/.gitmodules
index 39a77781529..12cee69142f 100644
--- a/tests/wpt/web-platform-tests/tools/.gitmodules
+++ b/tests/wpt/web-platform-tests/tools/.gitmodules
@@ -15,3 +15,6 @@
[submodule "pytest"]
path = pytest
url = https://github.com/pytest-dev/pytest.git
+[submodule "webdriver"]
+ path = webdriver
+ url = https://github.com/w3c/wdclient.git
diff --git a/tests/wpt/web-platform-tests/tools/localpaths.py b/tests/wpt/web-platform-tests/tools/localpaths.py
index c88e4f4cee2..cf31977ec7d 100644
--- a/tests/wpt/web-platform-tests/tools/localpaths.py
+++ b/tests/wpt/web-platform-tests/tools/localpaths.py
@@ -9,4 +9,6 @@ sys.path.insert(0, os.path.join(repo_root, "tools", "six"))
sys.path.insert(0, os.path.join(repo_root, "tools", "html5lib"))
sys.path.insert(0, os.path.join(repo_root, "tools", "wptserve"))
sys.path.insert(0, os.path.join(repo_root, "tools", "pywebsocket", "src"))
+sys.path.insert(0, os.path.join(repo_root, "tools", "py"))
sys.path.insert(0, os.path.join(repo_root, "tools", "pytest"))
+sys.path.insert(0, os.path.join(repo_root, "tools", "webdriver"))
diff --git a/tests/wpt/web-platform-tests/tools/py/.hgignore b/tests/wpt/web-platform-tests/tools/py/.hgignore
new file mode 100644
index 00000000000..34976da5d15
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/.hgignore
@@ -0,0 +1,29 @@
+
+# Automatically generated by `hgimportsvn`
+syntax:glob
+.svn
+.hgsvn
+
+# These lines are suggested according to the svn:ignore property
+# Feel free to enable them by uncommenting them
+syntax:glob
+*.pyc
+*.pyo
+*.swp
+*.html
+*.class
+*.orig
+*~
+
+doc/_build
+build/
+dist/
+*.egg-info
+issue/
+env/
+3rdparty/
+.tox
+lib/
+bin/
+include/
+src/
diff --git a/tests/wpt/web-platform-tests/tools/py/.hgtags b/tests/wpt/web-platform-tests/tools/py/.hgtags
new file mode 100644
index 00000000000..d45ebb5a237
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/.hgtags
@@ -0,0 +1,67 @@
+52c6d9e78777a5a34e813123997dfc614a1a4767 1.0.0b3
+1c7aaa8c61f3b0945921a9acc7beb184201aed4b 1.0.0b4
+1c7aaa8c61f3b0945921a9acc7beb184201aed4b 1.0.0b4
+0000000000000000000000000000000000000000 1.0.0b4
+0000000000000000000000000000000000000000 1.0.0b4
+8cd6eb91eba313b012d6e568f37d844dc0751f2e 1.0.0b4
+8cd6eb91eba313b012d6e568f37d844dc0751f2e 1.0.0b4
+0000000000000000000000000000000000000000 1.0.0b4
+2cc0507f117ffe721dff7ee026648cfce00ec92f 1.0.0b6
+86f1e1b6e49bf5882a809f11edd1dbb08162cdad 1.0.0b8
+86f1e1b6e49bf5882a809f11edd1dbb08162cdad 1.0.0b8
+c63f35c266cbb26dad6b87b5e115d65685adf448 1.0.0b8
+c63f35c266cbb26dad6b87b5e115d65685adf448 1.0.0b8
+0eaa0fdf2ba0163cf534dc2eff4ba2e5fc66c261 1.0.0b8
+e2a60653cb490aeed81bbbd83c070b99401c211c 1.0.0b9
+5ea0cdf7854c3d4278d36eda94a2b68483a0e211 1.0.0
+5ea0cdf7854c3d4278d36eda94a2b68483a0e211 1.0.0
+7acde360d94b6a2690ce3d03ff39301da84c0a2b 1.0.0
+6bd221981ac99103002c1cb94fede400d23a96a1 1.0.1
+4816e8b80602a3fd3a0a120333ad85fbe7d8bab4 1.0.2
+60c44bdbf093285dc69d5462d4dbb4acad325ca6 1.1.0
+319187fcda66714c5eb1353492babeec3d3c826f 1.1.1
+4fc5212f7626a56b9eb6437b5c673f56dd7eb942 1.2.0
+c143a8c8840a1c68570890c8ac6165bbf92fd3c6 1.2.1
+eafd3c256e8732dfb0a4d49d051b5b4339858926 1.3.0
+d5eacf390af74553227122b85e20345d47b2f9e6 1.3.1
+d5eacf390af74553227122b85e20345d47b2f9e6 1.3.1
+8b8e7c25a13cf863f01b2dd955978285ae9daf6a 1.3.1
+3bff44b188a7ec1af328d977b9d39b6757bb38df 1.3.2
+c59d3fa8681a5b5966b8375b16fccd64a3a8dbeb 1.3.3
+79ef6377705184c55633d456832eea318fedcf61 1.3.4
+79ef6377705184c55633d456832eea318fedcf61 1.3.4
+90fffd35373e9f125af233f78b19416f0938d841 1.3.4
+5346ab41b059c95a48cbe1e8a7bae96ce6e0da27 1.4.0
+1f3125cba7976538952be268f107c1d0c36c5ce8 1.4.1
+04ab22db4ff737cf31e91d75a0f5d7077f324167 1.4.2
+9950bf9d684a984d511795013421c89c5cf88bef 1.4.3
+d9951e3bdbc765e73835ae13012f6a074d13d8bf 1.4.4
+b827dd156a36753e32c7f3f15ce82d6fe9e356c8 1.4.6
+f15726f9e5a67cc6221c499affa4840e9d591763 1.4.7
+abfabd07a1d328f13c730e8a50d80d2e470afd3b 1.4.9
+7f37ee0aff9be4b839d6759cfee336f60e8393a4 1.4.10
+fe4593263efa10ea7ba014db6e3379e0b82368a2 1.4.11
+f07af25a26786e4825b5170e17ad693245cb3426 1.4.12
+d3730d84ba7eda92fd3469a3f63fd6d8cb22c975 1.4.13
+12c1ae8e7c5345721e9ec9f8e27b1e36c07f74dc 1.4.14
+12c1ae8e7c5345721e9ec9f8e27b1e36c07f74dc 1.4.14
+0000000000000000000000000000000000000000 1.4.14
+0000000000000000000000000000000000000000 1.4.14
+1497e2efd0f8c73a0e3d529debf0c489e4cd6cab 1.4.14
+e065014c1ce8ad110a381e9baaaa5d647ba7ac6b 1.4.15
+e9e5b38f53dc35b35aa1f9ee9a9be9bbd2d2c3b1 1.4.16
+c603503945f52b78522d96a423605cbc953236d3 1.4.17
+c59201105a29801cc858eb9160b7a19791b91a35 1.4.18
+284cc172e294d48edc840012e1451c32c3963d92 1.4.19
+a3e0626aa0c5aecf271367dc77e476ab216ea3c8 1.4.20
+5e48016c4a3af8e7358a1267d33d021e71765bed 1.4.21
+01ae2cfcc61c4fcb3aa5031349adb5b467c31018 1.4.23
+5ffd982f4dff60b588f309cd9bdc61036547282a 1.4.24
+dc9ffbcaf1f7d72e96be3f68c11deebb7e7193c5 1.4.25
+6de1a44bf75de7af4fcae947c235e9072bbdbb9a 1.4.26
+7d650ba2657890a2253c8c4a83f170febebd90fa 1.4.27
+7d650ba2657890a2253c8c4a83f170febebd90fa 1.4.27
+1810003dec63dd1b506a23849861fffa5bc3ba13 1.4.27
+ba08706f08ddea1b77a426f00dfe2bdc244345e8 1.4.28
+4e8054ada63f3327bcf759ae7cd36c7c8652bc9b 1.4.29
+366ab346610c6de8aaa7617e24011794b40236c6 1.4.30
diff --git a/tests/wpt/web-platform-tests/tools/py/AUTHORS b/tests/wpt/web-platform-tests/tools/py/AUTHORS
new file mode 100644
index 00000000000..8c0cf9b71b1
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/AUTHORS
@@ -0,0 +1,24 @@
+Holger Krekel, holger at merlinux eu
+Benjamin Peterson, benjamin at python org
+Ronny Pfannschmidt, Ronny.Pfannschmidt at gmx de
+Guido Wesdorp, johnny at johnnydebris net
+Samuele Pedroni, pedronis at openend se
+Carl Friedrich Bolz, cfbolz at gmx de
+Armin Rigo, arigo at tunes org
+Maciek Fijalkowski, fijal at genesilico pl
+Brian Dorsey, briandorsey at gmail com
+Floris Bruynooghe, flub at devork be
+merlinux GmbH, Germany, office at merlinux eu
+
+Contributors include::
+
+Ross Lawley
+Ralf Schmitt
+Chris Lamb
+Harald Armin Massa
+Martijn Faassen
+Ian Bicking
+Jan Balster
+Grig Gheorghiu
+Bob Ippolito
+Christian Tismer
diff --git a/tests/wpt/web-platform-tests/tools/py/CHANGELOG b/tests/wpt/web-platform-tests/tools/py/CHANGELOG
new file mode 100644
index 00000000000..712fc4c5389
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/CHANGELOG
@@ -0,0 +1,1089 @@
+1.4.31
+==================================================
+
+- fix local().copy(dest, mode=True) to also work
+ with unicode.
+
+- pass better error message with svn EEXIST paths
+
+1.4.30
+==================================================
+
+- fix issue68 an assert with a multiline list comprehension
+ was not reported correctly. Thanks Henrik Heibuerger.
+
+
+1.4.29
+==================================================
+
+- fix issue55: revert a change to the statement finding algorithm
+ which is used by pytest for generating tracebacks.
+ Thanks Daniel Hahler for initial analysis.
+
+- fix pytest issue254 for when traceback rendering can't
+ find valid source code. Thanks Ionel Cristian Maries.
+
+
+1.4.28
+==================================================
+
+- fix issue64 -- dirpath regression when "abs=True" is passed.
+ Thanks Gilles Dartiguelongue.
+
+1.4.27
+==================================================
+
+- fix issue59: point to new repo site
+
+- allow a new ensuresyspath="append" mode for py.path.local.pyimport()
+ so that a neccessary import path is appended instead of prepended to
+ sys.path
+
+- strike undocumented, untested argument to py.path.local.pypkgpath
+
+- speed up py.path.local.dirpath by a factor of 10
+
+1.4.26
+==================================================
+
+- avoid calling normpath twice in py.path.local
+
+- py.builtin._reraise properly reraises under Python3 now.
+
+- fix issue53 - remove module index, thanks jenisys.
+
+- allow posix path separators when "fnmatch" is called.
+ Thanks Christian Long for the complete PR.
+
+1.4.25
+==================================================
+
+- fix issue52: vaguely fix py25 compat of py.path.local (it's not
+ officially supported), also fix docs
+
+- fix pytest issue 589: when checking if we have a recursion error
+ check for the specific "maximum recursion depth" text of the exception.
+
+1.4.24
+==================================================
+
+- Fix retrieving source when an else: line has an other statement on
+ the same line.
+
+- add localpath read_text/write_text/read_bytes/write_bytes methods
+ as shortcuts and clearer bytes/text interfaces for read/write.
+ Adapted from a PR from Paul Moore.
+
+
+1.4.23
+==================================================
+
+- use newer apipkg version which makes attribute access on
+ alias modules resolve to None rather than an ImportError.
+ This helps with code that uses inspect.getframeinfo()
+ on py34 which causes a complete walk on sys.modules
+ thus triggering the alias module to resolve and blowing
+ up with ImportError. The negative side is that something
+ like "py.test.X" will now result in None instead of "importerror: pytest"
+ if pytest is not installed. But you shouldn't import "py.test"
+ anyway anymore.
+
+- adapt one svn test to only check for any exception instead
+ of specific ones because different svn versions cause different
+ errors and we don't care.
+
+
+1.4.22
+==================================================
+
+- refactor class-level registry on ForkedFunc child start/finish
+ event to become instance based (i.e. passed into the constructor)
+
+1.4.21
+==================================================
+
+- ForkedFunc now has class-level register_on_start/on_exit()
+ methods to allow adding information in the boxed process.
+ Thanks Marc Schlaich.
+
+- ForkedFunc in the child opens in "auto-flush" mode for
+ stdout/stderr so that when a subprocess dies you can see
+ its output even if it didn't flush itself.
+
+- refactor traceback generation in light of pytest issue 364
+ (shortening tracebacks). you can now set a new traceback style
+ on a per-entry basis such that a caller can force entries to be
+ isplayed as short or long entries.
+
+- win32: py.path.local.sysfind(name) will preferrably return files with
+ extensions so that if "X" and "X.bat" or "X.exe" is on the PATH,
+ one of the latter two will be returned.
+
+1.4.20
+==================================================
+
+- ignore unicode decode errors in xmlescape. Thanks Anatoly Bubenkoff.
+
+- on python2 modify traceback.format_exception_only to match python3
+ behaviour, namely trying to print unicode for Exception instances
+
+- use a safer way for serializing exception reports (helps to fix
+ pytest issue413)
+
+Changes between 1.4.18 and 1.4.19
+==================================================
+
+- merge in apipkg fixes
+
+- some micro-optimizations in py/_code/code.py for speeding
+ up pytest runs. Thanks Alex Gaynor for initiative.
+
+- check PY_COLORS=1 or PY_COLORS=0 to force coloring/not-coloring
+ for py.io.TerminalWriter() independently from capabilities
+ of the output file. Thanks Marc Abramowitz for the PR.
+
+- some fixes to unicode handling in assertion handling.
+ Thanks for the PR to Floris Bruynooghe. (This helps
+ to fix pytest issue 319).
+
+- depend on setuptools presence, remove distribute_setup
+
+Changes between 1.4.17 and 1.4.18
+==================================================
+
+- introduce path.ensure_dir() as a synonym for ensure(..., dir=1)
+
+- some unicode/python3 related fixes wrt to path manipulations
+ (if you start passing unicode particular in py2 you might
+ still get problems, though)
+
+Changes between 1.4.16 and 1.4.17
+==================================================
+
+- make py.io.TerminalWriter() prefer colorama if it is available
+ and avoid empty lines when separator-lines are printed by
+ being defensive and reducing the working terminalwidth by 1
+
+- introduce optional "expanduser" argument to py.path.local
+ to that local("~", expanduser=True) gives the home
+ directory of "user".
+
+Changes between 1.4.15 and 1.4.16
+==================================================
+
+- fix issue35 - define __gt__ ordering between a local path
+ and strings
+
+- fix issue36 - make chdir() work even if os.getcwd() fails.
+
+- add path.exists/isdir/isfile/islink shortcuts
+
+- introduce local path.as_cwd() context manager.
+
+- introduce p.write(ensure=1) and p.open(ensure=1)
+ where ensure triggers creation of neccessary parent
+ dirs.
+
+
+Changes between 1.4.14 and 1.4.15
+==================================================
+
+- majorly speed up some common calling patterns with
+ LocalPath.listdir()/join/check/stat functions considerably.
+
+- fix an edge case with fnmatch where a glob style pattern appeared
+ in an absolute path.
+
+Changes between 1.4.13 and 1.4.14
+==================================================
+
+- fix dupfile to work with files that don't
+ carry a mode. Thanks Jason R. Coombs.
+
+Changes between 1.4.12 and 1.4.13
+==================================================
+
+- fix getting statementrange/compiling a file ending
+ in a comment line without newline (on python2.5)
+- for local paths you can pass "mode=True" to a copy()
+ in order to copy permission bits (underlying mechanism
+ is using shutil.copymode)
+- add paths arguments to py.path.local.sysfind to restrict
+ search to the diretories in the path.
+- add isdir/isfile/islink to path.stat() objects allowing to perform
+ multiple checks without calling out multiple times
+- drop py.path.local.__new__ in favour of a simpler __init__
+- iniconfig: allow "name:value" settings in config files, no space after
+ "name" required
+- fix issue 27 - NameError in unlikely untested case of saferepr
+
+
+Changes between 1.4.11 and 1.4.12
+==================================================
+
+- fix python2.4 support - for pre-AST interpreters re-introduce
+ old way to find statements in exceptions (closes pytest issue 209)
+- add tox.ini to distribution
+- fix issue23 - print *,** args information in tracebacks,
+ thanks Manuel Jacob
+
+
+Changes between 1.4.10 and 1.4.11
+==================================================
+
+- use _ast to determine statement ranges when printing tracebacks -
+ avoiding multi-second delays on some large test modules
+- fix an internal test to not use class-denoted pytest_funcarg__
+- fix a doc link to bug tracker
+- try to make terminal.write() printing more robust against
+ unicodeencode/decode problems, amend according test
+- introduce py.builtin.text and py.builtin.bytes
+ to point to respective str/unicode (py2) and bytes/str (py3) types
+- fix error handling on win32/py33 for ENODIR
+
+Changes between 1.4.9 and 1.4.10
+==================================================
+
+- terminalwriter: default to encode to UTF8 if no encoding is defined
+ on the output stream
+- issue22: improve heuristic for finding the statementrange in exceptions
+
+Changes between 1.4.8 and 1.4.9
+==================================================
+
+- fix bug of path.visit() which would not recognize glob-style patterns
+ for the "rec" recursion argument
+- changed iniconfig parsing to better conform, now the chars ";"
+ and "#" only mark a comment at the stripped start of a line
+- include recent apipkg-1.2
+- change internal terminalwriter.line/reline logic to more nicely
+ support file spinners
+
+Changes between 1.4.7 and 1.4.8
+==================================================
+
+- fix issue 13 - correct handling of the tag name object in xmlgen
+- fix issue 14 - support raw attribute values in xmlgen
+- fix windows terminalwriter printing/re-line problem
+- update distribute_setup.py to 0.6.27
+
+Changes between 1.4.6 and 1.4.7
+==================================================
+
+- fix issue11 - own test failure with python3.3 / Thanks Benjamin Peterson
+- help fix pytest issue 102
+
+Changes between 1.4.5 and 1.4.6
+==================================================
+
+- help to fix pytest issue99: unify output of
+ ExceptionInfo.getrepr(style="native") with ...(style="long")
+- fix issue7: source.getstatementrange() now raises proper error
+ if no valid statement can be found
+- fix issue8: fix code and tests of svnurl/svnwc to work on subversion 1.7 -
+ note that path.status(updates=1) will not properly work svn-17's status
+ --xml output is broken.
+- make source.getstatementrange() more resilent about non-python code frames
+ (as seen from jnja2)
+- make trackeback recursion detection more resilent
+ about the eval magic of a decorator library
+- iniconfig: add support for ; as comment starter
+- properly handle lists in xmlgen on python3
+- normalize py.code.getfslineno(obj) to always return a (string, int) tuple
+ defaulting to ("", -1) respectively if no source code can be found for obj.
+
+Changes between 1.4.4 and 1.4.5
+==================================================
+
+- improve some unicode handling in terminalwriter and capturing
+ (used by pytest)
+
+Changes between 1.4.3 and 1.4.4
+==================================================
+
+- a few fixes and assertion related refinements for pytest-2.1
+- guard py.code.Code and getfslineno against bogus input
+ and make py.code.Code objects for object instance
+ by looking up their __call__ function.
+- make exception presentation robust against invalid current cwd
+
+Changes between 1.4.2 and 1.4.3
+==================================================
+
+- fix terminal coloring issue for skipped tests (thanks Amaury)
+- fix issue4 - large calls to ansi_print (thanks Amaury)
+
+Changes between 1.4.1 and 1.4.2
+==================================================
+
+- fix (pytest) issue23 - tmpdir argument now works on Python3.2 and WindowsXP
+ (which apparently starts to offer os.symlink now)
+
+- better error message for syntax errors from compiled code
+
+- small fix to better deal with (un-)colored terminal output on windows
+
+Changes between 1.4.0 and 1.4.1
+==================================================
+
+- fix issue1 - py.error.* classes to be pickleable
+
+- fix issue2 - on windows32 use PATHEXT as the list of potential
+ extensions to find find binaries with py.path.local.sysfind(commandname)
+
+- fix (pytest-) issue10 and refine assertion reinterpretation
+ to avoid breaking if the __nonzero__ of an object fails
+
+- fix (pytest-) issue17 where python3 does not like "import *"
+ leading to misrepresentation of import-errors in test modules
+
+- fix py.error.* attribute pypy access issue
+
+- allow path.samefile(arg) to succeed when arg is a relative filename
+
+- fix (pytest-) issue20 path.samefile(relpath) works as expected now
+
+- fix (pytest-) issue8 len(long_list) now shows the lenght of the list
+
+Changes between 1.3.4 and 1.4.0
+==================================================
+
+- py.test was moved to a separate "pytest" package. What remains is
+ a stub hook which will proxy ``import py.test`` to ``pytest``.
+- all command line tools ("py.cleanup/lookup/countloc/..." moved
+ to "pycmd" package)
+- removed the old and deprecated "py.magic" namespace
+- use apipkg-1.1 and make py.apipkg.initpkg|ApiModule available
+- add py.iniconfig module for brain-dead easy ini-config file parsing
+- introduce py.builtin.any()
+- path objects have a .dirname attribute now (equivalent to
+ os.path.dirname(path))
+- path.visit() accepts breadthfirst (bf) and sort options
+- remove deprecated py.compat namespace
+
+Changes between 1.3.3 and 1.3.4
+==================================================
+
+- fix issue111: improve install documentation for windows
+- fix issue119: fix custom collectability of __init__.py as a module
+- fix issue116: --doctestmodules work with __init__.py files as well
+- fix issue115: unify internal exception passthrough/catching/GeneratorExit
+- fix issue118: new --tb=native for presenting cpython-standard exceptions
+
+Changes between 1.3.2 and 1.3.3
+==================================================
+
+- fix issue113: assertion representation problem with triple-quoted strings
+ (and possibly other cases)
+- make conftest loading detect that a conftest file with the same
+ content was already loaded, avoids surprises in nested directory structures
+ which can be produced e.g. by Hudson. It probably removes the need to use
+ --confcutdir in most cases.
+- fix terminal coloring for win32
+ (thanks Michael Foord for reporting)
+- fix weirdness: make terminal width detection work on stdout instead of stdin
+ (thanks Armin Ronacher for reporting)
+- remove trailing whitespace in all py/text distribution files
+
+Changes between 1.3.1 and 1.3.2
+==================================================
+
+New features
+++++++++++++++++++
+
+- fix issue103: introduce py.test.raises as context manager, examples::
+
+ with py.test.raises(ZeroDivisionError):
+ x = 0
+ 1 / x
+
+ with py.test.raises(RuntimeError) as excinfo:
+ call_something()
+
+ # you may do extra checks on excinfo.value|type|traceback here
+
+ (thanks Ronny Pfannschmidt)
+
+- Funcarg factories can now dynamically apply a marker to a
+ test invocation. This is for example useful if a factory
+ provides parameters to a test which are expected-to-fail::
+
+ def pytest_funcarg__arg(request):
+ request.applymarker(py.test.mark.xfail(reason="flaky config"))
+ ...
+
+ def test_function(arg):
+ ...
+
+- improved error reporting on collection and import errors. This makes
+ use of a more general mechanism, namely that for custom test item/collect
+ nodes ``node.repr_failure(excinfo)`` is now uniformly called so that you can
+ override it to return a string error representation of your choice
+ which is going to be reported as a (red) string.
+
+- introduce '--junitprefix=STR' option to prepend a prefix
+ to all reports in the junitxml file.
+
+Bug fixes / Maintenance
+++++++++++++++++++++++++++
+
+- make tests and the ``pytest_recwarn`` plugin in particular fully compatible
+ to Python2.7 (if you use the ``recwarn`` funcarg warnings will be enabled so that
+ you can properly check for their existence in a cross-python manner).
+- refine --pdb: ignore xfailed tests, unify its TB-reporting and
+ don't display failures again at the end.
+- fix assertion interpretation with the ** operator (thanks Benjamin Peterson)
+- fix issue105 assignment on the same line as a failing assertion (thanks Benjamin Peterson)
+- fix issue104 proper escaping for test names in junitxml plugin (thanks anonymous)
+- fix issue57 -f|--looponfail to work with xpassing tests (thanks Ronny)
+- fix issue92 collectonly reporter and --pastebin (thanks Benjamin Peterson)
+- fix py.code.compile(source) to generate unique filenames
+- fix assertion re-interp problems on PyPy, by defering code
+ compilation to the (overridable) Frame.eval class. (thanks Amaury Forgeot)
+- fix py.path.local.pyimport() to work with directories
+- streamline py.path.local.mkdtemp implementation and usage
+- don't print empty lines when showing junitxml-filename
+- add optional boolean ignore_errors parameter to py.path.local.remove
+- fix terminal writing on win32/python2.4
+- py.process.cmdexec() now tries harder to return properly encoded unicode objects
+ on all python versions
+- install plain py.test/py.which scripts also for Jython, this helps to
+ get canonical script paths in virtualenv situations
+- make path.bestrelpath(path) return ".", note that when calling
+ X.bestrelpath the assumption is that X is a directory.
+- make initial conftest discovery ignore "--" prefixed arguments
+- fix resultlog plugin when used in an multicpu/multihost xdist situation
+ (thanks Jakub Gustak)
+- perform distributed testing related reporting in the xdist-plugin
+ rather than having dist-related code in the generic py.test
+ distribution
+- fix homedir detection on Windows
+- ship distribute_setup.py version 0.6.13
+
+Changes between 1.3.0 and 1.3.1
+==================================================
+
+New features
+++++++++++++++++++
+
+- issue91: introduce new py.test.xfail(reason) helper
+ to imperatively mark a test as expected to fail. Can
+ be used from within setup and test functions. This is
+ useful especially for parametrized tests when certain
+ configurations are expected-to-fail. In this case the
+ declarative approach with the @py.test.mark.xfail cannot
+ be used as it would mark all configurations as xfail.
+
+- issue102: introduce new --maxfail=NUM option to stop
+ test runs after NUM failures. This is a generalization
+ of the '-x' or '--exitfirst' option which is now equivalent
+ to '--maxfail=1'. Both '-x' and '--maxfail' will
+ now also print a line near the end indicating the Interruption.
+
+- issue89: allow py.test.mark decorators to be used on classes
+ (class decorators were introduced with python2.6) and
+ also allow to have multiple markers applied at class/module level
+ by specifying a list.
+
+- improve and refine letter reporting in the progress bar:
+ . pass
+ f failed test
+ s skipped tests (reminder: use for dependency/platform mismatch only)
+ x xfailed test (test that was expected to fail)
+ X xpassed test (test that was expected to fail but passed)
+
+ You can use any combination of 'fsxX' with the '-r' extended
+ reporting option. The xfail/xpass results will show up as
+ skipped tests in the junitxml output - which also fixes
+ issue99.
+
+- make py.test.cmdline.main() return the exitstatus instead of raising
+ SystemExit and also allow it to be called multiple times. This of
+ course requires that your application and tests are properly teared
+ down and don't have global state.
+
+Fixes / Maintenance
+++++++++++++++++++++++
+
+- improved traceback presentation:
+ - improved and unified reporting for "--tb=short" option
+ - Errors during test module imports are much shorter, (using --tb=short style)
+ - raises shows shorter more relevant tracebacks
+ - --fulltrace now more systematically makes traces longer / inhibits cutting
+
+- improve support for raises and other dynamically compiled code by
+ manipulating python's linecache.cache instead of the previous
+ rather hacky way of creating custom code objects. This makes
+ it seemlessly work on Jython and PyPy where it previously didn't.
+
+- fix issue96: make capturing more resilient against Control-C
+ interruptions (involved somewhat substantial refactoring
+ to the underlying capturing functionality to avoid race
+ conditions).
+
+- fix chaining of conditional skipif/xfail decorators - so it works now
+ as expected to use multiple @py.test.mark.skipif(condition) decorators,
+ including specific reporting which of the conditions lead to skipping.
+
+- fix issue95: late-import zlib so that it's not required
+ for general py.test startup.
+
+- fix issue94: make reporting more robust against bogus source code
+ (and internally be more careful when presenting unexpected byte sequences)
+
+
+Changes between 1.2.1 and 1.3.0
+==================================================
+
+- deprecate --report option in favour of a new shorter and easier to
+ remember -r option: it takes a string argument consisting of any
+ combination of 'xfsX' characters. They relate to the single chars
+ you see during the dotted progress printing and will print an extra line
+ per test at the end of the test run. This extra line indicates the exact
+ position or test ID that you directly paste to the py.test cmdline in order
+ to re-run a particular test.
+
+- allow external plugins to register new hooks via the new
+ pytest_addhooks(pluginmanager) hook. The new release of
+ the pytest-xdist plugin for distributed and looponfailing
+ testing requires this feature.
+
+- add a new pytest_ignore_collect(path, config) hook to allow projects and
+ plugins to define exclusion behaviour for their directory structure -
+ for example you may define in a conftest.py this method::
+
+ def pytest_ignore_collect(path):
+ return path.check(link=1)
+
+ to prevent even a collection try of any tests in symlinked dirs.
+
+- new pytest_pycollect_makemodule(path, parent) hook for
+ allowing customization of the Module collection object for a
+ matching test module.
+
+- extend and refine xfail mechanism:
+ ``@py.test.mark.xfail(run=False)`` do not run the decorated test
+ ``@py.test.mark.xfail(reason="...")`` prints the reason string in xfail summaries
+ specifiying ``--runxfail`` on command line virtually ignores xfail markers
+
+- expose (previously internal) commonly useful methods:
+ py.io.get_terminal_with() -> return terminal width
+ py.io.ansi_print(...) -> print colored/bold text on linux/win32
+ py.io.saferepr(obj) -> return limited representation string
+
+- expose test outcome related exceptions as py.test.skip.Exception,
+ py.test.raises.Exception etc., useful mostly for plugins
+ doing special outcome interpretation/tweaking
+
+- (issue85) fix junitxml plugin to handle tests with non-ascii output
+
+- fix/refine python3 compatibility (thanks Benjamin Peterson)
+
+- fixes for making the jython/win32 combination work, note however:
+ jython2.5.1/win32 does not provide a command line launcher, see
+ http://bugs.jython.org/issue1491 . See pylib install documentation
+ for how to work around.
+
+- fixes for handling of unicode exception values and unprintable objects
+
+- (issue87) fix unboundlocal error in assertionold code
+
+- (issue86) improve documentation for looponfailing
+
+- refine IO capturing: stdin-redirect pseudo-file now has a NOP close() method
+
+- ship distribute_setup.py version 0.6.10
+
+- added links to the new capturelog and coverage plugins
+
+
+Changes between 1.2.1 and 1.2.0
+=====================================
+
+- refined usage and options for "py.cleanup"::
+
+ py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
+ py.cleanup -e .swp -e .cache # also remove files with these extensions
+ py.cleanup -s # remove "build" and "dist" directory next to setup.py files
+ py.cleanup -d # also remove empty directories
+ py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
+ py.cleanup -n # dry run, only show what would be removed
+
+- add a new option "py.test --funcargs" which shows available funcargs
+ and their help strings (docstrings on their respective factory function)
+ for a given test path
+
+- display a short and concise traceback if a funcarg lookup fails
+
+- early-load "conftest.py" files in non-dot first-level sub directories.
+ allows to conveniently keep and access test-related options in a ``test``
+ subdir and still add command line options.
+
+- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
+
+- fix issue78: always call python-level teardown functions even if the
+ according setup failed. This includes refinements for calling setup_module/class functions
+ which will now only be called once instead of the previous behaviour where they'd be called
+ multiple times if they raise an exception (including a Skipped exception). Any exception
+ will be re-corded and associated with all tests in the according module/class scope.
+
+- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
+
+- fix pdb debugging to be in the correct frame on raises-related errors
+
+- update apipkg.py to fix an issue where recursive imports might
+ unnecessarily break importing
+
+- fix plugin links
+
+Changes between 1.2 and 1.1.1
+=====================================
+
+- moved dist/looponfailing from py.test core into a new
+ separately released pytest-xdist plugin.
+
+- new junitxml plugin: --junitxml=path will generate a junit style xml file
+ which is processable e.g. by the Hudson CI system.
+
+- new option: --genscript=path will generate a standalone py.test script
+ which will not need any libraries installed. thanks to Ralf Schmitt.
+
+- new option: --ignore will prevent specified path from collection.
+ Can be specified multiple times.
+
+- new option: --confcutdir=dir will make py.test only consider conftest
+ files that are relative to the specified dir.
+
+- new funcarg: "pytestconfig" is the pytest config object for access
+ to command line args and can now be easily used in a test.
+
+- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
+ disambiguate between Python3, python2.X, Jython and PyPy installed versions.
+
+- new "pytestconfig" funcarg allows access to test config object
+
+- new "pytest_report_header" hook can return additional lines
+ to be displayed at the header of a test run.
+
+- (experimental) allow "py.test path::name1::name2::..." for pointing
+ to a test within a test collection directly. This might eventually
+ evolve as a full substitute to "-k" specifications.
+
+- streamlined plugin loading: order is now as documented in
+ customize.html: setuptools, ENV, commandline, conftest.
+ also setuptools entry point names are turned to canonical namees ("pytest_*")
+
+- automatically skip tests that need 'capfd' but have no os.dup
+
+- allow pytest_generate_tests to be defined in classes as well
+
+- deprecate usage of 'disabled' attribute in favour of pytestmark
+- deprecate definition of Directory, Module, Class and Function nodes
+ in conftest.py files. Use pytest collect hooks instead.
+
+- collection/item node specific runtest/collect hooks are only called exactly
+ on matching conftest.py files, i.e. ones which are exactly below
+ the filesystem path of an item
+
+- change: the first pytest_collect_directory hook to return something
+ will now prevent further hooks to be called.
+
+- change: figleaf plugin now requires --figleaf to run. Also
+ change its long command line options to be a bit shorter (see py.test -h).
+
+- change: pytest doctest plugin is now enabled by default and has a
+ new option --doctest-glob to set a pattern for file matches.
+
+- change: remove internal py._* helper vars, only keep py._pydir
+
+- robustify capturing to survive if custom pytest_runtest_setup
+ code failed and prevented the capturing setup code from running.
+
+- make py.test.* helpers provided by default plugins visible early -
+ works transparently both for pydoc and for interactive sessions
+ which will regularly see e.g. py.test.mark and py.test.importorskip.
+
+- simplify internal plugin manager machinery
+- simplify internal collection tree by introducing a RootCollector node
+
+- fix assert reinterpreation that sees a call containing "keyword=..."
+
+- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
+ hooks on slaves during dist-testing, report module/session teardown
+ hooks correctly.
+
+- fix issue65: properly handle dist-testing if no
+ execnet/py lib installed remotely.
+
+- skip some install-tests if no execnet is available
+
+- fix docs, fix internal bin/ script generation
+
+
+Changes between 1.1.1 and 1.1.0
+=====================================
+
+- introduce automatic plugin registration via 'pytest11'
+ entrypoints via setuptools' pkg_resources.iter_entry_points
+
+- fix py.test dist-testing to work with execnet >= 1.0.0b4
+
+- re-introduce py.test.cmdline.main() for better backward compatibility
+
+- svn paths: fix a bug with path.check(versioned=True) for svn paths,
+ allow '%' in svn paths, make svnwc.update() default to interactive mode
+ like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
+
+- refine distributed tarball to contain test and no pyc files
+
+- try harder to have deprecation warnings for py.compat.* accesses
+ report a correct location
+
+Changes between 1.1.0 and 1.0.2
+=====================================
+
+* adjust and improve docs
+
+* remove py.rest tool and internal namespace - it was
+ never really advertised and can still be used with
+ the old release if needed. If there is interest
+ it could be revived into its own tool i guess.
+
+* fix issue48 and issue59: raise an Error if the module
+ from an imported test file does not seem to come from
+ the filepath - avoids "same-name" confusion that has
+ been reported repeatedly
+
+* merged Ronny's nose-compatibility hacks: now
+ nose-style setup_module() and setup() functions are
+ supported
+
+* introduce generalized py.test.mark function marking
+
+* reshuffle / refine command line grouping
+
+* deprecate parser.addgroup in favour of getgroup which creates option group
+
+* add --report command line option that allows to control showing of skipped/xfailed sections
+
+* generalized skipping: a new way to mark python functions with skipif or xfail
+ at function, class and modules level based on platform or sys-module attributes.
+
+* extend py.test.mark decorator to allow for positional args
+
+* introduce and test "py.cleanup -d" to remove empty directories
+
+* fix issue #59 - robustify unittest test collection
+
+* make bpython/help interaction work by adding an __all__ attribute
+ to ApiModule, cleanup initpkg
+
+* use MIT license for pylib, add some contributors
+
+* remove py.execnet code and substitute all usages with 'execnet' proper
+
+* fix issue50 - cached_setup now caches more to expectations
+ for test functions with multiple arguments.
+
+* merge Jarko's fixes, issue #45 and #46
+
+* add the ability to specify a path for py.lookup to search in
+
+* fix a funcarg cached_setup bug probably only occuring
+ in distributed testing and "module" scope with teardown.
+
+* many fixes and changes for making the code base python3 compatible,
+ many thanks to Benjamin Peterson for helping with this.
+
+* consolidate builtins implementation to be compatible with >=2.3,
+ add helpers to ease keeping 2 and 3k compatible code
+
+* deprecate py.compat.doctest|subprocess|textwrap|optparse
+
+* deprecate py.magic.autopath, remove py/magic directory
+
+* move pytest assertion handling to py/code and a pytest_assertion
+ plugin, add "--no-assert" option, deprecate py.magic namespaces
+ in favour of (less) py.code ones.
+
+* consolidate and cleanup py/code classes and files
+
+* cleanup py/misc, move tests to bin-for-dist
+
+* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
+
+* consolidate py.log implementation, remove old approach.
+
+* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
+ text/unicode and byte-streams (uses underlying standard lib io.*
+ if available)
+
+* make py.unittest_convert helper script available which converts "unittest.py"
+ style files into the simpler assert/direct-test-classes py.test/nosetests
+ style. The script was written by Laura Creighton.
+
+* simplified internal localpath implementation
+
+Changes between 1.0.1 and 1.0.2
+=====================================
+
+* fixing packaging issues, triggered by fedora redhat packaging,
+ also added doc, examples and contrib dirs to the tarball.
+
+* added a documentation link to the new django plugin.
+
+Changes between 1.0.0 and 1.0.1
+=====================================
+
+* added a 'pytest_nose' plugin which handles nose.SkipTest,
+ nose-style function/method/generator setup/teardown and
+ tries to report functions correctly.
+
+* capturing of unicode writes or encoded strings to sys.stdout/err
+ work better, also terminalwriting was adapted and somewhat
+ unified between windows and linux.
+
+* improved documentation layout and content a lot
+
+* added a "--help-config" option to show conftest.py / ENV-var names for
+ all longopt cmdline options, and some special conftest.py variables.
+ renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
+
+* fix issue #27: better reporting on non-collectable items given on commandline
+ (e.g. pyc files)
+
+* fix issue #33: added --version flag (thanks Benjamin Peterson)
+
+* fix issue #32: adding support for "incomplete" paths to wcpath.status()
+
+* "Test" prefixed classes are *not* collected by default anymore if they
+ have an __init__ method
+
+* monkeypatch setenv() now accepts a "prepend" parameter
+
+* improved reporting of collection error tracebacks
+
+* simplified multicall mechanism and plugin architecture,
+ renamed some internal methods and argnames
+
+Changes between 1.0.0b9 and 1.0.0
+=====================================
+
+* more terse reporting try to show filesystem path relatively to current dir
+* improve xfail output a bit
+
+Changes between 1.0.0b8 and 1.0.0b9
+=====================================
+
+* cleanly handle and report final teardown of test setup
+
+* fix svn-1.6 compat issue with py.path.svnwc().versioned()
+ (thanks Wouter Vanden Hove)
+
+* setup/teardown or collection problems now show as ERRORs
+ or with big "E"'s in the progress lines. they are reported
+ and counted separately.
+
+* dist-testing: properly handle test items that get locally
+ collected but cannot be collected on the remote side - often
+ due to platform/dependency reasons
+
+* simplified py.test.mark API - see keyword plugin documentation
+
+* integrate better with logging: capturing now by default captures
+ test functions and their immediate setup/teardown in a single stream
+
+* capsys and capfd funcargs now have a readouterr() and a close() method
+ (underlyingly py.io.StdCapture/FD objects are used which grew a
+ readouterr() method as well to return snapshots of captured out/err)
+
+* make assert-reinterpretation work better with comparisons not
+ returning bools (reported with numpy from thanks maciej fijalkowski)
+
+* reworked per-test output capturing into the pytest_iocapture.py plugin
+ and thus removed capturing code from config object
+
+* item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr)
+
+
+Changes between 1.0.0b7 and 1.0.0b8
+=====================================
+
+* pytest_unittest-plugin is now enabled by default
+
+* introduced pytest_keyboardinterrupt hook and
+ refined pytest_sessionfinish hooked, added tests.
+
+* workaround a buggy logging module interaction ("closing already closed
+ files"). Thanks to Sridhar Ratnakumar for triggering.
+
+* if plugins use "py.test.importorskip" for importing
+ a dependency only a warning will be issued instead
+ of exiting the testing process.
+
+* many improvements to docs:
+ - refined funcargs doc , use the term "factory" instead of "provider"
+ - added a new talk/tutorial doc page
+ - better download page
+ - better plugin docstrings
+ - added new plugins page and automatic doc generation script
+
+* fixed teardown problem related to partially failing funcarg setups
+ (thanks MrTopf for reporting), "pytest_runtest_teardown" is now
+ always invoked even if the "pytest_runtest_setup" failed.
+
+* tweaked doctest output for docstrings in py modules,
+ thanks Radomir.
+
+Changes between 1.0.0b3 and 1.0.0b7
+=============================================
+
+* renamed py.test.xfail back to py.test.mark.xfail to avoid
+ two ways to decorate for xfail
+
+* re-added py.test.mark decorator for setting keywords on functions
+ (it was actually documented so removing it was not nice)
+
+* remove scope-argument from request.addfinalizer() because
+ request.cached_setup has the scope arg. TOOWTDI.
+
+* perform setup finalization before reporting failures
+
+* apply modified patches from Andreas Kloeckner to allow
+ test functions to have no func_code (#22) and to make
+ "-k" and function keywords work (#20)
+
+* apply patch from Daniel Peolzleithner (issue #23)
+
+* resolve issue #18, multiprocessing.Manager() and
+ redirection clash
+
+* make __name__ == "__channelexec__" for remote_exec code
+
+Changes between 1.0.0b1 and 1.0.0b3
+=============================================
+
+* plugin classes are removed: one now defines
+ hooks directly in conftest.py or global pytest_*.py
+ files.
+
+* added new pytest_namespace(config) hook that allows
+ to inject helpers directly to the py.test.* namespace.
+
+* documented and refined many hooks
+
+* added new style of generative tests via
+ pytest_generate_tests hook that integrates
+ well with function arguments.
+
+
+Changes between 0.9.2 and 1.0.0b1
+=============================================
+
+* introduced new "funcarg" setup method,
+ see doc/test/funcarg.txt
+
+* introduced plugin architecuture and many
+ new py.test plugins, see
+ doc/test/plugins.txt
+
+* teardown_method is now guaranteed to get
+ called after a test method has run.
+
+* new method: py.test.importorskip(mod,minversion)
+ will either import or call py.test.skip()
+
+* completely revised internal py.test architecture
+
+* new py.process.ForkedFunc object allowing to
+ fork execution of a function to a sub process
+ and getting a result back.
+
+XXX lots of things missing here XXX
+
+Changes between 0.9.1 and 0.9.2
+===============================
+
+* refined installation and metadata, created new setup.py,
+ now based on setuptools/ez_setup (thanks to Ralf Schmitt
+ for his support).
+
+* improved the way of making py.* scripts available in
+ windows environments, they are now added to the
+ Scripts directory as ".cmd" files.
+
+* py.path.svnwc.status() now is more complete and
+ uses xml output from the 'svn' command if available
+ (Guido Wesdorp)
+
+* fix for py.path.svn* to work with svn 1.5
+ (Chris Lamb)
+
+* fix path.relto(otherpath) method on windows to
+ use normcase for checking if a path is relative.
+
+* py.test's traceback is better parseable from editors
+ (follows the filenames:LINENO: MSG convention)
+ (thanks to Osmo Salomaa)
+
+* fix to javascript-generation, "py.test --runbrowser"
+ should work more reliably now
+
+* removed previously accidentally added
+ py.test.broken and py.test.notimplemented helpers.
+
+* there now is a py.__version__ attribute
+
+Changes between 0.9.0 and 0.9.1
+===============================
+
+This is a fairly complete list of changes between 0.9 and 0.9.1, which can
+serve as a reference for developers.
+
+* allowing + signs in py.path.svn urls [39106]
+* fixed support for Failed exceptions without excinfo in py.test [39340]
+* added support for killing processes for Windows (as well as platforms that
+ support os.kill) in py.misc.killproc [39655]
+* added setup/teardown for generative tests to py.test [40702]
+* added detection of FAILED TO LOAD MODULE to py.test [40703, 40738, 40739]
+* fixed problem with calling .remove() on wcpaths of non-versioned files in
+ py.path [44248]
+* fixed some import and inheritance issues in py.test [41480, 44648, 44655]
+* fail to run greenlet tests when pypy is available, but without stackless
+ [45294]
+* small fixes in rsession tests [45295]
+* fixed issue with 2.5 type representations in py.test [45483, 45484]
+* made that internal reporting issues displaying is done atomically in py.test
+ [45518]
+* made that non-existing files are igored by the py.lookup script [45519]
+* improved exception name creation in py.test [45535]
+* made that less threads are used in execnet [merge in 45539]
+* removed lock required for atomical reporting issue displaying in py.test
+ [45545]
+* removed globals from execnet [45541, 45547]
+* refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit
+ get called in 2.5 (py.execnet) [45548]
+* fixed bug in joining threads in py.execnet's servemain [45549]
+* refactored py.test.rsession tests to not rely on exact output format anymore
+ [45646]
+* using repr() on test outcome [45647]
+* added 'Reason' classes for py.test.skip() [45648, 45649]
+* killed some unnecessary sanity check in py.test.collect [45655]
+* avoid using os.tmpfile() in py.io.fdcapture because on Windows it's only
+ usable by Administrators [45901]
+* added support for locking and non-recursive commits to py.path.svnwc [45994]
+* locking files in py.execnet to prevent CPython from segfaulting [46010]
+* added export() method to py.path.svnurl
+* fixed -d -x in py.test [47277]
+* fixed argument concatenation problem in py.path.svnwc [49423]
+* restore py.test behaviour that it exits with code 1 when there are failures
+ [49974]
+* don't fail on html files that don't have an accompanying .txt file [50606]
+* fixed 'utestconvert.py < input' [50645]
+* small fix for code indentation in py.code.source [50755]
+* fix _docgen.py documentation building [51285]
+* improved checks for source representation of code blocks in py.test [51292]
+* added support for passing authentication to py.path.svn* objects [52000,
+ 52001]
+* removed sorted() call for py.apigen tests in favour of [].sort() to support
+ Python 2.3 [52481]
diff --git a/tests/wpt/web-platform-tests/tools/py/LICENSE b/tests/wpt/web-platform-tests/tools/py/LICENSE
new file mode 100644
index 00000000000..31ecdfb1dbc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/LICENSE
@@ -0,0 +1,19 @@
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ SOFTWARE.
+
diff --git a/tests/wpt/web-platform-tests/tools/py/MANIFEST.in b/tests/wpt/web-platform-tests/tools/py/MANIFEST.in
new file mode 100644
index 00000000000..31fb010b487
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/MANIFEST.in
@@ -0,0 +1,9 @@
+include CHANGELOG
+include AUTHORS
+include README.txt
+include setup.py
+include LICENSE
+include conftest.py
+include tox.ini
+graft doc
+graft testing
diff --git a/tests/wpt/web-platform-tests/tools/py/README.txt b/tests/wpt/web-platform-tests/tools/py/README.txt
new file mode 100644
index 00000000000..e327e937373
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/README.txt
@@ -0,0 +1,21 @@
+.. image:: https://drone.io/bitbucket.org/pytest-dev/py/status.png
+ :target: https://drone.io/bitbucket.org/pytest-dev/py/latest
+.. image:: https://pypip.in/v/py/badge.png
+ :target: https://pypi.python.org/pypi/py
+
+The py lib is a Python development support library featuring
+the following tools and modules:
+
+* py.path: uniform local and svn path objects
+* py.apipkg: explicit API control and lazy-importing
+* py.iniconfig: easy parsing of .ini files
+* py.code: dynamic code generation and introspection
+
+NOTE: prior to the 1.4 release this distribution used to
+contain py.test which is now its own package, see http://pytest.org
+
+For questions and more information please visit http://pylib.readthedocs.org
+
+Bugs and issues: http://bitbucket.org/pytest-dev/py/issues/
+
+Authors: Holger Krekel and others, 2004-2015
diff --git a/tests/wpt/web-platform-tests/tools/py/bench/localpath.py b/tests/wpt/web-platform-tests/tools/py/bench/localpath.py
new file mode 100644
index 00000000000..ad4fbd8e2bf
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/bench/localpath.py
@@ -0,0 +1,75 @@
+
+import py
+import timeit
+
+class Listdir:
+ numiter = 100000
+ numentries = 100
+
+ def setup(self):
+ tmpdir = py.path.local.make_numbered_dir(self.__class__.__name__)
+ for i in range(self.numentries):
+ tmpdir.join(str(i))
+ self.tmpdir = tmpdir
+
+ def run(self):
+ return self.tmpdir.listdir()
+
+class Listdir_arg(Listdir):
+ numiter = 100000
+ numentries = 100
+
+ def run(self):
+ return self.tmpdir.listdir("47")
+
+class Join_onearg(Listdir):
+ def run(self):
+ self.tmpdir.join("17")
+ self.tmpdir.join("18")
+ self.tmpdir.join("19")
+
+class Join_multi(Listdir):
+ def run(self):
+ self.tmpdir.join("a", "b")
+ self.tmpdir.join("a", "b", "c")
+ self.tmpdir.join("a", "b", "c", "d")
+
+class Check(Listdir):
+ def run(self):
+ self.tmpdir.check()
+ self.tmpdir.check()
+ self.tmpdir.check()
+
+class CheckDir(Listdir):
+ def run(self):
+ self.tmpdir.check(dir=1)
+ self.tmpdir.check(dir=1)
+ assert not self.tmpdir.check(dir=0)
+
+class CheckDir2(Listdir):
+ def run(self):
+ self.tmpdir.stat().isdir()
+ self.tmpdir.stat().isdir()
+ assert self.tmpdir.stat().isdir()
+
+class CheckFile(Listdir):
+ def run(self):
+ self.tmpdir.check(file=1)
+ assert not self.tmpdir.check(file=1)
+ assert self.tmpdir.check(file=0)
+
+if __name__ == "__main__":
+ import time
+ for cls in [Listdir, Listdir_arg,
+ Join_onearg, Join_multi,
+ Check, CheckDir, CheckDir2, CheckFile,]:
+
+ inst = cls()
+ inst.setup()
+ now = time.time()
+ for i in xrange(cls.numiter):
+ inst.run()
+ elapsed = time.time() - now
+ print "%s: %d loops took %.2f seconds, per call %.6f" %(
+ cls.__name__,
+ cls.numiter, elapsed, elapsed / cls.numiter)
diff --git a/tests/wpt/web-platform-tests/tools/py/conftest.py b/tests/wpt/web-platform-tests/tools/py/conftest.py
new file mode 100644
index 00000000000..11c2d442504
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/conftest.py
@@ -0,0 +1,71 @@
+import py
+import sys
+
+pytest_plugins = 'doctest pytester'.split()
+
+collect_ignore = ['build', 'doc/_build']
+
+
+import os, py
+pid = os.getpid()
+
+def pytest_addoption(parser):
+ group = parser.getgroup("pylib", "py lib testing options")
+ group.addoption('--runslowtests',
+ action="store_true", dest="runslowtests", default=False,
+ help=("run slow tests"))
+
+def pytest_funcarg__sshhost(request):
+ val = request.config.getvalue("sshhost")
+ if val:
+ return val
+ py.test.skip("need --sshhost option")
+def pytest_generate_tests(metafunc):
+ multi = getattr(metafunc.function, 'multi', None)
+ if multi is not None:
+ assert len(multi.kwargs) == 1
+ for name, l in multi.kwargs.items():
+ for val in l:
+ metafunc.addcall(funcargs={name: val})
+ elif 'anypython' in metafunc.funcargnames:
+ for name in ('python2.4', 'python2.5', 'python2.6',
+ 'python2.7', 'python3.1', 'pypy-c', 'jython'):
+ metafunc.addcall(id=name, param=name)
+
+# XXX copied from execnet's conftest.py - needs to be merged
+winpymap = {
+ 'python2.7': r'C:\Python27\python.exe',
+ 'python2.6': r'C:\Python26\python.exe',
+ 'python2.5': r'C:\Python25\python.exe',
+ 'python2.4': r'C:\Python24\python.exe',
+ 'python3.1': r'C:\Python31\python.exe',
+}
+
+def getexecutable(name, cache={}):
+ try:
+ return cache[name]
+ except KeyError:
+ executable = py.path.local.sysfind(name)
+ if executable:
+ if name == "jython":
+ import subprocess
+ popen = subprocess.Popen([str(executable), "--version"],
+ universal_newlines=True, stderr=subprocess.PIPE)
+ out, err = popen.communicate()
+ if not err or "2.5" not in err:
+ executable = None
+ cache[name] = executable
+ return executable
+
+def pytest_funcarg__anypython(request):
+ name = request.param
+ executable = getexecutable(name)
+ if executable is None:
+ if sys.platform == "win32":
+ executable = winpymap.get(name, None)
+ if executable:
+ executable = py.path.local(executable)
+ if executable.check():
+ return executable
+ py.test.skip("no %s found" % (name,))
+ return executable
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/Makefile b/tests/wpt/web-platform-tests/tools/py/doc/Makefile
new file mode 100644
index 00000000000..0a0e89e01fe
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/Makefile
@@ -0,0 +1,133 @@
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS =
+SPHINXBUILD = sphinx-build
+PAPER =
+BUILDDIR = _build
+
+# Internal variables.
+PAPEROPT_a4 = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+ @echo "Please use \`make <target>' where <target> is one of"
+ @echo " html to make standalone HTML files"
+ @echo " dirhtml to make HTML files named index.html in directories"
+ @echo " singlehtml to make a single large HTML file"
+ @echo " pickle to make pickle files"
+ @echo " json to make JSON files"
+ @echo " htmlhelp to make HTML files and a HTML help project"
+ @echo " qthelp to make HTML files and a qthelp project"
+ @echo " devhelp to make HTML files and a Devhelp project"
+ @echo " epub to make an epub"
+ @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+ @echo " latexpdf to make LaTeX files and run them through pdflatex"
+ @echo " text to make text files"
+ @echo " man to make manual pages"
+ @echo " changes to make an overview of all changed/added/deprecated items"
+ @echo " linkcheck to check all external links for integrity"
+ @echo " doctest to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+ -rm -rf $(BUILDDIR)/*
+
+install: clean html
+ rsync -avz _build/html/ code:www-pylib/
+
+html:
+ $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+ $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+ @echo
+ @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+ $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+ @echo
+ @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+ $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+ @echo
+ @echo "Build finished; now you can process the pickle files."
+
+json:
+ $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+ @echo
+ @echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+ $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+ @echo
+ @echo "Build finished; now you can run HTML Help Workshop with the" \
+ ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+ $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+ @echo
+ @echo "Build finished; now you can run "qcollectiongenerator" with the" \
+ ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+ @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/py.qhcp"
+ @echo "To view the help file:"
+ @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/py.qhc"
+
+devhelp:
+ $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+ @echo
+ @echo "Build finished."
+ @echo "To view the help file:"
+ @echo "# mkdir -p $$HOME/.local/share/devhelp/py"
+ @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/py"
+ @echo "# devhelp"
+
+epub:
+ $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+ @echo
+ @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo
+ @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+ @echo "Run \`make' in that directory to run these through (pdf)latex" \
+ "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+ $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+ @echo "Running LaTeX files through pdflatex..."
+ make -C $(BUILDDIR)/latex all-pdf
+ @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+ $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+ @echo
+ @echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+ $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+ @echo
+ @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+ $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+ @echo
+ @echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+ $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+ @echo
+ @echo "Link check complete; look for any errors in the above output " \
+ "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+ $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+ @echo "Testing of doctests in the sources finished, look at the " \
+ "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/_templates/layout.html b/tests/wpt/web-platform-tests/tools/py/doc/_templates/layout.html
new file mode 100644
index 00000000000..683863aa460
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/_templates/layout.html
@@ -0,0 +1,18 @@
+{% extends "!layout.html" %}
+
+{% block footer %}
+{{ super() }}
+<script type="text/javascript">
+
+ var _gaq = _gaq || [];
+ _gaq.push(['_setAccount', 'UA-7597274-14']);
+ _gaq.push(['_trackPageview']);
+
+ (function() {
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+ })();
+
+</script>
+{% endblock %}
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.0.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.0.txt
new file mode 100644
index 00000000000..07109313543
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.0.txt
@@ -0,0 +1,7 @@
+py lib 1.0.0: XXX
+======================================================================
+
+Welcome to the 1.0.0 py lib release - a library aiming to
+support agile and test-driven python development on various levels.
+
+XXX
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.2.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.2.txt
new file mode 100644
index 00000000000..bc2d2ef2908
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-0.9.2.txt
@@ -0,0 +1,27 @@
+py lib 0.9.2: bugfix release
+=============================
+
+Welcome to the 0.9.2 py lib and py.test release -
+mainly fixing Windows issues, providing better
+packaging and integration with setuptools.
+
+Here is a quick summary of what the py lib provides:
+
+* py.test: cross-project testing tool with many advanced features
+* py.execnet: ad-hoc code distribution to SSH, Socket and local sub processes
+* py.magic.greenlet: micro-threads on standard CPython ("stackless-light")
+* py.path: path abstractions over local and subversion files
+* rich documentation of py's exported API
+* tested against Linux, Win32, OSX, works on python 2.3-2.6
+
+See here for more information:
+
+Pypi pages: http://pypi.python.org/pypi/py/
+
+Download/Install: http://codespeak.net/py/0.9.2/download.html
+
+Documentation/API: http://codespeak.net/py/0.9.2/index.html
+
+best and have fun,
+
+holger krekel
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.0.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.0.txt
new file mode 100644
index 00000000000..7024255a195
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.0.txt
@@ -0,0 +1,63 @@
+
+pylib 1.0.0 released: testing-with-python innovations continue
+--------------------------------------------------------------------
+
+Took a few betas but finally i uploaded a `1.0.0 py lib release`_,
+featuring the mature and powerful py.test tool and "execnet-style"
+*elastic* distributed programming. With the new release, there are
+many new advanced automated testing features - here is a quick summary:
+
+* funcargs_ - pythonic zero-boilerplate fixtures for Python test functions :
+
+ - totally separates test code, test configuration and test setup
+ - ideal for integration and functional tests
+ - allows for flexible and natural test parametrization schemes
+
+* new `plugin architecture`_, allowing easy-to-write project-specific and cross-project single-file plugins. The most notable new external plugin is `oejskit`_ which naturally enables **running and reporting of javascript-unittests in real-life browsers**.
+
+* many new features done in easy-to-improve `default plugins`_, highlights:
+
+ * xfail: mark tests as "expected to fail" and report separately.
+ * pastebin: automatically send tracebacks to pocoo paste service
+ * capture: flexibly capture stdout/stderr of subprocesses, per-test ...
+ * monkeypatch: safely monkeypatch modules/classes from within tests
+ * unittest: run and integrate traditional unittest.py tests
+ * figleaf: generate html coverage reports with the figleaf module
+ * resultlog: generate buildbot-friendly reporting output
+ * ...
+
+* `distributed testing`_ and `elastic distributed execution`_:
+
+ - new unified "TX" URL scheme for specifying remote processes
+ - new distribution modes "--dist=each" and "--dist=load"
+ - new sync/async ways to handle 1:N communication
+ - improved documentation
+
+The py lib continues to offer most of the functionality used by
+the testing tool in `independent namespaces`_.
+
+Some non-test related code, notably greenlets/co-routines and
+api-generation now live as their own projects which simplifies the
+installation procedure because no C-Extensions are required anymore.
+
+The whole package should work well with Linux, Win32 and OSX, on Python
+2.3, 2.4, 2.5 and 2.6. (Expect Python3 compatibility soon!)
+
+For more info, see the py.test and py lib documentation:
+
+ http://pytest.org
+
+ http://pylib.org
+
+have fun,
+holger
+
+.. _`independent namespaces`: http://pylib.org
+.. _`funcargs`: http://codespeak.net/py/dist/test/funcargs.html
+.. _`plugin architecture`: http://codespeak.net/py/dist/test/extend.html
+.. _`default plugins`: http://codespeak.net/py/dist/test/plugin/index.html
+.. _`distributed testing`: http://codespeak.net/py/dist/test/dist.html
+.. _`elastic distributed execution`: http://codespeak.net/py/dist/execnet.html
+.. _`1.0.0 py lib release`: http://pypi.python.org/pypi/py
+.. _`oejskit`: http://codespeak.net/py/dist/test/plugin/oejskit.html
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.1.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.1.txt
new file mode 100644
index 00000000000..0c9f8760bdb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.1.txt
@@ -0,0 +1,48 @@
+1.0.1: improved reporting, nose/unittest.py support, bug fixes
+-----------------------------------------------------------------------
+
+This is a bugfix release of pylib/py.test also coming with:
+
+* improved documentation, improved navigation
+* test failure reporting improvements
+* support for directly running existing nose/unittest.py style tests
+
+visit here for more info, including quickstart and tutorials:
+
+ http://pytest.org and http://pylib.org
+
+
+Changelog 1.0.0 to 1.0.1
+------------------------
+
+* added a default 'pytest_nose' plugin which handles nose.SkipTest,
+ nose-style function/method/generator setup/teardown and
+ tries to report functions correctly.
+
+* improved documentation, better navigation: see http://pytest.org
+
+* added a "--help-config" option to show conftest.py / ENV-var names for
+ all longopt cmdline options, and some special conftest.py variables.
+ renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
+
+* unicode fixes: capturing and unicode writes to sys.stdout
+ (through e.g a print statement) now work within tests,
+ they are encoded as "utf8" by default, also terminalwriting
+ was adapted and somewhat unified between windows and linux
+
+* fix issue #27: better reporting on non-collectable items given on commandline
+ (e.g. pyc files)
+
+* fix issue #33: added --version flag (thanks Benjamin Peterson)
+
+* fix issue #32: adding support for "incomplete" paths to wcpath.status()
+
+* "Test" prefixed classes are *not* collected by default anymore if they
+ have an __init__ method
+
+* monkeypatch setenv() now accepts a "prepend" parameter
+
+* improved reporting of collection error tracebacks
+
+* simplified multicall mechanism and plugin architecture,
+ renamed some internal methods and argnames
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.2.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.2.txt
new file mode 100644
index 00000000000..23546195353
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.0.2.txt
@@ -0,0 +1,5 @@
+1.0.2: packaging fixes
+-----------------------------------------------------------------------
+
+this release is purely a release for fixing packaging issues.
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.0.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.0.txt
new file mode 100644
index 00000000000..0441c3215eb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.0.txt
@@ -0,0 +1,115 @@
+py.test/pylib 1.1.0: Python3, Jython, advanced skipping, cleanups ...
+--------------------------------------------------------------------------------
+
+Features:
+
+* compatible to Python3 (single py2/py3 source), `easy to install`_
+* conditional skipping_: skip/xfail based on platform/dependencies
+* generalized marking_: mark tests one a whole-class or whole-module basis
+
+Fixes:
+
+* code reduction and "de-magification" (e.g. 23 KLoc -> 11 KLOC)
+* distribute testing requires the now separately released execnet_ package
+* funcarg-setup/caching, "same-name" test modules now cause an exlicit error
+* de-cluttered reporting options, --report for skipped/xfail details
+
+Compatibilities
+
+1.1.0 should allow running test code that already worked well with 1.0.2
+plus some more due to improved unittest/nose compatibility.
+
+More information: http://pytest.org
+
+thanks and have fun,
+
+holger (http://twitter.com/hpk42)
+
+.. _execnet: http://codespeak.net/execnet
+.. _`easy to install`: ../install.html
+.. _marking: ../test/plugin/mark.html
+.. _skipping: ../test/plugin/skipping.html
+
+
+Changelog 1.0.2 -> 1.1.0
+-----------------------------------------------------------------------
+
+* remove py.rest tool and internal namespace - it was
+ never really advertised and can still be used with
+ the old release if needed. If there is interest
+ it could be revived into its own tool i guess.
+
+* fix issue48 and issue59: raise an Error if the module
+ from an imported test file does not seem to come from
+ the filepath - avoids "same-name" confusion that has
+ been reported repeatedly
+
+* merged Ronny's nose-compatibility hacks: now
+ nose-style setup_module() and setup() functions are
+ supported
+
+* introduce generalized py.test.mark function marking
+
+* reshuffle / refine command line grouping
+
+* deprecate parser.addgroup in favour of getgroup which creates option group
+
+* add --report command line option that allows to control showing of skipped/xfailed sections
+
+* generalized skipping: a new way to mark python functions with skipif or xfail
+ at function, class and modules level based on platform or sys-module attributes.
+
+* extend py.test.mark decorator to allow for positional args
+
+* introduce and test "py.cleanup -d" to remove empty directories
+
+* fix issue #59 - robustify unittest test collection
+
+* make bpython/help interaction work by adding an __all__ attribute
+ to ApiModule, cleanup initpkg
+
+* use MIT license for pylib, add some contributors
+
+* remove py.execnet code and substitute all usages with 'execnet' proper
+
+* fix issue50 - cached_setup now caches more to expectations
+ for test functions with multiple arguments.
+
+* merge Jarko's fixes, issue #45 and #46
+
+* add the ability to specify a path for py.lookup to search in
+
+* fix a funcarg cached_setup bug probably only occuring
+ in distributed testing and "module" scope with teardown.
+
+* many fixes and changes for making the code base python3 compatible,
+ many thanks to Benjamin Peterson for helping with this.
+
+* consolidate builtins implementation to be compatible with >=2.3,
+ add helpers to ease keeping 2 and 3k compatible code
+
+* deprecate py.compat.doctest|subprocess|textwrap|optparse
+
+* deprecate py.magic.autopath, remove py/magic directory
+
+* move pytest assertion handling to py/code and a pytest_assertion
+ plugin, add "--no-assert" option, deprecate py.magic namespaces
+ in favour of (less) py.code ones.
+
+* consolidate and cleanup py/code classes and files
+
+* cleanup py/misc, move tests to bin-for-dist
+
+* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
+
+* consolidate py.log implementation, remove old approach.
+
+* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
+ text/unicode and byte-streams (uses underlying standard lib io.*
+ if available)
+
+* make py.unittest_convert helper script available which converts "unittest.py"
+ style files into the simpler assert/direct-test-classes py.test/nosetests
+ style. The script was written by Laura Creighton.
+
+* simplified internal localpath implementation
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.1.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.1.txt
new file mode 100644
index 00000000000..83e6a1fd8d9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.1.1.txt
@@ -0,0 +1,48 @@
+py.test/pylib 1.1.1: bugfix release, setuptools plugin registration
+--------------------------------------------------------------------------------
+
+This is a compatibility fixing release of pylib/py.test to work
+better with previous 1.0.x test code bases. It also contains fixes
+and changes to work with `execnet>=1.0.0`_ to provide distributed
+testing and looponfailing testing modes. py-1.1.1 also introduces
+a new mechanism for registering plugins via setuptools.
+
+What is pylib/py.test?
+-----------------------
+
+py.test is an advanced automated testing tool working with
+Python2, Python3 and Jython versions on all major operating
+systems. It has an extensive plugin architecture and can run many
+existing common Python test suites without modification. Moreover,
+it offers some unique features not found in other
+testing tools. See http://pytest.org for more info.
+
+The pylib also contains a localpath and svnpath implementation
+and some developer-oriented command line tools. See
+http://pylib.org for more info.
+
+thanks to all who helped and gave feedback,
+have fun,
+
+holger (http://twitter.com/hpk42)
+
+.. _`execnet>=1.0.0`: http://codespeak.net/execnet
+
+Changes between 1.1.1 and 1.1.0
+=====================================
+
+- introduce automatic plugin registration via 'pytest11'
+ entrypoints via setuptools' pkg_resources.iter_entry_points
+
+- fix py.test dist-testing to work with execnet >= 1.0.0b4
+
+- re-introduce py.test.cmdline.main() for better backward compatibility
+
+- svn paths: fix a bug with path.check(versioned=True) for svn paths,
+ allow '%' in svn paths, make svnwc.update() default to interactive mode
+ like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
+
+- refine distributed tarball to contain test and no pyc files
+
+- try harder to have deprecation warnings for py.compat.* accesses
+ report a correct location
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.0.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.0.txt
new file mode 100644
index 00000000000..4f6a5614476
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.0.txt
@@ -0,0 +1,116 @@
+py.test/pylib 1.2.0: junitxml, standalone test scripts, pluginization
+--------------------------------------------------------------------------------
+
+py.test is an advanced automated testing tool working with
+Python2, Python3 and Jython versions on all major operating
+systems. It has a simple plugin architecture and can run many
+existing common Python test suites without modification. It offers
+some unique features not found in other testing tools.
+See http://pytest.org for more info.
+
+py.test 1.2.0 brings many bug fixes and interesting new abilities:
+
+* --junitxml=path will create an XML file for use with CI processing
+* --genscript=path creates a standalone py.test-equivalent test-script
+* --ignore=path prevents collection of anything below that path
+* --confcutdir=path only lookup conftest.py test configs below that path
+* a 'pytest_report_header' hook to add info to the terminal report header
+* a 'pytestconfig' function argument gives direct access to option values
+* 'pytest_generate_tests' can now be put into a class as well
+* on CPython py.test additionally installs as "py.test-VERSION", on
+ Jython as py.test-jython and on PyPy as py.test-pypy-XYZ
+
+Apart from many bug fixes 1.2.0 also has better pluginization:
+Distributed testing and looponfailing testing now live in the
+separately installable 'pytest-xdist' plugin. The same is true for
+'pytest-figleaf' for doing coverage reporting. Those two plugins
+can serve well now as blue prints for doing your own.
+
+thanks to all who helped and gave feedback,
+have fun,
+
+holger krekel, January 2010
+
+Changes between 1.2.0 and 1.1.1
+=====================================
+
+- moved dist/looponfailing from py.test core into a new
+ separately released pytest-xdist plugin.
+
+- new junitxml plugin: --junitxml=path will generate a junit style xml file
+ which is processable e.g. by the Hudson CI system.
+
+- new option: --genscript=path will generate a standalone py.test script
+ which will not need any libraries installed. thanks to Ralf Schmitt.
+
+- new option: --ignore will prevent specified path from collection.
+ Can be specified multiple times.
+
+- new option: --confcutdir=dir will make py.test only consider conftest
+ files that are relative to the specified dir.
+
+- new funcarg: "pytestconfig" is the pytest config object for access
+ to command line args and can now be easily used in a test.
+
+- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
+ disambiguate between Python3, python2.X, Jython and PyPy installed versions.
+
+- new "pytestconfig" funcarg allows access to test config object
+
+- new "pytest_report_header" hook can return additional lines
+ to be displayed at the header of a test run.
+
+- (experimental) allow "py.test path::name1::name2::..." for pointing
+ to a test within a test collection directly. This might eventually
+ evolve as a full substitute to "-k" specifications.
+
+- streamlined plugin loading: order is now as documented in
+ customize.html: setuptools, ENV, commandline, conftest.
+ also setuptools entry point names are turned to canonical namees ("pytest_*")
+
+- automatically skip tests that need 'capfd' but have no os.dup
+
+- allow pytest_generate_tests to be defined in classes as well
+
+- deprecate usage of 'disabled' attribute in favour of pytestmark
+- deprecate definition of Directory, Module, Class and Function nodes
+ in conftest.py files. Use pytest collect hooks instead.
+
+- collection/item node specific runtest/collect hooks are only called exactly
+ on matching conftest.py files, i.e. ones which are exactly below
+ the filesystem path of an item
+
+- change: the first pytest_collect_directory hook to return something
+ will now prevent further hooks to be called.
+
+- change: figleaf plugin now requires --figleaf to run. Also
+ change its long command line options to be a bit shorter (see py.test -h).
+
+- change: pytest doctest plugin is now enabled by default and has a
+ new option --doctest-glob to set a pattern for file matches.
+
+- change: remove internal py._* helper vars, only keep py._pydir
+
+- robustify capturing to survive if custom pytest_runtest_setup
+ code failed and prevented the capturing setup code from running.
+
+- make py.test.* helpers provided by default plugins visible early -
+ works transparently both for pydoc and for interactive sessions
+ which will regularly see e.g. py.test.mark and py.test.importorskip.
+
+- simplify internal plugin manager machinery
+- simplify internal collection tree by introducing a RootCollector node
+
+- fix assert reinterpreation that sees a call containing "keyword=..."
+
+- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
+ hooks on slaves during dist-testing, report module/session teardown
+ hooks correctly.
+
+- fix issue65: properly handle dist-testing if no
+ execnet/py lib installed remotely.
+
+- skip some install-tests if no execnet is available
+
+- fix docs, fix internal bin/ script generation
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.1.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.1.txt
new file mode 100644
index 00000000000..5bf8ba22dc6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.2.1.txt
@@ -0,0 +1,66 @@
+py.test/pylib 1.2.1: little fixes and improvements
+--------------------------------------------------------------------------------
+
+py.test is an advanced automated testing tool working with
+Python2, Python3 and Jython versions on all major operating
+systems. It has a simple plugin architecture and can run many
+existing common Python test suites without modification. It offers
+some unique features not found in other testing tools.
+See http://pytest.org for more info.
+
+py.test 1.2.1 brings bug fixes and some new options and abilities triggered
+by user feedback:
+
+* --funcargs [testpath] will show available builtin- and project funcargs.
+* display a short and concise traceback if funcarg lookup fails.
+* early-load "conftest.py" files in non-dot first-level sub directories.
+* --tb=line will print a single line for each failing test (issue67)
+* py.cleanup has a number of new options, cleanups up setup.py related files
+* fix issue78: always call python-level teardown functions even if the
+ according setup failed.
+
+For more detailed information see the changelog below.
+
+cheers and have fun,
+
+holger
+
+
+Changes between 1.2.1 and 1.2.0
+=====================================
+
+- refined usage and options for "py.cleanup"::
+
+ py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
+ py.cleanup -e .swp -e .cache # also remove files with these extensions
+ py.cleanup -s # remove "build" and "dist" directory next to setup.py files
+ py.cleanup -d # also remove empty directories
+ py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
+ py.cleanup -n # dry run, only show what would be removed
+
+- add a new option "py.test --funcargs" which shows available funcargs
+ and their help strings (docstrings on their respective factory function)
+ for a given test path
+
+- display a short and concise traceback if a funcarg lookup fails
+
+- early-load "conftest.py" files in non-dot first-level sub directories.
+ allows to conveniently keep and access test-related options in a ``test``
+ subdir and still add command line options.
+
+- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
+
+- fix issue78: always call python-level teardown functions even if the
+ according setup failed. This includes refinements for calling setup_module/class functions
+ which will now only be called once instead of the previous behaviour where they'd be called
+ multiple times if they raise an exception (including a Skipped exception). Any exception
+ will be re-corded and associated with all tests in the according module/class scope.
+
+- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
+
+- fix pdb debugging to be in the correct frame on raises-related errors
+
+- update apipkg.py to fix an issue where recursive imports might
+ unnecessarily break importing
+
+- fix plugin links
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.0.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.0.txt
new file mode 100644
index 00000000000..cf97db0367a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.0.txt
@@ -0,0 +1,580 @@
+py.test/pylib 1.3.0: new options, per-plugin hooks, fixes ...
+===========================================================================
+
+The 1.3.0 release introduces new options, bug fixes and improved compatibility
+with Python3 and Jython-2.5.1 on Windows. If you already use py-1.2 chances
+are you can use py-1.3.0. See the below CHANGELOG for more details and
+http://pylib.org/install.html for installation instructions.
+
+py.test is an advanced automated testing tool working with Python2,
+Python3, Jython and PyPy versions on all major operating systems. It
+offers a no-boilerplate testing approach and has inspired other testing
+tools and enhancements in the standard Python library for more than five
+years. It has a simple and extensive plugin architecture, configurable
+reporting and provides unique ways to make it fit to your testing
+process and needs.
+
+See http://pytest.org for more info.
+
+cheers and have fun,
+
+holger krekel
+
+Changes between 1.2.1 and 1.3.0
+==================================================
+
+- deprecate --report option in favour of a new shorter and easier to
+ remember -r option: it takes a string argument consisting of any
+ combination of 'xfsX' characters. They relate to the single chars
+ you see during the dotted progress printing and will print an extra line
+ per test at the end of the test run. This extra line indicates the exact
+ position or test ID that you directly paste to the py.test cmdline in order
+ to re-run a particular test.
+
+- allow external plugins to register new hooks via the new
+ pytest_addhooks(pluginmanager) hook. The new release of
+ the pytest-xdist plugin for distributed and looponfailing
+ testing requires this feature.
+
+- add a new pytest_ignore_collect(path, config) hook to allow projects and
+ plugins to define exclusion behaviour for their directory structure -
+ for example you may define in a conftest.py this method::
+
+ def pytest_ignore_collect(path):
+ return path.check(link=1)
+
+ to prevent even collection of any tests in symlinked dirs.
+
+- new pytest_pycollect_makemodule(path, parent) hook for
+ allowing customization of the Module collection object for a
+ matching test module.
+
+- extend and refine xfail mechanism::
+
+ @py.test.mark.xfail(run=False) do not run the decorated test
+ @py.test.mark.xfail(reason="...") prints the reason string in xfail summaries
+
+ specifiying ``--runxfail`` on command line ignores xfail markers to show
+ you the underlying traceback.
+
+- expose (previously internal) commonly useful methods:
+ py.io.get_terminal_with() -> return terminal width
+ py.io.ansi_print(...) -> print colored/bold text on linux/win32
+ py.io.saferepr(obj) -> return limited representation string
+
+- expose test outcome related exceptions as py.test.skip.Exception,
+ py.test.raises.Exception etc., useful mostly for plugins
+ doing special outcome interpretation/tweaking
+
+- (issue85) fix junitxml plugin to handle tests with non-ascii output
+
+- fix/refine python3 compatibility (thanks Benjamin Peterson)
+
+- fixes for making the jython/win32 combination work, note however:
+ jython2.5.1/win32 does not provide a command line launcher, see
+ http://bugs.jython.org/issue1491 . See pylib install documentation
+ for how to work around.
+
+- fixes for handling of unicode exception values and unprintable objects
+
+- (issue87) fix unboundlocal error in assertionold code
+
+- (issue86) improve documentation for looponfailing
+
+- refine IO capturing: stdin-redirect pseudo-file now has a NOP close() method
+
+- ship distribute_setup.py version 0.6.10
+
+- added links to the new capturelog and coverage plugins
+
+
+Changes between 1.2.1 and 1.2.0
+=====================================
+
+- refined usage and options for "py.cleanup"::
+
+ py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
+ py.cleanup -e .swp -e .cache # also remove files with these extensions
+ py.cleanup -s # remove "build" and "dist" directory next to setup.py files
+ py.cleanup -d # also remove empty directories
+ py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
+ py.cleanup -n # dry run, only show what would be removed
+
+- add a new option "py.test --funcargs" which shows available funcargs
+ and their help strings (docstrings on their respective factory function)
+ for a given test path
+
+- display a short and concise traceback if a funcarg lookup fails
+
+- early-load "conftest.py" files in non-dot first-level sub directories.
+ allows to conveniently keep and access test-related options in a ``test``
+ subdir and still add command line options.
+
+- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
+
+- fix issue78: always call python-level teardown functions even if the
+ according setup failed. This includes refinements for calling setup_module/class functions
+ which will now only be called once instead of the previous behaviour where they'd be called
+ multiple times if they raise an exception (including a Skipped exception). Any exception
+ will be re-corded and associated with all tests in the according module/class scope.
+
+- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
+
+- fix pdb debugging to be in the correct frame on raises-related errors
+
+- update apipkg.py to fix an issue where recursive imports might
+ unnecessarily break importing
+
+- fix plugin links
+
+Changes between 1.2 and 1.1.1
+=====================================
+
+- moved dist/looponfailing from py.test core into a new
+ separately released pytest-xdist plugin.
+
+- new junitxml plugin: --junitxml=path will generate a junit style xml file
+ which is processable e.g. by the Hudson CI system.
+
+- new option: --genscript=path will generate a standalone py.test script
+ which will not need any libraries installed. thanks to Ralf Schmitt.
+
+- new option: --ignore will prevent specified path from collection.
+ Can be specified multiple times.
+
+- new option: --confcutdir=dir will make py.test only consider conftest
+ files that are relative to the specified dir.
+
+- new funcarg: "pytestconfig" is the pytest config object for access
+ to command line args and can now be easily used in a test.
+
+- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
+ disambiguate between Python3, python2.X, Jython and PyPy installed versions.
+
+- new "pytestconfig" funcarg allows access to test config object
+
+- new "pytest_report_header" hook can return additional lines
+ to be displayed at the header of a test run.
+
+- (experimental) allow "py.test path::name1::name2::..." for pointing
+ to a test within a test collection directly. This might eventually
+ evolve as a full substitute to "-k" specifications.
+
+- streamlined plugin loading: order is now as documented in
+ customize.html: setuptools, ENV, commandline, conftest.
+ also setuptools entry point names are turned to canonical namees ("pytest_*")
+
+- automatically skip tests that need 'capfd' but have no os.dup
+
+- allow pytest_generate_tests to be defined in classes as well
+
+- deprecate usage of 'disabled' attribute in favour of pytestmark
+- deprecate definition of Directory, Module, Class and Function nodes
+ in conftest.py files. Use pytest collect hooks instead.
+
+- collection/item node specific runtest/collect hooks are only called exactly
+ on matching conftest.py files, i.e. ones which are exactly below
+ the filesystem path of an item
+
+- change: the first pytest_collect_directory hook to return something
+ will now prevent further hooks to be called.
+
+- change: figleaf plugin now requires --figleaf to run. Also
+ change its long command line options to be a bit shorter (see py.test -h).
+
+- change: pytest doctest plugin is now enabled by default and has a
+ new option --doctest-glob to set a pattern for file matches.
+
+- change: remove internal py._* helper vars, only keep py._pydir
+
+- robustify capturing to survive if custom pytest_runtest_setup
+ code failed and prevented the capturing setup code from running.
+
+- make py.test.* helpers provided by default plugins visible early -
+ works transparently both for pydoc and for interactive sessions
+ which will regularly see e.g. py.test.mark and py.test.importorskip.
+
+- simplify internal plugin manager machinery
+- simplify internal collection tree by introducing a RootCollector node
+
+- fix assert reinterpreation that sees a call containing "keyword=..."
+
+- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
+ hooks on slaves during dist-testing, report module/session teardown
+ hooks correctly.
+
+- fix issue65: properly handle dist-testing if no
+ execnet/py lib installed remotely.
+
+- skip some install-tests if no execnet is available
+
+- fix docs, fix internal bin/ script generation
+
+
+Changes between 1.1.1 and 1.1.0
+=====================================
+
+- introduce automatic plugin registration via 'pytest11'
+ entrypoints via setuptools' pkg_resources.iter_entry_points
+
+- fix py.test dist-testing to work with execnet >= 1.0.0b4
+
+- re-introduce py.test.cmdline.main() for better backward compatibility
+
+- svn paths: fix a bug with path.check(versioned=True) for svn paths,
+ allow '%' in svn paths, make svnwc.update() default to interactive mode
+ like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
+
+- refine distributed tarball to contain test and no pyc files
+
+- try harder to have deprecation warnings for py.compat.* accesses
+ report a correct location
+
+Changes between 1.1.0 and 1.0.2
+=====================================
+
+* adjust and improve docs
+
+* remove py.rest tool and internal namespace - it was
+ never really advertised and can still be used with
+ the old release if needed. If there is interest
+ it could be revived into its own tool i guess.
+
+* fix issue48 and issue59: raise an Error if the module
+ from an imported test file does not seem to come from
+ the filepath - avoids "same-name" confusion that has
+ been reported repeatedly
+
+* merged Ronny's nose-compatibility hacks: now
+ nose-style setup_module() and setup() functions are
+ supported
+
+* introduce generalized py.test.mark function marking
+
+* reshuffle / refine command line grouping
+
+* deprecate parser.addgroup in favour of getgroup which creates option group
+
+* add --report command line option that allows to control showing of skipped/xfailed sections
+
+* generalized skipping: a new way to mark python functions with skipif or xfail
+ at function, class and modules level based on platform or sys-module attributes.
+
+* extend py.test.mark decorator to allow for positional args
+
+* introduce and test "py.cleanup -d" to remove empty directories
+
+* fix issue #59 - robustify unittest test collection
+
+* make bpython/help interaction work by adding an __all__ attribute
+ to ApiModule, cleanup initpkg
+
+* use MIT license for pylib, add some contributors
+
+* remove py.execnet code and substitute all usages with 'execnet' proper
+
+* fix issue50 - cached_setup now caches more to expectations
+ for test functions with multiple arguments.
+
+* merge Jarko's fixes, issue #45 and #46
+
+* add the ability to specify a path for py.lookup to search in
+
+* fix a funcarg cached_setup bug probably only occuring
+ in distributed testing and "module" scope with teardown.
+
+* many fixes and changes for making the code base python3 compatible,
+ many thanks to Benjamin Peterson for helping with this.
+
+* consolidate builtins implementation to be compatible with >=2.3,
+ add helpers to ease keeping 2 and 3k compatible code
+
+* deprecate py.compat.doctest|subprocess|textwrap|optparse
+
+* deprecate py.magic.autopath, remove py/magic directory
+
+* move pytest assertion handling to py/code and a pytest_assertion
+ plugin, add "--no-assert" option, deprecate py.magic namespaces
+ in favour of (less) py.code ones.
+
+* consolidate and cleanup py/code classes and files
+
+* cleanup py/misc, move tests to bin-for-dist
+
+* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
+
+* consolidate py.log implementation, remove old approach.
+
+* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
+ text/unicode and byte-streams (uses underlying standard lib io.*
+ if available)
+
+* make py.unittest_convert helper script available which converts "unittest.py"
+ style files into the simpler assert/direct-test-classes py.test/nosetests
+ style. The script was written by Laura Creighton.
+
+* simplified internal localpath implementation
+
+Changes between 1.0.1 and 1.0.2
+=====================================
+
+* fixing packaging issues, triggered by fedora redhat packaging,
+ also added doc, examples and contrib dirs to the tarball.
+
+* added a documentation link to the new django plugin.
+
+Changes between 1.0.0 and 1.0.1
+=====================================
+
+* added a 'pytest_nose' plugin which handles nose.SkipTest,
+ nose-style function/method/generator setup/teardown and
+ tries to report functions correctly.
+
+* capturing of unicode writes or encoded strings to sys.stdout/err
+ work better, also terminalwriting was adapted and somewhat
+ unified between windows and linux.
+
+* improved documentation layout and content a lot
+
+* added a "--help-config" option to show conftest.py / ENV-var names for
+ all longopt cmdline options, and some special conftest.py variables.
+ renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
+
+* fix issue #27: better reporting on non-collectable items given on commandline
+ (e.g. pyc files)
+
+* fix issue #33: added --version flag (thanks Benjamin Peterson)
+
+* fix issue #32: adding support for "incomplete" paths to wcpath.status()
+
+* "Test" prefixed classes are *not* collected by default anymore if they
+ have an __init__ method
+
+* monkeypatch setenv() now accepts a "prepend" parameter
+
+* improved reporting of collection error tracebacks
+
+* simplified multicall mechanism and plugin architecture,
+ renamed some internal methods and argnames
+
+Changes between 1.0.0b9 and 1.0.0
+=====================================
+
+* more terse reporting try to show filesystem path relatively to current dir
+* improve xfail output a bit
+
+Changes between 1.0.0b8 and 1.0.0b9
+=====================================
+
+* cleanly handle and report final teardown of test setup
+
+* fix svn-1.6 compat issue with py.path.svnwc().versioned()
+ (thanks Wouter Vanden Hove)
+
+* setup/teardown or collection problems now show as ERRORs
+ or with big "E"'s in the progress lines. they are reported
+ and counted separately.
+
+* dist-testing: properly handle test items that get locally
+ collected but cannot be collected on the remote side - often
+ due to platform/dependency reasons
+
+* simplified py.test.mark API - see keyword plugin documentation
+
+* integrate better with logging: capturing now by default captures
+ test functions and their immediate setup/teardown in a single stream
+
+* capsys and capfd funcargs now have a readouterr() and a close() method
+ (underlyingly py.io.StdCapture/FD objects are used which grew a
+ readouterr() method as well to return snapshots of captured out/err)
+
+* make assert-reinterpretation work better with comparisons not
+ returning bools (reported with numpy from thanks maciej fijalkowski)
+
+* reworked per-test output capturing into the pytest_iocapture.py plugin
+ and thus removed capturing code from config object
+
+* item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr)
+
+
+Changes between 1.0.0b7 and 1.0.0b8
+=====================================
+
+* pytest_unittest-plugin is now enabled by default
+
+* introduced pytest_keyboardinterrupt hook and
+ refined pytest_sessionfinish hooked, added tests.
+
+* workaround a buggy logging module interaction ("closing already closed
+ files"). Thanks to Sridhar Ratnakumar for triggering.
+
+* if plugins use "py.test.importorskip" for importing
+ a dependency only a warning will be issued instead
+ of exiting the testing process.
+
+* many improvements to docs:
+ - refined funcargs doc , use the term "factory" instead of "provider"
+ - added a new talk/tutorial doc page
+ - better download page
+ - better plugin docstrings
+ - added new plugins page and automatic doc generation script
+
+* fixed teardown problem related to partially failing funcarg setups
+ (thanks MrTopf for reporting), "pytest_runtest_teardown" is now
+ always invoked even if the "pytest_runtest_setup" failed.
+
+* tweaked doctest output for docstrings in py modules,
+ thanks Radomir.
+
+Changes between 1.0.0b3 and 1.0.0b7
+=============================================
+
+* renamed py.test.xfail back to py.test.mark.xfail to avoid
+ two ways to decorate for xfail
+
+* re-added py.test.mark decorator for setting keywords on functions
+ (it was actually documented so removing it was not nice)
+
+* remove scope-argument from request.addfinalizer() because
+ request.cached_setup has the scope arg. TOOWTDI.
+
+* perform setup finalization before reporting failures
+
+* apply modified patches from Andreas Kloeckner to allow
+ test functions to have no func_code (#22) and to make
+ "-k" and function keywords work (#20)
+
+* apply patch from Daniel Peolzleithner (issue #23)
+
+* resolve issue #18, multiprocessing.Manager() and
+ redirection clash
+
+* make __name__ == "__channelexec__" for remote_exec code
+
+Changes between 1.0.0b1 and 1.0.0b3
+=============================================
+
+* plugin classes are removed: one now defines
+ hooks directly in conftest.py or global pytest_*.py
+ files.
+
+* added new pytest_namespace(config) hook that allows
+ to inject helpers directly to the py.test.* namespace.
+
+* documented and refined many hooks
+
+* added new style of generative tests via
+ pytest_generate_tests hook that integrates
+ well with function arguments.
+
+
+Changes between 0.9.2 and 1.0.0b1
+=============================================
+
+* introduced new "funcarg" setup method,
+ see doc/test/funcarg.txt
+
+* introduced plugin architecuture and many
+ new py.test plugins, see
+ doc/test/plugins.txt
+
+* teardown_method is now guaranteed to get
+ called after a test method has run.
+
+* new method: py.test.importorskip(mod,minversion)
+ will either import or call py.test.skip()
+
+* completely revised internal py.test architecture
+
+* new py.process.ForkedFunc object allowing to
+ fork execution of a function to a sub process
+ and getting a result back.
+
+XXX lots of things missing here XXX
+
+Changes between 0.9.1 and 0.9.2
+===============================
+
+* refined installation and metadata, created new setup.py,
+ now based on setuptools/ez_setup (thanks to Ralf Schmitt
+ for his support).
+
+* improved the way of making py.* scripts available in
+ windows environments, they are now added to the
+ Scripts directory as ".cmd" files.
+
+* py.path.svnwc.status() now is more complete and
+ uses xml output from the 'svn' command if available
+ (Guido Wesdorp)
+
+* fix for py.path.svn* to work with svn 1.5
+ (Chris Lamb)
+
+* fix path.relto(otherpath) method on windows to
+ use normcase for checking if a path is relative.
+
+* py.test's traceback is better parseable from editors
+ (follows the filenames:LINENO: MSG convention)
+ (thanks to Osmo Salomaa)
+
+* fix to javascript-generation, "py.test --runbrowser"
+ should work more reliably now
+
+* removed previously accidentally added
+ py.test.broken and py.test.notimplemented helpers.
+
+* there now is a py.__version__ attribute
+
+Changes between 0.9.0 and 0.9.1
+===============================
+
+This is a fairly complete list of changes between 0.9 and 0.9.1, which can
+serve as a reference for developers.
+
+* allowing + signs in py.path.svn urls [39106]
+* fixed support for Failed exceptions without excinfo in py.test [39340]
+* added support for killing processes for Windows (as well as platforms that
+ support os.kill) in py.misc.killproc [39655]
+* added setup/teardown for generative tests to py.test [40702]
+* added detection of FAILED TO LOAD MODULE to py.test [40703, 40738, 40739]
+* fixed problem with calling .remove() on wcpaths of non-versioned files in
+ py.path [44248]
+* fixed some import and inheritance issues in py.test [41480, 44648, 44655]
+* fail to run greenlet tests when pypy is available, but without stackless
+ [45294]
+* small fixes in rsession tests [45295]
+* fixed issue with 2.5 type representations in py.test [45483, 45484]
+* made that internal reporting issues displaying is done atomically in py.test
+ [45518]
+* made that non-existing files are igored by the py.lookup script [45519]
+* improved exception name creation in py.test [45535]
+* made that less threads are used in execnet [merge in 45539]
+* removed lock required for atomical reporting issue displaying in py.test
+ [45545]
+* removed globals from execnet [45541, 45547]
+* refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit
+ get called in 2.5 (py.execnet) [45548]
+* fixed bug in joining threads in py.execnet's servemain [45549]
+* refactored py.test.rsession tests to not rely on exact output format anymore
+ [45646]
+* using repr() on test outcome [45647]
+* added 'Reason' classes for py.test.skip() [45648, 45649]
+* killed some unnecessary sanity check in py.test.collect [45655]
+* avoid using os.tmpfile() in py.io.fdcapture because on Windows it's only
+ usable by Administrators [45901]
+* added support for locking and non-recursive commits to py.path.svnwc [45994]
+* locking files in py.execnet to prevent CPython from segfaulting [46010]
+* added export() method to py.path.svnurl
+* fixed -d -x in py.test [47277]
+* fixed argument concatenation problem in py.path.svnwc [49423]
+* restore py.test behaviour that it exits with code 1 when there are failures
+ [49974]
+* don't fail on html files that don't have an accompanying .txt file [50606]
+* fixed 'utestconvert.py < input' [50645]
+* small fix for code indentation in py.code.source [50755]
+* fix _docgen.py documentation building [51285]
+* improved checks for source representation of code blocks in py.test [51292]
+* added support for passing authentication to py.path.svn* objects [52000,
+ 52001]
+* removed sorted() call for py.apigen tests in favour of [].sort() to support
+ Python 2.3 [52481]
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.1.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.1.txt
new file mode 100644
index 00000000000..471de408a10
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.1.txt
@@ -0,0 +1,104 @@
+py.test/pylib 1.3.1: new py.test.xfail, --maxfail, better reporting
+===========================================================================
+
+The pylib/py.test 1.3.1 release brings:
+
+- the new imperative ``py.test.xfail()`` helper in order to have a test or
+ setup function result in an "expected failure"
+- a new option ``--maxfail=NUM`` to stop the test run after some failures
+- markers/decorators are now applicable to test classes (>=Python2.6)
+- improved reporting, shorter tracebacks in several cases
+- some simplified internals, more compatibility with Jython and PyPy
+- bug fixes and various refinements
+
+See the below CHANGELOG entry below for more details and
+http://pylib.org/install.html for installation instructions.
+
+If you used older versions of py.test you should be able to upgrade
+to 1.3.1 without changes to your test source code.
+
+py.test is an automated testing tool working with Python2,
+Python3, Jython and PyPy versions on all major operating systems. It
+offers a no-boilerplate testing approach and has inspired other testing
+tools and enhancements in the standard Python library for more than five
+years. It has a simple and extensive plugin architecture, configurable
+reporting and provides unique ways to make it fit to your testing
+process and needs.
+
+See http://pytest.org for more info.
+
+cheers and have fun,
+
+holger krekel
+
+Changes between 1.3.0 and 1.3.1
+==================================================
+
+New features
+++++++++++++++++++
+
+- issue91: introduce new py.test.xfail(reason) helper
+ to imperatively mark a test as expected to fail. Can
+ be used from within setup and test functions. This is
+ useful especially for parametrized tests when certain
+ configurations are expected-to-fail. In this case the
+ declarative approach with the @py.test.mark.xfail cannot
+ be used as it would mark all configurations as xfail.
+
+- issue102: introduce new --maxfail=NUM option to stop
+ test runs after NUM failures. This is a generalization
+ of the '-x' or '--exitfirst' option which is now equivalent
+ to '--maxfail=1'. Both '-x' and '--maxfail' will
+ now also print a line near the end indicating the Interruption.
+
+- issue89: allow py.test.mark decorators to be used on classes
+ (class decorators were introduced with python2.6) and
+ also allow to have multiple markers applied at class/module level
+ by specifying a list.
+
+- improve and refine letter reporting in the progress bar:
+ . pass
+ f failed test
+ s skipped tests (reminder: use for dependency/platform mismatch only)
+ x xfailed test (test that was expected to fail)
+ X xpassed test (test that was expected to fail but passed)
+
+ You can use any combination of 'fsxX' with the '-r' extended
+ reporting option. The xfail/xpass results will show up as
+ skipped tests in the junitxml output - which also fixes
+ issue99.
+
+- make py.test.cmdline.main() return the exitstatus instead of raising
+ SystemExit and also allow it to be called multiple times. This of
+ course requires that your application and tests are properly teared
+ down and don't have global state.
+
+Fixes / Maintenance
+++++++++++++++++++++++
+
+- improved traceback presentation:
+ - improved and unified reporting for "--tb=short" option
+ - Errors during test module imports are much shorter, (using --tb=short style)
+ - raises shows shorter more relevant tracebacks
+ - --fulltrace now more systematically makes traces longer / inhibits cutting
+
+- improve support for raises and other dynamically compiled code by
+ manipulating python's linecache.cache instead of the previous
+ rather hacky way of creating custom code objects. This makes
+ it seemlessly work on Jython and PyPy where it previously didn't.
+
+- fix issue96: make capturing more resilient against Control-C
+ interruptions (involved somewhat substantial refactoring
+ to the underlying capturing functionality to avoid race
+ conditions).
+
+- fix chaining of conditional skipif/xfail decorators - so it works now
+ as expected to use multiple @py.test.mark.skipif(condition) decorators,
+ including specific reporting which of the conditions lead to skipping.
+
+- fix issue95: late-import zlib so that it's not required
+ for general py.test startup.
+
+- fix issue94: make reporting more robust against bogus source code
+ (and internally be more careful when presenting unexpected byte sequences)
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.2.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.2.txt
new file mode 100644
index 00000000000..599dfbed755
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.2.txt
@@ -0,0 +1,720 @@
+py.test/pylib 1.3.2: API and reporting refinements, many fixes
+===========================================================================
+
+The pylib/py.test 1.3.2 release brings many bug fixes and some new
+features. It was refined for and tested against the recently released
+Python2.7 and remains compatibile to the usual armada of interpreters
+(Python2.4 through to Python3.1.2, Jython and PyPy). Note that for using
+distributed testing features you'll need to upgrade to the jointly released
+pytest-xdist-1.4 because of some internal refactorings.
+
+See http://pytest.org for general documentation and below for
+a detailed CHANGELOG.
+
+cheers & particular thanks to Benjamin Peterson, Ronny Pfannschmidt
+and all issue and patch contributors,
+
+holger krekel
+
+Changes between 1.3.1 and 1.3.2
+==================================================
+
+New features
+++++++++++++++++++
+
+- fix issue103: introduce py.test.raises as context manager, examples::
+
+ with py.test.raises(ZeroDivisionError):
+ x = 0
+ 1 / x
+
+ with py.test.raises(RuntimeError) as excinfo:
+ call_something()
+
+ # you may do extra checks on excinfo.value|type|traceback here
+
+ (thanks Ronny Pfannschmidt)
+
+- Funcarg factories can now dynamically apply a marker to a
+ test invocation. This is for example useful if a factory
+ provides parameters to a test which are expected-to-fail::
+
+ def pytest_funcarg__arg(request):
+ request.applymarker(py.test.mark.xfail(reason="flaky config"))
+ ...
+
+ def test_function(arg):
+ ...
+
+- improved error reporting on collection and import errors. This makes
+ use of a more general mechanism, namely that for custom test item/collect
+ nodes ``node.repr_failure(excinfo)`` is now uniformly called so that you can
+ override it to return a string error representation of your choice
+ which is going to be reported as a (red) string.
+
+- introduce '--junitprefix=STR' option to prepend a prefix
+ to all reports in the junitxml file.
+
+Bug fixes / Maintenance
+++++++++++++++++++++++++++
+
+- make tests and the ``pytest_recwarn`` plugin in particular fully compatible
+ to Python2.7 (if you use the ``recwarn`` funcarg warnings will be enabled so that
+ you can properly check for their existence in a cross-python manner).
+- refine --pdb: ignore xfailed tests, unify its TB-reporting and
+ don't display failures again at the end.
+- fix assertion interpretation with the ** operator (thanks Benjamin Peterson)
+- fix issue105 assignment on the same line as a failing assertion (thanks Benjamin Peterson)
+- fix issue104 proper escaping for test names in junitxml plugin (thanks anonymous)
+- fix issue57 -f|--looponfail to work with xpassing tests (thanks Ronny)
+- fix issue92 collectonly reporter and --pastebin (thanks Benjamin Peterson)
+- fix py.code.compile(source) to generate unique filenames
+- fix assertion re-interp problems on PyPy, by defering code
+ compilation to the (overridable) Frame.eval class. (thanks Amaury Forgeot)
+- fix py.path.local.pyimport() to work with directories
+- streamline py.path.local.mkdtemp implementation and usage
+- don't print empty lines when showing junitxml-filename
+- add optional boolean ignore_errors parameter to py.path.local.remove
+- fix terminal writing on win32/python2.4
+- py.process.cmdexec() now tries harder to return properly encoded unicode objects
+ on all python versions
+- install plain py.test/py.which scripts also for Jython, this helps to
+ get canonical script paths in virtualenv situations
+- make path.bestrelpath(path) return ".", note that when calling
+ X.bestrelpath the assumption is that X is a directory.
+- make initial conftest discovery ignore "--" prefixed arguments
+- fix resultlog plugin when used in an multicpu/multihost xdist situation
+ (thanks Jakub Gustak)
+- perform distributed testing related reporting in the xdist-plugin
+ rather than having dist-related code in the generic py.test
+ distribution
+- fix homedir detection on Windows
+- ship distribute_setup.py version 0.6.13
+
+Changes between 1.3.0 and 1.3.1
+==================================================
+
+New features
+++++++++++++++++++
+
+- issue91: introduce new py.test.xfail(reason) helper
+ to imperatively mark a test as expected to fail. Can
+ be used from within setup and test functions. This is
+ useful especially for parametrized tests when certain
+ configurations are expected-to-fail. In this case the
+ declarative approach with the @py.test.mark.xfail cannot
+ be used as it would mark all configurations as xfail.
+
+- issue102: introduce new --maxfail=NUM option to stop
+ test runs after NUM failures. This is a generalization
+ of the '-x' or '--exitfirst' option which is now equivalent
+ to '--maxfail=1'. Both '-x' and '--maxfail' will
+ now also print a line near the end indicating the Interruption.
+
+- issue89: allow py.test.mark decorators to be used on classes
+ (class decorators were introduced with python2.6) and
+ also allow to have multiple markers applied at class/module level
+ by specifying a list.
+
+- improve and refine letter reporting in the progress bar:
+ . pass
+ f failed test
+ s skipped tests (reminder: use for dependency/platform mismatch only)
+ x xfailed test (test that was expected to fail)
+ X xpassed test (test that was expected to fail but passed)
+
+ You can use any combination of 'fsxX' with the '-r' extended
+ reporting option. The xfail/xpass results will show up as
+ skipped tests in the junitxml output - which also fixes
+ issue99.
+
+- make py.test.cmdline.main() return the exitstatus instead of raising
+ SystemExit and also allow it to be called multiple times. This of
+ course requires that your application and tests are properly teared
+ down and don't have global state.
+
+Fixes / Maintenance
+++++++++++++++++++++++
+
+- improved traceback presentation:
+ - improved and unified reporting for "--tb=short" option
+ - Errors during test module imports are much shorter, (using --tb=short style)
+ - raises shows shorter more relevant tracebacks
+ - --fulltrace now more systematically makes traces longer / inhibits cutting
+
+- improve support for raises and other dynamically compiled code by
+ manipulating python's linecache.cache instead of the previous
+ rather hacky way of creating custom code objects. This makes
+ it seemlessly work on Jython and PyPy where it previously didn't.
+
+- fix issue96: make capturing more resilient against Control-C
+ interruptions (involved somewhat substantial refactoring
+ to the underlying capturing functionality to avoid race
+ conditions).
+
+- fix chaining of conditional skipif/xfail decorators - so it works now
+ as expected to use multiple @py.test.mark.skipif(condition) decorators,
+ including specific reporting which of the conditions lead to skipping.
+
+- fix issue95: late-import zlib so that it's not required
+ for general py.test startup.
+
+- fix issue94: make reporting more robust against bogus source code
+ (and internally be more careful when presenting unexpected byte sequences)
+
+
+Changes between 1.2.1 and 1.3.0
+==================================================
+
+- deprecate --report option in favour of a new shorter and easier to
+ remember -r option: it takes a string argument consisting of any
+ combination of 'xfsX' characters. They relate to the single chars
+ you see during the dotted progress printing and will print an extra line
+ per test at the end of the test run. This extra line indicates the exact
+ position or test ID that you directly paste to the py.test cmdline in order
+ to re-run a particular test.
+
+- allow external plugins to register new hooks via the new
+ pytest_addhooks(pluginmanager) hook. The new release of
+ the pytest-xdist plugin for distributed and looponfailing
+ testing requires this feature.
+
+- add a new pytest_ignore_collect(path, config) hook to allow projects and
+ plugins to define exclusion behaviour for their directory structure -
+ for example you may define in a conftest.py this method::
+
+ def pytest_ignore_collect(path):
+ return path.check(link=1)
+
+ to prevent even a collection try of any tests in symlinked dirs.
+
+- new pytest_pycollect_makemodule(path, parent) hook for
+ allowing customization of the Module collection object for a
+ matching test module.
+
+- extend and refine xfail mechanism:
+ ``@py.test.mark.xfail(run=False)`` do not run the decorated test
+ ``@py.test.mark.xfail(reason="...")`` prints the reason string in xfail summaries
+ specifiying ``--runxfail`` on command line virtually ignores xfail markers
+
+- expose (previously internal) commonly useful methods:
+ py.io.get_terminal_with() -> return terminal width
+ py.io.ansi_print(...) -> print colored/bold text on linux/win32
+ py.io.saferepr(obj) -> return limited representation string
+
+- expose test outcome related exceptions as py.test.skip.Exception,
+ py.test.raises.Exception etc., useful mostly for plugins
+ doing special outcome interpretation/tweaking
+
+- (issue85) fix junitxml plugin to handle tests with non-ascii output
+
+- fix/refine python3 compatibility (thanks Benjamin Peterson)
+
+- fixes for making the jython/win32 combination work, note however:
+ jython2.5.1/win32 does not provide a command line launcher, see
+ http://bugs.jython.org/issue1491 . See pylib install documentation
+ for how to work around.
+
+- fixes for handling of unicode exception values and unprintable objects
+
+- (issue87) fix unboundlocal error in assertionold code
+
+- (issue86) improve documentation for looponfailing
+
+- refine IO capturing: stdin-redirect pseudo-file now has a NOP close() method
+
+- ship distribute_setup.py version 0.6.10
+
+- added links to the new capturelog and coverage plugins
+
+
+Changes between 1.2.1 and 1.2.0
+=====================================
+
+- refined usage and options for "py.cleanup"::
+
+ py.cleanup # remove "*.pyc" and "*$py.class" (jython) files
+ py.cleanup -e .swp -e .cache # also remove files with these extensions
+ py.cleanup -s # remove "build" and "dist" directory next to setup.py files
+ py.cleanup -d # also remove empty directories
+ py.cleanup -a # synonym for "-s -d -e 'pip-log.txt'"
+ py.cleanup -n # dry run, only show what would be removed
+
+- add a new option "py.test --funcargs" which shows available funcargs
+ and their help strings (docstrings on their respective factory function)
+ for a given test path
+
+- display a short and concise traceback if a funcarg lookup fails
+
+- early-load "conftest.py" files in non-dot first-level sub directories.
+ allows to conveniently keep and access test-related options in a ``test``
+ subdir and still add command line options.
+
+- fix issue67: new super-short traceback-printing option: "--tb=line" will print a single line for each failing (python) test indicating its filename, lineno and the failure value
+
+- fix issue78: always call python-level teardown functions even if the
+ according setup failed. This includes refinements for calling setup_module/class functions
+ which will now only be called once instead of the previous behaviour where they'd be called
+ multiple times if they raise an exception (including a Skipped exception). Any exception
+ will be re-corded and associated with all tests in the according module/class scope.
+
+- fix issue63: assume <40 columns to be a bogus terminal width, default to 80
+
+- fix pdb debugging to be in the correct frame on raises-related errors
+
+- update apipkg.py to fix an issue where recursive imports might
+ unnecessarily break importing
+
+- fix plugin links
+
+Changes between 1.2 and 1.1.1
+=====================================
+
+- moved dist/looponfailing from py.test core into a new
+ separately released pytest-xdist plugin.
+
+- new junitxml plugin: --junitxml=path will generate a junit style xml file
+ which is processable e.g. by the Hudson CI system.
+
+- new option: --genscript=path will generate a standalone py.test script
+ which will not need any libraries installed. thanks to Ralf Schmitt.
+
+- new option: --ignore will prevent specified path from collection.
+ Can be specified multiple times.
+
+- new option: --confcutdir=dir will make py.test only consider conftest
+ files that are relative to the specified dir.
+
+- new funcarg: "pytestconfig" is the pytest config object for access
+ to command line args and can now be easily used in a test.
+
+- install 'py.test' and `py.which` with a ``-$VERSION`` suffix to
+ disambiguate between Python3, python2.X, Jython and PyPy installed versions.
+
+- new "pytestconfig" funcarg allows access to test config object
+
+- new "pytest_report_header" hook can return additional lines
+ to be displayed at the header of a test run.
+
+- (experimental) allow "py.test path::name1::name2::..." for pointing
+ to a test within a test collection directly. This might eventually
+ evolve as a full substitute to "-k" specifications.
+
+- streamlined plugin loading: order is now as documented in
+ customize.html: setuptools, ENV, commandline, conftest.
+ also setuptools entry point names are turned to canonical namees ("pytest_*")
+
+- automatically skip tests that need 'capfd' but have no os.dup
+
+- allow pytest_generate_tests to be defined in classes as well
+
+- deprecate usage of 'disabled' attribute in favour of pytestmark
+- deprecate definition of Directory, Module, Class and Function nodes
+ in conftest.py files. Use pytest collect hooks instead.
+
+- collection/item node specific runtest/collect hooks are only called exactly
+ on matching conftest.py files, i.e. ones which are exactly below
+ the filesystem path of an item
+
+- change: the first pytest_collect_directory hook to return something
+ will now prevent further hooks to be called.
+
+- change: figleaf plugin now requires --figleaf to run. Also
+ change its long command line options to be a bit shorter (see py.test -h).
+
+- change: pytest doctest plugin is now enabled by default and has a
+ new option --doctest-glob to set a pattern for file matches.
+
+- change: remove internal py._* helper vars, only keep py._pydir
+
+- robustify capturing to survive if custom pytest_runtest_setup
+ code failed and prevented the capturing setup code from running.
+
+- make py.test.* helpers provided by default plugins visible early -
+ works transparently both for pydoc and for interactive sessions
+ which will regularly see e.g. py.test.mark and py.test.importorskip.
+
+- simplify internal plugin manager machinery
+- simplify internal collection tree by introducing a RootCollector node
+
+- fix assert reinterpreation that sees a call containing "keyword=..."
+
+- fix issue66: invoke pytest_sessionstart and pytest_sessionfinish
+ hooks on slaves during dist-testing, report module/session teardown
+ hooks correctly.
+
+- fix issue65: properly handle dist-testing if no
+ execnet/py lib installed remotely.
+
+- skip some install-tests if no execnet is available
+
+- fix docs, fix internal bin/ script generation
+
+
+Changes between 1.1.1 and 1.1.0
+=====================================
+
+- introduce automatic plugin registration via 'pytest11'
+ entrypoints via setuptools' pkg_resources.iter_entry_points
+
+- fix py.test dist-testing to work with execnet >= 1.0.0b4
+
+- re-introduce py.test.cmdline.main() for better backward compatibility
+
+- svn paths: fix a bug with path.check(versioned=True) for svn paths,
+ allow '%' in svn paths, make svnwc.update() default to interactive mode
+ like in 1.0.x and add svnwc.update(interactive=False) to inhibit interaction.
+
+- refine distributed tarball to contain test and no pyc files
+
+- try harder to have deprecation warnings for py.compat.* accesses
+ report a correct location
+
+Changes between 1.1.0 and 1.0.2
+=====================================
+
+* adjust and improve docs
+
+* remove py.rest tool and internal namespace - it was
+ never really advertised and can still be used with
+ the old release if needed. If there is interest
+ it could be revived into its own tool i guess.
+
+* fix issue48 and issue59: raise an Error if the module
+ from an imported test file does not seem to come from
+ the filepath - avoids "same-name" confusion that has
+ been reported repeatedly
+
+* merged Ronny's nose-compatibility hacks: now
+ nose-style setup_module() and setup() functions are
+ supported
+
+* introduce generalized py.test.mark function marking
+
+* reshuffle / refine command line grouping
+
+* deprecate parser.addgroup in favour of getgroup which creates option group
+
+* add --report command line option that allows to control showing of skipped/xfailed sections
+
+* generalized skipping: a new way to mark python functions with skipif or xfail
+ at function, class and modules level based on platform or sys-module attributes.
+
+* extend py.test.mark decorator to allow for positional args
+
+* introduce and test "py.cleanup -d" to remove empty directories
+
+* fix issue #59 - robustify unittest test collection
+
+* make bpython/help interaction work by adding an __all__ attribute
+ to ApiModule, cleanup initpkg
+
+* use MIT license for pylib, add some contributors
+
+* remove py.execnet code and substitute all usages with 'execnet' proper
+
+* fix issue50 - cached_setup now caches more to expectations
+ for test functions with multiple arguments.
+
+* merge Jarko's fixes, issue #45 and #46
+
+* add the ability to specify a path for py.lookup to search in
+
+* fix a funcarg cached_setup bug probably only occuring
+ in distributed testing and "module" scope with teardown.
+
+* many fixes and changes for making the code base python3 compatible,
+ many thanks to Benjamin Peterson for helping with this.
+
+* consolidate builtins implementation to be compatible with >=2.3,
+ add helpers to ease keeping 2 and 3k compatible code
+
+* deprecate py.compat.doctest|subprocess|textwrap|optparse
+
+* deprecate py.magic.autopath, remove py/magic directory
+
+* move pytest assertion handling to py/code and a pytest_assertion
+ plugin, add "--no-assert" option, deprecate py.magic namespaces
+ in favour of (less) py.code ones.
+
+* consolidate and cleanup py/code classes and files
+
+* cleanup py/misc, move tests to bin-for-dist
+
+* introduce delattr/delitem/delenv methods to py.test's monkeypatch funcarg
+
+* consolidate py.log implementation, remove old approach.
+
+* introduce py.io.TextIO and py.io.BytesIO for distinguishing between
+ text/unicode and byte-streams (uses underlying standard lib io.*
+ if available)
+
+* make py.unittest_convert helper script available which converts "unittest.py"
+ style files into the simpler assert/direct-test-classes py.test/nosetests
+ style. The script was written by Laura Creighton.
+
+* simplified internal localpath implementation
+
+Changes between 1.0.1 and 1.0.2
+=====================================
+
+* fixing packaging issues, triggered by fedora redhat packaging,
+ also added doc, examples and contrib dirs to the tarball.
+
+* added a documentation link to the new django plugin.
+
+Changes between 1.0.0 and 1.0.1
+=====================================
+
+* added a 'pytest_nose' plugin which handles nose.SkipTest,
+ nose-style function/method/generator setup/teardown and
+ tries to report functions correctly.
+
+* capturing of unicode writes or encoded strings to sys.stdout/err
+ work better, also terminalwriting was adapted and somewhat
+ unified between windows and linux.
+
+* improved documentation layout and content a lot
+
+* added a "--help-config" option to show conftest.py / ENV-var names for
+ all longopt cmdline options, and some special conftest.py variables.
+ renamed 'conf_capture' conftest setting to 'option_capture' accordingly.
+
+* fix issue #27: better reporting on non-collectable items given on commandline
+ (e.g. pyc files)
+
+* fix issue #33: added --version flag (thanks Benjamin Peterson)
+
+* fix issue #32: adding support for "incomplete" paths to wcpath.status()
+
+* "Test" prefixed classes are *not* collected by default anymore if they
+ have an __init__ method
+
+* monkeypatch setenv() now accepts a "prepend" parameter
+
+* improved reporting of collection error tracebacks
+
+* simplified multicall mechanism and plugin architecture,
+ renamed some internal methods and argnames
+
+Changes between 1.0.0b9 and 1.0.0
+=====================================
+
+* more terse reporting try to show filesystem path relatively to current dir
+* improve xfail output a bit
+
+Changes between 1.0.0b8 and 1.0.0b9
+=====================================
+
+* cleanly handle and report final teardown of test setup
+
+* fix svn-1.6 compat issue with py.path.svnwc().versioned()
+ (thanks Wouter Vanden Hove)
+
+* setup/teardown or collection problems now show as ERRORs
+ or with big "E"'s in the progress lines. they are reported
+ and counted separately.
+
+* dist-testing: properly handle test items that get locally
+ collected but cannot be collected on the remote side - often
+ due to platform/dependency reasons
+
+* simplified py.test.mark API - see keyword plugin documentation
+
+* integrate better with logging: capturing now by default captures
+ test functions and their immediate setup/teardown in a single stream
+
+* capsys and capfd funcargs now have a readouterr() and a close() method
+ (underlyingly py.io.StdCapture/FD objects are used which grew a
+ readouterr() method as well to return snapshots of captured out/err)
+
+* make assert-reinterpretation work better with comparisons not
+ returning bools (reported with numpy from thanks maciej fijalkowski)
+
+* reworked per-test output capturing into the pytest_iocapture.py plugin
+ and thus removed capturing code from config object
+
+* item.repr_failure(excinfo) instead of item.repr_failure(excinfo, outerr)
+
+
+Changes between 1.0.0b7 and 1.0.0b8
+=====================================
+
+* pytest_unittest-plugin is now enabled by default
+
+* introduced pytest_keyboardinterrupt hook and
+ refined pytest_sessionfinish hooked, added tests.
+
+* workaround a buggy logging module interaction ("closing already closed
+ files"). Thanks to Sridhar Ratnakumar for triggering.
+
+* if plugins use "py.test.importorskip" for importing
+ a dependency only a warning will be issued instead
+ of exiting the testing process.
+
+* many improvements to docs:
+ - refined funcargs doc , use the term "factory" instead of "provider"
+ - added a new talk/tutorial doc page
+ - better download page
+ - better plugin docstrings
+ - added new plugins page and automatic doc generation script
+
+* fixed teardown problem related to partially failing funcarg setups
+ (thanks MrTopf for reporting), "pytest_runtest_teardown" is now
+ always invoked even if the "pytest_runtest_setup" failed.
+
+* tweaked doctest output for docstrings in py modules,
+ thanks Radomir.
+
+Changes between 1.0.0b3 and 1.0.0b7
+=============================================
+
+* renamed py.test.xfail back to py.test.mark.xfail to avoid
+ two ways to decorate for xfail
+
+* re-added py.test.mark decorator for setting keywords on functions
+ (it was actually documented so removing it was not nice)
+
+* remove scope-argument from request.addfinalizer() because
+ request.cached_setup has the scope arg. TOOWTDI.
+
+* perform setup finalization before reporting failures
+
+* apply modified patches from Andreas Kloeckner to allow
+ test functions to have no func_code (#22) and to make
+ "-k" and function keywords work (#20)
+
+* apply patch from Daniel Peolzleithner (issue #23)
+
+* resolve issue #18, multiprocessing.Manager() and
+ redirection clash
+
+* make __name__ == "__channelexec__" for remote_exec code
+
+Changes between 1.0.0b1 and 1.0.0b3
+=============================================
+
+* plugin classes are removed: one now defines
+ hooks directly in conftest.py or global pytest_*.py
+ files.
+
+* added new pytest_namespace(config) hook that allows
+ to inject helpers directly to the py.test.* namespace.
+
+* documented and refined many hooks
+
+* added new style of generative tests via
+ pytest_generate_tests hook that integrates
+ well with function arguments.
+
+
+Changes between 0.9.2 and 1.0.0b1
+=============================================
+
+* introduced new "funcarg" setup method,
+ see doc/test/funcarg.txt
+
+* introduced plugin architecuture and many
+ new py.test plugins, see
+ doc/test/plugins.txt
+
+* teardown_method is now guaranteed to get
+ called after a test method has run.
+
+* new method: py.test.importorskip(mod,minversion)
+ will either import or call py.test.skip()
+
+* completely revised internal py.test architecture
+
+* new py.process.ForkedFunc object allowing to
+ fork execution of a function to a sub process
+ and getting a result back.
+
+XXX lots of things missing here XXX
+
+Changes between 0.9.1 and 0.9.2
+===============================
+
+* refined installation and metadata, created new setup.py,
+ now based on setuptools/ez_setup (thanks to Ralf Schmitt
+ for his support).
+
+* improved the way of making py.* scripts available in
+ windows environments, they are now added to the
+ Scripts directory as ".cmd" files.
+
+* py.path.svnwc.status() now is more complete and
+ uses xml output from the 'svn' command if available
+ (Guido Wesdorp)
+
+* fix for py.path.svn* to work with svn 1.5
+ (Chris Lamb)
+
+* fix path.relto(otherpath) method on windows to
+ use normcase for checking if a path is relative.
+
+* py.test's traceback is better parseable from editors
+ (follows the filenames:LINENO: MSG convention)
+ (thanks to Osmo Salomaa)
+
+* fix to javascript-generation, "py.test --runbrowser"
+ should work more reliably now
+
+* removed previously accidentally added
+ py.test.broken and py.test.notimplemented helpers.
+
+* there now is a py.__version__ attribute
+
+Changes between 0.9.0 and 0.9.1
+===============================
+
+This is a fairly complete list of changes between 0.9 and 0.9.1, which can
+serve as a reference for developers.
+
+* allowing + signs in py.path.svn urls [39106]
+* fixed support for Failed exceptions without excinfo in py.test [39340]
+* added support for killing processes for Windows (as well as platforms that
+ support os.kill) in py.misc.killproc [39655]
+* added setup/teardown for generative tests to py.test [40702]
+* added detection of FAILED TO LOAD MODULE to py.test [40703, 40738, 40739]
+* fixed problem with calling .remove() on wcpaths of non-versioned files in
+ py.path [44248]
+* fixed some import and inheritance issues in py.test [41480, 44648, 44655]
+* fail to run greenlet tests when pypy is available, but without stackless
+ [45294]
+* small fixes in rsession tests [45295]
+* fixed issue with 2.5 type representations in py.test [45483, 45484]
+* made that internal reporting issues displaying is done atomically in py.test
+ [45518]
+* made that non-existing files are igored by the py.lookup script [45519]
+* improved exception name creation in py.test [45535]
+* made that less threads are used in execnet [merge in 45539]
+* removed lock required for atomical reporting issue displaying in py.test
+ [45545]
+* removed globals from execnet [45541, 45547]
+* refactored cleanup mechanics, made that setDaemon is set to 1 to make atexit
+ get called in 2.5 (py.execnet) [45548]
+* fixed bug in joining threads in py.execnet's servemain [45549]
+* refactored py.test.rsession tests to not rely on exact output format anymore
+ [45646]
+* using repr() on test outcome [45647]
+* added 'Reason' classes for py.test.skip() [45648, 45649]
+* killed some unnecessary sanity check in py.test.collect [45655]
+* avoid using os.tmpfile() in py.io.fdcapture because on Windows it's only
+ usable by Administrators [45901]
+* added support for locking and non-recursive commits to py.path.svnwc [45994]
+* locking files in py.execnet to prevent CPython from segfaulting [46010]
+* added export() method to py.path.svnurl
+* fixed -d -x in py.test [47277]
+* fixed argument concatenation problem in py.path.svnwc [49423]
+* restore py.test behaviour that it exits with code 1 when there are failures
+ [49974]
+* don't fail on html files that don't have an accompanying .txt file [50606]
+* fixed 'utestconvert.py < input' [50645]
+* small fix for code indentation in py.code.source [50755]
+* fix _docgen.py documentation building [51285]
+* improved checks for source representation of code blocks in py.test [51292]
+* added support for passing authentication to py.path.svn* objects [52000,
+ 52001]
+* removed sorted() call for py.apigen tests in favour of [].sort() to support
+ Python 2.3 [52481]
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.3.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.3.txt
new file mode 100644
index 00000000000..c62cb859053
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.3.txt
@@ -0,0 +1,26 @@
+py.test/pylib 1.3.3: windows and other fixes
+===========================================================================
+
+pylib/py.test 1.3.3 is a minor bugfix release featuring some improvements
+and fixes. See changelog_ for full history.
+
+have fun,
+holger krekel
+
+.. _changelog: ../changelog.html
+
+Changes between 1.3.2 and 1.3.3
+==================================================
+
+- fix issue113: assertion representation problem with triple-quoted strings
+ (and possibly other cases)
+- make conftest loading detect that a conftest file with the same
+ content was already loaded, avoids surprises in nested directory structures
+ which can be produced e.g. by Hudson. It probably removes the need to use
+ --confcutdir in most cases.
+- fix terminal coloring for win32
+ (thanks Michael Foord for reporting)
+- fix weirdness: make terminal width detection work on stdout instead of stdin
+ (thanks Armin Ronacher for reporting)
+- remove trailing whitespace in all py/text distribution files
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.4.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.4.txt
new file mode 100644
index 00000000000..c156c8bdb33
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.3.4.txt
@@ -0,0 +1,22 @@
+py.test/pylib 1.3.4: fixes and new native traceback option
+===========================================================================
+
+pylib/py.test 1.3.4 is a minor maintenance release mostly containing bug fixes
+and a new "--tb=native" traceback option to show "normal" Python standard
+tracebacks instead of the py.test enhanced tracebacks. See below for more
+change info and http://pytest.org for more general information on features
+and configuration of the testing tool.
+
+Thanks to the issue reporters and generally to Ronny Pfannschmidt for help.
+
+cheers,
+holger krekel
+
+Changes between 1.3.3 and 1.3.4
+==================================================
+
+- fix issue111: improve install documentation for windows
+- fix issue119: fix custom collectability of __init__.py as a module
+- fix issue116: --doctestmodules work with __init__.py files as well
+- fix issue115: unify internal exception passthrough/catching/GeneratorExit
+- fix issue118: new --tb=native for presenting cpython-standard exceptions
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.0.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.0.txt
new file mode 100644
index 00000000000..6f9a7714d9f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.0.txt
@@ -0,0 +1,47 @@
+
+.. _`release-1.4.0`:
+
+py-1.4.0: cross-python lib for path, code, io, ... manipulations
+===========================================================================
+
+"py" is a small library comprising APIs for filesystem and svn path
+manipulations, dynamic code construction and introspection, a Py2/Py3
+compatibility namespace ("py.builtin"), IO capturing, terminal colored printing
+(on windows and linux), ini-file parsing and a lazy import mechanism.
+It runs unmodified on all Python interpreters compatible to Python2.4 up
+until Python 3.2. The general goal with "py" is to provide stable APIs
+for some common tasks that are continously tested against many Python
+interpreters and thus also to help transition. Here are some docs:
+
+ http://pylib.org
+
+NOTE: The prior py-1.3.X versions contained "py.test" which now comes
+as its own separate "pytest" distribution and was just released
+as "pytest-2.0.0", see here for the revamped docs:
+
+ http://pytest.org
+
+And "py.cleanup|py.lookup|py.countloc" etc. helpers are now part of
+the pycmd distribution, see http://pypi.python.org/pypi/pycmd
+
+This makes "py-1.4.0" a simple library which does not install
+any command line utilities anymore.
+
+cheers,
+holger
+
+Changes between 1.3.4 and 1.4.0
+-------------------------------------
+
+- py.test was moved to a separate "pytest" package. What remains is
+ a stub hook which will proxy ``import py.test`` to ``pytest``.
+- all command line tools ("py.cleanup/lookup/countloc/..." moved
+ to "pycmd" package)
+- removed the old and deprecated "py.magic" namespace
+- use apipkg-1.1 and make py.apipkg.initpkg|ApiModule available
+- add py.iniconfig module for brain-dead easy ini-config file parsing
+- introduce py.builtin.any()
+- path objects have a .dirname attribute now (equivalent to
+ os.path.dirname(path))
+- path.visit() accepts breadthfirst (bf) and sort options
+- remove deprecated py.compat namespace
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.1.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.1.txt
new file mode 100644
index 00000000000..a5aa76b1438
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/release-1.4.1.txt
@@ -0,0 +1,47 @@
+
+.. _`release-1.4.1`:
+
+py-1.4.1: cross-python lib for fs path, code, io, ... manipulations
+===========================================================================
+
+This is a bug fix release of the "py" lib, see below for detailed changes.
+The py lib is a small library comprising APIs for filesystem and svn path
+manipulations, dynamic code construction and introspection, a Py2/Py3
+compatibility namespace ("py.builtin"), IO capturing, terminal colored printing
+(on windows and linux), ini-file parsing and a lazy import mechanism.
+It runs unmodified on all Python interpreters compatible to Python2.4 up
+until Python 3.2, PyPy and Jython. The general goal with "py" is to
+provide stable APIs for some common tasks that are continously tested
+against many Python interpreters and thus also to help transition. Here
+are some docs:
+
+ http://pylib.org
+
+NOTE: The prior py-1.3.X versions contained "py.test" which since py-1.4.0
+comes as its own separate "pytest" distribution, see:
+
+ http://pytest.org
+
+Also, the "py.cleanup|py.lookup|py.countloc" helpers are now part of
+the pycmd distribution, see http://pypi.python.org/pypi/pycmd
+
+
+Changes between 1.4.0 and 1.4.1
+==================================================
+
+- fix issue1 - py.error.* classes to be pickleable
+
+- fix issue2 - on windows32 use PATHEXT as the list of potential
+ extensions to find find binaries with py.path.local.sysfind(commandname)
+
+- fix (pytest-) issue10 and refine assertion reinterpretation
+ to avoid breaking if the __nonzero__ of an object fails
+
+- fix (pytest-) issue17 where python3 does not like star-imports,
+ leading to misrepresentation of import-errors in test modules
+
+- fix ``py.error.*`` attribute pypy access
+
+- allow path.samefile(arg) to succeed when arg is a relative filename
+
+- fix (pytest-) issue20 path.samefile(relpath) works as expected now
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/announce/releases.txt b/tests/wpt/web-platform-tests/tools/py/doc/announce/releases.txt
new file mode 100644
index 00000000000..309c29bac5d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/announce/releases.txt
@@ -0,0 +1,16 @@
+=============
+Release notes
+=============
+
+Contents:
+
+.. toctree::
+ :maxdepth: 2
+
+.. include: release-1.1.0
+.. include: release-1.0.2
+
+ release-1.0.1
+ release-1.0.0
+ release-0.9.2
+ release-0.9.0
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/changelog.txt b/tests/wpt/web-platform-tests/tools/py/doc/changelog.txt
new file mode 100644
index 00000000000..237daca3548
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/changelog.txt
@@ -0,0 +1,3 @@
+.. _`changelog`:
+
+.. include:: ../CHANGELOG
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/code.txt b/tests/wpt/web-platform-tests/tools/py/doc/code.txt
new file mode 100644
index 00000000000..bdd8691da03
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/code.txt
@@ -0,0 +1,150 @@
+================================================================================
+py.code: higher level python code and introspection objects
+================================================================================
+
+``py.code`` provides higher level APIs and objects for Code, Frame, Traceback,
+ExceptionInfo and source code construction. The ``py.code`` library
+tries to simplify accessing the code objects as well as creating them.
+There is a small set of interfaces a user needs to deal with, all nicely
+bundled together, and with a rich set of 'Pythonic' functionality.
+
+Contents of the library
+=======================
+
+Every object in the ``py.code`` library wraps a code Python object related
+to code objects, source code, frames and tracebacks: the ``py.code.Code``
+class wraps code objects, ``py.code.Source`` source snippets,
+``py.code.Traceback` exception tracebacks, ``py.code.Frame`` frame
+objects (as found in e.g. tracebacks) and ``py.code.ExceptionInfo`` the
+tuple provided by sys.exc_info() (containing exception and traceback
+information when an exception occurs). Also in the library is a helper function
+``py.code.compile()`` that provides the same functionality as Python's
+built-in 'compile()' function, but returns a wrapped code object.
+
+The wrappers
+============
+
+``py.code.Code``
+-------------------
+
+Code objects are instantiated with a code object or a callable as argument,
+and provide functionality to compare themselves with other Code objects, get to
+the source file or its contents, create new Code objects from scratch, etc.
+
+A quick example::
+
+ >>> import py
+ >>> c = py.code.Code(py.path.local.read)
+ >>> c.path.basename
+ 'common.py'
+ >>> isinstance(c.source(), py.code.Source)
+ True
+ >>> str(c.source()).split('\n')[0]
+ "def read(self, mode='r'):"
+
+.. autoclass:: py.code.Code
+ :members:
+ :inherited-members:
+
+
+``py.code.Source``
+---------------------
+
+Source objects wrap snippets of Python source code, providing a simple yet
+powerful interface to read, deindent, slice, compare, compile and manipulate
+them, things that are not so easy in core Python.
+
+Example::
+
+ >>> s = py.code.Source("""\
+ ... def foo():
+ ... print "foo"
+ ... """)
+ >>> str(s).startswith('def') # automatic de-indentation!
+ True
+ >>> s.isparseable()
+ True
+ >>> sub = s.getstatement(1) # get the statement starting at line 1
+ >>> str(sub).strip() # XXX why is the strip() required?!?
+ 'print "foo"'
+
+.. autoclass:: py.code.Source
+ :members:
+
+
+``py.code.Traceback``
+------------------------
+
+Tracebacks are usually not very easy to examine, you need to access certain
+somewhat hidden attributes of the traceback's items (resulting in expressions
+such as 'fname = tb.tb_next.tb_frame.f_code.co_filename'). The Traceback
+interface (and its TracebackItem children) tries to improve this.
+
+Example::
+
+ >>> import sys
+ >>> try:
+ ... py.path.local(100) # illegal argument
+ ... except:
+ ... exc, e, tb = sys.exc_info()
+ >>> t = py.code.Traceback(tb)
+ >>> first = t[1] # get the second entry (first is in this doc)
+ >>> first.path.basename # second is in py/path/local.py
+ 'local.py'
+ >>> isinstance(first.statement, py.code.Source)
+ True
+ >>> str(first.statement).strip().startswith('raise ValueError')
+ True
+
+.. autoclass:: py.code.Traceback
+ :members:
+
+``py.code.Frame``
+--------------------
+
+Frame wrappers are used in ``py.code.Traceback`` items, and will usually not
+directly be instantiated. They provide some nice methods to evaluate code
+'inside' the frame (using the frame's local variables), get to the underlying
+code (frames have a code attribute that points to a ``py.code.Code`` object)
+and examine the arguments.
+
+Example (using the 'first' TracebackItem instance created above)::
+
+ >>> frame = first.frame
+ >>> isinstance(frame.code, py.code.Code)
+ True
+ >>> isinstance(frame.eval('self'), py.path.local)
+ True
+ >>> [namevalue[0] for namevalue in frame.getargs()]
+ ['cls', 'path']
+
+.. autoclass:: py.code.Frame
+ :members:
+
+``py.code.ExceptionInfo``
+----------------------------
+
+A wrapper around the tuple returned by sys.exc_info() (will call sys.exc_info()
+itself if the tuple is not provided as an argument), provides some handy
+attributes to easily access the traceback and exception string.
+
+Example::
+
+ >>> import sys
+ >>> try:
+ ... foobar()
+ ... except:
+ ... excinfo = py.code.ExceptionInfo()
+ >>> excinfo.typename
+ 'NameError'
+ >>> isinstance(excinfo.traceback, py.code.Traceback)
+ True
+ >>> excinfo.exconly()
+ "NameError: name 'foobar' is not defined"
+
+.. autoclass:: py.code.ExceptionInfo
+ :members:
+
+.. autoclass:: py.code.Traceback
+ :members:
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/conf.py b/tests/wpt/web-platform-tests/tools/py/doc/conf.py
new file mode 100644
index 00000000000..de4cbf8a46f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/conf.py
@@ -0,0 +1,263 @@
+# -*- coding: utf-8 -*-
+#
+# py documentation build configuration file, created by
+# sphinx-quickstart on Thu Oct 21 08:30:10 2010.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.viewcode']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.txt'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'py'
+copyright = u'2010, holger krekel et. al.'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+# The full version, including alpha/beta/rc tags.
+import py
+release = py.__version__
+version = ".".join(release.split(".")[:2])
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'py'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+ ('index', 'py.tex', u'py Documentation',
+ u'holger krekel et. al.', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'py', u'py Documentation',
+ [u'holger krekel et. al.'], 1)
+]
+
+autodoc_member_order = "bysource"
+autodoc_default_flags = "inherited-members"
+
+# -- Options for Epub output ---------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = u'py'
+epub_author = u'holger krekel et. al.'
+epub_publisher = u'holger krekel et. al.'
+epub_copyright = u'2010, holger krekel et. al.'
+
+# The language of the text. It defaults to the language option
+# or en if the language is not set.
+#epub_language = ''
+
+# The scheme of the identifier. Typical schemes are ISBN or URL.
+#epub_scheme = ''
+
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#epub_identifier = ''
+
+# A unique identification for the text.
+#epub_uid = ''
+
+# HTML files that should be inserted before the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_pre_files = []
+
+# HTML files shat should be inserted after the pages created by sphinx.
+# The format is a list of tuples containing the path and title.
+#epub_post_files = []
+
+# A list of files that should not be packed into the epub file.
+#epub_exclude_files = []
+
+# The depth of the table of contents in toc.ncx.
+#epub_tocdepth = 3
+
+# Allow duplicate toc entries.
+#epub_tocdup = True
+
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'http://docs.python.org/': None}
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/download.html b/tests/wpt/web-platform-tests/tools/py/doc/download.html
new file mode 100644
index 00000000000..5f4c466402d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/download.html
@@ -0,0 +1,18 @@
+<html>
+ <head>
+ <meta http-equiv="refresh" content=" 1 ; URL=install.html" />
+ </head>
+
+ <body>
+<script type="text/javascript">
+var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
+document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
+</script>
+<script type="text/javascript">
+try {
+var pageTracker = _gat._getTracker("UA-7597274-3");
+pageTracker._trackPageview();
+} catch(err) {}</script>
+</body>
+</html>
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/example/genhtml.py b/tests/wpt/web-platform-tests/tools/py/doc/example/genhtml.py
new file mode 100644
index 00000000000..b5c8f525b62
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/example/genhtml.py
@@ -0,0 +1,13 @@
+from py.xml import html
+
+paras = "First Para", "Second para"
+
+doc = html.html(
+ html.head(
+ html.meta(name="Content-Type", value="text/html; charset=latin1")),
+ html.body(
+ [html.p(p) for p in paras]))
+
+print unicode(doc).encode('latin1')
+
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/example/genhtmlcss.py b/tests/wpt/web-platform-tests/tools/py/doc/example/genhtmlcss.py
new file mode 100644
index 00000000000..3e6d0af5454
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/example/genhtmlcss.py
@@ -0,0 +1,23 @@
+import py
+html = py.xml.html
+
+class my(html):
+ "a custom style"
+ class body(html.body):
+ style = html.Style(font_size = "120%")
+
+ class h2(html.h2):
+ style = html.Style(background = "grey")
+
+ class p(html.p):
+ style = html.Style(font_weight="bold")
+
+doc = my.html(
+ my.head(),
+ my.body(
+ my.h2("hello world"),
+ my.p("bold as bold can")
+ )
+)
+
+print doc.unicode(indent=2)
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/example/genxml.py b/tests/wpt/web-platform-tests/tools/py/doc/example/genxml.py
new file mode 100644
index 00000000000..5f754e8897b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/example/genxml.py
@@ -0,0 +1,17 @@
+
+import py
+class ns(py.xml.Namespace):
+ pass
+
+doc = ns.books(
+ ns.book(
+ ns.author("May Day"),
+ ns.title("python for java programmers"),),
+ ns.book(
+ ns.author("why", class_="somecssclass"),
+ ns.title("Java for Python programmers"),),
+ publisher="N.N",
+ )
+print doc.unicode(indent=2).encode('utf8')
+
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/faq.txt b/tests/wpt/web-platform-tests/tools/py/doc/faq.txt
new file mode 100644
index 00000000000..52cb4b3fbd3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/faq.txt
@@ -0,0 +1,172 @@
+==================================
+Frequently Asked Questions
+==================================
+
+.. contents::
+ :local:
+ :depth: 2
+
+
+On naming, nosetests, licensing and magic
+===========================================
+
+Why the ``py`` naming? Why not ``pytest``?
+----------------------------------------------------
+
+This mostly has historic reasons - the aim is
+to get away from the somewhat questionable 'py' name
+at some point. These days (2010) the 'py' library
+almost completely comprises APIs that are used
+by the ``py.test`` tool. There also are some
+other uses, e.g. of the ``py.path.local()`` and
+other path implementations. So it requires some
+work to factor them out and do the shift.
+
+Why the ``py.test`` naming?
+------------------------------------
+
+because of TAB-completion under Bash/Shells. If you hit
+``py.<TAB>`` you'll get a list of available development
+tools that all share the ``py.`` prefix. Another motivation
+was to unify the package ("py.test") and tool filename.
+
+What's py.test's relation to ``nosetests``?
+---------------------------------------------
+
+py.test and nose_ share basic philosophy when it comes
+to running Python tests. In fact,
+with py.test-1.1.0 it is ever easier to run many test suites
+that currently work with ``nosetests``. nose_ was created
+as a clone of ``py.test`` when py.test was in the ``0.8`` release
+cycle so some of the newer features_ introduced with py.test-1.0
+and py.test-1.1 have no counterpart in nose_.
+
+.. _nose: http://somethingaboutorange.com/mrl/projects/nose/0.11.1/
+.. _features: test/features.html
+.. _apipkg: http://pypi.python.org/pypi/apipkg
+
+
+What's this "magic" with py.test?
+----------------------------------------
+
+issues where people have used the term "magic" in the past:
+
+* `py/__init__.py`_ uses the apipkg_ mechanism for lazy-importing
+ and full control on what API you get when importing "import py".
+
+* when an ``assert`` statement fails, py.test re-interprets the expression
+ to show intermediate values if a test fails. If your expression
+ has side effects the intermediate values may not be the same, obfuscating
+ the initial error (this is also explained at the command line if it happens).
+ ``py.test --no-assert`` turns off assert re-intepretation.
+ Sidenote: it is good practise to avoid asserts with side effects.
+
+
+.. _`py namespaces`: index.html
+.. _`py/__init__.py`: http://bitbucket.org/hpk42/py-trunk/src/trunk/py/__init__.py
+
+Where does my ``py.test`` come/import from?
+----------------------------------------------
+
+You can issue::
+
+ py.test --version
+
+which tells you both version and import location of the tool.
+
+
+function arguments, parametrized tests and setup
+====================================================
+
+.. _funcargs: test/funcargs.html
+
+Is using funcarg- versus xUnit-based setup a style question?
+---------------------------------------------------------------
+
+It depends. For simple applications or for people experienced
+with nose_ or unittest-style test setup using `xUnit style setup`_
+make some sense. For larger test suites, parametrized testing
+or setup of complex test resources using funcargs_ is recommended.
+Moreover, funcargs are ideal for writing advanced test support
+code (like e.g. the monkeypatch_, the tmpdir_ or capture_ funcargs)
+because the support code can register setup/teardown functions
+in a managed class/module/function scope.
+
+.. _monkeypatch: test/plugin/monkeypatch.html
+.. _tmpdir: test/plugin/tmpdir.html
+.. _capture: test/plugin/capture.html
+.. _`xUnit style setup`: test/xunit_setup.html
+.. _`pytest_nose`: test/plugin/nose.html
+
+.. _`why pytest_pyfuncarg__ methods?`:
+
+Why the ``pytest_funcarg__*`` name for funcarg factories?
+---------------------------------------------------------------
+
+When experimenting with funcargs an explicit registration mechanism
+was considered. But lacking a good use case for this indirection and
+flexibility we decided to go for `Convention over Configuration`_ and
+allow to directly specify the factory. Besides removing the need
+for an indirection it allows to "grep" for ``pytest_funcarg__MYARG``
+and will safely find all factory functions for the ``MYARG`` function
+argument. It helps to alleviate the de-coupling of function
+argument usage and creation.
+
+.. _`Convention over Configuration`: http://en.wikipedia.org/wiki/Convention_over_Configuration
+
+Can I yield multiple values from a factory function?
+-----------------------------------------------------
+
+There are two conceptual reasons why yielding from a factory function
+is not possible:
+
+* Calling factories for obtaining test function arguments
+ is part of setting up and running a test. At that
+ point it is not possible to add new test calls to
+ the test collection anymore.
+
+* If multiple factories yielded values there would
+ be no natural place to determine the combination
+ policy - in real-world examples some combinations
+ often should not run.
+
+Use the `pytest_generate_tests`_ hook to solve both issues
+and implement the `parametrization scheme of your choice`_.
+
+.. _`pytest_generate_tests`: test/funcargs.html#parametrizing-tests
+.. _`parametrization scheme of your choice`: http://tetamap.wordpress.com/2009/05/13/parametrizing-python-tests-generalized/
+
+
+py.test interaction with other packages
+===============================================
+
+Issues with py.test, multiprocess and setuptools?
+------------------------------------------------------------
+
+On windows the multiprocess package will instantiate sub processes
+by pickling and thus implicitely re-import a lot of local modules.
+Unfortuantely, setuptools-0.6.11 does not ``if __name__=='__main__'``
+protect its generated command line script. This leads to infinite
+recursion when running a test that instantiates Processes.
+There are these workarounds:
+
+* `install Distribute`_ as a drop-in replacement for setuptools
+ and install py.test
+
+* `directly use a checkout`_ which avoids all setuptools/Distribute
+ installation
+
+If those options are not available to you, you may also manually
+fix the script that is created by setuptools by inserting an
+``if __name__ == '__main__'``. Or you can create a "pytest.py"
+script with this content and invoke that with the python version::
+
+ import py
+ if __name__ == '__main__':
+ py.cmdline.pytest()
+
+.. _`directly use a checkout`: install.html#directly-use-a-checkout
+
+.. _`install distribute`: http://pypi.python.org/pypi/distribute#installation-instructions
+
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/img/pylib.png b/tests/wpt/web-platform-tests/tools/py/doc/img/pylib.png
new file mode 100644
index 00000000000..2e10d438866
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/img/pylib.png
Binary files differ
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/index.txt b/tests/wpt/web-platform-tests/tools/py/doc/index.txt
new file mode 100644
index 00000000000..7eb5c63905e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/index.txt
@@ -0,0 +1,43 @@
+.. py documentation master file, created by
+ sphinx-quickstart on Thu Oct 21 08:30:10 2010.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to py's documentation!
+=================================
+
+see :ref:`CHANGELOG <changelog>` for latest changes.
+
+.. note::
+
+ Since version 1.4, the testing tool "py.test" is part of its own `pytest distribution`_.
+
+.. _`pytest distribution`: http://pytest.org
+
+Contents:
+
+.. toctree::
+
+ install
+ path
+ code
+ io
+ log
+ xml
+ misc
+
+ :maxdepth: 2
+
+.. toctree::
+ :hidden:
+
+ announce/release-2.0.0
+ changelog
+ announce/*
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`search`
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/install.txt b/tests/wpt/web-platform-tests/tools/py/doc/install.txt
new file mode 100644
index 00000000000..d0e981def45
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/install.txt
@@ -0,0 +1,88 @@
+
+.. _`py`:
+.. _`index page`: http://pypi.python.org/pypi/py/
+
+installation info in a nutshell
+===================================================
+
+**PyPI name**: py_
+
+**Pythons**: CPython 2.6, 2.7, 3.3, 3.4, PyPy-2.3
+
+**Operating systems**: Linux, Windows, OSX, Unix
+
+**Requirements**: setuptools_ or Distribute_
+
+**Installers**: ``easy_install`` and ``pip``
+
+**hg repository**: https://bitbucket.org/hpk42/py
+
+easy install or pip ``py``
+-----------------------------
+
+Both `Distribute`_ and setuptools_ provide the ``easy_install``
+installation tool with which you can type into a command line window::
+
+ easy_install -U py
+
+to install the latest release of the py lib. The ``-U`` switch
+will trigger an upgrade if you already have an older version installed.
+
+.. note::
+
+ As of version 1.4 py does not contain py.test anymore - you
+ need to install the new `pytest`_ distribution.
+
+.. _pytest: http://pytest.org
+
+Working from version control or a tarball
+-----------------------------------------------
+
+To follow development or start experiments, checkout the
+complete code and documentation source with mercurial_::
+
+ hg clone https://bitbucket.org/hpk42/py
+
+Development takes place on the 'trunk' branch.
+
+You can also go to the python package index and
+download and unpack a TAR file::
+
+ http://pypi.python.org/pypi/py/
+
+activating a checkout with setuptools
+--------------------------------------------
+
+With a working `Distribute`_ or setuptools_ installation you can type::
+
+ python setup.py develop
+
+in order to work inline with the tools and the lib of your checkout.
+
+.. _`no-setuptools`:
+
+.. _`directly use a checkout`:
+
+.. _`setuptools`: http://pypi.python.org/pypi/setuptools
+
+
+Mailing list and issue tracker
+--------------------------------------
+
+- `py-dev developers list`_ and `commit mailing list`_.
+
+- #pylib on irc.freenode.net IRC channel for random questions.
+
+- `bitbucket issue tracker`_ use this bitbucket issue tracker to report
+ bugs or request features.
+
+.. _`bitbucket issue tracker`: http://bitbucket.org/hpk42/py/issues/
+
+.. _codespeak: http://codespeak.net/
+.. _`py-dev`:
+.. _`development mailing list`:
+.. _`py-dev developers list`: http://codespeak.net/mailman/listinfo/py-dev
+.. _`py-svn`:
+.. _`commit mailing list`: http://codespeak.net/mailman/listinfo/py-svn
+
+.. include:: links.inc
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/io.txt b/tests/wpt/web-platform-tests/tools/py/doc/io.txt
new file mode 100644
index 00000000000..c11308a6d28
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/io.txt
@@ -0,0 +1,59 @@
+=======
+py.io
+=======
+
+
+The 'py' lib provides helper classes for capturing IO during
+execution of a program.
+
+IO Capturing examples
+===============================================
+
+``py.io.StdCapture``
+---------------------------
+
+Basic Example::
+
+ >>> import py
+ >>> capture = py.io.StdCapture()
+ >>> print "hello"
+ >>> out,err = capture.reset()
+ >>> out.strip() == "hello"
+ True
+
+For calling functions you may use a shortcut::
+
+ >>> import py
+ >>> def f(): print "hello"
+ >>> res, out, err = py.io.StdCapture.call(f)
+ >>> out.strip() == "hello"
+ True
+
+``py.io.StdCaptureFD``
+---------------------------
+
+If you also want to capture writes to the stdout/stderr
+filedescriptors you may invoke::
+
+ >>> import py, sys
+ >>> capture = py.io.StdCaptureFD(out=False, in_=False)
+ >>> sys.stderr.write("world")
+ >>> out,err = capture.reset()
+ >>> err
+ 'world'
+
+py.io object reference
+============================
+
+.. autoclass:: py.io.StdCaptureFD
+ :members:
+ :inherited-members:
+
+.. autoclass:: py.io.StdCapture
+ :members:
+ :inherited-members:
+
+.. autoclass:: py.io.TerminalWriter
+ :members:
+ :inherited-members:
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/links.inc b/tests/wpt/web-platform-tests/tools/py/doc/links.inc
new file mode 100644
index 00000000000..9bcfe5cf85c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/links.inc
@@ -0,0 +1,16 @@
+
+.. _`skipping plugin`: plugin/skipping.html
+.. _`funcargs mechanism`: funcargs.html
+.. _`doctest.py`: http://docs.python.org/library/doctest.html
+.. _`xUnit style setup`: xunit_setup.html
+.. _`pytest_nose`: plugin/nose.html
+.. _`reStructured Text`: http://docutils.sourceforge.net
+.. _`Python debugger`: http://docs.python.org/lib/module-pdb.html
+.. _nose: http://somethingaboutorange.com/mrl/projects/nose/
+.. _pytest: http://pypi.python.org/pypi/pytest
+.. _mercurial: http://mercurial.selenic.com/wiki/
+.. _`setuptools`: http://pypi.python.org/pypi/setuptools
+.. _`distribute`: http://pypi.python.org/pypi/distribute
+.. _`pip`: http://pypi.python.org/pypi/pip
+.. _`virtualenv`: http://pypi.python.org/pypi/virtualenv
+.. _hudson: http://hudson-ci.org/
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/log.txt b/tests/wpt/web-platform-tests/tools/py/doc/log.txt
new file mode 100644
index 00000000000..ca60fcac250
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/log.txt
@@ -0,0 +1,208 @@
+.. role:: code(literal)
+.. role:: file(literal)
+
+.. XXX figure out how the code literals should be dealt with in sphinx. There is probably something builtin.
+
+========================================
+py.log documentation and musings
+========================================
+
+
+Foreword
+========
+
+This document is an attempt to briefly state the actual specification of the
+:code:`py.log` module. It was written by Francois Pinard and also contains
+some ideas for enhancing the py.log facilities.
+
+NOTE that :code:`py.log` is subject to refactorings, it may change with
+the next release.
+
+This document is meant to trigger or facilitate discussions. It shamelessly
+steals from the `Agile Testing`__ comments, and from other sources as well,
+without really trying to sort them out.
+
+__ http://agiletesting.blogspot.com/2005/06/keyword-based-logging-with-py-library.html
+
+
+Logging organisation
+====================
+
+The :code:`py.log` module aims a niche comparable to the one of the
+`logging module`__ found within the standard Python distributions, yet
+with much simpler paradigms for configuration and usage.
+
+__ http://www.python.org/doc/2.4.2/lib/module-logging.html
+
+Holger Krekel, the main :code:`py` library developer, introduced
+the idea of keyword-based logging and the idea of logging *producers* and
+*consumers*. A log producer is an object used by the application code
+to send messages to various log consumers. When you create a log
+producer, you define a set of keywords that are then used to both route
+the logging messages to consumers, and to prefix those messages.
+
+In fact, each log producer has a few keywords associated with it for
+identification purposes. These keywords form a tuple of strings, and
+may be used to later retrieve a particular log producer.
+
+A log producer may (or may not) be associated with a log consumer, meant
+to handle log messages in particular ways. The log consumers can be
+``STDOUT``, ``STDERR``, log files, syslog, the Windows Event Log, user
+defined functions, etc. (Yet, logging to syslog or to the Windows Event
+Log is only future plans for now). A log producer has never more than
+one consumer at a given time, but it is possible to dynamically switch
+a producer to use another consumer. On the other hand, a single log
+consumer may be associated with many producers.
+
+Note that creating and associating a producer and a consumer is done
+automatically when not otherwise overriden, so using :code:`py` logging
+is quite comfortable even in the smallest programs. More typically,
+the application programmer will likely design a hierarchy of producers,
+and will select keywords appropriately for marking the hierarchy tree.
+If a node of the hierarchical tree of producers has to be divided in
+sub-trees, all producers in the sub-trees share, as a common prefix, the
+keywords of the node being divided. In other words, we go further down
+in the hierarchy of producers merely by adding keywords.
+
+Using the py.log library
+================================
+
+To use the :code:`py.log` library, the user must import it into a Python
+application, create at least one log producer and one log consumer, have
+producers and consumers associated, and finally call the log producers
+as needed, giving them log messages.
+
+Importing
+---------
+
+Once the :code:`py` library is installed on your system, a mere::
+
+ import py
+
+holds enough magic for lazily importing the various facilities of the
+:code:`py` library when they are first needed. This is really how
+:code:`py.log` is made available to the application. For example, after
+the above ``import py``, one may directly write ``py.log.Producer(...)``
+and everything should work fine, the user does not have to worry about
+specifically importing more modules.
+
+Creating a producer
+-------------------
+
+There are three ways for creating a log producer instance:
+
+ + As soon as ``py.log`` is first evaluated within an application
+ program, a default log producer is created, and made available under
+ the name ``py.log.default``. The keyword ``default`` is associated
+ with that producer.
+
+ + The ``py.log.Producer()`` constructor may be explicitly called
+ for creating a new instance of a log producer. That constructor
+ accepts, as an argument, the keywords that should be associated with
+ that producer. Keywords may be given either as a tuple of keyword
+ strings, or as a single space-separated string of keywords.
+
+ + Whenever an attribute is *taken* out of a log producer instance,
+ for the first time that attribute is taken, a new log producer is
+ created. The keywords associated with that new producer are those
+ of the initial producer instance, to which is appended the name of
+ the attribute being taken.
+
+The last point is especially useful, as it allows using log producers
+without further declarations, merely creating them *on-the-fly*.
+
+Creating a consumer
+-------------------
+
+There are many ways for creating or denoting a log consumer:
+
+ + A default consumer exists within the ``py.log`` facilities, which
+ has the effect of writing log messages on the Python standard output
+ stream. That consumer is associated at the very top of the producer
+ hierarchy, and as such, is called whenever no other consumer is
+ found.
+
+ + The notation ``py.log.STDOUT`` accesses a log consumer which writes
+ log messages on the Python standard output stream.
+
+ + The notation ``py.log.STDERR`` accesses a log consumer which writes
+ log messages on the Python standard error stream.
+
+ + The ``py.log.File()`` constructor accepts, as argument, either a file
+ already opened in write mode or any similar file-like object, and
+ creates a log consumer able to write log messages onto that file.
+
+ + The ``py.log.Path()`` constructor accepts a file name for its first
+ argument, and creates a log consumer able to write log messages into
+ that file. The constructor call accepts a few keyword parameters:
+
+ + ``append``, which is ``False`` by default, may be used for
+ opening the file in append mode instead of write mode.
+
+ + ``delayed_create``, which is ``False`` by default, maybe be used
+ for opening the file at the latest possible time. Consequently,
+ the file will not be created if it did not exist, and no actual
+ log message gets written to it.
+
+ + ``buffering``, which is 1 by default, is used when opening the
+ file. Buffering can be turned off by specifying a 0 value. The
+ buffer size may also be selected through this argument.
+
+ + Any user defined function may be used for a log consumer. Such a
+ function should accept a single argument, which is the message to
+ write, and do whatever is deemed appropriate by the programmer.
+ When the need arises, this may be an especially useful and flexible
+ feature.
+
+ + The special value ``None`` means no consumer at all. This acts just
+ like if there was a consumer which would silently discard all log
+ messages sent to it.
+
+Associating producers and consumers
+-----------------------------------
+
+Each log producer may have at most one log consumer associated with
+it. A log producer gets associated with a log consumer through a
+``py.log.setconsumer()`` call. That function accepts two arguments,
+the first identifying a producer (a tuple of keyword strings or a single
+space-separated string of keywords), the second specifying the precise
+consumer to use for that producer. Until this function is called for a
+producer, that producer does not have any explicit consumer associated
+with it.
+
+Now, the hierarchy of log producers establishes which consumer gets used
+whenever a producer has no explicit consumer. When a log producer
+has no consumer explicitly associated with it, it dynamically and
+recursively inherits the consumer of its parent node, that is, that node
+being a bit closer to the root of the hierarchy. In other words, the
+rightmost keywords of that producer are dropped until another producer
+is found which has an explicit consumer. A nice side-effect is that,
+by explicitly associating a consumer with a producer, all consumer-less
+producers which appear under that producer, in the hierarchy tree,
+automatically *inherits* that consumer.
+
+Writing log messages
+--------------------
+
+All log producer instances are also functions, and this is by calling
+them that log messages are generated. Each call to a producer object
+produces the text for one log entry, which in turn, is sent to the log
+consumer for that producer.
+
+The log entry displays, after a prefix identifying the log producer
+being used, all arguments given in the call, converted to strings and
+space-separated. (This is meant by design to be fairly similar to what
+the ``print`` statement does in Python). The prefix itself is made up
+of a colon-separated list of keywords associated with the producer, the
+whole being set within square brackets.
+
+Note that the consumer is responsible for adding the newline at the end
+of the log entry. That final newline is not part of the text for the
+log entry.
+
+.. Other details
+.. -------------
+.. XXX: fill in details
+.. + Should speak about pickle-ability of :code:`py.log`.
+..
+.. + What is :code:`log.get` (in :file:`logger.py`)?
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/misc.txt b/tests/wpt/web-platform-tests/tools/py/doc/misc.txt
new file mode 100644
index 00000000000..8c3c0b3f7a3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/misc.txt
@@ -0,0 +1,93 @@
+====================================
+Miscellaneous features of the py lib
+====================================
+
+Mapping the standard python library into py
+===========================================
+
+The ``py.std`` object allows lazy access to
+standard library modules. For example, to get to the print-exception
+functionality of the standard library you can write::
+
+ py.std.traceback.print_exc()
+
+without having to do anything else than the usual ``import py``
+at the beginning. You can access any other top-level standard
+library module this way. This means that you will only trigger
+imports of modules that are actually needed. Note that no attempt
+is made to import submodules.
+
+Support for interaction with system utilities/binaries
+======================================================
+
+Currently, the py lib offers two ways to interact with
+system executables. ``py.process.cmdexec()`` invokes
+the shell in order to execute a string. The other
+one, ``py.path.local``'s 'sysexec()' method lets you
+directly execute a binary.
+
+Both approaches will raise an exception in case of a return-
+code other than 0 and otherwise return the stdout-output
+of the child process.
+
+The shell based approach
+------------------------
+
+You can execute a command via your system shell
+by doing something like::
+
+ out = py.process.cmdexec('ls -v')
+
+However, the ``cmdexec`` approach has a few shortcomings:
+
+- it relies on the underlying system shell
+- it neccessitates shell-escaping for expressing arguments
+- it does not easily allow to "fix" the binary you want to run.
+- it only allows to execute executables from the local
+ filesystem
+
+.. _sysexec:
+
+local paths have ``sysexec``
+----------------------------
+
+In order to synchronously execute an executable file you
+can use ``sysexec``::
+
+ binsvn.sysexec('ls', 'http://codespeak.net/svn')
+
+where ``binsvn`` is a path that points to the ``svn`` commandline
+binary. Note that this function does not offer any shell-escaping
+so you have to pass in already separated arguments.
+
+finding an executable local path
+--------------------------------
+
+Finding an executable is quite different on multiple platforms.
+Currently, the ``PATH`` environment variable based search on
+unix platforms is supported::
+
+ py.path.local.sysfind('svn')
+
+which returns the first path whose ``basename`` matches ``svn``.
+In principle, `sysfind` deploys platform specific algorithms
+to perform the search. On Windows, for example, it may look
+at the registry (XXX).
+
+To make the story complete, we allow to pass in a second ``checker``
+argument that is called for each found executable. For example, if
+you have multiple binaries available you may want to select the
+right version::
+
+ def mysvn(p):
+ """ check that the given svn binary has version 1.1. """
+ line = p.execute('--version'').readlines()[0]
+ if line.find('version 1.1'):
+ return p
+ binsvn = py.path.local.sysfind('svn', checker=mysvn)
+
+
+Cross-Python Version compatibility helpers
+=============================================
+
+The ``py.builtin`` namespace provides a number of helpers that help to write python code compatible across Python interpreters, mainly Python2 and Python3. Type ``help(py.builtin)`` on a Python prompt for a the selection of builtins.
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/path.txt b/tests/wpt/web-platform-tests/tools/py/doc/path.txt
new file mode 100644
index 00000000000..837c1d19272
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/path.txt
@@ -0,0 +1,260 @@
+=======
+py.path
+=======
+
+The 'py' lib provides a uniform high-level api to deal with filesystems
+and filesystem-like interfaces: ``py.path``. It aims to offer a central
+object to fs-like object trees (reading from and writing to files, adding
+files/directories, examining the types and structure, etc.), and out-of-the-box
+provides a number of implementations of this API.
+
+py.path.local - local file system path
+===============================================
+
+.. _`local`:
+
+basic interactive example
+-------------------------------------
+
+The first and most obvious of the implementations is a wrapper around a local
+filesystem. It's just a bit nicer in usage than the regular Python APIs, and
+of course all the functionality is bundled together rather than spread over a
+number of modules.
+
+Example usage, here we use the ``py.test.ensuretemp()`` function to create
+a ``py.path.local`` object for us (which wraps a directory):
+
+.. sourcecode:: pycon
+
+ >>> import py
+ >>> temppath = py.test.ensuretemp('py.path_documentation')
+ >>> foopath = temppath.join('foo') # get child 'foo' (lazily)
+ >>> foopath.check() # check if child 'foo' exists
+ False
+ >>> foopath.write('bar') # write some data to it
+ >>> foopath.check()
+ True
+ >>> foopath.read()
+ 'bar'
+ >>> foofile = foopath.open() # return a 'real' file object
+ >>> foofile.read(1)
+ 'b'
+
+reference documentation
+---------------------------------
+
+.. autoclass:: py._path.local.LocalPath
+ :members:
+ :inherited-members:
+
+``py.path.svnurl`` and ``py.path.svnwc``
+==================================================
+
+Two other ``py.path`` implementations that the py lib provides wrap the
+popular `Subversion`_ revision control system: the first (called 'svnurl')
+by interfacing with a remote server, the second by wrapping a local checkout.
+Both allow you to access relatively advanced features such as metadata and
+versioning, and both in a way more user-friendly manner than existing other
+solutions.
+
+Some example usage of ``py.path.svnurl``:
+
+.. sourcecode:: pycon
+
+ .. >>> import py
+ .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
+ >>> url = py.path.svnurl('http://codespeak.net/svn/py')
+ >>> info = url.info()
+ >>> info.kind
+ 'dir'
+ >>> firstentry = url.log()[-1]
+ >>> import time
+ >>> time.strftime('%Y-%m-%d', time.gmtime(firstentry.date))
+ '2004-10-02'
+
+Example usage of ``py.path.svnwc``:
+
+.. sourcecode:: pycon
+
+ .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
+ >>> temp = py.test.ensuretemp('py.path_documentation')
+ >>> wc = py.path.svnwc(temp.join('svnwc'))
+ >>> wc.checkout('http://codespeak.net/svn/py/dist/py/path/local')
+ >>> wc.join('local.py').check()
+ True
+
+.. _`Subversion`: http://subversion.tigris.org/
+
+svn path related API reference
+-----------------------------------------
+
+.. autoclass:: py._path.svnwc.SvnWCCommandPath
+ :members:
+ :inherited-members:
+
+.. autoclass:: py._path.svnurl.SvnCommandPath
+ :members:
+ :inherited-members:
+
+.. autoclass:: py._path.svnwc.SvnAuth
+ :members:
+ :inherited-members:
+
+Common vs. specific API, Examples
+========================================
+
+All Path objects support a common set of operations, suitable
+for many use cases and allowing to transparently switch the
+path object within an application (e.g. from "local" to "svnwc").
+The common set includes functions such as `path.read()` to read all data
+from a file, `path.write()` to write data, `path.listdir()` to get a list
+of directory entries, `path.check()` to check if a node exists
+and is of a particular type, `path.join()` to get
+to a (grand)child, `path.visit()` to recursively walk through a node's
+children, etc. Only things that are not common on 'normal' filesystems (yet),
+such as handling metadata (e.g. the Subversion "properties") require
+using specific APIs.
+
+A quick 'cookbook' of small examples that will be useful 'in real life',
+which also presents parts of the 'common' API, and shows some non-common
+methods:
+
+Searching `.txt` files
+--------------------------------
+
+Search for a particular string inside all files with a .txt extension in a
+specific directory.
+
+.. sourcecode:: pycon
+
+ >>> dirpath = temppath.ensure('testdir', dir=True)
+ >>> dirpath.join('textfile1.txt').write('foo bar baz')
+ >>> dirpath.join('textfile2.txt').write('frob bar spam eggs')
+ >>> subdir = dirpath.ensure('subdir', dir=True)
+ >>> subdir.join('textfile1.txt').write('foo baz')
+ >>> subdir.join('textfile2.txt').write('spam eggs spam foo bar spam')
+ >>> results = []
+ >>> for fpath in dirpath.visit('*.txt'):
+ ... if 'bar' in fpath.read():
+ ... results.append(fpath.basename)
+ >>> results.sort()
+ >>> results
+ ['textfile1.txt', 'textfile2.txt', 'textfile2.txt']
+
+Working with Paths
+----------------------------
+
+This example shows the ``py.path`` features to deal with
+filesystem paths Note that the filesystem is never touched,
+all operations are performed on a string level (so the paths
+don't have to exist, either):
+
+.. sourcecode:: pycon
+
+ >>> p1 = py.path.local('/foo/bar')
+ >>> p2 = p1.join('baz/qux')
+ >>> p2 == py.path.local('/foo/bar/baz/qux')
+ True
+ >>> sep = py.path.local.sep
+ >>> p2.relto(p1).replace(sep, '/') # os-specific path sep in the string
+ 'baz/qux'
+ >>> p2.bestrelpath(p1).replace(sep, '/')
+ '../..'
+ >>> p2.join(p2.bestrelpath(p1)) == p1
+ True
+ >>> p3 = p1 / 'baz/qux' # the / operator allows joining, too
+ >>> p2 == p3
+ True
+ >>> p4 = p1 + ".py"
+ >>> p4.basename == "bar.py"
+ True
+ >>> p4.ext == ".py"
+ True
+ >>> p4.purebasename == "bar"
+ True
+
+This should be possible on every implementation of ``py.path``, so
+regardless of whether the implementation wraps a UNIX filesystem, a Windows
+one, or a database or object tree, these functions should be available (each
+with their own notion of path seperators and dealing with conversions, etc.).
+
+Checking path types
+-------------------------------
+
+Now we will show a bit about the powerful 'check()' method on paths, which
+allows you to check whether a file exists, what type it is, etc.:
+
+.. sourcecode:: pycon
+
+ >>> file1 = temppath.join('file1')
+ >>> file1.check() # does it exist?
+ False
+ >>> file1 = file1.ensure(file=True) # 'touch' the file
+ >>> file1.check()
+ True
+ >>> file1.check(dir=True) # is it a dir?
+ False
+ >>> file1.check(file=True) # or a file?
+ True
+ >>> file1.check(ext='.txt') # check the extension
+ False
+ >>> textfile = temppath.ensure('text.txt', file=True)
+ >>> textfile.check(ext='.txt')
+ True
+ >>> file1.check(basename='file1') # we can use all the path's properties here
+ True
+
+Setting svn-properties
+--------------------------------
+
+As an example of 'uncommon' methods, we'll show how to read and write
+properties in an ``py.path.svnwc`` instance:
+
+.. sourcecode:: pycon
+
+ .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
+ >>> wc.propget('foo')
+ ''
+ >>> wc.propset('foo', 'bar')
+ >>> wc.propget('foo')
+ 'bar'
+ >>> len(wc.status().prop_modified) # our own props
+ 1
+ >>> msg = wc.revert() # roll back our changes
+ >>> len(wc.status().prop_modified)
+ 0
+
+SVN authentication
+----------------------------
+
+Some uncommon functionality can also be provided as extensions, such as SVN
+authentication:
+
+.. sourcecode:: pycon
+
+ .. >>> if not py.test.config.option.urlcheck: raise ValueError('skipchunk')
+ >>> auth = py.path.SvnAuth('anonymous', 'user', cache_auth=False,
+ ... interactive=False)
+ >>> wc.auth = auth
+ >>> wc.update() # this should work
+ >>> path = wc.ensure('thisshouldnotexist.txt')
+ >>> try:
+ ... path.commit('testing')
+ ... except py.process.cmdexec.Error, e:
+ ... pass
+ >>> 'authorization failed' in str(e)
+ True
+
+Known problems / limitations
+===================================
+
+* The SVN path objects require the "svn" command line,
+ there is currently no support for python bindings.
+ Parsing the svn output can lead to problems, particularly
+ regarding if you have a non-english "locales" setting.
+
+* While the path objects basically work on windows,
+ there is no attention yet on making unicode paths
+ work or deal with the famous "8.3" filename issues.
+
+
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/style.css b/tests/wpt/web-platform-tests/tools/py/doc/style.css
new file mode 100644
index 00000000000..1faf762c715
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/style.css
@@ -0,0 +1,1044 @@
+body,body.editor,body.body {
+ font: 110% "Times New Roman", Arial, Verdana, Helvetica, serif;
+ background: White;
+ color: Black;
+}
+
+a, a.reference {
+ text-decoration: none;
+}
+a[href]:hover { text-decoration: underline; }
+
+img {
+ border: none;
+ vertical-align: middle;
+}
+
+p, div.text {
+ text-align: left;
+ line-height: 1.5em;
+ margin: 0.5em 0em 0em 0em;
+}
+
+
+
+p a:active {
+ color: Red;
+ background-color: transparent;
+}
+
+p img {
+ border: 0;
+ margin: 0;
+}
+
+img.inlinephoto {
+ padding: 0;
+ padding-right: 1em;
+ padding-top: 0.7em;
+ float: left;
+}
+
+hr {
+ clear: both;
+ height: 1px;
+ color: #8CACBB;
+ background-color: transparent;
+}
+
+
+ul {
+ line-height: 1.5em;
+ /*list-style-image: url("bullet.gif"); */
+ margin-left: 1.5em;
+ padding:0;
+}
+
+ol {
+ line-height: 1.5em;
+ margin-left: 1.5em;
+ padding:0;
+}
+
+ul a, ol a {
+ text-decoration: underline;
+}
+
+dl {
+}
+
+dd {
+ line-height: 1.5em;
+ margin-bottom: 1em;
+}
+
+blockquote {
+ font-family: Times, "Times New Roman", serif;
+ font-style: italic;
+ font-size: 120%;
+}
+
+code {
+ color: Black;
+ /*background-color: #dee7ec;*/
+ /*background-color: #cccccc;*/
+}
+
+pre {
+ padding: 1em;
+ border: 1px dotted #8cacbb;
+ color: Black;
+ /*
+ background-color: #dee7ec;
+ background-color: #cccccc;
+ background-color: #dee7ec;
+ */
+ overflow: auto;
+}
+
+
+.netscape4 {
+ display: none;
+}
+
+/* main page styles */
+
+/*a[href]:hover { color: black; text-decoration: underline; }
+a[href]:link { color: black; text-decoration: underline; }
+a[href] { color: black; text-decoration: underline; }
+*/
+
+span.menu_selected {
+ color: black;
+ text-decoration: none;
+ padding-right: 0.3em;
+ background-color: #cccccc;
+}
+
+
+a.menu {
+ /*color: #3ba6ec; */
+ font: 120% Verdana, Helvetica, Arial, sans-serif;
+ text-decoration: none;
+ padding-right: 0.3em;
+}
+
+a.menu[href]:visited, a.menu[href]:link{
+ /*color: #3ba6ec; */
+ text-decoration: none;
+}
+
+a.menu[href]:hover {
+ /*color: black;*/
+}
+
+div#pagetitle{
+ /*border-spacing: 20px;*/
+ font: 160% Verdana, Helvetica, Arial, sans-serif;
+ color: #3ba6ec;
+ vertical-align: middle;
+ left: 80 px;
+ padding-bottom: 0.3em;
+}
+
+a.wikicurrent {
+ font: 100% Verdana, Helvetica, Arial, sans-serif;
+ color: #3ba6ec;
+ vertical-align: middle;
+}
+
+
+table.body {
+ border: 0;
+ /*padding: 0;
+ border-spacing: 0px;
+ border-collapse: separate;
+ */
+}
+
+td.page-header-left {
+ padding: 5px;
+ /*border-bottom: 1px solid #444444;*/
+}
+
+td.page-header-top {
+ padding: 0;
+
+ /*border-bottom: 1px solid #444444;*/
+}
+
+td.sidebar {
+ padding: 1 0 0 1;
+}
+
+td.sidebar p.classblock {
+ padding: 0 5 0 5;
+ margin: 1 1 1 1;
+ border: 1px solid #444444;
+ background-color: #eeeeee;
+}
+
+td.sidebar p.userblock {
+ padding: 0 5 0 5;
+ margin: 1 1 1 1;
+ border: 1px solid #444444;
+ background-color: #eeeeff;
+}
+
+td.content {
+ padding: 1 5 1 5;
+ vertical-align: top;
+ width: 100%;
+}
+
+p.ok-message {
+ background-color: #22bb22;
+ padding: 5 5 5 5;
+ color: white;
+ font-weight: bold;
+}
+p.error-message {
+ background-color: #bb2222;
+ padding: 5 5 5 5;
+ color: white;
+ font-weight: bold;
+}
+
+p:first-child {
+ margin: 0 ;
+ padding: 0;
+}
+
+/* style for forms */
+table.form {
+ padding: 2;
+ border-spacing: 0px;
+ border-collapse: separate;
+}
+
+table.form th {
+ color: #333388;
+ text-align: right;
+ vertical-align: top;
+ font-weight: normal;
+}
+table.form th.header {
+ font-weight: bold;
+ background-color: #eeeeff;
+ text-align: left;
+}
+
+table.form th.required {
+ font-weight: bold;
+}
+
+table.form td {
+ color: #333333;
+ empty-cells: show;
+ vertical-align: top;
+}
+
+table.form td.optional {
+ font-weight: bold;
+ font-style: italic;
+}
+
+table.form td.html {
+ color: #777777;
+}
+
+/* style for lists */
+table.list {
+ border-spacing: 0px;
+ border-collapse: separate;
+ vertical-align: top;
+ padding-top: 0;
+ width: 100%;
+}
+
+table.list th {
+ padding: 0 4 0 4;
+ color: #404070;
+ background-color: #eeeeff;
+ border-right: 1px solid #404070;
+ border-top: 1px solid #404070;
+ border-bottom: 1px solid #404070;
+ vertical-align: top;
+ empty-cells: show;
+}
+table.list th a[href]:hover { color: #404070 }
+table.list th a[href]:link { color: #404070 }
+table.list th a[href] { color: #404070 }
+table.list th.group {
+ background-color: #f4f4ff;
+ text-align: center;
+ font-size: 120%;
+}
+
+table.list td {
+ padding: 0 4 0 4;
+ border: 0 2 0 2;
+ border-right: 1px solid #404070;
+ color: #404070;
+ background-color: white;
+ vertical-align: top;
+ empty-cells: show;
+}
+
+table.list tr.normal td {
+ background-color: white;
+ white-space: nowrap;
+}
+
+table.list tr.alt td {
+ background-color: #efefef;
+ white-space: nowrap;
+}
+
+table.list td:first-child {
+ border-left: 1px solid #404070;
+ border-right: 1px solid #404070;
+}
+
+table.list th:first-child {
+ border-left: 1px solid #404070;
+ border-right: 1px solid #404070;
+}
+
+table.list tr.navigation th {
+ text-align: right;
+}
+table.list tr.navigation th:first-child {
+ border-right: none;
+ text-align: left;
+}
+
+
+/* style for message displays */
+table.messages {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.messages th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.messages th {
+ font-weight: bold;
+ color: black;
+ text-align: left;
+ border-bottom: 1px solid #afafaf;
+}
+
+table.messages td {
+ font-family: monospace;
+ background-color: #efefef;
+ border-bottom: 1px solid #afafaf;
+ color: black;
+ empty-cells: show;
+ border-right: 1px solid #afafaf;
+ vertical-align: top;
+ padding: 2 5 2 5;
+}
+
+table.messages td:first-child {
+ border-left: 1px solid #afafaf;
+ border-right: 1px solid #afafaf;
+}
+
+/* style for file displays */
+table.files {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.files th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.files th {
+ border-bottom: 1px solid #afafaf;
+ font-weight: bold;
+ text-align: left;
+}
+
+table.files td {
+ font-family: monospace;
+ empty-cells: show;
+}
+
+/* style for history displays */
+table.history {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.history th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+ font-size: 100%;
+}
+
+table.history th {
+ border-bottom: 1px solid #afafaf;
+ font-weight: bold;
+ text-align: left;
+ font-size: 90%;
+}
+
+table.history td {
+ font-size: 90%;
+ vertical-align: top;
+ empty-cells: show;
+}
+
+
+/* style for class list */
+table.classlist {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.classlist th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.classlist th {
+ font-weight: bold;
+ text-align: left;
+}
+
+
+/* style for class help display */
+table.classhelp {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.classhelp th {
+ font-weight: bold;
+ text-align: left;
+ color: #707040;
+}
+
+table.classhelp td {
+ padding: 2 2 2 2;
+ border: 1px solid black;
+ text-align: left;
+ vertical-align: top;
+ empty-cells: show;
+}
+
+
+/* style for "other" displays */
+table.otherinfo {
+ border-spacing: 0px;
+ border-collapse: separate;
+ width: 100%;
+}
+
+table.otherinfo th.header{
+ padding-top: 10px;
+ border-bottom: 1px solid gray;
+ font-weight: bold;
+ background-color: white;
+ color: #707040;
+}
+
+table.otherinfo th {
+ border-bottom: 1px solid #afafaf;
+ font-weight: bold;
+ text-align: left;
+}
+
+input {
+ border: 1px solid #8cacbb;
+ color: Black;
+ background-color: white;
+ vertical-align: middle;
+ margin-bottom: 1px; /* IE bug fix */
+ padding: 0.1em;
+}
+
+select {
+ border: 1px solid #8cacbb;
+ color: Black;
+ background-color: white;
+ vertical-align: middle;
+ margin-bottom: 1px; /* IE bug fix */
+ padding: 0.1em;
+}
+
+
+a.nonexistent {
+ color: #FF2222;
+}
+a.nonexistent:visited {
+ color: #FF2222;
+}
+a.external {
+ color: #AA6600;
+}
+
+/*
+dl,ul,ol {
+ margin-top: 1pt;
+}
+tt,pre {
+ font-family: Lucida Console,Courier New,Courier,monotype;
+ font-size: 12pt;
+}
+pre.code {
+ margin-top: 8pt;
+ margin-bottom: 8pt;
+ background-color: #FFFFEE;
+ white-space:pre;
+ border-style:solid;
+ border-width:1pt;
+ border-color:#999999;
+ color:#111111;
+ padding:5px;
+ width:100%;
+}
+*/
+div.diffold {
+ background-color: #FFFF80;
+ border-style:none;
+ border-width:thin;
+ width:100%;
+}
+div.diffnew {
+ background-color: #80FF80;
+ border-style:none;
+ border-width:thin;
+ width:100%;
+}
+div.message {
+ margin-top: 6pt;
+ background-color: #E8FFE8;
+ border-style:solid;
+ border-width:1pt;
+ border-color:#999999;
+ color:#440000;
+ padding:5px;
+ width:100%;
+}
+strong.highlight {
+ background-color: #FFBBBB;
+/* as usual, NetScape fucks up with innocent CSS
+ border-color: #FFAAAA;
+ border-style: solid;
+ border-width: 1pt;
+*/
+}
+
+table.navibar {
+ background-color: #C8C8C8;
+ border-spacing: 3px;
+}
+td.navibar {
+ background-color: #E8E8E8;
+ vertical-align: top;
+ text-align: right;
+ padding: 0px;
+}
+
+a#versioninfo {
+ color: blue;
+}
+
+div#pagename {
+ font-size: 140%;
+ color: blue;
+ text-align: center;
+ font-weight: bold;
+ background-color: white;
+ padding: 0 ;
+}
+
+a.wikiaction, input.wikiaction {
+ color: black;
+ text-decoration: None;
+ text-align: center;
+ color: black;
+ /*border: 1px solid #3ba6ec; */
+ margin: 4px;
+ padding: 5;
+ padding-bottom: 0;
+ white-space: nowrap;
+}
+
+a.wikiaction[href]:hover {
+ color: black;
+ text-decoration: none;
+ /*background-color: #dddddd; */
+}
+
+
+div.legenditem {
+ padding-top: 0.5em;
+ padding-left: 0.3em;
+}
+
+span.wikitoken {
+ background-color: #eeeeee;
+}
+
+
+div#contentspace h1:first-child, div.heading:first-child {
+ padding-top: 0;
+ margin-top: 0;
+}
+div#contentspace h2:first-child {
+ padding-top: 0;
+ margin-top: 0;
+}
+
+/* heading and paragraph text */
+
+div.heading, h1 {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ background-color: #58b3ef;
+ background-color: #FFFFFF;
+ /*color: #4893cf;*/
+ color: black;
+ padding-top: 1.0em;
+ padding-bottom:0.2em;
+ text-align: left;
+ margin-top: 0em;
+ /*margin-bottom:8pt;*/
+ font-weight: bold;
+ font-size: 115%;
+ border-bottom: 1px solid #8CACBB;
+}
+
+h2 {
+ border-bottom: 1px dotted #8CACBB;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+ color: Black;
+ clear: left;
+ font: 100% Verdana, Helvetica, Arial, sans-serif;
+ margin: 0;
+ padding-left: 0em;
+ padding-top: 1em;
+ padding-bottom: 0.2em;
+ /*border-bottom: 1px solid #8CACBB;*/
+}
+/* h1,h2 { padding-top: 0; }*/
+
+
+h1 { font-size: 145%; }
+h2 { font-size: 115%; }
+h3 { font-size: 105%; }
+h4 { font-size: 100%; }
+h5 { font-size: 100%; }
+
+h1 a { text-decoration: None;}
+
+div.exception {
+ background-color: #bb2222;
+ padding: 5 5 5 5;
+ color: white;
+ font-weight: bold;
+}
+pre.exception {
+ font-size: 110%;
+ padding: 1em;
+ border: 1px solid #8cacbb;
+ color: Black;
+ background-color: #dee7ec;
+ background-color: #cccccc;
+}
+
+/* defines for navgiation bar (documentation) */
+
+
+div.direntry {
+ padding-top: 0.3em;
+ padding-bottom: 0.3em;
+ margin-right: 1em;
+ font-weight: bold;
+ background-color: #dee7ec;
+ font-size: 110%;
+}
+
+div.fileentry {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ padding-bottom: 0.3em;
+ white-space: nowrap;
+ line-height: 150%;
+}
+
+a.fileentry {
+ white-space: nowrap;
+}
+
+
+span.left {
+ text-align: left;
+}
+span.right {
+ text-align: right;
+}
+
+div.navbar {
+ /*margin: 0;*/
+ font-size: 80% /*smaller*/;
+ font-weight: bold;
+ text-align: left;
+ /* position: fixed; */
+ top: 100pt;
+ left: 0pt; /* auto; */
+ width: 120pt;
+ /* right: auto;
+ right: 0pt; 2em; */
+}
+
+
+div.history a {
+ /* font-size: 70%; */
+}
+
+div.wikiactiontitle {
+ font-weight: bold;
+}
+
+/* REST defines */
+
+div.document {
+ margin: 0;
+}
+
+h1.title {
+ margin: 0;
+ margin-bottom: 0.5em;
+}
+
+td.toplist {
+ vertical-align: top;
+}
+
+img#pyimg {
+ float: left;
+ padding-bottom: 1em;
+}
+
+div#navspace {
+ position: absolute;
+ font-size: 100%;
+ width: 150px;
+ overflow: hidden; /* scroll; */
+}
+
+
+div#errorline {
+ position: relative;
+ top: 5px;
+ float: right;
+}
+
+div#contentspace {
+ position: absolute;
+ /* font: 120% "Times New Roman", serif;*/
+ font: 110% Verdana, Helvetica, Arial, sans-serif;
+ left: 170px;
+ margin-right: 5px;
+}
+
+div#menubar {
+/* width: 400px; */
+ float: left;
+}
+
+/* for the documentation page */
+div#title{
+
+ font-size: 110%;
+ color: black;
+
+
+ /*background-color: #dee7ec;
+ #padding: 5pt;
+ #padding-bottom: 1em;
+ #color: black;
+ border-width: 1pt;
+ border-style: solid;*/
+
+}
+
+div#docnavlist {
+ /*background-color: #dee7ec; */
+ padding: 5pt;
+ padding-bottom: 2em;
+ color: black;
+ border-width: 1pt;
+ /*border-style: solid;*/
+}
+
+
+/* text markup */
+
+div.listtitle {
+ color: Black;
+ clear: left;
+ font: 120% Verdana, Helvetica, Arial, sans-serif;
+ margin: 0;
+ padding-left: 0em;
+ padding-top: 0em;
+ padding-bottom: 0.2em;
+ margin-right: 0.5em;
+ border-bottom: 1px solid #8CACBB;
+}
+
+div.actionbox h3 {
+ padding-top: 0;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ background-color: #fabf00;
+ text-align: center;
+ border: 1px solid black; /* 8cacbb; */
+}
+
+div.actionbox a {
+ display: block;
+ padding-bottom: 0.5em;
+ padding-top: 0.5em;
+ margin-left: 0.5em;
+}
+
+div.actionbox a.history {
+ display: block;
+ padding-bottom: 0.5em;
+ padding-top: 0.5em;
+ margin-left: 0.5em;
+ font-size: 90%;
+}
+
+div.actionbox {
+ margin-bottom: 2em;
+ padding-bottom: 1em;
+ overflow: hidden; /* scroll; */
+}
+
+/* taken from docutils (oh dear, a bit senseless) */
+ol.simple, ul.simple {
+ margin-bottom: 1em }
+
+ol.arabic {
+ list-style: decimal }
+
+ol.loweralpha {
+ list-style: lower-alpha }
+
+ol.upperalpha {
+ list-style: upper-alpha }
+
+ol.lowerroman {
+ list-style: lower-roman }
+
+ol.upperroman {
+ list-style: upper-roman }
+
+
+/*
+:Author: David Goodger
+:Contact: goodger@users.sourceforge.net
+:date: $Date: 2003/01/22 22:26:48 $
+:version: $Revision: 1.29 $
+:copyright: This stylesheet has been placed in the public domain.
+
+Default cascading style sheet for the HTML output of Docutils.
+*/
+/*
+.first {
+ margin-top: 0 }
+
+.last {
+ margin-bottom: 0 }
+
+a.toc-backref {
+ text-decoration: none ;
+ color: black }
+
+dd {
+ margin-bottom: 0.5em }
+
+div.abstract {
+ margin: 2em 5em }
+
+div.abstract p.topic-title {
+ font-weight: bold ;
+ text-align: center }
+
+div.attention, div.caution, div.danger, div.error, div.hint,
+div.important, div.note, div.tip, div.warning {
+ margin: 2em ;
+ border: medium outset ;
+ padding: 1em }
+
+div.attention p.admonition-title, div.caution p.admonition-title,
+div.danger p.admonition-title, div.error p.admonition-title,
+div.warning p.admonition-title {
+ color: red ;
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.hint p.admonition-title, div.important p.admonition-title,
+div.note p.admonition-title, div.tip p.admonition-title {
+ font-weight: bold ;
+ font-family: sans-serif }
+
+div.dedication {
+ margin: 2em 5em ;
+ text-align: center ;
+ font-style: italic }
+
+div.dedication p.topic-title {
+ font-weight: bold ;
+ font-style: normal }
+
+div.figure {
+ margin-left: 2em }
+
+div.footer, div.header {
+ font-size: smaller }
+
+div.system-messages {
+ margin: 5em }
+
+div.system-messages h1 {
+ color: red }
+
+div.system-message {
+ border: medium outset ;
+ padding: 1em }
+
+div.system-message p.system-message-title {
+ color: red ;
+ font-weight: bold }
+
+div.topic {
+ margin: 2em }
+
+h1.title {
+ text-align: center }
+
+h2.subtitle {
+ text-align: center }
+
+hr {
+ width: 75% }
+
+p.caption {
+ font-style: italic }
+
+p.credits {
+ font-style: italic ;
+ font-size: smaller }
+
+p.label {
+ white-space: nowrap }
+
+p.topic-title {
+ font-weight: bold }
+
+pre.address {
+ margin-bottom: 0 ;
+ margin-top: 0 ;
+ font-family: serif ;
+ font-size: 100% }
+
+pre.line-block {
+ font-family: serif ;
+ font-size: 100% }
+
+pre.literal-block, pre.doctest-block {
+ margin-left: 2em ;
+ margin-right: 2em ;
+ background-color: #eeeeee }
+
+span.classifier {
+ font-family: sans-serif ;
+ font-style: oblique }
+
+span.classifier-delimiter {
+ font-family: sans-serif ;
+ font-weight: bold }
+
+span.interpreted {
+ font-family: sans-serif }
+
+span.option {
+ white-space: nowrap }
+
+span.option-argument {
+ font-style: italic }
+
+span.pre {
+ white-space: pre }
+
+span.problematic {
+ color: red }
+
+table {
+ margin-top: 0.5em ;
+ margin-bottom: 0.5em }
+
+table.citation {
+ border-left: solid thin gray ;
+ padding-left: 0.5ex }
+
+table.docinfo {
+ margin: 2em 4em }
+
+table.footnote {
+ border-left: solid thin black ;
+ padding-left: 0.5ex }
+
+td, th {
+ padding-left: 0.5em ;
+ padding-right: 0.5em ;
+ vertical-align: top }
+
+th.docinfo-name, th.field-name {
+ font-weight: bold ;
+ text-align: left ;
+ white-space: nowrap }
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+ font-size: 100% }
+
+tt {
+ background-color: #eeeeee }
+
+ul.auto-toc {
+ list-style-type: none }
+*/
+
+div.section {
+ margin-top: 1.0em ;
+}
diff --git a/tests/wpt/web-platform-tests/tools/py/doc/xml.txt b/tests/wpt/web-platform-tests/tools/py/doc/xml.txt
new file mode 100644
index 00000000000..1022de6e912
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/doc/xml.txt
@@ -0,0 +1,164 @@
+====================================================
+py.xml: simple pythonic xml/html file generation
+====================================================
+
+Motivation
+==========
+
+There are a plethora of frameworks and libraries to generate
+xml and html trees. However, many of them are large, have a
+steep learning curve and are often hard to debug. Not to
+speak of the fact that they are frameworks to begin with.
+
+.. _xist: http://www.livinglogic.de/Python/xist/index.html
+
+a pythonic object model , please
+================================
+
+The py lib offers a pythonic way to generate xml/html, based on
+ideas from xist_ which `uses python class objects`_ to build
+xml trees. However, xist_'s implementation is somewhat heavy
+because it has additional goals like transformations and
+supporting many namespaces. But its basic idea is very easy.
+
+.. _`uses python class objects`: http://www.livinglogic.de/Python/xist/Howto.html
+
+generating arbitrary xml structures
+-----------------------------------
+
+With ``py.xml.Namespace`` you have the basis
+to generate custom xml-fragments on the fly::
+
+ class ns(py.xml.Namespace):
+ "my custom xml namespace"
+ doc = ns.books(
+ ns.book(
+ ns.author("May Day"),
+ ns.title("python for java programmers"),),
+ ns.book(
+ ns.author("why"),
+ ns.title("Java for Python programmers"),),
+ publisher="N.N",
+ )
+ print doc.unicode(indent=2).encode('utf8')
+
+will give you this representation::
+
+ <books publisher="N.N">
+ <book>
+ <author>May Day</author>
+ <title>python for java programmers</title></book>
+ <book>
+ <author>why</author>
+ <title>Java for Python programmers</title></book></books>
+
+In a sentence: positional arguments are child-tags and
+keyword-arguments are attributes.
+
+On a side note, you'll see that the unicode-serializer
+supports a nice indentation style which keeps your generated
+html readable, basically through emulating python's white
+space significance by putting closing-tags rightmost and
+almost invisible at first glance :-)
+
+basic example for generating html
+---------------------------------
+
+Consider this example::
+
+ from py.xml import html # html namespace
+
+ paras = "First Para", "Second para"
+
+ doc = html.html(
+ html.head(
+ html.meta(name="Content-Type", value="text/html; charset=latin1")),
+ html.body(
+ [html.p(p) for p in paras]))
+
+ print unicode(doc).encode('latin1')
+
+Again, tags are objects which contain tags and have attributes.
+More exactly, Tags inherit from the list type and thus can be
+manipulated as list objects. They additionally support a default
+way to represent themselves as a serialized unicode object.
+
+If you happen to look at the py.xml implementation you'll
+note that the tag/namespace implementation consumes some 50 lines
+with another 50 lines for the unicode serialization code.
+
+CSS-styling your html Tags
+--------------------------
+
+One aspect where many of the huge python xml/html generation
+frameworks utterly fail is a clean and convenient integration
+of CSS styling. Often, developers are left alone with keeping
+CSS style definitions in sync with some style files
+represented as strings (often in a separate .css file). Not
+only is this hard to debug but the missing abstractions make
+it hard to modify the styling of your tags or to choose custom
+style representations (inline, html.head or external). Add the
+Browers usual tolerance of messyness and errors in Style
+references and welcome to hell, known as the domain of
+developing web applications :-)
+
+By contrast, consider this CSS styling example::
+
+ class my(html):
+ "my initial custom style"
+ class body(html.body):
+ style = html.Style(font_size = "120%")
+
+ class h2(html.h2):
+ style = html.Style(background = "grey")
+
+ class p(html.p):
+ style = html.Style(font_weight="bold")
+
+ doc = my.html(
+ my.head(),
+ my.body(
+ my.h2("hello world"),
+ my.p("bold as bold can")
+ )
+ )
+
+ print doc.unicode(indent=2)
+
+This will give you a small'n mean self contained
+represenation by default::
+
+ <html>
+ <head/>
+ <body style="font-size: 120%">
+ <h2 style="background: grey">hello world</h2>
+ <p style="font-weight: bold">bold as bold can</p></body></html>
+
+Most importantly, note that the inline-styling is just an
+implementation detail of the unicode serialization code.
+You can easily modify the serialization to put your styling into the
+``html.head`` or in a separate file and autogenerate CSS-class
+names or ids.
+
+Hey, you could even write tests that you are using correct
+styles suitable for specific browser requirements. Did i mention
+that the ability to easily write tests for your generated
+html and its serialization could help to develop _stable_ user
+interfaces?
+
+More to come ...
+----------------
+
+For now, i don't think we should strive to offer much more
+than the above. However, it is probably not hard to offer
+*partial serialization* to allow generating maybe hundreds of
+complex html documents per second. Basically we would allow
+putting callables both as Tag content and as values of
+attributes. A slightly more advanced Serialization would then
+produce a list of unicode objects intermingled with callables.
+At HTTP-Request time the callables would get called to
+complete the probably request-specific serialization of
+your Tags. Hum, it's probably harder to explain this than to
+actually code it :-)
+
+.. _`py.test`: test/index.html
diff --git a/tests/wpt/web-platform-tests/tools/py/py/__init__.py b/tests/wpt/web-platform-tests/tools/py/py/__init__.py
new file mode 100644
index 00000000000..bdb9aa2181f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/__init__.py
@@ -0,0 +1,150 @@
+"""
+py.test and pylib: rapid testing and development utils
+
+this module uses apipkg.py for lazy-loading sub modules
+and classes. The initpkg-dictionary below specifies
+name->value mappings where value can be another namespace
+dictionary or an import path.
+
+(c) Holger Krekel and others, 2004-2014
+"""
+__version__ = '1.4.31'
+
+from py import _apipkg
+
+# so that py.error.* instances are picklable
+import sys
+sys.modules['py.error'] = _apipkg.AliasModule("py.error", "py._error", 'error')
+
+_apipkg.initpkg(__name__, attr={'_apipkg': _apipkg}, exportdefs={
+ # access to all standard lib modules
+ 'std': '._std:std',
+ # access to all posix errno's as classes
+ 'error': '._error:error',
+
+ '_pydir' : '.__metainfo:pydir',
+ 'version': 'py:__version__', # backward compatibility
+
+ # pytest-2.0 has a flat namespace, we use alias modules
+ # to keep old references compatible
+ 'test' : 'pytest',
+ 'test.collect' : 'pytest',
+ 'test.cmdline' : 'pytest',
+
+ # hook into the top-level standard library
+ 'process' : {
+ '__doc__' : '._process:__doc__',
+ 'cmdexec' : '._process.cmdexec:cmdexec',
+ 'kill' : '._process.killproc:kill',
+ 'ForkedFunc' : '._process.forkedfunc:ForkedFunc',
+ },
+
+ 'apipkg' : {
+ 'initpkg' : '._apipkg:initpkg',
+ 'ApiModule' : '._apipkg:ApiModule',
+ },
+
+ 'iniconfig' : {
+ 'IniConfig' : '._iniconfig:IniConfig',
+ 'ParseError' : '._iniconfig:ParseError',
+ },
+
+ 'path' : {
+ '__doc__' : '._path:__doc__',
+ 'svnwc' : '._path.svnwc:SvnWCCommandPath',
+ 'svnurl' : '._path.svnurl:SvnCommandPath',
+ 'local' : '._path.local:LocalPath',
+ 'SvnAuth' : '._path.svnwc:SvnAuth',
+ },
+
+ # python inspection/code-generation API
+ 'code' : {
+ '__doc__' : '._code:__doc__',
+ 'compile' : '._code.source:compile_',
+ 'Source' : '._code.source:Source',
+ 'Code' : '._code.code:Code',
+ 'Frame' : '._code.code:Frame',
+ 'ExceptionInfo' : '._code.code:ExceptionInfo',
+ 'Traceback' : '._code.code:Traceback',
+ 'getfslineno' : '._code.source:getfslineno',
+ 'getrawcode' : '._code.code:getrawcode',
+ 'patch_builtins' : '._code.code:patch_builtins',
+ 'unpatch_builtins' : '._code.code:unpatch_builtins',
+ '_AssertionError' : '._code.assertion:AssertionError',
+ '_reinterpret_old' : '._code.assertion:reinterpret_old',
+ '_reinterpret' : '._code.assertion:reinterpret',
+ '_reprcompare' : '._code.assertion:_reprcompare',
+ '_format_explanation' : '._code.assertion:_format_explanation',
+ },
+
+ # backports and additions of builtins
+ 'builtin' : {
+ '__doc__' : '._builtin:__doc__',
+ 'enumerate' : '._builtin:enumerate',
+ 'reversed' : '._builtin:reversed',
+ 'sorted' : '._builtin:sorted',
+ 'any' : '._builtin:any',
+ 'all' : '._builtin:all',
+ 'set' : '._builtin:set',
+ 'frozenset' : '._builtin:frozenset',
+ 'BaseException' : '._builtin:BaseException',
+ 'GeneratorExit' : '._builtin:GeneratorExit',
+ '_sysex' : '._builtin:_sysex',
+ 'print_' : '._builtin:print_',
+ '_reraise' : '._builtin:_reraise',
+ '_tryimport' : '._builtin:_tryimport',
+ 'exec_' : '._builtin:exec_',
+ '_basestring' : '._builtin:_basestring',
+ '_totext' : '._builtin:_totext',
+ '_isbytes' : '._builtin:_isbytes',
+ '_istext' : '._builtin:_istext',
+ '_getimself' : '._builtin:_getimself',
+ '_getfuncdict' : '._builtin:_getfuncdict',
+ '_getcode' : '._builtin:_getcode',
+ 'builtins' : '._builtin:builtins',
+ 'execfile' : '._builtin:execfile',
+ 'callable' : '._builtin:callable',
+ 'bytes' : '._builtin:bytes',
+ 'text' : '._builtin:text',
+ },
+
+ # input-output helping
+ 'io' : {
+ '__doc__' : '._io:__doc__',
+ 'dupfile' : '._io.capture:dupfile',
+ 'TextIO' : '._io.capture:TextIO',
+ 'BytesIO' : '._io.capture:BytesIO',
+ 'FDCapture' : '._io.capture:FDCapture',
+ 'StdCapture' : '._io.capture:StdCapture',
+ 'StdCaptureFD' : '._io.capture:StdCaptureFD',
+ 'TerminalWriter' : '._io.terminalwriter:TerminalWriter',
+ 'ansi_print' : '._io.terminalwriter:ansi_print',
+ 'get_terminal_width' : '._io.terminalwriter:get_terminal_width',
+ 'saferepr' : '._io.saferepr:saferepr',
+ },
+
+ # small and mean xml/html generation
+ 'xml' : {
+ '__doc__' : '._xmlgen:__doc__',
+ 'html' : '._xmlgen:html',
+ 'Tag' : '._xmlgen:Tag',
+ 'raw' : '._xmlgen:raw',
+ 'Namespace' : '._xmlgen:Namespace',
+ 'escape' : '._xmlgen:escape',
+ },
+
+ 'log' : {
+ # logging API ('producers' and 'consumers' connected via keywords)
+ '__doc__' : '._log:__doc__',
+ '_apiwarn' : '._log.warning:_apiwarn',
+ 'Producer' : '._log.log:Producer',
+ 'setconsumer' : '._log.log:setconsumer',
+ '_setstate' : '._log.log:setstate',
+ '_getstate' : '._log.log:getstate',
+ 'Path' : '._log.log:Path',
+ 'STDOUT' : '._log.log:STDOUT',
+ 'STDERR' : '._log.log:STDERR',
+ 'Syslog' : '._log.log:Syslog',
+ },
+
+})
diff --git a/tests/wpt/web-platform-tests/tools/py/py/__metainfo.py b/tests/wpt/web-platform-tests/tools/py/py/__metainfo.py
new file mode 100644
index 00000000000..12581eb7afb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/__metainfo.py
@@ -0,0 +1,2 @@
+import py
+pydir = py.path.local(py.__file__).dirpath()
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_apipkg.py b/tests/wpt/web-platform-tests/tools/py/py/_apipkg.py
new file mode 100644
index 00000000000..a73b8f6d0bc
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_apipkg.py
@@ -0,0 +1,181 @@
+"""
+apipkg: control the exported namespace of a python package.
+
+see http://pypi.python.org/pypi/apipkg
+
+(c) holger krekel, 2009 - MIT license
+"""
+import os
+import sys
+from types import ModuleType
+
+__version__ = '1.3.dev'
+
+def _py_abspath(path):
+ """
+ special version of abspath
+ that will leave paths from jython jars alone
+ """
+ if path.startswith('__pyclasspath__'):
+
+ return path
+ else:
+ return os.path.abspath(path)
+
+def initpkg(pkgname, exportdefs, attr=dict()):
+ """ initialize given package from the export definitions. """
+ oldmod = sys.modules.get(pkgname)
+ d = {}
+ f = getattr(oldmod, '__file__', None)
+ if f:
+ f = _py_abspath(f)
+ d['__file__'] = f
+ if hasattr(oldmod, '__version__'):
+ d['__version__'] = oldmod.__version__
+ if hasattr(oldmod, '__loader__'):
+ d['__loader__'] = oldmod.__loader__
+ if hasattr(oldmod, '__path__'):
+ d['__path__'] = [_py_abspath(p) for p in oldmod.__path__]
+ if '__doc__' not in exportdefs and getattr(oldmod, '__doc__', None):
+ d['__doc__'] = oldmod.__doc__
+ d.update(attr)
+ if hasattr(oldmod, "__dict__"):
+ oldmod.__dict__.update(d)
+ mod = ApiModule(pkgname, exportdefs, implprefix=pkgname, attr=d)
+ sys.modules[pkgname] = mod
+
+def importobj(modpath, attrname):
+ module = __import__(modpath, None, None, ['__doc__'])
+ if not attrname:
+ return module
+
+ retval = module
+ names = attrname.split(".")
+ for x in names:
+ retval = getattr(retval, x)
+ return retval
+
+class ApiModule(ModuleType):
+ def __docget(self):
+ try:
+ return self.__doc
+ except AttributeError:
+ if '__doc__' in self.__map__:
+ return self.__makeattr('__doc__')
+ def __docset(self, value):
+ self.__doc = value
+ __doc__ = property(__docget, __docset)
+
+ def __init__(self, name, importspec, implprefix=None, attr=None):
+ self.__name__ = name
+ self.__all__ = [x for x in importspec if x != '__onfirstaccess__']
+ self.__map__ = {}
+ self.__implprefix__ = implprefix or name
+ if attr:
+ for name, val in attr.items():
+ # print "setting", self.__name__, name, val
+ setattr(self, name, val)
+ for name, importspec in importspec.items():
+ if isinstance(importspec, dict):
+ subname = '%s.%s' % (self.__name__, name)
+ apimod = ApiModule(subname, importspec, implprefix)
+ sys.modules[subname] = apimod
+ setattr(self, name, apimod)
+ else:
+ parts = importspec.split(':')
+ modpath = parts.pop(0)
+ attrname = parts and parts[0] or ""
+ if modpath[0] == '.':
+ modpath = implprefix + modpath
+
+ if not attrname:
+ subname = '%s.%s' % (self.__name__, name)
+ apimod = AliasModule(subname, modpath)
+ sys.modules[subname] = apimod
+ if '.' not in name:
+ setattr(self, name, apimod)
+ else:
+ self.__map__[name] = (modpath, attrname)
+
+ def __repr__(self):
+ l = []
+ if hasattr(self, '__version__'):
+ l.append("version=" + repr(self.__version__))
+ if hasattr(self, '__file__'):
+ l.append('from ' + repr(self.__file__))
+ if l:
+ return '<ApiModule %r %s>' % (self.__name__, " ".join(l))
+ return '<ApiModule %r>' % (self.__name__,)
+
+ def __makeattr(self, name):
+ """lazily compute value for name or raise AttributeError if unknown."""
+ # print "makeattr", self.__name__, name
+ target = None
+ if '__onfirstaccess__' in self.__map__:
+ target = self.__map__.pop('__onfirstaccess__')
+ importobj(*target)()
+ try:
+ modpath, attrname = self.__map__[name]
+ except KeyError:
+ if target is not None and name != '__onfirstaccess__':
+ # retry, onfirstaccess might have set attrs
+ return getattr(self, name)
+ raise AttributeError(name)
+ else:
+ result = importobj(modpath, attrname)
+ setattr(self, name, result)
+ try:
+ del self.__map__[name]
+ except KeyError:
+ pass # in a recursive-import situation a double-del can happen
+ return result
+
+ __getattr__ = __makeattr
+
+ def __dict__(self):
+ # force all the content of the module to be loaded when __dict__ is read
+ dictdescr = ModuleType.__dict__['__dict__']
+ dict = dictdescr.__get__(self)
+ if dict is not None:
+ hasattr(self, 'some')
+ for name in self.__all__:
+ try:
+ self.__makeattr(name)
+ except AttributeError:
+ pass
+ return dict
+ __dict__ = property(__dict__)
+
+
+def AliasModule(modname, modpath, attrname=None):
+ mod = []
+
+ def getmod():
+ if not mod:
+ x = importobj(modpath, None)
+ if attrname is not None:
+ x = getattr(x, attrname)
+ mod.append(x)
+ return mod[0]
+
+ class AliasModule(ModuleType):
+
+ def __repr__(self):
+ x = modpath
+ if attrname:
+ x += "." + attrname
+ return '<AliasModule %r for %r>' % (modname, x)
+
+ def __getattribute__(self, name):
+ try:
+ return getattr(getmod(), name)
+ except ImportError:
+ return None
+
+ def __setattr__(self, name, value):
+ setattr(getmod(), name, value)
+
+ def __delattr__(self, name):
+ delattr(getmod(), name)
+
+ return AliasModule(str(modname))
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_builtin.py b/tests/wpt/web-platform-tests/tools/py/py/_builtin.py
new file mode 100644
index 00000000000..52ee9d79cad
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_builtin.py
@@ -0,0 +1,248 @@
+import sys
+
+try:
+ reversed = reversed
+except NameError:
+ def reversed(sequence):
+ """reversed(sequence) -> reverse iterator over values of the sequence
+
+ Return a reverse iterator
+ """
+ if hasattr(sequence, '__reversed__'):
+ return sequence.__reversed__()
+ if not hasattr(sequence, '__getitem__'):
+ raise TypeError("argument to reversed() must be a sequence")
+ return reversed_iterator(sequence)
+
+ class reversed_iterator(object):
+
+ def __init__(self, seq):
+ self.seq = seq
+ self.remaining = len(seq)
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ i = self.remaining
+ if i > 0:
+ i -= 1
+ item = self.seq[i]
+ self.remaining = i
+ return item
+ raise StopIteration
+
+ def __length_hint__(self):
+ return self.remaining
+
+try:
+ any = any
+except NameError:
+ def any(iterable):
+ for x in iterable:
+ if x:
+ return True
+ return False
+
+try:
+ all = all
+except NameError:
+ def all(iterable):
+ for x in iterable:
+ if not x:
+ return False
+ return True
+
+try:
+ sorted = sorted
+except NameError:
+ builtin_cmp = cmp # need to use cmp as keyword arg
+
+ def sorted(iterable, cmp=None, key=None, reverse=0):
+ use_cmp = None
+ if key is not None:
+ if cmp is None:
+ def use_cmp(x, y):
+ return builtin_cmp(x[0], y[0])
+ else:
+ def use_cmp(x, y):
+ return cmp(x[0], y[0])
+ l = [(key(element), element) for element in iterable]
+ else:
+ if cmp is not None:
+ use_cmp = cmp
+ l = list(iterable)
+ if use_cmp is not None:
+ l.sort(use_cmp)
+ else:
+ l.sort()
+ if reverse:
+ l.reverse()
+ if key is not None:
+ return [element for (_, element) in l]
+ return l
+
+try:
+ set, frozenset = set, frozenset
+except NameError:
+ from sets import set, frozenset
+
+# pass through
+enumerate = enumerate
+
+try:
+ BaseException = BaseException
+except NameError:
+ BaseException = Exception
+
+try:
+ GeneratorExit = GeneratorExit
+except NameError:
+ class GeneratorExit(Exception):
+ """ This exception is never raised, it is there to make it possible to
+ write code compatible with CPython 2.5 even in lower CPython
+ versions."""
+ pass
+ GeneratorExit.__module__ = 'exceptions'
+
+_sysex = (KeyboardInterrupt, SystemExit, MemoryError, GeneratorExit)
+
+try:
+ callable = callable
+except NameError:
+ def callable(obj):
+ return hasattr(obj, "__call__")
+
+if sys.version_info >= (3, 0):
+ exec ("print_ = print ; exec_=exec")
+ import builtins
+
+ # some backward compatibility helpers
+ _basestring = str
+ def _totext(obj, encoding=None, errors=None):
+ if isinstance(obj, bytes):
+ if errors is None:
+ obj = obj.decode(encoding)
+ else:
+ obj = obj.decode(encoding, errors)
+ elif not isinstance(obj, str):
+ obj = str(obj)
+ return obj
+
+ def _isbytes(x):
+ return isinstance(x, bytes)
+ def _istext(x):
+ return isinstance(x, str)
+
+ text = str
+ bytes = bytes
+
+
+ def _getimself(function):
+ return getattr(function, '__self__', None)
+
+ def _getfuncdict(function):
+ return getattr(function, "__dict__", None)
+
+ def _getcode(function):
+ return getattr(function, "__code__", None)
+
+ def execfile(fn, globs=None, locs=None):
+ if globs is None:
+ back = sys._getframe(1)
+ globs = back.f_globals
+ locs = back.f_locals
+ del back
+ elif locs is None:
+ locs = globs
+ fp = open(fn, "r")
+ try:
+ source = fp.read()
+ finally:
+ fp.close()
+ co = compile(source, fn, "exec", dont_inherit=True)
+ exec_(co, globs, locs)
+
+else:
+ import __builtin__ as builtins
+ _totext = unicode
+ _basestring = basestring
+ text = unicode
+ bytes = str
+ execfile = execfile
+ callable = callable
+ def _isbytes(x):
+ return isinstance(x, str)
+ def _istext(x):
+ return isinstance(x, unicode)
+
+ def _getimself(function):
+ return getattr(function, 'im_self', None)
+
+ def _getfuncdict(function):
+ return getattr(function, "__dict__", None)
+
+ def _getcode(function):
+ try:
+ return getattr(function, "__code__")
+ except AttributeError:
+ return getattr(function, "func_code", None)
+
+ def print_(*args, **kwargs):
+ """ minimal backport of py3k print statement. """
+ sep = ' '
+ if 'sep' in kwargs:
+ sep = kwargs.pop('sep')
+ end = '\n'
+ if 'end' in kwargs:
+ end = kwargs.pop('end')
+ file = 'file' in kwargs and kwargs.pop('file') or sys.stdout
+ if kwargs:
+ args = ", ".join([str(x) for x in kwargs])
+ raise TypeError("invalid keyword arguments: %s" % args)
+ at_start = True
+ for x in args:
+ if not at_start:
+ file.write(sep)
+ file.write(str(x))
+ at_start = False
+ file.write(end)
+
+ def exec_(obj, globals=None, locals=None):
+ """ minimal backport of py3k exec statement. """
+ __tracebackhide__ = True
+ if globals is None:
+ frame = sys._getframe(1)
+ globals = frame.f_globals
+ if locals is None:
+ locals = frame.f_locals
+ elif locals is None:
+ locals = globals
+ exec2(obj, globals, locals)
+
+if sys.version_info >= (3, 0):
+ def _reraise(cls, val, tb):
+ __tracebackhide__ = True
+ assert hasattr(val, '__traceback__')
+ raise cls.with_traceback(val, tb)
+else:
+ exec ("""
+def _reraise(cls, val, tb):
+ __tracebackhide__ = True
+ raise cls, val, tb
+def exec2(obj, globals, locals):
+ __tracebackhide__ = True
+ exec obj in globals, locals
+""")
+
+def _tryimport(*names):
+ """ return the first successfully imported module. """
+ assert names
+ for name in names:
+ try:
+ __import__(name)
+ except ImportError:
+ excinfo = sys.exc_info()
+ else:
+ return sys.modules[name]
+ _reraise(*excinfo)
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_code/__init__.py b/tests/wpt/web-platform-tests/tools/py/py/_code/__init__.py
new file mode 100644
index 00000000000..f15acf85132
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_code/__init__.py
@@ -0,0 +1 @@
+""" python inspection/code generation API """
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_code/_assertionnew.py b/tests/wpt/web-platform-tests/tools/py/py/_code/_assertionnew.py
new file mode 100644
index 00000000000..afb1b31ff05
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_code/_assertionnew.py
@@ -0,0 +1,339 @@
+"""
+Find intermediate evalutation results in assert statements through builtin AST.
+This should replace _assertionold.py eventually.
+"""
+
+import sys
+import ast
+
+import py
+from py._code.assertion import _format_explanation, BuiltinAssertionError
+
+
+if sys.platform.startswith("java") and sys.version_info < (2, 5, 2):
+ # See http://bugs.jython.org/issue1497
+ _exprs = ("BoolOp", "BinOp", "UnaryOp", "Lambda", "IfExp", "Dict",
+ "ListComp", "GeneratorExp", "Yield", "Compare", "Call",
+ "Repr", "Num", "Str", "Attribute", "Subscript", "Name",
+ "List", "Tuple")
+ _stmts = ("FunctionDef", "ClassDef", "Return", "Delete", "Assign",
+ "AugAssign", "Print", "For", "While", "If", "With", "Raise",
+ "TryExcept", "TryFinally", "Assert", "Import", "ImportFrom",
+ "Exec", "Global", "Expr", "Pass", "Break", "Continue")
+ _expr_nodes = set(getattr(ast, name) for name in _exprs)
+ _stmt_nodes = set(getattr(ast, name) for name in _stmts)
+ def _is_ast_expr(node):
+ return node.__class__ in _expr_nodes
+ def _is_ast_stmt(node):
+ return node.__class__ in _stmt_nodes
+else:
+ def _is_ast_expr(node):
+ return isinstance(node, ast.expr)
+ def _is_ast_stmt(node):
+ return isinstance(node, ast.stmt)
+
+
+class Failure(Exception):
+ """Error found while interpreting AST."""
+
+ def __init__(self, explanation=""):
+ self.cause = sys.exc_info()
+ self.explanation = explanation
+
+
+def interpret(source, frame, should_fail=False):
+ mod = ast.parse(source)
+ visitor = DebugInterpreter(frame)
+ try:
+ visitor.visit(mod)
+ except Failure:
+ failure = sys.exc_info()[1]
+ return getfailure(failure)
+ if should_fail:
+ return ("(assertion failed, but when it was re-run for "
+ "printing intermediate values, it did not fail. Suggestions: "
+ "compute assert expression before the assert or use --no-assert)")
+
+def run(offending_line, frame=None):
+ if frame is None:
+ frame = py.code.Frame(sys._getframe(1))
+ return interpret(offending_line, frame)
+
+def getfailure(failure):
+ explanation = _format_explanation(failure.explanation)
+ value = failure.cause[1]
+ if str(value):
+ lines = explanation.splitlines()
+ if not lines:
+ lines.append("")
+ lines[0] += " << %s" % (value,)
+ explanation = "\n".join(lines)
+ text = "%s: %s" % (failure.cause[0].__name__, explanation)
+ if text.startswith("AssertionError: assert "):
+ text = text[16:]
+ return text
+
+
+operator_map = {
+ ast.BitOr : "|",
+ ast.BitXor : "^",
+ ast.BitAnd : "&",
+ ast.LShift : "<<",
+ ast.RShift : ">>",
+ ast.Add : "+",
+ ast.Sub : "-",
+ ast.Mult : "*",
+ ast.Div : "/",
+ ast.FloorDiv : "//",
+ ast.Mod : "%",
+ ast.Eq : "==",
+ ast.NotEq : "!=",
+ ast.Lt : "<",
+ ast.LtE : "<=",
+ ast.Gt : ">",
+ ast.GtE : ">=",
+ ast.Pow : "**",
+ ast.Is : "is",
+ ast.IsNot : "is not",
+ ast.In : "in",
+ ast.NotIn : "not in"
+}
+
+unary_map = {
+ ast.Not : "not %s",
+ ast.Invert : "~%s",
+ ast.USub : "-%s",
+ ast.UAdd : "+%s"
+}
+
+
+class DebugInterpreter(ast.NodeVisitor):
+ """Interpret AST nodes to gleam useful debugging information. """
+
+ def __init__(self, frame):
+ self.frame = frame
+
+ def generic_visit(self, node):
+ # Fallback when we don't have a special implementation.
+ if _is_ast_expr(node):
+ mod = ast.Expression(node)
+ co = self._compile(mod)
+ try:
+ result = self.frame.eval(co)
+ except Exception:
+ raise Failure()
+ explanation = self.frame.repr(result)
+ return explanation, result
+ elif _is_ast_stmt(node):
+ mod = ast.Module([node])
+ co = self._compile(mod, "exec")
+ try:
+ self.frame.exec_(co)
+ except Exception:
+ raise Failure()
+ return None, None
+ else:
+ raise AssertionError("can't handle %s" %(node,))
+
+ def _compile(self, source, mode="eval"):
+ return compile(source, "<assertion interpretation>", mode)
+
+ def visit_Expr(self, expr):
+ return self.visit(expr.value)
+
+ def visit_Module(self, mod):
+ for stmt in mod.body:
+ self.visit(stmt)
+
+ def visit_Name(self, name):
+ explanation, result = self.generic_visit(name)
+ # See if the name is local.
+ source = "%r in locals() is not globals()" % (name.id,)
+ co = self._compile(source)
+ try:
+ local = self.frame.eval(co)
+ except Exception:
+ # have to assume it isn't
+ local = False
+ if not local:
+ return name.id, result
+ return explanation, result
+
+ def visit_Compare(self, comp):
+ left = comp.left
+ left_explanation, left_result = self.visit(left)
+ for op, next_op in zip(comp.ops, comp.comparators):
+ next_explanation, next_result = self.visit(next_op)
+ op_symbol = operator_map[op.__class__]
+ explanation = "%s %s %s" % (left_explanation, op_symbol,
+ next_explanation)
+ source = "__exprinfo_left %s __exprinfo_right" % (op_symbol,)
+ co = self._compile(source)
+ try:
+ result = self.frame.eval(co, __exprinfo_left=left_result,
+ __exprinfo_right=next_result)
+ except Exception:
+ raise Failure(explanation)
+ try:
+ if not result:
+ break
+ except KeyboardInterrupt:
+ raise
+ except:
+ break
+ left_explanation, left_result = next_explanation, next_result
+
+ rcomp = py.code._reprcompare
+ if rcomp:
+ res = rcomp(op_symbol, left_result, next_result)
+ if res:
+ explanation = res
+ return explanation, result
+
+ def visit_BoolOp(self, boolop):
+ is_or = isinstance(boolop.op, ast.Or)
+ explanations = []
+ for operand in boolop.values:
+ explanation, result = self.visit(operand)
+ explanations.append(explanation)
+ if result == is_or:
+ break
+ name = is_or and " or " or " and "
+ explanation = "(" + name.join(explanations) + ")"
+ return explanation, result
+
+ def visit_UnaryOp(self, unary):
+ pattern = unary_map[unary.op.__class__]
+ operand_explanation, operand_result = self.visit(unary.operand)
+ explanation = pattern % (operand_explanation,)
+ co = self._compile(pattern % ("__exprinfo_expr",))
+ try:
+ result = self.frame.eval(co, __exprinfo_expr=operand_result)
+ except Exception:
+ raise Failure(explanation)
+ return explanation, result
+
+ def visit_BinOp(self, binop):
+ left_explanation, left_result = self.visit(binop.left)
+ right_explanation, right_result = self.visit(binop.right)
+ symbol = operator_map[binop.op.__class__]
+ explanation = "(%s %s %s)" % (left_explanation, symbol,
+ right_explanation)
+ source = "__exprinfo_left %s __exprinfo_right" % (symbol,)
+ co = self._compile(source)
+ try:
+ result = self.frame.eval(co, __exprinfo_left=left_result,
+ __exprinfo_right=right_result)
+ except Exception:
+ raise Failure(explanation)
+ return explanation, result
+
+ def visit_Call(self, call):
+ func_explanation, func = self.visit(call.func)
+ arg_explanations = []
+ ns = {"__exprinfo_func" : func}
+ arguments = []
+ for arg in call.args:
+ arg_explanation, arg_result = self.visit(arg)
+ arg_name = "__exprinfo_%s" % (len(ns),)
+ ns[arg_name] = arg_result
+ arguments.append(arg_name)
+ arg_explanations.append(arg_explanation)
+ for keyword in call.keywords:
+ arg_explanation, arg_result = self.visit(keyword.value)
+ arg_name = "__exprinfo_%s" % (len(ns),)
+ ns[arg_name] = arg_result
+ keyword_source = "%s=%%s" % (keyword.arg)
+ arguments.append(keyword_source % (arg_name,))
+ arg_explanations.append(keyword_source % (arg_explanation,))
+ if call.starargs:
+ arg_explanation, arg_result = self.visit(call.starargs)
+ arg_name = "__exprinfo_star"
+ ns[arg_name] = arg_result
+ arguments.append("*%s" % (arg_name,))
+ arg_explanations.append("*%s" % (arg_explanation,))
+ if call.kwargs:
+ arg_explanation, arg_result = self.visit(call.kwargs)
+ arg_name = "__exprinfo_kwds"
+ ns[arg_name] = arg_result
+ arguments.append("**%s" % (arg_name,))
+ arg_explanations.append("**%s" % (arg_explanation,))
+ args_explained = ", ".join(arg_explanations)
+ explanation = "%s(%s)" % (func_explanation, args_explained)
+ args = ", ".join(arguments)
+ source = "__exprinfo_func(%s)" % (args,)
+ co = self._compile(source)
+ try:
+ result = self.frame.eval(co, **ns)
+ except Exception:
+ raise Failure(explanation)
+ pattern = "%s\n{%s = %s\n}"
+ rep = self.frame.repr(result)
+ explanation = pattern % (rep, rep, explanation)
+ return explanation, result
+
+ def _is_builtin_name(self, name):
+ pattern = "%r not in globals() and %r not in locals()"
+ source = pattern % (name.id, name.id)
+ co = self._compile(source)
+ try:
+ return self.frame.eval(co)
+ except Exception:
+ return False
+
+ def visit_Attribute(self, attr):
+ if not isinstance(attr.ctx, ast.Load):
+ return self.generic_visit(attr)
+ source_explanation, source_result = self.visit(attr.value)
+ explanation = "%s.%s" % (source_explanation, attr.attr)
+ source = "__exprinfo_expr.%s" % (attr.attr,)
+ co = self._compile(source)
+ try:
+ result = self.frame.eval(co, __exprinfo_expr=source_result)
+ except Exception:
+ raise Failure(explanation)
+ explanation = "%s\n{%s = %s.%s\n}" % (self.frame.repr(result),
+ self.frame.repr(result),
+ source_explanation, attr.attr)
+ # Check if the attr is from an instance.
+ source = "%r in getattr(__exprinfo_expr, '__dict__', {})"
+ source = source % (attr.attr,)
+ co = self._compile(source)
+ try:
+ from_instance = self.frame.eval(co, __exprinfo_expr=source_result)
+ except Exception:
+ from_instance = True
+ if from_instance:
+ rep = self.frame.repr(result)
+ pattern = "%s\n{%s = %s\n}"
+ explanation = pattern % (rep, rep, explanation)
+ return explanation, result
+
+ def visit_Assert(self, assrt):
+ test_explanation, test_result = self.visit(assrt.test)
+ if test_explanation.startswith("False\n{False =") and \
+ test_explanation.endswith("\n"):
+ test_explanation = test_explanation[15:-2]
+ explanation = "assert %s" % (test_explanation,)
+ if not test_result:
+ try:
+ raise BuiltinAssertionError
+ except Exception:
+ raise Failure(explanation)
+ return explanation, test_result
+
+ def visit_Assign(self, assign):
+ value_explanation, value_result = self.visit(assign.value)
+ explanation = "... = %s" % (value_explanation,)
+ name = ast.Name("__exprinfo_expr", ast.Load(),
+ lineno=assign.value.lineno,
+ col_offset=assign.value.col_offset)
+ new_assign = ast.Assign(assign.targets, name, lineno=assign.lineno,
+ col_offset=assign.col_offset)
+ mod = ast.Module([new_assign])
+ co = self._compile(mod, "exec")
+ try:
+ self.frame.exec_(co, __exprinfo_expr=value_result)
+ except Exception:
+ raise Failure(explanation)
+ return explanation, value_result
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_code/_assertionold.py b/tests/wpt/web-platform-tests/tools/py/py/_code/_assertionold.py
new file mode 100644
index 00000000000..4e81fb3ef6e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_code/_assertionold.py
@@ -0,0 +1,555 @@
+import py
+import sys, inspect
+from compiler import parse, ast, pycodegen
+from py._code.assertion import BuiltinAssertionError, _format_explanation
+
+passthroughex = py.builtin._sysex
+
+class Failure:
+ def __init__(self, node):
+ self.exc, self.value, self.tb = sys.exc_info()
+ self.node = node
+
+class View(object):
+ """View base class.
+
+ If C is a subclass of View, then C(x) creates a proxy object around
+ the object x. The actual class of the proxy is not C in general,
+ but a *subclass* of C determined by the rules below. To avoid confusion
+ we call view class the class of the proxy (a subclass of C, so of View)
+ and object class the class of x.
+
+ Attributes and methods not found in the proxy are automatically read on x.
+ Other operations like setting attributes are performed on the proxy, as
+ determined by its view class. The object x is available from the proxy
+ as its __obj__ attribute.
+
+ The view class selection is determined by the __view__ tuples and the
+ optional __viewkey__ method. By default, the selected view class is the
+ most specific subclass of C whose __view__ mentions the class of x.
+ If no such subclass is found, the search proceeds with the parent
+ object classes. For example, C(True) will first look for a subclass
+ of C with __view__ = (..., bool, ...) and only if it doesn't find any
+ look for one with __view__ = (..., int, ...), and then ..., object,...
+ If everything fails the class C itself is considered to be the default.
+
+ Alternatively, the view class selection can be driven by another aspect
+ of the object x, instead of the class of x, by overriding __viewkey__.
+ See last example at the end of this module.
+ """
+
+ _viewcache = {}
+ __view__ = ()
+
+ def __new__(rootclass, obj, *args, **kwds):
+ self = object.__new__(rootclass)
+ self.__obj__ = obj
+ self.__rootclass__ = rootclass
+ key = self.__viewkey__()
+ try:
+ self.__class__ = self._viewcache[key]
+ except KeyError:
+ self.__class__ = self._selectsubclass(key)
+ return self
+
+ def __getattr__(self, attr):
+ # attributes not found in the normal hierarchy rooted on View
+ # are looked up in the object's real class
+ return getattr(self.__obj__, attr)
+
+ def __viewkey__(self):
+ return self.__obj__.__class__
+
+ def __matchkey__(self, key, subclasses):
+ if inspect.isclass(key):
+ keys = inspect.getmro(key)
+ else:
+ keys = [key]
+ for key in keys:
+ result = [C for C in subclasses if key in C.__view__]
+ if result:
+ return result
+ return []
+
+ def _selectsubclass(self, key):
+ subclasses = list(enumsubclasses(self.__rootclass__))
+ for C in subclasses:
+ if not isinstance(C.__view__, tuple):
+ C.__view__ = (C.__view__,)
+ choices = self.__matchkey__(key, subclasses)
+ if not choices:
+ return self.__rootclass__
+ elif len(choices) == 1:
+ return choices[0]
+ else:
+ # combine the multiple choices
+ return type('?', tuple(choices), {})
+
+ def __repr__(self):
+ return '%s(%r)' % (self.__rootclass__.__name__, self.__obj__)
+
+
+def enumsubclasses(cls):
+ for subcls in cls.__subclasses__():
+ for subsubclass in enumsubclasses(subcls):
+ yield subsubclass
+ yield cls
+
+
+class Interpretable(View):
+ """A parse tree node with a few extra methods."""
+ explanation = None
+
+ def is_builtin(self, frame):
+ return False
+
+ def eval(self, frame):
+ # fall-back for unknown expression nodes
+ try:
+ expr = ast.Expression(self.__obj__)
+ expr.filename = '<eval>'
+ self.__obj__.filename = '<eval>'
+ co = pycodegen.ExpressionCodeGenerator(expr).getCode()
+ result = frame.eval(co)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+ self.result = result
+ self.explanation = self.explanation or frame.repr(self.result)
+
+ def run(self, frame):
+ # fall-back for unknown statement nodes
+ try:
+ expr = ast.Module(None, ast.Stmt([self.__obj__]))
+ expr.filename = '<run>'
+ co = pycodegen.ModuleCodeGenerator(expr).getCode()
+ frame.exec_(co)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+
+ def nice_explanation(self):
+ return _format_explanation(self.explanation)
+
+
+class Name(Interpretable):
+ __view__ = ast.Name
+
+ def is_local(self, frame):
+ source = '%r in locals() is not globals()' % self.name
+ try:
+ return frame.is_true(frame.eval(source))
+ except passthroughex:
+ raise
+ except:
+ return False
+
+ def is_global(self, frame):
+ source = '%r in globals()' % self.name
+ try:
+ return frame.is_true(frame.eval(source))
+ except passthroughex:
+ raise
+ except:
+ return False
+
+ def is_builtin(self, frame):
+ source = '%r not in locals() and %r not in globals()' % (
+ self.name, self.name)
+ try:
+ return frame.is_true(frame.eval(source))
+ except passthroughex:
+ raise
+ except:
+ return False
+
+ def eval(self, frame):
+ super(Name, self).eval(frame)
+ if not self.is_local(frame):
+ self.explanation = self.name
+
+class Compare(Interpretable):
+ __view__ = ast.Compare
+
+ def eval(self, frame):
+ expr = Interpretable(self.expr)
+ expr.eval(frame)
+ for operation, expr2 in self.ops:
+ if hasattr(self, 'result'):
+ # shortcutting in chained expressions
+ if not frame.is_true(self.result):
+ break
+ expr2 = Interpretable(expr2)
+ expr2.eval(frame)
+ self.explanation = "%s %s %s" % (
+ expr.explanation, operation, expr2.explanation)
+ source = "__exprinfo_left %s __exprinfo_right" % operation
+ try:
+ self.result = frame.eval(source,
+ __exprinfo_left=expr.result,
+ __exprinfo_right=expr2.result)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+ expr = expr2
+
+class And(Interpretable):
+ __view__ = ast.And
+
+ def eval(self, frame):
+ explanations = []
+ for expr in self.nodes:
+ expr = Interpretable(expr)
+ expr.eval(frame)
+ explanations.append(expr.explanation)
+ self.result = expr.result
+ if not frame.is_true(expr.result):
+ break
+ self.explanation = '(' + ' and '.join(explanations) + ')'
+
+class Or(Interpretable):
+ __view__ = ast.Or
+
+ def eval(self, frame):
+ explanations = []
+ for expr in self.nodes:
+ expr = Interpretable(expr)
+ expr.eval(frame)
+ explanations.append(expr.explanation)
+ self.result = expr.result
+ if frame.is_true(expr.result):
+ break
+ self.explanation = '(' + ' or '.join(explanations) + ')'
+
+
+# == Unary operations ==
+keepalive = []
+for astclass, astpattern in {
+ ast.Not : 'not __exprinfo_expr',
+ ast.Invert : '(~__exprinfo_expr)',
+ }.items():
+
+ class UnaryArith(Interpretable):
+ __view__ = astclass
+
+ def eval(self, frame, astpattern=astpattern):
+ expr = Interpretable(self.expr)
+ expr.eval(frame)
+ self.explanation = astpattern.replace('__exprinfo_expr',
+ expr.explanation)
+ try:
+ self.result = frame.eval(astpattern,
+ __exprinfo_expr=expr.result)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+
+ keepalive.append(UnaryArith)
+
+# == Binary operations ==
+for astclass, astpattern in {
+ ast.Add : '(__exprinfo_left + __exprinfo_right)',
+ ast.Sub : '(__exprinfo_left - __exprinfo_right)',
+ ast.Mul : '(__exprinfo_left * __exprinfo_right)',
+ ast.Div : '(__exprinfo_left / __exprinfo_right)',
+ ast.Mod : '(__exprinfo_left % __exprinfo_right)',
+ ast.Power : '(__exprinfo_left ** __exprinfo_right)',
+ }.items():
+
+ class BinaryArith(Interpretable):
+ __view__ = astclass
+
+ def eval(self, frame, astpattern=astpattern):
+ left = Interpretable(self.left)
+ left.eval(frame)
+ right = Interpretable(self.right)
+ right.eval(frame)
+ self.explanation = (astpattern
+ .replace('__exprinfo_left', left .explanation)
+ .replace('__exprinfo_right', right.explanation))
+ try:
+ self.result = frame.eval(astpattern,
+ __exprinfo_left=left.result,
+ __exprinfo_right=right.result)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+
+ keepalive.append(BinaryArith)
+
+
+class CallFunc(Interpretable):
+ __view__ = ast.CallFunc
+
+ def is_bool(self, frame):
+ source = 'isinstance(__exprinfo_value, bool)'
+ try:
+ return frame.is_true(frame.eval(source,
+ __exprinfo_value=self.result))
+ except passthroughex:
+ raise
+ except:
+ return False
+
+ def eval(self, frame):
+ node = Interpretable(self.node)
+ node.eval(frame)
+ explanations = []
+ vars = {'__exprinfo_fn': node.result}
+ source = '__exprinfo_fn('
+ for a in self.args:
+ if isinstance(a, ast.Keyword):
+ keyword = a.name
+ a = a.expr
+ else:
+ keyword = None
+ a = Interpretable(a)
+ a.eval(frame)
+ argname = '__exprinfo_%d' % len(vars)
+ vars[argname] = a.result
+ if keyword is None:
+ source += argname + ','
+ explanations.append(a.explanation)
+ else:
+ source += '%s=%s,' % (keyword, argname)
+ explanations.append('%s=%s' % (keyword, a.explanation))
+ if self.star_args:
+ star_args = Interpretable(self.star_args)
+ star_args.eval(frame)
+ argname = '__exprinfo_star'
+ vars[argname] = star_args.result
+ source += '*' + argname + ','
+ explanations.append('*' + star_args.explanation)
+ if self.dstar_args:
+ dstar_args = Interpretable(self.dstar_args)
+ dstar_args.eval(frame)
+ argname = '__exprinfo_kwds'
+ vars[argname] = dstar_args.result
+ source += '**' + argname + ','
+ explanations.append('**' + dstar_args.explanation)
+ self.explanation = "%s(%s)" % (
+ node.explanation, ', '.join(explanations))
+ if source.endswith(','):
+ source = source[:-1]
+ source += ')'
+ try:
+ self.result = frame.eval(source, **vars)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+ if not node.is_builtin(frame) or not self.is_bool(frame):
+ r = frame.repr(self.result)
+ self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation)
+
+class Getattr(Interpretable):
+ __view__ = ast.Getattr
+
+ def eval(self, frame):
+ expr = Interpretable(self.expr)
+ expr.eval(frame)
+ source = '__exprinfo_expr.%s' % self.attrname
+ try:
+ self.result = frame.eval(source, __exprinfo_expr=expr.result)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+ self.explanation = '%s.%s' % (expr.explanation, self.attrname)
+ # if the attribute comes from the instance, its value is interesting
+ source = ('hasattr(__exprinfo_expr, "__dict__") and '
+ '%r in __exprinfo_expr.__dict__' % self.attrname)
+ try:
+ from_instance = frame.is_true(
+ frame.eval(source, __exprinfo_expr=expr.result))
+ except passthroughex:
+ raise
+ except:
+ from_instance = True
+ if from_instance:
+ r = frame.repr(self.result)
+ self.explanation = '%s\n{%s = %s\n}' % (r, r, self.explanation)
+
+# == Re-interpretation of full statements ==
+
+class Assert(Interpretable):
+ __view__ = ast.Assert
+
+ def run(self, frame):
+ test = Interpretable(self.test)
+ test.eval(frame)
+ # simplify 'assert False where False = ...'
+ if (test.explanation.startswith('False\n{False = ') and
+ test.explanation.endswith('\n}')):
+ test.explanation = test.explanation[15:-2]
+ # print the result as 'assert <explanation>'
+ self.result = test.result
+ self.explanation = 'assert ' + test.explanation
+ if not frame.is_true(test.result):
+ try:
+ raise BuiltinAssertionError
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+
+class Assign(Interpretable):
+ __view__ = ast.Assign
+
+ def run(self, frame):
+ expr = Interpretable(self.expr)
+ expr.eval(frame)
+ self.result = expr.result
+ self.explanation = '... = ' + expr.explanation
+ # fall-back-run the rest of the assignment
+ ass = ast.Assign(self.nodes, ast.Name('__exprinfo_expr'))
+ mod = ast.Module(None, ast.Stmt([ass]))
+ mod.filename = '<run>'
+ co = pycodegen.ModuleCodeGenerator(mod).getCode()
+ try:
+ frame.exec_(co, __exprinfo_expr=expr.result)
+ except passthroughex:
+ raise
+ except:
+ raise Failure(self)
+
+class Discard(Interpretable):
+ __view__ = ast.Discard
+
+ def run(self, frame):
+ expr = Interpretable(self.expr)
+ expr.eval(frame)
+ self.result = expr.result
+ self.explanation = expr.explanation
+
+class Stmt(Interpretable):
+ __view__ = ast.Stmt
+
+ def run(self, frame):
+ for stmt in self.nodes:
+ stmt = Interpretable(stmt)
+ stmt.run(frame)
+
+
+def report_failure(e):
+ explanation = e.node.nice_explanation()
+ if explanation:
+ explanation = ", in: " + explanation
+ else:
+ explanation = ""
+ sys.stdout.write("%s: %s%s\n" % (e.exc.__name__, e.value, explanation))
+
+def check(s, frame=None):
+ if frame is None:
+ frame = sys._getframe(1)
+ frame = py.code.Frame(frame)
+ expr = parse(s, 'eval')
+ assert isinstance(expr, ast.Expression)
+ node = Interpretable(expr.node)
+ try:
+ node.eval(frame)
+ except passthroughex:
+ raise
+ except Failure:
+ e = sys.exc_info()[1]
+ report_failure(e)
+ else:
+ if not frame.is_true(node.result):
+ sys.stderr.write("assertion failed: %s\n" % node.nice_explanation())
+
+
+###########################################################
+# API / Entry points
+# #########################################################
+
+def interpret(source, frame, should_fail=False):
+ module = Interpretable(parse(source, 'exec').node)
+ #print "got module", module
+ if isinstance(frame, py.std.types.FrameType):
+ frame = py.code.Frame(frame)
+ try:
+ module.run(frame)
+ except Failure:
+ e = sys.exc_info()[1]
+ return getfailure(e)
+ except passthroughex:
+ raise
+ except:
+ import traceback
+ traceback.print_exc()
+ if should_fail:
+ return ("(assertion failed, but when it was re-run for "
+ "printing intermediate values, it did not fail. Suggestions: "
+ "compute assert expression before the assert or use --nomagic)")
+ else:
+ return None
+
+def getmsg(excinfo):
+ if isinstance(excinfo, tuple):
+ excinfo = py.code.ExceptionInfo(excinfo)
+ #frame, line = gettbline(tb)
+ #frame = py.code.Frame(frame)
+ #return interpret(line, frame)
+
+ tb = excinfo.traceback[-1]
+ source = str(tb.statement).strip()
+ x = interpret(source, tb.frame, should_fail=True)
+ if not isinstance(x, str):
+ raise TypeError("interpret returned non-string %r" % (x,))
+ return x
+
+def getfailure(e):
+ explanation = e.node.nice_explanation()
+ if str(e.value):
+ lines = explanation.split('\n')
+ lines[0] += " << %s" % (e.value,)
+ explanation = '\n'.join(lines)
+ text = "%s: %s" % (e.exc.__name__, explanation)
+ if text.startswith('AssertionError: assert '):
+ text = text[16:]
+ return text
+
+def run(s, frame=None):
+ if frame is None:
+ frame = sys._getframe(1)
+ frame = py.code.Frame(frame)
+ module = Interpretable(parse(s, 'exec').node)
+ try:
+ module.run(frame)
+ except Failure:
+ e = sys.exc_info()[1]
+ report_failure(e)
+
+
+if __name__ == '__main__':
+ # example:
+ def f():
+ return 5
+ def g():
+ return 3
+ def h(x):
+ return 'never'
+ check("f() * g() == 5")
+ check("not f()")
+ check("not (f() and g() or 0)")
+ check("f() == g()")
+ i = 4
+ check("i == f()")
+ check("len(f()) == 0")
+ check("isinstance(2+3+4, float)")
+
+ run("x = i")
+ check("x == 5")
+
+ run("assert not f(), 'oops'")
+ run("a, b, c = 1, 2")
+ run("a, b, c = f()")
+
+ check("max([f(),g()]) == 4")
+ check("'hello'[g()] == 'h'")
+ run("'guk%d' % h(f())")
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_code/_py2traceback.py b/tests/wpt/web-platform-tests/tools/py/py/_code/_py2traceback.py
new file mode 100644
index 00000000000..d65e27cb730
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_code/_py2traceback.py
@@ -0,0 +1,79 @@
+# copied from python-2.7.3's traceback.py
+# CHANGES:
+# - some_str is replaced, trying to create unicode strings
+#
+import types
+
+def format_exception_only(etype, value):
+ """Format the exception part of a traceback.
+
+ The arguments are the exception type and value such as given by
+ sys.last_type and sys.last_value. The return value is a list of
+ strings, each ending in a newline.
+
+ Normally, the list contains a single string; however, for
+ SyntaxError exceptions, it contains several lines that (when
+ printed) display detailed information about where the syntax
+ error occurred.
+
+ The message indicating which exception occurred is always the last
+ string in the list.
+
+ """
+
+ # An instance should not have a meaningful value parameter, but
+ # sometimes does, particularly for string exceptions, such as
+ # >>> raise string1, string2 # deprecated
+ #
+ # Clear these out first because issubtype(string1, SyntaxError)
+ # would throw another exception and mask the original problem.
+ if (isinstance(etype, BaseException) or
+ isinstance(etype, types.InstanceType) or
+ etype is None or type(etype) is str):
+ return [_format_final_exc_line(etype, value)]
+
+ stype = etype.__name__
+
+ if not issubclass(etype, SyntaxError):
+ return [_format_final_exc_line(stype, value)]
+
+ # It was a syntax error; show exactly where the problem was found.
+ lines = []
+ try:
+ msg, (filename, lineno, offset, badline) = value.args
+ except Exception:
+ pass
+ else:
+ filename = filename or "<string>"
+ lines.append(' File "%s", line %d\n' % (filename, lineno))
+ if badline is not None:
+ lines.append(' %s\n' % badline.strip())
+ if offset is not None:
+ caretspace = badline.rstrip('\n')[:offset].lstrip()
+ # non-space whitespace (likes tabs) must be kept for alignment
+ caretspace = ((c.isspace() and c or ' ') for c in caretspace)
+ # only three spaces to account for offset1 == pos 0
+ lines.append(' %s^\n' % ''.join(caretspace))
+ value = msg
+
+ lines.append(_format_final_exc_line(stype, value))
+ return lines
+
+def _format_final_exc_line(etype, value):
+ """Return a list of a single line -- normal case for format_exception_only"""
+ valuestr = _some_str(value)
+ if value is None or not valuestr:
+ line = "%s\n" % etype
+ else:
+ line = "%s: %s\n" % (etype, valuestr)
+ return line
+
+def _some_str(value):
+ try:
+ return unicode(value)
+ except Exception:
+ try:
+ return str(value)
+ except Exception:
+ pass
+ return '<unprintable %s object>' % type(value).__name__
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_code/assertion.py b/tests/wpt/web-platform-tests/tools/py/py/_code/assertion.py
new file mode 100644
index 00000000000..4ce80c75b1c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_code/assertion.py
@@ -0,0 +1,94 @@
+import sys
+import py
+
+BuiltinAssertionError = py.builtin.builtins.AssertionError
+
+_reprcompare = None # if set, will be called by assert reinterp for comparison ops
+
+def _format_explanation(explanation):
+ """This formats an explanation
+
+ Normally all embedded newlines are escaped, however there are
+ three exceptions: \n{, \n} and \n~. The first two are intended
+ cover nested explanations, see function and attribute explanations
+ for examples (.visit_Call(), visit_Attribute()). The last one is
+ for when one explanation needs to span multiple lines, e.g. when
+ displaying diffs.
+ """
+ raw_lines = (explanation or '').split('\n')
+ # escape newlines not followed by {, } and ~
+ lines = [raw_lines[0]]
+ for l in raw_lines[1:]:
+ if l.startswith('{') or l.startswith('}') or l.startswith('~'):
+ lines.append(l)
+ else:
+ lines[-1] += '\\n' + l
+
+ result = lines[:1]
+ stack = [0]
+ stackcnt = [0]
+ for line in lines[1:]:
+ if line.startswith('{'):
+ if stackcnt[-1]:
+ s = 'and '
+ else:
+ s = 'where '
+ stack.append(len(result))
+ stackcnt[-1] += 1
+ stackcnt.append(0)
+ result.append(' +' + ' '*(len(stack)-1) + s + line[1:])
+ elif line.startswith('}'):
+ assert line.startswith('}')
+ stack.pop()
+ stackcnt.pop()
+ result[stack[-1]] += line[1:]
+ else:
+ assert line.startswith('~')
+ result.append(' '*len(stack) + line[1:])
+ assert len(stack) == 1
+ return '\n'.join(result)
+
+
+class AssertionError(BuiltinAssertionError):
+ def __init__(self, *args):
+ BuiltinAssertionError.__init__(self, *args)
+ if args:
+ try:
+ self.msg = str(args[0])
+ except py.builtin._sysex:
+ raise
+ except:
+ self.msg = "<[broken __repr__] %s at %0xd>" %(
+ args[0].__class__, id(args[0]))
+ else:
+ f = py.code.Frame(sys._getframe(1))
+ try:
+ source = f.code.fullsource
+ if source is not None:
+ try:
+ source = source.getstatement(f.lineno, assertion=True)
+ except IndexError:
+ source = None
+ else:
+ source = str(source.deindent()).strip()
+ except py.error.ENOENT:
+ source = None
+ # this can also occur during reinterpretation, when the
+ # co_filename is set to "<run>".
+ if source:
+ self.msg = reinterpret(source, f, should_fail=True)
+ else:
+ self.msg = "<could not determine information>"
+ if not self.args:
+ self.args = (self.msg,)
+
+if sys.version_info > (3, 0):
+ AssertionError.__module__ = "builtins"
+ reinterpret_old = "old reinterpretation not available for py3"
+else:
+ from py._code._assertionold import interpret as reinterpret_old
+if sys.version_info >= (2, 6) or (sys.platform.startswith("java")):
+ from py._code._assertionnew import interpret as reinterpret
+else:
+ reinterpret = reinterpret_old
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_code/code.py b/tests/wpt/web-platform-tests/tools/py/py/_code/code.py
new file mode 100644
index 00000000000..f14c562a296
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_code/code.py
@@ -0,0 +1,787 @@
+import py
+import sys
+from inspect import CO_VARARGS, CO_VARKEYWORDS
+
+builtin_repr = repr
+
+reprlib = py.builtin._tryimport('repr', 'reprlib')
+
+if sys.version_info[0] >= 3:
+ from traceback import format_exception_only
+else:
+ from py._code._py2traceback import format_exception_only
+
+class Code(object):
+ """ wrapper around Python code objects """
+ def __init__(self, rawcode):
+ if not hasattr(rawcode, "co_filename"):
+ rawcode = py.code.getrawcode(rawcode)
+ try:
+ self.filename = rawcode.co_filename
+ self.firstlineno = rawcode.co_firstlineno - 1
+ self.name = rawcode.co_name
+ except AttributeError:
+ raise TypeError("not a code object: %r" %(rawcode,))
+ self.raw = rawcode
+
+ def __eq__(self, other):
+ return self.raw == other.raw
+
+ def __ne__(self, other):
+ return not self == other
+
+ @property
+ def path(self):
+ """ return a path object pointing to source code (note that it
+ might not point to an actually existing file). """
+ p = py.path.local(self.raw.co_filename)
+ # maybe don't try this checking
+ if not p.check():
+ # XXX maybe try harder like the weird logic
+ # in the standard lib [linecache.updatecache] does?
+ p = self.raw.co_filename
+ return p
+
+ @property
+ def fullsource(self):
+ """ return a py.code.Source object for the full source file of the code
+ """
+ from py._code import source
+ full, _ = source.findsource(self.raw)
+ return full
+
+ def source(self):
+ """ return a py.code.Source object for the code object's source only
+ """
+ # return source only for that part of code
+ return py.code.Source(self.raw)
+
+ def getargs(self, var=False):
+ """ return a tuple with the argument names for the code object
+
+ if 'var' is set True also return the names of the variable and
+ keyword arguments when present
+ """
+ # handfull shortcut for getting args
+ raw = self.raw
+ argcount = raw.co_argcount
+ if var:
+ argcount += raw.co_flags & CO_VARARGS
+ argcount += raw.co_flags & CO_VARKEYWORDS
+ return raw.co_varnames[:argcount]
+
+class Frame(object):
+ """Wrapper around a Python frame holding f_locals and f_globals
+ in which expressions can be evaluated."""
+
+ def __init__(self, frame):
+ self.lineno = frame.f_lineno - 1
+ self.f_globals = frame.f_globals
+ self.f_locals = frame.f_locals
+ self.raw = frame
+ self.code = py.code.Code(frame.f_code)
+
+ @property
+ def statement(self):
+ """ statement this frame is at """
+ if self.code.fullsource is None:
+ return py.code.Source("")
+ return self.code.fullsource.getstatement(self.lineno)
+
+ def eval(self, code, **vars):
+ """ evaluate 'code' in the frame
+
+ 'vars' are optional additional local variables
+
+ returns the result of the evaluation
+ """
+ f_locals = self.f_locals.copy()
+ f_locals.update(vars)
+ return eval(code, self.f_globals, f_locals)
+
+ def exec_(self, code, **vars):
+ """ exec 'code' in the frame
+
+ 'vars' are optiona; additional local variables
+ """
+ f_locals = self.f_locals.copy()
+ f_locals.update(vars)
+ py.builtin.exec_(code, self.f_globals, f_locals )
+
+ def repr(self, object):
+ """ return a 'safe' (non-recursive, one-line) string repr for 'object'
+ """
+ return py.io.saferepr(object)
+
+ def is_true(self, object):
+ return object
+
+ def getargs(self, var=False):
+ """ return a list of tuples (name, value) for all arguments
+
+ if 'var' is set True also include the variable and keyword
+ arguments when present
+ """
+ retval = []
+ for arg in self.code.getargs(var):
+ try:
+ retval.append((arg, self.f_locals[arg]))
+ except KeyError:
+ pass # this can occur when using Psyco
+ return retval
+
+class TracebackEntry(object):
+ """ a single entry in a traceback """
+
+ _repr_style = None
+ exprinfo = None
+
+ def __init__(self, rawentry):
+ self._rawentry = rawentry
+ self.lineno = rawentry.tb_lineno - 1
+
+ def set_repr_style(self, mode):
+ assert mode in ("short", "long")
+ self._repr_style = mode
+
+ @property
+ def frame(self):
+ return py.code.Frame(self._rawentry.tb_frame)
+
+ @property
+ def relline(self):
+ return self.lineno - self.frame.code.firstlineno
+
+ def __repr__(self):
+ return "<TracebackEntry %s:%d>" %(self.frame.code.path, self.lineno+1)
+
+ @property
+ def statement(self):
+ """ py.code.Source object for the current statement """
+ source = self.frame.code.fullsource
+ return source.getstatement(self.lineno)
+
+ @property
+ def path(self):
+ """ path to the source code """
+ return self.frame.code.path
+
+ def getlocals(self):
+ return self.frame.f_locals
+ locals = property(getlocals, None, None, "locals of underlaying frame")
+
+ def reinterpret(self):
+ """Reinterpret the failing statement and returns a detailed information
+ about what operations are performed."""
+ if self.exprinfo is None:
+ source = str(self.statement).strip()
+ x = py.code._reinterpret(source, self.frame, should_fail=True)
+ if not isinstance(x, str):
+ raise TypeError("interpret returned non-string %r" % (x,))
+ self.exprinfo = x
+ return self.exprinfo
+
+ def getfirstlinesource(self):
+ # on Jython this firstlineno can be -1 apparently
+ return max(self.frame.code.firstlineno, 0)
+
+ def getsource(self, astcache=None):
+ """ return failing source code. """
+ # we use the passed in astcache to not reparse asttrees
+ # within exception info printing
+ from py._code.source import getstatementrange_ast
+ source = self.frame.code.fullsource
+ if source is None:
+ return None
+ key = astnode = None
+ if astcache is not None:
+ key = self.frame.code.path
+ if key is not None:
+ astnode = astcache.get(key, None)
+ start = self.getfirstlinesource()
+ try:
+ astnode, _, end = getstatementrange_ast(self.lineno, source,
+ astnode=astnode)
+ except SyntaxError:
+ end = self.lineno + 1
+ else:
+ if key is not None:
+ astcache[key] = astnode
+ return source[start:end]
+
+ source = property(getsource)
+
+ def ishidden(self):
+ """ return True if the current frame has a var __tracebackhide__
+ resolving to True
+
+ mostly for internal use
+ """
+ try:
+ return self.frame.f_locals['__tracebackhide__']
+ except KeyError:
+ try:
+ return self.frame.f_globals['__tracebackhide__']
+ except KeyError:
+ return False
+
+ def __str__(self):
+ try:
+ fn = str(self.path)
+ except py.error.Error:
+ fn = '???'
+ name = self.frame.code.name
+ try:
+ line = str(self.statement).lstrip()
+ except KeyboardInterrupt:
+ raise
+ except:
+ line = "???"
+ return " File %r:%d in %s\n %s\n" %(fn, self.lineno+1, name, line)
+
+ def name(self):
+ return self.frame.code.raw.co_name
+ name = property(name, None, None, "co_name of underlaying code")
+
+class Traceback(list):
+ """ Traceback objects encapsulate and offer higher level
+ access to Traceback entries.
+ """
+ Entry = TracebackEntry
+ def __init__(self, tb):
+ """ initialize from given python traceback object. """
+ if hasattr(tb, 'tb_next'):
+ def f(cur):
+ while cur is not None:
+ yield self.Entry(cur)
+ cur = cur.tb_next
+ list.__init__(self, f(tb))
+ else:
+ list.__init__(self, tb)
+
+ def cut(self, path=None, lineno=None, firstlineno=None, excludepath=None):
+ """ return a Traceback instance wrapping part of this Traceback
+
+ by provding any combination of path, lineno and firstlineno, the
+ first frame to start the to-be-returned traceback is determined
+
+ this allows cutting the first part of a Traceback instance e.g.
+ for formatting reasons (removing some uninteresting bits that deal
+ with handling of the exception/traceback)
+ """
+ for x in self:
+ code = x.frame.code
+ codepath = code.path
+ if ((path is None or codepath == path) and
+ (excludepath is None or not hasattr(codepath, 'relto') or
+ not codepath.relto(excludepath)) and
+ (lineno is None or x.lineno == lineno) and
+ (firstlineno is None or x.frame.code.firstlineno == firstlineno)):
+ return Traceback(x._rawentry)
+ return self
+
+ def __getitem__(self, key):
+ val = super(Traceback, self).__getitem__(key)
+ if isinstance(key, type(slice(0))):
+ val = self.__class__(val)
+ return val
+
+ def filter(self, fn=lambda x: not x.ishidden()):
+ """ return a Traceback instance with certain items removed
+
+ fn is a function that gets a single argument, a TracebackItem
+ instance, and should return True when the item should be added
+ to the Traceback, False when not
+
+ by default this removes all the TracebackItems which are hidden
+ (see ishidden() above)
+ """
+ return Traceback(filter(fn, self))
+
+ def getcrashentry(self):
+ """ return last non-hidden traceback entry that lead
+ to the exception of a traceback.
+ """
+ for i in range(-1, -len(self)-1, -1):
+ entry = self[i]
+ if not entry.ishidden():
+ return entry
+ return self[-1]
+
+ def recursionindex(self):
+ """ return the index of the frame/TracebackItem where recursion
+ originates if appropriate, None if no recursion occurred
+ """
+ cache = {}
+ for i, entry in enumerate(self):
+ # id for the code.raw is needed to work around
+ # the strange metaprogramming in the decorator lib from pypi
+ # which generates code objects that have hash/value equality
+ #XXX needs a test
+ key = entry.frame.code.path, id(entry.frame.code.raw), entry.lineno
+ #print "checking for recursion at", key
+ l = cache.setdefault(key, [])
+ if l:
+ f = entry.frame
+ loc = f.f_locals
+ for otherloc in l:
+ if f.is_true(f.eval(co_equal,
+ __recursioncache_locals_1=loc,
+ __recursioncache_locals_2=otherloc)):
+ return i
+ l.append(entry.frame.f_locals)
+ return None
+
+co_equal = compile('__recursioncache_locals_1 == __recursioncache_locals_2',
+ '?', 'eval')
+
+class ExceptionInfo(object):
+ """ wraps sys.exc_info() objects and offers
+ help for navigating the traceback.
+ """
+ _striptext = ''
+ def __init__(self, tup=None, exprinfo=None):
+ if tup is None:
+ tup = sys.exc_info()
+ if exprinfo is None and isinstance(tup[1], AssertionError):
+ exprinfo = getattr(tup[1], 'msg', None)
+ if exprinfo is None:
+ exprinfo = str(tup[1])
+ if exprinfo and exprinfo.startswith('assert '):
+ self._striptext = 'AssertionError: '
+ self._excinfo = tup
+ #: the exception class
+ self.type = tup[0]
+ #: the exception instance
+ self.value = tup[1]
+ #: the exception raw traceback
+ self.tb = tup[2]
+ #: the exception type name
+ self.typename = self.type.__name__
+ #: the exception traceback (py.code.Traceback instance)
+ self.traceback = py.code.Traceback(self.tb)
+
+ def __repr__(self):
+ return "<ExceptionInfo %s tblen=%d>" % (self.typename, len(self.traceback))
+
+ def exconly(self, tryshort=False):
+ """ return the exception as a string
+
+ when 'tryshort' resolves to True, and the exception is a
+ py.code._AssertionError, only the actual exception part of
+ the exception representation is returned (so 'AssertionError: ' is
+ removed from the beginning)
+ """
+ lines = format_exception_only(self.type, self.value)
+ text = ''.join(lines)
+ text = text.rstrip()
+ if tryshort:
+ if text.startswith(self._striptext):
+ text = text[len(self._striptext):]
+ return text
+
+ def errisinstance(self, exc):
+ """ return True if the exception is an instance of exc """
+ return isinstance(self.value, exc)
+
+ def _getreprcrash(self):
+ exconly = self.exconly(tryshort=True)
+ entry = self.traceback.getcrashentry()
+ path, lineno = entry.frame.code.raw.co_filename, entry.lineno
+ return ReprFileLocation(path, lineno+1, exconly)
+
+ def getrepr(self, showlocals=False, style="long",
+ abspath=False, tbfilter=True, funcargs=False):
+ """ return str()able representation of this exception info.
+ showlocals: show locals per traceback entry
+ style: long|short|no|native traceback style
+ tbfilter: hide entries (where __tracebackhide__ is true)
+
+ in case of style==native, tbfilter and showlocals is ignored.
+ """
+ if style == 'native':
+ return ReprExceptionInfo(ReprTracebackNative(
+ py.std.traceback.format_exception(
+ self.type,
+ self.value,
+ self.traceback[0]._rawentry,
+ )), self._getreprcrash())
+
+ fmt = FormattedExcinfo(showlocals=showlocals, style=style,
+ abspath=abspath, tbfilter=tbfilter, funcargs=funcargs)
+ return fmt.repr_excinfo(self)
+
+ def __str__(self):
+ entry = self.traceback[-1]
+ loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
+ return str(loc)
+
+ def __unicode__(self):
+ entry = self.traceback[-1]
+ loc = ReprFileLocation(entry.path, entry.lineno + 1, self.exconly())
+ return unicode(loc)
+
+
+class FormattedExcinfo(object):
+ """ presenting information about failing Functions and Generators. """
+ # for traceback entries
+ flow_marker = ">"
+ fail_marker = "E"
+
+ def __init__(self, showlocals=False, style="long", abspath=True, tbfilter=True, funcargs=False):
+ self.showlocals = showlocals
+ self.style = style
+ self.tbfilter = tbfilter
+ self.funcargs = funcargs
+ self.abspath = abspath
+ self.astcache = {}
+
+ def _getindent(self, source):
+ # figure out indent for given source
+ try:
+ s = str(source.getstatement(len(source)-1))
+ except KeyboardInterrupt:
+ raise
+ except:
+ try:
+ s = str(source[-1])
+ except KeyboardInterrupt:
+ raise
+ except:
+ return 0
+ return 4 + (len(s) - len(s.lstrip()))
+
+ def _getentrysource(self, entry):
+ source = entry.getsource(self.astcache)
+ if source is not None:
+ source = source.deindent()
+ return source
+
+ def _saferepr(self, obj):
+ return py.io.saferepr(obj)
+
+ def repr_args(self, entry):
+ if self.funcargs:
+ args = []
+ for argname, argvalue in entry.frame.getargs(var=True):
+ args.append((argname, self._saferepr(argvalue)))
+ return ReprFuncArgs(args)
+
+ def get_source(self, source, line_index=-1, excinfo=None, short=False):
+ """ return formatted and marked up source lines. """
+ lines = []
+ if source is None or line_index >= len(source.lines):
+ source = py.code.Source("???")
+ line_index = 0
+ if line_index < 0:
+ line_index += len(source)
+ space_prefix = " "
+ if short:
+ lines.append(space_prefix + source.lines[line_index].strip())
+ else:
+ for line in source.lines[:line_index]:
+ lines.append(space_prefix + line)
+ lines.append(self.flow_marker + " " + source.lines[line_index])
+ for line in source.lines[line_index+1:]:
+ lines.append(space_prefix + line)
+ if excinfo is not None:
+ indent = 4 if short else self._getindent(source)
+ lines.extend(self.get_exconly(excinfo, indent=indent, markall=True))
+ return lines
+
+ def get_exconly(self, excinfo, indent=4, markall=False):
+ lines = []
+ indent = " " * indent
+ # get the real exception information out
+ exlines = excinfo.exconly(tryshort=True).split('\n')
+ failindent = self.fail_marker + indent[1:]
+ for line in exlines:
+ lines.append(failindent + line)
+ if not markall:
+ failindent = indent
+ return lines
+
+ def repr_locals(self, locals):
+ if self.showlocals:
+ lines = []
+ keys = [loc for loc in locals if loc[0] != "@"]
+ keys.sort()
+ for name in keys:
+ value = locals[name]
+ if name == '__builtins__':
+ lines.append("__builtins__ = <builtins>")
+ else:
+ # This formatting could all be handled by the
+ # _repr() function, which is only reprlib.Repr in
+ # disguise, so is very configurable.
+ str_repr = self._saferepr(value)
+ #if len(str_repr) < 70 or not isinstance(value,
+ # (list, tuple, dict)):
+ lines.append("%-10s = %s" %(name, str_repr))
+ #else:
+ # self._line("%-10s =\\" % (name,))
+ # # XXX
+ # py.std.pprint.pprint(value, stream=self.excinfowriter)
+ return ReprLocals(lines)
+
+ def repr_traceback_entry(self, entry, excinfo=None):
+ source = self._getentrysource(entry)
+ if source is None:
+ source = py.code.Source("???")
+ line_index = 0
+ else:
+ # entry.getfirstlinesource() can be -1, should be 0 on jython
+ line_index = entry.lineno - max(entry.getfirstlinesource(), 0)
+
+ lines = []
+ style = entry._repr_style
+ if style is None:
+ style = self.style
+ if style in ("short", "long"):
+ short = style == "short"
+ reprargs = self.repr_args(entry) if not short else None
+ s = self.get_source(source, line_index, excinfo, short=short)
+ lines.extend(s)
+ if short:
+ message = "in %s" %(entry.name)
+ else:
+ message = excinfo and excinfo.typename or ""
+ path = self._makepath(entry.path)
+ filelocrepr = ReprFileLocation(path, entry.lineno+1, message)
+ localsrepr = None
+ if not short:
+ localsrepr = self.repr_locals(entry.locals)
+ return ReprEntry(lines, reprargs, localsrepr, filelocrepr, style)
+ if excinfo:
+ lines.extend(self.get_exconly(excinfo, indent=4))
+ return ReprEntry(lines, None, None, None, style)
+
+ def _makepath(self, path):
+ if not self.abspath:
+ try:
+ np = py.path.local().bestrelpath(path)
+ except OSError:
+ return path
+ if len(np) < len(str(path)):
+ path = np
+ return path
+
+ def repr_traceback(self, excinfo):
+ traceback = excinfo.traceback
+ if self.tbfilter:
+ traceback = traceback.filter()
+ recursionindex = None
+ if excinfo.errisinstance(RuntimeError):
+ if "maximum recursion depth exceeded" in str(excinfo.value):
+ recursionindex = traceback.recursionindex()
+ last = traceback[-1]
+ entries = []
+ extraline = None
+ for index, entry in enumerate(traceback):
+ einfo = (last == entry) and excinfo or None
+ reprentry = self.repr_traceback_entry(entry, einfo)
+ entries.append(reprentry)
+ if index == recursionindex:
+ extraline = "!!! Recursion detected (same locals & position)"
+ break
+ return ReprTraceback(entries, extraline, style=self.style)
+
+ def repr_excinfo(self, excinfo):
+ reprtraceback = self.repr_traceback(excinfo)
+ reprcrash = excinfo._getreprcrash()
+ return ReprExceptionInfo(reprtraceback, reprcrash)
+
+class TerminalRepr:
+ def __str__(self):
+ s = self.__unicode__()
+ if sys.version_info[0] < 3:
+ s = s.encode('utf-8')
+ return s
+
+ def __unicode__(self):
+ # FYI this is called from pytest-xdist's serialization of exception
+ # information.
+ io = py.io.TextIO()
+ tw = py.io.TerminalWriter(file=io)
+ self.toterminal(tw)
+ return io.getvalue().strip()
+
+ def __repr__(self):
+ return "<%s instance at %0x>" %(self.__class__, id(self))
+
+
+class ReprExceptionInfo(TerminalRepr):
+ def __init__(self, reprtraceback, reprcrash):
+ self.reprtraceback = reprtraceback
+ self.reprcrash = reprcrash
+ self.sections = []
+
+ def addsection(self, name, content, sep="-"):
+ self.sections.append((name, content, sep))
+
+ def toterminal(self, tw):
+ self.reprtraceback.toterminal(tw)
+ for name, content, sep in self.sections:
+ tw.sep(sep, name)
+ tw.line(content)
+
+class ReprTraceback(TerminalRepr):
+ entrysep = "_ "
+
+ def __init__(self, reprentries, extraline, style):
+ self.reprentries = reprentries
+ self.extraline = extraline
+ self.style = style
+
+ def toterminal(self, tw):
+ # the entries might have different styles
+ last_style = None
+ for i, entry in enumerate(self.reprentries):
+ if entry.style == "long":
+ tw.line("")
+ entry.toterminal(tw)
+ if i < len(self.reprentries) - 1:
+ next_entry = self.reprentries[i+1]
+ if entry.style == "long" or \
+ entry.style == "short" and next_entry.style == "long":
+ tw.sep(self.entrysep)
+
+ if self.extraline:
+ tw.line(self.extraline)
+
+class ReprTracebackNative(ReprTraceback):
+ def __init__(self, tblines):
+ self.style = "native"
+ self.reprentries = [ReprEntryNative(tblines)]
+ self.extraline = None
+
+class ReprEntryNative(TerminalRepr):
+ style = "native"
+
+ def __init__(self, tblines):
+ self.lines = tblines
+
+ def toterminal(self, tw):
+ tw.write("".join(self.lines))
+
+class ReprEntry(TerminalRepr):
+ localssep = "_ "
+
+ def __init__(self, lines, reprfuncargs, reprlocals, filelocrepr, style):
+ self.lines = lines
+ self.reprfuncargs = reprfuncargs
+ self.reprlocals = reprlocals
+ self.reprfileloc = filelocrepr
+ self.style = style
+
+ def toterminal(self, tw):
+ if self.style == "short":
+ self.reprfileloc.toterminal(tw)
+ for line in self.lines:
+ red = line.startswith("E ")
+ tw.line(line, bold=True, red=red)
+ #tw.line("")
+ return
+ if self.reprfuncargs:
+ self.reprfuncargs.toterminal(tw)
+ for line in self.lines:
+ red = line.startswith("E ")
+ tw.line(line, bold=True, red=red)
+ if self.reprlocals:
+ #tw.sep(self.localssep, "Locals")
+ tw.line("")
+ self.reprlocals.toterminal(tw)
+ if self.reprfileloc:
+ if self.lines:
+ tw.line("")
+ self.reprfileloc.toterminal(tw)
+
+ def __str__(self):
+ return "%s\n%s\n%s" % ("\n".join(self.lines),
+ self.reprlocals,
+ self.reprfileloc)
+
+class ReprFileLocation(TerminalRepr):
+ def __init__(self, path, lineno, message):
+ self.path = str(path)
+ self.lineno = lineno
+ self.message = message
+
+ def toterminal(self, tw):
+ # filename and lineno output for each entry,
+ # using an output format that most editors unterstand
+ msg = self.message
+ i = msg.find("\n")
+ if i != -1:
+ msg = msg[:i]
+ tw.line("%s:%s: %s" %(self.path, self.lineno, msg))
+
+class ReprLocals(TerminalRepr):
+ def __init__(self, lines):
+ self.lines = lines
+
+ def toterminal(self, tw):
+ for line in self.lines:
+ tw.line(line)
+
+class ReprFuncArgs(TerminalRepr):
+ def __init__(self, args):
+ self.args = args
+
+ def toterminal(self, tw):
+ if self.args:
+ linesofar = ""
+ for name, value in self.args:
+ ns = "%s = %s" %(name, value)
+ if len(ns) + len(linesofar) + 2 > tw.fullwidth:
+ if linesofar:
+ tw.line(linesofar)
+ linesofar = ns
+ else:
+ if linesofar:
+ linesofar += ", " + ns
+ else:
+ linesofar = ns
+ if linesofar:
+ tw.line(linesofar)
+ tw.line("")
+
+
+
+oldbuiltins = {}
+
+def patch_builtins(assertion=True, compile=True):
+ """ put compile and AssertionError builtins to Python's builtins. """
+ if assertion:
+ from py._code import assertion
+ l = oldbuiltins.setdefault('AssertionError', [])
+ l.append(py.builtin.builtins.AssertionError)
+ py.builtin.builtins.AssertionError = assertion.AssertionError
+ if compile:
+ l = oldbuiltins.setdefault('compile', [])
+ l.append(py.builtin.builtins.compile)
+ py.builtin.builtins.compile = py.code.compile
+
+def unpatch_builtins(assertion=True, compile=True):
+ """ remove compile and AssertionError builtins from Python builtins. """
+ if assertion:
+ py.builtin.builtins.AssertionError = oldbuiltins['AssertionError'].pop()
+ if compile:
+ py.builtin.builtins.compile = oldbuiltins['compile'].pop()
+
+def getrawcode(obj, trycall=True):
+ """ return code object for given function. """
+ try:
+ return obj.__code__
+ except AttributeError:
+ obj = getattr(obj, 'im_func', obj)
+ obj = getattr(obj, 'func_code', obj)
+ obj = getattr(obj, 'f_code', obj)
+ obj = getattr(obj, '__code__', obj)
+ if trycall and not hasattr(obj, 'co_firstlineno'):
+ if hasattr(obj, '__call__') and not py.std.inspect.isclass(obj):
+ x = getrawcode(obj.__call__, trycall=False)
+ if hasattr(x, 'co_firstlineno'):
+ return x
+ return obj
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_code/source.py b/tests/wpt/web-platform-tests/tools/py/py/_code/source.py
new file mode 100644
index 00000000000..3a648e63579
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_code/source.py
@@ -0,0 +1,419 @@
+from __future__ import generators
+
+from bisect import bisect_right
+import sys
+import inspect, tokenize
+import py
+from types import ModuleType
+cpy_compile = compile
+
+try:
+ import _ast
+ from _ast import PyCF_ONLY_AST as _AST_FLAG
+except ImportError:
+ _AST_FLAG = 0
+ _ast = None
+
+
+class Source(object):
+ """ a immutable object holding a source code fragment,
+ possibly deindenting it.
+ """
+ _compilecounter = 0
+ def __init__(self, *parts, **kwargs):
+ self.lines = lines = []
+ de = kwargs.get('deindent', True)
+ rstrip = kwargs.get('rstrip', True)
+ for part in parts:
+ if not part:
+ partlines = []
+ if isinstance(part, Source):
+ partlines = part.lines
+ elif isinstance(part, (tuple, list)):
+ partlines = [x.rstrip("\n") for x in part]
+ elif isinstance(part, py.builtin._basestring):
+ partlines = part.split('\n')
+ if rstrip:
+ while partlines:
+ if partlines[-1].strip():
+ break
+ partlines.pop()
+ else:
+ partlines = getsource(part, deindent=de).lines
+ if de:
+ partlines = deindent(partlines)
+ lines.extend(partlines)
+
+ def __eq__(self, other):
+ try:
+ return self.lines == other.lines
+ except AttributeError:
+ if isinstance(other, str):
+ return str(self) == other
+ return False
+
+ def __getitem__(self, key):
+ if isinstance(key, int):
+ return self.lines[key]
+ else:
+ if key.step not in (None, 1):
+ raise IndexError("cannot slice a Source with a step")
+ return self.__getslice__(key.start, key.stop)
+
+ def __len__(self):
+ return len(self.lines)
+
+ def __getslice__(self, start, end):
+ newsource = Source()
+ newsource.lines = self.lines[start:end]
+ return newsource
+
+ def strip(self):
+ """ return new source object with trailing
+ and leading blank lines removed.
+ """
+ start, end = 0, len(self)
+ while start < end and not self.lines[start].strip():
+ start += 1
+ while end > start and not self.lines[end-1].strip():
+ end -= 1
+ source = Source()
+ source.lines[:] = self.lines[start:end]
+ return source
+
+ def putaround(self, before='', after='', indent=' ' * 4):
+ """ return a copy of the source object with
+ 'before' and 'after' wrapped around it.
+ """
+ before = Source(before)
+ after = Source(after)
+ newsource = Source()
+ lines = [ (indent + line) for line in self.lines]
+ newsource.lines = before.lines + lines + after.lines
+ return newsource
+
+ def indent(self, indent=' ' * 4):
+ """ return a copy of the source object with
+ all lines indented by the given indent-string.
+ """
+ newsource = Source()
+ newsource.lines = [(indent+line) for line in self.lines]
+ return newsource
+
+ def getstatement(self, lineno, assertion=False):
+ """ return Source statement which contains the
+ given linenumber (counted from 0).
+ """
+ start, end = self.getstatementrange(lineno, assertion)
+ return self[start:end]
+
+ def getstatementrange(self, lineno, assertion=False):
+ """ return (start, end) tuple which spans the minimal
+ statement region which containing the given lineno.
+ """
+ if not (0 <= lineno < len(self)):
+ raise IndexError("lineno out of range")
+ ast, start, end = getstatementrange_ast(lineno, self)
+ return start, end
+
+ def deindent(self, offset=None):
+ """ return a new source object deindented by offset.
+ If offset is None then guess an indentation offset from
+ the first non-blank line. Subsequent lines which have a
+ lower indentation offset will be copied verbatim as
+ they are assumed to be part of multilines.
+ """
+ # XXX maybe use the tokenizer to properly handle multiline
+ # strings etc.pp?
+ newsource = Source()
+ newsource.lines[:] = deindent(self.lines, offset)
+ return newsource
+
+ def isparseable(self, deindent=True):
+ """ return True if source is parseable, heuristically
+ deindenting it by default.
+ """
+ try:
+ import parser
+ except ImportError:
+ syntax_checker = lambda x: compile(x, 'asd', 'exec')
+ else:
+ syntax_checker = parser.suite
+
+ if deindent:
+ source = str(self.deindent())
+ else:
+ source = str(self)
+ try:
+ #compile(source+'\n', "x", "exec")
+ syntax_checker(source+'\n')
+ except KeyboardInterrupt:
+ raise
+ except Exception:
+ return False
+ else:
+ return True
+
+ def __str__(self):
+ return "\n".join(self.lines)
+
+ def compile(self, filename=None, mode='exec',
+ flag=generators.compiler_flag,
+ dont_inherit=0, _genframe=None):
+ """ return compiled code object. if filename is None
+ invent an artificial filename which displays
+ the source/line position of the caller frame.
+ """
+ if not filename or py.path.local(filename).check(file=0):
+ if _genframe is None:
+ _genframe = sys._getframe(1) # the caller
+ fn,lineno = _genframe.f_code.co_filename, _genframe.f_lineno
+ base = "<%d-codegen " % self._compilecounter
+ self.__class__._compilecounter += 1
+ if not filename:
+ filename = base + '%s:%d>' % (fn, lineno)
+ else:
+ filename = base + '%r %s:%d>' % (filename, fn, lineno)
+ source = "\n".join(self.lines) + '\n'
+ try:
+ co = cpy_compile(source, filename, mode, flag)
+ except SyntaxError:
+ ex = sys.exc_info()[1]
+ # re-represent syntax errors from parsing python strings
+ msglines = self.lines[:ex.lineno]
+ if ex.offset:
+ msglines.append(" "*ex.offset + '^')
+ msglines.append("(code was compiled probably from here: %s)" % filename)
+ newex = SyntaxError('\n'.join(msglines))
+ newex.offset = ex.offset
+ newex.lineno = ex.lineno
+ newex.text = ex.text
+ raise newex
+ else:
+ if flag & _AST_FLAG:
+ return co
+ lines = [(x + "\n") for x in self.lines]
+ if sys.version_info[0] >= 3:
+ # XXX py3's inspect.getsourcefile() checks for a module
+ # and a pep302 __loader__ ... we don't have a module
+ # at code compile-time so we need to fake it here
+ m = ModuleType("_pycodecompile_pseudo_module")
+ py.std.inspect.modulesbyfile[filename] = None
+ py.std.sys.modules[None] = m
+ m.__loader__ = 1
+ py.std.linecache.cache[filename] = (1, None, lines, filename)
+ return co
+
+#
+# public API shortcut functions
+#
+
+def compile_(source, filename=None, mode='exec', flags=
+ generators.compiler_flag, dont_inherit=0):
+ """ compile the given source to a raw code object,
+ and maintain an internal cache which allows later
+ retrieval of the source code for the code object
+ and any recursively created code objects.
+ """
+ if _ast is not None and isinstance(source, _ast.AST):
+ # XXX should Source support having AST?
+ return cpy_compile(source, filename, mode, flags, dont_inherit)
+ _genframe = sys._getframe(1) # the caller
+ s = Source(source)
+ co = s.compile(filename, mode, flags, _genframe=_genframe)
+ return co
+
+
+def getfslineno(obj):
+ """ Return source location (path, lineno) for the given object.
+ If the source cannot be determined return ("", -1)
+ """
+ try:
+ code = py.code.Code(obj)
+ except TypeError:
+ try:
+ fn = (py.std.inspect.getsourcefile(obj) or
+ py.std.inspect.getfile(obj))
+ except TypeError:
+ return "", -1
+
+ fspath = fn and py.path.local(fn) or None
+ lineno = -1
+ if fspath:
+ try:
+ _, lineno = findsource(obj)
+ except IOError:
+ pass
+ else:
+ fspath = code.path
+ lineno = code.firstlineno
+ assert isinstance(lineno, int)
+ return fspath, lineno
+
+#
+# helper functions
+#
+
+def findsource(obj):
+ try:
+ sourcelines, lineno = py.std.inspect.findsource(obj)
+ except py.builtin._sysex:
+ raise
+ except:
+ return None, -1
+ source = Source()
+ source.lines = [line.rstrip() for line in sourcelines]
+ return source, lineno
+
+def getsource(obj, **kwargs):
+ obj = py.code.getrawcode(obj)
+ try:
+ strsrc = inspect.getsource(obj)
+ except IndentationError:
+ strsrc = "\"Buggy python version consider upgrading, cannot get source\""
+ assert isinstance(strsrc, str)
+ return Source(strsrc, **kwargs)
+
+def deindent(lines, offset=None):
+ if offset is None:
+ for line in lines:
+ line = line.expandtabs()
+ s = line.lstrip()
+ if s:
+ offset = len(line)-len(s)
+ break
+ else:
+ offset = 0
+ if offset == 0:
+ return list(lines)
+ newlines = []
+ def readline_generator(lines):
+ for line in lines:
+ yield line + '\n'
+ while True:
+ yield ''
+
+ it = readline_generator(lines)
+
+ try:
+ for _, _, (sline, _), (eline, _), _ in tokenize.generate_tokens(lambda: next(it)):
+ if sline > len(lines):
+ break # End of input reached
+ if sline > len(newlines):
+ line = lines[sline - 1].expandtabs()
+ if line.lstrip() and line[:offset].isspace():
+ line = line[offset:] # Deindent
+ newlines.append(line)
+
+ for i in range(sline, eline):
+ # Don't deindent continuing lines of
+ # multiline tokens (i.e. multiline strings)
+ newlines.append(lines[i])
+ except (IndentationError, tokenize.TokenError):
+ pass
+ # Add any lines we didn't see. E.g. if an exception was raised.
+ newlines.extend(lines[len(newlines):])
+ return newlines
+
+
+def get_statement_startend2(lineno, node):
+ import ast
+ # flatten all statements and except handlers into one lineno-list
+ # AST's line numbers start indexing at 1
+ l = []
+ for x in ast.walk(node):
+ if isinstance(x, _ast.stmt) or isinstance(x, _ast.ExceptHandler):
+ l.append(x.lineno - 1)
+ for name in "finalbody", "orelse":
+ val = getattr(x, name, None)
+ if val:
+ # treat the finally/orelse part as its own statement
+ l.append(val[0].lineno - 1 - 1)
+ l.sort()
+ insert_index = bisect_right(l, lineno)
+ start = l[insert_index - 1]
+ if insert_index >= len(l):
+ end = None
+ else:
+ end = l[insert_index]
+ return start, end
+
+
+def getstatementrange_ast(lineno, source, assertion=False, astnode=None):
+ if astnode is None:
+ content = str(source)
+ if sys.version_info < (2,7):
+ content += "\n"
+ try:
+ astnode = compile(content, "source", "exec", 1024) # 1024 for AST
+ except ValueError:
+ start, end = getstatementrange_old(lineno, source, assertion)
+ return None, start, end
+ start, end = get_statement_startend2(lineno, astnode)
+ # we need to correct the end:
+ # - ast-parsing strips comments
+ # - there might be empty lines
+ # - we might have lesser indented code blocks at the end
+ if end is None:
+ end = len(source.lines)
+
+ if end > start + 1:
+ # make sure we don't span differently indented code blocks
+ # by using the BlockFinder helper used which inspect.getsource() uses itself
+ block_finder = inspect.BlockFinder()
+ # if we start with an indented line, put blockfinder to "started" mode
+ block_finder.started = source.lines[start][0].isspace()
+ it = ((x + "\n") for x in source.lines[start:end])
+ try:
+ for tok in tokenize.generate_tokens(lambda: next(it)):
+ block_finder.tokeneater(*tok)
+ except (inspect.EndOfBlock, IndentationError):
+ end = block_finder.last + start
+ except Exception:
+ pass
+
+ # the end might still point to a comment or empty line, correct it
+ while end:
+ line = source.lines[end - 1].lstrip()
+ if line.startswith("#") or not line:
+ end -= 1
+ else:
+ break
+ return astnode, start, end
+
+
+def getstatementrange_old(lineno, source, assertion=False):
+ """ return (start, end) tuple which spans the minimal
+ statement region which containing the given lineno.
+ raise an IndexError if no such statementrange can be found.
+ """
+ # XXX this logic is only used on python2.4 and below
+ # 1. find the start of the statement
+ from codeop import compile_command
+ for start in range(lineno, -1, -1):
+ if assertion:
+ line = source.lines[start]
+ # the following lines are not fully tested, change with care
+ if 'super' in line and 'self' in line and '__init__' in line:
+ raise IndexError("likely a subclass")
+ if "assert" not in line and "raise" not in line:
+ continue
+ trylines = source.lines[start:lineno+1]
+ # quick hack to prepare parsing an indented line with
+ # compile_command() (which errors on "return" outside defs)
+ trylines.insert(0, 'def xxx():')
+ trysource = '\n '.join(trylines)
+ # ^ space here
+ try:
+ compile_command(trysource)
+ except (SyntaxError, OverflowError, ValueError):
+ continue
+
+ # 2. find the end of the statement
+ for end in range(lineno+1, len(source)+1):
+ trysource = source[start:end]
+ if trysource.isparseable():
+ return start, end
+ raise SyntaxError("no valid source range around line %d " % (lineno,))
+
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_error.py b/tests/wpt/web-platform-tests/tools/py/py/_error.py
new file mode 100644
index 00000000000..550fb521a04
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_error.py
@@ -0,0 +1,88 @@
+"""
+create errno-specific classes for IO or os calls.
+
+"""
+import sys, os, errno
+
+class Error(EnvironmentError):
+ def __repr__(self):
+ return "%s.%s %r: %s " %(self.__class__.__module__,
+ self.__class__.__name__,
+ self.__class__.__doc__,
+ " ".join(map(str, self.args)),
+ #repr(self.args)
+ )
+
+ def __str__(self):
+ s = "[%s]: %s" %(self.__class__.__doc__,
+ " ".join(map(str, self.args)),
+ )
+ return s
+
+_winerrnomap = {
+ 2: errno.ENOENT,
+ 3: errno.ENOENT,
+ 17: errno.EEXIST,
+ 13: errno.EBUSY, # empty cd drive, but ENOMEDIUM seems unavailiable
+ 22: errno.ENOTDIR,
+ 20: errno.ENOTDIR,
+ 267: errno.ENOTDIR,
+ 5: errno.EACCES, # anything better?
+}
+
+class ErrorMaker(object):
+ """ lazily provides Exception classes for each possible POSIX errno
+ (as defined per the 'errno' module). All such instances
+ subclass EnvironmentError.
+ """
+ Error = Error
+ _errno2class = {}
+
+ def __getattr__(self, name):
+ if name[0] == "_":
+ raise AttributeError(name)
+ eno = getattr(errno, name)
+ cls = self._geterrnoclass(eno)
+ setattr(self, name, cls)
+ return cls
+
+ def _geterrnoclass(self, eno):
+ try:
+ return self._errno2class[eno]
+ except KeyError:
+ clsname = errno.errorcode.get(eno, "UnknownErrno%d" %(eno,))
+ errorcls = type(Error)(clsname, (Error,),
+ {'__module__':'py.error',
+ '__doc__': os.strerror(eno)})
+ self._errno2class[eno] = errorcls
+ return errorcls
+
+ def checked_call(self, func, *args, **kwargs):
+ """ call a function and raise an errno-exception if applicable. """
+ __tracebackhide__ = True
+ try:
+ return func(*args, **kwargs)
+ except self.Error:
+ raise
+ except (OSError, EnvironmentError):
+ cls, value, tb = sys.exc_info()
+ if not hasattr(value, 'errno'):
+ raise
+ __tracebackhide__ = False
+ errno = value.errno
+ try:
+ if not isinstance(value, WindowsError):
+ raise NameError
+ except NameError:
+ # we are not on Windows, or we got a proper OSError
+ cls = self._geterrnoclass(errno)
+ else:
+ try:
+ cls = self._geterrnoclass(_winerrnomap[errno])
+ except KeyError:
+ raise value
+ raise cls("%s%r" % (func.__name__, args))
+ __tracebackhide__ = True
+
+
+error = ErrorMaker()
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_iniconfig.py b/tests/wpt/web-platform-tests/tools/py/py/_iniconfig.py
new file mode 100644
index 00000000000..92b50bd853a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_iniconfig.py
@@ -0,0 +1,162 @@
+""" brain-dead simple parser for ini-style files.
+(C) Ronny Pfannschmidt, Holger Krekel -- MIT licensed
+"""
+__version__ = "0.2.dev2"
+
+__all__ = ['IniConfig', 'ParseError']
+
+COMMENTCHARS = "#;"
+
+class ParseError(Exception):
+ def __init__(self, path, lineno, msg):
+ Exception.__init__(self, path, lineno, msg)
+ self.path = path
+ self.lineno = lineno
+ self.msg = msg
+
+ def __str__(self):
+ return "%s:%s: %s" %(self.path, self.lineno+1, self.msg)
+
+class SectionWrapper(object):
+ def __init__(self, config, name):
+ self.config = config
+ self.name = name
+
+ def lineof(self, name):
+ return self.config.lineof(self.name, name)
+
+ def get(self, key, default=None, convert=str):
+ return self.config.get(self.name, key, convert=convert, default=default)
+
+ def __getitem__(self, key):
+ return self.config.sections[self.name][key]
+
+ def __iter__(self):
+ section = self.config.sections.get(self.name, [])
+ def lineof(key):
+ return self.config.lineof(self.name, key)
+ for name in sorted(section, key=lineof):
+ yield name
+
+ def items(self):
+ for name in self:
+ yield name, self[name]
+
+
+class IniConfig(object):
+ def __init__(self, path, data=None):
+ self.path = str(path) # convenience
+ if data is None:
+ f = open(self.path)
+ try:
+ tokens = self._parse(iter(f))
+ finally:
+ f.close()
+ else:
+ tokens = self._parse(data.splitlines(True))
+
+ self._sources = {}
+ self.sections = {}
+
+ for lineno, section, name, value in tokens:
+ if section is None:
+ self._raise(lineno, 'no section header defined')
+ self._sources[section, name] = lineno
+ if name is None:
+ if section in self.sections:
+ self._raise(lineno, 'duplicate section %r'%(section, ))
+ self.sections[section] = {}
+ else:
+ if name in self.sections[section]:
+ self._raise(lineno, 'duplicate name %r'%(name, ))
+ self.sections[section][name] = value
+
+ def _raise(self, lineno, msg):
+ raise ParseError(self.path, lineno, msg)
+
+ def _parse(self, line_iter):
+ result = []
+ section = None
+ for lineno, line in enumerate(line_iter):
+ name, data = self._parseline(line, lineno)
+ # new value
+ if name is not None and data is not None:
+ result.append((lineno, section, name, data))
+ # new section
+ elif name is not None and data is None:
+ if not name:
+ self._raise(lineno, 'empty section name')
+ section = name
+ result.append((lineno, section, None, None))
+ # continuation
+ elif name is None and data is not None:
+ if not result:
+ self._raise(lineno, 'unexpected value continuation')
+ last = result.pop()
+ last_name, last_data = last[-2:]
+ if last_name is None:
+ self._raise(lineno, 'unexpected value continuation')
+
+ if last_data:
+ data = '%s\n%s' % (last_data, data)
+ result.append(last[:-1] + (data,))
+ return result
+
+ def _parseline(self, line, lineno):
+ # blank lines
+ if iscommentline(line):
+ line = ""
+ else:
+ line = line.rstrip()
+ if not line:
+ return None, None
+ # section
+ if line[0] == '[':
+ realline = line
+ for c in COMMENTCHARS:
+ line = line.split(c)[0].rstrip()
+ if line[-1] == "]":
+ return line[1:-1], None
+ return None, realline.strip()
+ # value
+ elif not line[0].isspace():
+ try:
+ name, value = line.split('=', 1)
+ if ":" in name:
+ raise ValueError()
+ except ValueError:
+ try:
+ name, value = line.split(":", 1)
+ except ValueError:
+ self._raise(lineno, 'unexpected line: %r' % line)
+ return name.strip(), value.strip()
+ # continuation
+ else:
+ return None, line.strip()
+
+ def lineof(self, section, name=None):
+ lineno = self._sources.get((section, name))
+ if lineno is not None:
+ return lineno + 1
+
+ def get(self, section, name, default=None, convert=str):
+ try:
+ return convert(self.sections[section][name])
+ except KeyError:
+ return default
+
+ def __getitem__(self, name):
+ if name not in self.sections:
+ raise KeyError(name)
+ return SectionWrapper(self, name)
+
+ def __iter__(self):
+ for name in sorted(self.sections, key=self.lineof):
+ yield SectionWrapper(self, name)
+
+ def __contains__(self, arg):
+ return arg in self.sections
+
+def iscommentline(line):
+ c = line.lstrip()[:1]
+ return c in COMMENTCHARS
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_io/__init__.py b/tests/wpt/web-platform-tests/tools/py/py/_io/__init__.py
new file mode 100644
index 00000000000..835f01f3ab9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_io/__init__.py
@@ -0,0 +1 @@
+""" input/output helping """
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_io/capture.py b/tests/wpt/web-platform-tests/tools/py/py/_io/capture.py
new file mode 100644
index 00000000000..bc157ed978f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_io/capture.py
@@ -0,0 +1,371 @@
+import os
+import sys
+import py
+import tempfile
+
+try:
+ from io import StringIO
+except ImportError:
+ from StringIO import StringIO
+
+if sys.version_info < (3,0):
+ class TextIO(StringIO):
+ def write(self, data):
+ if not isinstance(data, unicode):
+ data = unicode(data, getattr(self, '_encoding', 'UTF-8'), 'replace')
+ StringIO.write(self, data)
+else:
+ TextIO = StringIO
+
+try:
+ from io import BytesIO
+except ImportError:
+ class BytesIO(StringIO):
+ def write(self, data):
+ if isinstance(data, unicode):
+ raise TypeError("not a byte value: %r" %(data,))
+ StringIO.write(self, data)
+
+patchsysdict = {0: 'stdin', 1: 'stdout', 2: 'stderr'}
+
+class FDCapture:
+ """ Capture IO to/from a given os-level filedescriptor. """
+
+ def __init__(self, targetfd, tmpfile=None, now=True, patchsys=False):
+ """ save targetfd descriptor, and open a new
+ temporary file there. If no tmpfile is
+ specified a tempfile.Tempfile() will be opened
+ in text mode.
+ """
+ self.targetfd = targetfd
+ if tmpfile is None and targetfd != 0:
+ f = tempfile.TemporaryFile('wb+')
+ tmpfile = dupfile(f, encoding="UTF-8")
+ f.close()
+ self.tmpfile = tmpfile
+ self._savefd = os.dup(self.targetfd)
+ if patchsys:
+ self._oldsys = getattr(sys, patchsysdict[targetfd])
+ if now:
+ self.start()
+
+ def start(self):
+ try:
+ os.fstat(self._savefd)
+ except OSError:
+ raise ValueError("saved filedescriptor not valid, "
+ "did you call start() twice?")
+ if self.targetfd == 0 and not self.tmpfile:
+ fd = os.open(devnullpath, os.O_RDONLY)
+ os.dup2(fd, 0)
+ os.close(fd)
+ if hasattr(self, '_oldsys'):
+ setattr(sys, patchsysdict[self.targetfd], DontReadFromInput())
+ else:
+ os.dup2(self.tmpfile.fileno(), self.targetfd)
+ if hasattr(self, '_oldsys'):
+ setattr(sys, patchsysdict[self.targetfd], self.tmpfile)
+
+ def done(self):
+ """ unpatch and clean up, returns the self.tmpfile (file object)
+ """
+ os.dup2(self._savefd, self.targetfd)
+ os.close(self._savefd)
+ if self.targetfd != 0:
+ self.tmpfile.seek(0)
+ if hasattr(self, '_oldsys'):
+ setattr(sys, patchsysdict[self.targetfd], self._oldsys)
+ return self.tmpfile
+
+ def writeorg(self, data):
+ """ write a string to the original file descriptor
+ """
+ tempfp = tempfile.TemporaryFile()
+ try:
+ os.dup2(self._savefd, tempfp.fileno())
+ tempfp.write(data)
+ finally:
+ tempfp.close()
+
+
+def dupfile(f, mode=None, buffering=0, raising=False, encoding=None):
+ """ return a new open file object that's a duplicate of f
+
+ mode is duplicated if not given, 'buffering' controls
+ buffer size (defaulting to no buffering) and 'raising'
+ defines whether an exception is raised when an incompatible
+ file object is passed in (if raising is False, the file
+ object itself will be returned)
+ """
+ try:
+ fd = f.fileno()
+ mode = mode or f.mode
+ except AttributeError:
+ if raising:
+ raise
+ return f
+ newfd = os.dup(fd)
+ if sys.version_info >= (3,0):
+ if encoding is not None:
+ mode = mode.replace("b", "")
+ buffering = True
+ return os.fdopen(newfd, mode, buffering, encoding, closefd=True)
+ else:
+ f = os.fdopen(newfd, mode, buffering)
+ if encoding is not None:
+ return EncodedFile(f, encoding)
+ return f
+
+class EncodedFile(object):
+ def __init__(self, _stream, encoding):
+ self._stream = _stream
+ self.encoding = encoding
+
+ def write(self, obj):
+ if isinstance(obj, unicode):
+ obj = obj.encode(self.encoding)
+ elif isinstance(obj, str):
+ pass
+ else:
+ obj = str(obj)
+ self._stream.write(obj)
+
+ def writelines(self, linelist):
+ data = ''.join(linelist)
+ self.write(data)
+
+ def __getattr__(self, name):
+ return getattr(self._stream, name)
+
+class Capture(object):
+ def call(cls, func, *args, **kwargs):
+ """ return a (res, out, err) tuple where
+ out and err represent the output/error output
+ during function execution.
+ call the given function with args/kwargs
+ and capture output/error during its execution.
+ """
+ so = cls()
+ try:
+ res = func(*args, **kwargs)
+ finally:
+ out, err = so.reset()
+ return res, out, err
+ call = classmethod(call)
+
+ def reset(self):
+ """ reset sys.stdout/stderr and return captured output as strings. """
+ if hasattr(self, '_reset'):
+ raise ValueError("was already reset")
+ self._reset = True
+ outfile, errfile = self.done(save=False)
+ out, err = "", ""
+ if outfile and not outfile.closed:
+ out = outfile.read()
+ outfile.close()
+ if errfile and errfile != outfile and not errfile.closed:
+ err = errfile.read()
+ errfile.close()
+ return out, err
+
+ def suspend(self):
+ """ return current snapshot captures, memorize tempfiles. """
+ outerr = self.readouterr()
+ outfile, errfile = self.done()
+ return outerr
+
+
+class StdCaptureFD(Capture):
+ """ This class allows to capture writes to FD1 and FD2
+ and may connect a NULL file to FD0 (and prevent
+ reads from sys.stdin). If any of the 0,1,2 file descriptors
+ is invalid it will not be captured.
+ """
+ def __init__(self, out=True, err=True, mixed=False,
+ in_=True, patchsys=True, now=True):
+ self._options = {
+ "out": out,
+ "err": err,
+ "mixed": mixed,
+ "in_": in_,
+ "patchsys": patchsys,
+ "now": now,
+ }
+ self._save()
+ if now:
+ self.startall()
+
+ def _save(self):
+ in_ = self._options['in_']
+ out = self._options['out']
+ err = self._options['err']
+ mixed = self._options['mixed']
+ patchsys = self._options['patchsys']
+ if in_:
+ try:
+ self.in_ = FDCapture(0, tmpfile=None, now=False,
+ patchsys=patchsys)
+ except OSError:
+ pass
+ if out:
+ tmpfile = None
+ if hasattr(out, 'write'):
+ tmpfile = out
+ try:
+ self.out = FDCapture(1, tmpfile=tmpfile,
+ now=False, patchsys=patchsys)
+ self._options['out'] = self.out.tmpfile
+ except OSError:
+ pass
+ if err:
+ if out and mixed:
+ tmpfile = self.out.tmpfile
+ elif hasattr(err, 'write'):
+ tmpfile = err
+ else:
+ tmpfile = None
+ try:
+ self.err = FDCapture(2, tmpfile=tmpfile,
+ now=False, patchsys=patchsys)
+ self._options['err'] = self.err.tmpfile
+ except OSError:
+ pass
+
+ def startall(self):
+ if hasattr(self, 'in_'):
+ self.in_.start()
+ if hasattr(self, 'out'):
+ self.out.start()
+ if hasattr(self, 'err'):
+ self.err.start()
+
+ def resume(self):
+ """ resume capturing with original temp files. """
+ self.startall()
+
+ def done(self, save=True):
+ """ return (outfile, errfile) and stop capturing. """
+ outfile = errfile = None
+ if hasattr(self, 'out') and not self.out.tmpfile.closed:
+ outfile = self.out.done()
+ if hasattr(self, 'err') and not self.err.tmpfile.closed:
+ errfile = self.err.done()
+ if hasattr(self, 'in_'):
+ tmpfile = self.in_.done()
+ if save:
+ self._save()
+ return outfile, errfile
+
+ def readouterr(self):
+ """ return snapshot value of stdout/stderr capturings. """
+ if hasattr(self, "out"):
+ out = self._readsnapshot(self.out.tmpfile)
+ else:
+ out = ""
+ if hasattr(self, "err"):
+ err = self._readsnapshot(self.err.tmpfile)
+ else:
+ err = ""
+ return [out, err]
+
+ def _readsnapshot(self, f):
+ f.seek(0)
+ res = f.read()
+ enc = getattr(f, "encoding", None)
+ if enc:
+ res = py.builtin._totext(res, enc, "replace")
+ f.truncate(0)
+ f.seek(0)
+ return res
+
+
+class StdCapture(Capture):
+ """ This class allows to capture writes to sys.stdout|stderr "in-memory"
+ and will raise errors on tries to read from sys.stdin. It only
+ modifies sys.stdout|stderr|stdin attributes and does not
+ touch underlying File Descriptors (use StdCaptureFD for that).
+ """
+ def __init__(self, out=True, err=True, in_=True, mixed=False, now=True):
+ self._oldout = sys.stdout
+ self._olderr = sys.stderr
+ self._oldin = sys.stdin
+ if out and not hasattr(out, 'file'):
+ out = TextIO()
+ self.out = out
+ if err:
+ if mixed:
+ err = out
+ elif not hasattr(err, 'write'):
+ err = TextIO()
+ self.err = err
+ self.in_ = in_
+ if now:
+ self.startall()
+
+ def startall(self):
+ if self.out:
+ sys.stdout = self.out
+ if self.err:
+ sys.stderr = self.err
+ if self.in_:
+ sys.stdin = self.in_ = DontReadFromInput()
+
+ def done(self, save=True):
+ """ return (outfile, errfile) and stop capturing. """
+ outfile = errfile = None
+ if self.out and not self.out.closed:
+ sys.stdout = self._oldout
+ outfile = self.out
+ outfile.seek(0)
+ if self.err and not self.err.closed:
+ sys.stderr = self._olderr
+ errfile = self.err
+ errfile.seek(0)
+ if self.in_:
+ sys.stdin = self._oldin
+ return outfile, errfile
+
+ def resume(self):
+ """ resume capturing with original temp files. """
+ self.startall()
+
+ def readouterr(self):
+ """ return snapshot value of stdout/stderr capturings. """
+ out = err = ""
+ if self.out:
+ out = self.out.getvalue()
+ self.out.truncate(0)
+ self.out.seek(0)
+ if self.err:
+ err = self.err.getvalue()
+ self.err.truncate(0)
+ self.err.seek(0)
+ return out, err
+
+class DontReadFromInput:
+ """Temporary stub class. Ideally when stdin is accessed, the
+ capturing should be turned off, with possibly all data captured
+ so far sent to the screen. This should be configurable, though,
+ because in automated test runs it is better to crash than
+ hang indefinitely.
+ """
+ def read(self, *args):
+ raise IOError("reading from stdin while output is captured")
+ readline = read
+ readlines = read
+ __iter__ = read
+
+ def fileno(self):
+ raise ValueError("redirected Stdin is pseudofile, has no fileno()")
+ def isatty(self):
+ return False
+ def close(self):
+ pass
+
+try:
+ devnullpath = os.devnull
+except AttributeError:
+ if os.name == 'nt':
+ devnullpath = 'NUL'
+ else:
+ devnullpath = '/dev/null'
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_io/saferepr.py b/tests/wpt/web-platform-tests/tools/py/py/_io/saferepr.py
new file mode 100644
index 00000000000..8518290efdd
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_io/saferepr.py
@@ -0,0 +1,71 @@
+import py
+import sys
+
+builtin_repr = repr
+
+reprlib = py.builtin._tryimport('repr', 'reprlib')
+
+class SafeRepr(reprlib.Repr):
+ """ subclass of repr.Repr that limits the resulting size of repr()
+ and includes information on exceptions raised during the call.
+ """
+ def repr(self, x):
+ return self._callhelper(reprlib.Repr.repr, self, x)
+
+ def repr_unicode(self, x, level):
+ # Strictly speaking wrong on narrow builds
+ def repr(u):
+ if "'" not in u:
+ return py.builtin._totext("'%s'") % u
+ elif '"' not in u:
+ return py.builtin._totext('"%s"') % u
+ else:
+ return py.builtin._totext("'%s'") % u.replace("'", r"\'")
+ s = repr(x[:self.maxstring])
+ if len(s) > self.maxstring:
+ i = max(0, (self.maxstring-3)//2)
+ j = max(0, self.maxstring-3-i)
+ s = repr(x[:i] + x[len(x)-j:])
+ s = s[:i] + '...' + s[len(s)-j:]
+ return s
+
+ def repr_instance(self, x, level):
+ return self._callhelper(builtin_repr, x)
+
+ def _callhelper(self, call, x, *args):
+ try:
+ # Try the vanilla repr and make sure that the result is a string
+ s = call(x, *args)
+ except py.builtin._sysex:
+ raise
+ except:
+ cls, e, tb = sys.exc_info()
+ exc_name = getattr(cls, '__name__', 'unknown')
+ try:
+ exc_info = str(e)
+ except py.builtin._sysex:
+ raise
+ except:
+ exc_info = 'unknown'
+ return '<[%s("%s") raised in repr()] %s object at 0x%x>' % (
+ exc_name, exc_info, x.__class__.__name__, id(x))
+ else:
+ if len(s) > self.maxsize:
+ i = max(0, (self.maxsize-3)//2)
+ j = max(0, self.maxsize-3-i)
+ s = s[:i] + '...' + s[len(s)-j:]
+ return s
+
+def saferepr(obj, maxsize=240):
+ """ return a size-limited safe repr-string for the given object.
+ Failing __repr__ functions of user instances will be represented
+ with a short exception info and 'saferepr' generally takes
+ care to never raise exceptions itself. This function is a wrapper
+ around the Repr/reprlib functionality of the standard 2.6 lib.
+ """
+ # review exception handling
+ srepr = SafeRepr()
+ srepr.maxstring = maxsize
+ srepr.maxsize = maxsize
+ srepr.maxother = 160
+ return srepr.repr(obj)
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_io/terminalwriter.py b/tests/wpt/web-platform-tests/tools/py/py/_io/terminalwriter.py
new file mode 100644
index 00000000000..cef1ff58097
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_io/terminalwriter.py
@@ -0,0 +1,348 @@
+"""
+
+Helper functions for writing to terminals and files.
+
+"""
+
+
+import sys, os
+import py
+py3k = sys.version_info[0] >= 3
+from py.builtin import text, bytes
+
+win32_and_ctypes = False
+colorama = None
+if sys.platform == "win32":
+ try:
+ import colorama
+ except ImportError:
+ try:
+ import ctypes
+ win32_and_ctypes = True
+ except ImportError:
+ pass
+
+
+def _getdimensions():
+ import termios,fcntl,struct
+ call = fcntl.ioctl(1,termios.TIOCGWINSZ,"\000"*8)
+ height,width = struct.unpack( "hhhh", call ) [:2]
+ return height, width
+
+
+def get_terminal_width():
+ height = width = 0
+ try:
+ height, width = _getdimensions()
+ except py.builtin._sysex:
+ raise
+ except:
+ # pass to fallback below
+ pass
+
+ if width == 0:
+ # FALLBACK:
+ # * some exception happened
+ # * or this is emacs terminal which reports (0,0)
+ width = int(os.environ.get('COLUMNS', 80))
+
+ # XXX the windows getdimensions may be bogus, let's sanify a bit
+ if width < 40:
+ width = 80
+ return width
+
+terminal_width = get_terminal_width()
+
+# XXX unify with _escaped func below
+def ansi_print(text, esc, file=None, newline=True, flush=False):
+ if file is None:
+ file = sys.stderr
+ text = text.rstrip()
+ if esc and not isinstance(esc, tuple):
+ esc = (esc,)
+ if esc and sys.platform != "win32" and file.isatty():
+ text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
+ text +
+ '\x1b[0m') # ANSI color code "reset"
+ if newline:
+ text += '\n'
+
+ if esc and win32_and_ctypes and file.isatty():
+ if 1 in esc:
+ bold = True
+ esc = tuple([x for x in esc if x != 1])
+ else:
+ bold = False
+ esctable = {() : FOREGROUND_WHITE, # normal
+ (31,): FOREGROUND_RED, # red
+ (32,): FOREGROUND_GREEN, # green
+ (33,): FOREGROUND_GREEN|FOREGROUND_RED, # yellow
+ (34,): FOREGROUND_BLUE, # blue
+ (35,): FOREGROUND_BLUE|FOREGROUND_RED, # purple
+ (36,): FOREGROUND_BLUE|FOREGROUND_GREEN, # cyan
+ (37,): FOREGROUND_WHITE, # white
+ (39,): FOREGROUND_WHITE, # reset
+ }
+ attr = esctable.get(esc, FOREGROUND_WHITE)
+ if bold:
+ attr |= FOREGROUND_INTENSITY
+ STD_OUTPUT_HANDLE = -11
+ STD_ERROR_HANDLE = -12
+ if file is sys.stderr:
+ handle = GetStdHandle(STD_ERROR_HANDLE)
+ else:
+ handle = GetStdHandle(STD_OUTPUT_HANDLE)
+ oldcolors = GetConsoleInfo(handle).wAttributes
+ attr |= (oldcolors & 0x0f0)
+ SetConsoleTextAttribute(handle, attr)
+ while len(text) > 32768:
+ file.write(text[:32768])
+ text = text[32768:]
+ if text:
+ file.write(text)
+ SetConsoleTextAttribute(handle, oldcolors)
+ else:
+ file.write(text)
+
+ if flush:
+ file.flush()
+
+def should_do_markup(file):
+ if os.environ.get('PY_COLORS') == '1':
+ return True
+ if os.environ.get('PY_COLORS') == '0':
+ return False
+ return hasattr(file, 'isatty') and file.isatty() \
+ and os.environ.get('TERM') != 'dumb' \
+ and not (sys.platform.startswith('java') and os._name == 'nt')
+
+class TerminalWriter(object):
+ _esctable = dict(black=30, red=31, green=32, yellow=33,
+ blue=34, purple=35, cyan=36, white=37,
+ Black=40, Red=41, Green=42, Yellow=43,
+ Blue=44, Purple=45, Cyan=46, White=47,
+ bold=1, light=2, blink=5, invert=7)
+
+ # XXX deprecate stringio argument
+ def __init__(self, file=None, stringio=False, encoding=None):
+ if file is None:
+ if stringio:
+ self.stringio = file = py.io.TextIO()
+ else:
+ file = py.std.sys.stdout
+ elif py.builtin.callable(file) and not (
+ hasattr(file, "write") and hasattr(file, "flush")):
+ file = WriteFile(file, encoding=encoding)
+ if hasattr(file, "isatty") and file.isatty() and colorama:
+ file = colorama.AnsiToWin32(file).stream
+ self.encoding = encoding or getattr(file, 'encoding', "utf-8")
+ self._file = file
+ self.fullwidth = get_terminal_width()
+ self.hasmarkup = should_do_markup(file)
+ self._lastlen = 0
+
+ def _escaped(self, text, esc):
+ if esc and self.hasmarkup:
+ text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
+ text +'\x1b[0m')
+ return text
+
+ def markup(self, text, **kw):
+ esc = []
+ for name in kw:
+ if name not in self._esctable:
+ raise ValueError("unknown markup: %r" %(name,))
+ if kw[name]:
+ esc.append(self._esctable[name])
+ return self._escaped(text, tuple(esc))
+
+ def sep(self, sepchar, title=None, fullwidth=None, **kw):
+ if fullwidth is None:
+ fullwidth = self.fullwidth
+ # the goal is to have the line be as long as possible
+ # under the condition that len(line) <= fullwidth
+ if sys.platform == "win32":
+ # if we print in the last column on windows we are on a
+ # new line but there is no way to verify/neutralize this
+ # (we may not know the exact line width)
+ # so let's be defensive to avoid empty lines in the output
+ fullwidth -= 1
+ if title is not None:
+ # we want 2 + 2*len(fill) + len(title) <= fullwidth
+ # i.e. 2 + 2*len(sepchar)*N + len(title) <= fullwidth
+ # 2*len(sepchar)*N <= fullwidth - len(title) - 2
+ # N <= (fullwidth - len(title) - 2) // (2*len(sepchar))
+ N = (fullwidth - len(title) - 2) // (2*len(sepchar))
+ fill = sepchar * N
+ line = "%s %s %s" % (fill, title, fill)
+ else:
+ # we want len(sepchar)*N <= fullwidth
+ # i.e. N <= fullwidth // len(sepchar)
+ line = sepchar * (fullwidth // len(sepchar))
+ # in some situations there is room for an extra sepchar at the right,
+ # in particular if we consider that with a sepchar like "_ " the
+ # trailing space is not important at the end of the line
+ if len(line) + len(sepchar.rstrip()) <= fullwidth:
+ line += sepchar.rstrip()
+
+ self.line(line, **kw)
+
+ def write(self, msg, **kw):
+ if msg:
+ if not isinstance(msg, (bytes, text)):
+ msg = text(msg)
+ if self.hasmarkup and kw:
+ markupmsg = self.markup(msg, **kw)
+ else:
+ markupmsg = msg
+ write_out(self._file, markupmsg)
+
+ def line(self, s='', **kw):
+ self.write(s, **kw)
+ self._checkfill(s)
+ self.write('\n')
+
+ def reline(self, line, **kw):
+ if not self.hasmarkup:
+ raise ValueError("cannot use rewrite-line without terminal")
+ self.write(line, **kw)
+ self._checkfill(line)
+ self.write('\r')
+ self._lastlen = len(line)
+
+ def _checkfill(self, line):
+ diff2last = self._lastlen - len(line)
+ if diff2last > 0:
+ self.write(" " * diff2last)
+
+class Win32ConsoleWriter(TerminalWriter):
+ def write(self, msg, **kw):
+ if msg:
+ if not isinstance(msg, (bytes, text)):
+ msg = text(msg)
+ oldcolors = None
+ if self.hasmarkup and kw:
+ handle = GetStdHandle(STD_OUTPUT_HANDLE)
+ oldcolors = GetConsoleInfo(handle).wAttributes
+ default_bg = oldcolors & 0x00F0
+ attr = default_bg
+ if kw.pop('bold', False):
+ attr |= FOREGROUND_INTENSITY
+
+ if kw.pop('red', False):
+ attr |= FOREGROUND_RED
+ elif kw.pop('blue', False):
+ attr |= FOREGROUND_BLUE
+ elif kw.pop('green', False):
+ attr |= FOREGROUND_GREEN
+ elif kw.pop('yellow', False):
+ attr |= FOREGROUND_GREEN|FOREGROUND_RED
+ else:
+ attr |= oldcolors & 0x0007
+
+ SetConsoleTextAttribute(handle, attr)
+ write_out(self._file, msg)
+ if oldcolors:
+ SetConsoleTextAttribute(handle, oldcolors)
+
+class WriteFile(object):
+ def __init__(self, writemethod, encoding=None):
+ self.encoding = encoding
+ self._writemethod = writemethod
+
+ def write(self, data):
+ if self.encoding:
+ data = data.encode(self.encoding, "replace")
+ self._writemethod(data)
+
+ def flush(self):
+ return
+
+
+if win32_and_ctypes:
+ TerminalWriter = Win32ConsoleWriter
+ import ctypes
+ from ctypes import wintypes
+
+ # ctypes access to the Windows console
+ STD_OUTPUT_HANDLE = -11
+ STD_ERROR_HANDLE = -12
+ FOREGROUND_BLACK = 0x0000 # black text
+ FOREGROUND_BLUE = 0x0001 # text color contains blue.
+ FOREGROUND_GREEN = 0x0002 # text color contains green.
+ FOREGROUND_RED = 0x0004 # text color contains red.
+ FOREGROUND_WHITE = 0x0007
+ FOREGROUND_INTENSITY = 0x0008 # text color is intensified.
+ BACKGROUND_BLACK = 0x0000 # background color black
+ BACKGROUND_BLUE = 0x0010 # background color contains blue.
+ BACKGROUND_GREEN = 0x0020 # background color contains green.
+ BACKGROUND_RED = 0x0040 # background color contains red.
+ BACKGROUND_WHITE = 0x0070
+ BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
+
+ SHORT = ctypes.c_short
+ class COORD(ctypes.Structure):
+ _fields_ = [('X', SHORT),
+ ('Y', SHORT)]
+ class SMALL_RECT(ctypes.Structure):
+ _fields_ = [('Left', SHORT),
+ ('Top', SHORT),
+ ('Right', SHORT),
+ ('Bottom', SHORT)]
+ class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
+ _fields_ = [('dwSize', COORD),
+ ('dwCursorPosition', COORD),
+ ('wAttributes', wintypes.WORD),
+ ('srWindow', SMALL_RECT),
+ ('dwMaximumWindowSize', COORD)]
+
+ _GetStdHandle = ctypes.windll.kernel32.GetStdHandle
+ _GetStdHandle.argtypes = [wintypes.DWORD]
+ _GetStdHandle.restype = wintypes.HANDLE
+ def GetStdHandle(kind):
+ return _GetStdHandle(kind)
+
+ SetConsoleTextAttribute = ctypes.windll.kernel32.SetConsoleTextAttribute
+ SetConsoleTextAttribute.argtypes = [wintypes.HANDLE, wintypes.WORD]
+ SetConsoleTextAttribute.restype = wintypes.BOOL
+
+ _GetConsoleScreenBufferInfo = \
+ ctypes.windll.kernel32.GetConsoleScreenBufferInfo
+ _GetConsoleScreenBufferInfo.argtypes = [wintypes.HANDLE,
+ ctypes.POINTER(CONSOLE_SCREEN_BUFFER_INFO)]
+ _GetConsoleScreenBufferInfo.restype = wintypes.BOOL
+ def GetConsoleInfo(handle):
+ info = CONSOLE_SCREEN_BUFFER_INFO()
+ _GetConsoleScreenBufferInfo(handle, ctypes.byref(info))
+ return info
+
+ def _getdimensions():
+ handle = GetStdHandle(STD_OUTPUT_HANDLE)
+ info = GetConsoleInfo(handle)
+ # Substract one from the width, otherwise the cursor wraps
+ # and the ending \n causes an empty line to display.
+ return info.dwSize.Y, info.dwSize.X - 1
+
+def write_out(fil, msg):
+ # XXX sometimes "msg" is of type bytes, sometimes text which
+ # complicates the situation. Should we try to enforce unicode?
+ try:
+ # on py27 and above writing out to sys.stdout with an encoding
+ # should usually work for unicode messages (if the encoding is
+ # capable of it)
+ fil.write(msg)
+ except UnicodeEncodeError:
+ # on py26 it might not work because stdout expects bytes
+ if fil.encoding:
+ try:
+ fil.write(msg.encode(fil.encoding))
+ except UnicodeEncodeError:
+ # it might still fail if the encoding is not capable
+ pass
+ else:
+ fil.flush()
+ return
+ # fallback: escape all unicode characters
+ msg = msg.encode("unicode-escape").decode("ascii")
+ fil.write(msg)
+ fil.flush()
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_log/__init__.py b/tests/wpt/web-platform-tests/tools/py/py/_log/__init__.py
new file mode 100644
index 00000000000..fad62e960d4
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_log/__init__.py
@@ -0,0 +1,2 @@
+""" logging API ('producers' and 'consumers' connected via keywords) """
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_log/log.py b/tests/wpt/web-platform-tests/tools/py/py/_log/log.py
new file mode 100644
index 00000000000..ce47e8c754a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_log/log.py
@@ -0,0 +1,186 @@
+"""
+basic logging functionality based on a producer/consumer scheme.
+
+XXX implement this API: (maybe put it into slogger.py?)
+
+ log = Logger(
+ info=py.log.STDOUT,
+ debug=py.log.STDOUT,
+ command=None)
+ log.info("hello", "world")
+ log.command("hello", "world")
+
+ log = Logger(info=Logger(something=...),
+ debug=py.log.STDOUT,
+ command=None)
+"""
+import py, sys
+
+class Message(object):
+ def __init__(self, keywords, args):
+ self.keywords = keywords
+ self.args = args
+
+ def content(self):
+ return " ".join(map(str, self.args))
+
+ def prefix(self):
+ return "[%s] " % (":".join(self.keywords))
+
+ def __str__(self):
+ return self.prefix() + self.content()
+
+
+class Producer(object):
+ """ (deprecated) Log producer API which sends messages to be logged
+ to a 'consumer' object, which then prints them to stdout,
+ stderr, files, etc. Used extensively by PyPy-1.1.
+ """
+
+ Message = Message # to allow later customization
+ keywords2consumer = {}
+
+ def __init__(self, keywords, keywordmapper=None, **kw):
+ if hasattr(keywords, 'split'):
+ keywords = tuple(keywords.split())
+ self._keywords = keywords
+ if keywordmapper is None:
+ keywordmapper = default_keywordmapper
+ self._keywordmapper = keywordmapper
+
+ def __repr__(self):
+ return "<py.log.Producer %s>" % ":".join(self._keywords)
+
+ def __getattr__(self, name):
+ if '_' in name:
+ raise AttributeError(name)
+ producer = self.__class__(self._keywords + (name,))
+ setattr(self, name, producer)
+ return producer
+
+ def __call__(self, *args):
+ """ write a message to the appropriate consumer(s) """
+ func = self._keywordmapper.getconsumer(self._keywords)
+ if func is not None:
+ func(self.Message(self._keywords, args))
+
+class KeywordMapper:
+ def __init__(self):
+ self.keywords2consumer = {}
+
+ def getstate(self):
+ return self.keywords2consumer.copy()
+ def setstate(self, state):
+ self.keywords2consumer.clear()
+ self.keywords2consumer.update(state)
+
+ def getconsumer(self, keywords):
+ """ return a consumer matching the given keywords.
+
+ tries to find the most suitable consumer by walking, starting from
+ the back, the list of keywords, the first consumer matching a
+ keyword is returned (falling back to py.log.default)
+ """
+ for i in range(len(keywords), 0, -1):
+ try:
+ return self.keywords2consumer[keywords[:i]]
+ except KeyError:
+ continue
+ return self.keywords2consumer.get('default', default_consumer)
+
+ def setconsumer(self, keywords, consumer):
+ """ set a consumer for a set of keywords. """
+ # normalize to tuples
+ if isinstance(keywords, str):
+ keywords = tuple(filter(None, keywords.split()))
+ elif hasattr(keywords, '_keywords'):
+ keywords = keywords._keywords
+ elif not isinstance(keywords, tuple):
+ raise TypeError("key %r is not a string or tuple" % (keywords,))
+ if consumer is not None and not py.builtin.callable(consumer):
+ if not hasattr(consumer, 'write'):
+ raise TypeError(
+ "%r should be None, callable or file-like" % (consumer,))
+ consumer = File(consumer)
+ self.keywords2consumer[keywords] = consumer
+
+def default_consumer(msg):
+ """ the default consumer, prints the message to stdout (using 'print') """
+ sys.stderr.write(str(msg)+"\n")
+
+default_keywordmapper = KeywordMapper()
+
+def setconsumer(keywords, consumer):
+ default_keywordmapper.setconsumer(keywords, consumer)
+
+def setstate(state):
+ default_keywordmapper.setstate(state)
+def getstate():
+ return default_keywordmapper.getstate()
+
+#
+# Consumers
+#
+
+class File(object):
+ """ log consumer wrapping a file(-like) object """
+ def __init__(self, f):
+ assert hasattr(f, 'write')
+ #assert isinstance(f, file) or not hasattr(f, 'open')
+ self._file = f
+
+ def __call__(self, msg):
+ """ write a message to the log """
+ self._file.write(str(msg) + "\n")
+ if hasattr(self._file, 'flush'):
+ self._file.flush()
+
+class Path(object):
+ """ log consumer that opens and writes to a Path """
+ def __init__(self, filename, append=False,
+ delayed_create=False, buffering=False):
+ self._append = append
+ self._filename = str(filename)
+ self._buffering = buffering
+ if not delayed_create:
+ self._openfile()
+
+ def _openfile(self):
+ mode = self._append and 'a' or 'w'
+ f = open(self._filename, mode)
+ self._file = f
+
+ def __call__(self, msg):
+ """ write a message to the log """
+ if not hasattr(self, "_file"):
+ self._openfile()
+ self._file.write(str(msg) + "\n")
+ if not self._buffering:
+ self._file.flush()
+
+def STDOUT(msg):
+ """ consumer that writes to sys.stdout """
+ sys.stdout.write(str(msg)+"\n")
+
+def STDERR(msg):
+ """ consumer that writes to sys.stderr """
+ sys.stderr.write(str(msg)+"\n")
+
+class Syslog:
+ """ consumer that writes to the syslog daemon """
+
+ def __init__(self, priority = None):
+ if priority is None:
+ priority = self.LOG_INFO
+ self.priority = priority
+
+ def __call__(self, msg):
+ """ write a message to the log """
+ py.std.syslog.syslog(self.priority, str(msg))
+
+for _prio in "EMERG ALERT CRIT ERR WARNING NOTICE INFO DEBUG".split():
+ _prio = "LOG_" + _prio
+ try:
+ setattr(Syslog, _prio, getattr(py.std.syslog, _prio))
+ except AttributeError:
+ pass
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_log/warning.py b/tests/wpt/web-platform-tests/tools/py/py/_log/warning.py
new file mode 100644
index 00000000000..722e31e910d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_log/warning.py
@@ -0,0 +1,76 @@
+import py, sys
+
+class DeprecationWarning(DeprecationWarning):
+ def __init__(self, msg, path, lineno):
+ self.msg = msg
+ self.path = path
+ self.lineno = lineno
+ def __repr__(self):
+ return "%s:%d: %s" %(self.path, self.lineno+1, self.msg)
+ def __str__(self):
+ return self.msg
+
+def _apiwarn(startversion, msg, stacklevel=2, function=None):
+ # below is mostly COPIED from python2.4/warnings.py's def warn()
+ # Get context information
+ if isinstance(stacklevel, str):
+ frame = sys._getframe(1)
+ level = 1
+ found = frame.f_code.co_filename.find(stacklevel) != -1
+ while frame:
+ co = frame.f_code
+ if co.co_filename.find(stacklevel) == -1:
+ if found:
+ stacklevel = level
+ break
+ else:
+ found = True
+ level += 1
+ frame = frame.f_back
+ else:
+ stacklevel = 1
+ msg = "%s (since version %s)" %(msg, startversion)
+ warn(msg, stacklevel=stacklevel+1, function=function)
+
+def warn(msg, stacklevel=1, function=None):
+ if function is not None:
+ filename = py.std.inspect.getfile(function)
+ lineno = py.code.getrawcode(function).co_firstlineno
+ else:
+ try:
+ caller = sys._getframe(stacklevel)
+ except ValueError:
+ globals = sys.__dict__
+ lineno = 1
+ else:
+ globals = caller.f_globals
+ lineno = caller.f_lineno
+ if '__name__' in globals:
+ module = globals['__name__']
+ else:
+ module = "<string>"
+ filename = globals.get('__file__')
+ if filename:
+ fnl = filename.lower()
+ if fnl.endswith(".pyc") or fnl.endswith(".pyo"):
+ filename = filename[:-1]
+ elif fnl.endswith("$py.class"):
+ filename = filename.replace('$py.class', '.py')
+ else:
+ if module == "__main__":
+ try:
+ filename = sys.argv[0]
+ except AttributeError:
+ # embedded interpreters don't have sys.argv, see bug #839151
+ filename = '__main__'
+ if not filename:
+ filename = module
+ path = py.path.local(filename)
+ warning = DeprecationWarning(msg, path, lineno)
+ py.std.warnings.warn_explicit(warning, category=Warning,
+ filename=str(warning.path),
+ lineno=warning.lineno,
+ registry=py.std.warnings.__dict__.setdefault(
+ "__warningsregistry__", {})
+ )
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_path/__init__.py b/tests/wpt/web-platform-tests/tools/py/py/_path/__init__.py
new file mode 100644
index 00000000000..51f3246f807
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_path/__init__.py
@@ -0,0 +1 @@
+""" unified file system api """
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_path/cacheutil.py b/tests/wpt/web-platform-tests/tools/py/py/_path/cacheutil.py
new file mode 100644
index 00000000000..99225047502
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_path/cacheutil.py
@@ -0,0 +1,114 @@
+"""
+This module contains multithread-safe cache implementations.
+
+All Caches have
+
+ getorbuild(key, builder)
+ delentry(key)
+
+methods and allow configuration when instantiating the cache class.
+"""
+from time import time as gettime
+
+class BasicCache(object):
+ def __init__(self, maxentries=128):
+ self.maxentries = maxentries
+ self.prunenum = int(maxentries - maxentries/8)
+ self._dict = {}
+
+ def clear(self):
+ self._dict.clear()
+
+ def _getentry(self, key):
+ return self._dict[key]
+
+ def _putentry(self, key, entry):
+ self._prunelowestweight()
+ self._dict[key] = entry
+
+ def delentry(self, key, raising=False):
+ try:
+ del self._dict[key]
+ except KeyError:
+ if raising:
+ raise
+
+ def getorbuild(self, key, builder):
+ try:
+ entry = self._getentry(key)
+ except KeyError:
+ entry = self._build(key, builder)
+ self._putentry(key, entry)
+ return entry.value
+
+ def _prunelowestweight(self):
+ """ prune out entries with lowest weight. """
+ numentries = len(self._dict)
+ if numentries >= self.maxentries:
+ # evict according to entry's weight
+ items = [(entry.weight, key)
+ for key, entry in self._dict.items()]
+ items.sort()
+ index = numentries - self.prunenum
+ if index > 0:
+ for weight, key in items[:index]:
+ # in MT situations the element might be gone
+ self.delentry(key, raising=False)
+
+class BuildcostAccessCache(BasicCache):
+ """ A BuildTime/Access-counting cache implementation.
+ the weight of a value is computed as the product of
+
+ num-accesses-of-a-value * time-to-build-the-value
+
+ The values with the least such weights are evicted
+ if the cache maxentries threshold is superceded.
+ For implementation flexibility more than one object
+ might be evicted at a time.
+ """
+ # time function to use for measuring build-times
+
+ def _build(self, key, builder):
+ start = gettime()
+ val = builder()
+ end = gettime()
+ return WeightedCountingEntry(val, end-start)
+
+
+class WeightedCountingEntry(object):
+ def __init__(self, value, oneweight):
+ self._value = value
+ self.weight = self._oneweight = oneweight
+
+ def value(self):
+ self.weight += self._oneweight
+ return self._value
+ value = property(value)
+
+class AgingCache(BasicCache):
+ """ This cache prunes out cache entries that are too old.
+ """
+ def __init__(self, maxentries=128, maxseconds=10.0):
+ super(AgingCache, self).__init__(maxentries)
+ self.maxseconds = maxseconds
+
+ def _getentry(self, key):
+ entry = self._dict[key]
+ if entry.isexpired():
+ self.delentry(key)
+ raise KeyError(key)
+ return entry
+
+ def _build(self, key, builder):
+ val = builder()
+ entry = AgingEntry(val, gettime() + self.maxseconds)
+ return entry
+
+class AgingEntry(object):
+ def __init__(self, value, expirationtime):
+ self.value = value
+ self.weight = expirationtime
+
+ def isexpired(self):
+ t = gettime()
+ return t >= self.weight
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_path/common.py b/tests/wpt/web-platform-tests/tools/py/py/_path/common.py
new file mode 100644
index 00000000000..d407434cb2a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_path/common.py
@@ -0,0 +1,403 @@
+"""
+"""
+import os, sys, posixpath
+import py
+
+# Moved from local.py.
+iswin32 = sys.platform == "win32" or (getattr(os, '_name', False) == 'nt')
+
+class Checkers:
+ _depend_on_existence = 'exists', 'link', 'dir', 'file'
+
+ def __init__(self, path):
+ self.path = path
+
+ def dir(self):
+ raise NotImplementedError
+
+ def file(self):
+ raise NotImplementedError
+
+ def dotfile(self):
+ return self.path.basename.startswith('.')
+
+ def ext(self, arg):
+ if not arg.startswith('.'):
+ arg = '.' + arg
+ return self.path.ext == arg
+
+ def exists(self):
+ raise NotImplementedError
+
+ def basename(self, arg):
+ return self.path.basename == arg
+
+ def basestarts(self, arg):
+ return self.path.basename.startswith(arg)
+
+ def relto(self, arg):
+ return self.path.relto(arg)
+
+ def fnmatch(self, arg):
+ return self.path.fnmatch(arg)
+
+ def endswith(self, arg):
+ return str(self.path).endswith(arg)
+
+ def _evaluate(self, kw):
+ for name, value in kw.items():
+ invert = False
+ meth = None
+ try:
+ meth = getattr(self, name)
+ except AttributeError:
+ if name[:3] == 'not':
+ invert = True
+ try:
+ meth = getattr(self, name[3:])
+ except AttributeError:
+ pass
+ if meth is None:
+ raise TypeError(
+ "no %r checker available for %r" % (name, self.path))
+ try:
+ if py.code.getrawcode(meth).co_argcount > 1:
+ if (not meth(value)) ^ invert:
+ return False
+ else:
+ if bool(value) ^ bool(meth()) ^ invert:
+ return False
+ except (py.error.ENOENT, py.error.ENOTDIR, py.error.EBUSY):
+ # EBUSY feels not entirely correct,
+ # but its kind of necessary since ENOMEDIUM
+ # is not accessible in python
+ for name in self._depend_on_existence:
+ if name in kw:
+ if kw.get(name):
+ return False
+ name = 'not' + name
+ if name in kw:
+ if not kw.get(name):
+ return False
+ return True
+
+class NeverRaised(Exception):
+ pass
+
+class PathBase(object):
+ """ shared implementation for filesystem path objects."""
+ Checkers = Checkers
+
+ def __div__(self, other):
+ return self.join(str(other))
+ __truediv__ = __div__ # py3k
+
+ def basename(self):
+ """ basename part of path. """
+ return self._getbyspec('basename')[0]
+ basename = property(basename, None, None, basename.__doc__)
+
+ def dirname(self):
+ """ dirname part of path. """
+ return self._getbyspec('dirname')[0]
+ dirname = property(dirname, None, None, dirname.__doc__)
+
+ def purebasename(self):
+ """ pure base name of the path."""
+ return self._getbyspec('purebasename')[0]
+ purebasename = property(purebasename, None, None, purebasename.__doc__)
+
+ def ext(self):
+ """ extension of the path (including the '.')."""
+ return self._getbyspec('ext')[0]
+ ext = property(ext, None, None, ext.__doc__)
+
+ def dirpath(self, *args, **kwargs):
+ """ return the directory path joined with any given path arguments. """
+ return self.new(basename='').join(*args, **kwargs)
+
+ def read_binary(self):
+ """ read and return a bytestring from reading the path. """
+ with self.open('rb') as f:
+ return f.read()
+
+ def read_text(self, encoding):
+ """ read and return a Unicode string from reading the path. """
+ with self.open("r", encoding=encoding) as f:
+ return f.read()
+
+
+ def read(self, mode='r'):
+ """ read and return a bytestring from reading the path. """
+ with self.open(mode) as f:
+ return f.read()
+
+ def readlines(self, cr=1):
+ """ read and return a list of lines from the path. if cr is False, the
+newline will be removed from the end of each line. """
+ if not cr:
+ content = self.read('rU')
+ return content.split('\n')
+ else:
+ f = self.open('rU')
+ try:
+ return f.readlines()
+ finally:
+ f.close()
+
+ def load(self):
+ """ (deprecated) return object unpickled from self.read() """
+ f = self.open('rb')
+ try:
+ return py.error.checked_call(py.std.pickle.load, f)
+ finally:
+ f.close()
+
+ def move(self, target):
+ """ move this path to target. """
+ if target.relto(self):
+ raise py.error.EINVAL(target,
+ "cannot move path into a subdirectory of itself")
+ try:
+ self.rename(target)
+ except py.error.EXDEV: # invalid cross-device link
+ self.copy(target)
+ self.remove()
+
+ def __repr__(self):
+ """ return a string representation of this path. """
+ return repr(str(self))
+
+ def check(self, **kw):
+ """ check a path for existence and properties.
+
+ Without arguments, return True if the path exists, otherwise False.
+
+ valid checkers::
+
+ file=1 # is a file
+ file=0 # is not a file (may not even exist)
+ dir=1 # is a dir
+ link=1 # is a link
+ exists=1 # exists
+
+ You can specify multiple checker definitions, for example::
+
+ path.check(file=1, link=1) # a link pointing to a file
+ """
+ if not kw:
+ kw = {'exists' : 1}
+ return self.Checkers(self)._evaluate(kw)
+
+ def fnmatch(self, pattern):
+ """return true if the basename/fullname matches the glob-'pattern'.
+
+ valid pattern characters::
+
+ * matches everything
+ ? matches any single character
+ [seq] matches any character in seq
+ [!seq] matches any char not in seq
+
+ If the pattern contains a path-separator then the full path
+ is used for pattern matching and a '*' is prepended to the
+ pattern.
+
+ if the pattern doesn't contain a path-separator the pattern
+ is only matched against the basename.
+ """
+ return FNMatcher(pattern)(self)
+
+ def relto(self, relpath):
+ """ return a string which is the relative part of the path
+ to the given 'relpath'.
+ """
+ if not isinstance(relpath, (str, PathBase)):
+ raise TypeError("%r: not a string or path object" %(relpath,))
+ strrelpath = str(relpath)
+ if strrelpath and strrelpath[-1] != self.sep:
+ strrelpath += self.sep
+ #assert strrelpath[-1] == self.sep
+ #assert strrelpath[-2] != self.sep
+ strself = self.strpath
+ if sys.platform == "win32" or getattr(os, '_name', None) == 'nt':
+ if os.path.normcase(strself).startswith(
+ os.path.normcase(strrelpath)):
+ return strself[len(strrelpath):]
+ elif strself.startswith(strrelpath):
+ return strself[len(strrelpath):]
+ return ""
+
+ def ensure_dir(self, *args):
+ """ ensure the path joined with args is a directory. """
+ return self.ensure(*args, **{"dir": True})
+
+ def bestrelpath(self, dest):
+ """ return a string which is a relative path from self
+ (assumed to be a directory) to dest such that
+ self.join(bestrelpath) == dest and if not such
+ path can be determined return dest.
+ """
+ try:
+ if self == dest:
+ return os.curdir
+ base = self.common(dest)
+ if not base: # can be the case on windows
+ return str(dest)
+ self2base = self.relto(base)
+ reldest = dest.relto(base)
+ if self2base:
+ n = self2base.count(self.sep) + 1
+ else:
+ n = 0
+ l = [os.pardir] * n
+ if reldest:
+ l.append(reldest)
+ target = dest.sep.join(l)
+ return target
+ except AttributeError:
+ return str(dest)
+
+ def exists(self):
+ return self.check()
+
+ def isdir(self):
+ return self.check(dir=1)
+
+ def isfile(self):
+ return self.check(file=1)
+
+ def parts(self, reverse=False):
+ """ return a root-first list of all ancestor directories
+ plus the path itself.
+ """
+ current = self
+ l = [self]
+ while 1:
+ last = current
+ current = current.dirpath()
+ if last == current:
+ break
+ l.append(current)
+ if not reverse:
+ l.reverse()
+ return l
+
+ def common(self, other):
+ """ return the common part shared with the other path
+ or None if there is no common part.
+ """
+ last = None
+ for x, y in zip(self.parts(), other.parts()):
+ if x != y:
+ return last
+ last = x
+ return last
+
+ def __add__(self, other):
+ """ return new path object with 'other' added to the basename"""
+ return self.new(basename=self.basename+str(other))
+
+ def __cmp__(self, other):
+ """ return sort value (-1, 0, +1). """
+ try:
+ return cmp(self.strpath, other.strpath)
+ except AttributeError:
+ return cmp(str(self), str(other)) # self.path, other.path)
+
+ def __lt__(self, other):
+ try:
+ return self.strpath < other.strpath
+ except AttributeError:
+ return str(self) < str(other)
+
+ def visit(self, fil=None, rec=None, ignore=NeverRaised, bf=False, sort=False):
+ """ yields all paths below the current one
+
+ fil is a filter (glob pattern or callable), if not matching the
+ path will not be yielded, defaulting to None (everything is
+ returned)
+
+ rec is a filter (glob pattern or callable) that controls whether
+ a node is descended, defaulting to None
+
+ ignore is an Exception class that is ignoredwhen calling dirlist()
+ on any of the paths (by default, all exceptions are reported)
+
+ bf if True will cause a breadthfirst search instead of the
+ default depthfirst. Default: False
+
+ sort if True will sort entries within each directory level.
+ """
+ for x in Visitor(fil, rec, ignore, bf, sort).gen(self):
+ yield x
+
+ def _sortlist(self, res, sort):
+ if sort:
+ if hasattr(sort, '__call__'):
+ res.sort(sort)
+ else:
+ res.sort()
+
+ def samefile(self, other):
+ """ return True if other refers to the same stat object as self. """
+ return self.strpath == str(other)
+
+class Visitor:
+ def __init__(self, fil, rec, ignore, bf, sort):
+ if isinstance(fil, str):
+ fil = FNMatcher(fil)
+ if isinstance(rec, str):
+ self.rec = FNMatcher(rec)
+ elif not hasattr(rec, '__call__') and rec:
+ self.rec = lambda path: True
+ else:
+ self.rec = rec
+ self.fil = fil
+ self.ignore = ignore
+ self.breadthfirst = bf
+ self.optsort = sort and sorted or (lambda x: x)
+
+ def gen(self, path):
+ try:
+ entries = path.listdir()
+ except self.ignore:
+ return
+ rec = self.rec
+ dirs = self.optsort([p for p in entries
+ if p.check(dir=1) and (rec is None or rec(p))])
+ if not self.breadthfirst:
+ for subdir in dirs:
+ for p in self.gen(subdir):
+ yield p
+ for p in self.optsort(entries):
+ if self.fil is None or self.fil(p):
+ yield p
+ if self.breadthfirst:
+ for subdir in dirs:
+ for p in self.gen(subdir):
+ yield p
+
+class FNMatcher:
+ def __init__(self, pattern):
+ self.pattern = pattern
+
+ def __call__(self, path):
+ pattern = self.pattern
+
+ if (pattern.find(path.sep) == -1 and
+ iswin32 and
+ pattern.find(posixpath.sep) != -1):
+ # Running on Windows, the pattern has no Windows path separators,
+ # and the pattern has one or more Posix path separators. Replace
+ # the Posix path separators with the Windows path separator.
+ pattern = pattern.replace(posixpath.sep, path.sep)
+
+ if pattern.find(path.sep) == -1:
+ name = path.basename
+ else:
+ name = str(path) # path.strpath # XXX svn?
+ if not os.path.isabs(pattern):
+ pattern = '*' + path.sep + pattern
+ return py.std.fnmatch.fnmatch(name, pattern)
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_path/local.py b/tests/wpt/web-platform-tests/tools/py/py/_path/local.py
new file mode 100644
index 00000000000..d569404ec21
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_path/local.py
@@ -0,0 +1,911 @@
+"""
+local path implementation.
+"""
+from __future__ import with_statement
+
+from contextlib import contextmanager
+import sys, os, re, atexit, io
+import py
+from py._path import common
+from py._path.common import iswin32
+from stat import S_ISLNK, S_ISDIR, S_ISREG
+
+from os.path import abspath, normpath, isabs, exists, isdir, isfile, islink, dirname
+
+if sys.version_info > (3,0):
+ def map_as_list(func, iter):
+ return list(map(func, iter))
+else:
+ map_as_list = map
+
+class Stat(object):
+ def __getattr__(self, name):
+ return getattr(self._osstatresult, "st_" + name)
+
+ def __init__(self, path, osstatresult):
+ self.path = path
+ self._osstatresult = osstatresult
+
+ @property
+ def owner(self):
+ if iswin32:
+ raise NotImplementedError("XXX win32")
+ import pwd
+ entry = py.error.checked_call(pwd.getpwuid, self.uid)
+ return entry[0]
+
+ @property
+ def group(self):
+ """ return group name of file. """
+ if iswin32:
+ raise NotImplementedError("XXX win32")
+ import grp
+ entry = py.error.checked_call(grp.getgrgid, self.gid)
+ return entry[0]
+
+ def isdir(self):
+ return S_ISDIR(self._osstatresult.st_mode)
+
+ def isfile(self):
+ return S_ISREG(self._osstatresult.st_mode)
+
+ def islink(self):
+ st = self.path.lstat()
+ return S_ISLNK(self._osstatresult.st_mode)
+
+class PosixPath(common.PathBase):
+ def chown(self, user, group, rec=0):
+ """ change ownership to the given user and group.
+ user and group may be specified by a number or
+ by a name. if rec is True change ownership
+ recursively.
+ """
+ uid = getuserid(user)
+ gid = getgroupid(group)
+ if rec:
+ for x in self.visit(rec=lambda x: x.check(link=0)):
+ if x.check(link=0):
+ py.error.checked_call(os.chown, str(x), uid, gid)
+ py.error.checked_call(os.chown, str(self), uid, gid)
+
+ def readlink(self):
+ """ return value of a symbolic link. """
+ return py.error.checked_call(os.readlink, self.strpath)
+
+ def mklinkto(self, oldname):
+ """ posix style hard link to another name. """
+ py.error.checked_call(os.link, str(oldname), str(self))
+
+ def mksymlinkto(self, value, absolute=1):
+ """ create a symbolic link with the given value (pointing to another name). """
+ if absolute:
+ py.error.checked_call(os.symlink, str(value), self.strpath)
+ else:
+ base = self.common(value)
+ # with posix local paths '/' is always a common base
+ relsource = self.__class__(value).relto(base)
+ reldest = self.relto(base)
+ n = reldest.count(self.sep)
+ target = self.sep.join(('..', )*n + (relsource, ))
+ py.error.checked_call(os.symlink, target, self.strpath)
+
+def getuserid(user):
+ import pwd
+ if not isinstance(user, int):
+ user = pwd.getpwnam(user)[2]
+ return user
+
+def getgroupid(group):
+ import grp
+ if not isinstance(group, int):
+ group = grp.getgrnam(group)[2]
+ return group
+
+FSBase = not iswin32 and PosixPath or common.PathBase
+
+class LocalPath(FSBase):
+ """ object oriented interface to os.path and other local filesystem
+ related information.
+ """
+ class ImportMismatchError(ImportError):
+ """ raised on pyimport() if there is a mismatch of __file__'s"""
+
+ sep = os.sep
+ class Checkers(common.Checkers):
+ def _stat(self):
+ try:
+ return self._statcache
+ except AttributeError:
+ try:
+ self._statcache = self.path.stat()
+ except py.error.ELOOP:
+ self._statcache = self.path.lstat()
+ return self._statcache
+
+ def dir(self):
+ return S_ISDIR(self._stat().mode)
+
+ def file(self):
+ return S_ISREG(self._stat().mode)
+
+ def exists(self):
+ return self._stat()
+
+ def link(self):
+ st = self.path.lstat()
+ return S_ISLNK(st.mode)
+
+ def __init__(self, path=None, expanduser=False):
+ """ Initialize and return a local Path instance.
+
+ Path can be relative to the current directory.
+ If path is None it defaults to the current working directory.
+ If expanduser is True, tilde-expansion is performed.
+ Note that Path instances always carry an absolute path.
+ Note also that passing in a local path object will simply return
+ the exact same path object. Use new() to get a new copy.
+ """
+ if path is None:
+ self.strpath = py.error.checked_call(os.getcwd)
+ elif isinstance(path, common.PathBase):
+ self.strpath = path.strpath
+ elif isinstance(path, py.builtin._basestring):
+ if expanduser:
+ path = os.path.expanduser(path)
+ self.strpath = abspath(path)
+ else:
+ raise ValueError("can only pass None, Path instances "
+ "or non-empty strings to LocalPath")
+
+ def __hash__(self):
+ return hash(self.strpath)
+
+ def __eq__(self, other):
+ s1 = self.strpath
+ s2 = getattr(other, "strpath", other)
+ if iswin32:
+ s1 = s1.lower()
+ try:
+ s2 = s2.lower()
+ except AttributeError:
+ return False
+ return s1 == s2
+
+ def __ne__(self, other):
+ return not (self == other)
+
+ def __lt__(self, other):
+ return self.strpath < getattr(other, "strpath", other)
+
+ def __gt__(self, other):
+ return self.strpath > getattr(other, "strpath", other)
+
+ def samefile(self, other):
+ """ return True if 'other' references the same file as 'self'.
+ """
+ other = getattr(other, "strpath", other)
+ if not isabs(other):
+ other = abspath(other)
+ if self == other:
+ return True
+ if iswin32:
+ return False # there is no samefile
+ return py.error.checked_call(
+ os.path.samefile, self.strpath, other)
+
+ def remove(self, rec=1, ignore_errors=False):
+ """ remove a file or directory (or a directory tree if rec=1).
+ if ignore_errors is True, errors while removing directories will
+ be ignored.
+ """
+ if self.check(dir=1, link=0):
+ if rec:
+ # force remove of readonly files on windows
+ if iswin32:
+ self.chmod(448, rec=1) # octcal 0700
+ py.error.checked_call(py.std.shutil.rmtree, self.strpath,
+ ignore_errors=ignore_errors)
+ else:
+ py.error.checked_call(os.rmdir, self.strpath)
+ else:
+ if iswin32:
+ self.chmod(448) # octcal 0700
+ py.error.checked_call(os.remove, self.strpath)
+
+ def computehash(self, hashtype="md5", chunksize=524288):
+ """ return hexdigest of hashvalue for this file. """
+ try:
+ try:
+ import hashlib as mod
+ except ImportError:
+ if hashtype == "sha1":
+ hashtype = "sha"
+ mod = __import__(hashtype)
+ hash = getattr(mod, hashtype)()
+ except (AttributeError, ImportError):
+ raise ValueError("Don't know how to compute %r hash" %(hashtype,))
+ f = self.open('rb')
+ try:
+ while 1:
+ buf = f.read(chunksize)
+ if not buf:
+ return hash.hexdigest()
+ hash.update(buf)
+ finally:
+ f.close()
+
+ def new(self, **kw):
+ """ create a modified version of this path.
+ the following keyword arguments modify various path parts::
+
+ a:/some/path/to/a/file.ext
+ xx drive
+ xxxxxxxxxxxxxxxxx dirname
+ xxxxxxxx basename
+ xxxx purebasename
+ xxx ext
+ """
+ obj = object.__new__(self.__class__)
+ if not kw:
+ obj.strpath = self.strpath
+ return obj
+ drive, dirname, basename, purebasename,ext = self._getbyspec(
+ "drive,dirname,basename,purebasename,ext")
+ if 'basename' in kw:
+ if 'purebasename' in kw or 'ext' in kw:
+ raise ValueError("invalid specification %r" % kw)
+ else:
+ pb = kw.setdefault('purebasename', purebasename)
+ try:
+ ext = kw['ext']
+ except KeyError:
+ pass
+ else:
+ if ext and not ext.startswith('.'):
+ ext = '.' + ext
+ kw['basename'] = pb + ext
+
+ if ('dirname' in kw and not kw['dirname']):
+ kw['dirname'] = drive
+ else:
+ kw.setdefault('dirname', dirname)
+ kw.setdefault('sep', self.sep)
+ obj.strpath = normpath(
+ "%(dirname)s%(sep)s%(basename)s" % kw)
+ return obj
+
+ def _getbyspec(self, spec):
+ """ see new for what 'spec' can be. """
+ res = []
+ parts = self.strpath.split(self.sep)
+
+ args = filter(None, spec.split(',') )
+ append = res.append
+ for name in args:
+ if name == 'drive':
+ append(parts[0])
+ elif name == 'dirname':
+ append(self.sep.join(parts[:-1]))
+ else:
+ basename = parts[-1]
+ if name == 'basename':
+ append(basename)
+ else:
+ i = basename.rfind('.')
+ if i == -1:
+ purebasename, ext = basename, ''
+ else:
+ purebasename, ext = basename[:i], basename[i:]
+ if name == 'purebasename':
+ append(purebasename)
+ elif name == 'ext':
+ append(ext)
+ else:
+ raise ValueError("invalid part specification %r" % name)
+ return res
+
+ def dirpath(self, *args, **kwargs):
+ """ return the directory path joined with any given path arguments. """
+ if not kwargs:
+ path = object.__new__(self.__class__)
+ path.strpath = dirname(self.strpath)
+ if args:
+ path = path.join(*args)
+ return path
+ return super(LocalPath, self).dirpath(*args, **kwargs)
+
+ def join(self, *args, **kwargs):
+ """ return a new path by appending all 'args' as path
+ components. if abs=1 is used restart from root if any
+ of the args is an absolute path.
+ """
+ sep = self.sep
+ strargs = [getattr(arg, "strpath", arg) for arg in args]
+ strpath = self.strpath
+ if kwargs.get('abs'):
+ newargs = []
+ for arg in reversed(strargs):
+ if isabs(arg):
+ strpath = arg
+ strargs = newargs
+ break
+ newargs.insert(0, arg)
+ for arg in strargs:
+ arg = arg.strip(sep)
+ if iswin32:
+ # allow unix style paths even on windows.
+ arg = arg.strip('/')
+ arg = arg.replace('/', sep)
+ strpath = strpath + sep + arg
+ obj = object.__new__(self.__class__)
+ obj.strpath = normpath(strpath)
+ return obj
+
+ def open(self, mode='r', ensure=False, encoding=None):
+ """ return an opened file with the given mode.
+
+ If ensure is True, create parent directories if needed.
+ """
+ if ensure:
+ self.dirpath().ensure(dir=1)
+ if encoding:
+ return py.error.checked_call(io.open, self.strpath, mode, encoding=encoding)
+ return py.error.checked_call(open, self.strpath, mode)
+
+ def _fastjoin(self, name):
+ child = object.__new__(self.__class__)
+ child.strpath = self.strpath + self.sep + name
+ return child
+
+ def islink(self):
+ return islink(self.strpath)
+
+ def check(self, **kw):
+ if not kw:
+ return exists(self.strpath)
+ if len(kw) == 1:
+ if "dir" in kw:
+ return not kw["dir"] ^ isdir(self.strpath)
+ if "file" in kw:
+ return not kw["file"] ^ isfile(self.strpath)
+ return super(LocalPath, self).check(**kw)
+
+ _patternchars = set("*?[" + os.path.sep)
+ def listdir(self, fil=None, sort=None):
+ """ list directory contents, possibly filter by the given fil func
+ and possibly sorted.
+ """
+ if fil is None and sort is None:
+ names = py.error.checked_call(os.listdir, self.strpath)
+ return map_as_list(self._fastjoin, names)
+ if isinstance(fil, py.builtin._basestring):
+ if not self._patternchars.intersection(fil):
+ child = self._fastjoin(fil)
+ if exists(child.strpath):
+ return [child]
+ return []
+ fil = common.FNMatcher(fil)
+ names = py.error.checked_call(os.listdir, self.strpath)
+ res = []
+ for name in names:
+ child = self._fastjoin(name)
+ if fil is None or fil(child):
+ res.append(child)
+ self._sortlist(res, sort)
+ return res
+
+ def size(self):
+ """ return size of the underlying file object """
+ return self.stat().size
+
+ def mtime(self):
+ """ return last modification time of the path. """
+ return self.stat().mtime
+
+ def copy(self, target, mode=False):
+ """ copy path to target."""
+ if self.check(file=1):
+ if target.check(dir=1):
+ target = target.join(self.basename)
+ assert self!=target
+ copychunked(self, target)
+ if mode:
+ copymode(self.strpath, target.strpath)
+ else:
+ def rec(p):
+ return p.check(link=0)
+ for x in self.visit(rec=rec):
+ relpath = x.relto(self)
+ newx = target.join(relpath)
+ newx.dirpath().ensure(dir=1)
+ if x.check(link=1):
+ newx.mksymlinkto(x.readlink())
+ continue
+ elif x.check(file=1):
+ copychunked(x, newx)
+ elif x.check(dir=1):
+ newx.ensure(dir=1)
+ if mode:
+ copymode(x.strpath, newx.strpath)
+
+ def rename(self, target):
+ """ rename this path to target. """
+ target = getattr(target, "strpath", target)
+ return py.error.checked_call(os.rename, self.strpath, target)
+
+ def dump(self, obj, bin=1):
+ """ pickle object into path location"""
+ f = self.open('wb')
+ try:
+ py.error.checked_call(py.std.pickle.dump, obj, f, bin)
+ finally:
+ f.close()
+
+ def mkdir(self, *args):
+ """ create & return the directory joined with args. """
+ p = self.join(*args)
+ py.error.checked_call(os.mkdir, getattr(p, "strpath", p))
+ return p
+
+ def write_binary(self, data, ensure=False):
+ """ write binary data into path. If ensure is True create
+ missing parent directories.
+ """
+ if ensure:
+ self.dirpath().ensure(dir=1)
+ with self.open('wb') as f:
+ f.write(data)
+
+ def write_text(self, data, encoding, ensure=False):
+ """ write text data into path using the specified encoding.
+ If ensure is True create missing parent directories.
+ """
+ if ensure:
+ self.dirpath().ensure(dir=1)
+ with self.open('w', encoding=encoding) as f:
+ f.write(data)
+
+ def write(self, data, mode='w', ensure=False):
+ """ write data into path. If ensure is True create
+ missing parent directories.
+ """
+ if ensure:
+ self.dirpath().ensure(dir=1)
+ if 'b' in mode:
+ if not py.builtin._isbytes(data):
+ raise ValueError("can only process bytes")
+ else:
+ if not py.builtin._istext(data):
+ if not py.builtin._isbytes(data):
+ data = str(data)
+ else:
+ data = py.builtin._totext(data, sys.getdefaultencoding())
+ f = self.open(mode)
+ try:
+ f.write(data)
+ finally:
+ f.close()
+
+ def _ensuredirs(self):
+ parent = self.dirpath()
+ if parent == self:
+ return self
+ if parent.check(dir=0):
+ parent._ensuredirs()
+ if self.check(dir=0):
+ try:
+ self.mkdir()
+ except py.error.EEXIST:
+ # race condition: file/dir created by another thread/process.
+ # complain if it is not a dir
+ if self.check(dir=0):
+ raise
+ return self
+
+ def ensure(self, *args, **kwargs):
+ """ ensure that an args-joined path exists (by default as
+ a file). if you specify a keyword argument 'dir=True'
+ then the path is forced to be a directory path.
+ """
+ p = self.join(*args)
+ if kwargs.get('dir', 0):
+ return p._ensuredirs()
+ else:
+ p.dirpath()._ensuredirs()
+ if not p.check(file=1):
+ p.open('w').close()
+ return p
+
+ def stat(self, raising=True):
+ """ Return an os.stat() tuple. """
+ if raising == True:
+ return Stat(self, py.error.checked_call(os.stat, self.strpath))
+ try:
+ return Stat(self, os.stat(self.strpath))
+ except KeyboardInterrupt:
+ raise
+ except Exception:
+ return None
+
+ def lstat(self):
+ """ Return an os.lstat() tuple. """
+ return Stat(self, py.error.checked_call(os.lstat, self.strpath))
+
+ def setmtime(self, mtime=None):
+ """ set modification time for the given path. if 'mtime' is None
+ (the default) then the file's mtime is set to current time.
+
+ Note that the resolution for 'mtime' is platform dependent.
+ """
+ if mtime is None:
+ return py.error.checked_call(os.utime, self.strpath, mtime)
+ try:
+ return py.error.checked_call(os.utime, self.strpath, (-1, mtime))
+ except py.error.EINVAL:
+ return py.error.checked_call(os.utime, self.strpath, (self.atime(), mtime))
+
+ def chdir(self):
+ """ change directory to self and return old current directory """
+ try:
+ old = self.__class__()
+ except py.error.ENOENT:
+ old = None
+ py.error.checked_call(os.chdir, self.strpath)
+ return old
+
+
+ @contextmanager
+ def as_cwd(self):
+ """ return context manager which changes to current dir during the
+ managed "with" context. On __enter__ it returns the old dir.
+ """
+ old = self.chdir()
+ try:
+ yield old
+ finally:
+ old.chdir()
+
+ def realpath(self):
+ """ return a new path which contains no symbolic links."""
+ return self.__class__(os.path.realpath(self.strpath))
+
+ def atime(self):
+ """ return last access time of the path. """
+ return self.stat().atime
+
+ def __repr__(self):
+ return 'local(%r)' % self.strpath
+
+ def __str__(self):
+ """ return string representation of the Path. """
+ return self.strpath
+
+ def chmod(self, mode, rec=0):
+ """ change permissions to the given mode. If mode is an
+ integer it directly encodes the os-specific modes.
+ if rec is True perform recursively.
+ """
+ if not isinstance(mode, int):
+ raise TypeError("mode %r must be an integer" % (mode,))
+ if rec:
+ for x in self.visit(rec=rec):
+ py.error.checked_call(os.chmod, str(x), mode)
+ py.error.checked_call(os.chmod, self.strpath, mode)
+
+ def pypkgpath(self):
+ """ return the Python package path by looking for the last
+ directory upwards which still contains an __init__.py.
+ Return None if a pkgpath can not be determined.
+ """
+ pkgpath = None
+ for parent in self.parts(reverse=True):
+ if parent.isdir():
+ if not parent.join('__init__.py').exists():
+ break
+ if not isimportable(parent.basename):
+ break
+ pkgpath = parent
+ return pkgpath
+
+ def _ensuresyspath(self, ensuremode, path):
+ if ensuremode:
+ s = str(path)
+ if ensuremode == "append":
+ if s not in sys.path:
+ sys.path.append(s)
+ else:
+ if s != sys.path[0]:
+ sys.path.insert(0, s)
+
+ def pyimport(self, modname=None, ensuresyspath=True):
+ """ return path as an imported python module.
+
+ If modname is None, look for the containing package
+ and construct an according module name.
+ The module will be put/looked up in sys.modules.
+ if ensuresyspath is True then the root dir for importing
+ the file (taking __init__.py files into account) will
+ be prepended to sys.path if it isn't there already.
+ If ensuresyspath=="append" the root dir will be appended
+ if it isn't already contained in sys.path.
+ if ensuresyspath is False no modification of syspath happens.
+ """
+ if not self.check():
+ raise py.error.ENOENT(self)
+
+ pkgpath = None
+ if modname is None:
+ pkgpath = self.pypkgpath()
+ if pkgpath is not None:
+ pkgroot = pkgpath.dirpath()
+ names = self.new(ext="").relto(pkgroot).split(self.sep)
+ if names[-1] == "__init__":
+ names.pop()
+ modname = ".".join(names)
+ else:
+ pkgroot = self.dirpath()
+ modname = self.purebasename
+
+ self._ensuresyspath(ensuresyspath, pkgroot)
+ __import__(modname)
+ mod = sys.modules[modname]
+ if self.basename == "__init__.py":
+ return mod # we don't check anything as we might
+ # we in a namespace package ... too icky to check
+ modfile = mod.__file__
+ if modfile[-4:] in ('.pyc', '.pyo'):
+ modfile = modfile[:-1]
+ elif modfile.endswith('$py.class'):
+ modfile = modfile[:-9] + '.py'
+ if modfile.endswith(os.path.sep + "__init__.py"):
+ if self.basename != "__init__.py":
+ modfile = modfile[:-12]
+ try:
+ issame = self.samefile(modfile)
+ except py.error.ENOENT:
+ issame = False
+ if not issame:
+ raise self.ImportMismatchError(modname, modfile, self)
+ return mod
+ else:
+ try:
+ return sys.modules[modname]
+ except KeyError:
+ # we have a custom modname, do a pseudo-import
+ mod = py.std.types.ModuleType(modname)
+ mod.__file__ = str(self)
+ sys.modules[modname] = mod
+ try:
+ py.builtin.execfile(str(self), mod.__dict__)
+ except:
+ del sys.modules[modname]
+ raise
+ return mod
+
+ def sysexec(self, *argv, **popen_opts):
+ """ return stdout text from executing a system child process,
+ where the 'self' path points to executable.
+ The process is directly invoked and not through a system shell.
+ """
+ from subprocess import Popen, PIPE
+ argv = map_as_list(str, argv)
+ popen_opts['stdout'] = popen_opts['stderr'] = PIPE
+ proc = Popen([str(self)] + argv, **popen_opts)
+ stdout, stderr = proc.communicate()
+ ret = proc.wait()
+ if py.builtin._isbytes(stdout):
+ stdout = py.builtin._totext(stdout, sys.getdefaultencoding())
+ if ret != 0:
+ if py.builtin._isbytes(stderr):
+ stderr = py.builtin._totext(stderr, sys.getdefaultencoding())
+ raise py.process.cmdexec.Error(ret, ret, str(self),
+ stdout, stderr,)
+ return stdout
+
+ def sysfind(cls, name, checker=None, paths=None):
+ """ return a path object found by looking at the systems
+ underlying PATH specification. If the checker is not None
+ it will be invoked to filter matching paths. If a binary
+ cannot be found, None is returned
+ Note: This is probably not working on plain win32 systems
+ but may work on cygwin.
+ """
+ if isabs(name):
+ p = py.path.local(name)
+ if p.check(file=1):
+ return p
+ else:
+ if paths is None:
+ if iswin32:
+ paths = py.std.os.environ['Path'].split(';')
+ if '' not in paths and '.' not in paths:
+ paths.append('.')
+ try:
+ systemroot = os.environ['SYSTEMROOT']
+ except KeyError:
+ pass
+ else:
+ paths = [re.sub('%SystemRoot%', systemroot, path)
+ for path in paths]
+ else:
+ paths = py.std.os.environ['PATH'].split(':')
+ tryadd = []
+ if iswin32:
+ tryadd += os.environ['PATHEXT'].split(os.pathsep)
+ tryadd.append("")
+
+ for x in paths:
+ for addext in tryadd:
+ p = py.path.local(x).join(name, abs=True) + addext
+ try:
+ if p.check(file=1):
+ if checker:
+ if not checker(p):
+ continue
+ return p
+ except py.error.EACCES:
+ pass
+ return None
+ sysfind = classmethod(sysfind)
+
+ def _gethomedir(cls):
+ try:
+ x = os.environ['HOME']
+ except KeyError:
+ try:
+ x = os.environ["HOMEDRIVE"] + os.environ['HOMEPATH']
+ except KeyError:
+ return None
+ return cls(x)
+ _gethomedir = classmethod(_gethomedir)
+
+ #"""
+ #special class constructors for local filesystem paths
+ #"""
+ def get_temproot(cls):
+ """ return the system's temporary directory
+ (where tempfiles are usually created in)
+ """
+ return py.path.local(py.std.tempfile.gettempdir())
+ get_temproot = classmethod(get_temproot)
+
+ def mkdtemp(cls, rootdir=None):
+ """ return a Path object pointing to a fresh new temporary directory
+ (which we created ourself).
+ """
+ import tempfile
+ if rootdir is None:
+ rootdir = cls.get_temproot()
+ return cls(py.error.checked_call(tempfile.mkdtemp, dir=str(rootdir)))
+ mkdtemp = classmethod(mkdtemp)
+
+ def make_numbered_dir(cls, prefix='session-', rootdir=None, keep=3,
+ lock_timeout = 172800): # two days
+ """ return unique directory with a number greater than the current
+ maximum one. The number is assumed to start directly after prefix.
+ if keep is true directories with a number less than (maxnum-keep)
+ will be removed.
+ """
+ if rootdir is None:
+ rootdir = cls.get_temproot()
+
+ def parse_num(path):
+ """ parse the number out of a path (if it matches the prefix) """
+ bn = path.basename
+ if bn.startswith(prefix):
+ try:
+ return int(bn[len(prefix):])
+ except ValueError:
+ pass
+
+ # compute the maximum number currently in use with the
+ # prefix
+ lastmax = None
+ while True:
+ maxnum = -1
+ for path in rootdir.listdir():
+ num = parse_num(path)
+ if num is not None:
+ maxnum = max(maxnum, num)
+
+ # make the new directory
+ try:
+ udir = rootdir.mkdir(prefix + str(maxnum+1))
+ except py.error.EEXIST:
+ # race condition: another thread/process created the dir
+ # in the meantime. Try counting again
+ if lastmax == maxnum:
+ raise
+ lastmax = maxnum
+ continue
+ break
+
+ # put a .lock file in the new directory that will be removed at
+ # process exit
+ if lock_timeout:
+ lockfile = udir.join('.lock')
+ mypid = os.getpid()
+ if hasattr(lockfile, 'mksymlinkto'):
+ lockfile.mksymlinkto(str(mypid))
+ else:
+ lockfile.write(str(mypid))
+ def try_remove_lockfile():
+ # in a fork() situation, only the last process should
+ # remove the .lock, otherwise the other processes run the
+ # risk of seeing their temporary dir disappear. For now
+ # we remove the .lock in the parent only (i.e. we assume
+ # that the children finish before the parent).
+ if os.getpid() != mypid:
+ return
+ try:
+ lockfile.remove()
+ except py.error.Error:
+ pass
+ atexit.register(try_remove_lockfile)
+
+ # prune old directories
+ if keep:
+ for path in rootdir.listdir():
+ num = parse_num(path)
+ if num is not None and num <= (maxnum - keep):
+ lf = path.join('.lock')
+ try:
+ t1 = lf.lstat().mtime
+ t2 = lockfile.lstat().mtime
+ if not lock_timeout or abs(t2-t1) < lock_timeout:
+ continue # skip directories still locked
+ except py.error.Error:
+ pass # assume that it means that there is no 'lf'
+ try:
+ path.remove(rec=1)
+ except KeyboardInterrupt:
+ raise
+ except: # this might be py.error.Error, WindowsError ...
+ pass
+
+ # make link...
+ try:
+ username = os.environ['USER'] #linux, et al
+ except KeyError:
+ try:
+ username = os.environ['USERNAME'] #windows
+ except KeyError:
+ username = 'current'
+
+ src = str(udir)
+ dest = src[:src.rfind('-')] + '-' + username
+ try:
+ os.unlink(dest)
+ except OSError:
+ pass
+ try:
+ os.symlink(src, dest)
+ except (OSError, AttributeError, NotImplementedError):
+ pass
+
+ return udir
+ make_numbered_dir = classmethod(make_numbered_dir)
+
+def copymode(src, dest):
+ py.std.shutil.copymode(src, dest)
+
+def copychunked(src, dest):
+ chunksize = 524288 # half a meg of bytes
+ fsrc = src.open('rb')
+ try:
+ fdest = dest.open('wb')
+ try:
+ while 1:
+ buf = fsrc.read(chunksize)
+ if not buf:
+ break
+ fdest.write(buf)
+ finally:
+ fdest.close()
+ finally:
+ fsrc.close()
+
+def isimportable(name):
+ if name and (name[0].isalpha() or name[0] == '_'):
+ name = name.replace("_", '')
+ return not name or name.isalnum()
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_path/svnurl.py b/tests/wpt/web-platform-tests/tools/py/py/_path/svnurl.py
new file mode 100644
index 00000000000..78d71317ac0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_path/svnurl.py
@@ -0,0 +1,380 @@
+"""
+module defining a subversion path object based on the external
+command 'svn'. This modules aims to work with svn 1.3 and higher
+but might also interact well with earlier versions.
+"""
+
+import os, sys, time, re
+import py
+from py import path, process
+from py._path import common
+from py._path import svnwc as svncommon
+from py._path.cacheutil import BuildcostAccessCache, AgingCache
+
+DEBUG=False
+
+class SvnCommandPath(svncommon.SvnPathBase):
+ """ path implementation that offers access to (possibly remote) subversion
+ repositories. """
+
+ _lsrevcache = BuildcostAccessCache(maxentries=128)
+ _lsnorevcache = AgingCache(maxentries=1000, maxseconds=60.0)
+
+ def __new__(cls, path, rev=None, auth=None):
+ self = object.__new__(cls)
+ if isinstance(path, cls):
+ rev = path.rev
+ auth = path.auth
+ path = path.strpath
+ svncommon.checkbadchars(path)
+ path = path.rstrip('/')
+ self.strpath = path
+ self.rev = rev
+ self.auth = auth
+ return self
+
+ def __repr__(self):
+ if self.rev == -1:
+ return 'svnurl(%r)' % self.strpath
+ else:
+ return 'svnurl(%r, %r)' % (self.strpath, self.rev)
+
+ def _svnwithrev(self, cmd, *args):
+ """ execute an svn command, append our own url and revision """
+ if self.rev is None:
+ return self._svnwrite(cmd, *args)
+ else:
+ args = ['-r', self.rev] + list(args)
+ return self._svnwrite(cmd, *args)
+
+ def _svnwrite(self, cmd, *args):
+ """ execute an svn command, append our own url """
+ l = ['svn %s' % cmd]
+ args = ['"%s"' % self._escape(item) for item in args]
+ l.extend(args)
+ l.append('"%s"' % self._encodedurl())
+ # fixing the locale because we can't otherwise parse
+ string = " ".join(l)
+ if DEBUG:
+ print("execing %s" % string)
+ out = self._svncmdexecauth(string)
+ return out
+
+ def _svncmdexecauth(self, cmd):
+ """ execute an svn command 'as is' """
+ cmd = svncommon.fixlocale() + cmd
+ if self.auth is not None:
+ cmd += ' ' + self.auth.makecmdoptions()
+ return self._cmdexec(cmd)
+
+ def _cmdexec(self, cmd):
+ try:
+ out = process.cmdexec(cmd)
+ except py.process.cmdexec.Error:
+ e = sys.exc_info()[1]
+ if (e.err.find('File Exists') != -1 or
+ e.err.find('File already exists') != -1):
+ raise py.error.EEXIST(self)
+ raise
+ return out
+
+ def _svnpopenauth(self, cmd):
+ """ execute an svn command, return a pipe for reading stdin """
+ cmd = svncommon.fixlocale() + cmd
+ if self.auth is not None:
+ cmd += ' ' + self.auth.makecmdoptions()
+ return self._popen(cmd)
+
+ def _popen(self, cmd):
+ return os.popen(cmd)
+
+ def _encodedurl(self):
+ return self._escape(self.strpath)
+
+ def _norev_delentry(self, path):
+ auth = self.auth and self.auth.makecmdoptions() or None
+ self._lsnorevcache.delentry((str(path), auth))
+
+ def open(self, mode='r'):
+ """ return an opened file with the given mode. """
+ if mode not in ("r", "rU",):
+ raise ValueError("mode %r not supported" % (mode,))
+ assert self.check(file=1) # svn cat returns an empty file otherwise
+ if self.rev is None:
+ return self._svnpopenauth('svn cat "%s"' % (
+ self._escape(self.strpath), ))
+ else:
+ return self._svnpopenauth('svn cat -r %s "%s"' % (
+ self.rev, self._escape(self.strpath)))
+
+ def dirpath(self, *args, **kwargs):
+ """ return the directory path of the current path joined
+ with any given path arguments.
+ """
+ l = self.strpath.split(self.sep)
+ if len(l) < 4:
+ raise py.error.EINVAL(self, "base is not valid")
+ elif len(l) == 4:
+ return self.join(*args, **kwargs)
+ else:
+ return self.new(basename='').join(*args, **kwargs)
+
+ # modifying methods (cache must be invalidated)
+ def mkdir(self, *args, **kwargs):
+ """ create & return the directory joined with args.
+ pass a 'msg' keyword argument to set the commit message.
+ """
+ commit_msg = kwargs.get('msg', "mkdir by py lib invocation")
+ createpath = self.join(*args)
+ createpath._svnwrite('mkdir', '-m', commit_msg)
+ self._norev_delentry(createpath.dirpath())
+ return createpath
+
+ def copy(self, target, msg='copied by py lib invocation'):
+ """ copy path to target with checkin message msg."""
+ if getattr(target, 'rev', None) is not None:
+ raise py.error.EINVAL(target, "revisions are immutable")
+ self._svncmdexecauth('svn copy -m "%s" "%s" "%s"' %(msg,
+ self._escape(self), self._escape(target)))
+ self._norev_delentry(target.dirpath())
+
+ def rename(self, target, msg="renamed by py lib invocation"):
+ """ rename this path to target with checkin message msg. """
+ if getattr(self, 'rev', None) is not None:
+ raise py.error.EINVAL(self, "revisions are immutable")
+ self._svncmdexecauth('svn move -m "%s" --force "%s" "%s"' %(
+ msg, self._escape(self), self._escape(target)))
+ self._norev_delentry(self.dirpath())
+ self._norev_delentry(self)
+
+ def remove(self, rec=1, msg='removed by py lib invocation'):
+ """ remove a file or directory (or a directory tree if rec=1) with
+checkin message msg."""
+ if self.rev is not None:
+ raise py.error.EINVAL(self, "revisions are immutable")
+ self._svncmdexecauth('svn rm -m "%s" "%s"' %(msg, self._escape(self)))
+ self._norev_delentry(self.dirpath())
+
+ def export(self, topath):
+ """ export to a local path
+
+ topath should not exist prior to calling this, returns a
+ py.path.local instance
+ """
+ topath = py.path.local(topath)
+ args = ['"%s"' % (self._escape(self),),
+ '"%s"' % (self._escape(topath),)]
+ if self.rev is not None:
+ args = ['-r', str(self.rev)] + args
+ self._svncmdexecauth('svn export %s' % (' '.join(args),))
+ return topath
+
+ def ensure(self, *args, **kwargs):
+ """ ensure that an args-joined path exists (by default as
+ a file). If you specify a keyword argument 'dir=True'
+ then the path is forced to be a directory path.
+ """
+ if getattr(self, 'rev', None) is not None:
+ raise py.error.EINVAL(self, "revisions are immutable")
+ target = self.join(*args)
+ dir = kwargs.get('dir', 0)
+ for x in target.parts(reverse=True):
+ if x.check():
+ break
+ else:
+ raise py.error.ENOENT(target, "has not any valid base!")
+ if x == target:
+ if not x.check(dir=dir):
+ raise dir and py.error.ENOTDIR(x) or py.error.EISDIR(x)
+ return x
+ tocreate = target.relto(x)
+ basename = tocreate.split(self.sep, 1)[0]
+ tempdir = py.path.local.mkdtemp()
+ try:
+ tempdir.ensure(tocreate, dir=dir)
+ cmd = 'svn import -m "%s" "%s" "%s"' % (
+ "ensure %s" % self._escape(tocreate),
+ self._escape(tempdir.join(basename)),
+ x.join(basename)._encodedurl())
+ self._svncmdexecauth(cmd)
+ self._norev_delentry(x)
+ finally:
+ tempdir.remove()
+ return target
+
+ # end of modifying methods
+ def _propget(self, name):
+ res = self._svnwithrev('propget', name)
+ return res[:-1] # strip trailing newline
+
+ def _proplist(self):
+ res = self._svnwithrev('proplist')
+ lines = res.split('\n')
+ lines = [x.strip() for x in lines[1:]]
+ return svncommon.PropListDict(self, lines)
+
+ def info(self):
+ """ return an Info structure with svn-provided information. """
+ parent = self.dirpath()
+ nameinfo_seq = parent._listdir_nameinfo()
+ bn = self.basename
+ for name, info in nameinfo_seq:
+ if name == bn:
+ return info
+ raise py.error.ENOENT(self)
+
+
+ def _listdir_nameinfo(self):
+ """ return sequence of name-info directory entries of self """
+ def builder():
+ try:
+ res = self._svnwithrev('ls', '-v')
+ except process.cmdexec.Error:
+ e = sys.exc_info()[1]
+ if e.err.find('non-existent in that revision') != -1:
+ raise py.error.ENOENT(self, e.err)
+ elif e.err.find("E200009:") != -1:
+ raise py.error.ENOENT(self, e.err)
+ elif e.err.find('File not found') != -1:
+ raise py.error.ENOENT(self, e.err)
+ elif e.err.find('not part of a repository')!=-1:
+ raise py.error.ENOENT(self, e.err)
+ elif e.err.find('Unable to open')!=-1:
+ raise py.error.ENOENT(self, e.err)
+ elif e.err.lower().find('method not allowed')!=-1:
+ raise py.error.EACCES(self, e.err)
+ raise py.error.Error(e.err)
+ lines = res.split('\n')
+ nameinfo_seq = []
+ for lsline in lines:
+ if lsline:
+ info = InfoSvnCommand(lsline)
+ if info._name != '.': # svn 1.5 produces '.' dirs,
+ nameinfo_seq.append((info._name, info))
+ nameinfo_seq.sort()
+ return nameinfo_seq
+ auth = self.auth and self.auth.makecmdoptions() or None
+ if self.rev is not None:
+ return self._lsrevcache.getorbuild((self.strpath, self.rev, auth),
+ builder)
+ else:
+ return self._lsnorevcache.getorbuild((self.strpath, auth),
+ builder)
+
+ def listdir(self, fil=None, sort=None):
+ """ list directory contents, possibly filter by the given fil func
+ and possibly sorted.
+ """
+ if isinstance(fil, str):
+ fil = common.FNMatcher(fil)
+ nameinfo_seq = self._listdir_nameinfo()
+ if len(nameinfo_seq) == 1:
+ name, info = nameinfo_seq[0]
+ if name == self.basename and info.kind == 'file':
+ #if not self.check(dir=1):
+ raise py.error.ENOTDIR(self)
+ paths = [self.join(name) for (name, info) in nameinfo_seq]
+ if fil:
+ paths = [x for x in paths if fil(x)]
+ self._sortlist(paths, sort)
+ return paths
+
+
+ def log(self, rev_start=None, rev_end=1, verbose=False):
+ """ return a list of LogEntry instances for this path.
+rev_start is the starting revision (defaulting to the first one).
+rev_end is the last revision (defaulting to HEAD).
+if verbose is True, then the LogEntry instances also know which files changed.
+"""
+ assert self.check() #make it simpler for the pipe
+ rev_start = rev_start is None and "HEAD" or rev_start
+ rev_end = rev_end is None and "HEAD" or rev_end
+
+ if rev_start == "HEAD" and rev_end == 1:
+ rev_opt = ""
+ else:
+ rev_opt = "-r %s:%s" % (rev_start, rev_end)
+ verbose_opt = verbose and "-v" or ""
+ xmlpipe = self._svnpopenauth('svn log --xml %s %s "%s"' %
+ (rev_opt, verbose_opt, self.strpath))
+ from xml.dom import minidom
+ tree = minidom.parse(xmlpipe)
+ result = []
+ for logentry in filter(None, tree.firstChild.childNodes):
+ if logentry.nodeType == logentry.ELEMENT_NODE:
+ result.append(svncommon.LogEntry(logentry))
+ return result
+
+#01234567890123456789012345678901234567890123467
+# 2256 hpk 165 Nov 24 17:55 __init__.py
+# XXX spotted by Guido, SVN 1.3.0 has different aligning, breaks the code!!!
+# 1312 johnny 1627 May 05 14:32 test_decorators.py
+#
+class InfoSvnCommand:
+ # the '0?' part in the middle is an indication of whether the resource is
+ # locked, see 'svn help ls'
+ lspattern = re.compile(
+ r'^ *(?P<rev>\d+) +(?P<author>.+?) +(0? *(?P<size>\d+))? '
+ '*(?P<date>\w+ +\d{2} +[\d:]+) +(?P<file>.*)$')
+ def __init__(self, line):
+ # this is a typical line from 'svn ls http://...'
+ #_ 1127 jum 0 Jul 13 15:28 branch/
+ match = self.lspattern.match(line)
+ data = match.groupdict()
+ self._name = data['file']
+ if self._name[-1] == '/':
+ self._name = self._name[:-1]
+ self.kind = 'dir'
+ else:
+ self.kind = 'file'
+ #self.has_props = l.pop(0) == 'P'
+ self.created_rev = int(data['rev'])
+ self.last_author = data['author']
+ self.size = data['size'] and int(data['size']) or 0
+ self.mtime = parse_time_with_missing_year(data['date'])
+ self.time = self.mtime * 1000000
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+
+#____________________________________________________
+#
+# helper functions
+#____________________________________________________
+def parse_time_with_missing_year(timestr):
+ """ analyze the time part from a single line of "svn ls -v"
+ the svn output doesn't show the year makes the 'timestr'
+ ambigous.
+ """
+ import calendar
+ t_now = time.gmtime()
+
+ tparts = timestr.split()
+ month = time.strptime(tparts.pop(0), '%b')[1]
+ day = time.strptime(tparts.pop(0), '%d')[2]
+ last = tparts.pop(0) # year or hour:minute
+ try:
+ if ":" in last:
+ raise ValueError()
+ year = time.strptime(last, '%Y')[0]
+ hour = minute = 0
+ except ValueError:
+ hour, minute = time.strptime(last, '%H:%M')[3:5]
+ year = t_now[0]
+
+ t_result = (year, month, day, hour, minute, 0,0,0,0)
+ if t_result > t_now:
+ year -= 1
+ t_result = (year, month, day, hour, minute, 0,0,0,0)
+ return calendar.timegm(t_result)
+
+class PathEntry:
+ def __init__(self, ppart):
+ self.strpath = ppart.firstChild.nodeValue.encode('UTF-8')
+ self.action = ppart.getAttribute('action').encode('UTF-8')
+ if self.action == 'A':
+ self.copyfrom_path = ppart.getAttribute('copyfrom-path').encode('UTF-8')
+ if self.copyfrom_path:
+ self.copyfrom_rev = int(ppart.getAttribute('copyfrom-rev'))
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_path/svnwc.py b/tests/wpt/web-platform-tests/tools/py/py/_path/svnwc.py
new file mode 100644
index 00000000000..00d3b4bbaf3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_path/svnwc.py
@@ -0,0 +1,1240 @@
+"""
+svn-Command based Implementation of a Subversion WorkingCopy Path.
+
+ SvnWCCommandPath is the main class.
+
+"""
+
+import os, sys, time, re, calendar
+import py
+import subprocess
+from py._path import common
+
+#-----------------------------------------------------------
+# Caching latest repository revision and repo-paths
+# (getting them is slow with the current implementations)
+#
+# XXX make mt-safe
+#-----------------------------------------------------------
+
+class cache:
+ proplist = {}
+ info = {}
+ entries = {}
+ prop = {}
+
+class RepoEntry:
+ def __init__(self, url, rev, timestamp):
+ self.url = url
+ self.rev = rev
+ self.timestamp = timestamp
+
+ def __str__(self):
+ return "repo: %s;%s %s" %(self.url, self.rev, self.timestamp)
+
+class RepoCache:
+ """ The Repocache manages discovered repository paths
+ and their revisions. If inside a timeout the cache
+ will even return the revision of the root.
+ """
+ timeout = 20 # seconds after which we forget that we know the last revision
+
+ def __init__(self):
+ self.repos = []
+
+ def clear(self):
+ self.repos = []
+
+ def put(self, url, rev, timestamp=None):
+ if rev is None:
+ return
+ if timestamp is None:
+ timestamp = time.time()
+
+ for entry in self.repos:
+ if url == entry.url:
+ entry.timestamp = timestamp
+ entry.rev = rev
+ #print "set repo", entry
+ break
+ else:
+ entry = RepoEntry(url, rev, timestamp)
+ self.repos.append(entry)
+ #print "appended repo", entry
+
+ def get(self, url):
+ now = time.time()
+ for entry in self.repos:
+ if url.startswith(entry.url):
+ if now < entry.timestamp + self.timeout:
+ #print "returning immediate Etrny", entry
+ return entry.url, entry.rev
+ return entry.url, -1
+ return url, -1
+
+repositories = RepoCache()
+
+
+# svn support code
+
+ALLOWED_CHARS = "_ -/\\=$.~+%" #add characters as necessary when tested
+if sys.platform == "win32":
+ ALLOWED_CHARS += ":"
+ALLOWED_CHARS_HOST = ALLOWED_CHARS + '@:'
+
+def _getsvnversion(ver=[]):
+ try:
+ return ver[0]
+ except IndexError:
+ v = py.process.cmdexec("svn -q --version")
+ v.strip()
+ v = '.'.join(v.split('.')[:2])
+ ver.append(v)
+ return v
+
+def _escape_helper(text):
+ text = str(text)
+ if py.std.sys.platform != 'win32':
+ text = str(text).replace('$', '\\$')
+ return text
+
+def _check_for_bad_chars(text, allowed_chars=ALLOWED_CHARS):
+ for c in str(text):
+ if c.isalnum():
+ continue
+ if c in allowed_chars:
+ continue
+ return True
+ return False
+
+def checkbadchars(url):
+ # (hpk) not quite sure about the exact purpose, guido w.?
+ proto, uri = url.split("://", 1)
+ if proto != "file":
+ host, uripath = uri.split('/', 1)
+ # only check for bad chars in the non-protocol parts
+ if (_check_for_bad_chars(host, ALLOWED_CHARS_HOST) \
+ or _check_for_bad_chars(uripath, ALLOWED_CHARS)):
+ raise ValueError("bad char in %r" % (url, ))
+
+
+#_______________________________________________________________
+
+class SvnPathBase(common.PathBase):
+ """ Base implementation for SvnPath implementations. """
+ sep = '/'
+
+ def _geturl(self):
+ return self.strpath
+ url = property(_geturl, None, None, "url of this svn-path.")
+
+ def __str__(self):
+ """ return a string representation (including rev-number) """
+ return self.strpath
+
+ def __hash__(self):
+ return hash(self.strpath)
+
+ def new(self, **kw):
+ """ create a modified version of this path. A 'rev' argument
+ indicates a new revision.
+ the following keyword arguments modify various path parts::
+
+ http://host.com/repo/path/file.ext
+ |-----------------------| dirname
+ |------| basename
+ |--| purebasename
+ |--| ext
+ """
+ obj = object.__new__(self.__class__)
+ obj.rev = kw.get('rev', self.rev)
+ obj.auth = kw.get('auth', self.auth)
+ dirname, basename, purebasename, ext = self._getbyspec(
+ "dirname,basename,purebasename,ext")
+ if 'basename' in kw:
+ if 'purebasename' in kw or 'ext' in kw:
+ raise ValueError("invalid specification %r" % kw)
+ else:
+ pb = kw.setdefault('purebasename', purebasename)
+ ext = kw.setdefault('ext', ext)
+ if ext and not ext.startswith('.'):
+ ext = '.' + ext
+ kw['basename'] = pb + ext
+
+ kw.setdefault('dirname', dirname)
+ kw.setdefault('sep', self.sep)
+ if kw['basename']:
+ obj.strpath = "%(dirname)s%(sep)s%(basename)s" % kw
+ else:
+ obj.strpath = "%(dirname)s" % kw
+ return obj
+
+ def _getbyspec(self, spec):
+ """ get specified parts of the path. 'arg' is a string
+ with comma separated path parts. The parts are returned
+ in exactly the order of the specification.
+
+ you may specify the following parts:
+
+ http://host.com/repo/path/file.ext
+ |-----------------------| dirname
+ |------| basename
+ |--| purebasename
+ |--| ext
+ """
+ res = []
+ parts = self.strpath.split(self.sep)
+ for name in spec.split(','):
+ name = name.strip()
+ if name == 'dirname':
+ res.append(self.sep.join(parts[:-1]))
+ elif name == 'basename':
+ res.append(parts[-1])
+ else:
+ basename = parts[-1]
+ i = basename.rfind('.')
+ if i == -1:
+ purebasename, ext = basename, ''
+ else:
+ purebasename, ext = basename[:i], basename[i:]
+ if name == 'purebasename':
+ res.append(purebasename)
+ elif name == 'ext':
+ res.append(ext)
+ else:
+ raise NameError("Don't know part %r" % name)
+ return res
+
+ def __eq__(self, other):
+ """ return true if path and rev attributes each match """
+ return (str(self) == str(other) and
+ (self.rev == other.rev or self.rev == other.rev))
+
+ def __ne__(self, other):
+ return not self == other
+
+ def join(self, *args):
+ """ return a new Path (with the same revision) which is composed
+ of the self Path followed by 'args' path components.
+ """
+ if not args:
+ return self
+
+ args = tuple([arg.strip(self.sep) for arg in args])
+ parts = (self.strpath, ) + args
+ newpath = self.__class__(self.sep.join(parts), self.rev, self.auth)
+ return newpath
+
+ def propget(self, name):
+ """ return the content of the given property. """
+ value = self._propget(name)
+ return value
+
+ def proplist(self):
+ """ list all property names. """
+ content = self._proplist()
+ return content
+
+ def size(self):
+ """ Return the size of the file content of the Path. """
+ return self.info().size
+
+ def mtime(self):
+ """ Return the last modification time of the file. """
+ return self.info().mtime
+
+ # shared help methods
+
+ def _escape(self, cmd):
+ return _escape_helper(cmd)
+
+
+ #def _childmaxrev(self):
+ # """ return maximum revision number of childs (or self.rev if no childs) """
+ # rev = self.rev
+ # for name, info in self._listdir_nameinfo():
+ # rev = max(rev, info.created_rev)
+ # return rev
+
+ #def _getlatestrevision(self):
+ # """ return latest repo-revision for this path. """
+ # url = self.strpath
+ # path = self.__class__(url, None)
+ #
+ # # we need a long walk to find the root-repo and revision
+ # while 1:
+ # try:
+ # rev = max(rev, path._childmaxrev())
+ # previous = path
+ # path = path.dirpath()
+ # except (IOError, process.cmdexec.Error):
+ # break
+ # if rev is None:
+ # raise IOError, "could not determine newest repo revision for %s" % self
+ # return rev
+
+ class Checkers(common.Checkers):
+ def dir(self):
+ try:
+ return self.path.info().kind == 'dir'
+ except py.error.Error:
+ return self._listdirworks()
+
+ def _listdirworks(self):
+ try:
+ self.path.listdir()
+ except py.error.ENOENT:
+ return False
+ else:
+ return True
+
+ def file(self):
+ try:
+ return self.path.info().kind == 'file'
+ except py.error.ENOENT:
+ return False
+
+ def exists(self):
+ try:
+ return self.path.info()
+ except py.error.ENOENT:
+ return self._listdirworks()
+
+def parse_apr_time(timestr):
+ i = timestr.rfind('.')
+ if i == -1:
+ raise ValueError("could not parse %s" % timestr)
+ timestr = timestr[:i]
+ parsedtime = time.strptime(timestr, "%Y-%m-%dT%H:%M:%S")
+ return time.mktime(parsedtime)
+
+class PropListDict(dict):
+ """ a Dictionary which fetches values (InfoSvnCommand instances) lazily"""
+ def __init__(self, path, keynames):
+ dict.__init__(self, [(x, None) for x in keynames])
+ self.path = path
+
+ def __getitem__(self, key):
+ value = dict.__getitem__(self, key)
+ if value is None:
+ value = self.path.propget(key)
+ dict.__setitem__(self, key, value)
+ return value
+
+def fixlocale():
+ if sys.platform != 'win32':
+ return 'LC_ALL=C '
+ return ''
+
+# some nasty chunk of code to solve path and url conversion and quoting issues
+ILLEGAL_CHARS = '* | \ / : < > ? \t \n \x0b \x0c \r'.split(' ')
+if os.sep in ILLEGAL_CHARS:
+ ILLEGAL_CHARS.remove(os.sep)
+ISWINDOWS = sys.platform == 'win32'
+_reg_allow_disk = re.compile(r'^([a-z]\:\\)?[^:]+$', re.I)
+def _check_path(path):
+ illegal = ILLEGAL_CHARS[:]
+ sp = path.strpath
+ if ISWINDOWS:
+ illegal.remove(':')
+ if not _reg_allow_disk.match(sp):
+ raise ValueError('path may not contain a colon (:)')
+ for char in sp:
+ if char not in string.printable or char in illegal:
+ raise ValueError('illegal character %r in path' % (char,))
+
+def path_to_fspath(path, addat=True):
+ _check_path(path)
+ sp = path.strpath
+ if addat and path.rev != -1:
+ sp = '%s@%s' % (sp, path.rev)
+ elif addat:
+ sp = '%s@HEAD' % (sp,)
+ return sp
+
+def url_from_path(path):
+ fspath = path_to_fspath(path, False)
+ quote = py.std.urllib.quote
+ if ISWINDOWS:
+ match = _reg_allow_disk.match(fspath)
+ fspath = fspath.replace('\\', '/')
+ if match.group(1):
+ fspath = '/%s%s' % (match.group(1).replace('\\', '/'),
+ quote(fspath[len(match.group(1)):]))
+ else:
+ fspath = quote(fspath)
+ else:
+ fspath = quote(fspath)
+ if path.rev != -1:
+ fspath = '%s@%s' % (fspath, path.rev)
+ else:
+ fspath = '%s@HEAD' % (fspath,)
+ return 'file://%s' % (fspath,)
+
+class SvnAuth(object):
+ """ container for auth information for Subversion """
+ def __init__(self, username, password, cache_auth=True, interactive=True):
+ self.username = username
+ self.password = password
+ self.cache_auth = cache_auth
+ self.interactive = interactive
+
+ def makecmdoptions(self):
+ uname = self.username.replace('"', '\\"')
+ passwd = self.password.replace('"', '\\"')
+ ret = []
+ if uname:
+ ret.append('--username="%s"' % (uname,))
+ if passwd:
+ ret.append('--password="%s"' % (passwd,))
+ if not self.cache_auth:
+ ret.append('--no-auth-cache')
+ if not self.interactive:
+ ret.append('--non-interactive')
+ return ' '.join(ret)
+
+ def __str__(self):
+ return "<SvnAuth username=%s ...>" %(self.username,)
+
+rex_blame = re.compile(r'\s*(\d+)\s*(\S+) (.*)')
+
+class SvnWCCommandPath(common.PathBase):
+ """ path implementation offering access/modification to svn working copies.
+ It has methods similar to the functions in os.path and similar to the
+ commands of the svn client.
+ """
+ sep = os.sep
+
+ def __new__(cls, wcpath=None, auth=None):
+ self = object.__new__(cls)
+ if isinstance(wcpath, cls):
+ if wcpath.__class__ == cls:
+ return wcpath
+ wcpath = wcpath.localpath
+ if _check_for_bad_chars(str(wcpath),
+ ALLOWED_CHARS):
+ raise ValueError("bad char in wcpath %s" % (wcpath, ))
+ self.localpath = py.path.local(wcpath)
+ self.auth = auth
+ return self
+
+ strpath = property(lambda x: str(x.localpath), None, None, "string path")
+ rev = property(lambda x: x.info(usecache=0).rev, None, None, "revision")
+
+ def __eq__(self, other):
+ return self.localpath == getattr(other, 'localpath', None)
+
+ def _geturl(self):
+ if getattr(self, '_url', None) is None:
+ info = self.info()
+ self._url = info.url #SvnPath(info.url, info.rev)
+ assert isinstance(self._url, py.builtin._basestring)
+ return self._url
+
+ url = property(_geturl, None, None, "url of this WC item")
+
+ def _escape(self, cmd):
+ return _escape_helper(cmd)
+
+ def dump(self, obj):
+ """ pickle object into path location"""
+ return self.localpath.dump(obj)
+
+ def svnurl(self):
+ """ return current SvnPath for this WC-item. """
+ info = self.info()
+ return py.path.svnurl(info.url)
+
+ def __repr__(self):
+ return "svnwc(%r)" % (self.strpath) # , self._url)
+
+ def __str__(self):
+ return str(self.localpath)
+
+ def _makeauthoptions(self):
+ if self.auth is None:
+ return ''
+ return self.auth.makecmdoptions()
+
+ def _authsvn(self, cmd, args=None):
+ args = args and list(args) or []
+ args.append(self._makeauthoptions())
+ return self._svn(cmd, *args)
+
+ def _svn(self, cmd, *args):
+ l = ['svn %s' % cmd]
+ args = [self._escape(item) for item in args]
+ l.extend(args)
+ l.append('"%s"' % self._escape(self.strpath))
+ # try fixing the locale because we can't otherwise parse
+ string = fixlocale() + " ".join(l)
+ try:
+ try:
+ key = 'LC_MESSAGES'
+ hold = os.environ.get(key)
+ os.environ[key] = 'C'
+ out = py.process.cmdexec(string)
+ finally:
+ if hold:
+ os.environ[key] = hold
+ else:
+ del os.environ[key]
+ except py.process.cmdexec.Error:
+ e = sys.exc_info()[1]
+ strerr = e.err.lower()
+ if strerr.find('not found') != -1:
+ raise py.error.ENOENT(self)
+ elif strerr.find("E200009:") != -1:
+ raise py.error.ENOENT(self)
+ if (strerr.find('file exists') != -1 or
+ strerr.find('file already exists') != -1 or
+ strerr.find('w150002:') != -1 or
+ strerr.find("can't create directory") != -1):
+ raise py.error.EEXIST(strerr) #self)
+ raise
+ return out
+
+ def switch(self, url):
+ """ switch to given URL. """
+ self._authsvn('switch', [url])
+
+ def checkout(self, url=None, rev=None):
+ """ checkout from url to local wcpath. """
+ args = []
+ if url is None:
+ url = self.url
+ if rev is None or rev == -1:
+ if (py.std.sys.platform != 'win32' and
+ _getsvnversion() == '1.3'):
+ url += "@HEAD"
+ else:
+ if _getsvnversion() == '1.3':
+ url += "@%d" % rev
+ else:
+ args.append('-r' + str(rev))
+ args.append(url)
+ self._authsvn('co', args)
+
+ def update(self, rev='HEAD', interactive=True):
+ """ update working copy item to given revision. (None -> HEAD). """
+ opts = ['-r', rev]
+ if not interactive:
+ opts.append("--non-interactive")
+ self._authsvn('up', opts)
+
+ def write(self, content, mode='w'):
+ """ write content into local filesystem wc. """
+ self.localpath.write(content, mode)
+
+ def dirpath(self, *args):
+ """ return the directory Path of the current Path. """
+ return self.__class__(self.localpath.dirpath(*args), auth=self.auth)
+
+ def _ensuredirs(self):
+ parent = self.dirpath()
+ if parent.check(dir=0):
+ parent._ensuredirs()
+ if self.check(dir=0):
+ self.mkdir()
+ return self
+
+ def ensure(self, *args, **kwargs):
+ """ ensure that an args-joined path exists (by default as
+ a file). if you specify a keyword argument 'directory=True'
+ then the path is forced to be a directory path.
+ """
+ p = self.join(*args)
+ if p.check():
+ if p.check(versioned=False):
+ p.add()
+ return p
+ if kwargs.get('dir', 0):
+ return p._ensuredirs()
+ parent = p.dirpath()
+ parent._ensuredirs()
+ p.write("")
+ p.add()
+ return p
+
+ def mkdir(self, *args):
+ """ create & return the directory joined with args. """
+ if args:
+ return self.join(*args).mkdir()
+ else:
+ self._svn('mkdir')
+ return self
+
+ def add(self):
+ """ add ourself to svn """
+ self._svn('add')
+
+ def remove(self, rec=1, force=1):
+ """ remove a file or a directory tree. 'rec'ursive is
+ ignored and considered always true (because of
+ underlying svn semantics.
+ """
+ assert rec, "svn cannot remove non-recursively"
+ if not self.check(versioned=True):
+ # not added to svn (anymore?), just remove
+ py.path.local(self).remove()
+ return
+ flags = []
+ if force:
+ flags.append('--force')
+ self._svn('remove', *flags)
+
+ def copy(self, target):
+ """ copy path to target."""
+ py.process.cmdexec("svn copy %s %s" %(str(self), str(target)))
+
+ def rename(self, target):
+ """ rename this path to target. """
+ py.process.cmdexec("svn move --force %s %s" %(str(self), str(target)))
+
+ def lock(self):
+ """ set a lock (exclusive) on the resource """
+ out = self._authsvn('lock').strip()
+ if not out:
+ # warning or error, raise exception
+ raise ValueError("unknown error in svn lock command")
+
+ def unlock(self):
+ """ unset a previously set lock """
+ out = self._authsvn('unlock').strip()
+ if out.startswith('svn:'):
+ # warning or error, raise exception
+ raise Exception(out[4:])
+
+ def cleanup(self):
+ """ remove any locks from the resource """
+ # XXX should be fixed properly!!!
+ try:
+ self.unlock()
+ except:
+ pass
+
+ def status(self, updates=0, rec=0, externals=0):
+ """ return (collective) Status object for this file. """
+ # http://svnbook.red-bean.com/book.html#svn-ch-3-sect-4.3.1
+ # 2201 2192 jum test
+ # XXX
+ if externals:
+ raise ValueError("XXX cannot perform status() "
+ "on external items yet")
+ else:
+ #1.2 supports: externals = '--ignore-externals'
+ externals = ''
+ if rec:
+ rec= ''
+ else:
+ rec = '--non-recursive'
+
+ # XXX does not work on all subversion versions
+ #if not externals:
+ # externals = '--ignore-externals'
+
+ if updates:
+ updates = '-u'
+ else:
+ updates = ''
+
+ try:
+ cmd = 'status -v --xml --no-ignore %s %s %s' % (
+ updates, rec, externals)
+ out = self._authsvn(cmd)
+ except py.process.cmdexec.Error:
+ cmd = 'status -v --no-ignore %s %s %s' % (
+ updates, rec, externals)
+ out = self._authsvn(cmd)
+ rootstatus = WCStatus(self).fromstring(out, self)
+ else:
+ rootstatus = XMLWCStatus(self).fromstring(out, self)
+ return rootstatus
+
+ def diff(self, rev=None):
+ """ return a diff of the current path against revision rev (defaulting
+ to the last one).
+ """
+ args = []
+ if rev is not None:
+ args.append("-r %d" % rev)
+ out = self._authsvn('diff', args)
+ return out
+
+ def blame(self):
+ """ return a list of tuples of three elements:
+ (revision, commiter, line)
+ """
+ out = self._svn('blame')
+ result = []
+ blamelines = out.splitlines()
+ reallines = py.path.svnurl(self.url).readlines()
+ for i, (blameline, line) in enumerate(
+ zip(blamelines, reallines)):
+ m = rex_blame.match(blameline)
+ if not m:
+ raise ValueError("output line %r of svn blame does not match "
+ "expected format" % (line, ))
+ rev, name, _ = m.groups()
+ result.append((int(rev), name, line))
+ return result
+
+ _rex_commit = re.compile(r'.*Committed revision (\d+)\.$', re.DOTALL)
+ def commit(self, msg='', rec=1):
+ """ commit with support for non-recursive commits """
+ # XXX i guess escaping should be done better here?!?
+ cmd = 'commit -m "%s" --force-log' % (msg.replace('"', '\\"'),)
+ if not rec:
+ cmd += ' -N'
+ out = self._authsvn(cmd)
+ try:
+ del cache.info[self]
+ except KeyError:
+ pass
+ if out:
+ m = self._rex_commit.match(out)
+ return int(m.group(1))
+
+ def propset(self, name, value, *args):
+ """ set property name to value on this path. """
+ d = py.path.local.mkdtemp()
+ try:
+ p = d.join('value')
+ p.write(value)
+ self._svn('propset', name, '--file', str(p), *args)
+ finally:
+ d.remove()
+
+ def propget(self, name):
+ """ get property name on this path. """
+ res = self._svn('propget', name)
+ return res[:-1] # strip trailing newline
+
+ def propdel(self, name):
+ """ delete property name on this path. """
+ res = self._svn('propdel', name)
+ return res[:-1] # strip trailing newline
+
+ def proplist(self, rec=0):
+ """ return a mapping of property names to property values.
+If rec is True, then return a dictionary mapping sub-paths to such mappings.
+"""
+ if rec:
+ res = self._svn('proplist -R')
+ return make_recursive_propdict(self, res)
+ else:
+ res = self._svn('proplist')
+ lines = res.split('\n')
+ lines = [x.strip() for x in lines[1:]]
+ return PropListDict(self, lines)
+
+ def revert(self, rec=0):
+ """ revert the local changes of this path. if rec is True, do so
+recursively. """
+ if rec:
+ result = self._svn('revert -R')
+ else:
+ result = self._svn('revert')
+ return result
+
+ def new(self, **kw):
+ """ create a modified version of this path. A 'rev' argument
+ indicates a new revision.
+ the following keyword arguments modify various path parts:
+
+ http://host.com/repo/path/file.ext
+ |-----------------------| dirname
+ |------| basename
+ |--| purebasename
+ |--| ext
+ """
+ if kw:
+ localpath = self.localpath.new(**kw)
+ else:
+ localpath = self.localpath
+ return self.__class__(localpath, auth=self.auth)
+
+ def join(self, *args, **kwargs):
+ """ return a new Path (with the same revision) which is composed
+ of the self Path followed by 'args' path components.
+ """
+ if not args:
+ return self
+ localpath = self.localpath.join(*args, **kwargs)
+ return self.__class__(localpath, auth=self.auth)
+
+ def info(self, usecache=1):
+ """ return an Info structure with svn-provided information. """
+ info = usecache and cache.info.get(self)
+ if not info:
+ try:
+ output = self._svn('info')
+ except py.process.cmdexec.Error:
+ e = sys.exc_info()[1]
+ if e.err.find('Path is not a working copy directory') != -1:
+ raise py.error.ENOENT(self, e.err)
+ elif e.err.find("is not under version control") != -1:
+ raise py.error.ENOENT(self, e.err)
+ raise
+ # XXX SVN 1.3 has output on stderr instead of stdout (while it does
+ # return 0!), so a bit nasty, but we assume no output is output
+ # to stderr...
+ if (output.strip() == '' or
+ output.lower().find('not a versioned resource') != -1):
+ raise py.error.ENOENT(self, output)
+ info = InfoSvnWCCommand(output)
+
+ # Can't reliably compare on Windows without access to win32api
+ if py.std.sys.platform != 'win32':
+ if info.path != self.localpath:
+ raise py.error.ENOENT(self, "not a versioned resource:" +
+ " %s != %s" % (info.path, self.localpath))
+ cache.info[self] = info
+ return info
+
+ def listdir(self, fil=None, sort=None):
+ """ return a sequence of Paths.
+
+ listdir will return either a tuple or a list of paths
+ depending on implementation choices.
+ """
+ if isinstance(fil, str):
+ fil = common.FNMatcher(fil)
+ # XXX unify argument naming with LocalPath.listdir
+ def notsvn(path):
+ return path.basename != '.svn'
+
+ paths = []
+ for localpath in self.localpath.listdir(notsvn):
+ p = self.__class__(localpath, auth=self.auth)
+ if notsvn(p) and (not fil or fil(p)):
+ paths.append(p)
+ self._sortlist(paths, sort)
+ return paths
+
+ def open(self, mode='r'):
+ """ return an opened file with the given mode. """
+ return open(self.strpath, mode)
+
+ def _getbyspec(self, spec):
+ return self.localpath._getbyspec(spec)
+
+ class Checkers(py.path.local.Checkers):
+ def __init__(self, path):
+ self.svnwcpath = path
+ self.path = path.localpath
+ def versioned(self):
+ try:
+ s = self.svnwcpath.info()
+ except (py.error.ENOENT, py.error.EEXIST):
+ return False
+ except py.process.cmdexec.Error:
+ e = sys.exc_info()[1]
+ if e.err.find('is not a working copy')!=-1:
+ return False
+ if e.err.lower().find('not a versioned resource') != -1:
+ return False
+ raise
+ else:
+ return True
+
+ def log(self, rev_start=None, rev_end=1, verbose=False):
+ """ return a list of LogEntry instances for this path.
+rev_start is the starting revision (defaulting to the first one).
+rev_end is the last revision (defaulting to HEAD).
+if verbose is True, then the LogEntry instances also know which files changed.
+"""
+ assert self.check() # make it simpler for the pipe
+ rev_start = rev_start is None and "HEAD" or rev_start
+ rev_end = rev_end is None and "HEAD" or rev_end
+ if rev_start == "HEAD" and rev_end == 1:
+ rev_opt = ""
+ else:
+ rev_opt = "-r %s:%s" % (rev_start, rev_end)
+ verbose_opt = verbose and "-v" or ""
+ locale_env = fixlocale()
+ # some blather on stderr
+ auth_opt = self._makeauthoptions()
+ #stdin, stdout, stderr = os.popen3(locale_env +
+ # 'svn log --xml %s %s %s "%s"' % (
+ # rev_opt, verbose_opt, auth_opt,
+ # self.strpath))
+ cmd = locale_env + 'svn log --xml %s %s %s "%s"' % (
+ rev_opt, verbose_opt, auth_opt, self.strpath)
+
+ popen = subprocess.Popen(cmd,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ shell=True,
+ )
+ stdout, stderr = popen.communicate()
+ stdout = py.builtin._totext(stdout, sys.getdefaultencoding())
+ minidom,ExpatError = importxml()
+ try:
+ tree = minidom.parseString(stdout)
+ except ExpatError:
+ raise ValueError('no such revision')
+ result = []
+ for logentry in filter(None, tree.firstChild.childNodes):
+ if logentry.nodeType == logentry.ELEMENT_NODE:
+ result.append(LogEntry(logentry))
+ return result
+
+ def size(self):
+ """ Return the size of the file content of the Path. """
+ return self.info().size
+
+ def mtime(self):
+ """ Return the last modification time of the file. """
+ return self.info().mtime
+
+ def __hash__(self):
+ return hash((self.strpath, self.__class__, self.auth))
+
+
+class WCStatus:
+ attrnames = ('modified','added', 'conflict', 'unchanged', 'external',
+ 'deleted', 'prop_modified', 'unknown', 'update_available',
+ 'incomplete', 'kindmismatch', 'ignored', 'locked', 'replaced'
+ )
+
+ def __init__(self, wcpath, rev=None, modrev=None, author=None):
+ self.wcpath = wcpath
+ self.rev = rev
+ self.modrev = modrev
+ self.author = author
+
+ for name in self.attrnames:
+ setattr(self, name, [])
+
+ def allpath(self, sort=True, **kw):
+ d = {}
+ for name in self.attrnames:
+ if name not in kw or kw[name]:
+ for path in getattr(self, name):
+ d[path] = 1
+ l = d.keys()
+ if sort:
+ l.sort()
+ return l
+
+ # XXX a bit scary to assume there's always 2 spaces between username and
+ # path, however with win32 allowing spaces in user names there doesn't
+ # seem to be a more solid approach :(
+ _rex_status = re.compile(r'\s+(\d+|-)\s+(\S+)\s+(.+?)\s{2,}(.*)')
+
+ def fromstring(data, rootwcpath, rev=None, modrev=None, author=None):
+ """ return a new WCStatus object from data 's'
+ """
+ rootstatus = WCStatus(rootwcpath, rev, modrev, author)
+ update_rev = None
+ for line in data.split('\n'):
+ if not line.strip():
+ continue
+ #print "processing %r" % line
+ flags, rest = line[:8], line[8:]
+ # first column
+ c0,c1,c2,c3,c4,c5,x6,c7 = flags
+ #if '*' in line:
+ # print "flags", repr(flags), "rest", repr(rest)
+
+ if c0 in '?XI':
+ fn = line.split(None, 1)[1]
+ if c0 == '?':
+ wcpath = rootwcpath.join(fn, abs=1)
+ rootstatus.unknown.append(wcpath)
+ elif c0 == 'X':
+ wcpath = rootwcpath.__class__(
+ rootwcpath.localpath.join(fn, abs=1),
+ auth=rootwcpath.auth)
+ rootstatus.external.append(wcpath)
+ elif c0 == 'I':
+ wcpath = rootwcpath.join(fn, abs=1)
+ rootstatus.ignored.append(wcpath)
+
+ continue
+
+ #elif c0 in '~!' or c4 == 'S':
+ # raise NotImplementedError("received flag %r" % c0)
+
+ m = WCStatus._rex_status.match(rest)
+ if not m:
+ if c7 == '*':
+ fn = rest.strip()
+ wcpath = rootwcpath.join(fn, abs=1)
+ rootstatus.update_available.append(wcpath)
+ continue
+ if line.lower().find('against revision:')!=-1:
+ update_rev = int(rest.split(':')[1].strip())
+ continue
+ if line.lower().find('status on external') > -1:
+ # XXX not sure what to do here... perhaps we want to
+ # store some state instead of just continuing, as right
+ # now it makes the top-level external get added twice
+ # (once as external, once as 'normal' unchanged item)
+ # because of the way SVN presents external items
+ continue
+ # keep trying
+ raise ValueError("could not parse line %r" % line)
+ else:
+ rev, modrev, author, fn = m.groups()
+ wcpath = rootwcpath.join(fn, abs=1)
+ #assert wcpath.check()
+ if c0 == 'M':
+ assert wcpath.check(file=1), "didn't expect a directory with changed content here"
+ rootstatus.modified.append(wcpath)
+ elif c0 == 'A' or c3 == '+' :
+ rootstatus.added.append(wcpath)
+ elif c0 == 'D':
+ rootstatus.deleted.append(wcpath)
+ elif c0 == 'C':
+ rootstatus.conflict.append(wcpath)
+ elif c0 == '~':
+ rootstatus.kindmismatch.append(wcpath)
+ elif c0 == '!':
+ rootstatus.incomplete.append(wcpath)
+ elif c0 == 'R':
+ rootstatus.replaced.append(wcpath)
+ elif not c0.strip():
+ rootstatus.unchanged.append(wcpath)
+ else:
+ raise NotImplementedError("received flag %r" % c0)
+
+ if c1 == 'M':
+ rootstatus.prop_modified.append(wcpath)
+ # XXX do we cover all client versions here?
+ if c2 == 'L' or c5 == 'K':
+ rootstatus.locked.append(wcpath)
+ if c7 == '*':
+ rootstatus.update_available.append(wcpath)
+
+ if wcpath == rootwcpath:
+ rootstatus.rev = rev
+ rootstatus.modrev = modrev
+ rootstatus.author = author
+ if update_rev:
+ rootstatus.update_rev = update_rev
+ continue
+ return rootstatus
+ fromstring = staticmethod(fromstring)
+
+class XMLWCStatus(WCStatus):
+ def fromstring(data, rootwcpath, rev=None, modrev=None, author=None):
+ """ parse 'data' (XML string as outputted by svn st) into a status obj
+ """
+ # XXX for externals, the path is shown twice: once
+ # with external information, and once with full info as if
+ # the item was a normal non-external... the current way of
+ # dealing with this issue is by ignoring it - this does make
+ # externals appear as external items as well as 'normal',
+ # unchanged ones in the status object so this is far from ideal
+ rootstatus = WCStatus(rootwcpath, rev, modrev, author)
+ update_rev = None
+ minidom, ExpatError = importxml()
+ try:
+ doc = minidom.parseString(data)
+ except ExpatError:
+ e = sys.exc_info()[1]
+ raise ValueError(str(e))
+ urevels = doc.getElementsByTagName('against')
+ if urevels:
+ rootstatus.update_rev = urevels[-1].getAttribute('revision')
+ for entryel in doc.getElementsByTagName('entry'):
+ path = entryel.getAttribute('path')
+ statusel = entryel.getElementsByTagName('wc-status')[0]
+ itemstatus = statusel.getAttribute('item')
+
+ if itemstatus == 'unversioned':
+ wcpath = rootwcpath.join(path, abs=1)
+ rootstatus.unknown.append(wcpath)
+ continue
+ elif itemstatus == 'external':
+ wcpath = rootwcpath.__class__(
+ rootwcpath.localpath.join(path, abs=1),
+ auth=rootwcpath.auth)
+ rootstatus.external.append(wcpath)
+ continue
+ elif itemstatus == 'ignored':
+ wcpath = rootwcpath.join(path, abs=1)
+ rootstatus.ignored.append(wcpath)
+ continue
+ elif itemstatus == 'incomplete':
+ wcpath = rootwcpath.join(path, abs=1)
+ rootstatus.incomplete.append(wcpath)
+ continue
+
+ rev = statusel.getAttribute('revision')
+ if itemstatus == 'added' or itemstatus == 'none':
+ rev = '0'
+ modrev = '?'
+ author = '?'
+ date = ''
+ elif itemstatus == "replaced":
+ pass
+ else:
+ #print entryel.toxml()
+ commitel = entryel.getElementsByTagName('commit')[0]
+ if commitel:
+ modrev = commitel.getAttribute('revision')
+ author = ''
+ author_els = commitel.getElementsByTagName('author')
+ if author_els:
+ for c in author_els[0].childNodes:
+ author += c.nodeValue
+ date = ''
+ for c in commitel.getElementsByTagName('date')[0]\
+ .childNodes:
+ date += c.nodeValue
+
+ wcpath = rootwcpath.join(path, abs=1)
+
+ assert itemstatus != 'modified' or wcpath.check(file=1), (
+ 'did\'t expect a directory with changed content here')
+
+ itemattrname = {
+ 'normal': 'unchanged',
+ 'unversioned': 'unknown',
+ 'conflicted': 'conflict',
+ 'none': 'added',
+ }.get(itemstatus, itemstatus)
+
+ attr = getattr(rootstatus, itemattrname)
+ attr.append(wcpath)
+
+ propsstatus = statusel.getAttribute('props')
+ if propsstatus not in ('none', 'normal'):
+ rootstatus.prop_modified.append(wcpath)
+
+ if wcpath == rootwcpath:
+ rootstatus.rev = rev
+ rootstatus.modrev = modrev
+ rootstatus.author = author
+ rootstatus.date = date
+
+ # handle repos-status element (remote info)
+ rstatusels = entryel.getElementsByTagName('repos-status')
+ if rstatusels:
+ rstatusel = rstatusels[0]
+ ritemstatus = rstatusel.getAttribute('item')
+ if ritemstatus in ('added', 'modified'):
+ rootstatus.update_available.append(wcpath)
+
+ lockels = entryel.getElementsByTagName('lock')
+ if len(lockels):
+ rootstatus.locked.append(wcpath)
+
+ return rootstatus
+ fromstring = staticmethod(fromstring)
+
+class InfoSvnWCCommand:
+ def __init__(self, output):
+ # Path: test
+ # URL: http://codespeak.net/svn/std.path/trunk/dist/std.path/test
+ # Repository UUID: fd0d7bf2-dfb6-0310-8d31-b7ecfe96aada
+ # Revision: 2151
+ # Node Kind: directory
+ # Schedule: normal
+ # Last Changed Author: hpk
+ # Last Changed Rev: 2100
+ # Last Changed Date: 2003-10-27 20:43:14 +0100 (Mon, 27 Oct 2003)
+ # Properties Last Updated: 2003-11-03 14:47:48 +0100 (Mon, 03 Nov 2003)
+
+ d = {}
+ for line in output.split('\n'):
+ if not line.strip():
+ continue
+ key, value = line.split(':', 1)
+ key = key.lower().replace(' ', '')
+ value = value.strip()
+ d[key] = value
+ try:
+ self.url = d['url']
+ except KeyError:
+ raise ValueError("Not a versioned resource")
+ #raise ValueError, "Not a versioned resource %r" % path
+ self.kind = d['nodekind'] == 'directory' and 'dir' or d['nodekind']
+ try:
+ self.rev = int(d['revision'])
+ except KeyError:
+ self.rev = None
+
+ self.path = py.path.local(d['path'])
+ self.size = self.path.size()
+ if 'lastchangedrev' in d:
+ self.created_rev = int(d['lastchangedrev'])
+ if 'lastchangedauthor' in d:
+ self.last_author = d['lastchangedauthor']
+ if 'lastchangeddate' in d:
+ self.mtime = parse_wcinfotime(d['lastchangeddate'])
+ self.time = self.mtime * 1000000
+
+ def __eq__(self, other):
+ return self.__dict__ == other.__dict__
+
+def parse_wcinfotime(timestr):
+ """ Returns seconds since epoch, UTC. """
+ # example: 2003-10-27 20:43:14 +0100 (Mon, 27 Oct 2003)
+ m = re.match(r'(\d+-\d+-\d+ \d+:\d+:\d+) ([+-]\d+) .*', timestr)
+ if not m:
+ raise ValueError("timestring %r does not match" % timestr)
+ timestr, timezone = m.groups()
+ # do not handle timezone specially, return value should be UTC
+ parsedtime = time.strptime(timestr, "%Y-%m-%d %H:%M:%S")
+ return calendar.timegm(parsedtime)
+
+def make_recursive_propdict(wcroot,
+ output,
+ rex = re.compile("Properties on '(.*)':")):
+ """ Return a dictionary of path->PropListDict mappings. """
+ lines = [x for x in output.split('\n') if x]
+ pdict = {}
+ while lines:
+ line = lines.pop(0)
+ m = rex.match(line)
+ if not m:
+ raise ValueError("could not parse propget-line: %r" % line)
+ path = m.groups()[0]
+ wcpath = wcroot.join(path, abs=1)
+ propnames = []
+ while lines and lines[0].startswith(' '):
+ propname = lines.pop(0).strip()
+ propnames.append(propname)
+ assert propnames, "must have found properties!"
+ pdict[wcpath] = PropListDict(wcpath, propnames)
+ return pdict
+
+
+def importxml(cache=[]):
+ if cache:
+ return cache
+ from xml.dom import minidom
+ from xml.parsers.expat import ExpatError
+ cache.extend([minidom, ExpatError])
+ return cache
+
+class LogEntry:
+ def __init__(self, logentry):
+ self.rev = int(logentry.getAttribute('revision'))
+ for lpart in filter(None, logentry.childNodes):
+ if lpart.nodeType == lpart.ELEMENT_NODE:
+ if lpart.nodeName == 'author':
+ self.author = lpart.firstChild.nodeValue
+ elif lpart.nodeName == 'msg':
+ if lpart.firstChild:
+ self.msg = lpart.firstChild.nodeValue
+ else:
+ self.msg = ''
+ elif lpart.nodeName == 'date':
+ #2003-07-29T20:05:11.598637Z
+ timestr = lpart.firstChild.nodeValue
+ self.date = parse_apr_time(timestr)
+ elif lpart.nodeName == 'paths':
+ self.strpaths = []
+ for ppart in filter(None, lpart.childNodes):
+ if ppart.nodeType == ppart.ELEMENT_NODE:
+ self.strpaths.append(PathEntry(ppart))
+ def __repr__(self):
+ return '<Logentry rev=%d author=%s date=%s>' % (
+ self.rev, self.author, self.date)
+
+
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_process/__init__.py b/tests/wpt/web-platform-tests/tools/py/py/_process/__init__.py
new file mode 100644
index 00000000000..86c714ad1ae
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_process/__init__.py
@@ -0,0 +1 @@
+""" high-level sub-process handling """
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_process/cmdexec.py b/tests/wpt/web-platform-tests/tools/py/py/_process/cmdexec.py
new file mode 100644
index 00000000000..f83a2494029
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_process/cmdexec.py
@@ -0,0 +1,49 @@
+import sys
+import subprocess
+import py
+from subprocess import Popen, PIPE
+
+def cmdexec(cmd):
+ """ return unicode output of executing 'cmd' in a separate process.
+
+ raise cmdexec.Error exeception if the command failed.
+ the exception will provide an 'err' attribute containing
+ the error-output from the command.
+ if the subprocess module does not provide a proper encoding/unicode strings
+ sys.getdefaultencoding() will be used, if that does not exist, 'UTF-8'.
+ """
+ process = subprocess.Popen(cmd, shell=True,
+ universal_newlines=True,
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ out, err = process.communicate()
+ if sys.version_info[0] < 3: # on py3 we get unicode strings, on py2 not
+ try:
+ default_encoding = sys.getdefaultencoding() # jython may not have it
+ except AttributeError:
+ default_encoding = sys.stdout.encoding or 'UTF-8'
+ out = unicode(out, process.stdout.encoding or default_encoding)
+ err = unicode(err, process.stderr.encoding or default_encoding)
+ status = process.poll()
+ if status:
+ raise ExecutionFailed(status, status, cmd, out, err)
+ return out
+
+class ExecutionFailed(py.error.Error):
+ def __init__(self, status, systemstatus, cmd, out, err):
+ Exception.__init__(self)
+ self.status = status
+ self.systemstatus = systemstatus
+ self.cmd = cmd
+ self.err = err
+ self.out = out
+
+ def __str__(self):
+ return "ExecutionFailed: %d %s\n%s" %(self.status, self.cmd, self.err)
+
+# export the exception under the name 'py.process.cmdexec.Error'
+cmdexec.Error = ExecutionFailed
+try:
+ ExecutionFailed.__module__ = 'py.process.cmdexec'
+ ExecutionFailed.__name__ = 'Error'
+except (AttributeError, TypeError):
+ pass
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_process/forkedfunc.py b/tests/wpt/web-platform-tests/tools/py/py/_process/forkedfunc.py
new file mode 100644
index 00000000000..1c285306884
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_process/forkedfunc.py
@@ -0,0 +1,120 @@
+
+"""
+ ForkedFunc provides a way to run a function in a forked process
+ and get at its return value, stdout and stderr output as well
+ as signals and exitstatusus.
+"""
+
+import py
+import os
+import sys
+import marshal
+
+
+def get_unbuffered_io(fd, filename):
+ f = open(str(filename), "w")
+ if fd != f.fileno():
+ os.dup2(f.fileno(), fd)
+ class AutoFlush:
+ def write(self, data):
+ f.write(data)
+ f.flush()
+ def __getattr__(self, name):
+ return getattr(f, name)
+ return AutoFlush()
+
+
+class ForkedFunc:
+ EXITSTATUS_EXCEPTION = 3
+
+
+ def __init__(self, fun, args=None, kwargs=None, nice_level=0,
+ child_on_start=None, child_on_exit=None):
+ if args is None:
+ args = []
+ if kwargs is None:
+ kwargs = {}
+ self.fun = fun
+ self.args = args
+ self.kwargs = kwargs
+ self.tempdir = tempdir = py.path.local.mkdtemp()
+ self.RETVAL = tempdir.ensure('retval')
+ self.STDOUT = tempdir.ensure('stdout')
+ self.STDERR = tempdir.ensure('stderr')
+
+ pid = os.fork()
+ if pid: # in parent process
+ self.pid = pid
+ else: # in child process
+ self.pid = None
+ self._child(nice_level, child_on_start, child_on_exit)
+
+ def _child(self, nice_level, child_on_start, child_on_exit):
+ # right now we need to call a function, but first we need to
+ # map all IO that might happen
+ sys.stdout = stdout = get_unbuffered_io(1, self.STDOUT)
+ sys.stderr = stderr = get_unbuffered_io(2, self.STDERR)
+ retvalf = self.RETVAL.open("wb")
+ EXITSTATUS = 0
+ try:
+ if nice_level:
+ os.nice(nice_level)
+ try:
+ if child_on_start is not None:
+ child_on_start()
+ retval = self.fun(*self.args, **self.kwargs)
+ retvalf.write(marshal.dumps(retval))
+ if child_on_exit is not None:
+ child_on_exit()
+ except:
+ excinfo = py.code.ExceptionInfo()
+ stderr.write(str(excinfo._getreprcrash()))
+ EXITSTATUS = self.EXITSTATUS_EXCEPTION
+ finally:
+ stdout.close()
+ stderr.close()
+ retvalf.close()
+ os.close(1)
+ os.close(2)
+ os._exit(EXITSTATUS)
+
+ def waitfinish(self, waiter=os.waitpid):
+ pid, systemstatus = waiter(self.pid, 0)
+ if systemstatus:
+ if os.WIFSIGNALED(systemstatus):
+ exitstatus = os.WTERMSIG(systemstatus) + 128
+ else:
+ exitstatus = os.WEXITSTATUS(systemstatus)
+ else:
+ exitstatus = 0
+ signal = systemstatus & 0x7f
+ if not exitstatus and not signal:
+ retval = self.RETVAL.open('rb')
+ try:
+ retval_data = retval.read()
+ finally:
+ retval.close()
+ retval = marshal.loads(retval_data)
+ else:
+ retval = None
+ stdout = self.STDOUT.read()
+ stderr = self.STDERR.read()
+ self._removetemp()
+ return Result(exitstatus, signal, retval, stdout, stderr)
+
+ def _removetemp(self):
+ if self.tempdir.check():
+ self.tempdir.remove()
+
+ def __del__(self):
+ if self.pid is not None: # only clean up in main process
+ self._removetemp()
+
+
+class Result(object):
+ def __init__(self, exitstatus, signal, retval, stdout, stderr):
+ self.exitstatus = exitstatus
+ self.signal = signal
+ self.retval = retval
+ self.out = stdout
+ self.err = stderr
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_process/killproc.py b/tests/wpt/web-platform-tests/tools/py/py/_process/killproc.py
new file mode 100644
index 00000000000..18e8310b5f6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_process/killproc.py
@@ -0,0 +1,23 @@
+import py
+import os, sys
+
+if sys.platform == "win32" or getattr(os, '_name', '') == 'nt':
+ try:
+ import ctypes
+ except ImportError:
+ def dokill(pid):
+ py.process.cmdexec("taskkill /F /PID %d" %(pid,))
+ else:
+ def dokill(pid):
+ PROCESS_TERMINATE = 1
+ handle = ctypes.windll.kernel32.OpenProcess(
+ PROCESS_TERMINATE, False, pid)
+ ctypes.windll.kernel32.TerminateProcess(handle, -1)
+ ctypes.windll.kernel32.CloseHandle(handle)
+else:
+ def dokill(pid):
+ os.kill(pid, 15)
+
+def kill(pid):
+ """ kill process by id. """
+ dokill(pid)
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_std.py b/tests/wpt/web-platform-tests/tools/py/py/_std.py
new file mode 100644
index 00000000000..97a9853323b
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_std.py
@@ -0,0 +1,18 @@
+import sys
+
+class Std(object):
+ """ makes top-level python modules available as an attribute,
+ importing them on first access.
+ """
+
+ def __init__(self):
+ self.__dict__ = sys.modules
+
+ def __getattr__(self, name):
+ try:
+ m = __import__(name)
+ except ImportError:
+ raise AttributeError("py.std: could not import %s" % name)
+ return m
+
+std = Std()
diff --git a/tests/wpt/web-platform-tests/tools/py/py/_xmlgen.py b/tests/wpt/web-platform-tests/tools/py/py/_xmlgen.py
new file mode 100644
index 00000000000..2ffcaa14b8e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/_xmlgen.py
@@ -0,0 +1,253 @@
+"""
+module for generating and serializing xml and html structures
+by using simple python objects.
+
+(c) holger krekel, holger at merlinux eu. 2009
+"""
+import sys, re
+
+if sys.version_info >= (3,0):
+ def u(s):
+ return s
+ def unicode(x, errors=None):
+ if hasattr(x, '__unicode__'):
+ return x.__unicode__()
+ return str(x)
+else:
+ def u(s):
+ return unicode(s)
+ unicode = unicode
+
+
+class NamespaceMetaclass(type):
+ def __getattr__(self, name):
+ if name[:1] == '_':
+ raise AttributeError(name)
+ if self == Namespace:
+ raise ValueError("Namespace class is abstract")
+ tagspec = self.__tagspec__
+ if tagspec is not None and name not in tagspec:
+ raise AttributeError(name)
+ classattr = {}
+ if self.__stickyname__:
+ classattr['xmlname'] = name
+ cls = type(name, (self.__tagclass__,), classattr)
+ setattr(self, name, cls)
+ return cls
+
+class Tag(list):
+ class Attr(object):
+ def __init__(self, **kwargs):
+ self.__dict__.update(kwargs)
+
+ def __init__(self, *args, **kwargs):
+ super(Tag, self).__init__(args)
+ self.attr = self.Attr(**kwargs)
+
+ def __unicode__(self):
+ return self.unicode(indent=0)
+ __str__ = __unicode__
+
+ def unicode(self, indent=2):
+ l = []
+ SimpleUnicodeVisitor(l.append, indent).visit(self)
+ return u("").join(l)
+
+ def __repr__(self):
+ name = self.__class__.__name__
+ return "<%r tag object %d>" % (name, id(self))
+
+Namespace = NamespaceMetaclass('Namespace', (object, ), {
+ '__tagspec__': None,
+ '__tagclass__': Tag,
+ '__stickyname__': False,
+})
+
+class HtmlTag(Tag):
+ def unicode(self, indent=2):
+ l = []
+ HtmlVisitor(l.append, indent, shortempty=False).visit(self)
+ return u("").join(l)
+
+# exported plain html namespace
+class html(Namespace):
+ __tagclass__ = HtmlTag
+ __stickyname__ = True
+ __tagspec__ = dict([(x,1) for x in (
+ 'a,abbr,acronym,address,applet,area,b,bdo,big,blink,'
+ 'blockquote,body,br,button,caption,center,cite,code,col,'
+ 'colgroup,comment,dd,del,dfn,dir,div,dl,dt,em,embed,'
+ 'fieldset,font,form,frameset,h1,h2,h3,h4,h5,h6,head,html,'
+ 'i,iframe,img,input,ins,kbd,label,legend,li,link,listing,'
+ 'map,marquee,menu,meta,multicol,nobr,noembed,noframes,'
+ 'noscript,object,ol,optgroup,option,p,pre,q,s,script,'
+ 'select,small,span,strike,strong,style,sub,sup,table,'
+ 'tbody,td,textarea,tfoot,th,thead,title,tr,tt,u,ul,xmp,'
+ 'base,basefont,frame,hr,isindex,param,samp,var'
+ ).split(',') if x])
+
+ class Style(object):
+ def __init__(self, **kw):
+ for x, y in kw.items():
+ x = x.replace('_', '-')
+ setattr(self, x, y)
+
+
+class raw(object):
+ """just a box that can contain a unicode string that will be
+ included directly in the output"""
+ def __init__(self, uniobj):
+ self.uniobj = uniobj
+
+class SimpleUnicodeVisitor(object):
+ """ recursive visitor to write unicode. """
+ def __init__(self, write, indent=0, curindent=0, shortempty=True):
+ self.write = write
+ self.cache = {}
+ self.visited = {} # for detection of recursion
+ self.indent = indent
+ self.curindent = curindent
+ self.parents = []
+ self.shortempty = shortempty # short empty tags or not
+
+ def visit(self, node):
+ """ dispatcher on node's class/bases name. """
+ cls = node.__class__
+ try:
+ visitmethod = self.cache[cls]
+ except KeyError:
+ for subclass in cls.__mro__:
+ visitmethod = getattr(self, subclass.__name__, None)
+ if visitmethod is not None:
+ break
+ else:
+ visitmethod = self.__object
+ self.cache[cls] = visitmethod
+ visitmethod(node)
+
+ # the default fallback handler is marked private
+ # to avoid clashes with the tag name object
+ def __object(self, obj):
+ #self.write(obj)
+ self.write(escape(unicode(obj)))
+
+ def raw(self, obj):
+ self.write(obj.uniobj)
+
+ def list(self, obj):
+ assert id(obj) not in self.visited
+ self.visited[id(obj)] = 1
+ for elem in obj:
+ self.visit(elem)
+
+ def Tag(self, tag):
+ assert id(tag) not in self.visited
+ try:
+ tag.parent = self.parents[-1]
+ except IndexError:
+ tag.parent = None
+ self.visited[id(tag)] = 1
+ tagname = getattr(tag, 'xmlname', tag.__class__.__name__)
+ if self.curindent and not self._isinline(tagname):
+ self.write("\n" + u(' ') * self.curindent)
+ if tag:
+ self.curindent += self.indent
+ self.write(u('<%s%s>') % (tagname, self.attributes(tag)))
+ self.parents.append(tag)
+ for x in tag:
+ self.visit(x)
+ self.parents.pop()
+ self.write(u('</%s>') % tagname)
+ self.curindent -= self.indent
+ else:
+ nameattr = tagname+self.attributes(tag)
+ if self._issingleton(tagname):
+ self.write(u('<%s/>') % (nameattr,))
+ else:
+ self.write(u('<%s></%s>') % (nameattr, tagname))
+
+ def attributes(self, tag):
+ # serialize attributes
+ attrlist = dir(tag.attr)
+ attrlist.sort()
+ l = []
+ for name in attrlist:
+ res = self.repr_attribute(tag.attr, name)
+ if res is not None:
+ l.append(res)
+ l.extend(self.getstyle(tag))
+ return u("").join(l)
+
+ def repr_attribute(self, attrs, name):
+ if name[:2] != '__':
+ value = getattr(attrs, name)
+ if name.endswith('_'):
+ name = name[:-1]
+ if isinstance(value, raw):
+ insert = value.uniobj
+ else:
+ insert = escape(unicode(value))
+ return ' %s="%s"' % (name, insert)
+
+ def getstyle(self, tag):
+ """ return attribute list suitable for styling. """
+ try:
+ styledict = tag.style.__dict__
+ except AttributeError:
+ return []
+ else:
+ stylelist = [x+': ' + y for x,y in styledict.items()]
+ return [u(' style="%s"') % u('; ').join(stylelist)]
+
+ def _issingleton(self, tagname):
+ """can (and will) be overridden in subclasses"""
+ return self.shortempty
+
+ def _isinline(self, tagname):
+ """can (and will) be overridden in subclasses"""
+ return False
+
+class HtmlVisitor(SimpleUnicodeVisitor):
+
+ single = dict([(x, 1) for x in
+ ('br,img,area,param,col,hr,meta,link,base,'
+ 'input,frame').split(',')])
+ inline = dict([(x, 1) for x in
+ ('a abbr acronym b basefont bdo big br cite code dfn em font '
+ 'i img input kbd label q s samp select small span strike '
+ 'strong sub sup textarea tt u var'.split(' '))])
+
+ def repr_attribute(self, attrs, name):
+ if name == 'class_':
+ value = getattr(attrs, name)
+ if value is None:
+ return
+ return super(HtmlVisitor, self).repr_attribute(attrs, name)
+
+ def _issingleton(self, tagname):
+ return tagname in self.single
+
+ def _isinline(self, tagname):
+ return tagname in self.inline
+
+
+class _escape:
+ def __init__(self):
+ self.escape = {
+ u('"') : u('&quot;'), u('<') : u('&lt;'), u('>') : u('&gt;'),
+ u('&') : u('&amp;'), u("'") : u('&apos;'),
+ }
+ self.charef_rex = re.compile(u("|").join(self.escape.keys()))
+
+ def _replacer(self, match):
+ return self.escape[match.group(0)]
+
+ def __call__(self, ustring):
+ """ xml-escape the given unicode string. """
+ try:
+ ustring = unicode(ustring)
+ except UnicodeDecodeError:
+ ustring = unicode(ustring, 'utf-8', errors='replace')
+ return self.charef_rex.sub(self._replacer, ustring)
+
+escape = _escape()
diff --git a/tests/wpt/web-platform-tests/tools/py/py/test.py b/tests/wpt/web-platform-tests/tools/py/py/test.py
new file mode 100644
index 00000000000..aa5beb1789f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/py/test.py
@@ -0,0 +1,10 @@
+import sys
+if __name__ == '__main__':
+ import pytest
+ sys.exit(pytest.main())
+else:
+ import sys, pytest
+ sys.modules['py.test'] = pytest
+
+# for more API entry points see the 'tests' definition
+# in __init__.py
diff --git a/tests/wpt/web-platform-tests/tools/py/setup.cfg b/tests/wpt/web-platform-tests/tools/py/setup.cfg
new file mode 100644
index 00000000000..272e488f363
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/setup.cfg
@@ -0,0 +1,5 @@
+[wheel]
+universal = 1
+
+[devpi:upload]
+formats=sdist.tgz,bdist_wheel
diff --git a/tests/wpt/web-platform-tests/tools/py/setup.py b/tests/wpt/web-platform-tests/tools/py/setup.py
new file mode 100644
index 00000000000..06f0885cd71
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/setup.py
@@ -0,0 +1,38 @@
+import os, sys
+
+from setuptools import setup
+
+def main():
+ setup(
+ name='py',
+ description='library with cross-python path, ini-parsing, io, code, log facilities',
+ long_description = open('README.txt').read(),
+ version='1.4.31',
+ url='http://pylib.readthedocs.org/',
+ license='MIT license',
+ platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
+ author='holger krekel, Ronny Pfannschmidt, Benjamin Peterson and others',
+ author_email='pytest-dev@python.org',
+ classifiers=['Development Status :: 6 - Mature',
+ 'Intended Audience :: Developers',
+ 'License :: OSI Approved :: MIT License',
+ 'Operating System :: POSIX',
+ 'Operating System :: Microsoft :: Windows',
+ 'Operating System :: MacOS :: MacOS X',
+ 'Topic :: Software Development :: Testing',
+ 'Topic :: Software Development :: Libraries',
+ 'Topic :: Utilities',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 3'],
+ packages=['py',
+ 'py._code',
+ 'py._io',
+ 'py._log',
+ 'py._path',
+ 'py._process',
+ ],
+ zip_safe=False,
+ )
+
+if __name__ == '__main__':
+ main()
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/code/test_assertion.py b/tests/wpt/web-platform-tests/tools/py/testing/code/test_assertion.py
new file mode 100644
index 00000000000..e2154d0fc7a
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/code/test_assertion.py
@@ -0,0 +1,308 @@
+import pytest, py
+
+def exvalue():
+ return py.std.sys.exc_info()[1]
+
+def f():
+ return 2
+
+def test_assert():
+ try:
+ assert f() == 3
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith('assert 2 == 3\n')
+
+
+def test_assert_within_finally():
+ excinfo = py.test.raises(ZeroDivisionError, """
+ try:
+ 1/0
+ finally:
+ i = 42
+ """)
+ s = excinfo.exconly()
+ assert py.std.re.search("division.+by zero", s) is not None
+
+ #def g():
+ # A.f()
+ #excinfo = getexcinfo(TypeError, g)
+ #msg = getmsg(excinfo)
+ #assert msg.find("must be called with A") != -1
+
+
+def test_assert_multiline_1():
+ try:
+ assert (f() ==
+ 3)
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith('assert 2 == 3\n')
+
+def test_assert_multiline_2():
+ try:
+ assert (f() == (4,
+ 3)[-1])
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith('assert 2 ==')
+
+def test_in():
+ try:
+ assert "hi" in [1, 2]
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith("assert 'hi' in")
+
+def test_is():
+ try:
+ assert 1 is 2
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith("assert 1 is 2")
+
+
+@py.test.mark.skipif("sys.version_info < (2,6)")
+def test_attrib():
+ class Foo(object):
+ b = 1
+ i = Foo()
+ try:
+ assert i.b == 2
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith("assert 1 == 2")
+
+@py.test.mark.skipif("sys.version_info < (2,6)")
+def test_attrib_inst():
+ class Foo(object):
+ b = 1
+ try:
+ assert Foo().b == 2
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith("assert 1 == 2")
+
+def test_len():
+ l = list(range(42))
+ try:
+ assert len(l) == 100
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert s.startswith("assert 42 == 100")
+ assert "where 42 = len([" in s
+
+
+def test_assert_keyword_arg():
+ def f(x=3):
+ return False
+ try:
+ assert f(x=5)
+ except AssertionError:
+ e = exvalue()
+ assert "x=5" in e.msg
+
+# These tests should both fail, but should fail nicely...
+class WeirdRepr:
+ def __repr__(self):
+ return '<WeirdRepr\nsecond line>'
+
+def bug_test_assert_repr():
+ v = WeirdRepr()
+ try:
+ assert v == 1
+ except AssertionError:
+ e = exvalue()
+ assert e.msg.find('WeirdRepr') != -1
+ assert e.msg.find('second line') != -1
+ assert 0
+
+def test_assert_non_string():
+ try:
+ assert 0, ['list']
+ except AssertionError:
+ e = exvalue()
+ assert e.msg.find("list") != -1
+
+def test_assert_implicit_multiline():
+ try:
+ x = [1,2,3]
+ assert x != [1,
+ 2, 3]
+ except AssertionError:
+ e = exvalue()
+ assert e.msg.find('assert [1, 2, 3] !=') != -1
+
+
+def test_assert_with_brokenrepr_arg():
+ class BrokenRepr:
+ def __repr__(self): 0 / 0
+ e = AssertionError(BrokenRepr())
+ if e.msg.find("broken __repr__") == -1:
+ py.test.fail("broken __repr__ not handle correctly")
+
+def test_multiple_statements_per_line():
+ try:
+ a = 1; assert a == 2
+ except AssertionError:
+ e = exvalue()
+ assert "assert 1 == 2" in e.msg
+
+def test_power():
+ try:
+ assert 2**3 == 7
+ except AssertionError:
+ e = exvalue()
+ assert "assert (2 ** 3) == 7" in e.msg
+
+
+class TestView:
+
+ def setup_class(cls):
+ cls.View = py.test.importorskip("py._code._assertionold").View
+
+ def test_class_dispatch(self):
+ ### Use a custom class hierarchy with existing instances
+
+ class Picklable(self.View):
+ pass
+
+ class Simple(Picklable):
+ __view__ = object
+ def pickle(self):
+ return repr(self.__obj__)
+
+ class Seq(Picklable):
+ __view__ = list, tuple, dict
+ def pickle(self):
+ return ';'.join(
+ [Picklable(item).pickle() for item in self.__obj__])
+
+ class Dict(Seq):
+ __view__ = dict
+ def pickle(self):
+ return Seq.pickle(self) + '!' + Seq(self.values()).pickle()
+
+ assert Picklable(123).pickle() == '123'
+ assert Picklable([1,[2,3],4]).pickle() == '1;2;3;4'
+ assert Picklable({1:2}).pickle() == '1!2'
+
+ def test_viewtype_class_hierarchy(self):
+ # Use a custom class hierarchy based on attributes of existing instances
+ class Operation:
+ "Existing class that I don't want to change."
+ def __init__(self, opname, *args):
+ self.opname = opname
+ self.args = args
+
+ existing = [Operation('+', 4, 5),
+ Operation('getitem', '', 'join'),
+ Operation('setattr', 'x', 'y', 3),
+ Operation('-', 12, 1)]
+
+ class PyOp(self.View):
+ def __viewkey__(self):
+ return self.opname
+ def generate(self):
+ return '%s(%s)' % (self.opname, ', '.join(map(repr, self.args)))
+
+ class PyBinaryOp(PyOp):
+ __view__ = ('+', '-', '*', '/')
+ def generate(self):
+ return '%s %s %s' % (self.args[0], self.opname, self.args[1])
+
+ codelines = [PyOp(op).generate() for op in existing]
+ assert codelines == ["4 + 5", "getitem('', 'join')",
+ "setattr('x', 'y', 3)", "12 - 1"]
+
+def test_underscore_api():
+ py.code._AssertionError
+ py.code._reinterpret_old # used by pypy
+ py.code._reinterpret
+
+@py.test.mark.skipif("sys.version_info < (2,6)")
+def test_assert_customizable_reprcompare(monkeypatch):
+ util = pytest.importorskip("_pytest.assertion.util")
+ monkeypatch.setattr(util, '_reprcompare', lambda *args: 'hello')
+ try:
+ assert 3 == 4
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert "hello" in s
+
+def test_assert_long_source_1():
+ try:
+ assert len == [
+ (None, ['somet text', 'more text']),
+ ]
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert 're-run' not in s
+ assert 'somet text' in s
+
+def test_assert_long_source_2():
+ try:
+ assert(len == [
+ (None, ['somet text', 'more text']),
+ ])
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert 're-run' not in s
+ assert 'somet text' in s
+
+def test_assert_raise_alias(testdir):
+ testdir.makepyfile("""
+ import sys
+ EX = AssertionError
+ def test_hello():
+ raise EX("hello"
+ "multi"
+ "line")
+ """)
+ result = testdir.runpytest()
+ result.stdout.fnmatch_lines([
+ "*def test_hello*",
+ "*raise EX*",
+ "*1 failed*",
+ ])
+
+
+@pytest.mark.skipif("sys.version_info < (2,5)")
+def test_assert_raise_subclass():
+ class SomeEx(AssertionError):
+ def __init__(self, *args):
+ super(SomeEx, self).__init__()
+ try:
+ raise SomeEx("hello")
+ except AssertionError:
+ s = str(exvalue())
+ assert 're-run' not in s
+ assert 'could not determine' in s
+
+def test_assert_raises_in_nonzero_of_object_pytest_issue10():
+ class A(object):
+ def __nonzero__(self):
+ raise ValueError(42)
+ def __lt__(self, other):
+ return A()
+ def __repr__(self):
+ return "<MY42 object>"
+ def myany(x):
+ return True
+ try:
+ assert not(myany(A() < 0))
+ except AssertionError:
+ e = exvalue()
+ s = str(e)
+ assert "<MY42 object> < 0" in s
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/code/test_code.py b/tests/wpt/web-platform-tests/tools/py/testing/code/test_code.py
new file mode 100644
index 00000000000..28ec628b00d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/code/test_code.py
@@ -0,0 +1,159 @@
+import py
+import sys
+
+def test_ne():
+ code1 = py.code.Code(compile('foo = "bar"', '', 'exec'))
+ assert code1 == code1
+ code2 = py.code.Code(compile('foo = "baz"', '', 'exec'))
+ assert code2 != code1
+
+def test_code_gives_back_name_for_not_existing_file():
+ name = 'abc-123'
+ co_code = compile("pass\n", name, 'exec')
+ assert co_code.co_filename == name
+ code = py.code.Code(co_code)
+ assert str(code.path) == name
+ assert code.fullsource is None
+
+def test_code_with_class():
+ class A:
+ pass
+ py.test.raises(TypeError, "py.code.Code(A)")
+
+if True:
+ def x():
+ pass
+
+def test_code_fullsource():
+ code = py.code.Code(x)
+ full = code.fullsource
+ assert 'test_code_fullsource()' in str(full)
+
+def test_code_source():
+ code = py.code.Code(x)
+ src = code.source()
+ expected = """def x():
+ pass"""
+ assert str(src) == expected
+
+def test_frame_getsourcelineno_myself():
+ def func():
+ return sys._getframe(0)
+ f = func()
+ f = py.code.Frame(f)
+ source, lineno = f.code.fullsource, f.lineno
+ assert source[lineno].startswith(" return sys._getframe(0)")
+
+def test_getstatement_empty_fullsource():
+ def func():
+ return sys._getframe(0)
+ f = func()
+ f = py.code.Frame(f)
+ prop = f.code.__class__.fullsource
+ try:
+ f.code.__class__.fullsource = None
+ assert f.statement == py.code.Source("")
+ finally:
+ f.code.__class__.fullsource = prop
+
+def test_code_from_func():
+ co = py.code.Code(test_frame_getsourcelineno_myself)
+ assert co.firstlineno
+ assert co.path
+
+
+
+def test_builtin_patch_unpatch(monkeypatch):
+ cpy_builtin = py.builtin.builtins
+ comp = cpy_builtin.compile
+ def mycompile(*args, **kwargs):
+ return comp(*args, **kwargs)
+ class Sub(AssertionError):
+ pass
+ monkeypatch.setattr(cpy_builtin, 'AssertionError', Sub)
+ monkeypatch.setattr(cpy_builtin, 'compile', mycompile)
+ py.code.patch_builtins()
+ assert cpy_builtin.AssertionError != Sub
+ assert cpy_builtin.compile != mycompile
+ py.code.unpatch_builtins()
+ assert cpy_builtin.AssertionError is Sub
+ assert cpy_builtin.compile == mycompile
+
+
+def test_unicode_handling():
+ value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
+ def f():
+ raise Exception(value)
+ excinfo = py.test.raises(Exception, f)
+ s = str(excinfo)
+ if sys.version_info[0] < 3:
+ u = unicode(excinfo)
+
+def test_code_getargs():
+ def f1(x):
+ pass
+ c1 = py.code.Code(f1)
+ assert c1.getargs(var=True) == ('x',)
+
+ def f2(x, *y):
+ pass
+ c2 = py.code.Code(f2)
+ assert c2.getargs(var=True) == ('x', 'y')
+
+ def f3(x, **z):
+ pass
+ c3 = py.code.Code(f3)
+ assert c3.getargs(var=True) == ('x', 'z')
+
+ def f4(x, *y, **z):
+ pass
+ c4 = py.code.Code(f4)
+ assert c4.getargs(var=True) == ('x', 'y', 'z')
+
+
+def test_frame_getargs():
+ def f1(x):
+ return sys._getframe(0)
+ fr1 = py.code.Frame(f1('a'))
+ assert fr1.getargs(var=True) == [('x', 'a')]
+
+ def f2(x, *y):
+ return sys._getframe(0)
+ fr2 = py.code.Frame(f2('a', 'b', 'c'))
+ assert fr2.getargs(var=True) == [('x', 'a'), ('y', ('b', 'c'))]
+
+ def f3(x, **z):
+ return sys._getframe(0)
+ fr3 = py.code.Frame(f3('a', b='c'))
+ assert fr3.getargs(var=True) == [('x', 'a'), ('z', {'b': 'c'})]
+
+ def f4(x, *y, **z):
+ return sys._getframe(0)
+ fr4 = py.code.Frame(f4('a', 'b', c='d'))
+ assert fr4.getargs(var=True) == [('x', 'a'), ('y', ('b',)),
+ ('z', {'c': 'd'})]
+
+
+class TestExceptionInfo:
+
+ def test_bad_getsource(self):
+ try:
+ if False: pass
+ else: assert False
+ except AssertionError:
+ exci = py.code.ExceptionInfo()
+ assert exci.getrepr()
+
+
+class TestTracebackEntry:
+
+ def test_getsource(self):
+ try:
+ if False: pass
+ else: assert False
+ except AssertionError:
+ exci = py.code.ExceptionInfo()
+ entry = exci.traceback[0]
+ source = entry.getsource()
+ assert len(source) == 4
+ assert 'else: assert False' in source[3]
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/code/test_excinfo.py b/tests/wpt/web-platform-tests/tools/py/testing/code/test_excinfo.py
new file mode 100644
index 00000000000..65742c6f62e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/code/test_excinfo.py
@@ -0,0 +1,909 @@
+# -*- coding: utf-8 -*-
+
+import py
+from py._code.code import FormattedExcinfo, ReprExceptionInfo
+queue = py.builtin._tryimport('queue', 'Queue')
+
+failsonjython = py.test.mark.xfail("sys.platform.startswith('java')")
+from test_source import astonly
+
+try:
+ import importlib
+except ImportError:
+ invalidate_import_caches = None
+else:
+ invalidate_import_caches = getattr(importlib, "invalidate_caches", None)
+
+import pytest
+pytest_version_info = tuple(map(int, pytest.__version__.split(".")[:3]))
+
+class TWMock:
+ def __init__(self):
+ self.lines = []
+ def sep(self, sep, line=None):
+ self.lines.append((sep, line))
+ def line(self, line, **kw):
+ self.lines.append(line)
+ def markup(self, text, **kw):
+ return text
+
+ fullwidth = 80
+
+def test_excinfo_simple():
+ try:
+ raise ValueError
+ except ValueError:
+ info = py.code.ExceptionInfo()
+ assert info.type == ValueError
+
+def test_excinfo_getstatement():
+ def g():
+ raise ValueError
+ def f():
+ g()
+ try:
+ f()
+ except ValueError:
+ excinfo = py.code.ExceptionInfo()
+ linenumbers = [py.code.getrawcode(f).co_firstlineno-1+3,
+ py.code.getrawcode(f).co_firstlineno-1+1,
+ py.code.getrawcode(g).co_firstlineno-1+1,]
+ l = list(excinfo.traceback)
+ foundlinenumbers = [x.lineno for x in l]
+ assert foundlinenumbers == linenumbers
+ #for x in info:
+ # print "%s:%d %s" %(x.path.relto(root), x.lineno, x.statement)
+ #xxx
+
+# testchain for getentries test below
+def f():
+ #
+ raise ValueError
+ #
+def g():
+ #
+ __tracebackhide__ = True
+ f()
+ #
+def h():
+ #
+ g()
+ #
+
+class TestTraceback_f_g_h:
+ def setup_method(self, method):
+ try:
+ h()
+ except ValueError:
+ self.excinfo = py.code.ExceptionInfo()
+
+ def test_traceback_entries(self):
+ tb = self.excinfo.traceback
+ entries = list(tb)
+ assert len(tb) == 4 # maybe fragile test
+ assert len(entries) == 4 # maybe fragile test
+ names = ['f', 'g', 'h']
+ for entry in entries:
+ try:
+ names.remove(entry.frame.code.name)
+ except ValueError:
+ pass
+ assert not names
+
+ def test_traceback_entry_getsource(self):
+ tb = self.excinfo.traceback
+ s = str(tb[-1].getsource() )
+ assert s.startswith("def f():")
+ assert s.endswith("raise ValueError")
+
+ @astonly
+ @failsonjython
+ def test_traceback_entry_getsource_in_construct(self):
+ source = py.code.Source("""\
+ def xyz():
+ try:
+ raise ValueError
+ except somenoname:
+ pass
+ xyz()
+ """)
+ try:
+ exec (source.compile())
+ except NameError:
+ tb = py.code.ExceptionInfo().traceback
+ print (tb[-1].getsource())
+ s = str(tb[-1].getsource())
+ assert s.startswith("def xyz():\n try:")
+ assert s.strip().endswith("except somenoname:")
+
+ def test_traceback_cut(self):
+ co = py.code.Code(f)
+ path, firstlineno = co.path, co.firstlineno
+ traceback = self.excinfo.traceback
+ newtraceback = traceback.cut(path=path, firstlineno=firstlineno)
+ assert len(newtraceback) == 1
+ newtraceback = traceback.cut(path=path, lineno=firstlineno+2)
+ assert len(newtraceback) == 1
+
+ def test_traceback_cut_excludepath(self, testdir):
+ p = testdir.makepyfile("def f(): raise ValueError")
+ excinfo = py.test.raises(ValueError, "p.pyimport().f()")
+ basedir = py.path.local(py.test.__file__).dirpath()
+ newtraceback = excinfo.traceback.cut(excludepath=basedir)
+ for x in newtraceback:
+ if hasattr(x, 'path'):
+ assert not py.path.local(x.path).relto(basedir)
+ assert newtraceback[-1].frame.code.path == p
+
+ def test_traceback_filter(self):
+ traceback = self.excinfo.traceback
+ ntraceback = traceback.filter()
+ assert len(ntraceback) == len(traceback) - 1
+
+ def test_traceback_recursion_index(self):
+ def f(n):
+ if n < 10:
+ n += 1
+ f(n)
+ excinfo = py.test.raises(RuntimeError, f, 8)
+ traceback = excinfo.traceback
+ recindex = traceback.recursionindex()
+ assert recindex == 3
+
+ def test_traceback_only_specific_recursion_errors(self, monkeypatch):
+ def f(n):
+ if n == 0:
+ raise RuntimeError("hello")
+ f(n-1)
+
+ excinfo = pytest.raises(RuntimeError, f, 100)
+ monkeypatch.delattr(excinfo.traceback.__class__, "recursionindex")
+ repr = excinfo.getrepr()
+ assert "RuntimeError: hello" in str(repr.reprcrash)
+
+ def test_traceback_no_recursion_index(self):
+ def do_stuff():
+ raise RuntimeError
+ def reraise_me():
+ import sys
+ exc, val, tb = sys.exc_info()
+ py.builtin._reraise(exc, val, tb)
+ def f(n):
+ try:
+ do_stuff()
+ except:
+ reraise_me()
+ excinfo = py.test.raises(RuntimeError, f, 8)
+ traceback = excinfo.traceback
+ recindex = traceback.recursionindex()
+ assert recindex is None
+
+ def test_traceback_messy_recursion(self):
+ #XXX: simplified locally testable version
+ decorator = py.test.importorskip('decorator').decorator
+
+ def log(f, *k, **kw):
+ print('%s %s' % (k, kw))
+ f(*k, **kw)
+ log = decorator(log)
+
+ def fail():
+ raise ValueError('')
+
+ fail = log(log(fail))
+
+ excinfo = py.test.raises(ValueError, fail)
+ assert excinfo.traceback.recursionindex() is None
+
+
+
+ def test_traceback_getcrashentry(self):
+ def i():
+ __tracebackhide__ = True
+ raise ValueError
+ def h():
+ i()
+ def g():
+ __tracebackhide__ = True
+ h()
+ def f():
+ g()
+
+ excinfo = py.test.raises(ValueError, f)
+ tb = excinfo.traceback
+ entry = tb.getcrashentry()
+ co = py.code.Code(h)
+ assert entry.frame.code.path == co.path
+ assert entry.lineno == co.firstlineno + 1
+ assert entry.frame.code.name == 'h'
+
+ def test_traceback_getcrashentry_empty(self):
+ def g():
+ __tracebackhide__ = True
+ raise ValueError
+ def f():
+ __tracebackhide__ = True
+ g()
+
+ excinfo = py.test.raises(ValueError, f)
+ tb = excinfo.traceback
+ entry = tb.getcrashentry()
+ co = py.code.Code(g)
+ assert entry.frame.code.path == co.path
+ assert entry.lineno == co.firstlineno + 2
+ assert entry.frame.code.name == 'g'
+
+def hello(x):
+ x + 5
+
+def test_tbentry_reinterpret():
+ try:
+ hello("hello")
+ except TypeError:
+ excinfo = py.code.ExceptionInfo()
+ tbentry = excinfo.traceback[-1]
+ msg = tbentry.reinterpret()
+ assert msg.startswith("TypeError: ('hello' + 5)")
+
+def test_excinfo_exconly():
+ excinfo = py.test.raises(ValueError, h)
+ assert excinfo.exconly().startswith('ValueError')
+ excinfo = py.test.raises(ValueError,
+ "raise ValueError('hello\\nworld')")
+ msg = excinfo.exconly(tryshort=True)
+ assert msg.startswith('ValueError')
+ assert msg.endswith("world")
+
+def test_excinfo_repr():
+ excinfo = py.test.raises(ValueError, h)
+ s = repr(excinfo)
+ assert s == "<ExceptionInfo ValueError tblen=4>"
+
+def test_excinfo_str():
+ excinfo = py.test.raises(ValueError, h)
+ s = str(excinfo)
+ assert s.startswith(__file__[:-9]) # pyc file and $py.class
+ assert s.endswith("ValueError")
+ assert len(s.split(":")) >= 3 # on windows it's 4
+
+def test_excinfo_errisinstance():
+ excinfo = py.test.raises(ValueError, h)
+ assert excinfo.errisinstance(ValueError)
+
+def test_excinfo_no_sourcecode():
+ try:
+ exec ("raise ValueError()")
+ except ValueError:
+ excinfo = py.code.ExceptionInfo()
+ s = str(excinfo.traceback[-1])
+ if py.std.sys.version_info < (2,5):
+ assert s == " File '<string>':1 in ?\n ???\n"
+ else:
+ assert s == " File '<string>':1 in <module>\n ???\n"
+
+def test_excinfo_no_python_sourcecode(tmpdir):
+ #XXX: simplified locally testable version
+ tmpdir.join('test.txt').write("{{ h()}}:")
+
+ jinja2 = py.test.importorskip('jinja2')
+ loader = jinja2.FileSystemLoader(str(tmpdir))
+ env = jinja2.Environment(loader=loader)
+ template = env.get_template('test.txt')
+ excinfo = py.test.raises(ValueError,
+ template.render, h=h)
+ for item in excinfo.traceback:
+ print(item) #XXX: for some reason jinja.Template.render is printed in full
+ item.source # shouldnt fail
+ if item.path.basename == 'test.txt':
+ assert str(item.source) == '{{ h()}}:'
+
+
+def test_entrysource_Queue_example():
+ try:
+ queue.Queue().get(timeout=0.001)
+ except queue.Empty:
+ excinfo = py.code.ExceptionInfo()
+ entry = excinfo.traceback[-1]
+ source = entry.getsource()
+ assert source is not None
+ s = str(source).strip()
+ assert s.startswith("def get")
+
+def test_codepath_Queue_example():
+ try:
+ queue.Queue().get(timeout=0.001)
+ except queue.Empty:
+ excinfo = py.code.ExceptionInfo()
+ entry = excinfo.traceback[-1]
+ path = entry.path
+ assert isinstance(path, py.path.local)
+ assert path.basename.lower() == "queue.py"
+ assert path.check()
+
+class TestFormattedExcinfo:
+ def pytest_funcarg__importasmod(self, request):
+ def importasmod(source):
+ source = py.code.Source(source)
+ tmpdir = request.getfuncargvalue("tmpdir")
+ modpath = tmpdir.join("mod.py")
+ tmpdir.ensure("__init__.py")
+ modpath.write(source)
+ if invalidate_import_caches is not None:
+ invalidate_import_caches()
+ return modpath.pyimport()
+ return importasmod
+
+ def excinfo_from_exec(self, source):
+ source = py.code.Source(source).strip()
+ try:
+ exec (source.compile())
+ except KeyboardInterrupt:
+ raise
+ except:
+ return py.code.ExceptionInfo()
+ assert 0, "did not raise"
+
+ def test_repr_source(self):
+ pr = FormattedExcinfo()
+ source = py.code.Source("""
+ def f(x):
+ pass
+ """).strip()
+ pr.flow_marker = "|"
+ lines = pr.get_source(source, 0)
+ assert len(lines) == 2
+ assert lines[0] == "| def f(x):"
+ assert lines[1] == " pass"
+
+ def test_repr_source_excinfo(self):
+ """ check if indentation is right """
+ pr = FormattedExcinfo()
+ excinfo = self.excinfo_from_exec("""
+ def f():
+ assert 0
+ f()
+ """)
+ pr = FormattedExcinfo()
+ source = pr._getentrysource(excinfo.traceback[-1])
+ lines = pr.get_source(source, 1, excinfo)
+ assert lines == [
+ ' def f():',
+ '> assert 0',
+ 'E assert 0'
+ ]
+
+
+ def test_repr_source_not_existing(self):
+ pr = FormattedExcinfo()
+ co = compile("raise ValueError()", "", "exec")
+ try:
+ exec (co)
+ except ValueError:
+ excinfo = py.code.ExceptionInfo()
+ repr = pr.repr_excinfo(excinfo)
+ assert repr.reprtraceback.reprentries[1].lines[0] == "> ???"
+
+ def test_repr_many_line_source_not_existing(self):
+ pr = FormattedExcinfo()
+ co = compile("""
+a = 1
+raise ValueError()
+""", "", "exec")
+ try:
+ exec (co)
+ except ValueError:
+ excinfo = py.code.ExceptionInfo()
+ repr = pr.repr_excinfo(excinfo)
+ assert repr.reprtraceback.reprentries[1].lines[0] == "> ???"
+
+ def test_repr_source_failing_fullsource(self):
+ pr = FormattedExcinfo()
+
+ class FakeCode(object):
+ class raw:
+ co_filename = '?'
+ path = '?'
+ firstlineno = 5
+
+ def fullsource(self):
+ return None
+ fullsource = property(fullsource)
+
+ class FakeFrame(object):
+ code = FakeCode()
+ f_locals = {}
+ f_globals = {}
+
+ class FakeTracebackEntry(py.code.Traceback.Entry):
+ def __init__(self, tb):
+ self.lineno = 5+3
+
+ @property
+ def frame(self):
+ return FakeFrame()
+
+ class Traceback(py.code.Traceback):
+ Entry = FakeTracebackEntry
+
+ class FakeExcinfo(py.code.ExceptionInfo):
+ typename = "Foo"
+ def __init__(self):
+ pass
+
+ def exconly(self, tryshort):
+ return "EXC"
+ def errisinstance(self, cls):
+ return False
+
+ excinfo = FakeExcinfo()
+ class FakeRawTB(object):
+ tb_next = None
+ tb = FakeRawTB()
+ excinfo.traceback = Traceback(tb)
+
+ fail = IOError()
+ repr = pr.repr_excinfo(excinfo)
+ assert repr.reprtraceback.reprentries[0].lines[0] == "> ???"
+
+ fail = py.error.ENOENT
+ repr = pr.repr_excinfo(excinfo)
+ assert repr.reprtraceback.reprentries[0].lines[0] == "> ???"
+
+
+ def test_repr_local(self):
+ p = FormattedExcinfo(showlocals=True)
+ loc = {'y': 5, 'z': 7, 'x': 3, '@x': 2, '__builtins__': {}}
+ reprlocals = p.repr_locals(loc)
+ assert reprlocals.lines
+ assert reprlocals.lines[0] == '__builtins__ = <builtins>'
+ assert reprlocals.lines[1] == 'x = 3'
+ assert reprlocals.lines[2] == 'y = 5'
+ assert reprlocals.lines[3] == 'z = 7'
+
+ def test_repr_tracebackentry_lines(self, importasmod):
+ mod = importasmod("""
+ def func1():
+ raise ValueError("hello\\nworld")
+ """)
+ excinfo = py.test.raises(ValueError, mod.func1)
+ excinfo.traceback = excinfo.traceback.filter()
+ p = FormattedExcinfo()
+ reprtb = p.repr_traceback_entry(excinfo.traceback[-1])
+
+ # test as intermittent entry
+ lines = reprtb.lines
+ assert lines[0] == ' def func1():'
+ assert lines[1] == '> raise ValueError("hello\\nworld")'
+
+ # test as last entry
+ p = FormattedExcinfo(showlocals=True)
+ repr_entry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
+ lines = repr_entry.lines
+ assert lines[0] == ' def func1():'
+ assert lines[1] == '> raise ValueError("hello\\nworld")'
+ assert lines[2] == 'E ValueError: hello'
+ assert lines[3] == 'E world'
+ assert not lines[4:]
+
+ loc = repr_entry.reprlocals is not None
+ loc = repr_entry.reprfileloc
+ assert loc.path == mod.__file__
+ assert loc.lineno == 3
+ #assert loc.message == "ValueError: hello"
+
+ def test_repr_tracebackentry_lines(self, importasmod):
+ mod = importasmod("""
+ def func1(m, x, y, z):
+ raise ValueError("hello\\nworld")
+ """)
+ excinfo = py.test.raises(ValueError, mod.func1, "m"*90, 5, 13, "z"*120)
+ excinfo.traceback = excinfo.traceback.filter()
+ entry = excinfo.traceback[-1]
+ p = FormattedExcinfo(funcargs=True)
+ reprfuncargs = p.repr_args(entry)
+ assert reprfuncargs.args[0] == ('m', repr("m"*90))
+ assert reprfuncargs.args[1] == ('x', '5')
+ assert reprfuncargs.args[2] == ('y', '13')
+ assert reprfuncargs.args[3] == ('z', repr("z" * 120))
+
+ p = FormattedExcinfo(funcargs=True)
+ repr_entry = p.repr_traceback_entry(entry)
+ assert repr_entry.reprfuncargs.args == reprfuncargs.args
+ tw = TWMock()
+ repr_entry.toterminal(tw)
+ assert tw.lines[0] == "m = " + repr('m' * 90)
+ assert tw.lines[1] == "x = 5, y = 13"
+ assert tw.lines[2] == "z = " + repr('z' * 120)
+
+ def test_repr_tracebackentry_lines_var_kw_args(self, importasmod):
+ mod = importasmod("""
+ def func1(x, *y, **z):
+ raise ValueError("hello\\nworld")
+ """)
+ excinfo = py.test.raises(ValueError, mod.func1, 'a', 'b', c='d')
+ excinfo.traceback = excinfo.traceback.filter()
+ entry = excinfo.traceback[-1]
+ p = FormattedExcinfo(funcargs=True)
+ reprfuncargs = p.repr_args(entry)
+ assert reprfuncargs.args[0] == ('x', repr('a'))
+ assert reprfuncargs.args[1] == ('y', repr(('b',)))
+ assert reprfuncargs.args[2] == ('z', repr({'c': 'd'}))
+
+ p = FormattedExcinfo(funcargs=True)
+ repr_entry = p.repr_traceback_entry(entry)
+ assert repr_entry.reprfuncargs.args == reprfuncargs.args
+ tw = TWMock()
+ repr_entry.toterminal(tw)
+ assert tw.lines[0] == "x = 'a', y = ('b',), z = {'c': 'd'}"
+
+ def test_repr_tracebackentry_short(self, importasmod):
+ mod = importasmod("""
+ def func1():
+ raise ValueError("hello")
+ def entry():
+ func1()
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+ p = FormattedExcinfo(style="short")
+ reprtb = p.repr_traceback_entry(excinfo.traceback[-2])
+ lines = reprtb.lines
+ basename = py.path.local(mod.__file__).basename
+ assert lines[0] == ' func1()'
+ assert basename in str(reprtb.reprfileloc.path)
+ assert reprtb.reprfileloc.lineno == 5
+
+ # test last entry
+ p = FormattedExcinfo(style="short")
+ reprtb = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
+ lines = reprtb.lines
+ assert lines[0] == ' raise ValueError("hello")'
+ assert lines[1] == 'E ValueError: hello'
+ assert basename in str(reprtb.reprfileloc.path)
+ assert reprtb.reprfileloc.lineno == 3
+
+ def test_repr_tracebackentry_no(self, importasmod):
+ mod = importasmod("""
+ def func1():
+ raise ValueError("hello")
+ def entry():
+ func1()
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+ p = FormattedExcinfo(style="no")
+ p.repr_traceback_entry(excinfo.traceback[-2])
+
+ p = FormattedExcinfo(style="no")
+ reprentry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
+ lines = reprentry.lines
+ assert lines[0] == 'E ValueError: hello'
+ assert not lines[1:]
+
+ def test_repr_traceback_tbfilter(self, importasmod):
+ mod = importasmod("""
+ def f(x):
+ raise ValueError(x)
+ def entry():
+ f(0)
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+ p = FormattedExcinfo(tbfilter=True)
+ reprtb = p.repr_traceback(excinfo)
+ assert len(reprtb.reprentries) == 2
+ p = FormattedExcinfo(tbfilter=False)
+ reprtb = p.repr_traceback(excinfo)
+ assert len(reprtb.reprentries) == 3
+
+ def test_traceback_short_no_source(self, importasmod, monkeypatch):
+ mod = importasmod("""
+ def func1():
+ raise ValueError("hello")
+ def entry():
+ func1()
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+ from py._code.code import Code
+ monkeypatch.setattr(Code, 'path', 'bogus')
+ excinfo.traceback[0].frame.code.path = "bogus"
+ p = FormattedExcinfo(style="short")
+ reprtb = p.repr_traceback_entry(excinfo.traceback[-2])
+ lines = reprtb.lines
+ last_p = FormattedExcinfo(style="short")
+ last_reprtb = last_p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
+ last_lines = last_reprtb.lines
+ monkeypatch.undo()
+ basename = py.path.local(mod.__file__).basename
+ assert lines[0] == ' func1()'
+
+ assert last_lines[0] == ' raise ValueError("hello")'
+ assert last_lines[1] == 'E ValueError: hello'
+
+ def test_repr_traceback_and_excinfo(self, importasmod):
+ mod = importasmod("""
+ def f(x):
+ raise ValueError(x)
+ def entry():
+ f(0)
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+
+ for style in ("long", "short"):
+ p = FormattedExcinfo(style=style)
+ reprtb = p.repr_traceback(excinfo)
+ assert len(reprtb.reprentries) == 2
+ assert reprtb.style == style
+ assert not reprtb.extraline
+ repr = p.repr_excinfo(excinfo)
+ assert repr.reprtraceback
+ assert len(repr.reprtraceback.reprentries) == len(reprtb.reprentries)
+ assert repr.reprcrash.path.endswith("mod.py")
+ assert repr.reprcrash.message == "ValueError: 0"
+
+ def test_repr_traceback_with_invalid_cwd(self, importasmod, monkeypatch):
+ mod = importasmod("""
+ def f(x):
+ raise ValueError(x)
+ def entry():
+ f(0)
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+
+ p = FormattedExcinfo()
+ def raiseos():
+ raise OSError(2)
+ monkeypatch.setattr(py.std.os, 'getcwd', raiseos)
+ assert p._makepath(__file__) == __file__
+ reprtb = p.repr_traceback(excinfo)
+
+ def test_repr_excinfo_addouterr(self, importasmod):
+ mod = importasmod("""
+ def entry():
+ raise ValueError()
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+ repr = excinfo.getrepr()
+ repr.addsection("title", "content")
+ twmock = TWMock()
+ repr.toterminal(twmock)
+ assert twmock.lines[-1] == "content"
+ assert twmock.lines[-2] == ("-", "title")
+
+ def test_repr_excinfo_reprcrash(self, importasmod):
+ mod = importasmod("""
+ def entry():
+ raise ValueError()
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+ repr = excinfo.getrepr()
+ assert repr.reprcrash.path.endswith("mod.py")
+ assert repr.reprcrash.lineno == 3
+ assert repr.reprcrash.message == "ValueError"
+ assert str(repr.reprcrash).endswith("mod.py:3: ValueError")
+
+ def test_repr_traceback_recursion(self, importasmod):
+ mod = importasmod("""
+ def rec2(x):
+ return rec1(x+1)
+ def rec1(x):
+ return rec2(x-1)
+ def entry():
+ rec1(42)
+ """)
+ excinfo = py.test.raises(RuntimeError, mod.entry)
+
+ for style in ("short", "long", "no"):
+ p = FormattedExcinfo(style="short")
+ reprtb = p.repr_traceback(excinfo)
+ assert reprtb.extraline == "!!! Recursion detected (same locals & position)"
+ assert str(reprtb)
+
+ def test_tb_entry_AssertionError(self, importasmod):
+ # probably this test is a bit redundant
+ # as py/magic/testing/test_assertion.py
+ # already tests correctness of
+ # assertion-reinterpretation logic
+ mod = importasmod("""
+ def somefunc():
+ x = 1
+ assert x == 2
+ """)
+ excinfo = py.test.raises(AssertionError, mod.somefunc)
+
+ p = FormattedExcinfo()
+ reprentry = p.repr_traceback_entry(excinfo.traceback[-1], excinfo)
+ lines = reprentry.lines
+ assert lines[-1] == "E assert 1 == 2"
+
+ def test_reprexcinfo_getrepr(self, importasmod):
+ mod = importasmod("""
+ def f(x):
+ raise ValueError(x)
+ def entry():
+ f(0)
+ """)
+ excinfo = py.test.raises(ValueError, mod.entry)
+
+ for style in ("short", "long", "no"):
+ for showlocals in (True, False):
+ repr = excinfo.getrepr(style=style, showlocals=showlocals)
+ assert isinstance(repr, ReprExceptionInfo)
+ assert repr.reprtraceback.style == style
+
+ def test_reprexcinfo_unicode(self):
+ from py._code.code import TerminalRepr
+ class MyRepr(TerminalRepr):
+ def toterminal(self, tw):
+ tw.line(py.builtin._totext("я", "utf-8"))
+ x = py.builtin._totext(MyRepr())
+ assert x == py.builtin._totext("я", "utf-8")
+
+ def test_toterminal_long(self, importasmod):
+ mod = importasmod("""
+ def g(x):
+ raise ValueError(x)
+ def f():
+ g(3)
+ """)
+ excinfo = py.test.raises(ValueError, mod.f)
+ excinfo.traceback = excinfo.traceback.filter()
+ repr = excinfo.getrepr()
+ tw = TWMock()
+ repr.toterminal(tw)
+ assert tw.lines[0] == ""
+ tw.lines.pop(0)
+ assert tw.lines[0] == " def f():"
+ assert tw.lines[1] == "> g(3)"
+ assert tw.lines[2] == ""
+ assert tw.lines[3].endswith("mod.py:5: ")
+ assert tw.lines[4] == ("_ ", None)
+ assert tw.lines[5] == ""
+ assert tw.lines[6] == " def g(x):"
+ assert tw.lines[7] == "> raise ValueError(x)"
+ assert tw.lines[8] == "E ValueError: 3"
+ assert tw.lines[9] == ""
+ assert tw.lines[10].endswith("mod.py:3: ValueError")
+
+ def test_toterminal_long_missing_source(self, importasmod, tmpdir):
+ mod = importasmod("""
+ def g(x):
+ raise ValueError(x)
+ def f():
+ g(3)
+ """)
+ excinfo = py.test.raises(ValueError, mod.f)
+ tmpdir.join('mod.py').remove()
+ excinfo.traceback = excinfo.traceback.filter()
+ repr = excinfo.getrepr()
+ tw = TWMock()
+ repr.toterminal(tw)
+ assert tw.lines[0] == ""
+ tw.lines.pop(0)
+ assert tw.lines[0] == "> ???"
+ assert tw.lines[1] == ""
+ assert tw.lines[2].endswith("mod.py:5: ")
+ assert tw.lines[3] == ("_ ", None)
+ assert tw.lines[4] == ""
+ assert tw.lines[5] == "> ???"
+ assert tw.lines[6] == "E ValueError: 3"
+ assert tw.lines[7] == ""
+ assert tw.lines[8].endswith("mod.py:3: ValueError")
+
+ def test_toterminal_long_incomplete_source(self, importasmod, tmpdir):
+ mod = importasmod("""
+ def g(x):
+ raise ValueError(x)
+ def f():
+ g(3)
+ """)
+ excinfo = py.test.raises(ValueError, mod.f)
+ tmpdir.join('mod.py').write('asdf')
+ excinfo.traceback = excinfo.traceback.filter()
+ repr = excinfo.getrepr()
+ tw = TWMock()
+ repr.toterminal(tw)
+ assert tw.lines[0] == ""
+ tw.lines.pop(0)
+ assert tw.lines[0] == "> ???"
+ assert tw.lines[1] == ""
+ assert tw.lines[2].endswith("mod.py:5: ")
+ assert tw.lines[3] == ("_ ", None)
+ assert tw.lines[4] == ""
+ assert tw.lines[5] == "> ???"
+ assert tw.lines[6] == "E ValueError: 3"
+ assert tw.lines[7] == ""
+ assert tw.lines[8].endswith("mod.py:3: ValueError")
+
+ def test_toterminal_long_filenames(self, importasmod):
+ mod = importasmod("""
+ def f():
+ raise ValueError()
+ """)
+ excinfo = py.test.raises(ValueError, mod.f)
+ tw = TWMock()
+ path = py.path.local(mod.__file__)
+ old = path.dirpath().chdir()
+ try:
+ repr = excinfo.getrepr(abspath=False)
+ repr.toterminal(tw)
+ line = tw.lines[-1]
+ x = py.path.local().bestrelpath(path)
+ if len(x) < len(str(path)):
+ assert line == "mod.py:3: ValueError"
+
+ repr = excinfo.getrepr(abspath=True)
+ repr.toterminal(tw)
+ line = tw.lines[-1]
+ assert line == "%s:3: ValueError" %(path,)
+ finally:
+ old.chdir()
+
+ @py.test.mark.multi(reproptions=[
+ {'style': style, 'showlocals': showlocals,
+ 'funcargs': funcargs, 'tbfilter': tbfilter
+ } for style in ("long", "short", "no")
+ for showlocals in (True, False)
+ for tbfilter in (True, False)
+ for funcargs in (True, False)])
+ def test_format_excinfo(self, importasmod, reproptions):
+ mod = importasmod("""
+ def g(x):
+ raise ValueError(x)
+ def f():
+ g(3)
+ """)
+ excinfo = py.test.raises(ValueError, mod.f)
+ tw = py.io.TerminalWriter(stringio=True)
+ repr = excinfo.getrepr(**reproptions)
+ repr.toterminal(tw)
+ assert tw.stringio.getvalue()
+
+
+ def test_native_style(self):
+ excinfo = self.excinfo_from_exec("""
+ assert 0
+ """)
+ repr = excinfo.getrepr(style='native')
+ assert "assert 0" in str(repr.reprcrash)
+ s = str(repr)
+ assert s.startswith('Traceback (most recent call last):\n File')
+ assert s.endswith('\nAssertionError: assert 0')
+ assert 'exec (source.compile())' in s
+ # python 2.4 fails to get the source line for the assert
+ if py.std.sys.version_info >= (2, 5):
+ assert s.count('assert 0') == 2
+
+ def test_traceback_repr_style(self, importasmod):
+ mod = importasmod("""
+ def f():
+ g()
+ def g():
+ h()
+ def h():
+ i()
+ def i():
+ raise ValueError()
+ """)
+ excinfo = py.test.raises(ValueError, mod.f)
+ excinfo.traceback = excinfo.traceback.filter()
+ excinfo.traceback[1].set_repr_style("short")
+ excinfo.traceback[2].set_repr_style("short")
+ r = excinfo.getrepr(style="long")
+ tw = TWMock()
+ r.toterminal(tw)
+ for line in tw.lines: print (line)
+ assert tw.lines[0] == ""
+ assert tw.lines[1] == " def f():"
+ assert tw.lines[2] == "> g()"
+ assert tw.lines[3] == ""
+ assert tw.lines[4].endswith("mod.py:3: ")
+ assert tw.lines[5] == ("_ ", None)
+ assert tw.lines[6].endswith("in g")
+ assert tw.lines[7] == " h()"
+ assert tw.lines[8].endswith("in h")
+ assert tw.lines[9] == " i()"
+ assert tw.lines[10] == ("_ ", None)
+ assert tw.lines[11] == ""
+ assert tw.lines[12] == " def i():"
+ assert tw.lines[13] == "> raise ValueError()"
+ assert tw.lines[14] == "E ValueError"
+ assert tw.lines[15] == ""
+ assert tw.lines[16].endswith("mod.py:9: ValueError")
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/code/test_source.py b/tests/wpt/web-platform-tests/tools/py/testing/code/test_source.py
new file mode 100644
index 00000000000..830de2c95de
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/code/test_source.py
@@ -0,0 +1,651 @@
+from py.code import Source
+import py
+import sys
+
+from py._code.source import _ast
+if _ast is not None:
+ astonly = py.test.mark.nothing
+else:
+ astonly = py.test.mark.xfail("True", reason="only works with AST-compile")
+
+failsonjython = py.test.mark.xfail("sys.platform.startswith('java')")
+
+def test_source_str_function():
+ x = Source("3")
+ assert str(x) == "3"
+
+ x = Source(" 3")
+ assert str(x) == "3"
+
+ x = Source("""
+ 3
+ """, rstrip=False)
+ assert str(x) == "\n3\n "
+
+ x = Source("""
+ 3
+ """, rstrip=True)
+ assert str(x) == "\n3"
+
+def test_unicode():
+ try:
+ unicode
+ except NameError:
+ return
+ x = Source(unicode("4"))
+ assert str(x) == "4"
+ co = py.code.compile(unicode('u"\xc3\xa5"', 'utf8'), mode='eval')
+ val = eval(co)
+ assert isinstance(val, unicode)
+
+def test_source_from_function():
+ source = py.code.Source(test_source_str_function)
+ assert str(source).startswith('def test_source_str_function():')
+
+def test_source_from_method():
+ class TestClass:
+ def test_method(self):
+ pass
+ source = py.code.Source(TestClass().test_method)
+ assert source.lines == ["def test_method(self):",
+ " pass"]
+
+def test_source_from_lines():
+ lines = ["a \n", "b\n", "c"]
+ source = py.code.Source(lines)
+ assert source.lines == ['a ', 'b', 'c']
+
+def test_source_from_inner_function():
+ def f():
+ pass
+ source = py.code.Source(f, deindent=False)
+ assert str(source).startswith(' def f():')
+ source = py.code.Source(f)
+ assert str(source).startswith('def f():')
+
+def test_source_putaround_simple():
+ source = Source("raise ValueError")
+ source = source.putaround(
+ "try:", """\
+ except ValueError:
+ x = 42
+ else:
+ x = 23""")
+ assert str(source)=="""\
+try:
+ raise ValueError
+except ValueError:
+ x = 42
+else:
+ x = 23"""
+
+def test_source_putaround():
+ source = Source()
+ source = source.putaround("""
+ if 1:
+ x=1
+ """)
+ assert str(source).strip() == "if 1:\n x=1"
+
+def test_source_strips():
+ source = Source("")
+ assert source == Source()
+ assert str(source) == ''
+ assert source.strip() == source
+
+def test_source_strip_multiline():
+ source = Source()
+ source.lines = ["", " hello", " "]
+ source2 = source.strip()
+ assert source2.lines == [" hello"]
+
+def test_syntaxerror_rerepresentation():
+ ex = py.test.raises(SyntaxError, py.code.compile, 'xyz xyz')
+ assert ex.value.lineno == 1
+ assert ex.value.offset in (4,7) # XXX pypy/jython versus cpython?
+ assert ex.value.text.strip(), 'x x'
+
+def test_isparseable():
+ assert Source("hello").isparseable()
+ assert Source("if 1:\n pass").isparseable()
+ assert Source(" \nif 1:\n pass").isparseable()
+ assert not Source("if 1:\n").isparseable()
+ assert not Source(" \nif 1:\npass").isparseable()
+ assert not Source(chr(0)).isparseable()
+
+class TestAccesses:
+ source = Source("""\
+ def f(x):
+ pass
+ def g(x):
+ pass
+ """)
+ def test_getrange(self):
+ x = self.source[0:2]
+ assert x.isparseable()
+ assert len(x.lines) == 2
+ assert str(x) == "def f(x):\n pass"
+
+ def test_getline(self):
+ x = self.source[0]
+ assert x == "def f(x):"
+
+ def test_len(self):
+ assert len(self.source) == 4
+
+ def test_iter(self):
+ l = [x for x in self.source]
+ assert len(l) == 4
+
+class TestSourceParsingAndCompiling:
+ source = Source("""\
+ def f(x):
+ assert (x ==
+ 3 +
+ 4)
+ """).strip()
+
+ def test_compile(self):
+ co = py.code.compile("x=3")
+ d = {}
+ exec (co, d)
+ assert d['x'] == 3
+
+ def test_compile_and_getsource_simple(self):
+ co = py.code.compile("x=3")
+ exec (co)
+ source = py.code.Source(co)
+ assert str(source) == "x=3"
+
+ def test_compile_and_getsource_through_same_function(self):
+ def gensource(source):
+ return py.code.compile(source)
+ co1 = gensource("""
+ def f():
+ raise KeyError()
+ """)
+ co2 = gensource("""
+ def f():
+ raise ValueError()
+ """)
+ source1 = py.std.inspect.getsource(co1)
+ assert 'KeyError' in source1
+ source2 = py.std.inspect.getsource(co2)
+ assert 'ValueError' in source2
+
+ def test_getstatement(self):
+ #print str(self.source)
+ ass = str(self.source[1:])
+ for i in range(1, 4):
+ #print "trying start in line %r" % self.source[i]
+ s = self.source.getstatement(i)
+ #x = s.deindent()
+ assert str(s) == ass
+
+ def test_getstatementrange_triple_quoted(self):
+ #print str(self.source)
+ source = Source("""hello('''
+ ''')""")
+ s = source.getstatement(0)
+ assert s == str(source)
+ s = source.getstatement(1)
+ assert s == str(source)
+
+ @astonly
+ def test_getstatementrange_within_constructs(self):
+ source = Source("""\
+ try:
+ try:
+ raise ValueError
+ except SomeThing:
+ pass
+ finally:
+ 42
+ """)
+ assert len(source) == 7
+ # check all lineno's that could occur in a traceback
+ #assert source.getstatementrange(0) == (0, 7)
+ #assert source.getstatementrange(1) == (1, 5)
+ assert source.getstatementrange(2) == (2, 3)
+ assert source.getstatementrange(3) == (3, 4)
+ assert source.getstatementrange(4) == (4, 5)
+ #assert source.getstatementrange(5) == (0, 7)
+ assert source.getstatementrange(6) == (6, 7)
+
+ def test_getstatementrange_bug(self):
+ source = Source("""\
+ try:
+ x = (
+ y +
+ z)
+ except:
+ pass
+ """)
+ assert len(source) == 6
+ assert source.getstatementrange(2) == (1, 4)
+
+ def test_getstatementrange_bug2(self):
+ source = Source("""\
+ assert (
+ 33
+ ==
+ [
+ X(3,
+ b=1, c=2
+ ),
+ ]
+ )
+ """)
+ assert len(source) == 9
+ assert source.getstatementrange(5) == (0, 9)
+
+ def test_getstatementrange_ast_issue58(self):
+ source = Source("""\
+
+ def test_some():
+ for a in [a for a in
+ CAUSE_ERROR]: pass
+
+ x = 3
+ """)
+ assert getstatement(2, source).lines == source.lines[2:3]
+ assert getstatement(3, source).lines == source.lines[3:4]
+
+ @py.test.mark.skipif("sys.version_info < (2,6)")
+ def test_getstatementrange_out_of_bounds_py3(self):
+ source = Source("if xxx:\n from .collections import something")
+ r = source.getstatementrange(1)
+ assert r == (1,2)
+
+ def test_getstatementrange_with_syntaxerror_issue7(self):
+ source = Source(":")
+ py.test.raises(SyntaxError, lambda: source.getstatementrange(0))
+
+ @py.test.mark.skipif("sys.version_info < (2,6)")
+ def test_compile_to_ast(self):
+ import ast
+ source = Source("x = 4")
+ mod = source.compile(flag=ast.PyCF_ONLY_AST)
+ assert isinstance(mod, ast.Module)
+ compile(mod, "<filename>", "exec")
+
+ def test_compile_and_getsource(self):
+ co = self.source.compile()
+ py.builtin.exec_(co, globals())
+ f(7)
+ excinfo = py.test.raises(AssertionError, "f(6)")
+ frame = excinfo.traceback[-1].frame
+ stmt = frame.code.fullsource.getstatement(frame.lineno)
+ #print "block", str(block)
+ assert str(stmt).strip().startswith('assert')
+
+ def test_compilefuncs_and_path_sanity(self):
+ def check(comp, name):
+ co = comp(self.source, name)
+ if not name:
+ expected = "codegen %s:%d>" %(mypath, mylineno+2+1)
+ else:
+ expected = "codegen %r %s:%d>" % (name, mypath, mylineno+2+1)
+ fn = co.co_filename
+ assert fn.endswith(expected)
+
+ mycode = py.code.Code(self.test_compilefuncs_and_path_sanity)
+ mylineno = mycode.firstlineno
+ mypath = mycode.path
+
+ for comp in py.code.compile, py.code.Source.compile:
+ for name in '', None, 'my':
+ yield check, comp, name
+
+ def test_offsetless_synerr(self):
+ py.test.raises(SyntaxError, py.code.compile, "lambda a,a: 0", mode='eval')
+
+def test_getstartingblock_singleline():
+ class A:
+ def __init__(self, *args):
+ frame = sys._getframe(1)
+ self.source = py.code.Frame(frame).statement
+
+ x = A('x', 'y')
+
+ l = [i for i in x.source.lines if i.strip()]
+ assert len(l) == 1
+
+def test_getstartingblock_multiline():
+ class A:
+ def __init__(self, *args):
+ frame = sys._getframe(1)
+ self.source = py.code.Frame(frame).statement
+
+ x = A('x',
+ 'y' \
+ ,
+ 'z')
+
+ l = [i for i in x.source.lines if i.strip()]
+ assert len(l) == 4
+
+def test_getline_finally():
+ def c(): pass
+ excinfo = py.test.raises(TypeError, """
+ teardown = None
+ try:
+ c(1)
+ finally:
+ if teardown:
+ teardown()
+ """)
+ source = excinfo.traceback[-1].statement
+ assert str(source).strip() == 'c(1)'
+
+def test_getfuncsource_dynamic():
+ source = """
+ def f():
+ raise ValueError
+
+ def g(): pass
+ """
+ co = py.code.compile(source)
+ py.builtin.exec_(co, globals())
+ assert str(py.code.Source(f)).strip() == 'def f():\n raise ValueError'
+ assert str(py.code.Source(g)).strip() == 'def g(): pass'
+
+
+def test_getfuncsource_with_multine_string():
+ def f():
+ c = '''while True:
+ pass
+'''
+ assert str(py.code.Source(f)).strip() == "def f():\n c = '''while True:\n pass\n'''"
+
+
+def test_deindent():
+ from py._code.source import deindent as deindent
+ assert deindent(['\tfoo', '\tbar', ]) == ['foo', 'bar']
+
+ def f():
+ c = '''while True:
+ pass
+'''
+ import inspect
+ lines = deindent(inspect.getsource(f).splitlines())
+ assert lines == ["def f():", " c = '''while True:", " pass", "'''"]
+
+ source = """
+ def f():
+ def g():
+ pass
+ """
+ lines = deindent(source.splitlines())
+ assert lines == ['', 'def f():', ' def g():', ' pass', ' ']
+
+@py.test.mark.xfail("sys.version_info[:3] < (2,7,0) or "
+ "((3,0) <= sys.version_info[:2] < (3,2))")
+def test_source_of_class_at_eof_without_newline(tmpdir):
+ # this test fails because the implicit inspect.getsource(A) below
+ # does not return the "x = 1" last line.
+ source = py.code.Source('''
+ class A(object):
+ def method(self):
+ x = 1
+ ''')
+ path = tmpdir.join("a.py")
+ path.write(source)
+ s2 = py.code.Source(tmpdir.join("a.py").pyimport().A)
+ assert str(source).strip() == str(s2).strip()
+
+if True:
+ def x():
+ pass
+
+def test_getsource_fallback():
+ from py._code.source import getsource
+ expected = """def x():
+ pass"""
+ src = getsource(x)
+ assert src == expected
+
+def test_idem_compile_and_getsource():
+ from py._code.source import getsource
+ expected = "def x(): pass"
+ co = py.code.compile(expected)
+ src = getsource(co)
+ assert src == expected
+
+def test_findsource_fallback():
+ from py._code.source import findsource
+ src, lineno = findsource(x)
+ assert 'test_findsource_simple' in str(src)
+ assert src[lineno] == ' def x():'
+
+def test_findsource():
+ from py._code.source import findsource
+ co = py.code.compile("""if 1:
+ def x():
+ pass
+""")
+
+ src, lineno = findsource(co)
+ assert 'if 1:' in str(src)
+
+ d = {}
+ eval(co, d)
+ src, lineno = findsource(d['x'])
+ assert 'if 1:' in str(src)
+ assert src[lineno] == " def x():"
+
+
+def test_getfslineno():
+ from py.code import getfslineno
+
+ def f(x):
+ pass
+
+ fspath, lineno = getfslineno(f)
+
+ assert fspath.basename == "test_source.py"
+ assert lineno == py.code.getrawcode(f).co_firstlineno-1 # see findsource
+
+ class A(object):
+ pass
+
+ fspath, lineno = getfslineno(A)
+
+ _, A_lineno = py.std.inspect.findsource(A)
+ assert fspath.basename == "test_source.py"
+ assert lineno == A_lineno
+
+ assert getfslineno(3) == ("", -1)
+ class B:
+ pass
+ B.__name__ = "B2"
+ assert getfslineno(B)[1] == -1
+
+def test_code_of_object_instance_with_call():
+ class A:
+ pass
+ py.test.raises(TypeError, lambda: py.code.Source(A()))
+ class WithCall:
+ def __call__(self):
+ pass
+
+ code = py.code.Code(WithCall())
+ assert 'pass' in str(code.source())
+
+ class Hello(object):
+ def __call__(self):
+ pass
+ py.test.raises(TypeError, lambda: py.code.Code(Hello))
+
+
+def getstatement(lineno, source):
+ from py._code.source import getstatementrange_ast
+ source = py.code.Source(source, deindent=False)
+ ast, start, end = getstatementrange_ast(lineno, source)
+ return source[start:end]
+
+def test_oneline():
+ source = getstatement(0, "raise ValueError")
+ assert str(source) == "raise ValueError"
+
+def test_comment_and_no_newline_at_end():
+ from py._code.source import getstatementrange_ast
+ source = Source(['def test_basic_complex():',
+ ' assert 1 == 2',
+ '# vim: filetype=pyopencl:fdm=marker'])
+ ast, start, end = getstatementrange_ast(1, source)
+ assert end == 2
+
+def test_oneline_and_comment():
+ source = getstatement(0, "raise ValueError\n#hello")
+ assert str(source) == "raise ValueError"
+
+def test_comments():
+ source = '''def test():
+ "comment 1"
+ x = 1
+ # comment 2
+ # comment 3
+
+ assert False
+
+"""
+comment 4
+"""
+'''
+ for line in range(2,6):
+ assert str(getstatement(line, source)) == ' x = 1'
+ for line in range(6,10):
+ assert str(getstatement(line, source)) == ' assert False'
+ assert str(getstatement(10, source)) == '"""'
+
+def test_comment_in_statement():
+ source = '''test(foo=1,
+ # comment 1
+ bar=2)
+'''
+ for line in range(1,3):
+ assert str(getstatement(line, source)) == \
+ 'test(foo=1,\n # comment 1\n bar=2)'
+
+def test_single_line_else():
+ source = getstatement(1, "if False: 2\nelse: 3")
+ assert str(source) == "else: 3"
+
+def test_single_line_finally():
+ source = getstatement(1, "try: 1\nfinally: 3")
+ assert str(source) == "finally: 3"
+
+def test_issue55():
+ source = ('def round_trip(dinp):\n assert 1 == dinp\n'
+ 'def test_rt():\n round_trip("""\n""")\n')
+ s = getstatement(3, source)
+ assert str(s) == ' round_trip("""\n""")'
+
+
+def XXXtest_multiline():
+ source = getstatement(0, """\
+raise ValueError(
+ 23
+)
+x = 3
+""")
+ assert str(source) == "raise ValueError(\n 23\n)"
+
+class TestTry:
+ pytestmark = astonly
+ source = """\
+try:
+ raise ValueError
+except Something:
+ raise IndexError(1)
+else:
+ raise KeyError()
+"""
+
+ def test_body(self):
+ source = getstatement(1, self.source)
+ assert str(source) == " raise ValueError"
+
+ def test_except_line(self):
+ source = getstatement(2, self.source)
+ assert str(source) == "except Something:"
+
+ def test_except_body(self):
+ source = getstatement(3, self.source)
+ assert str(source) == " raise IndexError(1)"
+
+ def test_else(self):
+ source = getstatement(5, self.source)
+ assert str(source) == " raise KeyError()"
+
+class TestTryFinally:
+ source = """\
+try:
+ raise ValueError
+finally:
+ raise IndexError(1)
+"""
+
+ def test_body(self):
+ source = getstatement(1, self.source)
+ assert str(source) == " raise ValueError"
+
+ def test_finally(self):
+ source = getstatement(3, self.source)
+ assert str(source) == " raise IndexError(1)"
+
+
+
+class TestIf:
+ pytestmark = astonly
+ source = """\
+if 1:
+ y = 3
+elif False:
+ y = 5
+else:
+ y = 7
+"""
+
+ def test_body(self):
+ source = getstatement(1, self.source)
+ assert str(source) == " y = 3"
+
+ def test_elif_clause(self):
+ source = getstatement(2, self.source)
+ assert str(source) == "elif False:"
+
+ def test_elif(self):
+ source = getstatement(3, self.source)
+ assert str(source) == " y = 5"
+
+ def test_else(self):
+ source = getstatement(5, self.source)
+ assert str(source) == " y = 7"
+
+def test_semicolon():
+ s = """\
+hello ; pytest.skip()
+"""
+ source = getstatement(0, s)
+ assert str(source) == s.strip()
+
+def test_def_online():
+ s = """\
+def func(): raise ValueError(42)
+
+def something():
+ pass
+"""
+ source = getstatement(0, s)
+ assert str(source) == "def func(): raise ValueError(42)"
+
+def XXX_test_expression_multiline():
+ source = """\
+something
+'''
+'''"""
+ result = getstatement(1, source)
+ assert str(result) == "'''\n'''"
+
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/conftest.py b/tests/wpt/web-platform-tests/tools/py/testing/conftest.py
new file mode 100644
index 00000000000..0f956b3dd25
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/conftest.py
@@ -0,0 +1,3 @@
+
+pytest_plugins = "pytester",
+
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/io_/__init__.py b/tests/wpt/web-platform-tests/tools/py/testing/io_/__init__.py
new file mode 100644
index 00000000000..792d6005489
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/io_/__init__.py
@@ -0,0 +1 @@
+#
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/io_/test_capture.py b/tests/wpt/web-platform-tests/tools/py/testing/io_/test_capture.py
new file mode 100644
index 00000000000..5745e12a1a1
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/io_/test_capture.py
@@ -0,0 +1,501 @@
+from __future__ import with_statement
+
+import os, sys
+import py
+
+needsdup = py.test.mark.skipif("not hasattr(os, 'dup')")
+
+from py.builtin import print_
+
+if sys.version_info >= (3,0):
+ def tobytes(obj):
+ if isinstance(obj, str):
+ obj = obj.encode('UTF-8')
+ assert isinstance(obj, bytes)
+ return obj
+ def totext(obj):
+ if isinstance(obj, bytes):
+ obj = str(obj, 'UTF-8')
+ assert isinstance(obj, str)
+ return obj
+else:
+ def tobytes(obj):
+ if isinstance(obj, unicode):
+ obj = obj.encode('UTF-8')
+ assert isinstance(obj, str)
+ return obj
+ def totext(obj):
+ if isinstance(obj, str):
+ obj = unicode(obj, 'UTF-8')
+ assert isinstance(obj, unicode)
+ return obj
+
+def oswritebytes(fd, obj):
+ os.write(fd, tobytes(obj))
+
+class TestTextIO:
+ def test_text(self):
+ f = py.io.TextIO()
+ f.write("hello")
+ s = f.getvalue()
+ assert s == "hello"
+ f.close()
+
+ def test_unicode_and_str_mixture(self):
+ f = py.io.TextIO()
+ if sys.version_info >= (3,0):
+ f.write("\u00f6")
+ py.test.raises(TypeError, "f.write(bytes('hello', 'UTF-8'))")
+ else:
+ f.write(unicode("\u00f6", 'UTF-8'))
+ f.write("hello") # bytes
+ s = f.getvalue()
+ f.close()
+ assert isinstance(s, unicode)
+
+def test_bytes_io():
+ f = py.io.BytesIO()
+ f.write(tobytes("hello"))
+ py.test.raises(TypeError, "f.write(totext('hello'))")
+ s = f.getvalue()
+ assert s == tobytes("hello")
+
+def test_dontreadfrominput():
+ from py._io.capture import DontReadFromInput
+ f = DontReadFromInput()
+ assert not f.isatty()
+ py.test.raises(IOError, f.read)
+ py.test.raises(IOError, f.readlines)
+ py.test.raises(IOError, iter, f)
+ py.test.raises(ValueError, f.fileno)
+ f.close() # just for completeness
+
+def pytest_funcarg__tmpfile(request):
+ testdir = request.getfuncargvalue("testdir")
+ f = testdir.makepyfile("").open('wb+')
+ request.addfinalizer(f.close)
+ return f
+
+@needsdup
+def test_dupfile(tmpfile):
+ flist = []
+ for i in range(5):
+ nf = py.io.dupfile(tmpfile, encoding="utf-8")
+ assert nf != tmpfile
+ assert nf.fileno() != tmpfile.fileno()
+ assert nf not in flist
+ print_(i, end="", file=nf)
+ flist.append(nf)
+ for i in range(5):
+ f = flist[i]
+ f.close()
+ tmpfile.seek(0)
+ s = tmpfile.read()
+ assert "01234" in repr(s)
+ tmpfile.close()
+
+def test_dupfile_no_mode():
+ """
+ dupfile should trap an AttributeError and return f if no mode is supplied.
+ """
+ class SomeFileWrapper(object):
+ "An object with a fileno method but no mode attribute"
+ def fileno(self):
+ return 1
+ tmpfile = SomeFileWrapper()
+ assert py.io.dupfile(tmpfile) is tmpfile
+ with py.test.raises(AttributeError):
+ py.io.dupfile(tmpfile, raising=True)
+
+def lsof_check(func):
+ pid = os.getpid()
+ try:
+ out = py.process.cmdexec("lsof -p %d" % pid)
+ except py.process.cmdexec.Error:
+ py.test.skip("could not run 'lsof'")
+ func()
+ out2 = py.process.cmdexec("lsof -p %d" % pid)
+ len1 = len([x for x in out.split("\n") if "REG" in x])
+ len2 = len([x for x in out2.split("\n") if "REG" in x])
+ assert len2 < len1 + 3, out2
+
+class TestFDCapture:
+ pytestmark = needsdup
+
+ def test_not_now(self, tmpfile):
+ fd = tmpfile.fileno()
+ cap = py.io.FDCapture(fd, now=False)
+ data = tobytes("hello")
+ os.write(fd, data)
+ f = cap.done()
+ s = f.read()
+ assert not s
+ cap = py.io.FDCapture(fd, now=False)
+ cap.start()
+ os.write(fd, data)
+ f = cap.done()
+ s = f.read()
+ assert s == "hello"
+
+ def test_simple(self, tmpfile):
+ fd = tmpfile.fileno()
+ cap = py.io.FDCapture(fd)
+ data = tobytes("hello")
+ os.write(fd, data)
+ f = cap.done()
+ s = f.read()
+ assert s == "hello"
+ f.close()
+
+ def test_simple_many(self, tmpfile):
+ for i in range(10):
+ self.test_simple(tmpfile)
+
+ def test_simple_many_check_open_files(self, tmpfile):
+ lsof_check(lambda: self.test_simple_many(tmpfile))
+
+ def test_simple_fail_second_start(self, tmpfile):
+ fd = tmpfile.fileno()
+ cap = py.io.FDCapture(fd)
+ f = cap.done()
+ py.test.raises(ValueError, cap.start)
+ f.close()
+
+ def test_stderr(self):
+ cap = py.io.FDCapture(2, patchsys=True)
+ print_("hello", file=sys.stderr)
+ f = cap.done()
+ s = f.read()
+ assert s == "hello\n"
+
+ def test_stdin(self, tmpfile):
+ tmpfile.write(tobytes("3"))
+ tmpfile.seek(0)
+ cap = py.io.FDCapture(0, tmpfile=tmpfile)
+ # check with os.read() directly instead of raw_input(), because
+ # sys.stdin itself may be redirected (as py.test now does by default)
+ x = os.read(0, 100).strip()
+ f = cap.done()
+ assert x == tobytes("3")
+
+ def test_writeorg(self, tmpfile):
+ data1, data2 = tobytes("foo"), tobytes("bar")
+ try:
+ cap = py.io.FDCapture(tmpfile.fileno())
+ tmpfile.write(data1)
+ cap.writeorg(data2)
+ finally:
+ tmpfile.close()
+ f = cap.done()
+ scap = f.read()
+ assert scap == totext(data1)
+ stmp = open(tmpfile.name, 'rb').read()
+ assert stmp == data2
+
+
+class TestStdCapture:
+ def getcapture(self, **kw):
+ return py.io.StdCapture(**kw)
+
+ def test_capturing_done_simple(self):
+ cap = self.getcapture()
+ sys.stdout.write("hello")
+ sys.stderr.write("world")
+ outfile, errfile = cap.done()
+ s = outfile.read()
+ assert s == "hello"
+ s = errfile.read()
+ assert s == "world"
+
+ def test_capturing_reset_simple(self):
+ cap = self.getcapture()
+ print("hello world")
+ sys.stderr.write("hello error\n")
+ out, err = cap.reset()
+ assert out == "hello world\n"
+ assert err == "hello error\n"
+
+ def test_capturing_readouterr(self):
+ cap = self.getcapture()
+ try:
+ print ("hello world")
+ sys.stderr.write("hello error\n")
+ out, err = cap.readouterr()
+ assert out == "hello world\n"
+ assert err == "hello error\n"
+ sys.stderr.write("error2")
+ finally:
+ out, err = cap.reset()
+ assert err == "error2"
+
+ def test_capturing_readouterr_unicode(self):
+ cap = self.getcapture()
+ print ("hx\xc4\x85\xc4\x87")
+ out, err = cap.readouterr()
+ assert out == py.builtin._totext("hx\xc4\x85\xc4\x87\n", "utf8")
+
+ @py.test.mark.skipif('sys.version_info >= (3,)',
+ reason='text output different for bytes on python3')
+ def test_capturing_readouterr_decode_error_handling(self):
+ cap = self.getcapture()
+ # triggered a internal error in pytest
+ print('\xa6')
+ out, err = cap.readouterr()
+ assert out == py.builtin._totext('\ufffd\n', 'unicode-escape')
+
+ def test_capturing_mixed(self):
+ cap = self.getcapture(mixed=True)
+ sys.stdout.write("hello ")
+ sys.stderr.write("world")
+ sys.stdout.write(".")
+ out, err = cap.reset()
+ assert out.strip() == "hello world."
+ assert not err
+
+ def test_reset_twice_error(self):
+ cap = self.getcapture()
+ print ("hello")
+ out, err = cap.reset()
+ py.test.raises(ValueError, cap.reset)
+ assert out == "hello\n"
+ assert not err
+
+ def test_capturing_modify_sysouterr_in_between(self):
+ oldout = sys.stdout
+ olderr = sys.stderr
+ cap = self.getcapture()
+ sys.stdout.write("hello")
+ sys.stderr.write("world")
+ sys.stdout = py.io.TextIO()
+ sys.stderr = py.io.TextIO()
+ print ("not seen")
+ sys.stderr.write("not seen\n")
+ out, err = cap.reset()
+ assert out == "hello"
+ assert err == "world"
+ assert sys.stdout == oldout
+ assert sys.stderr == olderr
+
+ def test_capturing_error_recursive(self):
+ cap1 = self.getcapture()
+ print ("cap1")
+ cap2 = self.getcapture()
+ print ("cap2")
+ out2, err2 = cap2.reset()
+ out1, err1 = cap1.reset()
+ assert out1 == "cap1\n"
+ assert out2 == "cap2\n"
+
+ def test_just_out_capture(self):
+ cap = self.getcapture(out=True, err=False)
+ sys.stdout.write("hello")
+ sys.stderr.write("world")
+ out, err = cap.reset()
+ assert out == "hello"
+ assert not err
+
+ def test_just_err_capture(self):
+ cap = self.getcapture(out=False, err=True)
+ sys.stdout.write("hello")
+ sys.stderr.write("world")
+ out, err = cap.reset()
+ assert err == "world"
+ assert not out
+
+ def test_stdin_restored(self):
+ old = sys.stdin
+ cap = self.getcapture(in_=True)
+ newstdin = sys.stdin
+ out, err = cap.reset()
+ assert newstdin != sys.stdin
+ assert sys.stdin is old
+
+ def test_stdin_nulled_by_default(self):
+ print ("XXX this test may well hang instead of crashing")
+ print ("XXX which indicates an error in the underlying capturing")
+ print ("XXX mechanisms")
+ cap = self.getcapture()
+ py.test.raises(IOError, "sys.stdin.read()")
+ out, err = cap.reset()
+
+ def test_suspend_resume(self):
+ cap = self.getcapture(out=True, err=False, in_=False)
+ try:
+ print ("hello")
+ sys.stderr.write("error\n")
+ out, err = cap.suspend()
+ assert out == "hello\n"
+ assert not err
+ print ("in between")
+ sys.stderr.write("in between\n")
+ cap.resume()
+ print ("after")
+ sys.stderr.write("error_after\n")
+ finally:
+ out, err = cap.reset()
+ assert out == "after\n"
+ assert not err
+
+class TestStdCaptureNotNow(TestStdCapture):
+ def getcapture(self, **kw):
+ kw['now'] = False
+ cap = py.io.StdCapture(**kw)
+ cap.startall()
+ return cap
+
+class TestStdCaptureFD(TestStdCapture):
+ pytestmark = needsdup
+
+ def getcapture(self, **kw):
+ return py.io.StdCaptureFD(**kw)
+
+ def test_intermingling(self):
+ cap = self.getcapture()
+ oswritebytes(1, "1")
+ sys.stdout.write(str(2))
+ sys.stdout.flush()
+ oswritebytes(1, "3")
+ oswritebytes(2, "a")
+ sys.stderr.write("b")
+ sys.stderr.flush()
+ oswritebytes(2, "c")
+ out, err = cap.reset()
+ assert out == "123"
+ assert err == "abc"
+
+ def test_callcapture(self):
+ def func(x, y):
+ print (x)
+ py.std.sys.stderr.write(str(y))
+ return 42
+
+ res, out, err = py.io.StdCaptureFD.call(func, 3, y=4)
+ assert res == 42
+ assert out.startswith("3")
+ assert err.startswith("4")
+
+ def test_many(self, capfd):
+ def f():
+ for i in range(10):
+ cap = py.io.StdCaptureFD()
+ cap.reset()
+ lsof_check(f)
+
+class TestStdCaptureFDNotNow(TestStdCaptureFD):
+ pytestmark = needsdup
+
+ def getcapture(self, **kw):
+ kw['now'] = False
+ cap = py.io.StdCaptureFD(**kw)
+ cap.startall()
+ return cap
+
+@needsdup
+def test_stdcapture_fd_tmpfile(tmpfile):
+ capfd = py.io.StdCaptureFD(out=tmpfile)
+ os.write(1, "hello".encode("ascii"))
+ os.write(2, "world".encode("ascii"))
+ outf, errf = capfd.done()
+ assert outf == tmpfile
+
+class TestStdCaptureFDinvalidFD:
+ pytestmark = needsdup
+ def test_stdcapture_fd_invalid_fd(self, testdir):
+ testdir.makepyfile("""
+ import py, os
+ def test_stdout():
+ os.close(1)
+ cap = py.io.StdCaptureFD(out=True, err=False, in_=False)
+ cap.done()
+ def test_stderr():
+ os.close(2)
+ cap = py.io.StdCaptureFD(out=False, err=True, in_=False)
+ cap.done()
+ def test_stdin():
+ os.close(0)
+ cap = py.io.StdCaptureFD(out=False, err=False, in_=True)
+ cap.done()
+ """)
+ result = testdir.runpytest("--capture=fd")
+ assert result.ret == 0
+ assert result.parseoutcomes()['passed'] == 3
+
+def test_capture_not_started_but_reset():
+ capsys = py.io.StdCapture(now=False)
+ capsys.done()
+ capsys.done()
+ capsys.reset()
+
+@needsdup
+def test_capture_no_sys():
+ capsys = py.io.StdCapture()
+ try:
+ cap = py.io.StdCaptureFD(patchsys=False)
+ sys.stdout.write("hello")
+ sys.stderr.write("world")
+ oswritebytes(1, "1")
+ oswritebytes(2, "2")
+ out, err = cap.reset()
+ assert out == "1"
+ assert err == "2"
+ finally:
+ capsys.reset()
+
+@needsdup
+def test_callcapture_nofd():
+ def func(x, y):
+ oswritebytes(1, "hello")
+ oswritebytes(2, "hello")
+ print (x)
+ sys.stderr.write(str(y))
+ return 42
+
+ capfd = py.io.StdCaptureFD(patchsys=False)
+ try:
+ res, out, err = py.io.StdCapture.call(func, 3, y=4)
+ finally:
+ capfd.reset()
+ assert res == 42
+ assert out.startswith("3")
+ assert err.startswith("4")
+
+@needsdup
+@py.test.mark.multi(use=[True, False])
+def test_fdcapture_tmpfile_remains_the_same(tmpfile, use):
+ if not use:
+ tmpfile = True
+ cap = py.io.StdCaptureFD(out=False, err=tmpfile, now=False)
+ cap.startall()
+ capfile = cap.err.tmpfile
+ cap.suspend()
+ cap.resume()
+ capfile2 = cap.err.tmpfile
+ assert capfile2 == capfile
+
+@py.test.mark.multi(method=['StdCapture', 'StdCaptureFD'])
+def test_capturing_and_logging_fundamentals(testdir, method):
+ if method == "StdCaptureFD" and not hasattr(os, 'dup'):
+ py.test.skip("need os.dup")
+ # here we check a fundamental feature
+ p = testdir.makepyfile("""
+ import sys, os
+ import py, logging
+ cap = py.io.%s(out=False, in_=False)
+
+ logging.warn("hello1")
+ outerr = cap.suspend()
+ print ("suspend, captured %%s" %%(outerr,))
+ logging.warn("hello2")
+
+ cap.resume()
+ logging.warn("hello3")
+
+ outerr = cap.suspend()
+ print ("suspend2, captured %%s" %% (outerr,))
+ """ % (method,))
+ result = testdir.runpython(p)
+ result.stdout.fnmatch_lines([
+ "suspend, captured*hello1*",
+ "suspend2, captured*hello2*WARNING:root:hello3*",
+ ])
+ assert "atexit" not in result.stderr.str()
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/io_/test_saferepr.py b/tests/wpt/web-platform-tests/tools/py/testing/io_/test_saferepr.py
new file mode 100644
index 00000000000..1ed9c4faf62
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/io_/test_saferepr.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import generators
+import py
+import sys
+
+saferepr = py.io.saferepr
+
+class TestSafeRepr:
+ def test_simple_repr(self):
+ assert saferepr(1) == '1'
+ assert saferepr(None) == 'None'
+
+ def test_maxsize(self):
+ s = saferepr('x'*50, maxsize=25)
+ assert len(s) == 25
+ expected = repr('x'*10 + '...' + 'x'*10)
+ assert s == expected
+
+ def test_maxsize_error_on_instance(self):
+ class A:
+ def __repr__(self):
+ raise ValueError('...')
+
+ s = saferepr(('*'*50, A()), maxsize=25)
+ assert len(s) == 25
+ assert s[0] == '(' and s[-1] == ')'
+
+ def test_exceptions(self):
+ class BrokenRepr:
+ def __init__(self, ex):
+ self.ex = ex
+ foo = 0
+ def __repr__(self):
+ raise self.ex
+ class BrokenReprException(Exception):
+ __str__ = None
+ __repr__ = None
+ assert 'Exception' in saferepr(BrokenRepr(Exception("broken")))
+ s = saferepr(BrokenReprException("really broken"))
+ assert 'TypeError' in s
+ if py.std.sys.version_info < (2,6):
+ assert 'unknown' in saferepr(BrokenRepr("string"))
+ else:
+ assert 'TypeError' in saferepr(BrokenRepr("string"))
+
+ s2 = saferepr(BrokenRepr(BrokenReprException('omg even worse')))
+ assert 'NameError' not in s2
+ assert 'unknown' in s2
+
+ def test_big_repr(self):
+ from py._io.saferepr import SafeRepr
+ assert len(saferepr(range(1000))) <= \
+ len('[' + SafeRepr().maxlist * "1000" + ']')
+
+ def test_repr_on_newstyle(self):
+ class Function(object):
+ def __repr__(self):
+ return "<%s>" %(self.name)
+ try:
+ s = saferepr(Function())
+ except Exception:
+ py.test.fail("saferepr failed for newstyle class")
+
+ def test_unicode(self):
+ val = py.builtin._totext('£€', 'utf-8')
+ reprval = py.builtin._totext("'£€'", 'utf-8')
+ assert saferepr(val) == reprval
+
+def test_unicode_handling():
+ value = py.builtin._totext('\xc4\x85\xc4\x87\n', 'utf-8').encode('utf8')
+ def f():
+ raise Exception(value)
+ excinfo = py.test.raises(Exception, f)
+ s = str(excinfo)
+ if sys.version_info[0] < 3:
+ u = unicode(excinfo)
+
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/io_/test_terminalwriter.py b/tests/wpt/web-platform-tests/tools/py/testing/io_/test_terminalwriter.py
new file mode 100644
index 00000000000..0a15541bd23
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/io_/test_terminalwriter.py
@@ -0,0 +1,271 @@
+
+import py
+import os, sys
+from py._io import terminalwriter
+import codecs
+import pytest
+
+def test_get_terminal_width():
+ x = py.io.get_terminal_width
+ assert x == terminalwriter.get_terminal_width
+
+def test_getdimensions(monkeypatch):
+ fcntl = py.test.importorskip("fcntl")
+ import struct
+ l = []
+ monkeypatch.setattr(fcntl, 'ioctl', lambda *args: l.append(args))
+ try:
+ terminalwriter._getdimensions()
+ except (TypeError, struct.error):
+ pass
+ assert len(l) == 1
+ assert l[0][0] == 1
+
+def test_terminal_width_COLUMNS(monkeypatch):
+ """ Dummy test for get_terminal_width
+ """
+ fcntl = py.test.importorskip("fcntl")
+ monkeypatch.setattr(fcntl, 'ioctl', lambda *args: int('x'))
+ monkeypatch.setenv('COLUMNS', '42')
+ assert terminalwriter.get_terminal_width() == 42
+ monkeypatch.delenv('COLUMNS', raising=False)
+
+def test_terminalwriter_defaultwidth_80(monkeypatch):
+ monkeypatch.setattr(terminalwriter, '_getdimensions', lambda: 0/0)
+ monkeypatch.delenv('COLUMNS', raising=False)
+ tw = py.io.TerminalWriter()
+ assert tw.fullwidth == 80
+
+def test_terminalwriter_getdimensions_bogus(monkeypatch):
+ monkeypatch.setattr(terminalwriter, '_getdimensions', lambda: (10,10))
+ monkeypatch.delenv('COLUMNS', raising=False)
+ tw = py.io.TerminalWriter()
+ assert tw.fullwidth == 80
+
+def test_terminalwriter_getdimensions_emacs(monkeypatch):
+ # emacs terminal returns (0,0) but set COLUMNS properly
+ monkeypatch.setattr(terminalwriter, '_getdimensions', lambda: (0,0))
+ monkeypatch.setenv('COLUMNS', '42')
+ tw = py.io.TerminalWriter()
+ assert tw.fullwidth == 42
+
+def test_terminalwriter_computes_width(monkeypatch):
+ monkeypatch.setattr(terminalwriter, 'get_terminal_width', lambda: 42)
+ tw = py.io.TerminalWriter()
+ assert tw.fullwidth == 42
+
+def test_terminalwriter_default_instantiation():
+ tw = py.io.TerminalWriter(stringio=True)
+ assert hasattr(tw, 'stringio')
+
+def test_terminalwriter_dumb_term_no_markup(monkeypatch):
+ monkeypatch.setattr(os, 'environ', {'TERM': 'dumb', 'PATH': ''})
+ class MyFile:
+ closed = False
+ def isatty(self):
+ return True
+ monkeypatch.setattr(sys, 'stdout', MyFile())
+ try:
+ assert sys.stdout.isatty()
+ tw = py.io.TerminalWriter()
+ assert not tw.hasmarkup
+ finally:
+ monkeypatch.undo()
+
+def test_terminalwriter_file_unicode(tmpdir):
+ f = py.std.codecs.open(str(tmpdir.join("xyz")), "wb", "utf8")
+ tw = py.io.TerminalWriter(file=f)
+ assert tw.encoding == "utf8"
+
+def test_unicode_encoding():
+ msg = py.builtin._totext('b\u00f6y', 'utf8')
+ for encoding in 'utf8', 'latin1':
+ l = []
+ tw = py.io.TerminalWriter(l.append, encoding=encoding)
+ tw.line(msg)
+ assert l[0].strip() == msg.encode(encoding)
+
+@pytest.mark.parametrize("encoding", ["ascii"])
+def test_unicode_on_file_with_ascii_encoding(tmpdir, monkeypatch, encoding):
+ msg = py.builtin._totext('hell\xf6', "latin1")
+ #pytest.raises(UnicodeEncodeError, lambda: bytes(msg))
+ f = py.std.codecs.open(str(tmpdir.join("x")), "w", encoding)
+ tw = py.io.TerminalWriter(f)
+ tw.line(msg)
+ f.close()
+ s = tmpdir.join("x").open("rb").read().strip()
+ assert encoding == "ascii"
+ assert s == msg.encode("unicode-escape")
+
+
+win32 = int(sys.platform == "win32")
+class TestTerminalWriter:
+ def pytest_generate_tests(self, metafunc):
+ if "tw" in metafunc.funcargnames:
+ metafunc.addcall(id="path", param="path")
+ metafunc.addcall(id="stringio", param="stringio")
+ metafunc.addcall(id="callable", param="callable")
+ def pytest_funcarg__tw(self, request):
+ if request.param == "path":
+ tmpdir = request.getfuncargvalue("tmpdir")
+ p = tmpdir.join("tmpfile")
+ f = codecs.open(str(p), 'w+', encoding='utf8')
+ tw = py.io.TerminalWriter(f)
+ def getlines():
+ tw._file.flush()
+ return codecs.open(str(p), 'r',
+ encoding='utf8').readlines()
+ elif request.param == "stringio":
+ tw = py.io.TerminalWriter(stringio=True)
+ def getlines():
+ tw.stringio.seek(0)
+ return tw.stringio.readlines()
+ elif request.param == "callable":
+ writes = []
+ tw = py.io.TerminalWriter(writes.append)
+ def getlines():
+ io = py.io.TextIO()
+ io.write("".join(writes))
+ io.seek(0)
+ return io.readlines()
+ tw.getlines = getlines
+ tw.getvalue = lambda: "".join(getlines())
+ return tw
+
+ def test_line(self, tw):
+ tw.line("hello")
+ l = tw.getlines()
+ assert len(l) == 1
+ assert l[0] == "hello\n"
+
+ def test_line_unicode(self, tw):
+ for encoding in 'utf8', 'latin1':
+ tw._encoding = encoding
+ msg = py.builtin._totext('b\u00f6y', 'utf8')
+ tw.line(msg)
+ l = tw.getlines()
+ assert l[0] == msg + "\n"
+
+ def test_sep_no_title(self, tw):
+ tw.sep("-", fullwidth=60)
+ l = tw.getlines()
+ assert len(l) == 1
+ assert l[0] == "-" * (60-win32) + "\n"
+
+ def test_sep_with_title(self, tw):
+ tw.sep("-", "hello", fullwidth=60)
+ l = tw.getlines()
+ assert len(l) == 1
+ assert l[0] == "-" * 26 + " hello " + "-" * (27-win32) + "\n"
+
+ @py.test.mark.skipif("sys.platform == 'win32'")
+ def test__escaped(self, tw):
+ text2 = tw._escaped("hello", (31))
+ assert text2.find("hello") != -1
+
+ @py.test.mark.skipif("sys.platform == 'win32'")
+ def test_markup(self, tw):
+ for bold in (True, False):
+ for color in ("red", "green"):
+ text2 = tw.markup("hello", **{color: True, 'bold': bold})
+ assert text2.find("hello") != -1
+ py.test.raises(ValueError, "tw.markup('x', wronkw=3)")
+ py.test.raises(ValueError, "tw.markup('x', wronkw=0)")
+
+ def test_line_write_markup(self, tw):
+ tw.hasmarkup = True
+ tw.line("x", bold=True)
+ tw.write("x\n", red=True)
+ l = tw.getlines()
+ if sys.platform != "win32":
+ assert len(l[0]) >= 2, l
+ assert len(l[1]) >= 2, l
+
+ def test_attr_fullwidth(self, tw):
+ tw.sep("-", "hello", fullwidth=70)
+ tw.fullwidth = 70
+ tw.sep("-", "hello")
+ l = tw.getlines()
+ assert len(l[0]) == len(l[1])
+
+ def test_reline(self, tw):
+ tw.line("hello")
+ tw.hasmarkup = False
+ pytest.raises(ValueError, lambda: tw.reline("x"))
+ tw.hasmarkup = True
+ tw.reline("0 1 2")
+ tw.getlines()
+ l = tw.getvalue().split("\n")
+ assert len(l) == 2
+ tw.reline("0 1 3")
+ l = tw.getvalue().split("\n")
+ assert len(l) == 2
+ assert l[1].endswith("0 1 3\r")
+ tw.line("so")
+ l = tw.getvalue().split("\n")
+ assert len(l) == 3
+ assert l[-1] == ""
+ assert l[1] == ("0 1 2\r0 1 3\rso ")
+ assert l[0] == "hello"
+
+
+def test_terminal_with_callable_write_and_flush():
+ l = set()
+ class fil:
+ flush = lambda self: l.add("1")
+ write = lambda self, x: l.add("1")
+ __call__ = lambda self, x: l.add("2")
+
+ tw = py.io.TerminalWriter(fil())
+ tw.line("hello")
+ assert l == set(["1"])
+ del fil.flush
+ l.clear()
+ tw = py.io.TerminalWriter(fil())
+ tw.line("hello")
+ assert l == set(["2"])
+
+
+@pytest.mark.skipif(sys.platform == "win32", reason="win32 has no native ansi")
+def test_attr_hasmarkup():
+ tw = py.io.TerminalWriter(stringio=True)
+ assert not tw.hasmarkup
+ tw.hasmarkup = True
+ tw.line("hello", bold=True)
+ s = tw.stringio.getvalue()
+ assert len(s) > len("hello\n")
+ assert '\x1b[1m' in s
+ assert '\x1b[0m' in s
+
+@pytest.mark.skipif(sys.platform == "win32", reason="win32 has no native ansi")
+def test_ansi_print():
+ # we have no easy way to construct a file that
+ # represents a terminal
+ f = py.io.TextIO()
+ f.isatty = lambda: True
+ py.io.ansi_print("hello", 0x32, file=f)
+ text2 = f.getvalue()
+ assert text2.find("hello") != -1
+ assert len(text2) >= len("hello\n")
+ assert '\x1b[50m' in text2
+ assert '\x1b[0m' in text2
+
+def test_should_do_markup_PY_COLORS_eq_1(monkeypatch):
+ monkeypatch.setitem(os.environ, 'PY_COLORS', '1')
+ tw = py.io.TerminalWriter(stringio=True)
+ assert tw.hasmarkup
+ tw.line("hello", bold=True)
+ s = tw.stringio.getvalue()
+ assert len(s) > len("hello\n")
+ assert '\x1b[1m' in s
+ assert '\x1b[0m' in s
+
+def test_should_do_markup_PY_COLORS_eq_0(monkeypatch):
+ monkeypatch.setitem(os.environ, 'PY_COLORS', '0')
+ f = py.io.TextIO()
+ f.isatty = lambda: True
+ tw = py.io.TerminalWriter(file=f)
+ assert not tw.hasmarkup
+ tw.line("hello", bold=True)
+ s = f.getvalue()
+ assert s == "hello\n"
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/log/__init__.py b/tests/wpt/web-platform-tests/tools/py/testing/log/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/log/__init__.py
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/log/test_log.py b/tests/wpt/web-platform-tests/tools/py/testing/log/test_log.py
new file mode 100644
index 00000000000..b41bc3a5821
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/log/test_log.py
@@ -0,0 +1,190 @@
+import py
+import sys
+
+from py._log.log import default_keywordmapper
+
+callcapture = py.io.StdCapture.call
+
+def setup_module(mod):
+ mod._oldstate = default_keywordmapper.getstate()
+
+def teardown_module(mod):
+ default_keywordmapper.setstate(mod._oldstate)
+
+class TestLogProducer:
+ def setup_method(self, meth):
+ default_keywordmapper.setstate(_oldstate)
+
+ def test_getstate_setstate(self):
+ state = py.log._getstate()
+ py.log.setconsumer("hello", [].append)
+ state2 = py.log._getstate()
+ assert state2 != state
+ py.log._setstate(state)
+ state3 = py.log._getstate()
+ assert state3 == state
+
+ def test_producer_repr(self):
+ d = py.log.Producer("default")
+ assert repr(d).find('default') != -1
+
+ def test_produce_one_keyword(self):
+ l = []
+ py.log.setconsumer('s1', l.append)
+ py.log.Producer('s1')("hello world")
+ assert len(l) == 1
+ msg = l[0]
+ assert msg.content().startswith('hello world')
+ assert msg.prefix() == '[s1] '
+ assert str(msg) == "[s1] hello world"
+
+ def test_producer_class(self):
+ p = py.log.Producer('x1')
+ l = []
+ py.log.setconsumer(p._keywords, l.append)
+ p("hello")
+ assert len(l) == 1
+ assert len(l[0].keywords) == 1
+ assert 'x1' == l[0].keywords[0]
+
+ def test_producer_caching(self):
+ p = py.log.Producer('x1')
+ x2 = p.x2
+ assert x2 is p.x2
+
+class TestLogConsumer:
+ def setup_method(self, meth):
+ default_keywordmapper.setstate(_oldstate)
+ def test_log_none(self):
+ log = py.log.Producer("XXX")
+ l = []
+ py.log.setconsumer('XXX', l.append)
+ log("1")
+ assert l
+ l[:] = []
+ py.log.setconsumer('XXX', None)
+ log("2")
+ assert not l
+
+ def test_log_default_stderr(self):
+ res, out, err = callcapture(py.log.Producer("default"), "hello")
+ assert err.strip() == "[default] hello"
+
+ def test_simple_consumer_match(self):
+ l = []
+ py.log.setconsumer("x1", l.append)
+ p = py.log.Producer("x1 x2")
+ p("hello")
+ assert l
+ assert l[0].content() == "hello"
+
+ def test_simple_consumer_match_2(self):
+ l = []
+ p = py.log.Producer("x1 x2")
+ py.log.setconsumer(p._keywords, l.append)
+ p("42")
+ assert l
+ assert l[0].content() == "42"
+
+ def test_no_auto_producer(self):
+ p = py.log.Producer('x')
+ py.test.raises(AttributeError, "p._x")
+ py.test.raises(AttributeError, "p.x_y")
+
+ def test_setconsumer_with_producer(self):
+ l = []
+ p = py.log.Producer("hello")
+ py.log.setconsumer(p, l.append)
+ p("world")
+ assert str(l[0]) == "[hello] world"
+
+ def test_multi_consumer(self):
+ l = []
+ py.log.setconsumer("x1", l.append)
+ py.log.setconsumer("x1 x2", None)
+ p = py.log.Producer("x1 x2")
+ p("hello")
+ assert not l
+ py.log.Producer("x1")("hello")
+ assert l
+ assert l[0].content() == "hello"
+
+ def test_log_stderr(self):
+ py.log.setconsumer("xyz", py.log.STDOUT)
+ res, out, err = callcapture(py.log.Producer("xyz"), "hello")
+ assert not err
+ assert out.strip() == '[xyz] hello'
+
+ def test_log_file(self, tmpdir):
+ customlog = tmpdir.join('log.out')
+ py.log.setconsumer("default", open(str(customlog), 'w', 1))
+ py.log.Producer("default")("hello world #1")
+ assert customlog.readlines() == ['[default] hello world #1\n']
+
+ py.log.setconsumer("default", py.log.Path(customlog, buffering=False))
+ py.log.Producer("default")("hello world #2")
+ res = customlog.readlines()
+ assert res == ['[default] hello world #2\n'] # no append by default!
+
+ def test_log_file_append_mode(self, tmpdir):
+ logfilefn = tmpdir.join('log_append.out')
+
+ # The append mode is on by default, so we don't need to specify it for File
+ py.log.setconsumer("default", py.log.Path(logfilefn, append=True,
+ buffering=0))
+ assert logfilefn.check()
+ py.log.Producer("default")("hello world #1")
+ lines = logfilefn.readlines()
+ assert lines == ['[default] hello world #1\n']
+ py.log.setconsumer("default", py.log.Path(logfilefn, append=True,
+ buffering=0))
+ py.log.Producer("default")("hello world #1")
+ lines = logfilefn.readlines()
+ assert lines == ['[default] hello world #1\n',
+ '[default] hello world #1\n']
+
+ def test_log_file_delayed_create(self, tmpdir):
+ logfilefn = tmpdir.join('log_create.out')
+
+ py.log.setconsumer("default", py.log.Path(logfilefn,
+ delayed_create=True, buffering=0))
+ assert not logfilefn.check()
+ py.log.Producer("default")("hello world #1")
+ lines = logfilefn.readlines()
+ assert lines == ['[default] hello world #1\n']
+
+ def test_keyword_based_log_files(self, tmpdir):
+ logfiles = []
+ keywords = 'k1 k2 k3'.split()
+ for key in keywords:
+ path = tmpdir.join(key)
+ py.log.setconsumer(key, py.log.Path(path, buffering=0))
+
+ py.log.Producer('k1')('1')
+ py.log.Producer('k2')('2')
+ py.log.Producer('k3')('3')
+
+ for key in keywords:
+ path = tmpdir.join(key)
+ assert path.read().strip() == '[%s] %s' % (key, key[-1])
+
+ # disabled for now; the syslog log file can usually be read only by root
+ # I manually inspected /var/log/messages and the entries were there
+ def no_test_log_syslog(self):
+ py.log.setconsumer("default", py.log.Syslog())
+ py.log.default("hello world #1")
+
+ # disabled for now until I figure out how to read entries in the
+ # Event Logs on Windows
+ # I manually inspected the Application Log and the entries were there
+ def no_test_log_winevent(self):
+ py.log.setconsumer("default", py.log.WinEvent())
+ py.log.default("hello world #1")
+
+ # disabled for now until I figure out how to properly pass the parameters
+ def no_test_log_email(self):
+ py.log.setconsumer("default", py.log.Email(mailhost="gheorghiu.net",
+ fromaddr="grig",
+ toaddrs="grig",
+ subject = "py.log email"))
+ py.log.default("hello world #1")
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/log/test_warning.py b/tests/wpt/web-platform-tests/tools/py/testing/log/test_warning.py
new file mode 100644
index 00000000000..8c89cf8adbb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/log/test_warning.py
@@ -0,0 +1,76 @@
+import pytest
+import py
+
+mypath = py.path.local(__file__).new(ext=".py")
+
+@pytest.mark.xfail
+def test_forwarding_to_warnings_module():
+ pytest.deprecated_call(py.log._apiwarn, "1.3", "..")
+
+def test_apiwarn_functional(recwarn):
+ capture = py.io.StdCapture()
+ py.log._apiwarn("x.y.z", "something", stacklevel=1)
+ out, err = capture.reset()
+ py.builtin.print_("out", out)
+ py.builtin.print_("err", err)
+ assert err.find("x.y.z") != -1
+ lno = py.code.getrawcode(test_apiwarn_functional).co_firstlineno + 2
+ exp = "%s:%s" % (mypath, lno)
+ assert err.find(exp) != -1
+
+def test_stacklevel(recwarn):
+ def f():
+ py.log._apiwarn("x", "some", stacklevel=2)
+ # 3
+ # 4
+ capture = py.io.StdCapture()
+ f()
+ out, err = capture.reset()
+ lno = py.code.getrawcode(test_stacklevel).co_firstlineno + 6
+ warning = str(err)
+ assert warning.find(":%s" % lno) != -1
+
+def test_stacklevel_initpkg_with_resolve(testdir, recwarn):
+ testdir.makepyfile(modabc="""
+ import py
+ def f():
+ py.log._apiwarn("x", "some", stacklevel="apipkg123")
+ """)
+ testdir.makepyfile(apipkg123="""
+ def __getattr__():
+ import modabc
+ modabc.f()
+ """)
+ p = testdir.makepyfile("""
+ import apipkg123
+ apipkg123.__getattr__()
+ """)
+ capture = py.io.StdCapture()
+ p.pyimport()
+ out, err = capture.reset()
+ warning = str(err)
+ loc = 'test_stacklevel_initpkg_with_resolve.py:2'
+ assert warning.find(loc) != -1
+
+def test_stacklevel_initpkg_no_resolve(recwarn):
+ def f():
+ py.log._apiwarn("x", "some", stacklevel="apipkg")
+ capture = py.io.StdCapture()
+ f()
+ out, err = capture.reset()
+ lno = py.code.getrawcode(test_stacklevel_initpkg_no_resolve).co_firstlineno + 2
+ warning = str(err)
+ assert warning.find(":%s" % lno) != -1
+
+
+def test_function(recwarn):
+ capture = py.io.StdCapture()
+ py.log._apiwarn("x.y.z", "something", function=test_function)
+ out, err = capture.reset()
+ py.builtin.print_("out", out)
+ py.builtin.print_("err", err)
+ assert err.find("x.y.z") != -1
+ lno = py.code.getrawcode(test_function).co_firstlineno
+ exp = "%s:%s" % (mypath, lno)
+ assert err.find(exp) != -1
+
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/common.py b/tests/wpt/web-platform-tests/tools/py/testing/path/common.py
new file mode 100644
index 00000000000..4834fba12d0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/common.py
@@ -0,0 +1,470 @@
+import py
+import sys
+
+class CommonFSTests(object):
+ def test_constructor_equality(self, path1):
+ p = path1.__class__(path1)
+ assert p == path1
+
+ def test_eq_nonstring(self, path1):
+ p1 = path1.join('sampledir')
+ p2 = path1.join('sampledir')
+ assert p1 == p2
+
+ def test_new_identical(self, path1):
+ assert path1 == path1.new()
+
+ def test_join(self, path1):
+ p = path1.join('sampledir')
+ strp = str(p)
+ assert strp.endswith('sampledir')
+ assert strp.startswith(str(path1))
+
+ def test_join_normalized(self, path1):
+ newpath = path1.join(path1.sep+'sampledir')
+ strp = str(newpath)
+ assert strp.endswith('sampledir')
+ assert strp.startswith(str(path1))
+ newpath = path1.join((path1.sep*2) + 'sampledir')
+ strp = str(newpath)
+ assert strp.endswith('sampledir')
+ assert strp.startswith(str(path1))
+
+ def test_join_noargs(self, path1):
+ newpath = path1.join()
+ assert path1 == newpath
+
+ def test_add_something(self, path1):
+ p = path1.join('sample')
+ p = p + 'dir'
+ assert p.check()
+ assert p.exists()
+ assert p.isdir()
+ assert not p.isfile()
+
+ def test_parts(self, path1):
+ newpath = path1.join('sampledir', 'otherfile')
+ par = newpath.parts()[-3:]
+ assert par == [path1, path1.join('sampledir'), newpath]
+
+ revpar = newpath.parts(reverse=True)[:3]
+ assert revpar == [newpath, path1.join('sampledir'), path1]
+
+ def test_common(self, path1):
+ other = path1.join('sampledir')
+ x = other.common(path1)
+ assert x == path1
+
+ #def test_parents_nonexisting_file(self, path1):
+ # newpath = path1 / 'dirnoexist' / 'nonexisting file'
+ # par = list(newpath.parents())
+ # assert par[:2] == [path1 / 'dirnoexist', path1]
+
+ def test_basename_checks(self, path1):
+ newpath = path1.join('sampledir')
+ assert newpath.check(basename='sampledir')
+ assert newpath.check(notbasename='xyz')
+ assert newpath.basename == 'sampledir'
+
+ def test_basename(self, path1):
+ newpath = path1.join('sampledir')
+ assert newpath.check(basename='sampledir')
+ assert newpath.basename, 'sampledir'
+
+ def test_dirname(self, path1):
+ newpath = path1.join('sampledir')
+ assert newpath.dirname == str(path1)
+
+ def test_dirpath(self, path1):
+ newpath = path1.join('sampledir')
+ assert newpath.dirpath() == path1
+
+ def test_dirpath_with_args(self, path1):
+ newpath = path1.join('sampledir')
+ assert newpath.dirpath('x') == path1.join('x')
+
+ def test_newbasename(self, path1):
+ newpath = path1.join('samplefile')
+ newbase = newpath.new(basename="samplefile2")
+ assert newbase.basename == "samplefile2"
+ assert newbase.dirpath() == newpath.dirpath()
+
+ def test_not_exists(self, path1):
+ assert not path1.join('does_not_exist').check()
+ assert path1.join('does_not_exist').check(exists=0)
+
+ def test_exists(self, path1):
+ assert path1.join("samplefile").check()
+ assert path1.join("samplefile").check(exists=1)
+ assert path1.join("samplefile").exists()
+ assert path1.join("samplefile").isfile()
+ assert not path1.join("samplefile").isdir()
+
+ def test_dir(self, path1):
+ #print repr(path1.join("sampledir"))
+ assert path1.join("sampledir").check(dir=1)
+ assert path1.join('samplefile').check(notdir=1)
+ assert not path1.join("samplefile").check(dir=1)
+ assert path1.join("samplefile").exists()
+ assert not path1.join("samplefile").isdir()
+ assert path1.join("samplefile").isfile()
+
+ def test_fnmatch_file(self, path1):
+ assert path1.join("samplefile").check(fnmatch='s*e')
+ assert path1.join("samplefile").fnmatch('s*e')
+ assert not path1.join("samplefile").fnmatch('s*x')
+ assert not path1.join("samplefile").check(fnmatch='s*x')
+
+ #def test_fnmatch_dir(self, path1):
+
+ # pattern = path1.sep.join(['s*file'])
+ # sfile = path1.join("samplefile")
+ # assert sfile.check(fnmatch=pattern)
+
+ def test_relto(self, path1):
+ l=path1.join("sampledir", "otherfile")
+ assert l.relto(path1) == l.sep.join(["sampledir", "otherfile"])
+ assert l.check(relto=path1)
+ assert path1.check(notrelto=l)
+ assert not path1.check(relto=l)
+
+ def test_bestrelpath(self, path1):
+ curdir = path1
+ sep = curdir.sep
+ s = curdir.bestrelpath(curdir)
+ assert s == "."
+ s = curdir.bestrelpath(curdir.join("hello", "world"))
+ assert s == "hello" + sep + "world"
+
+ s = curdir.bestrelpath(curdir.dirpath().join("sister"))
+ assert s == ".." + sep + "sister"
+ assert curdir.bestrelpath(curdir.dirpath()) == ".."
+
+ assert curdir.bestrelpath("hello") == "hello"
+
+ def test_relto_not_relative(self, path1):
+ l1=path1.join("bcde")
+ l2=path1.join("b")
+ assert not l1.relto(l2)
+ assert not l2.relto(l1)
+
+ @py.test.mark.xfail("sys.platform.startswith('java')")
+ def test_listdir(self, path1):
+ l = path1.listdir()
+ assert path1.join('sampledir') in l
+ assert path1.join('samplefile') in l
+ py.test.raises(py.error.ENOTDIR,
+ "path1.join('samplefile').listdir()")
+
+ def test_listdir_fnmatchstring(self, path1):
+ l = path1.listdir('s*dir')
+ assert len(l)
+ assert l[0], path1.join('sampledir')
+
+ def test_listdir_filter(self, path1):
+ l = path1.listdir(lambda x: x.check(dir=1))
+ assert path1.join('sampledir') in l
+ assert not path1.join('samplefile') in l
+
+ def test_listdir_sorted(self, path1):
+ l = path1.listdir(lambda x: x.check(basestarts="sample"), sort=True)
+ assert path1.join('sampledir') == l[0]
+ assert path1.join('samplefile') == l[1]
+ assert path1.join('samplepickle') == l[2]
+
+ def test_visit_nofilter(self, path1):
+ l = []
+ for i in path1.visit():
+ l.append(i.relto(path1))
+ assert "sampledir" in l
+ assert path1.sep.join(["sampledir", "otherfile"]) in l
+
+ def test_visit_norecurse(self, path1):
+ l = []
+ for i in path1.visit(None, lambda x: x.basename != "sampledir"):
+ l.append(i.relto(path1))
+ assert "sampledir" in l
+ assert not path1.sep.join(["sampledir", "otherfile"]) in l
+
+ def test_visit_filterfunc_is_string(self, path1):
+ l = []
+ for i in path1.visit('*dir'):
+ l.append(i.relto(path1))
+ assert len(l), 2
+ assert "sampledir" in l
+ assert "otherdir" in l
+
+ @py.test.mark.xfail("sys.platform.startswith('java')")
+ def test_visit_ignore(self, path1):
+ p = path1.join('nonexisting')
+ assert list(p.visit(ignore=py.error.ENOENT)) == []
+
+ def test_visit_endswith(self, path1):
+ l = []
+ for i in path1.visit(lambda x: x.check(endswith="file")):
+ l.append(i.relto(path1))
+ assert path1.sep.join(["sampledir", "otherfile"]) in l
+ assert "samplefile" in l
+
+ def test_endswith(self, path1):
+ assert path1.check(notendswith='.py')
+ x = path1.join('samplefile')
+ assert x.check(endswith='file')
+
+ def test_cmp(self, path1):
+ path1 = path1.join('samplefile')
+ path2 = path1.join('samplefile2')
+ assert (path1 < path2) == ('samplefile' < 'samplefile2')
+ assert not (path1 < path1)
+
+ def test_simple_read(self, path1):
+ x = path1.join('samplefile').read('r')
+ assert x == 'samplefile\n'
+
+ def test_join_div_operator(self, path1):
+ newpath = path1 / '/sampledir' / '/test//'
+ newpath2 = path1.join('sampledir', 'test')
+ assert newpath == newpath2
+
+ def test_ext(self, path1):
+ newpath = path1.join('sampledir.ext')
+ assert newpath.ext == '.ext'
+ newpath = path1.join('sampledir')
+ assert not newpath.ext
+
+ def test_purebasename(self, path1):
+ newpath = path1.join('samplefile.py')
+ assert newpath.purebasename == 'samplefile'
+
+ def test_multiple_parts(self, path1):
+ newpath = path1.join('samplefile.py')
+ dirname, purebasename, basename, ext = newpath._getbyspec(
+ 'dirname,purebasename,basename,ext')
+ assert str(path1).endswith(dirname) # be careful with win32 'drive'
+ assert purebasename == 'samplefile'
+ assert basename == 'samplefile.py'
+ assert ext == '.py'
+
+ def test_dotted_name_ext(self, path1):
+ newpath = path1.join('a.b.c')
+ ext = newpath.ext
+ assert ext == '.c'
+ assert newpath.ext == '.c'
+
+ def test_newext(self, path1):
+ newpath = path1.join('samplefile.py')
+ newext = newpath.new(ext='.txt')
+ assert newext.basename == "samplefile.txt"
+ assert newext.purebasename == "samplefile"
+
+ def test_readlines(self, path1):
+ fn = path1.join('samplefile')
+ contents = fn.readlines()
+ assert contents == ['samplefile\n']
+
+ def test_readlines_nocr(self, path1):
+ fn = path1.join('samplefile')
+ contents = fn.readlines(cr=0)
+ assert contents == ['samplefile', '']
+
+ def test_file(self, path1):
+ assert path1.join('samplefile').check(file=1)
+
+ def test_not_file(self, path1):
+ assert not path1.join("sampledir").check(file=1)
+ assert path1.join("sampledir").check(file=0)
+
+ def test_non_existent(self, path1):
+ assert path1.join("sampledir.nothere").check(dir=0)
+ assert path1.join("sampledir.nothere").check(file=0)
+ assert path1.join("sampledir.nothere").check(notfile=1)
+ assert path1.join("sampledir.nothere").check(notdir=1)
+ assert path1.join("sampledir.nothere").check(notexists=1)
+ assert not path1.join("sampledir.nothere").check(notfile=0)
+
+ # pattern = path1.sep.join(['s*file'])
+ # sfile = path1.join("samplefile")
+ # assert sfile.check(fnmatch=pattern)
+
+ def test_size(self, path1):
+ url = path1.join("samplefile")
+ assert url.size() > len("samplefile")
+
+ def test_mtime(self, path1):
+ url = path1.join("samplefile")
+ assert url.mtime() > 0
+
+ def test_relto_wrong_type(self, path1):
+ py.test.raises(TypeError, "path1.relto(42)")
+
+ def test_load(self, path1):
+ p = path1.join('samplepickle')
+ obj = p.load()
+ assert type(obj) is dict
+ assert obj.get('answer',None) == 42
+
+ def test_visit_filesonly(self, path1):
+ l = []
+ for i in path1.visit(lambda x: x.check(file=1)):
+ l.append(i.relto(path1))
+ assert not "sampledir" in l
+ assert path1.sep.join(["sampledir", "otherfile"]) in l
+
+ def test_visit_nodotfiles(self, path1):
+ l = []
+ for i in path1.visit(lambda x: x.check(dotfile=0)):
+ l.append(i.relto(path1))
+ assert "sampledir" in l
+ assert path1.sep.join(["sampledir", "otherfile"]) in l
+ assert not ".dotfile" in l
+
+ def test_visit_breadthfirst(self, path1):
+ l = []
+ for i in path1.visit(bf=True):
+ l.append(i.relto(path1))
+ for i, p in enumerate(l):
+ if path1.sep in p:
+ for j in range(i, len(l)):
+ assert path1.sep in l[j]
+ break
+ else:
+ py.test.fail("huh")
+
+ def test_visit_sort(self, path1):
+ l = []
+ for i in path1.visit(bf=True, sort=True):
+ l.append(i.relto(path1))
+ for i, p in enumerate(l):
+ if path1.sep in p:
+ break
+ assert l[:i] == sorted(l[:i])
+ assert l[i:] == sorted(l[i:])
+
+ def test_endswith(self, path1):
+ def chk(p):
+ return p.check(endswith="pickle")
+ assert not chk(path1)
+ assert not chk(path1.join('samplefile'))
+ assert chk(path1.join('somepickle'))
+
+ def test_copy_file(self, path1):
+ otherdir = path1.join('otherdir')
+ initpy = otherdir.join('__init__.py')
+ copied = otherdir.join('copied')
+ initpy.copy(copied)
+ try:
+ assert copied.check()
+ s1 = initpy.read()
+ s2 = copied.read()
+ assert s1 == s2
+ finally:
+ if copied.check():
+ copied.remove()
+
+ def test_copy_dir(self, path1):
+ otherdir = path1.join('otherdir')
+ copied = path1.join('newdir')
+ try:
+ otherdir.copy(copied)
+ assert copied.check(dir=1)
+ assert copied.join('__init__.py').check(file=1)
+ s1 = otherdir.join('__init__.py').read()
+ s2 = copied.join('__init__.py').read()
+ assert s1 == s2
+ finally:
+ if copied.check(dir=1):
+ copied.remove(rec=1)
+
+ def test_remove_file(self, path1):
+ d = path1.ensure('todeleted')
+ assert d.check()
+ d.remove()
+ assert not d.check()
+
+ def test_remove_dir_recursive_by_default(self, path1):
+ d = path1.ensure('to', 'be', 'deleted')
+ assert d.check()
+ p = path1.join('to')
+ p.remove()
+ assert not p.check()
+
+ def test_ensure_dir(self, path1):
+ b = path1.ensure_dir("001", "002")
+ assert b.basename == "002"
+ assert b.isdir()
+
+ def test_mkdir_and_remove(self, path1):
+ tmpdir = path1
+ py.test.raises(py.error.EEXIST, tmpdir.mkdir, 'sampledir')
+ new = tmpdir.join('mktest1')
+ new.mkdir()
+ assert new.check(dir=1)
+ new.remove()
+
+ new = tmpdir.mkdir('mktest')
+ assert new.check(dir=1)
+ new.remove()
+ assert tmpdir.join('mktest') == new
+
+ def test_move_file(self, path1):
+ p = path1.join('samplefile')
+ newp = p.dirpath('moved_samplefile')
+ p.move(newp)
+ try:
+ assert newp.check(file=1)
+ assert not p.check()
+ finally:
+ dp = newp.dirpath()
+ if hasattr(dp, 'revert'):
+ dp.revert()
+ else:
+ newp.move(p)
+ assert p.check()
+
+ def test_move_dir(self, path1):
+ source = path1.join('sampledir')
+ dest = path1.join('moveddir')
+ source.move(dest)
+ assert dest.check(dir=1)
+ assert dest.join('otherfile').check(file=1)
+ assert not source.join('sampledir').check()
+
+def setuptestfs(path):
+ if path.join('samplefile').check():
+ return
+ #print "setting up test fs for", repr(path)
+ samplefile = path.ensure('samplefile')
+ samplefile.write('samplefile\n')
+
+ execfile = path.ensure('execfile')
+ execfile.write('x=42')
+
+ execfilepy = path.ensure('execfile.py')
+ execfilepy.write('x=42')
+
+ d = {1:2, 'hello': 'world', 'answer': 42}
+ path.ensure('samplepickle').dump(d)
+
+ sampledir = path.ensure('sampledir', dir=1)
+ sampledir.ensure('otherfile')
+
+ otherdir = path.ensure('otherdir', dir=1)
+ otherdir.ensure('__init__.py')
+
+ module_a = otherdir.ensure('a.py')
+ if sys.version_info >= (2,6):
+ module_a.write('from .b import stuff as result\n')
+ else:
+ module_a.write('from b import stuff as result\n')
+ module_b = otherdir.ensure('b.py')
+ module_b.write('stuff="got it"\n')
+ module_c = otherdir.ensure('c.py')
+ module_c.write('''import py;
+import otherdir.a
+value = otherdir.a.result
+''')
+ module_d = otherdir.ensure('d.py')
+ module_d.write('''import py;
+from otherdir import a
+value2 = a.result
+''')
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/conftest.py b/tests/wpt/web-platform-tests/tools/py/testing/path/conftest.py
new file mode 100644
index 00000000000..a9711b2ce30
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/conftest.py
@@ -0,0 +1,80 @@
+import py
+import sys
+from py._path import svnwc as svncommon
+
+svnbin = py.path.local.sysfind('svn')
+repodump = py.path.local(__file__).dirpath('repotest.dump')
+from py.builtin import print_
+
+def pytest_funcarg__repowc1(request):
+ if svnbin is None:
+ py.test.skip("svn binary not found")
+
+ tmpdir = request.getfuncargvalue("tmpdir")
+ repo, repourl, wc = request.cached_setup(
+ setup=lambda: getrepowc(tmpdir, "path1repo", "path1wc"),
+ scope="module",
+ )
+ for x in ('test_remove', 'test_move', 'test_status_deleted'):
+ if request.function.__name__.startswith(x):
+ #print >>sys.stderr, ("saving repo", repo, "for", request.function)
+ _savedrepowc = save_repowc(repo, wc)
+ request.addfinalizer(lambda: restore_repowc(_savedrepowc))
+ return repo, repourl, wc
+
+def pytest_funcarg__repowc2(request):
+ tmpdir = request.getfuncargvalue("tmpdir")
+ name = request.function.__name__
+ repo, url, wc = getrepowc(tmpdir, "%s-repo-2" % name, "%s-wc-2" % name)
+ return repo, url, wc
+
+def getsvnbin():
+ if svnbin is None:
+ py.test.skip("svn binary not found")
+ return svnbin
+
+# make a wc directory out of a given root url
+# cache previously obtained wcs!
+#
+def getrepowc(tmpdir, reponame='basetestrepo', wcname='wc'):
+ repo = tmpdir.mkdir(reponame)
+ wcdir = tmpdir.mkdir(wcname)
+ repo.ensure(dir=1)
+ py.process.cmdexec('svnadmin create "%s"' %
+ svncommon._escape_helper(repo))
+ py.process.cmdexec('svnadmin load -q "%s" <"%s"' %
+ (svncommon._escape_helper(repo), repodump))
+ print_("created svn repository", repo)
+ wcdir.ensure(dir=1)
+ wc = py.path.svnwc(wcdir)
+ if py.std.sys.platform == 'win32':
+ repourl = "file://" + '/' + str(repo).replace('\\', '/')
+ else:
+ repourl = "file://%s" % repo
+ wc.checkout(repourl)
+ print_("checked out new repo into", wc)
+ return (repo, repourl, wc)
+
+
+def save_repowc(repo, wc):
+ assert not str(repo).startswith("file://"), repo
+ assert repo.check()
+ savedrepo = repo.dirpath(repo.basename+".1")
+ savedwc = wc.dirpath(wc.basename+".1")
+ repo.copy(savedrepo)
+ wc.localpath.copy(savedwc.localpath)
+ return savedrepo, savedwc
+
+def restore_repowc(obj):
+ savedrepo, savedwc = obj
+ #print >>sys.stderr, ("restoring", savedrepo)
+ repo = savedrepo.new(basename=savedrepo.basename[:-2])
+ assert repo.check()
+ wc = savedwc.new(basename=savedwc.basename[:-2])
+ assert wc.check()
+ wc.localpath.remove()
+ repo.remove()
+ savedrepo.move(repo)
+ savedwc.localpath.move(wc.localpath)
+ py.path.svnurl._lsnorevcache.clear()
+ py.path.svnurl._lsrevcache.clear()
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/repotest.dump b/tests/wpt/web-platform-tests/tools/py/testing/path/repotest.dump
new file mode 100644
index 00000000000..c7819cad7a5
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/repotest.dump
@@ -0,0 +1,228 @@
+SVN-fs-dump-format-version: 2
+
+UUID: 876a30f4-1eed-0310-aeb7-ae314d1e5934
+
+Revision-number: 0
+Prop-content-length: 56
+Content-length: 56
+
+K 8
+svn:date
+V 27
+2005-01-07T23:55:31.755989Z
+PROPS-END
+
+Revision-number: 1
+Prop-content-length: 118
+Content-length: 118
+
+K 7
+svn:log
+V 20
+testrepo setup rev 1
+K 10
+svn:author
+V 3
+hpk
+K 8
+svn:date
+V 27
+2005-01-07T23:55:37.815386Z
+PROPS-END
+
+Node-path: execfile
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 4
+Text-content-md5: d4b5bc61e16310f08c5d11866eba0a22
+Content-length: 14
+
+PROPS-END
+x=42
+
+Node-path: otherdir
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: otherdir/__init__.py
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 0
+Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: otherdir/a.py
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 30
+Text-content-md5: 247c7daeb2ee5dcab0aba7bd12bad665
+Content-length: 40
+
+PROPS-END
+from b import stuff as result
+
+
+Node-path: otherdir/b.py
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 15
+Text-content-md5: c1b13503469a7711306d03a4b0721bc6
+Content-length: 25
+
+PROPS-END
+stuff="got it"
+
+
+Node-path: otherdir/c.py
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 75
+Text-content-md5: 250cdb6b5df68536152c681f48297569
+Content-length: 85
+
+PROPS-END
+import py; py.magic.autopath()
+import otherdir.a
+value = otherdir.a.result
+
+
+Node-path: otherdir/d.py
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 72
+Text-content-md5: 940c9c621e7b198e081459642c37f5a7
+Content-length: 82
+
+PROPS-END
+import py; py.magic.autopath()
+from otherdir import a
+value2 = a.result
+
+
+Node-path: sampledir
+Node-kind: dir
+Node-action: add
+Prop-content-length: 10
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: sampledir/otherfile
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 0
+Text-content-md5: d41d8cd98f00b204e9800998ecf8427e
+Content-length: 10
+
+PROPS-END
+
+
+Node-path: samplefile
+Node-kind: file
+Node-action: add
+Prop-content-length: 40
+Text-content-length: 11
+Text-content-md5: 9225ac28b32156979ab6482b8bb5fb8c
+Content-length: 51
+
+K 13
+svn:eol-style
+V 6
+native
+PROPS-END
+samplefile
+
+
+Node-path: samplepickle
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 56
+Text-content-md5: 719d85c1329a33134bb98f56b756c545
+Content-length: 66
+
+PROPS-END
+(dp1
+S'answer'
+p2
+I42
+sI1
+I2
+sS'hello'
+p3
+S'world'
+p4
+s.
+
+Revision-number: 2
+Prop-content-length: 108
+Content-length: 108
+
+K 7
+svn:log
+V 10
+second rev
+K 10
+svn:author
+V 3
+hpk
+K 8
+svn:date
+V 27
+2005-01-07T23:55:39.223202Z
+PROPS-END
+
+Node-path: anotherfile
+Node-kind: file
+Node-action: add
+Prop-content-length: 10
+Text-content-length: 5
+Text-content-md5: 5d41402abc4b2a76b9719d911017c592
+Content-length: 15
+
+PROPS-END
+hello
+
+Revision-number: 3
+Prop-content-length: 106
+Content-length: 106
+
+K 7
+svn:log
+V 9
+third rev
+K 10
+svn:author
+V 3
+hpk
+K 8
+svn:date
+V 27
+2005-01-07T23:55:41.556642Z
+PROPS-END
+
+Node-path: anotherfile
+Node-kind: file
+Node-action: change
+Text-content-length: 5
+Text-content-md5: 7d793037a0760186574b0282f2f435e7
+Content-length: 5
+
+world
+
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/svntestbase.py b/tests/wpt/web-platform-tests/tools/py/testing/path/svntestbase.py
new file mode 100644
index 00000000000..8d94a9ca649
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/svntestbase.py
@@ -0,0 +1,31 @@
+import sys
+import py
+from py._path import svnwc as svncommon
+from common import CommonFSTests
+
+class CommonSvnTests(CommonFSTests):
+
+ def test_propget(self, path1):
+ url = path1.join("samplefile")
+ value = url.propget('svn:eol-style')
+ assert value == 'native'
+
+ def test_proplist(self, path1):
+ url = path1.join("samplefile")
+ res = url.proplist()
+ assert res['svn:eol-style'] == 'native'
+
+ def test_info(self, path1):
+ url = path1.join("samplefile")
+ res = url.info()
+ assert res.size > len("samplefile") and res.created_rev >= 0
+
+ def test_log_simple(self, path1):
+ url = path1.join("samplefile")
+ logentries = url.log()
+ for logentry in logentries:
+ assert logentry.rev == 1
+ assert hasattr(logentry, 'author')
+ assert hasattr(logentry, 'date')
+
+#cache.repositories.put(svnrepourl, 1200, 0)
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/test_cacheutil.py b/tests/wpt/web-platform-tests/tools/py/testing/path/test_cacheutil.py
new file mode 100644
index 00000000000..0b5cd31332f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/test_cacheutil.py
@@ -0,0 +1,84 @@
+import py
+from py._path import cacheutil
+
+class BasicCacheAPITest:
+ cache = None
+ def test_getorbuild(self):
+ val = self.cache.getorbuild(-42, lambda: 42)
+ assert val == 42
+ val = self.cache.getorbuild(-42, lambda: 23)
+ assert val == 42
+
+ def test_cache_get_key_error(self):
+ py.test.raises(KeyError, "self.cache._getentry(-23)")
+
+ def test_delentry_non_raising(self):
+ val = self.cache.getorbuild(100, lambda: 100)
+ self.cache.delentry(100)
+ py.test.raises(KeyError, "self.cache._getentry(100)")
+
+ def test_delentry_raising(self):
+ val = self.cache.getorbuild(100, lambda: 100)
+ self.cache.delentry(100)
+ py.test.raises(KeyError, "self.cache.delentry(100, raising=True)")
+
+ def test_clear(self):
+ self.cache.clear()
+
+class TestBuildcostAccess(BasicCacheAPITest):
+ cache = cacheutil.BuildcostAccessCache(maxentries=128)
+
+ def test_cache_works_somewhat_simple(self, monkeypatch):
+ cache = cacheutil.BuildcostAccessCache()
+ # the default gettime
+ # BuildcostAccessCache.build can
+ # result into time()-time() == 0 which makes the below
+ # test fail randomly. Let's rather use incrementing
+ # numbers instead.
+ l = [0]
+ def counter():
+ l[0] = l[0] + 1
+ return l[0]
+ monkeypatch.setattr(cacheutil, 'gettime', counter)
+ for x in range(cache.maxentries):
+ y = cache.getorbuild(x, lambda: x)
+ assert x == y
+ for x in range(cache.maxentries):
+ assert cache.getorbuild(x, None) == x
+ halfentries = int(cache.maxentries / 2)
+ for x in range(halfentries):
+ assert cache.getorbuild(x, None) == x
+ assert cache.getorbuild(x, None) == x
+ # evict one entry
+ val = cache.getorbuild(-1, lambda: 42)
+ assert val == 42
+ # check that recently used ones are still there
+ # and are not build again
+ for x in range(halfentries):
+ assert cache.getorbuild(x, None) == x
+ assert cache.getorbuild(-1, None) == 42
+
+
+class TestAging(BasicCacheAPITest):
+ maxsecs = 0.10
+ cache = cacheutil.AgingCache(maxentries=128, maxseconds=maxsecs)
+
+ def test_cache_eviction(self):
+ self.cache.getorbuild(17, lambda: 17)
+ endtime = py.std.time.time() + self.maxsecs * 10
+ while py.std.time.time() < endtime:
+ try:
+ self.cache._getentry(17)
+ except KeyError:
+ break
+ py.std.time.sleep(self.maxsecs*0.3)
+ else:
+ py.test.fail("waiting for cache eviction failed")
+
+def test_prune_lowestweight():
+ maxsecs = 0.05
+ cache = cacheutil.AgingCache(maxentries=10, maxseconds=maxsecs)
+ for x in range(cache.maxentries):
+ cache.getorbuild(x, lambda: x)
+ py.std.time.sleep(maxsecs*1.1)
+ cache.getorbuild(cache.maxentries+1, lambda: 42)
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/test_local.py b/tests/wpt/web-platform-tests/tools/py/testing/path/test_local.py
new file mode 100644
index 00000000000..bcf131fd2b7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/test_local.py
@@ -0,0 +1,860 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import with_statement
+import py
+import pytest
+import os, sys
+from py.path import local
+import common
+
+failsonjython = py.test.mark.xfail("sys.platform.startswith('java')")
+failsonjywin32 = py.test.mark.xfail("sys.platform.startswith('java') "
+ "and getattr(os, '_name', None) == 'nt'")
+win32only = py.test.mark.skipif(
+ "not (sys.platform == 'win32' or getattr(os, '_name', None) == 'nt')")
+skiponwin32 = py.test.mark.skipif(
+ "sys.platform == 'win32' or getattr(os, '_name', None) == 'nt'")
+
+
+def pytest_funcarg__path1(request):
+ def setup():
+ path1 = request.getfuncargvalue("tmpdir")
+ common.setuptestfs(path1)
+ return path1
+ def teardown(path1):
+ # post check
+ assert path1.join("samplefile").check()
+ return request.cached_setup(setup, teardown, scope="session")
+
+class TestLocalPath(common.CommonFSTests):
+ def test_join_normpath(self, tmpdir):
+ assert tmpdir.join(".") == tmpdir
+ p = tmpdir.join("../%s" % tmpdir.basename)
+ assert p == tmpdir
+ p = tmpdir.join("..//%s/" % tmpdir.basename)
+ assert p == tmpdir
+
+ @skiponwin32
+ def test_dirpath_abs_no_abs(self, tmpdir):
+ p = tmpdir.join('foo')
+ assert p.dirpath('/bar') == tmpdir.join('bar')
+ assert tmpdir.dirpath('/bar', abs=True) == py.path.local('/bar')
+
+ def test_gethash(self, tmpdir):
+ md5 = py.builtin._tryimport('md5', 'hashlib').md5
+ lib = py.builtin._tryimport('sha', 'hashlib')
+ sha = getattr(lib, 'sha1', getattr(lib, 'sha', None))
+ fn = tmpdir.join("testhashfile")
+ data = 'hello'.encode('ascii')
+ fn.write(data, mode="wb")
+ assert fn.computehash("md5") == md5(data).hexdigest()
+ assert fn.computehash("sha1") == sha(data).hexdigest()
+ py.test.raises(ValueError, fn.computehash, "asdasd")
+
+ def test_remove_removes_readonly_file(self, tmpdir):
+ readonly_file = tmpdir.join('readonly').ensure()
+ readonly_file.chmod(0)
+ readonly_file.remove()
+ assert not readonly_file.check(exists=1)
+
+ def test_remove_removes_readonly_dir(self, tmpdir):
+ readonly_dir = tmpdir.join('readonlydir').ensure(dir=1)
+ readonly_dir.chmod(int("500", 8))
+ readonly_dir.remove()
+ assert not readonly_dir.check(exists=1)
+
+ def test_remove_removes_dir_and_readonly_file(self, tmpdir):
+ readonly_dir = tmpdir.join('readonlydir').ensure(dir=1)
+ readonly_file = readonly_dir.join('readonlyfile').ensure()
+ readonly_file.chmod(0)
+ readonly_dir.remove()
+ assert not readonly_dir.check(exists=1)
+
+ def test_remove_routes_ignore_errors(self, tmpdir, monkeypatch):
+ l = []
+ monkeypatch.setattr(py.std.shutil, 'rmtree',
+ lambda *args, **kwargs: l.append(kwargs))
+ tmpdir.remove()
+ assert not l[0]['ignore_errors']
+ for val in (True, False):
+ l[:] = []
+ tmpdir.remove(ignore_errors=val)
+ assert l[0]['ignore_errors'] == val
+
+ def test_initialize_curdir(self):
+ assert str(local()) == py.std.os.getcwd()
+
+ @skiponwin32
+ def test_chdir_gone(self, path1):
+ p = path1.ensure("dir_to_be_removed", dir=1)
+ p.chdir()
+ p.remove()
+ pytest.raises(py.error.ENOENT, py.path.local)
+ assert path1.chdir() is None
+ assert os.getcwd() == str(path1)
+
+ def test_as_cwd(self, path1):
+ dir = path1.ensure("subdir", dir=1)
+ old = py.path.local()
+ with dir.as_cwd() as x:
+ assert x == old
+ assert py.path.local() == dir
+ assert os.getcwd() == str(old)
+
+ def test_as_cwd_exception(self, path1):
+ old = py.path.local()
+ dir = path1.ensure("subdir", dir=1)
+ with pytest.raises(ValueError):
+ with dir.as_cwd():
+ raise ValueError()
+ assert old == py.path.local()
+
+ def test_initialize_reldir(self, path1):
+ with path1.as_cwd():
+ p = local('samplefile')
+ assert p.check()
+
+ @pytest.mark.xfail("sys.version_info < (2,6) and sys.platform == 'win32'")
+ def test_tilde_expansion(self, monkeypatch, tmpdir):
+ monkeypatch.setenv("HOME", str(tmpdir))
+ p = py.path.local("~", expanduser=True)
+ assert p == os.path.expanduser("~")
+
+ def test_eq_with_strings(self, path1):
+ path1 = path1.join('sampledir')
+ path2 = str(path1)
+ assert path1 == path2
+ assert path2 == path1
+ path3 = path1.join('samplefile')
+ assert path3 != path2
+ assert path2 != path3
+
+ def test_eq_with_none(self, path1):
+ assert path1 != None
+
+ def test_gt_with_strings(self, path1):
+ path2 = path1.join('sampledir')
+ path3 = str(path1.join("ttt"))
+ assert path3 > path2
+ assert path2 < path3
+ assert path2 < "ttt"
+ assert "ttt" > path2
+ path4 = path1.join("aaa")
+ l = [path2, path4,path3]
+ assert sorted(l) == [path4, path2, path3]
+
+ def test_open_and_ensure(self, path1):
+ p = path1.join("sub1", "sub2", "file")
+ with p.open("w", ensure=1) as f:
+ f.write("hello")
+ assert p.read() == "hello"
+
+ def test_write_and_ensure(self, path1):
+ p = path1.join("sub1", "sub2", "file")
+ p.write("hello", ensure=1)
+ assert p.read() == "hello"
+
+ @py.test.mark.multi(bin=(False, True))
+ def test_dump(self, tmpdir, bin):
+ path = tmpdir.join("dumpfile%s" % int(bin))
+ try:
+ d = {'answer' : 42}
+ path.dump(d, bin=bin)
+ f = path.open('rb+')
+ dnew = py.std.pickle.load(f)
+ assert d == dnew
+ finally:
+ f.close()
+
+ @failsonjywin32
+ def test_setmtime(self):
+ import tempfile
+ import time
+ try:
+ fd, name = tempfile.mkstemp()
+ py.std.os.close(fd)
+ except AttributeError:
+ name = tempfile.mktemp()
+ open(name, 'w').close()
+ try:
+ mtime = int(time.time())-100
+ path = local(name)
+ assert path.mtime() != mtime
+ path.setmtime(mtime)
+ assert path.mtime() == mtime
+ path.setmtime()
+ assert path.mtime() != mtime
+ finally:
+ py.std.os.remove(name)
+
+ def test_normpath(self, path1):
+ new1 = path1.join("/otherdir")
+ new2 = path1.join("otherdir")
+ assert str(new1) == str(new2)
+
+ def test_mkdtemp_creation(self):
+ d = local.mkdtemp()
+ try:
+ assert d.check(dir=1)
+ finally:
+ d.remove(rec=1)
+
+ def test_tmproot(self):
+ d = local.mkdtemp()
+ tmproot = local.get_temproot()
+ try:
+ assert d.check(dir=1)
+ assert d.dirpath() == tmproot
+ finally:
+ d.remove(rec=1)
+
+ def test_chdir(self, tmpdir):
+ old = local()
+ try:
+ res = tmpdir.chdir()
+ assert str(res) == str(old)
+ assert py.std.os.getcwd() == str(tmpdir)
+ finally:
+ old.chdir()
+
+ def test_ensure_filepath_withdir(self, tmpdir):
+ newfile = tmpdir.join('test1','test')
+ newfile.ensure()
+ assert newfile.check(file=1)
+ newfile.write("42")
+ newfile.ensure()
+ s = newfile.read()
+ assert s == "42"
+
+ def test_ensure_filepath_withoutdir(self, tmpdir):
+ newfile = tmpdir.join('test1file')
+ t = newfile.ensure()
+ assert t == newfile
+ assert newfile.check(file=1)
+
+ def test_ensure_dirpath(self, tmpdir):
+ newfile = tmpdir.join('test1','testfile')
+ t = newfile.ensure(dir=1)
+ assert t == newfile
+ assert newfile.check(dir=1)
+
+ def test_init_from_path(self, tmpdir):
+ l = local()
+ l2 = local(l)
+ assert l2 == l
+
+ wc = py.path.svnwc('.')
+ l3 = local(wc)
+ assert l3 is not wc
+ assert l3.strpath == wc.strpath
+ assert not hasattr(l3, 'commit')
+
+ @py.test.mark.xfail(run=False, reason="unreliable est for long filenames")
+ def test_long_filenames(self, tmpdir):
+ if sys.platform == "win32":
+ py.test.skip("win32: work around needed for path length limit")
+ # see http://codespeak.net/pipermail/py-dev/2008q2/000922.html
+
+ # testing paths > 260 chars (which is Windows' limitation, but
+ # depending on how the paths are used), but > 4096 (which is the
+ # Linux' limitation) - the behaviour of paths with names > 4096 chars
+ # is undetermined
+ newfilename = '/test' * 60
+ l = tmpdir.join(newfilename)
+ l.ensure(file=True)
+ l.write('foo')
+ l2 = tmpdir.join(newfilename)
+ assert l2.read() == 'foo'
+
+ def test_visit_depth_first(self, tmpdir):
+ p1 = tmpdir.ensure("a","1")
+ p2 = tmpdir.ensure("b","2")
+ p3 = tmpdir.ensure("breadth")
+ l = list(tmpdir.visit(lambda x: x.check(file=1)))
+ assert len(l) == 3
+ # check that breadth comes last
+ assert l[2] == p3
+
+ def test_visit_rec_fnmatch(self, tmpdir):
+ p1 = tmpdir.ensure("a","123")
+ p2 = tmpdir.ensure(".b","345")
+ l = list(tmpdir.visit("???", rec="[!.]*"))
+ assert len(l) == 1
+ # check that breadth comes last
+ assert l[0] == p1
+
+ def test_fnmatch_file_abspath(self, tmpdir):
+ b = tmpdir.join("a", "b")
+ assert b.fnmatch(os.sep.join("ab"))
+ pattern = os.sep.join([str(tmpdir), "*", "b"])
+ assert b.fnmatch(pattern)
+
+ def test_sysfind(self):
+ name = sys.platform == "win32" and "cmd" or "test"
+ x = py.path.local.sysfind(name)
+ assert x.check(file=1)
+ assert py.path.local.sysfind('jaksdkasldqwe') is None
+ assert py.path.local.sysfind(name, paths=[]) is None
+ x2 = py.path.local.sysfind(name, paths=[x.dirpath()])
+ assert x2 == x
+
+
+class TestExecutionOnWindows:
+ pytestmark = win32only
+
+ def test_sysfind_bat_exe_before(self, tmpdir, monkeypatch):
+ monkeypatch.setenv("PATH", str(tmpdir), prepend=os.pathsep)
+ tmpdir.ensure("hello")
+ h = tmpdir.ensure("hello.bat")
+ x = py.path.local.sysfind("hello")
+ assert x == h
+
+
+class TestExecution:
+ pytestmark = skiponwin32
+
+ def test_sysfind_no_permisson_ignored(self, monkeypatch, tmpdir):
+ noperm = tmpdir.ensure('noperm', dir=True)
+ monkeypatch.setenv("PATH", noperm, prepend=":")
+ noperm.chmod(0)
+ assert py.path.local.sysfind('jaksdkasldqwe') is None
+
+ def test_sysfind_absolute(self):
+ x = py.path.local.sysfind('test')
+ assert x.check(file=1)
+ y = py.path.local.sysfind(str(x))
+ assert y.check(file=1)
+ assert y == x
+
+ def test_sysfind_multiple(self, tmpdir, monkeypatch):
+ monkeypatch.setenv('PATH',
+ "%s:%s" % (tmpdir.ensure('a'),
+ tmpdir.join('b')),
+ prepend=":")
+ tmpdir.ensure('b', 'a')
+ checker = lambda x: x.dirpath().basename == 'b'
+ x = py.path.local.sysfind('a', checker=checker)
+ assert x.basename == 'a'
+ assert x.dirpath().basename == 'b'
+ checker = lambda x: None
+ assert py.path.local.sysfind('a', checker=checker) is None
+
+ def test_sysexec(self):
+ x = py.path.local.sysfind('ls')
+ out = x.sysexec('-a')
+ for x in py.path.local().listdir():
+ assert out.find(x.basename) != -1
+
+ def test_sysexec_failing(self):
+ x = py.path.local.sysfind('false')
+ py.test.raises(py.process.cmdexec.Error, """
+ x.sysexec('aksjdkasjd')
+ """)
+
+ def test_make_numbered_dir(self, tmpdir):
+ tmpdir.ensure('base.not_an_int', dir=1)
+ for i in range(10):
+ numdir = local.make_numbered_dir(prefix='base.', rootdir=tmpdir,
+ keep=2, lock_timeout=0)
+ assert numdir.check()
+ assert numdir.basename == 'base.%d' %i
+ if i>=1:
+ assert numdir.new(ext=str(i-1)).check()
+ if i>=2:
+ assert numdir.new(ext=str(i-2)).check()
+ if i>=3:
+ assert not numdir.new(ext=str(i-3)).check()
+
+ def test_make_numbered_dir_NotImplemented_Error(self, tmpdir, monkeypatch):
+ def notimpl(x, y):
+ raise NotImplementedError(42)
+ monkeypatch.setattr(py.std.os, 'symlink', notimpl)
+ x = tmpdir.make_numbered_dir(rootdir=tmpdir, lock_timeout=0)
+ assert x.relto(tmpdir)
+ assert x.check()
+
+ def test_locked_make_numbered_dir(self, tmpdir):
+ for i in range(10):
+ numdir = local.make_numbered_dir(prefix='base2.', rootdir=tmpdir,
+ keep=2)
+ assert numdir.check()
+ assert numdir.basename == 'base2.%d' %i
+ for j in range(i):
+ assert numdir.new(ext=str(j)).check()
+
+ def test_error_preservation(self, path1):
+ py.test.raises (EnvironmentError, path1.join('qwoeqiwe').mtime)
+ py.test.raises (EnvironmentError, path1.join('qwoeqiwe').read)
+
+ #def test_parentdirmatch(self):
+ # local.parentdirmatch('std', startmodule=__name__)
+ #
+
+
+class TestImport:
+ def test_pyimport(self, path1):
+ obj = path1.join('execfile.py').pyimport()
+ assert obj.x == 42
+ assert obj.__name__ == 'execfile'
+
+ def test_pyimport_renamed_dir_creates_mismatch(self, tmpdir):
+ p = tmpdir.ensure("a", "test_x123.py")
+ p.pyimport()
+ tmpdir.join("a").move(tmpdir.join("b"))
+ pytest.raises(tmpdir.ImportMismatchError,
+ lambda: tmpdir.join("b", "test_x123.py").pyimport())
+
+ def test_pyimport_messy_name(self, tmpdir):
+ # http://bitbucket.org/hpk42/py-trunk/issue/129
+ path = tmpdir.ensure('foo__init__.py')
+ obj = path.pyimport()
+
+ def test_pyimport_dir(self, tmpdir):
+ p = tmpdir.join("hello_123")
+ p_init = p.ensure("__init__.py")
+ m = p.pyimport()
+ assert m.__name__ == "hello_123"
+ m = p_init.pyimport()
+ assert m.__name__ == "hello_123"
+
+ def test_pyimport_execfile_different_name(self, path1):
+ obj = path1.join('execfile.py').pyimport(modname="0x.y.z")
+ assert obj.x == 42
+ assert obj.__name__ == '0x.y.z'
+
+ def test_pyimport_a(self, path1):
+ otherdir = path1.join('otherdir')
+ mod = otherdir.join('a.py').pyimport()
+ assert mod.result == "got it"
+ assert mod.__name__ == 'otherdir.a'
+
+ def test_pyimport_b(self, path1):
+ otherdir = path1.join('otherdir')
+ mod = otherdir.join('b.py').pyimport()
+ assert mod.stuff == "got it"
+ assert mod.__name__ == 'otherdir.b'
+
+ def test_pyimport_c(self, path1):
+ otherdir = path1.join('otherdir')
+ mod = otherdir.join('c.py').pyimport()
+ assert mod.value == "got it"
+
+ def test_pyimport_d(self, path1):
+ otherdir = path1.join('otherdir')
+ mod = otherdir.join('d.py').pyimport()
+ assert mod.value2 == "got it"
+
+ def test_pyimport_and_import(self, tmpdir):
+ tmpdir.ensure('xxxpackage', '__init__.py')
+ mod1path = tmpdir.ensure('xxxpackage', 'module1.py')
+ mod1 = mod1path.pyimport()
+ assert mod1.__name__ == 'xxxpackage.module1'
+ from xxxpackage import module1
+ assert module1 is mod1
+
+ def test_pyimport_check_filepath_consistency(self, monkeypatch, tmpdir):
+ name = 'pointsback123'
+ ModuleType = type(py.std.os)
+ p = tmpdir.ensure(name + '.py')
+ for ending in ('.pyc', '$py.class', '.pyo'):
+ mod = ModuleType(name)
+ pseudopath = tmpdir.ensure(name+ending)
+ mod.__file__ = str(pseudopath)
+ monkeypatch.setitem(sys.modules, name, mod)
+ newmod = p.pyimport()
+ assert mod == newmod
+ monkeypatch.undo()
+ mod = ModuleType(name)
+ pseudopath = tmpdir.ensure(name+"123.py")
+ mod.__file__ = str(pseudopath)
+ monkeypatch.setitem(sys.modules, name, mod)
+ excinfo = py.test.raises(pseudopath.ImportMismatchError,
+ "p.pyimport()")
+ modname, modfile, orig = excinfo.value.args
+ assert modname == name
+ assert modfile == pseudopath
+ assert orig == p
+ assert issubclass(pseudopath.ImportMismatchError, ImportError)
+
+ def test_issue131_pyimport_on__init__(self, tmpdir):
+ # __init__.py files may be namespace packages, and thus the
+ # __file__ of an imported module may not be ourselves
+ # see issue
+ p1 = tmpdir.ensure("proja", "__init__.py")
+ p2 = tmpdir.ensure("sub", "proja", "__init__.py")
+ m1 = p1.pyimport()
+ m2 = p2.pyimport()
+ assert m1 == m2
+
+ def test_ensuresyspath_append(self, tmpdir):
+ root1 = tmpdir.mkdir("root1")
+ file1 = root1.ensure("x123.py")
+ assert str(root1) not in sys.path
+ file1.pyimport(ensuresyspath="append")
+ assert str(root1) == sys.path[-1]
+ assert str(root1) not in sys.path[:-1]
+
+
+def test_pypkgdir(tmpdir):
+ pkg = tmpdir.ensure('pkg1', dir=1)
+ pkg.ensure("__init__.py")
+ pkg.ensure("subdir/__init__.py")
+ assert pkg.pypkgpath() == pkg
+ assert pkg.join('subdir', '__init__.py').pypkgpath() == pkg
+
+def test_pypkgdir_unimportable(tmpdir):
+ pkg = tmpdir.ensure('pkg1-1', dir=1) # unimportable
+ pkg.ensure("__init__.py")
+ subdir = pkg.ensure("subdir/__init__.py").dirpath()
+ assert subdir.pypkgpath() == subdir
+ assert subdir.ensure("xyz.py").pypkgpath() == subdir
+ assert not pkg.pypkgpath()
+
+def test_isimportable():
+ from py._path.local import isimportable
+ assert not isimportable("")
+ assert isimportable("x")
+ assert isimportable("x1")
+ assert isimportable("x_1")
+ assert isimportable("_")
+ assert isimportable("_1")
+ assert not isimportable("x-1")
+ assert not isimportable("x:1")
+
+def test_homedir_from_HOME(monkeypatch):
+ path = os.getcwd()
+ monkeypatch.setenv("HOME", path)
+ assert py.path.local._gethomedir() == py.path.local(path)
+
+def test_homedir_not_exists(monkeypatch):
+ monkeypatch.delenv("HOME", raising=False)
+ monkeypatch.delenv("HOMEDRIVE", raising=False)
+ homedir = py.path.local._gethomedir()
+ assert homedir is None
+
+def test_samefile(tmpdir):
+ assert tmpdir.samefile(tmpdir)
+ p = tmpdir.ensure("hello")
+ assert p.samefile(p)
+ with p.dirpath().as_cwd():
+ assert p.samefile(p.basename)
+ if sys.platform == "win32":
+ p1 = p.__class__(str(p).lower())
+ p2 = p.__class__(str(p).upper())
+ assert p1.samefile(p2)
+
+def test_listdir_single_arg(tmpdir):
+ tmpdir.ensure("hello")
+ assert tmpdir.listdir("hello")[0].basename == "hello"
+
+def test_mkdtemp_rootdir(tmpdir):
+ dtmp = local.mkdtemp(rootdir=tmpdir)
+ assert tmpdir.listdir() == [dtmp]
+
+class TestWINLocalPath:
+ pytestmark = win32only
+
+ def test_owner_group_not_implemented(self, path1):
+ py.test.raises(NotImplementedError, "path1.stat().owner")
+ py.test.raises(NotImplementedError, "path1.stat().group")
+
+ def test_chmod_simple_int(self, path1):
+ py.builtin.print_("path1 is", path1)
+ mode = path1.stat().mode
+ # Ensure that we actually change the mode to something different.
+ path1.chmod(mode == 0 and 1 or 0)
+ try:
+ print(path1.stat().mode)
+ print(mode)
+ assert path1.stat().mode != mode
+ finally:
+ path1.chmod(mode)
+ assert path1.stat().mode == mode
+
+ def test_path_comparison_lowercase_mixed(self, path1):
+ t1 = path1.join("a_path")
+ t2 = path1.join("A_path")
+ assert t1 == t1
+ assert t1 == t2
+
+ def test_relto_with_mixed_case(self, path1):
+ t1 = path1.join("a_path", "fiLe")
+ t2 = path1.join("A_path")
+ assert t1.relto(t2) == "fiLe"
+
+ def test_allow_unix_style_paths(self, path1):
+ t1 = path1.join('a_path')
+ assert t1 == str(path1) + '\\a_path'
+ t1 = path1.join('a_path/')
+ assert t1 == str(path1) + '\\a_path'
+ t1 = path1.join('dir/a_path')
+ assert t1 == str(path1) + '\\dir\\a_path'
+
+ def test_sysfind_in_currentdir(self, path1):
+ cmd = py.path.local.sysfind('cmd')
+ root = cmd.new(dirname='', basename='') # c:\ in most installations
+ with root.as_cwd():
+ x = py.path.local.sysfind(cmd.relto(root))
+ assert x.check(file=1)
+
+ def test_fnmatch_file_abspath_posix_pattern_on_win32(self, tmpdir):
+ # path-matching patterns might contain a posix path separator '/'
+ # Test that we can match that pattern on windows.
+ import posixpath
+ b = tmpdir.join("a", "b")
+ assert b.fnmatch(posixpath.sep.join("ab"))
+ pattern = posixpath.sep.join([str(tmpdir), "*", "b"])
+ assert b.fnmatch(pattern)
+
+class TestPOSIXLocalPath:
+ pytestmark = skiponwin32
+
+ def test_hardlink(self, tmpdir):
+ linkpath = tmpdir.join('test')
+ filepath = tmpdir.join('file')
+ filepath.write("Hello")
+ nlink = filepath.stat().nlink
+ linkpath.mklinkto(filepath)
+ assert filepath.stat().nlink == nlink + 1
+
+ def test_symlink_are_identical(self, tmpdir):
+ filepath = tmpdir.join('file')
+ filepath.write("Hello")
+ linkpath = tmpdir.join('test')
+ linkpath.mksymlinkto(filepath)
+ assert linkpath.readlink() == str(filepath)
+
+ def test_symlink_isfile(self, tmpdir):
+ linkpath = tmpdir.join('test')
+ filepath = tmpdir.join('file')
+ filepath.write("")
+ linkpath.mksymlinkto(filepath)
+ assert linkpath.check(file=1)
+ assert not linkpath.check(link=0, file=1)
+ assert linkpath.islink()
+
+ def test_symlink_relative(self, tmpdir):
+ linkpath = tmpdir.join('test')
+ filepath = tmpdir.join('file')
+ filepath.write("Hello")
+ linkpath.mksymlinkto(filepath, absolute=False)
+ assert linkpath.readlink() == "file"
+ assert filepath.read() == linkpath.read()
+
+ def test_symlink_not_existing(self, tmpdir):
+ linkpath = tmpdir.join('testnotexisting')
+ assert not linkpath.check(link=1)
+ assert linkpath.check(link=0)
+
+ def test_relto_with_root(self, path1, tmpdir):
+ y = path1.join('x').relto(py.path.local('/'))
+ assert y[0] == str(path1)[1]
+
+ def test_visit_recursive_symlink(self, tmpdir):
+ linkpath = tmpdir.join('test')
+ linkpath.mksymlinkto(tmpdir)
+ visitor = tmpdir.visit(None, lambda x: x.check(link=0))
+ assert list(visitor) == [linkpath]
+
+ def test_symlink_isdir(self, tmpdir):
+ linkpath = tmpdir.join('test')
+ linkpath.mksymlinkto(tmpdir)
+ assert linkpath.check(dir=1)
+ assert not linkpath.check(link=0, dir=1)
+
+ def test_symlink_remove(self, tmpdir):
+ linkpath = tmpdir.join('test')
+ linkpath.mksymlinkto(linkpath) # point to itself
+ assert linkpath.check(link=1)
+ linkpath.remove()
+ assert not linkpath.check()
+
+ def test_realpath_file(self, tmpdir):
+ linkpath = tmpdir.join('test')
+ filepath = tmpdir.join('file')
+ filepath.write("")
+ linkpath.mksymlinkto(filepath)
+ realpath = linkpath.realpath()
+ assert realpath.basename == 'file'
+
+ def test_owner(self, path1, tmpdir):
+ from pwd import getpwuid
+ from grp import getgrgid
+ stat = path1.stat()
+ assert stat.path == path1
+
+ uid = stat.uid
+ gid = stat.gid
+ owner = getpwuid(uid)[0]
+ group = getgrgid(gid)[0]
+
+ assert uid == stat.uid
+ assert owner == stat.owner
+ assert gid == stat.gid
+ assert group == stat.group
+
+ def test_stat_helpers(self, tmpdir, monkeypatch):
+ path1 = tmpdir.ensure("file")
+ stat1 = path1.stat()
+ stat2 = tmpdir.stat()
+ assert stat1.isfile()
+ assert stat2.isdir()
+ assert not stat1.islink()
+ assert not stat2.islink()
+
+ def test_stat_non_raising(self, tmpdir):
+ path1 = tmpdir.join("file")
+ pytest.raises(py.error.ENOENT, lambda: path1.stat())
+ res = path1.stat(raising=False)
+ assert res is None
+
+ def test_atime(self, tmpdir):
+ import time
+ path = tmpdir.ensure('samplefile')
+ now = time.time()
+ atime1 = path.atime()
+ # we could wait here but timer resolution is very
+ # system dependent
+ path.read()
+ time.sleep(0.01)
+ atime2 = path.atime()
+ time.sleep(0.01)
+ duration = time.time() - now
+ assert (atime2-atime1) <= duration
+
+ def test_commondir(self, path1):
+ # XXX This is here in local until we find a way to implement this
+ # using the subversion command line api.
+ p1 = path1.join('something')
+ p2 = path1.join('otherthing')
+ assert p1.common(p2) == path1
+ assert p2.common(p1) == path1
+
+ def test_commondir_nocommon(self, path1):
+ # XXX This is here in local until we find a way to implement this
+ # using the subversion command line api.
+ p1 = path1.join('something')
+ p2 = py.path.local(path1.sep+'blabla')
+ assert p1.common(p2) == '/'
+
+ def test_join_to_root(self, path1):
+ root = path1.parts()[0]
+ assert len(str(root)) == 1
+ assert str(root.join('a')) == '//a' # posix allows two slashes
+
+ def test_join_root_to_root_with_no_abs(self, path1):
+ nroot = path1.join('/')
+ assert str(path1) == str(nroot)
+ assert path1 == nroot
+
+ def test_chmod_simple_int(self, path1):
+ mode = path1.stat().mode
+ path1.chmod(int(mode/2))
+ try:
+ assert path1.stat().mode != mode
+ finally:
+ path1.chmod(mode)
+ assert path1.stat().mode == mode
+
+ def test_chmod_rec_int(self, path1):
+ # XXX fragile test
+ recfilter = lambda x: x.check(dotfile=0, link=0)
+ oldmodes = {}
+ for x in path1.visit(rec=recfilter):
+ oldmodes[x] = x.stat().mode
+ path1.chmod(int("772", 8), rec=recfilter)
+ try:
+ for x in path1.visit(rec=recfilter):
+ assert x.stat().mode & int("777", 8) == int("772", 8)
+ finally:
+ for x,y in oldmodes.items():
+ x.chmod(y)
+
+ def test_copy_archiving(self, tmpdir):
+ unicode_fn = u"something-\342\200\223.txt"
+ f = tmpdir.ensure("a", unicode_fn)
+ a = f.dirpath()
+ oldmode = f.stat().mode
+ newmode = oldmode ^ 1
+ f.chmod(newmode)
+ b = tmpdir.join("b")
+ a.copy(b, mode=True)
+ assert b.join(f.basename).stat().mode == newmode
+
+ @failsonjython
+ def test_chown_identity(self, path1):
+ owner = path1.stat().owner
+ group = path1.stat().group
+ path1.chown(owner, group)
+
+ @failsonjython
+ def test_chown_dangling_link(self, path1):
+ owner = path1.stat().owner
+ group = path1.stat().group
+ x = path1.join('hello')
+ x.mksymlinkto('qlwkejqwlek')
+ try:
+ path1.chown(owner, group, rec=1)
+ finally:
+ x.remove(rec=0)
+
+ @failsonjython
+ def test_chown_identity_rec_mayfail(self, path1):
+ owner = path1.stat().owner
+ group = path1.stat().group
+ path1.chown(owner, group)
+
+
+class TestUnicodePy2Py3:
+ def test_join_ensure(self, tmpdir, monkeypatch):
+ if sys.version_info >= (3,0) and "LANG" not in os.environ:
+ pytest.skip("cannot run test without locale")
+ x = py.path.local(tmpdir.strpath)
+ part = "hällo"
+ y = x.ensure(part)
+ assert x.join(part) == y
+
+ def test_listdir(self, tmpdir):
+ if sys.version_info >= (3,0) and "LANG" not in os.environ:
+ pytest.skip("cannot run test without locale")
+ x = py.path.local(tmpdir.strpath)
+ part = "hällo"
+ y = x.ensure(part)
+ assert x.listdir(part)[0] == y
+
+ @pytest.mark.xfail(reason="changing read/write might break existing usages")
+ def test_read_write(self, tmpdir):
+ x = tmpdir.join("hello")
+ part = py.builtin._totext("hällo", "utf8")
+ x.write(part)
+ assert x.read() == part
+ x.write(part.encode(sys.getdefaultencoding()))
+ assert x.read() == part.encode(sys.getdefaultencoding())
+
+class TestBinaryAndTextMethods:
+ def test_read_binwrite(self, tmpdir):
+ x = tmpdir.join("hello")
+ part = py.builtin._totext("hällo", "utf8")
+ part_utf8 = part.encode("utf8")
+ x.write_binary(part_utf8)
+ assert x.read_binary() == part_utf8
+ s = x.read_text(encoding="utf8")
+ assert s == part
+ assert py.builtin._istext(s)
+
+ def test_read_textwrite(self, tmpdir):
+ x = tmpdir.join("hello")
+ part = py.builtin._totext("hällo", "utf8")
+ part_utf8 = part.encode("utf8")
+ x.write_text(part, encoding="utf8")
+ assert x.read_binary() == part_utf8
+ assert x.read_text(encoding="utf8") == part
+
+ def test_default_encoding(self, tmpdir):
+ x = tmpdir.join("hello")
+ # Can't use UTF8 as the default encoding (ASCII) doesn't support it
+ part = py.builtin._totext("hello", "ascii")
+ x.write_text(part, "ascii")
+ s = x.read_text("ascii")
+ assert s == part
+ assert type(s) == type(part)
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnauth.py b/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnauth.py
new file mode 100644
index 00000000000..b3f36656168
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnauth.py
@@ -0,0 +1,454 @@
+import py
+import svntestbase
+from py.path import SvnAuth
+import time
+import sys
+
+svnbin = py.path.local.sysfind('svn')
+
+def make_repo_auth(repo, userdata):
+ """ write config to repo
+
+ user information in userdata is used for auth
+ userdata has user names as keys, and a tuple (password, readwrite) as
+ values, where 'readwrite' is either 'r' or 'rw'
+ """
+ confdir = py.path.local(repo).join('conf')
+ confdir.join('svnserve.conf').write('''\
+[general]
+anon-access = none
+password-db = passwd
+authz-db = authz
+realm = TestRepo
+''')
+ authzdata = '[/]\n'
+ passwddata = '[users]\n'
+ for user in userdata:
+ authzdata += '%s = %s\n' % (user, userdata[user][1])
+ passwddata += '%s = %s\n' % (user, userdata[user][0])
+ confdir.join('authz').write(authzdata)
+ confdir.join('passwd').write(passwddata)
+
+def serve_bg(repopath):
+ pidfile = py.path.local(repopath).join('pid')
+ port = 10000
+ e = None
+ while port < 10010:
+ cmd = 'svnserve -d -T --listen-port=%d --pid-file=%s -r %s' % (
+ port, pidfile, repopath)
+ print(cmd)
+ try:
+ py.process.cmdexec(cmd)
+ except py.process.cmdexec.Error:
+ e = sys.exc_info()[1]
+ else:
+ # XXX we assume here that the pid file gets written somewhere, I
+ # guess this should be relatively safe... (I hope, at least?)
+ counter = pid = 0
+ while counter < 10:
+ counter += 1
+ try:
+ pid = pidfile.read()
+ except py.error.ENOENT:
+ pass
+ if pid:
+ break
+ time.sleep(0.2)
+ return port, int(pid)
+ port += 1
+ raise IOError('could not start svnserve: %s' % (e,))
+
+class TestSvnAuth(object):
+ def test_basic(self):
+ auth = SvnAuth('foo', 'bar')
+ assert auth.username == 'foo'
+ assert auth.password == 'bar'
+ assert str(auth)
+
+ def test_makecmdoptions_uname_pw_makestr(self):
+ auth = SvnAuth('foo', 'bar')
+ assert auth.makecmdoptions() == '--username="foo" --password="bar"'
+
+ def test_makecmdoptions_quote_escape(self):
+ auth = SvnAuth('fo"o', '"ba\'r"')
+ assert auth.makecmdoptions() == '--username="fo\\"o" --password="\\"ba\'r\\""'
+
+ def test_makecmdoptions_no_cache_auth(self):
+ auth = SvnAuth('foo', 'bar', cache_auth=False)
+ assert auth.makecmdoptions() == ('--username="foo" --password="bar" '
+ '--no-auth-cache')
+
+ def test_makecmdoptions_no_interactive(self):
+ auth = SvnAuth('foo', 'bar', interactive=False)
+ assert auth.makecmdoptions() == ('--username="foo" --password="bar" '
+ '--non-interactive')
+
+ def test_makecmdoptions_no_interactive_no_cache_auth(self):
+ auth = SvnAuth('foo', 'bar', cache_auth=False,
+ interactive=False)
+ assert auth.makecmdoptions() == ('--username="foo" --password="bar" '
+ '--no-auth-cache --non-interactive')
+
+class svnwc_no_svn(py.path.svnwc):
+ def __new__(cls, *args, **kwargs):
+ self = super(svnwc_no_svn, cls).__new__(cls, *args, **kwargs)
+ self.commands = []
+ return self
+
+ def _svn(self, *args):
+ self.commands.append(args)
+
+class TestSvnWCAuth(object):
+ def setup_method(self, meth):
+ if not svnbin:
+ py.test.skip("svn binary required")
+ self.auth = SvnAuth('user', 'pass', cache_auth=False)
+
+ def test_checkout(self):
+ wc = svnwc_no_svn('foo', auth=self.auth)
+ wc.checkout('url')
+ assert wc.commands[0][-1] == ('--username="user" --password="pass" '
+ '--no-auth-cache')
+
+ def test_commit(self):
+ wc = svnwc_no_svn('foo', auth=self.auth)
+ wc.commit('msg')
+ assert wc.commands[0][-1] == ('--username="user" --password="pass" '
+ '--no-auth-cache')
+
+ def test_checkout_no_cache_auth(self):
+ wc = svnwc_no_svn('foo', auth=self.auth)
+ wc.checkout('url')
+ assert wc.commands[0][-1] == ('--username="user" --password="pass" '
+ '--no-auth-cache')
+
+ def test_checkout_auth_from_constructor(self):
+ wc = svnwc_no_svn('foo', auth=self.auth)
+ wc.checkout('url')
+ assert wc.commands[0][-1] == ('--username="user" --password="pass" '
+ '--no-auth-cache')
+
+class svnurl_no_svn(py.path.svnurl):
+ cmdexec_output = 'test'
+ popen_output = 'test'
+ def __new__(cls, *args, **kwargs):
+ self = super(svnurl_no_svn, cls).__new__(cls, *args, **kwargs)
+ self.commands = []
+ return self
+
+ def _cmdexec(self, cmd):
+ self.commands.append(cmd)
+ return self.cmdexec_output
+
+ def _popen(self, cmd):
+ self.commands.append(cmd)
+ return self.popen_output
+
+class TestSvnURLAuth(object):
+ def setup_method(self, meth):
+ self.auth = SvnAuth('foo', 'bar')
+
+ def test_init(self):
+ u = svnurl_no_svn('http://foo.bar/svn')
+ assert u.auth is None
+
+ u = svnurl_no_svn('http://foo.bar/svn', auth=self.auth)
+ assert u.auth is self.auth
+
+ def test_new(self):
+ u = svnurl_no_svn('http://foo.bar/svn/foo', auth=self.auth)
+ new = u.new(basename='bar')
+ assert new.auth is self.auth
+ assert new.url == 'http://foo.bar/svn/bar'
+
+ def test_join(self):
+ u = svnurl_no_svn('http://foo.bar/svn', auth=self.auth)
+ new = u.join('foo')
+ assert new.auth is self.auth
+ assert new.url == 'http://foo.bar/svn/foo'
+
+ def test_listdir(self):
+ u = svnurl_no_svn('http://foo.bar/svn', auth=self.auth)
+ u.cmdexec_output = '''\
+ 1717 johnny 1529 Nov 04 14:32 LICENSE.txt
+ 1716 johnny 5352 Nov 04 14:28 README.txt
+'''
+ paths = u.listdir()
+ assert paths[0].auth is self.auth
+ assert paths[1].auth is self.auth
+ assert paths[0].basename == 'LICENSE.txt'
+
+ def test_info(self):
+ u = svnurl_no_svn('http://foo.bar/svn/LICENSE.txt', auth=self.auth)
+ def dirpath(self):
+ return self
+ u.cmdexec_output = '''\
+ 1717 johnny 1529 Nov 04 14:32 LICENSE.txt
+ 1716 johnny 5352 Nov 04 14:28 README.txt
+'''
+ org_dp = u.__class__.dirpath
+ u.__class__.dirpath = dirpath
+ try:
+ info = u.info()
+ finally:
+ u.dirpath = org_dp
+ assert info.size == 1529
+
+ def test_open(self):
+ u = svnurl_no_svn('http://foo.bar/svn', auth=self.auth)
+ foo = u.join('foo')
+ foo.check = lambda *args, **kwargs: True
+ ret = foo.open()
+ assert ret == 'test'
+ assert '--username="foo" --password="bar"' in foo.commands[0]
+
+ def test_dirpath(self):
+ u = svnurl_no_svn('http://foo.bar/svn/foo', auth=self.auth)
+ parent = u.dirpath()
+ assert parent.auth is self.auth
+
+ def test_mkdir(self):
+ u = svnurl_no_svn('http://foo.bar/svn/qweqwe', auth=self.auth)
+ assert not u.commands
+ u.mkdir(msg='created dir foo')
+ assert u.commands
+ assert '--username="foo" --password="bar"' in u.commands[0]
+
+ def test_copy(self):
+ u = svnurl_no_svn('http://foo.bar/svn', auth=self.auth)
+ u2 = svnurl_no_svn('http://foo.bar/svn2')
+ u.copy(u2, 'copied dir')
+ assert '--username="foo" --password="bar"' in u.commands[0]
+
+ def test_rename(self):
+ u = svnurl_no_svn('http://foo.bar/svn/foo', auth=self.auth)
+ u.rename('http://foo.bar/svn/bar', 'moved foo to bar')
+ assert '--username="foo" --password="bar"' in u.commands[0]
+
+ def test_remove(self):
+ u = svnurl_no_svn('http://foo.bar/svn/foo', auth=self.auth)
+ u.remove(msg='removing foo')
+ assert '--username="foo" --password="bar"' in u.commands[0]
+
+ def test_export(self):
+ u = svnurl_no_svn('http://foo.bar/svn', auth=self.auth)
+ target = py.path.local('/foo')
+ u.export(target)
+ assert '--username="foo" --password="bar"' in u.commands[0]
+
+ def test_log(self):
+ u = svnurl_no_svn('http://foo.bar/svn/foo', auth=self.auth)
+ u.popen_output = py.io.TextIO(py.builtin._totext('''\
+<?xml version="1.0"?>
+<log>
+<logentry revision="51381">
+<author>guido</author>
+<date>2008-02-11T12:12:18.476481Z</date>
+<msg>Creating branch to work on auth support for py.path.svn*.
+</msg>
+</logentry>
+</log>
+''', 'ascii'))
+ u.check = lambda *args, **kwargs: True
+ ret = u.log(10, 20, verbose=True)
+ assert '--username="foo" --password="bar"' in u.commands[0]
+ assert len(ret) == 1
+ assert int(ret[0].rev) == 51381
+ assert ret[0].author == 'guido'
+
+ def test_propget(self):
+ u = svnurl_no_svn('http://foo.bar/svn', auth=self.auth)
+ u.propget('foo')
+ assert '--username="foo" --password="bar"' in u.commands[0]
+
+def pytest_funcarg__setup(request):
+ return Setup(request)
+
+class Setup:
+ def __init__(self, request):
+ if not svnbin:
+ py.test.skip("svn binary required")
+ if not request.config.option.runslowtests:
+ py.test.skip('use --runslowtests to run these tests')
+
+ tmpdir = request.getfuncargvalue("tmpdir")
+ repodir = tmpdir.join("repo")
+ py.process.cmdexec('svnadmin create %s' % repodir)
+ if sys.platform == 'win32':
+ repodir = '/' + str(repodir).replace('\\', '/')
+ self.repo = py.path.svnurl("file://%s" % repodir)
+ if py.std.sys.platform == 'win32':
+ # remove trailing slash...
+ repodir = repodir[1:]
+ self.repopath = py.path.local(repodir)
+ self.temppath = tmpdir.mkdir("temppath")
+ self.auth = SvnAuth('johnny', 'foo', cache_auth=False,
+ interactive=False)
+ make_repo_auth(self.repopath, {'johnny': ('foo', 'rw')})
+ self.port, self.pid = serve_bg(self.repopath.dirpath())
+ # XXX caching is too global
+ py.path.svnurl._lsnorevcache._dict.clear()
+ request.addfinalizer(lambda: py.process.kill(self.pid))
+
+class TestSvnWCAuthFunctional:
+ def test_checkout_constructor_arg(self, setup):
+ wc = py.path.svnwc(setup.temppath, auth=setup.auth)
+ wc.checkout(
+ 'svn://localhost:%s/%s' % (setup.port, setup.repopath.basename))
+ assert wc.join('.svn').check()
+
+ def test_checkout_function_arg(self, setup):
+ wc = py.path.svnwc(setup.temppath, auth=setup.auth)
+ wc.checkout(
+ 'svn://localhost:%s/%s' % (setup.port, setup.repopath.basename))
+ assert wc.join('.svn').check()
+
+ def test_checkout_failing_non_interactive(self, setup):
+ auth = SvnAuth('johnny', 'bar', cache_auth=False,
+ interactive=False)
+ wc = py.path.svnwc(setup.temppath, auth)
+ py.test.raises(Exception,
+ ("wc.checkout('svn://localhost:%(port)s/%(repopath)s')" %
+ setup.__dict__))
+
+ def test_log(self, setup):
+ wc = py.path.svnwc(setup.temppath, setup.auth)
+ wc.checkout(
+ 'svn://localhost:%s/%s' % (setup.port, setup.repopath.basename))
+ foo = wc.ensure('foo.txt')
+ wc.commit('added foo.txt')
+ log = foo.log()
+ assert len(log) == 1
+ assert log[0].msg == 'added foo.txt'
+
+ def test_switch(self, setup):
+ wc = py.path.svnwc(setup.temppath, auth=setup.auth)
+ svnurl = 'svn://localhost:%s/%s' % (setup.port, setup.repopath.basename)
+ wc.checkout(svnurl)
+ wc.ensure('foo', dir=True).ensure('foo.txt').write('foo')
+ wc.commit('added foo dir with foo.txt file')
+ wc.ensure('bar', dir=True)
+ wc.commit('added bar dir')
+ bar = wc.join('bar')
+ bar.switch(svnurl + '/foo')
+ assert bar.join('foo.txt')
+
+ def test_update(self, setup):
+ wc1 = py.path.svnwc(setup.temppath.ensure('wc1', dir=True),
+ auth=setup.auth)
+ wc2 = py.path.svnwc(setup.temppath.ensure('wc2', dir=True),
+ auth=setup.auth)
+ wc1.checkout(
+ 'svn://localhost:%s/%s' % (setup.port, setup.repopath.basename))
+ wc2.checkout(
+ 'svn://localhost:%s/%s' % (setup.port, setup.repopath.basename))
+ wc1.ensure('foo', dir=True)
+ wc1.commit('added foo dir')
+ wc2.update()
+ assert wc2.join('foo').check()
+
+ auth = SvnAuth('unknown', 'unknown', interactive=False)
+ wc2.auth = auth
+ py.test.raises(Exception, 'wc2.update()')
+
+ def test_lock_unlock_status(self, setup):
+ port = setup.port
+ wc = py.path.svnwc(setup.temppath, auth=setup.auth)
+ wc.checkout(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename,))
+ wc.ensure('foo', file=True)
+ wc.commit('added foo file')
+ foo = wc.join('foo')
+ foo.lock()
+ status = foo.status()
+ assert status.locked
+ foo.unlock()
+ status = foo.status()
+ assert not status.locked
+
+ auth = SvnAuth('unknown', 'unknown', interactive=False)
+ foo.auth = auth
+ py.test.raises(Exception, 'foo.lock()')
+ py.test.raises(Exception, 'foo.unlock()')
+
+ def test_diff(self, setup):
+ port = setup.port
+ wc = py.path.svnwc(setup.temppath, auth=setup.auth)
+ wc.checkout(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename,))
+ wc.ensure('foo', file=True)
+ wc.commit('added foo file')
+ wc.update()
+ rev = int(wc.status().rev)
+ foo = wc.join('foo')
+ foo.write('bar')
+ diff = foo.diff()
+ assert '\n+bar\n' in diff
+ foo.commit('added some content')
+ diff = foo.diff()
+ assert not diff
+ diff = foo.diff(rev=rev)
+ assert '\n+bar\n' in diff
+
+ auth = SvnAuth('unknown', 'unknown', interactive=False)
+ foo.auth = auth
+ py.test.raises(Exception, 'foo.diff(rev=rev)')
+
+class TestSvnURLAuthFunctional:
+ def test_listdir(self, setup):
+ port = setup.port
+ u = py.path.svnurl(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename),
+ auth=setup.auth)
+ u.ensure('foo')
+ paths = u.listdir()
+ assert len(paths) == 1
+ assert paths[0].auth is setup.auth
+
+ auth = SvnAuth('foo', 'bar', interactive=False)
+ u = py.path.svnurl(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename),
+ auth=auth)
+ py.test.raises(Exception, 'u.listdir()')
+
+ def test_copy(self, setup):
+ port = setup.port
+ u = py.path.svnurl(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename),
+ auth=setup.auth)
+ foo = u.mkdir('foo')
+ assert foo.check()
+ bar = u.join('bar')
+ foo.copy(bar)
+ assert bar.check()
+ assert bar.auth is setup.auth
+
+ auth = SvnAuth('foo', 'bar', interactive=False)
+ u = py.path.svnurl(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename),
+ auth=auth)
+ foo = u.join('foo')
+ bar = u.join('bar')
+ py.test.raises(Exception, 'foo.copy(bar)')
+
+ def test_write_read(self, setup):
+ port = setup.port
+ u = py.path.svnurl(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename),
+ auth=setup.auth)
+ foo = u.ensure('foo')
+ fp = foo.open()
+ try:
+ data = fp.read()
+ finally:
+ fp.close()
+ assert data == ''
+
+ auth = SvnAuth('foo', 'bar', interactive=False)
+ u = py.path.svnurl(
+ 'svn://localhost:%s/%s' % (port, setup.repopath.basename),
+ auth=auth)
+ foo = u.join('foo')
+ py.test.raises(Exception, 'foo.open()')
+
+ # XXX rinse, repeat... :|
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnurl.py b/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnurl.py
new file mode 100644
index 00000000000..15fbea5047d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnurl.py
@@ -0,0 +1,95 @@
+import py
+from py._path.svnurl import InfoSvnCommand
+import datetime
+import time
+from svntestbase import CommonSvnTests
+
+def pytest_funcarg__path1(request):
+ repo, repourl, wc = request.getfuncargvalue("repowc1")
+ return py.path.svnurl(repourl)
+
+class TestSvnURLCommandPath(CommonSvnTests):
+ @py.test.mark.xfail
+ def test_load(self, path1):
+ super(TestSvnURLCommandPath, self).test_load(path1)
+
+ # the following two work on jython but not in local/svnwc
+ def test_listdir(self, path1):
+ super(TestSvnURLCommandPath, self).test_listdir(path1)
+ def test_visit_ignore(self, path1):
+ super(TestSvnURLCommandPath, self).test_visit_ignore(path1)
+
+ def test_svnurl_needs_arg(self, path1):
+ py.test.raises(TypeError, "py.path.svnurl()")
+
+ def test_svnurl_does_not_accept_None_either(self, path1):
+ py.test.raises(Exception, "py.path.svnurl(None)")
+
+ def test_svnurl_characters_simple(self, path1):
+ py.path.svnurl("svn+ssh://hello/world")
+
+ def test_svnurl_characters_at_user(self, path1):
+ py.path.svnurl("http://user@host.com/some/dir")
+
+ def test_svnurl_characters_at_path(self, path1):
+ py.test.raises(ValueError, 'py.path.svnurl("http://host.com/foo@bar")')
+
+ def test_svnurl_characters_colon_port(self, path1):
+ py.path.svnurl("http://host.com:8080/some/dir")
+
+ def test_svnurl_characters_tilde_end(self, path1):
+ py.path.svnurl("http://host.com/some/file~")
+
+ @py.test.mark.xfail("sys.platform == 'win32'")
+ def test_svnurl_characters_colon_path(self, path1):
+ # colons are allowed on win32, because they're part of the drive
+ # part of an absolute path... however, they shouldn't be allowed in
+ # other parts, I think
+ py.test.raises(ValueError, 'py.path.svnurl("http://host.com/foo:bar")')
+
+ def test_export(self, path1, tmpdir):
+ tmpdir = tmpdir.join("empty")
+ p = path1.export(tmpdir)
+ assert p == tmpdir # XXX should return None
+ n1 = [x.basename for x in tmpdir.listdir()]
+ n2 = [x.basename for x in path1.listdir()]
+ n1.sort()
+ n2.sort()
+ assert n1 == n2
+ assert not p.join('.svn').check()
+ rev = path1.mkdir("newdir")
+ tmpdir.remove()
+ assert not tmpdir.check()
+ path1.new(rev=1).export(tmpdir)
+ for p in tmpdir.listdir():
+ assert p.basename in n2
+
+class TestSvnInfoCommand:
+
+ def test_svn_1_2(self):
+ line = " 2256 hpk 165 Nov 24 17:55 __init__.py"
+ info = InfoSvnCommand(line)
+ now = datetime.datetime.now()
+ assert info.last_author == 'hpk'
+ assert info.created_rev == 2256
+ assert info.kind == 'file'
+ # we don't check for the year (2006), because that depends
+ # on the clock correctly being setup
+ assert time.gmtime(info.mtime)[1:6] == (11, 24, 17, 55, 0)
+ assert info.size == 165
+ assert info.time == info.mtime * 1000000
+
+ def test_svn_1_3(self):
+ line =" 4784 hpk 2 Jun 01 2004 __init__.py"
+ info = InfoSvnCommand(line)
+ assert info.last_author == 'hpk'
+ assert info.kind == 'file'
+
+ def test_svn_1_3_b(self):
+ line =" 74 autoadmi Oct 06 23:59 plonesolutions.com/"
+ info = InfoSvnCommand(line)
+ assert info.last_author == 'autoadmi'
+ assert info.kind == 'dir'
+
+def test_badchars():
+ py.test.raises(ValueError, "py.path.svnurl('http://host/tmp/@@@:')")
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnwc.py b/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnwc.py
new file mode 100644
index 00000000000..9e6b524acab
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/path/test_svnwc.py
@@ -0,0 +1,549 @@
+import py
+import os, sys
+import pytest
+from py._path.svnwc import InfoSvnWCCommand, XMLWCStatus, parse_wcinfotime
+from py._path import svnwc as svncommon
+from svntestbase import CommonSvnTests
+
+def test_make_repo(path1, tmpdir):
+ repo = tmpdir.join("repo")
+ py.process.cmdexec('svnadmin create %s' % repo)
+ if sys.platform == 'win32':
+ repo = '/' + str(repo).replace('\\', '/')
+ repo = py.path.svnurl("file://%s" % repo)
+ wc = py.path.svnwc(tmpdir.join("wc"))
+ wc.checkout(repo)
+ assert wc.rev == 0
+ assert len(wc.listdir()) == 0
+ p = wc.join("a_file")
+ p.write("test file")
+ p.add()
+ rev = wc.commit("some test")
+ assert p.info().rev == 1
+ assert rev == 1
+ rev = wc.commit()
+ assert rev is None
+
+def pytest_funcarg__path1(request):
+ repo, repourl, wc = request.getfuncargvalue("repowc1")
+ return wc
+
+class TestWCSvnCommandPath(CommonSvnTests):
+ def test_status_attributes_simple(self, path1):
+ def assert_nochange(p):
+ s = p.status()
+ assert not s.modified
+ assert not s.prop_modified
+ assert not s.added
+ assert not s.deleted
+ assert not s.replaced
+
+ dpath = path1.join('sampledir')
+ assert_nochange(path1.join('sampledir'))
+ assert_nochange(path1.join('samplefile'))
+
+ def test_status_added(self, path1):
+ nf = path1.join('newfile')
+ nf.write('hello')
+ nf.add()
+ try:
+ s = nf.status()
+ assert s.added
+ assert not s.modified
+ assert not s.prop_modified
+ assert not s.replaced
+ finally:
+ nf.revert()
+
+ def test_status_change(self, path1):
+ nf = path1.join('samplefile')
+ try:
+ nf.write(nf.read() + 'change')
+ s = nf.status()
+ assert not s.added
+ assert s.modified
+ assert not s.prop_modified
+ assert not s.replaced
+ finally:
+ nf.revert()
+
+ def test_status_added_ondirectory(self, path1):
+ sampledir = path1.join('sampledir')
+ try:
+ t2 = sampledir.mkdir('t2')
+ t1 = t2.join('t1')
+ t1.write('test')
+ t1.add()
+ s = sampledir.status(rec=1)
+ # Comparing just the file names, because paths are unpredictable
+ # on Windows. (long vs. 8.3 paths)
+ assert t1.basename in [item.basename for item in s.added]
+ assert t2.basename in [item.basename for item in s.added]
+ finally:
+ t2.revert(rec=1)
+ t2.localpath.remove(rec=1)
+
+ def test_status_unknown(self, path1):
+ t1 = path1.join('un1')
+ try:
+ t1.write('test')
+ s = path1.status()
+ # Comparing just the file names, because paths are unpredictable
+ # on Windows. (long vs. 8.3 paths)
+ assert t1.basename in [item.basename for item in s.unknown]
+ finally:
+ t1.localpath.remove()
+
+ def test_status_unchanged(self, path1):
+ r = path1
+ s = path1.status(rec=1)
+ # Comparing just the file names, because paths are unpredictable
+ # on Windows. (long vs. 8.3 paths)
+ assert r.join('samplefile').basename in [item.basename
+ for item in s.unchanged]
+ assert r.join('sampledir').basename in [item.basename
+ for item in s.unchanged]
+ assert r.join('sampledir/otherfile').basename in [item.basename
+ for item in s.unchanged]
+
+ @pytest.mark.xfail(reason="svn-1.7 has buggy 'status --xml' output")
+ def test_status_update(self, path1):
+ r = path1
+ try:
+ r.update(rev=1)
+ s = r.status(updates=1, rec=1)
+ # Comparing just the file names, because paths are unpredictable
+ # on Windows. (long vs. 8.3 paths)
+ py.std.pprint.pprint(s.allpath())
+ assert r.join('anotherfile').basename in [item.basename for
+ item in s.update_available]
+ #assert len(s.update_available) == 1
+ finally:
+ r.update()
+
+ def test_status_replaced(self, path1):
+ p = path1.join("samplefile")
+ p.remove()
+ p.ensure(dir=0)
+ try:
+ s = path1.status()
+ assert p.basename in [item.basename for item in s.replaced]
+ finally:
+ path1.revert(rec=1)
+
+ def test_status_ignored(self, path1):
+ try:
+ d = path1.join('sampledir')
+ p = py.path.local(d).join('ignoredfile')
+ p.ensure(file=True)
+ s = d.status()
+ assert [x.basename for x in s.unknown] == ['ignoredfile']
+ assert [x.basename for x in s.ignored] == []
+ d.propset('svn:ignore', 'ignoredfile')
+ s = d.status()
+ assert [x.basename for x in s.unknown] == []
+ assert [x.basename for x in s.ignored] == ['ignoredfile']
+ finally:
+ path1.revert(rec=1)
+
+ def test_status_conflict(self, path1, tmpdir):
+ wc = path1
+ wccopy = py.path.svnwc(tmpdir.join("conflict_copy"))
+ wccopy.checkout(wc.url)
+ p = wc.ensure('conflictsamplefile', file=1)
+ p.write('foo')
+ wc.commit('added conflictsamplefile')
+ wccopy.update()
+ assert wccopy.join('conflictsamplefile').check()
+ p.write('bar')
+ wc.commit('wrote some data')
+ wccopy.join('conflictsamplefile').write('baz')
+ wccopy.update(interactive=False)
+ s = wccopy.status()
+ assert [x.basename for x in s.conflict] == ['conflictsamplefile']
+
+ def test_status_external(self, path1, repowc2):
+ otherrepo, otherrepourl, otherwc = repowc2
+ d = path1.ensure('sampledir', dir=1)
+ try:
+ d.update()
+ d.propset('svn:externals', 'otherwc %s' % (otherwc.url,))
+ d.update()
+ s = d.status()
+ assert [x.basename for x in s.external] == ['otherwc']
+ assert 'otherwc' not in [x.basename for x in s.unchanged]
+ s = d.status(rec=1)
+ assert [x.basename for x in s.external] == ['otherwc']
+ assert 'otherwc' in [x.basename for x in s.unchanged]
+ finally:
+ path1.revert(rec=1)
+
+ def test_status_deleted(self, path1):
+ d = path1.ensure('sampledir', dir=1)
+ d.remove()
+ d.ensure(dir=1)
+ path1.commit()
+ d.ensure('deletefile', dir=0)
+ d.commit()
+ s = d.status()
+ assert 'deletefile' in [x.basename for x in s.unchanged]
+ assert not s.deleted
+ p = d.join('deletefile')
+ p.remove()
+ s = d.status()
+ assert 'deletefile' not in s.unchanged
+ assert [x.basename for x in s.deleted] == ['deletefile']
+
+ def test_status_noauthor(self, path1):
+ # testing for XML without author - this used to raise an exception
+ xml = '''\
+ <entry path="/tmp/pytest-23/wc">
+ <wc-status item="normal" props="none" revision="0">
+ <commit revision="0">
+ <date>2008-08-19T16:50:53.400198Z</date>
+ </commit>
+ </wc-status>
+ </entry>
+ '''
+ XMLWCStatus.fromstring(xml, path1)
+
+ def test_status_wrong_xml(self, path1):
+ # testing for XML without author - this used to raise an exception
+ xml = '<entry path="/home/jean/zope/venv/projectdb/parts/development-products/DataGridField">\n<wc-status item="incomplete" props="none" revision="784">\n</wc-status>\n</entry>'
+ st = XMLWCStatus.fromstring(xml, path1)
+ assert len(st.incomplete) == 1
+
+ def test_diff(self, path1):
+ p = path1 / 'anotherfile'
+ out = p.diff(rev=2)
+ assert out.find('hello') != -1
+
+ def test_blame(self, path1):
+ p = path1.join('samplepickle')
+ lines = p.blame()
+ assert sum([l[0] for l in lines]) == len(lines)
+ for l1, l2 in zip(p.readlines(), [l[2] for l in lines]):
+ assert l1 == l2
+ assert [l[1] for l in lines] == ['hpk'] * len(lines)
+ p = path1.join('samplefile')
+ lines = p.blame()
+ assert sum([l[0] for l in lines]) == len(lines)
+ for l1, l2 in zip(p.readlines(), [l[2] for l in lines]):
+ assert l1 == l2
+ assert [l[1] for l in lines] == ['hpk'] * len(lines)
+
+ def test_join_abs(self, path1):
+ s = str(path1.localpath)
+ n = path1.join(s, abs=1)
+ assert path1 == n
+
+ def test_join_abs2(self, path1):
+ assert path1.join('samplefile', abs=1) == path1.join('samplefile')
+
+ def test_str_gives_localpath(self, path1):
+ assert str(path1) == str(path1.localpath)
+
+ def test_versioned(self, path1):
+ assert path1.check(versioned=1)
+ # TODO: Why does my copy of svn think .svn is versioned?
+ #assert path1.join('.svn').check(versioned=0)
+ assert path1.join('samplefile').check(versioned=1)
+ assert not path1.join('notexisting').check(versioned=1)
+ notexisting = path1.join('hello').localpath
+ try:
+ notexisting.write("")
+ assert path1.join('hello').check(versioned=0)
+ finally:
+ notexisting.remove()
+
+ def test_listdir_versioned(self, path1):
+ assert path1.check(versioned=1)
+ p = path1.localpath.ensure("not_a_versioned_file")
+ l = [x.localpath
+ for x in path1.listdir(lambda x: x.check(versioned=True))]
+ assert p not in l
+
+ def test_nonversioned_remove(self, path1):
+ assert path1.check(versioned=1)
+ somefile = path1.join('nonversioned/somefile')
+ nonwc = py.path.local(somefile)
+ nonwc.ensure()
+ assert somefile.check()
+ assert not somefile.check(versioned=True)
+ somefile.remove() # this used to fail because it tried to 'svn rm'
+
+ def test_properties(self, path1):
+ try:
+ path1.propset('gaga', 'this')
+ assert path1.propget('gaga') == 'this'
+ # Comparing just the file names, because paths are unpredictable
+ # on Windows. (long vs. 8.3 paths)
+ assert path1.basename in [item.basename for item in
+ path1.status().prop_modified]
+ assert 'gaga' in path1.proplist()
+ assert path1.proplist()['gaga'] == 'this'
+
+ finally:
+ path1.propdel('gaga')
+
+ def test_proplist_recursive(self, path1):
+ s = path1.join('samplefile')
+ s.propset('gugu', 'that')
+ try:
+ p = path1.proplist(rec=1)
+ # Comparing just the file names, because paths are unpredictable
+ # on Windows. (long vs. 8.3 paths)
+ assert (path1 / 'samplefile').basename in [item.basename
+ for item in p]
+ finally:
+ s.propdel('gugu')
+
+ def test_long_properties(self, path1):
+ value = """
+ vadm:posix : root root 0100755
+ Properties on 'chroot/dns/var/bind/db.net.xots':
+ """
+ try:
+ path1.propset('gaga', value)
+ backvalue = path1.propget('gaga')
+ assert backvalue == value
+ #assert len(backvalue.split('\n')) == 1
+ finally:
+ path1.propdel('gaga')
+
+
+ def test_ensure(self, path1):
+ newpath = path1.ensure('a', 'b', 'c')
+ try:
+ assert newpath.check(exists=1, versioned=1)
+ newpath.write("hello")
+ newpath.ensure()
+ assert newpath.read() == "hello"
+ finally:
+ path1.join('a').remove(force=1)
+
+ def test_not_versioned(self, path1):
+ p = path1.localpath.mkdir('whatever')
+ f = path1.localpath.ensure('testcreatedfile')
+ try:
+ assert path1.join('whatever').check(versioned=0)
+ assert path1.join('testcreatedfile').check(versioned=0)
+ assert not path1.join('testcreatedfile').check(versioned=1)
+ finally:
+ p.remove(rec=1)
+ f.remove()
+
+ def test_lock_unlock(self, path1):
+ root = path1
+ somefile = root.join('somefile')
+ somefile.ensure(file=True)
+ # not yet added to repo
+ py.test.raises(Exception, 'somefile.lock()')
+ somefile.write('foo')
+ somefile.commit('test')
+ assert somefile.check(versioned=True)
+ somefile.lock()
+ try:
+ locked = root.status().locked
+ assert len(locked) == 1
+ assert locked[0].basename == somefile.basename
+ assert locked[0].dirpath().basename == somefile.dirpath().basename
+ #assert somefile.locked()
+ py.test.raises(Exception, 'somefile.lock()')
+ finally:
+ somefile.unlock()
+ #assert not somefile.locked()
+ locked = root.status().locked
+ assert locked == []
+ py.test.raises(Exception, 'somefile,unlock()')
+ somefile.remove()
+
+ def test_commit_nonrecursive(self, path1):
+ somedir = path1.join('sampledir')
+ somedir.mkdir("subsubdir")
+ somedir.propset('foo', 'bar')
+ status = somedir.status()
+ assert len(status.prop_modified) == 1
+ assert len(status.added) == 1
+
+ somedir.commit('non-recursive commit', rec=0)
+ status = somedir.status()
+ assert len(status.prop_modified) == 0
+ assert len(status.added) == 1
+
+ somedir.commit('recursive commit')
+ status = somedir.status()
+ assert len(status.prop_modified) == 0
+ assert len(status.added) == 0
+
+ def test_commit_return_value(self, path1):
+ testfile = path1.join('test.txt').ensure(file=True)
+ testfile.write('test')
+ rev = path1.commit('testing')
+ assert type(rev) == int
+
+ anotherfile = path1.join('another.txt').ensure(file=True)
+ anotherfile.write('test')
+ rev2 = path1.commit('testing more')
+ assert type(rev2) == int
+ assert rev2 == rev + 1
+
+ #def test_log(self, path1):
+ # l = path1.log()
+ # assert len(l) == 3 # might need to be upped if more tests are added
+
+class XTestWCSvnCommandPathSpecial:
+
+ rooturl = 'http://codespeak.net/svn/py.path/trunk/dist/py.path/test/data'
+ #def test_update_none_rev(self, path1):
+ # path = tmpdir.join('checkouttest')
+ # wcpath = newpath(xsvnwc=str(path), url=path1url)
+ # try:
+ # wcpath.checkout(rev=2100)
+ # wcpath.update()
+ # assert wcpath.info().rev > 2100
+ # finally:
+ # wcpath.localpath.remove(rec=1)
+
+def test_parse_wcinfotime():
+ assert (parse_wcinfotime('2006-05-30 20:45:26 +0200 (Tue, 30 May 2006)') ==
+ 1149021926)
+ assert (parse_wcinfotime('2003-10-27 20:43:14 +0100 (Mon, 27 Oct 2003)') ==
+ 1067287394)
+
+class TestInfoSvnWCCommand:
+
+ def test_svn_1_2(self, path1):
+ output = """
+ Path: test_svnwc.py
+ Name: test_svnwc.py
+ URL: http://codespeak.net/svn/py/dist/py/path/svn/wccommand.py
+ Repository UUID: fd0d7bf2-dfb6-0310-8d31-b7ecfe96aada
+ Revision: 28137
+ Node Kind: file
+ Schedule: normal
+ Last Changed Author: jan
+ Last Changed Rev: 27939
+ Last Changed Date: 2006-05-30 20:45:26 +0200 (Tue, 30 May 2006)
+ Text Last Updated: 2006-06-01 00:42:53 +0200 (Thu, 01 Jun 2006)
+ Properties Last Updated: 2006-05-23 11:54:59 +0200 (Tue, 23 May 2006)
+ Checksum: 357e44880e5d80157cc5fbc3ce9822e3
+ """
+ path = py.path.local(__file__).dirpath().chdir()
+ try:
+ info = InfoSvnWCCommand(output)
+ finally:
+ path.chdir()
+ assert info.last_author == 'jan'
+ assert info.kind == 'file'
+ assert info.mtime == 1149021926.0
+ assert info.url == 'http://codespeak.net/svn/py/dist/py/path/svn/wccommand.py'
+ assert info.time == 1149021926000000.0
+ assert info.rev == 28137
+
+
+ def test_svn_1_3(self, path1):
+ output = """
+ Path: test_svnwc.py
+ Name: test_svnwc.py
+ URL: http://codespeak.net/svn/py/dist/py/path/svn/wccommand.py
+ Repository Root: http://codespeak.net/svn
+ Repository UUID: fd0d7bf2-dfb6-0310-8d31-b7ecfe96aada
+ Revision: 28124
+ Node Kind: file
+ Schedule: normal
+ Last Changed Author: jan
+ Last Changed Rev: 27939
+ Last Changed Date: 2006-05-30 20:45:26 +0200 (Tue, 30 May 2006)
+ Text Last Updated: 2006-06-02 23:46:11 +0200 (Fri, 02 Jun 2006)
+ Properties Last Updated: 2006-06-02 23:45:28 +0200 (Fri, 02 Jun 2006)
+ Checksum: 357e44880e5d80157cc5fbc3ce9822e3
+ """
+ path = py.path.local(__file__).dirpath().chdir()
+ try:
+ info = InfoSvnWCCommand(output)
+ finally:
+ path.chdir()
+ assert info.last_author == 'jan'
+ assert info.kind == 'file'
+ assert info.mtime == 1149021926.0
+ assert info.url == 'http://codespeak.net/svn/py/dist/py/path/svn/wccommand.py'
+ assert info.rev == 28124
+ assert info.time == 1149021926000000.0
+
+
+def test_characters_at():
+ py.test.raises(ValueError, "py.path.svnwc('/tmp/@@@:')")
+
+def test_characters_tilde():
+ py.path.svnwc('/tmp/test~')
+
+
+class TestRepo:
+ def test_trailing_slash_is_stripped(self, path1):
+ # XXX we need to test more normalizing properties
+ url = path1.join("/")
+ assert path1 == url
+
+ #def test_different_revs_compare_unequal(self, path1):
+ # newpath = path1.new(rev=1199)
+ # assert newpath != path1
+
+ def test_exists_svn_root(self, path1):
+ assert path1.check()
+
+ #def test_not_exists_rev(self, path1):
+ # url = path1.__class__(path1url, rev=500)
+ # assert url.check(exists=0)
+
+ #def test_nonexisting_listdir_rev(self, path1):
+ # url = path1.__class__(path1url, rev=500)
+ # raises(py.error.ENOENT, url.listdir)
+
+ #def test_newrev(self, path1):
+ # url = path1.new(rev=None)
+ # assert url.rev == None
+ # assert url.strpath == path1.strpath
+ # url = path1.new(rev=10)
+ # assert url.rev == 10
+
+ #def test_info_rev(self, path1):
+ # url = path1.__class__(path1url, rev=1155)
+ # url = url.join("samplefile")
+ # res = url.info()
+ # assert res.size > len("samplefile") and res.created_rev == 1155
+
+ # the following tests are easier if we have a path class
+ def test_repocache_simple(self, path1):
+ repocache = svncommon.RepoCache()
+ repocache.put(path1.strpath, 42)
+ url, rev = repocache.get(path1.join('test').strpath)
+ assert rev == 42
+ assert url == path1.strpath
+
+ def test_repocache_notimeout(self, path1):
+ repocache = svncommon.RepoCache()
+ repocache.timeout = 0
+ repocache.put(path1.strpath, path1.rev)
+ url, rev = repocache.get(path1.strpath)
+ assert rev == -1
+ assert url == path1.strpath
+
+ def test_repocache_outdated(self, path1):
+ repocache = svncommon.RepoCache()
+ repocache.put(path1.strpath, 42, timestamp=0)
+ url, rev = repocache.get(path1.join('test').strpath)
+ assert rev == -1
+ assert url == path1.strpath
+
+ def _test_getreporev(self):
+ """ this test runs so slow it's usually disabled """
+ old = svncommon.repositories.repos
+ try:
+ _repocache.clear()
+ root = path1.new(rev=-1)
+ url, rev = cache.repocache.get(root.strpath)
+ assert rev>=0
+ assert url == svnrepourl
+ finally:
+ repositories.repos = old
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/process/__init__.py b/tests/wpt/web-platform-tests/tools/py/testing/process/__init__.py
new file mode 100644
index 00000000000..792d6005489
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/process/__init__.py
@@ -0,0 +1 @@
+#
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/process/test_cmdexec.py b/tests/wpt/web-platform-tests/tools/py/testing/process/test_cmdexec.py
new file mode 100644
index 00000000000..b539e0af381
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/process/test_cmdexec.py
@@ -0,0 +1,39 @@
+import py
+from py.process import cmdexec
+
+def exvalue():
+ return py.std.sys.exc_info()[1]
+
+class Test_exec_cmd:
+ def test_simple(self):
+ out = cmdexec('echo hallo')
+ assert out.strip() == 'hallo'
+ assert py.builtin._istext(out)
+
+ def test_simple_newline(self):
+ import sys
+ out = cmdexec(r"""%s -c "print ('hello')" """ % sys.executable)
+ assert out == 'hello\n'
+ assert py.builtin._istext(out)
+
+ def test_simple_error(self):
+ py.test.raises (cmdexec.Error, cmdexec, 'exit 1')
+
+ def test_simple_error_exact_status(self):
+ try:
+ cmdexec('exit 1')
+ except cmdexec.Error:
+ e = exvalue()
+ assert e.status == 1
+ assert py.builtin._istext(e.out)
+ assert py.builtin._istext(e.err)
+
+ def test_err(self):
+ try:
+ cmdexec('echoqweqwe123 hallo')
+ raise AssertionError("command succeeded but shouldn't")
+ except cmdexec.Error:
+ e = exvalue()
+ assert hasattr(e, 'err')
+ assert hasattr(e, 'out')
+ assert e.err or e.out
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/process/test_forkedfunc.py b/tests/wpt/web-platform-tests/tools/py/testing/process/test_forkedfunc.py
new file mode 100644
index 00000000000..d4f9f985e0f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/process/test_forkedfunc.py
@@ -0,0 +1,177 @@
+import pytest
+import py, sys, os
+
+pytestmark = py.test.mark.skipif("not hasattr(os, 'fork')")
+
+
+def test_waitfinish_removes_tempdir():
+ ff = py.process.ForkedFunc(boxf1)
+ assert ff.tempdir.check()
+ ff.waitfinish()
+ assert not ff.tempdir.check()
+
+def test_tempdir_gets_gc_collected(monkeypatch):
+ monkeypatch.setattr(os, 'fork', lambda: os.getpid())
+ ff = py.process.ForkedFunc(boxf1)
+ assert ff.tempdir.check()
+ ff.__del__()
+ assert not ff.tempdir.check()
+
+def test_basic_forkedfunc():
+ result = py.process.ForkedFunc(boxf1).waitfinish()
+ assert result.out == "some out\n"
+ assert result.err == "some err\n"
+ assert result.exitstatus == 0
+ assert result.signal == 0
+ assert result.retval == 1
+
+def test_exitstatus():
+ def func():
+ os._exit(4)
+ result = py.process.ForkedFunc(func).waitfinish()
+ assert result.exitstatus == 4
+ assert result.signal == 0
+ assert not result.out
+ assert not result.err
+
+def test_execption_in_func():
+ def fun():
+ raise ValueError(42)
+ ff = py.process.ForkedFunc(fun)
+ result = ff.waitfinish()
+ assert result.exitstatus == ff.EXITSTATUS_EXCEPTION
+ assert result.err.find("ValueError: 42") != -1
+ assert result.signal == 0
+ assert not result.retval
+
+def test_forkedfunc_on_fds():
+ result = py.process.ForkedFunc(boxf2).waitfinish()
+ assert result.out == "someout"
+ assert result.err == "someerr"
+ assert result.exitstatus == 0
+ assert result.signal == 0
+ assert result.retval == 2
+
+def test_forkedfunc_on_fds_output():
+ result = py.process.ForkedFunc(boxf3).waitfinish()
+ assert result.signal == 11
+ assert result.out == "s"
+
+
+def test_forkedfunc_on_stdout():
+ def boxf3():
+ import sys
+ sys.stdout.write("hello\n")
+ os.kill(os.getpid(), 11)
+ result = py.process.ForkedFunc(boxf3).waitfinish()
+ assert result.signal == 11
+ assert result.out == "hello\n"
+
+def test_forkedfunc_signal():
+ result = py.process.ForkedFunc(boxseg).waitfinish()
+ assert result.retval is None
+ if sys.version_info < (2,4):
+ py.test.skip("signal detection does not work with python prior 2.4")
+ assert result.signal == 11
+
+def test_forkedfunc_huge_data():
+ result = py.process.ForkedFunc(boxhuge).waitfinish()
+ assert result.out
+ assert result.exitstatus == 0
+ assert result.signal == 0
+ assert result.retval == 3
+
+def test_box_seq():
+ # we run many boxes with huge data, just one after another
+ for i in range(50):
+ result = py.process.ForkedFunc(boxhuge).waitfinish()
+ assert result.out
+ assert result.exitstatus == 0
+ assert result.signal == 0
+ assert result.retval == 3
+
+def test_box_in_a_box():
+ def boxfun():
+ result = py.process.ForkedFunc(boxf2).waitfinish()
+ print (result.out)
+ sys.stderr.write(result.err + "\n")
+ return result.retval
+
+ result = py.process.ForkedFunc(boxfun).waitfinish()
+ assert result.out == "someout\n"
+ assert result.err == "someerr\n"
+ assert result.exitstatus == 0
+ assert result.signal == 0
+ assert result.retval == 2
+
+def test_kill_func_forked():
+ class A:
+ pass
+ info = A()
+ import time
+
+ def box_fun():
+ time.sleep(10) # we don't want to last forever here
+
+ ff = py.process.ForkedFunc(box_fun)
+ os.kill(ff.pid, 15)
+ result = ff.waitfinish()
+ if py.std.sys.version_info < (2,4):
+ py.test.skip("signal detection does not work with python prior 2.4")
+ assert result.signal == 15
+
+
+def test_hooks(monkeypatch):
+ def _boxed():
+ return 1
+
+ def _on_start():
+ sys.stdout.write("some out\n")
+ sys.stdout.flush()
+
+ def _on_exit():
+ sys.stderr.write("some err\n")
+ sys.stderr.flush()
+
+ result = py.process.ForkedFunc(_boxed, child_on_start=_on_start,
+ child_on_exit=_on_exit).waitfinish()
+ assert result.out == "some out\n"
+ assert result.err == "some err\n"
+ assert result.exitstatus == 0
+ assert result.signal == 0
+ assert result.retval == 1
+
+
+# ======================================================================
+# examples
+# ======================================================================
+#
+
+def boxf1():
+ sys.stdout.write("some out\n")
+ sys.stderr.write("some err\n")
+ return 1
+
+def boxf2():
+ os.write(1, "someout".encode('ascii'))
+ os.write(2, "someerr".encode('ascii'))
+ return 2
+
+def boxf3():
+ os.write(1, "s".encode('ascii'))
+ os.kill(os.getpid(), 11)
+
+def boxseg():
+ os.kill(os.getpid(), 11)
+
+def boxhuge():
+ s = " ".encode('ascii')
+ os.write(1, s * 10000)
+ os.write(2, s * 10000)
+ os.write(1, s * 10000)
+
+ os.write(1, s * 10000)
+ os.write(2, s * 10000)
+ os.write(2, s * 10000)
+ os.write(1, s * 10000)
+ return 3
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/process/test_killproc.py b/tests/wpt/web-platform-tests/tools/py/testing/process/test_killproc.py
new file mode 100644
index 00000000000..57088e1db8c
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/process/test_killproc.py
@@ -0,0 +1,16 @@
+
+import py, sys
+
+@py.test.mark.skipif("sys.platform.startswith('java')")
+def test_kill(tmpdir):
+ subprocess = py.test.importorskip("subprocess")
+ t = tmpdir.join("t.py")
+ t.write("import time ; time.sleep(100)")
+ proc = py.std.subprocess.Popen([sys.executable, str(t)])
+ assert proc.poll() is None # no return value yet
+ py.process.kill(proc.pid)
+ ret = proc.wait()
+ if sys.platform == "win32" and ret == 0:
+ py.test.skip("XXX on win32, subprocess.Popen().wait() on a killed "
+ "process does not yield return value != 0")
+ assert ret != 0
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/root/__init__.py b/tests/wpt/web-platform-tests/tools/py/testing/root/__init__.py
new file mode 100644
index 00000000000..792d6005489
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/root/__init__.py
@@ -0,0 +1 @@
+#
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/root/test_builtin.py b/tests/wpt/web-platform-tests/tools/py/testing/root/test_builtin.py
new file mode 100644
index 00000000000..a6f1a3c7399
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/root/test_builtin.py
@@ -0,0 +1,179 @@
+import sys
+import types
+import py
+from py.builtin import set, frozenset, reversed, sorted
+
+def test_enumerate():
+ l = [0,1,2]
+ for i,x in enumerate(l):
+ assert i == x
+
+def test_any():
+ assert not py.builtin.any([0,False, None])
+ assert py.builtin.any([0,False, None,1])
+
+def test_all():
+ assert not py.builtin.all([True, 1, False])
+ assert py.builtin.all([True, 1, object])
+
+def test_BaseException():
+ assert issubclass(IndexError, py.builtin.BaseException)
+ assert issubclass(Exception, py.builtin.BaseException)
+ assert issubclass(KeyboardInterrupt, py.builtin.BaseException)
+
+ class MyRandomClass(object):
+ pass
+ assert not issubclass(MyRandomClass, py.builtin.BaseException)
+
+ assert py.builtin.BaseException.__module__ in ('exceptions', 'builtins')
+ assert Exception.__name__ == 'Exception'
+
+
+def test_GeneratorExit():
+ assert py.builtin.GeneratorExit.__module__ in ('exceptions', 'builtins')
+ assert issubclass(py.builtin.GeneratorExit, py.builtin.BaseException)
+
+def test_reversed():
+ reversed = py.builtin.reversed
+ r = reversed("hello")
+ assert iter(r) is r
+ s = "".join(list(r))
+ assert s == "olleh"
+ assert list(reversed(list(reversed("hello")))) == ['h','e','l','l','o']
+ py.test.raises(TypeError, reversed, reversed("hello"))
+
+def test_simple():
+ s = set([1, 2, 3, 4])
+ assert s == set([3, 4, 2, 1])
+ s1 = s.union(set([5, 6]))
+ assert 5 in s1
+ assert 1 in s1
+
+def test_frozenset():
+ s = set([frozenset([0, 1]), frozenset([1, 0])])
+ assert len(s) == 1
+
+def test_sorted():
+ if sorted == py.builtin.sorted:
+ return # don't test a real builtin
+ for s in [py.builtin.sorted]:
+ def test():
+ assert s([3, 2, 1]) == [1, 2, 3]
+ assert s([1, 2, 3], reverse=True) == [3, 2, 1]
+ l = s([1, 2, 3, 4, 5, 6], key=lambda x: x % 2)
+ assert l == [2, 4, 6, 1, 3, 5]
+ l = s([1, 2, 3, 4], cmp=lambda x, y: -cmp(x, y))
+ assert l == [4, 3, 2, 1]
+ l = s([1, 2, 3, 4], cmp=lambda x, y: -cmp(x, y),
+ key=lambda x: x % 2)
+ assert l == [1, 3, 2, 4]
+
+ def compare(x, y):
+ assert type(x) == str
+ assert type(y) == str
+ return cmp(x, y)
+ data = 'The quick Brown fox Jumped over The lazy Dog'.split()
+ s(data, cmp=compare, key=str.lower)
+ yield test
+
+
+def test_print_simple():
+ from py.builtin import print_
+ py.test.raises(TypeError, "print_(hello=3)")
+ f = py.io.TextIO()
+ print_("hello", "world", file=f)
+ s = f.getvalue()
+ assert s == "hello world\n"
+
+ f = py.io.TextIO()
+ print_("hello", end="", file=f)
+ s = f.getvalue()
+ assert s == "hello"
+
+ f = py.io.TextIO()
+ print_("xyz", "abc", sep="", end="", file=f)
+ s = f.getvalue()
+ assert s == "xyzabc"
+
+ class X:
+ def __repr__(self): return "rep"
+ f = py.io.TextIO()
+ print_(X(), file=f)
+ assert f.getvalue() == "rep\n"
+
+def test_execfile(tmpdir):
+ test_file = tmpdir.join("test.py")
+ test_file.write("x = y\ndef f(): pass")
+ ns = {"y" : 42}
+ py.builtin.execfile(str(test_file), ns)
+ assert ns["x"] == 42
+ assert py.code.getrawcode(ns["f"]).co_filename == str(test_file)
+ class A:
+ y = 3
+ x = 4
+ py.builtin.execfile(str(test_file))
+ assert A.x == 3
+
+def test_getfuncdict():
+ def f():
+ pass
+ f.x = 4
+ assert py.builtin._getfuncdict(f)["x"] == 4
+ assert py.builtin._getfuncdict(2) is None
+
+def test_callable():
+ class A: pass
+ assert py.builtin.callable(test_callable)
+ assert py.builtin.callable(A)
+ assert py.builtin.callable(list)
+ assert py.builtin.callable(id)
+ assert not py.builtin.callable(4)
+ assert not py.builtin.callable("hi")
+
+def test_totext():
+ py.builtin._totext("hello", "UTF-8")
+
+def test_bytes_text():
+ if sys.version_info[0] < 3:
+ assert py.builtin.text == unicode
+ assert py.builtin.bytes == str
+ else:
+ assert py.builtin.text == str
+ assert py.builtin.bytes == bytes
+
+def test_totext_badutf8():
+ # this was in printouts within the pytest testsuite
+ # totext would fail
+ if sys.version_info >= (3,):
+ errors = 'surrogateescape'
+ else: # old python has crappy error handlers
+ errors = 'replace'
+ py.builtin._totext("\xa6", "UTF-8", errors)
+
+def test_reraise():
+ from py.builtin import _reraise
+ try:
+ raise Exception()
+ except Exception:
+ cls, val, tb = sys.exc_info()
+ excinfo = py.test.raises(Exception, "_reraise(cls, val, tb)")
+
+def test_exec():
+ l = []
+ py.builtin.exec_("l.append(1)")
+ assert l == [1]
+ d = {}
+ py.builtin.exec_("x=4", d)
+ assert d['x'] == 4
+
+def test_tryimport():
+ py.test.raises(ImportError, py.builtin._tryimport, 'xqwe123')
+ x = py.builtin._tryimport('asldkajsdl', 'py')
+ assert x == py
+ x = py.builtin._tryimport('asldkajsdl', 'py.path')
+ assert x == py.path
+
+def test_getcode():
+ code = py.builtin._getcode(test_getcode)
+ assert isinstance(code, types.CodeType)
+ assert py.builtin._getcode(4) is None
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/root/test_error.py b/tests/wpt/web-platform-tests/tools/py/testing/root/test_error.py
new file mode 100644
index 00000000000..a34e0068d92
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/root/test_error.py
@@ -0,0 +1,37 @@
+
+import py
+
+import errno
+
+def test_error_classes():
+ for name in errno.errorcode.values():
+ x = getattr(py.error, name)
+ assert issubclass(x, py.error.Error)
+ assert issubclass(x, EnvironmentError)
+
+def test_picklability_issue1():
+ e1 = py.error.ENOENT()
+ s = py.std.pickle.dumps(e1)
+ e2 = py.std.pickle.loads(s)
+ assert isinstance(e2, py.error.ENOENT)
+
+def test_unknown_error():
+ num = 3999
+ cls = py.error._geterrnoclass(num)
+ assert cls.__name__ == 'UnknownErrno%d' % (num,)
+ assert issubclass(cls, py.error.Error)
+ assert issubclass(cls, EnvironmentError)
+ cls2 = py.error._geterrnoclass(num)
+ assert cls is cls2
+
+def test_error_conversion_ENOTDIR(testdir):
+ p = testdir.makepyfile("")
+ excinfo = py.test.raises(py.error.Error, py.error.checked_call, p.listdir)
+ assert isinstance(excinfo.value, EnvironmentError)
+ assert isinstance(excinfo.value, py.error.Error)
+ assert "ENOTDIR" in repr(excinfo.value)
+
+
+def test_checked_call_supports_kwargs(tmpdir):
+ import tempfile
+ py.error.checked_call(tempfile.mkdtemp, dir=str(tmpdir))
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/root/test_py_imports.py b/tests/wpt/web-platform-tests/tools/py/testing/root/test_py_imports.py
new file mode 100644
index 00000000000..5f5954e9943
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/root/test_py_imports.py
@@ -0,0 +1,68 @@
+import py
+import types
+import sys
+
+def checksubpackage(name):
+ obj = getattr(py, name)
+ if hasattr(obj, '__map__'): # isinstance(obj, Module):
+ keys = dir(obj)
+ assert len(keys) > 0
+ print (obj.__map__)
+ for name in list(obj.__map__):
+ assert hasattr(obj, name), (obj, name)
+
+def test_dir():
+ for name in dir(py):
+ if not name.startswith('_'):
+ yield checksubpackage, name
+
+def test_virtual_module_identity():
+ from py import path as path1
+ from py import path as path2
+ assert path1 is path2
+ from py.path import local as local1
+ from py.path import local as local2
+ assert local1 is local2
+
+def test_importall():
+ base = py._pydir
+ nodirs = [
+ ]
+ if sys.version_info >= (3,0):
+ nodirs.append(base.join('_code', '_assertionold.py'))
+ else:
+ nodirs.append(base.join('_code', '_assertionnew.py'))
+
+ def recurse(p):
+ return p.check(dotfile=0) and p.basename != "attic"
+
+ for p in base.visit('*.py', recurse):
+ if p.basename == '__init__.py':
+ continue
+ relpath = p.new(ext='').relto(base)
+ if base.sep in relpath: # not py/*.py itself
+ for x in nodirs:
+ if p == x or p.relto(x):
+ break
+ else:
+ relpath = relpath.replace(base.sep, '.')
+ modpath = 'py.%s' % relpath
+ try:
+ check_import(modpath)
+ except py.test.skip.Exception:
+ pass
+
+def check_import(modpath):
+ py.builtin.print_("checking import", modpath)
+ assert __import__(modpath)
+
+def test_all_resolves():
+ seen = py.builtin.set([py])
+ lastlength = None
+ while len(seen) != lastlength:
+ lastlength = len(seen)
+ for item in py.builtin.frozenset(seen):
+ for value in item.__dict__.values():
+ if isinstance(value, type(py.test)):
+ seen.add(value)
+
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/root/test_std.py b/tests/wpt/web-platform-tests/tools/py/testing/root/test_std.py
new file mode 100644
index 00000000000..143556a0557
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/root/test_std.py
@@ -0,0 +1,13 @@
+
+import py
+
+def test_os():
+ import os
+ assert py.std.os is os
+
+def test_import_error_converts_to_attributeerror():
+ py.test.raises(AttributeError, "py.std.xyzalskdj")
+
+def test_std_gets_it():
+ for x in py.std.sys.modules:
+ assert x in py.std.__dict__
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/root/test_xmlgen.py b/tests/wpt/web-platform-tests/tools/py/testing/root/test_xmlgen.py
new file mode 100644
index 00000000000..704d1492cb3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/root/test_xmlgen.py
@@ -0,0 +1,145 @@
+
+import py
+from py._xmlgen import unicode, html, raw
+
+class ns(py.xml.Namespace):
+ pass
+
+def test_escape():
+ uvalue = py.builtin._totext('\xc4\x85\xc4\x87\n\xe2\x82\xac\n', 'utf-8')
+ class A:
+ def __unicode__(self):
+ return uvalue
+ def __str__(self):
+ x = self.__unicode__()
+ if py.std.sys.version_info[0] < 3:
+ return x.encode('utf-8')
+ return x
+ y = py.xml.escape(uvalue)
+ assert y == uvalue
+ x = py.xml.escape(A())
+ assert x == uvalue
+ if py.std.sys.version_info[0] < 3:
+ assert isinstance(x, unicode)
+ assert isinstance(y, unicode)
+ y = py.xml.escape(uvalue.encode('utf-8'))
+ assert y == uvalue
+
+
+def test_tag_with_text():
+ x = ns.hello("world")
+ u = unicode(x)
+ assert u == "<hello>world</hello>"
+
+def test_class_identity():
+ assert ns.hello is ns.hello
+
+def test_tag_with_text_and_attributes():
+ x = ns.some(name="hello", value="world")
+ assert x.attr.name == 'hello'
+ assert x.attr.value == 'world'
+ u = unicode(x)
+ assert u == '<some name="hello" value="world"/>'
+
+def test_tag_with_subclassed_attr_simple():
+ class my(ns.hello):
+ class Attr(ns.hello.Attr):
+ hello="world"
+ x = my()
+ assert x.attr.hello == 'world'
+ assert unicode(x) == '<my hello="world"/>'
+
+def test_tag_with_raw_attr():
+ x = html.object(data=raw('&'))
+ assert unicode(x) == '<object data="&"></object>'
+
+def test_tag_nested():
+ x = ns.hello(ns.world())
+ unicode(x) # triggers parentifying
+ assert x[0].parent is x
+ u = unicode(x)
+ assert u == '<hello><world/></hello>'
+
+def test_list_nested():
+ x = ns.hello([ns.world()]) #pass in a list here
+ u = unicode(x)
+ assert u == '<hello><world/></hello>'
+
+def test_tag_xmlname():
+ class my(ns.hello):
+ xmlname = 'world'
+ u = unicode(my())
+ assert u == '<world/>'
+
+def test_tag_with_text_entity():
+ x = ns.hello('world & rest')
+ u = unicode(x)
+ assert u == "<hello>world &amp; rest</hello>"
+
+def test_tag_with_text_and_attributes_entity():
+ x = ns.some(name="hello & world")
+ assert x.attr.name == "hello & world"
+ u = unicode(x)
+ assert u == '<some name="hello &amp; world"/>'
+
+def test_raw():
+ x = ns.some(py.xml.raw("<p>literal</p>"))
+ u = unicode(x)
+ assert u == "<some><p>literal</p></some>"
+
+
+def test_html_name_stickyness():
+ class my(html.p):
+ pass
+ x = my("hello")
+ assert unicode(x) == '<p>hello</p>'
+
+def test_stylenames():
+ class my:
+ class body(html.body):
+ style = html.Style(font_size = "12pt")
+ u = unicode(my.body())
+ assert u == '<body style="font-size: 12pt"></body>'
+
+def test_class_None():
+ t = html.body(class_=None)
+ u = unicode(t)
+ assert u == '<body></body>'
+
+def test_alternating_style():
+ alternating = (
+ html.Style(background="white"),
+ html.Style(background="grey"),
+ )
+ class my(html):
+ class li(html.li):
+ def style(self):
+ i = self.parent.index(self)
+ return alternating[i%2]
+ style = property(style)
+
+ x = my.ul(
+ my.li("hello"),
+ my.li("world"),
+ my.li("42"))
+ u = unicode(x)
+ assert u == ('<ul><li style="background: white">hello</li>'
+ '<li style="background: grey">world</li>'
+ '<li style="background: white">42</li>'
+ '</ul>')
+
+def test_singleton():
+ h = html.head(html.link(href="foo"))
+ assert unicode(h) == '<head><link href="foo"/></head>'
+
+ h = html.head(html.script(src="foo"))
+ assert unicode(h) == '<head><script src="foo"></script></head>'
+
+def test_inline():
+ h = html.div(html.span('foo'), html.span('bar'))
+ assert (h.unicode(indent=2) ==
+ '<div><span>foo</span><span>bar</span></div>')
+
+def test_object_tags():
+ o = html.object(html.object())
+ assert o.unicode(indent=0) == '<object><object></object></object>'
diff --git a/tests/wpt/web-platform-tests/tools/py/testing/test_iniconfig.py b/tests/wpt/web-platform-tests/tools/py/testing/test_iniconfig.py
new file mode 100644
index 00000000000..9a7f72c11b3
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/testing/test_iniconfig.py
@@ -0,0 +1,299 @@
+import py
+import pytest
+from py._iniconfig import IniConfig, ParseError, __all__ as ALL
+from py._iniconfig import iscommentline
+from textwrap import dedent
+
+def pytest_generate_tests(metafunc):
+ if 'input' in metafunc.funcargnames:
+ for name, (input, expected) in check_tokens.items():
+ metafunc.addcall(id=name, funcargs={
+ 'input': input,
+ 'expected': expected,
+ })
+ elif hasattr(metafunc.function, 'multi'):
+ kwargs = metafunc.function.multi.kwargs
+ names, values = zip(*kwargs.items())
+ values = cartesian_product(*values)
+ for p in values:
+ metafunc.addcall(funcargs=dict(zip(names, p)))
+
+def cartesian_product(L,*lists):
+ # copied from http://bit.ly/cyIXjn
+ if not lists:
+ for x in L:
+ yield (x,)
+ else:
+ for x in L:
+ for y in cartesian_product(lists[0],*lists[1:]):
+ yield (x,)+y
+
+check_tokens = {
+ 'section': (
+ '[section]',
+ [(0, 'section', None, None)]
+ ),
+ 'value': (
+ 'value = 1',
+ [(0, None, 'value', '1')]
+ ),
+ 'value in section': (
+ '[section]\nvalue=1',
+ [(0, 'section', None, None), (1, 'section', 'value', '1')]
+ ),
+ 'value with continuation': (
+ 'names =\n Alice\n Bob',
+ [(0, None, 'names', 'Alice\nBob')]
+ ),
+ 'value with aligned continuation': (
+ 'names = Alice\n'
+ ' Bob',
+ [(0, None, 'names', 'Alice\nBob')]
+ ),
+ 'blank line':(
+ '[section]\n\nvalue=1',
+ [(0, 'section', None, None), (2, 'section', 'value', '1')]
+ ),
+ 'comment': (
+ '# comment',
+ []
+ ),
+ 'comment on value': (
+ 'value = 1',
+ [(0, None, 'value', '1')]
+ ),
+
+ 'comment on section': (
+ '[section] #comment',
+ [(0, 'section', None, None)]
+ ),
+ 'comment2': (
+ '; comment',
+ []
+ ),
+
+ 'comment2 on section': (
+ '[section] ;comment',
+ [(0, 'section', None, None)]
+ ),
+ 'pseudo section syntax in value': (
+ 'name = value []',
+ [(0, None, 'name', 'value []')]
+ ),
+ 'assignment in value': (
+ 'value = x = 3',
+ [(0, None, 'value', 'x = 3')]
+ ),
+ 'use of colon for name-values': (
+ 'name: y',
+ [(0, None, 'name', 'y')]
+ ),
+ 'use of colon without space': (
+ 'value:y=5',
+ [(0, None, 'value', 'y=5')]
+ ),
+ 'equality gets precedence': (
+ 'value=xyz:5',
+ [(0, None, 'value', 'xyz:5')]
+ ),
+
+}
+
+def parse(input):
+ # only for testing purposes - _parse() does not use state except path
+ ini = object.__new__(IniConfig)
+ ini.path = "sample"
+ return ini._parse(input.splitlines(True))
+
+def parse_a_error(input):
+ return py.test.raises(ParseError, parse, input)
+
+def test_tokenize(input, expected):
+ parsed = parse(input)
+ assert parsed == expected
+
+def test_parse_empty():
+ parsed = parse("")
+ assert not parsed
+ ini = IniConfig("sample", "")
+ assert not ini.sections
+
+def test_ParseError():
+ e = ParseError("filename", 0, "hello")
+ assert str(e) == "filename:1: hello"
+
+def test_continuation_needs_perceeding_token():
+ excinfo = parse_a_error(' Foo')
+ assert excinfo.value.lineno == 0
+
+def test_continuation_cant_be_after_section():
+ excinfo = parse_a_error('[section]\n Foo')
+ assert excinfo.value.lineno == 1
+
+def test_section_cant_be_empty():
+ excinfo = parse_a_error('[]')
+
+@py.test.mark.multi(line=[
+ '!!',
+ ])
+def test_error_on_weird_lines(line):
+ parse_a_error(line)
+
+def test_iniconfig_from_file(tmpdir):
+ path = tmpdir/'test.txt'
+ path.write('[metadata]\nname=1')
+
+ config = IniConfig(path=path)
+ assert list(config.sections) == ['metadata']
+ config = IniConfig(path, "[diff]")
+ assert list(config.sections) == ['diff']
+ py.test.raises(TypeError, "IniConfig(data=path.read())")
+
+def test_iniconfig_section_first(tmpdir):
+ excinfo = py.test.raises(ParseError, """
+ IniConfig("x", data='name=1')
+ """)
+ assert excinfo.value.msg == "no section header defined"
+
+def test_iniconig_section_duplicate_fails():
+ excinfo = py.test.raises(ParseError, r"""
+ IniConfig("x", data='[section]\n[section]')
+ """)
+ assert 'duplicate section' in str(excinfo.value)
+
+def test_iniconfig_duplicate_key_fails():
+ excinfo = py.test.raises(ParseError, r"""
+ IniConfig("x", data='[section]\nname = Alice\nname = bob')
+ """)
+
+ assert 'duplicate name' in str(excinfo.value)
+
+def test_iniconfig_lineof():
+ config = IniConfig("x.ini", data=
+ '[section]\n'
+ 'value = 1\n'
+ '[section2]\n'
+ '# comment\n'
+ 'value =2'
+ )
+
+ assert config.lineof('missing') is None
+ assert config.lineof('section') == 1
+ assert config.lineof('section2') == 3
+ assert config.lineof('section', 'value') == 2
+ assert config.lineof('section2','value') == 5
+
+ assert config['section'].lineof('value') == 2
+ assert config['section2'].lineof('value') == 5
+
+def test_iniconfig_get_convert():
+ config= IniConfig("x", data='[section]\nint = 1\nfloat = 1.1')
+ assert config.get('section', 'int') == '1'
+ assert config.get('section', 'int', convert=int) == 1
+
+def test_iniconfig_get_missing():
+ config= IniConfig("x", data='[section]\nint = 1\nfloat = 1.1')
+ assert config.get('section', 'missing', default=1) == 1
+ assert config.get('section', 'missing') is None
+
+def test_section_get():
+ config = IniConfig("x", data='[section]\nvalue=1')
+ section = config['section']
+ assert section.get('value', convert=int) == 1
+ assert section.get('value', 1) == "1"
+ assert section.get('missing', 2) == 2
+
+def test_missing_section():
+ config = IniConfig("x", data='[section]\nvalue=1')
+ py.test.raises(KeyError,'config["other"]')
+
+def test_section_getitem():
+ config = IniConfig("x", data='[section]\nvalue=1')
+ assert config['section']['value'] == '1'
+ assert config['section']['value'] == '1'
+
+def test_section_iter():
+ config = IniConfig("x", data='[section]\nvalue=1')
+ names = list(config['section'])
+ assert names == ['value']
+ items = list(config['section'].items())
+ assert items==[('value', '1')]
+
+def test_config_iter():
+ config = IniConfig("x.ini", data=dedent('''
+ [section1]
+ value=1
+ [section2]
+ value=2
+ '''))
+ l = list(config)
+ assert len(l) == 2
+ assert l[0].name == 'section1'
+ assert l[0]['value'] == '1'
+ assert l[1].name == 'section2'
+ assert l[1]['value'] == '2'
+
+def test_config_contains():
+ config = IniConfig("x.ini", data=dedent('''
+ [section1]
+ value=1
+ [section2]
+ value=2
+ '''))
+ assert 'xyz' not in config
+ assert 'section1' in config
+ assert 'section2' in config
+
+def test_iter_file_order():
+ config = IniConfig("x.ini", data="""
+[section2] #cpython dict ordered before section
+value = 1
+value2 = 2 # dict ordered before value
+[section]
+a = 1
+b = 2
+""")
+ l = list(config)
+ secnames = [x.name for x in l]
+ assert secnames == ['section2', 'section']
+ assert list(config['section2']) == ['value', 'value2']
+ assert list(config['section']) == ['a', 'b']
+
+def test_example_pypirc():
+ config = IniConfig("pypirc", data=dedent('''
+ [distutils]
+ index-servers =
+ pypi
+ other
+
+ [pypi]
+ repository: <repository-url>
+ username: <username>
+ password: <password>
+
+ [other]
+ repository: http://example.com/pypi
+ username: <username>
+ password: <password>
+ '''))
+ distutils, pypi, other = list(config)
+ assert distutils["index-servers"] == "pypi\nother"
+ assert pypi['repository'] == '<repository-url>'
+ assert pypi['username'] == '<username>'
+ assert pypi['password'] == '<password>'
+ assert ['repository', 'username', 'password'] == list(other)
+
+
+def test_api_import():
+ assert ALL == ['IniConfig', 'ParseError']
+
+@pytest.mark.parametrize("line", [
+ "#qwe",
+ " #qwe",
+ ";qwe",
+ " ;qwe",
+])
+def test_iscommentline_true(line):
+ assert iscommentline(line)
+
+
diff --git a/tests/wpt/web-platform-tests/tools/py/tox.ini b/tests/wpt/web-platform-tests/tools/py/tox.ini
new file mode 100644
index 00000000000..8c0c79d6960
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/py/tox.ini
@@ -0,0 +1,39 @@
+[tox]
+envlist=py26,py27,py33,py34,external
+# py27-xdist causes problems with svn, py25 requires virtualenv==1.9.1
+#indexserver=
+# default=http://pypi.testrun.org
+
+[testenv]
+changedir=testing
+commands=py.test --confcutdir=.. -rfsxX --junitxml={envlogdir}/junit-{envname}.xml []
+deps=pytest
+
+[testenv:py27-xdist]
+basepython=python2.7
+deps=
+ pytest
+ pytest-xdist
+commands=
+ py.test -n3 -rfsxX --confcutdir=.. --runslowtests \
+ --junitxml={envlogdir}/junit-{envname}.xml []
+
+[testenv:jython]
+changedir=testing
+commands=
+ {envpython} -m pytest --confcutdir=.. -rfsxX --junitxml={envlogdir}/junit-{envname}0.xml {posargs:io_ code}
+
+[testenv:py25]
+setenv = PIP_INSECURE=1
+
+[testenv:external]
+deps=
+ pytest
+ jinja2
+ decorator
+commands=
+ py.test --confcutdir=.. -rfsxX --junitxml={envlogdir}/junit-{envname}.xml {posargs:code}
+
+[pytest]
+rsyncdirs = conftest.py py doc testing
+addopts = -rxXf
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/.gitignore b/tests/wpt/web-platform-tests/tools/webdriver/.gitignore
new file mode 100644
index 00000000000..c99747ced28
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/webdriver/.gitignore
@@ -0,0 +1 @@
+webdriver.egg-info/
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/README.md b/tests/wpt/web-platform-tests/tools/webdriver/README.md
new file mode 100644
index 00000000000..f5be793a8bb
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/webdriver/README.md
@@ -0,0 +1,48 @@
+# WebDriver client for Python
+
+This package provides a WebDriver client compatible with
+ the [W3C browser automation specification](https://w3c.github.io/webdriver/webdriver-spec.html).
+
+The client is written with determining
+implementation compliance to the specification in mind,
+so that different remote end drivers
+can determine whether they meet the recognised standard.
+The client is used for the WebDriver specification tests
+in the [Web Platform Tests](https://github.com/w3c/web-platform-tests).
+
+## Installation
+
+To install the package individually
+in your virtualenv or system-wide::
+
+ % python setup.py install
+
+Or if you want to contribute patches::
+
+ % python setup.py develop
+
+If you are writing WebDriver specification tests for
+[WPT](https://github.com/w3c/web-platform-tests),
+there is no need to install the client manually
+as it is picked up as a submodule to
+[wpt-tools](https://github.com/w3c/wpt-tools)
+that is checked out in `./tools`.
+
+## Usage
+
+```py
+import webdriver
+
+session = webdriver.Session("127.0.0.1", "4444")
+session.start()
+
+session.url = "https://mozilla.org"
+print "The current URL is %s" % session.url
+
+session.end()
+```
+
+## Dependencies
+
+This client has the benefit of only using standard library dependencies.
+No external PyPI dependencies are needed.
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/setup.py b/tests/wpt/web-platform-tests/tools/webdriver/setup.py
new file mode 100644
index 00000000000..720fcf05cd2
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/webdriver/setup.py
@@ -0,0 +1,18 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from setuptools import setup, find_packages
+
+setup(name="webdriver",
+ version="1.0",
+ description="WebDriver client compatible with "
+ "the W3C browser automation specification.",
+ author="Mozilla Engineering Productivity",
+ author_email="tools@lists.mozilla.org",
+ license="MPL 2.0",
+ packages=find_packages(),
+ classifiers=["Development Status :: 4 - Beta",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
+ "Operating System :: OS Independent"])
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/__init__.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/__init__.py
index e69de29bb2d..c827f59f138 100644
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/__init__.py
+++ b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/__init__.py
@@ -0,0 +1,31 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from client import Cookies, Element, Find, Session, Timeouts, Window
+from error import (
+ ElementNotSelectableException,
+ ElementNotVisibleException,
+ InvalidArgumentException,
+ InvalidCookieDomainException,
+ InvalidElementCoordinatesException,
+ InvalidElementStateException,
+ InvalidSelectorException,
+ InvalidSessionIdException,
+ JavascriptErrorException,
+ MoveTargetOutOfBoundsException,
+ NoSuchAlertException,
+ NoSuchElementException,
+ NoSuchFrameException,
+ NoSuchWindowException,
+ ScriptTimeoutException,
+ SessionNotCreatedException,
+ StaleElementReferenceException,
+ TimeoutException,
+ UnableToSetCookieException,
+ UnexpectedAlertOpenException,
+ UnknownCommandException,
+ UnknownErrorException,
+ UnknownMethodException,
+ UnsupportedOperationException,
+ WebDriverException)
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/alert.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/alert.py
deleted file mode 100644
index 0dee3127d29..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/alert.py
+++ /dev/null
@@ -1,26 +0,0 @@
-"""WebDriver alert handling."""
-
-class Alert(object):
- """Class that provides access to the WebDriver alert handling functions."""
-
- def __init__(self, driver):
- self._driver = driver
-
- def _execute(self, method, path, name, body=None):
- return self._driver.execute(method, path, name, body)
-
- def dismiss(self):
- """Dismiss the alert."""
- self._execute('POST', '/dismiss_alert', 'dismiss')
-
- def accept(self):
- """Accept the alert."""
- self._execute('POST', '/accept_alert', 'accept')
-
- def get_text(self):
- """Get the text displayed in the alert."""
- return self._execute('GET', '/alert_text', 'getText')
-
- def send_keys(self, keys):
- """Type into the text input of the alert if available."""
- self._execute('POST', '/alert_text', 'sendKeys', { 'text': keys })
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/capabilities.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/capabilities.py
deleted file mode 100644
index 44bb1fd647d..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/capabilities.py
+++ /dev/null
@@ -1,30 +0,0 @@
-"""Definition of various capability-related constants."""
-
-class Capability:
- """Standard capability names."""
- BROWSER_NAME = 'browserName'
- BROWSER_VERSION = 'browserVersion'
- PAGE_LOADING_STRATEGY = 'pageLoadingStrategy'
- PLATFORM_NAME = 'platformName'
- PLATFORM_VERSION = 'platformVersion'
- SECURE_SSL = 'secureSsl'
- TAKES_SCREENSHOT = 'takesScreenshot'
- TAKE_ELEMENT_SCREENSHOT = 'takeElementScreenshot'
- TOUCH_ENABLED = 'touchEnabled'
-
-class Platform:
- """Standard OS names."""
- ANY = 'any'
- ANDROID = 'android'
- IOS = 'ios'
- LINUX = 'linux'
- MAC = 'mac'
- UNIX = 'unix'
- WINDOW = 'windows'
-
-class PageLoadingStrategy:
- """Standard page loading strategies."""
- CONSERVATIVE = 'conservative'
- NORMAL = 'normal'
- EAGER = 'eager'
- NONE = 'none'
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/client.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/client.py
new file mode 100644
index 00000000000..49c7b280a9e
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/client.py
@@ -0,0 +1,409 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+import urlparse
+
+import transport
+
+
+element_key = "element-6066-11e4-a52e-4f735466cecf"
+
+
+def command(func):
+ def inner(self, *args, **kwargs):
+ if hasattr(self, "session"):
+ session = self.session
+ else:
+ session = self
+
+ if session.session_id is None:
+ session.start()
+ assert session.session_id != None
+
+ return func(self, *args, **kwargs)
+
+ inner.__name__ = func.__name__
+ inner.__doc__ = func.__doc__
+
+ return inner
+
+
+class Timeouts(object):
+ def __init__(self, session):
+ self.session = session
+ self._script = 30
+ self._load = 0
+ self._implicit_wait = 0
+
+ def _set_timeouts(self, name, value):
+ body = {"type": name,
+ "ms": value * 1000}
+ return self.session.send_command("POST", "timeouts", body)
+
+ @property
+ def script(self):
+ return self._script
+
+ @script.setter
+ def script(self, value):
+ self._set_timeouts("script", value)
+ self._script = value
+
+ @property
+ def load(self):
+ return self._load
+
+ @load.setter
+ def set_load(self, value):
+ self._set_timeouts("page load", value)
+ self._script = value
+
+ @property
+ def implicit_wait(self):
+ return self._implicit_wait
+
+ @implicit_wait.setter
+ def implicit_wait(self, value):
+ self._set_timeouts("implicit wait", value)
+ self._implicit_wait = value
+
+
+class Window(object):
+ def __init__(self, session):
+ self.session = session
+
+ @property
+ @command
+ def size(self):
+ return self.session.send_command("GET", "window/size")
+
+ @size.setter
+ @command
+ def size(self, (height, width)):
+ body = {"width": width,
+ "height": height}
+
+ return self.session.send_command("POST", "window/size", body)
+
+ @property
+ @command
+ def maximize(self):
+ return self.session.send_command("POST", "window/maximize")
+
+
+class Find(object):
+ def __init__(self, session):
+ self.session = session
+
+ @command
+ def css(self, selector, all=True):
+ return self._find_element("css selector", selector, all)
+
+ def _find_element(self, strategy, selector, all):
+ route = "elements" if all else "element"
+
+ body = {"using": strategy,
+ "value": selector}
+
+ data = self.session.send_command("POST", route, body, key="value")
+
+ if all:
+ rv = [self.session._element(item) for item in data]
+ else:
+ rv = self.session._element(data)
+
+ return rv
+
+
+class Cookies(object):
+ def __init__(self, session):
+ self.session = session
+
+ def __getitem__(self, name):
+ self.session.send_command("GET", "cookie/%s" % name, {}, key="value")
+
+ def __setitem__(self, name, value):
+ cookie = {"name": name,
+ "value": None}
+
+ if isinstance(name, (str, unicode)):
+ cookie["value"] = value
+ elif hasattr(value, "value"):
+ cookie["value"] = value.value
+ self.session.send_command("POST", "cookie/%s" % name, {}, key="value")
+
+
+class Session(object):
+ def __init__(self, host, port, url_prefix="", desired_capabilities=None,
+ required_capabilities=None, timeout=60, extension=None):
+ self.transport = transport.HTTPWireProtocol(
+ host, port, url_prefix, timeout=timeout)
+ self.desired_capabilities = desired_capabilities
+ self.required_capabilities = required_capabilities
+ self.session_id = None
+ self.timeouts = None
+ self.window = None
+ self.find = None
+ self._element_cache = {}
+ self.extension = None
+ self.extension_cls = extension
+
+ def start(self):
+ if self.session_id is not None:
+ return
+
+ body = {}
+
+ caps = {}
+ if self.desired_capabilities is not None:
+ caps["desiredCapabilities"] = self.desired_capabilities
+ if self.required_capabilities is not None:
+ caps["requiredCapabilities"] = self.required_capabilities
+ body["capabilities"] = caps
+
+ resp = self.transport.send("POST", "session", body=body)
+ self.session_id = resp["sessionId"]
+
+ self.timeouts = Timeouts(self)
+ self.window = Window(self)
+ self.find = Find(self)
+ if self.extension_cls:
+ self.extension = self.extension_cls(self)
+
+ return resp["value"]
+
+ def end(self):
+ if self.session_id is None:
+ return
+
+ url = "session/%s" % self.session_id
+ self.transport.send("DELETE", url)
+
+ self.session_id = None
+ self.timeouts = None
+ self.window = None
+ self.find = None
+ self.extension = None
+ self.transport.disconnect()
+
+ def __enter__(self):
+ resp = self.start()
+ if resp.error:
+ raise Exception(resp)
+ return self
+
+ def __exit__(self, *args, **kwargs):
+ resp = self.end()
+ if resp.error:
+ raise Exception(resp)
+
+ def send_command(self, method, url, body=None, key=None):
+ url = urlparse.urljoin("session/%s/" % self.session_id, url)
+ return self.transport.send(method, url, body, key=key)
+
+ @property
+ @command
+ def url(self):
+ return self.send_command("GET", "url", key="value")
+
+ @url.setter
+ @command
+ def url(self, url):
+ if urlparse.urlsplit(url).netloc is None:
+ return self.url(url)
+ body = {"url": url}
+ return self.send_command("POST", "url", body)
+
+ @command
+ def back(self):
+ return self.send_command("POST", "back")
+
+ @command
+ def forward(self):
+ return self.send_command("POST", "forward")
+
+ @command
+ def refresh(self):
+ return self.send_command("POST", "refresh")
+
+ @property
+ @command
+ def title(self):
+ return self.send_command("GET", "title", key="value")
+
+ @property
+ @command
+ def window_handle(self):
+ return self.send_command("GET", "window_handle", key="value")
+
+ @window_handle.setter
+ @command
+ def window_handle(self, handle):
+ body = {"handle": handle}
+ return self.send_command("POST", "window", body=body)
+
+ def switch_frame(self, frame):
+ if frame == "parent":
+ url = "frame/parent"
+ body = None
+ else:
+ url = "frame"
+ if isinstance(frame, Element):
+ body = {"id": frame.json()}
+ else:
+ body = {"id": frame}
+
+ return self.send_command("POST", url, body)
+
+ @command
+ def close(self):
+ return self.send_command("DELETE", "window_handle")
+
+ @property
+ @command
+ def handles(self):
+ return self.send_command("GET", "window_handles", key="value")
+
+ @property
+ @command
+ def active_element(self):
+ data = self.send_command("GET", "element/active", key="value")
+ if data is not None:
+ return self._element(data)
+
+ def _element(self, data):
+ elem_id = data[element_key]
+ assert elem_id
+ if elem_id in self._element_cache:
+ return self._element_cache[elem_id]
+ return Element(self, elem_id)
+
+ @command
+ def cookies(self, name=None):
+ if name is None:
+ url = "cookie"
+ else:
+ url = "cookie/%s" % name
+ return self.send_command("GET", url, {}, key="value")
+
+ @command
+ def set_cookie(self, name, value, path=None, domain=None, secure=None, expiry=None):
+ body = {"name": name,
+ "value": value}
+ if path is not None:
+ body["path"] = path
+ if domain is not None:
+ body["domain"] = domain
+ if secure is not None:
+ body["secure"] = secure
+ if expiry is not None:
+ body["expiry"] = expiry
+ self.send_command("POST", "cookie", {"cookie": body})
+
+ def delete_cookie(self, name=None):
+ if name is None:
+ url = "cookie"
+ else:
+ url = "cookie/%s" % name
+ self.send_command("DELETE", url, {}, key="value")
+
+ #[...]
+
+ @command
+ def execute_script(self, script, args=None):
+ if args is None:
+ args = []
+
+ body = {
+ "script": script,
+ "args": args
+ }
+ return self.send_command("POST", "execute", body, key="value")
+
+ @command
+ def execute_async_script(self, script, args=None):
+ if args is None:
+ args = []
+
+ body = {
+ "script": script,
+ "args": args
+ }
+ return self.send_command("POST", "execute_async", body, key="value")
+
+ #[...]
+
+ @command
+ def screenshot(self):
+ return self.send_command("GET", "screenshot", key="value")
+
+
+class Element(object):
+ def __init__(self, session, id):
+ self.session = session
+ self.id = id
+ assert id not in self.session._element_cache
+ self.session._element_cache[self.id] = self
+
+ def json(self):
+ return {element_key: self.id}
+
+ @property
+ def session_id(self):
+ return self.session.session_id
+
+ def url(self, suffix):
+ return "element/%s/%s" % (self.id, suffix)
+
+ @command
+ def find_element(self, strategy, selector):
+ body = {"using": strategy,
+ "value": selector}
+
+ elem = self.session.send_command("POST", self.url("element"), body, key="value")
+ return self.session.element(elem)
+
+ @command
+ def click(self):
+ self.session.send_command("POST", self.url("click"), {})
+
+ @command
+ def tap(self):
+ self.session.send_command("POST", self.url("tap"), {})
+
+ @command
+ def clear(self):
+ self.session.send_command("POST", self.url("clear"), {})
+
+ @command
+ def send_keys(self, keys):
+ if isinstance(keys, (str, unicode)):
+ keys = [char for char in keys]
+
+ body = {"value": keys}
+
+ return self.session.send_command("POST", self.url("value"), body)
+
+ @property
+ @command
+ def text(self):
+ return self.session.send_command("GET", self.url("text"))
+
+ @property
+ @command
+ def name(self):
+ return self.session.send_command("GET", self.url("name"))
+
+ @command
+ def style(self, property_name):
+ return self.session.send_command("GET", self.url("css/%s" % property_name))
+
+ @property
+ @command
+ def rect(self):
+ return self.session.send_command("GET", self.url("rect"))
+
+ @command
+ def attribute(self, name):
+ return self.session.send_command("GET", self.url("attribute/%s" % name))
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/command.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/command.py
deleted file mode 100644
index 4ea162fea12..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/command.py
+++ /dev/null
@@ -1,111 +0,0 @@
-"""Dispatches requests to remote WebDriver endpoint."""
-
-import exceptions
-
-import httplib
-import json
-import urlparse
-import webelement
-
-class CommandExecutor(object):
- """Dispatches requests to remote WebDriver endpoint."""
-
- _HEADERS = {
- "User-Agent": "Python WebDriver Local End",
- "Content-Type": "application/json;charset=\"UTF-8\"",
- "Accept": "application/json",
- "Accept-Charset": "utf-8",
- "Accept-Encoding": "identity",
- "Connection": "close",
- }
-
- def __init__(self, url, mode='strict'):
- self._parsed_url = urlparse.urlparse(url)
- self._conn = httplib.HTTPConnection(self._parsed_url.hostname,
- self._parsed_url.port)
- self._mode = mode
-
- def execute(self,
- method,
- path,
- session_id,
- name,
- parameters=None,
- object_hook=None):
- """Execute a command against the WebDriver endpoint.
-
- Arguments:
- method -- one of GET, POST, DELETE
- path -- the path of the url endpoint (needs to include
- session/<sessionId> if needed)
- session_id -- the sessionId to include in the JSON body
- name -- name of the command that is being executed to include in
- the JSON body
- parameters -- the JSON body to send with the command. Only used if
- method is POST
- object_hook -- function used by json.loads to properly deserialize
- objects in the request
- """
- if self._mode == 'strict':
- return self._execute_strict(
- method, path, session_id, name, parameters, object_hook)
- elif self._mode == 'compatibility':
- return self._execute_compatibility(
- method, path, session_id, name, parameters, object_hook)
- else:
- raise Exception("Unknown mode: " + self._mode)
-
- def _execute_compatibility(self,
- method,
- path,
- session_id,
- name,
- parameters,
- object_hook):
- body = {'sessionId': session_id, 'name': name }
- if parameters:
- body.update(parameters)
-
- self._conn.request(
- method,
- self._parsed_url.path + path,
- json.dumps(body, default = self._json_encode).encode('utf-8'),
- self._HEADERS)
- resp = self._conn.getresponse()
- data = resp.read().decode('utf-8')
- if data:
- data = json.loads(data, object_hook = object_hook)
- if data['status'] != 0:
- raise exceptions.create_webdriver_exception_compatibility(
- data['status'], data['value']['message'])
- return data
- if resp.status < 200 or resp.status > 299:
- raise exceptions.create_webdriver_exception_compatibility(
- resp.status, resp.reason)
-
- def _execute_strict(self,
- method,
- path,
- session_id,
- name,
- parameters,
- object_hook):
- body = {
- 'sessionId': session_id,
- 'name': name,
- 'parameters': parameters }
- self._conn.request(
- method,
- self._parsed_url.path + path,
- json.dumps(body, default = self._json_encode).encode('utf-8'),
- self._HEADERS)
- resp = self._conn.getresponse()
- data = json.loads(
- resp.read().decode('utf-8'), object_hook = object_hook)
- if data['status'] != 'success':
- raise exceptions.create_webdriver_exception_strict(
- data['status'], data['value'])
- return data
-
- def _json_encode(self, obj):
- return obj.to_json()
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/driver.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/driver.py
deleted file mode 100644
index 27d543ed22b..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/driver.py
+++ /dev/null
@@ -1,199 +0,0 @@
-"""Entry point for WebDriver."""
-
-import alert
-import command
-import searchcontext
-import webelement
-
-import base64
-
-
-class WebDriver(searchcontext.SearchContext):
- """Controls a web browser."""
-
- def __init__(self, host, required, desired, mode='strict'):
- args = { 'desiredCapabilities': desired }
- if required:
- args['requiredCapabilities'] = required
-
- self._executor = command.CommandExecutor(host, mode)
-
- resp = self._executor.execute(
- 'POST', '/session', None, 'newSession', args)
- self.capabilities = resp['value']
- self._session_id = resp['sessionId']
- self.mode = mode
-
- def execute(self, method, path, name, parameters= None):
- """Execute a command against the current WebDriver session."""
- data = self._executor.execute(
- method,
- '/session/' + self._session_id + path,
- self._session_id,
- name,
- parameters,
- self._object_hook)
- if data:
- return data['value']
-
- def get(self, url):
- """Navigate to url."""
- self.execute('POST', '/url', 'get', { 'url': url })
-
- def get_current_url(self):
- """Get the current value of the location bar."""
- return self.execute('GET', '/url', 'getCurrentUrl')
-
- def go_back(self):
- """Hit the browser back button."""
- self.execute('POST', '/back', 'goBack')
-
- def go_forward(self):
- """Hit the browser forward button."""
- self.execute('POST', '/forward', 'goForward')
-
- def refresh(self):
- """Refresh the current page in the browser."""
- self.execute('POST', '/refresh', 'refresh')
-
- def quit(self):
- """Shutdown the current WebDriver session."""
- self.execute('DELETE', '', 'quit')
-
- def get_window_handle(self):
- """Get the handle for the browser window/tab currently accepting
- commands.
- """
- return self.execute('GET', '/window_handle', 'getWindowHandle')
-
- def get_window_handles(self):
- """Get handles for all open windows/tabs."""
- return self.execute('GET', '/window_handles', 'getWindowHandles')
-
- def close(self):
- """Close the current tab or window.
-
- If this is the last tab or window, then this is the same as
- calling quit.
- """
- self.execute('DELETE', '/window', 'close')
-
- 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']}
-
- def set_window_size(self, height, width):
- """Set the size of the current window."""
- self._window_command(
- 'POST',
- '/size',
- 'setWindowSize',
- { 'height': height, 'width': width})
-
- def fullscreen_window(self):
- """Make the current window fullscreen."""
- pass # implement when end point is defined
-
- def switch_to_window(self, name):
- """Switch to the window with the given handle or name."""
- self.execute('POST', '/window', 'switchToWindow', { 'name': name })
-
- def switch_to_frame(self, id):
- """Switch to a frame.
-
- id can be either a WebElement or an integer.
- """
- self.execute('POST', '/frame', 'switchToFrame', { 'id': id})
-
- def switch_to_parent_frame(self):
- """Move to the browsing context containing the currently selected frame.
-
- If in the top-level browsing context, this is a no-op.
- """
- self.execute('POST', '/frame/parent', 'switchToParentFrame')
-
- def switch_to_alert(self):
- """Return an Alert object to interact with a modal dialog."""
- alert_ = alert.Alert(self)
- alert_.get_text()
- return alert_
-
- def execute_script(self, script, args=[]):
- """Execute a Javascript script in the current browsing context."""
- return self.execute(
- 'POST',
- '/execute',
- 'executeScript',
- { 'script': script, 'args': args })
-
- def execute_script_async(self, script, args=[]):
- """Execute a Javascript script in the current browsing context."""
- return self.execute(
- 'POST',
- '/execute_async',
- 'executeScriptAsync',
- { 'script': script, 'args': args })
-
- def take_screenshot(self, element=None):
- """Take a screenshot.
-
- If element is not provided, the screenshot should be of the
- current page, otherwise the screenshot should be of the given element.
- """
- if self.mode == 'strict':
- pass # implement when endpoint is defined
- elif self.mode == 'compatibility':
- if element:
- pass # element screenshots are unsupported in compatibility
- else:
- return base64.standard_b64decode(
- self.execute('GET', '/screenshot', 'takeScreenshot'))
-
- def add_cookie(self, cookie):
- """Add a cookie to the browser."""
- self.execute('POST', '/cookie', 'addCookie', { 'cookie': cookie })
-
- def get_cookie(self, name = None):
- """Get the cookies accessible from the current page."""
- if self.mode == 'compatibility':
- cookies = self.execute('GET', '/cookie', 'getCookie')
- if name:
- cookies_ = []
- for cookie in cookies:
- if cookie['name'] == name:
- cookies_.append(cookie)
- return cookies_
- return cookies
- elif self.mode == 'strict':
- pass # implement when wire protocol for this has been defined
-
- def set_implicit_timeout(self, ms):
- self._set_timeout('implicit', ms)
-
- def set_page_load_timeout(self, ms):
- self._set_timeout('page load', ms)
-
- def set_script_timeout(self, ms):
- self._set_timeout('script', ms)
-
- def _set_timeout(self, type, ms):
- params = { 'type': type, 'ms': ms }
- self.execute('POST', '/timeouts', 'timeouts', params)
-
- def _window_command(self, method, path, name, parameters = None):
- if self.mode == 'compatibility':
- return self.execute(
- method, '/window/current' + path, name, parameters)
- elif self.mode == 'strict':
- pass # implement this when end-points are defined in doc
-
- def _object_hook(self, obj):
- if 'ELEMENT' in obj:
- return webelement.WebElement(self, obj['ELEMENT'])
- return obj
-
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py
new file mode 100644
index 00000000000..dc168f3ef4d
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/error.py
@@ -0,0 +1,144 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+import collections
+
+
+class WebDriverException(Exception):
+ http_status = None
+ status_code = None
+
+
+class ElementNotSelectableException(WebDriverException):
+ http_status = 400
+ status_code = "element not selectable"
+
+
+class ElementNotVisibleException(WebDriverException):
+ http_status = 400
+ status_code = "element not visible"
+
+
+class InvalidArgumentException(WebDriverException):
+ http_status = 400
+ status_code = "invalid argument"
+
+
+class InvalidCookieDomainException(WebDriverException):
+ http_status = 400
+ status_code = "invalid cookie domain"
+
+
+class InvalidElementCoordinatesException(WebDriverException):
+ http_status = 400
+ status_code = "invalid element coordinates"
+
+
+class InvalidElementStateException(WebDriverException):
+ http_status = 400
+ status_code = "invalid cookie domain"
+
+
+class InvalidSelectorException(WebDriverException):
+ http_status = 400
+ status_code = "invalid selector"
+
+
+class InvalidSessionIdException(WebDriverException):
+ http_status = 404
+ status_code = "invalid session id"
+
+
+class JavascriptErrorException(WebDriverException):
+ http_status = 500
+ status_code = "javascript error"
+
+
+class MoveTargetOutOfBoundsException(WebDriverException):
+ http_status = 500
+ status_code = "move target out of bounds"
+
+
+class NoSuchAlertException(WebDriverException):
+ http_status = 400
+ status_code = "no such alert"
+
+
+class NoSuchElementException(WebDriverException):
+ http_status = 404
+ status_code = "no such element"
+
+
+class NoSuchFrameException(WebDriverException):
+ http_status = 400
+ status_code = "no such frame"
+
+
+class NoSuchWindowException(WebDriverException):
+ http_status = 400
+ status_code = "no such window"
+
+
+class ScriptTimeoutException(WebDriverException):
+ http_status = 408
+ status_code = "script timeout"
+
+
+class SessionNotCreatedException(WebDriverException):
+ http_status = 500
+ status_code = "session not created"
+
+
+class StaleElementReferenceException(WebDriverException):
+ http_status = 400
+ status_code = "stale element reference"
+
+
+class TimeoutException(WebDriverException):
+ http_status = 408
+ status_code = "timeout"
+
+
+class UnableToSetCookieException(WebDriverException):
+ http_status = 500
+ status_code = "unable to set cookie"
+
+
+class UnexpectedAlertOpenException(WebDriverException):
+ http_status = 500
+ status_code = "unexpected alert open"
+
+
+class UnknownErrorException(WebDriverException):
+ http_status = 500
+ status_code = "unknown error"
+
+
+class UnknownCommandException(WebDriverException):
+ http_status = 404
+ status_code = "unknown command"
+
+
+class UnknownMethodException(WebDriverException):
+ http_status = 405
+ status_code = "unknown method"
+
+
+class UnsupportedOperationException(WebDriverException):
+ http_status = 500
+ status_code = "unsupported operation"
+
+
+def get(status_code):
+ """Gets exception from `status_code`, falling back to
+ ``WebDriverException`` if it is not found.
+ """
+ return _errors.get(status_code, WebDriverException)
+
+
+_errors = collections.defaultdict()
+for item in locals().values():
+ if type(item) == type and issubclass(item, WebDriverException):
+ _errors[item.status_code] = item
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/exceptions.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/exceptions.py
deleted file mode 100644
index 33f63ea5811..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/exceptions.py
+++ /dev/null
@@ -1,166 +0,0 @@
-"""Definition of WebDriverException classes."""
-
-def create_webdriver_exception_strict(status_code, message):
- """Create the appropriate WebDriverException given the status_code."""
- if status_code in _exceptions_strict:
- return _exceptions_strict[status_code](message)
- return UnknownStatusCodeException("[%s] %s" % (status_code, message))
-
-def create_webdriver_exception_compatibility(status_code, message):
- """Create the appropriate WebDriverException given the status_code."""
- if status_code in _exceptions_compatibility:
- return _exceptions_compatibility[status_code](message)
- return UnknownStatusCodeException("[%s] %s" % (status_code, message))
-
-class WebDriverException(Exception):
- """Base class for all WebDriverExceptions."""
-
-class UnableToSetCookieException(WebDriverException):
- """A request to set a cookie's value could not be satisfied."""
-
-class InvalidElementStateException(WebDriverException):
- """An element command could not be completed because the element is
- in an invalid state (e.g. attempting to click an element that is no
- longer attached to the DOM).
- """
-
-class NoSuchElementException(WebDriverException):
- """An element could not be located on the page using the given
- search parameters.
- """
-
-class TimeoutException(WebDriverException):
- """An operation did not complete before its timeout expired."""
-
-class ElementNotSelectableException(InvalidElementStateException):
- """An attempt was made to select an element that cannot be selected."""
-
-class ElementNotVisibleException(InvalidElementStateException):
- """An element command could not be completed because the element is
- not visible on the page.
- """
-
-class ImeEngineActivationFailedException(WebDriverException):
- """An IME engine could not be started."""
-
-class ImeNotAvailableException(ImeEngineActivationFailedException):
- """IME was not available."""
-
-class InvalidCookieDomainException(UnableToSetCookieException):
- """An illegal attempt was made to set a cookie under a different
- domain than the current page.
- """
-
-class InvalidElementCoordinatesException(WebDriverException):
- """The coordinates provided to an interactions operation are invalid."""
-
-class InvalidSelectorException(NoSuchElementException):
- """Argument was an invalid selector (e.g. XPath/CSS)."""
-
-class JavascriptErrorException(WebDriverException):
- """An error occurred while executing user supplied JavaScript."""
-
-class MoveTargetOutOfBoundsException(InvalidElementStateException):
- """The target for mouse interaction is not in the browser's viewport
- and cannot be brought into that viewport.
- """
-
-class NoSuchAlertException(WebDriverException):
- """An attempt was made to operate on a modal dialog when one was not open."""
-
-class NoSuchFrameException(WebDriverException):
- """A request to switch to a frame could not be satisfied because
- the frame could not be found."""
-
-class NoSuchWindowException(WebDriverException):
- """A request to switch to a different window could not be satisfied
- because the window could not be found.
- """
-
-class ScriptTimeoutException(TimeoutException):
- """A script did not complete before its timeout expired."""
-
-class SessionNotCreatedException(WebDriverException):
- """A new session could not be created."""
-
-class StaleElementReferenceException(InvalidElementStateException):
- """An element command failed because the referenced element is no
- longer attached to the DOM.
- """
-
-class UnexpectedAlertOpenException(WebDriverException):
- """A modal dialog was open, blocking this operation."""
-
-class UnknownCommandException(WebDriverException):
- """A command could not be executed because the remote end is not
- aware of it.
- """
-
-class UnknownErrorException(WebDriverException):
- """An unknown error occurred in the remote end while processing
- the command.
- """
-
-class UnsupportedOperationException(WebDriverException):
- """Indicates that a command that should have executed properly
- cannot be supported for some reason.
- """
-
-class UnknownStatusCodeException(WebDriverException):
- """Exception for all other status codes."""
-
-_exceptions_strict = {
- "element not selectable": ElementNotSelectableException,
- "element not visible": ElementNotVisibleException,
- "ime engine activation failed": ImeEngineActivationFailedException,
- "ime not available": ImeNotAvailableException,
- "invalid cookie domain": InvalidCookieDomainException,
- "invalid element coordinates": InvalidElementCoordinatesException,
- "invalid element state": InvalidElementStateException,
- "invalid selector": InvalidSelectorException,
- "javascript error": JavascriptErrorException,
- "move target out of bounds": MoveTargetOutOfBoundsException,
- "no such alert": NoSuchAlertException,
- "no such element": NoSuchElementException,
- "no such frame": NoSuchFrameException,
- "no such window": NoSuchWindowException,
- "script timeout": ScriptTimeoutException,
- "session not created": SessionNotCreatedException,
- "stale element reference": StaleElementReferenceException,
- "success": None,
- "timeout": TimeoutException,
- "unable to set cookie": UnableToSetCookieException,
- "unexpected alert open": UnexpectedAlertOpenException,
- "unknown command": UnknownCommandException,
- "unknown error": UnknownErrorException,
- "unsupported operation": UnsupportedOperationException,
-}
-
-_exceptions_compatibility = {
- 15: ElementNotSelectableException,
- 11: ElementNotVisibleException,
- 31: ImeEngineActivationFailedException,
- 30: ImeNotAvailableException,
- 24: InvalidCookieDomainException,
- 29: InvalidElementCoordinatesException,
- 12: InvalidElementStateException,
- 19: InvalidSelectorException,
- 32: InvalidSelectorException,
- 17: JavascriptErrorException,
- 34: MoveTargetOutOfBoundsException,
- 27: NoSuchAlertException,
- 7: NoSuchElementException,
- 8: NoSuchFrameException,
- 23: NoSuchWindowException,
- 28: ScriptTimeoutException,
- 6: SessionNotCreatedException,
- 33: SessionNotCreatedException,
- 10: StaleElementReferenceException,
- 0: None, # success
- 21: TimeoutException,
- 25: UnableToSetCookieException,
- 26: UnexpectedAlertOpenException,
- 9: UnknownCommandException,
- 13: UnknownErrorException,
- # "unsupported operation": UnsupportedOperationException
-}
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/keys.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/keys.py
deleted file mode 100644
index 9c6d93df821..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/keys.py
+++ /dev/null
@@ -1,68 +0,0 @@
-"""Constants for special keys."""
-
-class Keys:
- """Constants for special keys."""
- NULL = '\uE000'
- CANCEL = '\uE001'
- HELP = '\uE002'
- BACK_SPACE = '\uE003'
- TAB = '\uE004'
- CLEAR = '\uE005'
- RETURN = '\uE006'
- ENTER = '\uE007'
- SHIFT = '\uE008'
- LEFT_SHIFT = '\uE008'
- CONTROL = '\uE009'
- LEFT_CONTROL = '\uE009'
- ALT = '\uE00A'
- LEFT_ALT = '\uE00A'
- PAUSE = '\uE00B'
- ESCAPE = '\uE00C'
- SPACE = '\uE00D'
- PAGE_UP = '\uE00E'
- PAGE_DOWN = '\uE00F'
- END = '\uE010'
- HOME = '\uE011'
- LEFT = '\uE012'
- ARROW_LEFT = '\uE012'
- UP = '\uE013'
- ARROW_UP = '\uE013'
- RIGHT = '\uE014'
- ARROW_RIGHT = '\uE014'
- DOWN = '\uE015'
- ARROW_DOWN = '\uE015'
- INSERT = '\uE016'
- DELETE = '\uE017'
- SEMICOLON = '\uE018'
- EQUALS = '\uE019'
- NUMPAD0 = '\uE01A'
- NUMPAD1 = '\uE01B'
- NUMPAD2 = '\uE01C'
- NUMPAD3 = '\uE01D'
- NUMPAD4 = '\uE01E'
- NUMPAD5 = '\uE01F'
- NUMPAD6 = '\uE020'
- NUMPAD7 = '\uE021'
- NUMPAD8 = '\uE022'
- NUMPAD9 = '\uE023'
- MULTIPLY = '\uE024'
- ADD = '\uE025'
- SEPARATOR = '\uE026'
- SUBTRACT = '\uE027'
- DECIMAL = '\uE028'
- DIVIDE = '\uE029'
- F1 = '\uE031'
- F2 = '\uE032'
- F3 = '\uE033'
- F4 = '\uE034'
- F5 = '\uE035'
- F6 = '\uE036'
- F7 = '\uE037'
- F8 = '\uE038'
- F9 = '\uE039'
- F10 = '\uE03A'
- F11 = '\uE03B'
- F12 = '\uE03C'
- META = '\uE03D'
- COMMAND = '\uE03D'
- ZENKAKU_HANKAKU = '\uE040'
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/searchcontext.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/searchcontext.py
deleted file mode 100644
index 061fa027db1..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/searchcontext.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""WebDriver element location functionality."""
-
-class SearchContext(object):
- """Abstract class that provides the core element location functionality."""
-
- def find_element_by_css(self, selector):
- """Find the first element matching a css selector."""
- return self._find_element('css selector', selector)
-
- def find_elements_by_css(self, selector):
- """Find all elements matching a css selector."""
- return self._find_elements('css selector', selector)
-
- def find_element_by_link_text(self, text):
- """Find the first link with the given text."""
- return self._find_element('link text', text)
-
- def find_elements_by_link_text(self, text):
- """Find all links with the given text."""
- return self._find_elements('link text', text)
-
- def find_element_by_partial_link_text(self, text):
- """Find the first link containing the given text."""
- return self._find_element('partial link text', text)
-
- def find_elements_by_partial_link_text(self, text):
- """Find all links containing the given text."""
- return self._find_elements('partial link text', text)
-
- def find_element_by_xpath(self, xpath):
- """Find the first element matching the xpath."""
- return self._find_element('xpath', xpath)
-
- def find_elements_by_xpath(self, xpath):
- """Find all elements matching the xpath."""
- return self._find_elements('xpath', xpath)
-
- def _find_element(self, strategy, value):
- return self.execute('POST',
- '/element',
- 'findElement',
- self._get_locator(strategy, value))
-
- def _find_elements(self, strategy, value):
- return self.execute('POST',
- '/elements',
- 'findElements',
- self._get_locator(strategy, value))
-
- def _get_locator(self, strategy, value):
- if self.mode == 'strict':
- return {'strategy': strategy, 'value': value}
- elif self.mode == 'compatibility':
- return {'using': strategy, 'value': value}
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/servo.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/servo.py
new file mode 100644
index 00000000000..fd1539f7bc7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/servo.py
@@ -0,0 +1,22 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+class ServoExtensionCommands(object):
+ def __init__(self, session):
+ self.session = session
+
+ @command
+ def get_prefs(self, *prefs):
+ body = {"prefs": list(prefs)}
+ return self.session.send_command("POST", "servo/prefs/get", body)
+
+ @command
+ def set_prefs(self, prefs):
+ body = {"prefs": prefs}
+ return self.session.send_command("POST", "servo/prefs/set", body)
+
+ @command
+ def reset_prefs(self, *prefs):
+ body = {"prefs": list(prefs)}
+ return self.session.send_command("POST", "servo/prefs/reset", body)
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/transport.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/transport.py
new file mode 100644
index 00000000000..d4b0adfda05
--- /dev/null
+++ b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/transport.py
@@ -0,0 +1,117 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this file,
+# You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+import errno
+import httplib
+import json
+import socket
+import time
+import urlparse
+
+import error
+
+
+HTTP_TIMEOUT = 5
+
+
+class HTTPWireProtocol(object):
+ """Transports messages (commands and responses) over the WebDriver
+ wire protocol.
+ """
+
+ def __init__(self, host, port, url_prefix="/", timeout=HTTP_TIMEOUT):
+ """Construct interface for communicating with the remote server.
+
+ :param url: URL of remote WebDriver server.
+ :param wait: Duration to wait for remote to appear.
+ """
+
+ self.host = host
+ self.port = port
+ self.path_prefix = url_prefix
+
+ self._timeout = timeout
+ self._connection = None
+
+ def connect(self):
+ wait_for_port(self.host, self.port, self._timeout)
+ self._connection = httplib.HTTPConnection(
+ self.host, self.port, timeout=self._timeout)
+
+ def disconnect(self):
+ if self._connection:
+ self._connection.close()
+ self._connection = None
+
+ def url(self, suffix):
+ return urlparse.urljoin(self.path_prefix, suffix)
+
+ def send(self, method, url, body=None, headers=None, key=None):
+ """Send a command to the remote.
+
+ :param method: "POST" or "GET".
+ :param body: Body of the request. Defaults to an empty dictionary
+ if ``method`` is "POST".
+ :param headers: Additional headers to include in the request.
+ :param key: Extract this key from the dictionary returned from
+ the remote.
+ """
+
+ if not self._connection:
+ self.connect()
+
+ if body is None and method == "POST":
+ body = {}
+
+ if isinstance(body, dict):
+ body = json.dumps(body)
+
+ if isinstance(body, unicode):
+ body = body.encode("utf-8")
+
+ if headers is None:
+ headers = {}
+
+ url = self.path_prefix + url
+ self._connection.request(method, url, body, headers)
+
+ resp = self._connection.getresponse()
+ resp_body = resp.read()
+
+ try:
+ data = json.loads(resp_body)
+ except:
+ raise IOError("Could not parse response body as JSON: %s" % body)
+
+ if resp.status != 200:
+ cls = error.get(data.get("error"))
+ raise cls(data.get("message"))
+
+ if key is not None:
+ data = data[key]
+ if not data:
+ data = None
+
+ return data
+
+
+def wait_for_port(host, port, timeout=HTTP_TIMEOUT):
+ """Wait for a given host/port to be available."""
+ starttime = time.time()
+ poll_interval = 0.1
+ while time.time() - starttime < timeout:
+ sock = None
+ try:
+ sock = socket.socket()
+ sock.connect((host, port))
+ return True
+ except socket.error as e:
+ if e[0] != errno.ECONNREFUSED:
+ raise
+ finally:
+ if sock:
+ sock.close()
+ time.sleep(poll_interval)
+ return False
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/wait.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/wait.py
deleted file mode 100644
index e93c42d1d72..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/wait.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright 2011 Software Freedom Conservancy.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Waiting functionality."""
-
-import time
-from exceptions import NoSuchElementException
-from exceptions import TimeoutException
-
-POLL_FREQUENCY = 0.5 # How long to sleep inbetween calls to the method
-IGNORED_EXCEPTIONS = [NoSuchElementException] # list of exceptions ignored during calls to the method
-
-class WebDriverWait(object):
-
- def __init__(self, driver, timeout, poll_frequency=POLL_FREQUENCY, ignored_exceptions=None):
- """Constructor, takes a WebDriver instance and timeout in seconds.
-
- :Args:
- - driver - Instance of WebDriver (Ie, Firefox, Chrome or Remote)
- - timeout - Number of seconds before timing out
- - poll_frequency - sleep interval between calls
- By default, it is 0.5 second.
- - ignored_exceptions - iterable structure of exception classes ignored during calls.
- By default, it contains NoSuchElementException only.
-
- Example:
- from selenium.webdriver.support.ui import WebDriverWait \n
- element = WebDriverWait(driver, 10).until(lambda x: x.find_element_by_id("someId")) \n
- is_disappeared = WebDriverWait(driver, 30, 1, (ElementNotVisibleException)).\ \n
- until_not(lambda x: x.find_element_by_id("someId").is_displayed())
- """
- self._driver = driver
- self._timeout = timeout
- self._poll = poll_frequency
- # avoid the divide by zero
- if self._poll == 0:
- self._poll = POLL_FREQUENCY
- exceptions = IGNORED_EXCEPTIONS
- if ignored_exceptions is not None:
- try:
- exceptions.extend(iter(ignored_exceptions))
- except TypeError: # ignored_exceptions is not iterable
- exceptions.append(ignored_exceptions)
- self._ignored_exceptions = tuple(exceptions)
-
- def until(self, method, message=''):
- """Calls the method provided with the driver as an argument until the \
- return value is not False."""
- end_time = time.time() + self._timeout
- while(True):
- try:
- value = method(self._driver)
- if value:
- return value
- except self._ignored_exceptions:
- pass
- time.sleep(self._poll)
- if(time.time() > end_time):
- break
- raise TimeoutException(message)
-
- def until_not(self, method, message=''):
- """Calls the method provided with the driver as an argument until the \
- return value is False."""
- end_time = time.time() + self._timeout
- while(True):
- try:
- value = method(self._driver)
- if not value:
- return value
- except self._ignored_exceptions:
- return True
- time.sleep(self._poll)
- if(time.time() > end_time):
- break
- raise TimeoutException(message)
diff --git a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/webelement.py b/tests/wpt/web-platform-tests/tools/webdriver/webdriver/webelement.py
deleted file mode 100644
index 83e27f23116..00000000000
--- a/tests/wpt/web-platform-tests/tools/webdriver/webdriver/webelement.py
+++ /dev/null
@@ -1,56 +0,0 @@
-"""Element-level WebDriver operations."""
-
-import searchcontext
-
-class WebElement(searchcontext.SearchContext):
- """Corresponds to a DOM element in the current page."""
-
- def __init__(self, driver, id):
- self._driver = driver
- self._id = id
- # Set value of mode used by SearchContext
- self.mode = driver.mode
-
- def execute(self, method, path, name, body=None):
- """Execute a command against this WebElement."""
- return self._driver.execute(
- method, '/element/%s%s' % (self._id, path), name, body)
-
- def is_displayed(self):
- """Is this element displayed?"""
- return self.execute('GET', '/displayed', 'isDisplayed')
-
- def is_selected(self):
- """Is this checkbox, radio button, or option selected?"""
- return self.execute('GET', '/selected', 'isSelected')
-
- def get_attribute(self, name):
- """Get the value of an element property or attribute."""
- return self.execute('GET', '/attribute/%s' % name, 'getElementAttribute')
-
- @property
- def text(self):
- """Get the visible text for this element."""
- return self.execute('GET', '/text', 'text')
-
- @property
- def tag_name(self):
- """Get the tag name for this element"""
- return self.execute('GET', '/name', 'getElementTagName')
-
- def click(self):
- """Click on this element."""
- return self.execute('POST', '/click', 'click')
-
- def clear(self):
- """Clear the contents of the this text input."""
- self.execute('POST', '/clear', 'clear')
-
- def send_keys(self, keys):
- """Send keys to this text input or body element."""
- if isinstance(keys, str):
- keys = [keys]
- self.execute('POST', '/value', 'sendKeys', {'value': keys})
-
- def to_json(self):
- return {'ELEMENT': self.id}
diff --git a/tests/wpt/web-platform-tests/url/OWNERS b/tests/wpt/web-platform-tests/url/OWNERS
index fe4257cdb03..562d1ccf8e1 100644
--- a/tests/wpt/web-platform-tests/url/OWNERS
+++ b/tests/wpt/web-platform-tests/url/OWNERS
@@ -7,3 +7,4 @@
@xiaojunwu
@smola
@domenic
+@Sebmaster
diff --git a/tests/wpt/web-platform-tests/url/historical.html b/tests/wpt/web-platform-tests/url/historical.html
index 41f359d3d67..17fdb97294b 100644
--- a/tests/wpt/web-platform-tests/url/historical.html
+++ b/tests/wpt/web-platform-tests/url/historical.html
@@ -18,4 +18,12 @@ objects.forEach(function(o) {
o[1] + " should not have a searchParams attribute");
}, "searchParams on " + o[1]);
});
+
+test(function() {
+ var url = new URL("./foo", "http://www.example.org");
+ assert_equals(url.href, "http://www.example.org/foo");
+ assert_throws(new TypeError(), function() {
+ url.href = "./bar";
+ });
+}, "Setting URL's href attribute and base URLs");
</script>
diff --git a/tests/wpt/web-platform-tests/url/historical.worker.js b/tests/wpt/web-platform-tests/url/historical.worker.js
index 4fcba6c90ee..d90915a38a0 100644
--- a/tests/wpt/web-platform-tests/url/historical.worker.js
+++ b/tests/wpt/web-platform-tests/url/historical.worker.js
@@ -5,4 +5,12 @@ test(function() {
"location object should not have a searchParams attribute");
}, "searchParams on location object");
+test(function() {
+ var url = new URL("./foo", "http://www.example.org");
+ assert_equals(url.href, "http://www.example.org/foo");
+ assert_throws(new TypeError(), function() {
+ url.href = "./bar";
+ });
+}, "Setting URL's href attribute and base URLs");
+
done();
diff --git a/tests/wpt/web-platform-tests/url/url-constructor.html b/tests/wpt/web-platform-tests/url/url-constructor.html
index a7503310397..80eb943aa16 100644
--- a/tests/wpt/web-platform-tests/url/url-constructor.html
+++ b/tests/wpt/web-platform-tests/url/url-constructor.html
@@ -5,20 +5,22 @@
<script src=urltestparser.js></script>
<div id=log></div>
<script>
-var setup = async_test("Loading data…")
-setup.step(function() {
- var request = new XMLHttpRequest()
- request.open("GET", "urltestdata.json")
- request.send()
- request.responseType = "json"
- request.onload = setup.step_func(function() {
- runURLTests(request.response)
- setup.done()
+function runURLConstructorTests() {
+ var setup = async_test("Loading data…")
+ setup.step(function() {
+ var request = new XMLHttpRequest()
+ request.open("GET", "urltestdata.json")
+ request.send()
+ request.responseType = "json"
+ request.onload = setup.step_func(function() {
+ runURLTests(request.response)
+ setup.done()
+ })
})
-})
+}
function bURL(url, base) {
- return new URL(url, base || "about:blank");
+ return new URL(url, base || "about:blank")
}
function runURLTests(urltests) {
@@ -30,8 +32,8 @@ function runURLTests(urltests) {
if (expected.failure) {
assert_throws(new TypeError(), function() {
bURL(expected.input, expected.base)
- });
- return;
+ })
+ return
}
var url = bURL(expected.input, expected.base)
@@ -45,8 +47,82 @@ function runURLTests(urltests) {
assert_equals(url.port, expected.port, "port")
assert_equals(url.pathname, expected.pathname, "pathname")
assert_equals(url.search, expected.search, "search")
+ if ("searchParams" in expected) {
+ assert_true("searchParams" in url)
+ assert_equals(url.searchParams.toString(), expected.searchParams, "searchParams")
+ }
assert_equals(url.hash, expected.hash, "hash")
}, "Parsing: <" + expected.input + "> against <" + expected.base + ">")
}
}
+
+function runURLSearchParamTests() {
+ test(function() {
+ var url = bURL('http://example.org/?a=b')
+ assert_true("searchParams" in url)
+ var searchParams = url.searchParams
+ assert_true(url.searchParams === searchParams, 'Object identity should hold.')
+ }, 'URL.searchParams getter')
+
+ test(function() {
+ var url = bURL('http://example.org/?a=b')
+ assert_true("searchParams" in url)
+ var searchParams = url.searchParams
+ assert_equals(searchParams.toString(), 'a=b')
+
+ searchParams.set('a', 'b')
+ assert_equals(url.searchParams.toString(), 'a=b')
+ assert_equals(url.search, '?a=b')
+ url.search = ''
+ assert_equals(url.searchParams.toString(), '')
+ assert_equals(url.search, '')
+ assert_equals(searchParams.toString(), '')
+ }, 'URL.searchParams updating, clearing')
+
+ test(function() {
+ 'use strict'
+ var urlString = 'http://example.org'
+ var url = bURL(urlString)
+ assert_throws(TypeError(), function() { url.searchParams = new URLSearchParams(urlString) })
+ }, 'URL.searchParams setter, invalid values')
+
+ test(function() {
+ var url = bURL('http://example.org/file?a=b&c=d')
+ assert_true("searchParams" in url)
+ var searchParams = url.searchParams
+ assert_equals(url.search, '?a=b&c=d')
+ assert_equals(searchParams.toString(), 'a=b&c=d')
+
+ // Test that setting 'search' propagates to the URL object's query object.
+ url.search = 'e=f&g=h'
+ assert_equals(url.search, '?e=f&g=h')
+ assert_equals(searchParams.toString(), 'e=f&g=h')
+
+ // ..and same but with a leading '?'.
+ url.search = '?e=f&g=h'
+ assert_equals(url.search, '?e=f&g=h')
+ assert_equals(searchParams.toString(), 'e=f&g=h')
+
+ // And in the other direction, altering searchParams propagates
+ // back to 'search'.
+ searchParams.append('i', ' j ')
+ assert_equals(url.search, '?e=f&g=h&i=+j+')
+ assert_equals(url.searchParams.toString(), 'e=f&g=h&i=+j+')
+ assert_equals(searchParams.get('i'), ' j ')
+
+ searchParams.set('e', 'updated')
+ assert_equals(url.search, '?e=updated&g=h&i=+j+')
+ assert_equals(searchParams.get('e'), 'updated')
+
+ var url2 = bURL('http://example.org/file??a=b&c=d')
+ assert_equals(url2.search, '??a=b&c=d')
+ assert_equals(url2.searchParams.toString(), '%3Fa=b&c=d')
+
+ url2.href = 'http://example.org/file??a=b'
+ assert_equals(url2.search, '??a=b')
+ assert_equals(url2.searchParams.toString(), '%3Fa=b')
+ }, 'URL.searchParams and URL.search setters, update propagation')
+}
+runURLSearchParamTests()
+runURLConstructorTests()
</script>
diff --git a/tests/wpt/web-platform-tests/url/urltestdata.json b/tests/wpt/web-platform-tests/url/urltestdata.json
index 7d9b9090fb2..322f69ec893 100644
--- a/tests/wpt/web-platform-tests/url/urltestdata.json
+++ b/tests/wpt/web-platform-tests/url/urltestdata.json
@@ -4224,5 +4224,38 @@
"pathname": "/path",
"search": "?query",
"hash": "#frag"
+ },
+ "# Stringification of URL.searchParams",
+ {
+ "input": "?a=b&c=d",
+ "base": "http://example.org/foo/bar",
+ "href": "http://example.org/foo/bar?a=b&c=d",
+ "origin": "http://example.org",
+ "protocol": "http:",
+ "username": "",
+ "password": "",
+ "host": "example.org",
+ "hostname": "example.org",
+ "port": "",
+ "pathname": "/foo/bar",
+ "search": "?a=b&c=d",
+ "searchParams": "a=b&c=d",
+ "hash": ""
+ },
+ {
+ "input": "??a=b&c=d",
+ "base": "http://example.org/foo/bar",
+ "href": "http://example.org/foo/bar??a=b&c=d",
+ "origin": "http://example.org",
+ "protocol": "http:",
+ "username": "",
+ "password": "",
+ "host": "example.org",
+ "hostname": "example.org",
+ "port": "",
+ "pathname": "/foo/bar",
+ "search": "??a=b&c=d",
+ "searchParams": "%3Fa=b&c=d",
+ "hash": ""
}
]
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/delay.html b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/delay.html
new file mode 100644
index 00000000000..82761cf85b6
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/delay.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>delay tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-delay">
+<link rel="author" title="Daisuke Akatsuka" href="mailto:daisuke@mozilla-japan.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 100);
+ anim.effect.timing.delay = 100;
+ assert_equals(anim.effect.timing.delay, 100, 'set delay 100');
+ assert_equals(anim.effect.getComputedTiming().delay, 100,
+ 'getComputedTiming() after set delay 100');
+}, 'set delay 100');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 100);
+ anim.effect.timing.delay = -100;
+ assert_equals(anim.effect.timing.delay, -100, 'set delay -100');
+ assert_equals(anim.effect.getComputedTiming().delay, -100,
+ 'getComputedTiming() after set delay -100');
+}, 'set delay -100');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 100);
+ anim.effect.timing.delay = 100;
+ assert_equals(anim.effect.getComputedTiming().progress, null);
+ assert_equals(anim.effect.getComputedTiming().currentIteration, null);
+}, 'Test adding a positive delay to an animation without a backwards fill ' +
+ 'makes it no longer active');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] },
+ { fill: 'both',
+ duration: 100 });
+ anim.effect.timing.delay = -50;
+ assert_equals(anim.effect.getComputedTiming().progress, 0.5);
+}, 'Test seeking an animation by setting a negative delay');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] },
+ { fill: 'both',
+ duration: 100 });
+ anim.effect.timing.delay = -100;
+ assert_equals(anim.effect.getComputedTiming().progress, 1);
+ assert_equals(anim.effect.getComputedTiming().currentIteration, 0);
+}, 'Test finishing an animation using a large negative delay');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/direction.html b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/direction.html
new file mode 100644
index 00000000000..454f13604c9
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/direction.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>direction tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-direction">
+<link rel="author" title="Ryo Kato" href="mailto:foobar094@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+
+ var directions = ['normal', 'reverse', 'alternate', 'alternate-reverse'];
+ directions.forEach(function(direction) {
+ anim.effect.timing.direction = direction;
+ assert_equals(anim.effect.timing.direction, direction,
+ 'set direction to ' + direction);
+ });
+}, 'set direction to a valid keyword');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getAnimations.html b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getAnimations.html
index ffbfd94c18b..d4d9e32b5fa 100644
--- a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getAnimations.html
+++ b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getAnimations.html
@@ -53,6 +53,19 @@ test(function(t) {
test(function(t) {
var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+ anim.finish();
+ assert_equals(div.getAnimations().length, 0, 'animation finished');
+ anim.effect.timing.iterations = 10;
+ assert_equals(div.getAnimations()[0], anim, 'set iterations 10');
+ anim.effect.timing.iterations = 0;
+ assert_equals(div.getAnimations().length, 0, 'set iterations 0');
+ anim.effect.timing.iterations = Infinity;
+ assert_equals(div.getAnimations().length, 1, 'set iterations Infinity');
+}, 'when iterations is changed');
+
+test(function(t) {
+ var div = createDiv(t);
var anim = div.animate({ opacity: [ 0, 1 ] },
{ duration: 1000, delay: 500, endDelay: -500 });
assert_equals(div.getAnimations()[0], anim, 'when currentTime 0');
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getComputedStyle.html b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getComputedStyle.html
index d49e07e39f8..e562783c88e 100644
--- a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getComputedStyle.html
+++ b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/getComputedStyle.html
@@ -26,6 +26,19 @@ test(function(t) {
test(function(t) {
var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 100000);
+ anim.finish();
+ assert_equals(getComputedStyle(div).opacity, '1', 'animation finished');
+ anim.effect.timing.iterations = 2;
+ assert_equals(getComputedStyle(div).opacity, '0', 'set 2 iterations');
+ anim.effect.timing.iterations = 0;
+ assert_equals(getComputedStyle(div).opacity, '1', 'set iterations 0');
+ anim.effect.timing.iterations = Infinity;
+ assert_equals(getComputedStyle(div).opacity, '0', 'set iterations Infinity');
+}, 'changed iterations immediately updates its computed styles');
+
+test(function(t) {
+ var div = createDiv(t);
var anim = div.animate({ opacity: [ 1, 0 ] },
{ duration: 10000, endDelay: 1000, fill: 'none' });
@@ -103,5 +116,61 @@ test(function(t) {
'set currentTime after endTime');
}, 'change currentTime when fill forwards and endDelay is negative');
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] },
+ { duration: 10000,
+ direction: 'normal' });
+
+ anim.currentTime = 7000;
+ anim.effect.timing.direction = 'reverse';
+
+ assert_equals(getComputedStyle(div).opacity, '0.3',
+ 'change direction from "normal" to "reverse"');
+}, 'change direction from "normal" to "reverse"');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] },
+ { iterations: 2,
+ duration: 10000,
+ direction: 'normal' });
+
+ anim.currentTime = 17000;
+ anim.effect.timing.direction = 'alternate';
+
+ assert_equals(getComputedStyle(div).opacity, '0.3',
+ 'change direction from "normal" to "alternate"');
+ }, 'change direction from "normal" to "alternate"');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] },
+ { iterations: 2,
+ duration: 10000,
+ direction: 'normal' });
+
+ anim.currentTime = 17000;
+ anim.effect.timing.direction = 'alternate-reverse';
+
+ assert_equals(getComputedStyle(div).opacity, '0.7',
+ 'change direction from "normal" to "alternate-reverse"');
+}, 'change direction from "normal" to "alternate-reverse"');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] },
+ { fill: 'backwards',
+ duration: 10000,
+ direction: 'normal' });
+
+ // test for a flip of value at the currentTime = 0
+ anim.effect.timing.direction = 'reverse';
+
+ assert_equals(getComputedStyle(div).opacity, '1',
+ 'change direction from "normal" to "reverse" ' +
+ 'at the starting point');
+}, 'change direction from "normal" to "reverse"');
+
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/iterations.html b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/iterations.html
new file mode 100644
index 00000000000..f313d4bff48
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation-effect-timing/iterations.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>iterations tests</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animationeffecttiming-iterations">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+ anim.effect.timing.iterations = 2;
+ assert_equals(anim.effect.timing.iterations, 2, 'set duration 2');
+ assert_equals(anim.effect.getComputedTiming().iterations, 2,
+ 'getComputedTiming() after set iterations 2');
+}, 'set iterations 2');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+ anim.effect.timing.iterations = Infinity;
+ assert_equals(anim.effect.timing.iterations, Infinity, 'set duration Infinity');
+ assert_equals(anim.effect.getComputedTiming().iterations, Infinity,
+ 'getComputedTiming() after set iterations Infinity');
+}, 'set iterations Infinity');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+ assert_throws({ name: 'TypeError' }, function() {
+ anim.effect.timing.iterations = -1;
+ });
+}, 'set negative iterations');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+ assert_throws({ name: 'TypeError' }, function() {
+ anim.effect.timing.iterations = -Infinity;
+ });
+}, 'set negative infinity iterations ');
+
+test(function(t) {
+ var div = createDiv(t);
+ var anim = div.animate({ opacity: [ 0, 1 ] }, 2000);
+ assert_throws({ name: 'TypeError' }, function() {
+ anim.effect.timing.iterations = NaN;
+ });
+}, 'set NaN iterations');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-after.html b/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-after.html
deleted file mode 100644
index 93d79e03804..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-after.html
+++ /dev/null
@@ -1,419 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationNode after() method tests</title>
-<meta name="assert" content="Inserts nodes after this animation node">
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animationnode-after">
-<link rel="help" href="http://w3c.github.io/web-animations/#insert-children">
-<link rel="help" href="http://w3c.github.io/web-animations/#remove-an-animation-node">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-// Test step 1. If there is no parent animation group, terminate these steps.
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- try {
- node.after(null);
- } catch(e) {
- assert_unreached(type(node) + '.after(null) throws unexpected exception: ' + e);
- }
- });
-}, 'AnimationNode.after() does nothing if the node has no parent animation group. ' +
- 'HierarchyRequestError is not thrown in call node.after(null)');
-
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- try {
- node.after(node);
- } catch(e) {
- assert_unreached(type(node) + '.after() throws unexpected exception: ' + e);
- }
- });
-}, 'AnimationNode.after() does nothing if the node has no parent animation group. ' +
- 'No HierarchyRequestError is thrown if the node is inserted after itself');
-
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- var node2 = newAnimation(createDiv(this));
- nodes.forEach(function(node1) {
- node1.after(node2);
-
- assert_equals(node1.nextSibling, null, type(node1) + '.after() should do nothing ' +
- 'if the node has no parent animation group');
- assert_equals(node2.previousSibling, null, type(node1) + '.after() should do nothing ' +
- 'if the node has no parent animation group');
- });
-}, 'AnimationNode.after() does nothing if there is no parent animation group');
-
-// Test step 2. If any of the animation nodes in nodes is an inclusive ancestor of this animation node throw a HierarchyRequestError exception and terminate these steps.
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_throws('HierarchyRequestError', function() {
- node.after(node);
- }, type(node) + '.after() should throw HierarchyRequestError ' +
- 'if inserting node after itself');
- assert_equals(node.parent, parent, type(node) + '.after() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent.children, [node], type(node) + '.after() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if node is inserted after itself');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_throws('HierarchyRequestError', function() {
- node.after(parent);
- }, type(node) + '.after() should throw HierarchyRequestError ' +
- 'if inserting node\'s parent');
- assert_equals(node.parent, parent, type(node) + '.after() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent.children, [node], type(node) + '.after() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if direct parent is inserted after the node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent1 = new parentCtor([node]);
- var parent2 = new parentCtor([parent1]);
- var parent3 = new parentCtor([parent2]);
- var parent4 = new parentCtor([parent3]);
-
- assert_throws('HierarchyRequestError', function() {
- node.after(parent3);
- }, type(node) + '.after() should throw HierarchyRequestError ' +
- 'if inserting node\'s ancestor');
- assert_equals(node.parent, parent1, type(node) + '.after() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent1.children, [node], type(node) + '.after() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- assert_equals(parent3.parent, parent4, type(node) + '.after() should not change ' +
- 'parent attribute of inserted node before throwing HierarchyRequestError');
- assert_array_equals(parent4.children, [parent3], type(node) + '.after() ' +
- 'should not change inserted node parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if an inclusive ancestor is inserted after the node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([parent1]);
- var parent3 = new parentCtor([parent2]);
- var parent4 = new parentCtor([parent3]);
- var parent5 = new ParentCtor([node3]);
-
- assert_throws('HierarchyRequestError', function() {
- node1.after(node3, parent3);
- }, type(node1) + '.after() should throw HierarchyRequestError ' +
- 'if inserting node\'s parent');
- assert_equals(node1.parent, parent1, type(node1) + '.after() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent1.children, [node1, node2], type(node1) + '.after() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- assert_equals(parent3.parent, parent4, type(node1) + '.after() should not change ' +
- 'parent attribute of inserted node before throwing HierarchyRequestError');
- assert_array_equals(parent4.children, [parent3], type(node1) + '.after() ' +
- 'should not change inserted node parent children before throwing HierarchyRequestError');
- assert_equals(node3.parent, parent5, type(node1) + '.after() should not change ' +
- 'parent attribute of inserted node before throwing HierarchyRequestError');
- assert_array_equals(parent5.children, [node3], type(node1) + '.after() ' +
- 'should not change inserted node parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if an inclusive ancestor is inserted after the node. ' +
- 'Test several arguments in after() call');
-
-// Test step 3 and 4.
-// 3. Let reference child be the next sibling of this animation node not in nodes.
-// 4. Insert nodes before reference child.
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
-
- node1.after(node2);
-
- assert_equals(node2.previousSibling, node1, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node2.parent, parent, 'Node should be inserted into the tree');
- assert_equals(node1.nextSibling, node2, 'Node should be inserted into the tree ' +
- 'after this node');
- assert_equals(parent.children, [node1, node2], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'AnimationNode.after() inserts nodes after this node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.after(node1);
-
- assert_equals(node2.previousSibling, null, type(node2) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node2.nextSibling, node1, 'Node should be inserted into the tree ' +
- 'after this node');
- assert_equals(node1.previousSibling, node2, type(node2) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node1.nextSibling, null, 'Node should be inserted into the tree ' +
- 'after this node');
- assert_equals(parent.children, [node2, node1], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'AnimationNode.after() inserts nodes after this node. Inserted node is on the same ' +
- 'level in the tree');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node1.after(node2);
-
- assert_equals(node1.nextSibling, node2, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node2.previousSibling, node1, 'Node should be inserted into the tree ' +
- 'after this node');
- assert_equals(parent.children, [node1, node2], parentCtor.name +
- '.children should not be changed');
- });
- });
-}, 'Test AnimationNode.after() inserts node after this node even if inserted ' +
- 'node is already after this one');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node3) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3, parent1, node4]);
-
- node3.after(node1);
-
- assert_equals(node1.nextSibling, parent1, type(node3) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node1.parent, parent2, 'Parent group of the inserted node should be changed');
- assert_equals(node1.previousSibling, node3, 'Node should be inserted into the tree ' +
- 'after this node');
-
- assert_equals(node3.nextSibling, node1, type(node3) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(parent1.previousSibling, node1, type(node3) + '.after() should insert ' +
- 'nodes after this node');
-
- assert_equals(node2.previousSibling, null, 'Inserted node should be removed from its ' +
- 'previous position in the tree');
- assert_array_equals(parent1.children, [node2], 'Inserted node should be removed from its ' +
- 'previous position in the tree');
- assert_array_equals(parent2.children, [node1, node3, parent1, node4], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.after() inserts node after this node. The previous position ' +
- 'of the inserted node is deeper in the tree than current node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3, parent1, node4]);
-
- node1.after(node4);
-
- assert_equals(node4.nextSibling, node2, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.parent, parent1, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node1, type(node1) + '.after() should insert ' +
- 'nodes after this node');
-
- assert_equals(node1.nextSibling, node4, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node2.previousSibling, node4, 'Node should be inserted into the tree ' +
- 'after this node');
-
- assert_equals(parent1.nextSibling, null, 'Inserted node should be removed from its ' +
- 'previous position in the tree');
- assert_array_equals(parent1.children, [node1, node4, node2], parentCtor.name +
- '.children should be updated');
- assert_array_equals(parent2.children, [node3, parent1], 'Inserted node should be ' +
- 'removed from its previous position in the tree');
- });
- });
-}, 'Test AnimationNode.after() inserts node after this node. The previous position ' +
- 'of the inserted node is shallower in the tree than current node, but not ancestor');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node1.after(node3, node4);
-
- assert_equals(node1.nextSibling, node3, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.previousSibling, node1, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.nextSibling, node4, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node3, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.nextSibling, node2, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node2.previousSibling, node4, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_array_equals(parent.children, [node1, node3, node4, node2], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.after() inserts several nodes after this node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node1.after(node3, node4, node3, node4);
-
- assert_equals(node1.nextSibling, node3, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.previousSibling, node1, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.nextSibling, node4, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node3, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.nextSibling, node2, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node2.previousSibling, node4, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_array_equals(parent.children, [node1, node3, node4, node2], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.after() inserts several nodes after this node, duplicate nodes are ignored');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node1.after(node3, node4, node3);
-
- assert_equals(node1.nextSibling, node4, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.previousSibling, node1, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.nextSibling, node3, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node4.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node3.previousSibling, node4, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.nextSibling, node2, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node2.previousSibling, node3, type(node1) + '.after() should insert ' +
- 'nodes after this node');
- assert_array_equals(parent.children, [node1, node4, node3, node2], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.after() inserts several nodes after this node, check insertion order');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- var player = document.timeline.play(node2);
-
- assert_equals(player.source, node2, 'The node should be associated with its player');
- node1.after(node2);
- assert_equals(player.source, null, 'The node should be disassociated from its player');
- });
- });
-}, 'Test AnimationNode.after() disassociates the inserted node from the player, ' +
- 'if node is directly associated with a player');
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-before.html b/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-before.html
deleted file mode 100644
index 714f1e4d152..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-before.html
+++ /dev/null
@@ -1,418 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationNode before() method tests</title>
-<meta name="assert" content="Inserts nodes before this animation node.">
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animationnode-before">
-<link rel="help" href="http://w3c.github.io/web-animations/#insert-children">
-<link rel="help" href="http://w3c.github.io/web-animations/#remove-an-animation-node">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-// Test step 1. If there is no parent animation group, terminate these steps.
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- try {
- node.before(null);
- } catch(e) {
- assert_unreached(type(node) + '.before(null) throws unexpected exception: ' + e);
- }
- });
-}, 'AnimationNode.before() does nothing if the node has no parent animation group. ' +
- 'HierarchyRequestError is not thrown in call node.before(null)');
-
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- try {
- node.before(node);
- } catch(e) {
- assert_unreached(type(node) + '.before() throws unexpected exception: ' + e);
- }
- });
-}, 'AnimationNode.before() does nothing if the node has no parent animation group. ' +
- 'No HierarchyRequestError is thrown if the node is inserted before itself');
-
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- var node2 = newAnimation(createDiv(this));
- nodes.forEach(function(node1) {
- node1.before(node2);
-
- assert_equals(node1.nextSibling, null, type(node1) + '.before() should do nothing ' +
- 'if the node has no parent animation group');
- assert_equals(node2.previousSibling, null, type(node1) + '.before() should do nothing ' +
- 'if the node has no parent animation group');
- });
-}, 'AnimationNode.before() does nothing if there is no parent animation group');
-
-// Test step 2. If any of the animation nodes in nodes is an inclusive ancestor of this animation node throw a HierarchyRequestError exception and terminate these steps.
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_throws('HierarchyRequestError', function() {
- node.before(node);
- }, type(node) + '.before() should throw HierarchyRequestError ' +
- 'if inserting node before itself');
- assert_equals(node.parent, parent, type(node) + '.before() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent.children, [node], type(node) + '.before() ' +
- 'should not change parent children before throwing HierarchyRequestError');
-
- });
- });
-}, 'HierarchyRequestError is thrown if node is inserted before itself');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_throws('HierarchyRequestError', function() {
- node.before(parent);
- }, type(node) + '.before() should throw HierarchyRequestError ' +
- 'if inserting node\'s parent');
- assert_equals(node.parent, parent, type(node) + '.before() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent.children, [node], type(node) + '.before() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if direct parent is inserted before the node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent1 = new parentCtor([node]);
- var parent2 = new parentCtor([parent1]);
- var parent3 = new parentCtor([parent2]);
- var parent4 = new parentCtor([parent3]);
-
- assert_throws('HierarchyRequestError', function() {
- node.before(parent4);
- }, type(node) + '.before() should throw HierarchyRequestError ' +
- 'if inserting node\'s ancestor');
- assert_equals(node.parent, parent1, type(node) + '.before() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent1.children, [node], type(node) + '.before() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- assert_equals(parent3.parent, parent4, type(node) + '.before() should not change ' +
- 'parent attribute of inserted node before throwing HierarchyRequestError');
- assert_array_equals(parent4.children, [parent3], type(node) + '.before() ' +
- 'should not change inserted node parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if an inclusive ancestor is inserted before the node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([parent1]);
- var parent3 = new parentCtor([parent2]);
- var parent4 = new parentCtor([parent3]);
- var parent5 = new ParentCtor([node3]);
-
- assert_throws('HierarchyRequestError', function() {
- node1.before(node3, parent3);
- }, type(node1) + '.before() should throw HierarchyRequestError ' +
- 'if inserting node\'s parent');
- assert_equals(node1.parent, parent1, type(node1) + '.before() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent1.children, [node1, node2], type(node1) + '.before() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- assert_equals(parent3.parent, parent4, type(node1) + '.before() should not change ' +
- 'parent attribute of inserted node before throwing HierarchyRequestError');
- assert_array_equals(parent4.children, [parent3], type(node1) + '.before() ' +
- 'should not change inserted node parent children before throwing HierarchyRequestError');
- assert_equals(node3.parent, parent5, type(node1) + '.before() should not change ' +
- 'parent attribute of inserted node before throwing HierarchyRequestError');
- assert_array_equals(parent5.children, [node3], type(node1) + '.before() ' +
- 'should not change inserted node parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if an inclusive ancestor is inserted before the node. ' +
- 'Test several arguments in before() call');
-
-// Test step 3. Insert nodes before this animation node.
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
-
- node1.before(node2);
-
- assert_equals(node1.previousSibling, node2, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node2.parent, parent, 'Node should be inserted into the tree');
- assert_equals(node2.nextSibling, node1, 'Node should be inserted into the tree ' +
- 'before this node');
- assert_equals(parent.children, [node2, node1], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'AnimationNode.before() inserts nodes before this node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node1.before(node2);
-
- assert_equals(node2.previousSibling, null, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node2.nextSibling, node1, 'Node should be inserted into the tree ' +
- 'before this node');
- assert_equals(node1.previousSibling, node2, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node1.nextSibling, null, 'Node should be inserted into the tree ' +
- 'before this node');
- assert_equals(parent.children, [node2, node1], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'AnimationNode.before() inserts nodes before this node. Inserted node is on the same ' +
- 'level in the tree');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.before(node1);
-
- assert_equals(node1.nextSibling, node2, type(node2) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node2.previousSibling, node1, 'Node should be inserted into the tree ' +
- 'before this node');
- assert_equals(parent.children, [node1, node2], parentCtor.name +
- '.children should not be changed');
- });
- });
-}, 'Test AnimationNode.before() inserts node before this node even if inserted ' +
- 'node is already before this one');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node4) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3, parent1, node4]);
-
- node4.before(node1);
-
- assert_equals(node1.nextSibling, parent1, type(node4) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node1.parent, parent2, 'Parent group of the inserted node should be changed');
- assert_equals(node1.previousSibling, parent1, 'Node should be inserted into the tree ' +
- 'before this node');
-
- assert_equals(parent1.nextSibling, node1, type(node4) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.previousSibling, node1, type(node4) + '.before() should insert ' +
- 'nodes before this node');
-
- assert_equals(node2.previousSibling, null, 'Inserted node should be removed from its ' +
- 'previous position in the tree');
- assert_array_equals(parent1.children, [node2], 'Inserted node should be removed from its ' +
- 'previous position in the tree');
- assert_array_equals(parent2.children, [node3, parent1, node1, node4], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.before() inserts node before this node. The previous position ' +
- 'of the inserted node is deeper in the tree than current node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3, parent1, node4]);
-
- node2.before(node4);
-
- assert_equals(node4.nextSibling, node2, type(node2) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.parent, parent1, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node1, type(node2) + '.before() should insert ' +
- 'nodes before this node');
-
- assert_equals(node1.nextSibling, node4, type(node2) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node2.previousSibling, node4, 'Node should be inserted into the tree ' +
- 'before this node');
-
- assert_equals(parent1.nextSibling, null, 'Inserted node should be removed from its ' +
- 'previous position in the tree');
- assert_array_equals(parent1.children, [node1, node4, node2], parentCtor.name +
- '.children should be updated');
- assert_array_equals(parent2.children, [node3, parent1], 'Inserted node should be ' +
- 'removed from its previous position in the tree');
- });
- });
-}, 'Test AnimationNode.before() inserts node before this node. The previous position ' +
- 'of the inserted node is shallower in the tree than current node, but not ancestor');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.before(node3, node4);
-
- assert_equals(node1.nextSibling, node3, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.previousSibling, node1, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.nextSibling, node4, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node3, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.nextSibling, node2, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node2.previousSibling, node4, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_array_equals(parent.children, [node1, node3, node4, node2], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.before() inserts several nodes before this node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.before(node3, node4, node3, node4);
-
- assert_equals(node1.nextSibling, node3, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.previousSibling, node1, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.nextSibling, node4, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node3, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.nextSibling, node2, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node2.previousSibling, node4, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_array_equals(parent.children, [node1, node3, node4, node2], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.before() inserts several nodes before this node, duplicate nodes are ignored');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.before(node3, node4, node3);
-
- assert_equals(node1.nextSibling, node4, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.previousSibling, node1, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.nextSibling, node3, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node4.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node3.previousSibling, node4, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.nextSibling, node2, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node2.previousSibling, node3, type(node1) + '.before() should insert ' +
- 'nodes before this node');
- assert_array_equals(parent.children, [node1, node4, node3, node2], parentCtor.name +
- '.children should be updated');
- });
- });
-}, 'Test AnimationNode.before() inserts several nodes before this node, check insertion order');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- var player = document.timeline.play(node2);
-
- assert_equals(player.source, node2, 'The node should be associated with its player');
- node1.before(node2);
- assert_equals(player.source, null, 'The node should be disassociated from its player');
- });
- });
-}, 'Test AnimationNode.before() disassociates the inserted node from the player, ' +
- 'if node is directly associated with a player');
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-next-sibling.html b/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-next-sibling.html
deleted file mode 100644
index a1cd7e94878..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-next-sibling.html
+++ /dev/null
@@ -1,503 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationNode nextSibling attribute tests</title>
-<meta name="assert" content="The next sibling of this animation node">
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animationnode-nextsibling">
-<link rel="help" href="http://www.w3.org/TR/dom/#concept-tree-next-sibling">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- assert_equals(node.nextSibling, null, type(node) + '.nextSibling should be null');
- });
-}, 'AnimationNode.nextSibling is null if the node is standalone');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_equals(node.nextSibling, null, type(node) + '.nextSibling ' +
- 'should be null');
- });
- });
-}, 'AnimationNode.nextSibling is null if the node is the only child of its parent');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- assert_equals(node1.nextSibling, node2, type(node1) + '.nextSibling should return ' +
- 'next sibling of this animation node');
- assert_equals(node2.nextSibling, null, type(node2) + '.nextSibling should be null');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node. Test first child');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- assert_equals(node1.nextSibling, node2, type(node1) + '.nextSibling should return ' +
- 'next sibling of this animation node');
- assert_equals(node2.nextSibling, null, type(node2) + '.nextSibling should be null');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node. Test second child');
-
-test(function() {
- var node1 = newAnimation(createDiv(this));
- var node2 = newAnimation(createDiv(this));
- var node3 = newAnimation(createDiv(this));
- var node4 = newAnimation(createDiv(this));
- var node5 = newAnimation(createDiv(this));
- var node6 = newAnimation(createDiv(this));
- var node7 = new AnimationGroup([node3, node4]);
- var node8 = new AnimationGroup([node5, node6]);
- var node9 = newAnimation(createDiv(this));
- var group = new AnimationGroup([node1, node2, node7, node8, node9]);
-
- assert_equals(group.nextSibling, null, 'AnimationNode.nextSibling should return ' +
- 'null (root node)');
- assert_equals(node1.nextSibling, node2, 'AnimationNode.nextSibling should return ' +
- 'next sibling for the first node in the group');
- assert_equals(node2.nextSibling, node7, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node');
- assert_equals(node3.nextSibling, node4, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (first node in the nested group)');
- assert_equals(node4.nextSibling, null, 'AnimationNode.nextSibling should be null ' +
- 'for the last node in the nested group');
- assert_equals(node5.nextSibling, node6, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (first node in the second nested group)');
- assert_equals(node6.nextSibling, null, 'AnimationNode.nextSibling should be null ' +
- 'for the last node in the second nested group');
- assert_equals(node7.nextSibling, node8, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (first nested group)');
- assert_equals(node8.nextSibling, node9, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (second nested group)');
- assert_equals(node9.nextSibling, null, 'AnimationNode.nextSibling should return ' +
- 'null (the last node)');
-}, 'AnimationNode.nextSibling returns next sibling of this animation node. Test ' +
- 'tree structure with AnimationGroup');
-
-test(function() {
- var node1 = newAnimation(createDiv(this));
- var node2 = newAnimation(createDiv(this));
- var node3 = newAnimation(createDiv(this));
- var node4 = newAnimation(createDiv(this));
- var node5 = newAnimation(createDiv(this));
- var node6 = newAnimation(createDiv(this));
- var node7 = new AnimationSequence([node3, node4]);
- var node8 = new AnimationSequence([node5, node6]);
- var node9 = newAnimation(createDiv(this));
- var sequence = new AnimationSequence([node1, node2, node7, node8, node9]);
-
- assert_equals(sequence.nextSibling, null, 'AnimationNode.nextSibling should return ' +
- 'null (root node)');
- assert_equals(node1.nextSibling, node2, 'AnimationNode.nextSibling should return ' +
- 'next sibling for the first node in the sequence');
- assert_equals(node2.nextSibling, node7, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node');
- assert_equals(node3.nextSibling, node4, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (first node in the nested sequence)');
- assert_equals(node4.nextSibling, null, 'AnimationNode.nextSibling should be null ' +
- 'for the last node in the nested sequence');
- assert_equals(node5.nextSibling, node6, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (first node in the second nested sequence)');
- assert_equals(node6.nextSibling, null, 'AnimationNode.nextSibling should be null ' +
- 'for the last node in the second nested sequence');
- assert_equals(node7.nextSibling, node8, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (first nested sequence)');
- assert_equals(node8.nextSibling, node9, 'AnimationNode.nextSibling should return ' +
- 'next sibling of this animation node (second nested sequence)');
- assert_equals(node9.nextSibling, null, 'AnimationNode.nextSibling should return ' +
- 'null (the last node)');
-}, 'AnimationNode.nextSibling returns next sibling of this animation node. Test ' +
- 'tree structure with AnimationSequence');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
- node2.before(node3);
-
- assert_equals(node1.nextSibling, node3, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node2, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is changed by method before()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node3) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- node3.before(node2);
-
- assert_equals(node1.nextSibling, null, type(node3) + '.before() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, node3, type(node3) + '.before() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is removed by method before()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = new AnimationGroup([]);
- var node5 = new AnimationSequence([]);
- var parent = new parentCtor([node1, node2]);
- node2.before(node3, node4, node5);
-
- assert_equals(node1.nextSibling, node3, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node4, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- assert_equals(node4.nextSibling, node5, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- assert_equals(node5.nextSibling, node2, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node2) + '.before() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'several nodes are added by method before()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
- node1.after(node3);
-
- assert_equals(node1.nextSibling, node3, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node2, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is changed by method after()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node3) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- node3.after(node2);
-
- assert_equals(node1.nextSibling, null, type(node3) + '.after() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node2, type(node3) + '.after() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is removed by method after()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = new AnimationGroup([]);
- var node5 = new AnimationSequence([]);
- var parent = new parentCtor([node1, node2]);
- node1.after(node3, node4, node5);
-
- assert_equals(node1.nextSibling, node3, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node4, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- assert_equals(node4.nextSibling, node5, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- assert_equals(node5.nextSibling, node2, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node1) + '.after() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'several nodes are added by method after()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2, node3]);
- node2.replace(node4);
-
- assert_equals(node1.nextSibling, node4, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node4.nextSibling, node3, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is changed by method replace()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node4) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2, node3]);
- var parent2 = new parentCtor([node4]);
-
- node4.replace(node2);
-
- assert_equals(node1.nextSibling, node3, type(node4) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node4) + '.replace() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is removed by method replace()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var node5 = new AnimationGroup([]);
- var node6 = new AnimationSequence([]);
- var parent = new parentCtor([node1, node2, node3]);
- node2.replace(node4, node5, node6);
-
- assert_equals(node1.nextSibling, node4, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node4.nextSibling, node5, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node5.nextSibling, node6, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node6.nextSibling, node3, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'several nodes are added by method replace()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2, node3]);
- node2.remove();
-
- assert_equals(node1.nextSibling, node3, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, type(node2) + '.replace() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is changed by method remove()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- parent.prepend(node2);
-
- assert_equals(node2.nextSibling, node1, parentCtor.name + '.prepend() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is changed by method AnimationGroup.prepend()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- parent2.prepend(node2);
-
- assert_equals(node1.nextSibling, null, parentCtor.name + '.prepend() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, node3, parentCtor.name + '.prepend() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is removed by method AnimationGroup.prepend()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var node1 = newAnimation(createDiv(test));
- var node2 = new AnimationGroup([]);
- var node3 = new AnimationSequence([]);
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- parent.prepend(node2, node3, node4);
-
- assert_equals(node2.nextSibling, node3, parentCtor.name + '.prepend() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node4, parentCtor.name + '.prepend() should update ' +
- 'next sibling of animation node');
- assert_equals(node4.nextSibling, node1, parentCtor.name + '.prepend() should update ' +
- 'next sibling of animation node');
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'several nodes are added by method AnimationGroup.prepend()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- parent.append(node2);
-
- assert_equals(node1.nextSibling, node2, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, null, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is changed by method AnimationGroup.append()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- parent2.append(node2);
-
- assert_equals(node1.nextSibling, null, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node2, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'the next sibling is removed by method AnimationGroup.append()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = new AnimationGroup([]);
- var node4 = new AnimationSequence([]);
- var parent = new parentCtor([node1]);
- parent.append(node2, node3, node4);
-
- assert_equals(node1.nextSibling, node2, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- assert_equals(node2.nextSibling, node3, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- assert_equals(node3.nextSibling, node4, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- assert_equals(node4.nextSibling, null, parentCtor.name + '.append() should update ' +
- 'next sibling of animation node');
- });
- });
-}, 'AnimationNode.nextSibling returns next sibling of this animation node, ' +
- 'several nodes are added by method AnimationGroup.append()');
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-parent.html b/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-parent.html
deleted file mode 100644
index 6e2ec65f914..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-parent.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationNode parent attribute tests</title>
-<meta name="assert" content="The parent animation group of this animation node or null if this animation node does not have a parent animation group">
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animationnode-parent">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- assert_equals(node.parent, null, type(node) + '.parent should be null');
- });
-}, 'AnimationNode.parent is null if animation node does not have a parent animation group');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_equals(node.parent, parent, type(node) + '.parent should return ' +
- 'parent animation group of this animation node');
- });
- });
-}, 'AnimationNode.parent returns parent animation group of this animation node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- var parent = new parentCtor([nodes[0], nodes[1], nodes[2]]);
- nodes.forEach(function(node) {
- assert_equals(node.parent, parent, type(node) + '.parent should return ' +
- 'parent animation group of this animation node');
- });
- });
-}, 'AnimationNode.parent returns parent animation group of this animation node. ' +
- 'The group has several children nodes');
-
-// The rest is tested in mutator methods: AnimationNode.before(), AnimationNode.after(),
-// AnimationNode.replace(), AnimationNode.remove(),
-// AnimationGroup.prepend(), AnimationGroup.append(), AnimationGroup.clone()
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-previous-sibling.html b/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-previous-sibling.html
deleted file mode 100644
index 60ed9e372aa..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-previous-sibling.html
+++ /dev/null
@@ -1,511 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationNode previousSibling attribute tests</title>
-<meta name="assert" content="The previous sibling of this animation node">
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animationnode-previoussibling">
-<link rel="help" href="http://www.w3.org/TR/dom/#concept-tree-previous-sibling">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-test(function() {
- var nodes = [
- newAnimation(createDiv(this)),
- new AnimationGroup([]),
- new AnimationSequence([])
- ];
- nodes.forEach(function(node) {
- assert_equals(node.previousSibling, null, type(node) + '.previousSibling should be null');
- });
-}, 'AnimationNode.previousSibling is null if the node is standalone');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_equals(node.previousSibling, null, type(node) + '.previousSibling ' +
- 'should be null');
- });
- });
-}, 'AnimationNode.previousSibling is null if the node is the only child of its parent');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- assert_equals(node1.previousSibling, null, type(node1) + '.previousSibling should be null');
- assert_equals(node2.previousSibling, node1, type(node2) + '.previousSibling should return ' +
- 'previous sibling of this animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node. Test first child');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- assert_equals(node1.previousSibling, null, type(node1) + '.previousSibling should be null');
- assert_equals(node2.previousSibling, node1, type(node2) + '.previousSibling should return ' +
- 'previous sibling of this animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node. Test second child');
-
-test(function() {
- var node1 = newAnimation(createDiv(this));
- var node2 = newAnimation(createDiv(this));
- var node3 = newAnimation(createDiv(this));
- var node4 = newAnimation(createDiv(this));
- var node5 = newAnimation(createDiv(this));
- var node6 = newAnimation(createDiv(this));
- var node7 = new AnimationGroup([node3, node4]);
- var node8 = new AnimationGroup([node5, node6]);
- var node9 = newAnimation(createDiv(this));
- var group = new AnimationGroup([node1, node2, node7, node8, node9]);
-
- assert_equals(group.previousSibling, null, 'AnimationNode.previousSibling should return ' +
- 'null (root node)');
- assert_equals(node1.previousSibling, null, 'AnimationNode.previousSibling should return ' +
- 'null for the first node in the group');
- assert_equals(node2.previousSibling, node1, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node');
- assert_equals(node3.previousSibling, null, 'AnimationNode.previousSibling should be null ' +
- 'for the first node in the nested group');
- assert_equals(node4.previousSibling, node3, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (first node in the nested group)');
- assert_equals(node5.previousSibling, null, 'AnimationNode.previousSibling should be null ' +
- 'for the first node in the second nested group');
- assert_equals(node6.previousSibling, node5, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (first node in the second nested group)');
- assert_equals(node7.previousSibling, node2, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (first nested group)');
- assert_equals(node8.previousSibling, node7, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (second nested group)');
- assert_equals(node9.previousSibling, node8, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node');
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node. Test ' +
- 'tree structure with AnimationGroup');
-
-test(function() {
- var node1 = newAnimation(createDiv(this));
- var node2 = newAnimation(createDiv(this));
- var node3 = newAnimation(createDiv(this));
- var node4 = newAnimation(createDiv(this));
- var node5 = newAnimation(createDiv(this));
- var node6 = newAnimation(createDiv(this));
- var node7 = new AnimationSequence([node3, node4]);
- var node8 = new AnimationSequence([node5, node6]);
- var node9 = newAnimation(createDiv(this));
- var sequence = new AnimationSequence([node1, node2, node7, node8, node9]);
-
- assert_equals(sequence.previousSibling, null, 'AnimationNode.previousSibling should return ' +
- 'null (root node)');
- assert_equals(node1.previousSibling, null, 'AnimationNode.previousSibling should return ' +
- 'null for the first node in the group');
- assert_equals(node2.previousSibling, node1, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node');
- assert_equals(node3.previousSibling, null, 'AnimationNode.previousSibling should be null ' +
- 'for the first node in the nested group');
- assert_equals(node4.previousSibling, node3, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (first node in the nested group)');
- assert_equals(node5.previousSibling, null, 'AnimationNode.previousSibling should be null ' +
- 'for the first node in the second nested group');
- assert_equals(node6.previousSibling, node5, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (first node in the second nested group)');
- assert_equals(node7.previousSibling, node2, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (first nested group)');
- assert_equals(node8.previousSibling, node7, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node (second nested group)');
- assert_equals(node9.previousSibling, node8, 'AnimationNode.previousSibling should return ' +
- 'previous sibling of this animation node');
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node. Test ' +
- 'tree structure with AnimationSequence');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
- node2.before(node3);
-
- assert_equals(node1.previousSibling, null, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node1, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, node3, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is changed by method before()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node3) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- node3.before(node1);
-
- assert_equals(node1.previousSibling, null, type(node3) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, null, type(node3) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node1, type(node3) + '.before() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is removed by method before()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = new AnimationGroup([]);
- var node5 = new AnimationSequence([]);
- var parent = new parentCtor([node1, node2]);
- node2.before(node3, node4, node5);
-
- assert_equals(node1.previousSibling, null, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node1, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node4.previousSibling, node3, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node5.previousSibling, node4, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, node5, type(node2) + '.before() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'several nodes are added by method before()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
- node1.after(node3);
-
- assert_equals(node1.previousSibling, null, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node1, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, node3, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is changed by method after()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node3) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- node3.after(node1);
-
- assert_equals(node1.previousSibling, node3, type(node3) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, null, type(node3) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, null, type(node3) + '.after() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is removed by method after()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = new AnimationGroup([]);
- var node5 = new AnimationSequence([]);
- var parent = new parentCtor([node1, node2]);
- node1.after(node3, node4, node5);
-
- assert_equals(node1.previousSibling, null, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node1, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node4.previousSibling, node3, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node5.previousSibling, node4, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, node5, type(node1) + '.after() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'several nodes are added by method after()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2, node3]);
- node2.replace(node4);
-
- assert_equals(node4.previousSibling, node1, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, null, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node4, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is changed by method replace()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node4) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2, node3]);
- var parent2 = new parentCtor([node4]);
-
- node4.replace(node2);
-
- assert_equals(node3.previousSibling, node1, type(node4) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, null, type(node4) + '.replace() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is removed by method replace()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var node5 = new AnimationGroup([]);
- var node6 = new AnimationSequence([]);
- var parent = new parentCtor([node1, node2, node3]);
- node2.replace(node4, node5, node6);
-
- assert_equals(node4.previousSibling, node1, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node5.previousSibling, node4, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node6.previousSibling, node5, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node6, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, null, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'several nodes are added by method replace()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2, node3]);
- node2.remove();
-
- assert_equals(node3.previousSibling, node1, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, null, type(node2) + '.replace() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is changed by method remove()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- parent.prepend(node2);
-
- assert_equals(node1.previousSibling, node2, parentCtor.name + '.prepend() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is changed by method AnimationGroup.prepend()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- parent2.prepend(node1);
-
- assert_equals(node2.previousSibling, null, parentCtor.name + '.prepend() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node1, parentCtor.name + '.prepend() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is removed by method AnimationGroup.prepend()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var node1 = newAnimation(createDiv(test));
- var node2 = new AnimationGroup([]);
- var node3 = new AnimationSequence([]);
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- parent.prepend(node2, node3, node4);
-
- assert_equals(node2.previousSibling, null, parentCtor.name + '.prepend() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node2, parentCtor.name + '.prepend() should update ' +
- 'previous sibling of animation node');
- assert_equals(node4.previousSibling, node3, parentCtor.name + '.prepend() should update ' +
- 'previous sibling of animation node');
- assert_equals(node1.previousSibling, node4, parentCtor.name + '.prepend() should update ' +
- 'previous sibling of animation node');
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'several nodes are added by method AnimationGroup.prepend()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- parent.append(node2);
-
- assert_equals(node1.previousSibling, null, parentCtor.name + '.append() should update ' +
- 'previous sibling of animation node');
- assert_equals(node2.previousSibling, node1, parentCtor.name + '.append() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is changed by method AnimationGroup.append()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3]);
-
- parent2.append(node1);
-
- assert_equals(node2.previousSibling, null, parentCtor.name + '.append() should update ' +
- 'previous sibling of animation node');
- assert_equals(node1.previousSibling, node3, parentCtor.name + '.append() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'the previous sibling is removed by method AnimationGroup.append()');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var node3 = new AnimationGroup([]);
- var node4 = new AnimationSequence([]);
- var parent = new parentCtor([node1]);
- parent.append(node2, node3, node4);
-
- assert_equals(node2.previousSibling, node1, parentCtor.name + '.append() should update ' +
- 'previous sibling of animation node');
- assert_equals(node3.previousSibling, node2, parentCtor.name + '.append() should update ' +
- 'previous sibling of animation node');
- assert_equals(node4.previousSibling, node3, parentCtor.name + '.append() should update ' +
- 'previous sibling of animation node');
- });
- });
-}, 'AnimationNode.previousSibling returns previous sibling of this animation node, ' +
- 'several nodes are added by method AnimationGroup.append()');
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-remove.html b/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-remove.html
deleted file mode 100644
index 5ded75c1bfd..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-remove.html
+++ /dev/null
@@ -1,239 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationNode remove() method tests</title>
-<meta name="assert" content="Removes this animation node from its parent animation group or player">
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animationnode-remove">
-<link rel="help" href="http://w3c.github.io/web-animations/#remove-an-animation-node">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- node.remove();
-
- assert_equals(node.parent, null, type(node) + ' node parent attribute should be null');
- });
-}, 'AnimationNode.remove() does nothing for standalone node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
- node.remove();
-
- assert_array_equals(parent.children, [], type(node) +
- ' node should be removed from the parent ' + parentCtor.name);
- assert_equals(node.parent, null, type(node) +
- ' node parent attribute should be updated');
- });
- });
-}, 'AnimationNode.remove() removes node from the parent animation group. ' +
- 'Removed node is the only node in the tree');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node1.remove();
-
- assert_array_equals(parent.children, [node2], type(node1) +
- ' node should be removed from the parent ' + parentCtor.name);
- assert_equals(parent.firstChild, node2, 'Parent ' + parentCtor.name +
- ' firstChild attribute should be updated');
- assert_equals(node1.parent, null, 'Removed ' + type(node1) +
- ' node parent attribute should be updated');
- assert_equals(node1.nextSibling, null, 'Removed ' + type(node1) +
- ' node nextSibling attribute should be updated');
- assert_equals(node2.previousSibling, null,
- 'Remaining node previousSibling attribute should be updated');
- });
- });
-}, 'AnimationNode.remove() removes node from the parent animation group. ' +
- 'Remove the first node in the group');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.remove();
-
- assert_array_equals(parent.children, [node1], type(node2) +
- ' node should be removed from the parent ' + parentCtor.name);
- assert_equals(parent.lastChild, node1, 'Parent ' + parentCtor.name +
- ' lastChild attribute should be updated');
- assert_equals(node2.parent, null, 'Removed ' + type(node2) +
- ' node parent attribute should be updated');
- assert_equals(node1.nextSibling, null,
- 'Remaining node nextSibling attribute should be updated');
- assert_equals(node2.previousSibling, null, 'Removed ' + type(node2) +
- ' node previousSibling attribute should be updated');
- });
- });
-}, 'AnimationNode.remove() removes node from the parent animation group. ' +
- 'Remove the last node in the group');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2, node3]);
-
- node2.remove();
-
- assert_array_equals(parent.children, [node1, node3], type(node2) +
- ' node should be removed from the parent ' + parentCtor.name);
- assert_equals(node2.parent, null, 'Removed ' + type(node2) +
- ' node parent attribute should be updated');
- assert_equals(node2.nextSibling, null, 'Removed ' + type(node2) +
- ' node nextSibling attribute should be updated');
- assert_equals(node2.previousSibling, null, 'Removed ' + type(node2) +
- ' node previousSibling attribute should be updated');
- assert_equals(node1.nextSibling, node3,
- 'Remaining node nextSibling attribute should be updated');
- assert_equals(node3.previousSibling, node1,
- 'Remaining node previousSibling attribute should be updated');
- });
- });
-}, 'AnimationNode.remove() removes node from the parent animation group. ' +
- 'Remove node from the middle of the group');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- parents.forEach(function(nodeCtor) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = new nodeCtor([node1, node2]);
- var node5 = newAnimation(createDiv(test));
- var parent = new parentCtor([node3, node4, node5]);
-
- node4.remove();
-
- assert_array_equals(node4.children, [node1, node2], 'Removed ' +
- type(node4) + ' node children should not be changed');
- assert_array_equals(parent.children, [node3, node5], type(node4) +
- ' node should be removed from the parent ' + parentCtor.name);
- assert_equals(node4.parent, null, 'Removed ' + type(node2) +
- ' node parent attribute should be updated');
- assert_equals(node4.nextSibling, null, 'Removed ' + type(node2) +
- ' node nextSibling attribute should be updated');
- assert_equals(node4.previousSibling, null, 'Removed ' + type(node2) +
- ' node previousSibling attribute should be updated');
- assert_equals(node3.nextSibling, node5,
- 'Remaining node nextSibling attribute should be updated');
- assert_equals(node5.previousSibling, node3,
- 'Remaining node previousSibling attribute should be updated');
- });
- });
-}, 'Test removing a node that has children');
-
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var player = document.timeline.play(node);
- node.remove();
-
- assert_equals(player.source, null, type(node) +
- ' node should be disassociated from the player');
- });
-}, 'AnimationNode.remove() disassociates the node from player, ' +
- 'if node is directly associated with a player');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2, node3]);
- var player = document.timeline.play(parent);
-
- node2.remove();
-
- assert_equals(player.source, parent, type(node2) +
- ' parent node should remain associated with the player');
- });
- });
-}, 'AnimationNode.remove() keeps parent direct association with the player');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- parents.forEach(function(nodeCtor) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var node5 = new parentCtor([node4]);
- var group1 = new AnimationGroup([node3, node5]);
- var node6 = newAnimation(createDiv(test));
- var node7 = new parentCtor([node6]);
- var node8 = newAnimation(createDiv(test));
- var sequence1 = new AnimationSequence([node7,node8]);
- var node9 = new nodeCtor([node1, group1, node2, sequence1]);
- var node10 = newAnimation(createDiv(test));
- var parent = new parentCtor([node9, node10]);
-
- node9.remove();
-
- assert_equals(node9.parent, null, 'Removed ' + type(node9) +
- ' node parent attribute should be updated');
- assert_array_equals(node9.children, [node1, group1, node2, sequence1],
- 'Removed ' + type(node9) + ' node children should not be changed');
- for (var i = 0; i < node9.children.length; i++) {
- assert_equals(node9.children[i].parent, node9, 'Removed ' + type(node9) +
- ' node children parent attribute should not be changed for child ' + i);
- }
- assert_array_equals(group1.children, [node3, node5],
- 'Removed ' + type(node9) + ' node grand children should not be changed');
- for (var i = 0; i < group1.children.length; i++) {
- assert_equals(group1.children[i].parent, group1, 'Removed ' + type(node9) +
- ' node grand children parent attribute should not be changed for child ' + i);
- }
- assert_array_equals(sequence1.children, [node7,node8],
- 'Removed ' + type(node9) + ' node grand children should not be changed');
- for (var i = 0; i < sequence1.children.length; i++) {
- assert_equals(sequence1.children[i].parent, sequence1, 'Removed ' + type(node9) +
- ' node grand children parent attribute should not be changed for child ' + i);
- }
- assert_array_equals(node5.children, [node4],
- 'Removed ' + type(node9) + ' node grand children should not be changed');
- assert_equals(node4.parent, node5, 'Removed ' + type(node9) +
- ' node grand children parent attribute should not be changed');
- assert_array_equals(node7.children, [node6],
- 'Removed ' + type(node9) + ' node grand children should not be changed');
- assert_equals(node6.parent, node7, 'Removed ' + type(node9) +
- ' node grand children parent attribute should not be changed');
- });
- });
-}, 'AnimationNode.remove() on the root of a non-trivial tree does not change child structure');
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-replace.html b/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-replace.html
deleted file mode 100644
index a4bbbe77313..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/animation-node-replace.html
+++ /dev/null
@@ -1,444 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>AnimationNode replace() method tests</title>
-<meta name="assert" content="Replaces this AnimationNode with the passed in nodes parameter">
-<link rel="help" href="http://w3c.github.io/web-animations/#dom-animationnode-replace">
-<link rel="help" href="http://w3c.github.io/web-animations/#remove-an-animation-node">
-<link rel="help" href="http://w3c.github.io/web-animations/#insert-children">
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="../testcommon.js"></script>
-<body>
-<div id="log"></div>
-<script>
-// Step 1. If there is no parent animation group, terminate these steps.
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- try {
- node.replace(null);
- } catch(e) {
- assert_unreached(type(node) + '.replace(null) throws unexpected exception: ' + e);
- }
- });
-}, 'AnimationNode.replace(null) does nothing if node has no parent animation group');
-
-test(function() {
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- try {
- node.replace(node);
- } catch(e) {
- assert_unreached(type(node) + '.replace(node) throws unexpected exception: ' + e);
- }
- });
-}, 'AnimationNode.replace() does nothing if node has no parent animation group. ' +
- 'HierarchyRequestError is not thrown if the node is replacing itself');
-
-test(function() {
- var test = this;
- var nodes = [newAnimation(createDiv(this)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
-
- try {
- node1.replace(node2);
- } catch(e) {
- assert_unreached(type(node1) + '.replace() throws unexpected exception: ' + e);
- }
- });
-}, 'AnimationNode.replace() does nothing if node has no parent animation group');
-
-// Step 2. If any of the animation nodes in nodes is an inclusive ancestor
-// of the parent animation group throw a HierarchyRequestError exception and terminate these steps.
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_throws('HierarchyRequestError', function() {
- node.replace(node);
- }, 'HierarchyRequestError should be thrown if ' + type(node) +
- ' replaces itself');
- assert_equals(node.parent, parent, type(node) + '.replace() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent.children, [node], type(node) + '.replace() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if the node replaces itself');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- assert_throws('HierarchyRequestError', function() {
- node.replace(parent);
- }, 'HierarchyRequestError should be thrown if ' + type(node) +
- ' is replaced by its parent ' + parentCtor.name);
- assert_equals(node.parent, parent, type(node) + '.replace() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent.children, [node], type(node) + '.replace() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if the node is replaced by its parent');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent1 = new parentCtor([node]);
- var parent2 = new parentCtor([parent1]);
- var parent3 = new parentCtor([parent2]);
- var parent4 = new parentCtor([parent3]);
-
- assert_throws('HierarchyRequestError', function() {
- node.replace(parent3);
- }, 'HierarchyRequestError should be thrown if ' + type(node) +
- ' is replaced by its inclusive ancestor' + parentCtor.name);
- assert_equals(node.parent, parent1, type(node) + '.replace() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent1.children, [node], type(node) + '.replace() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- assert_equals(parent3.parent, parent4, type(node) + '.replace() should not change ' +
- 'parent attribute of replacement node before throwing HierarchyRequestError');
- assert_array_equals(parent4.children, [parent3], type(node) + '.replace() ' +
- 'should not change replacement node parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if the node is replaced by its inclusive ancestor');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var parent1 = new parentCtor([node1]);
- var parent2 = new parentCtor([parent1]);
- var parent3 = new parentCtor([parent2]);
- var parent4 = new parentCtor([parent3]);
- var node2 = newAnimation(createDiv(test));
- var parent5 = new parentCtor([node2]);
-
- assert_throws('HierarchyRequestError', function() {
- node1.replace(node2, parent3);
- }, 'HierarchyRequestError should be thrown if ' + type(node1) +
- ' is replaced by its inclusive ancestor' + parentCtor.name);
- assert_equals(node1.parent, parent1, type(node1) + '.replace() should not change ' +
- 'parent attribute before throwing HierarchyRequestError');
- assert_array_equals(parent1.children, [node1], type(node1) + '.replace() ' +
- 'should not change parent children before throwing HierarchyRequestError');
- assert_equals(parent3.parent, parent4, type(node1) + '.replace() should not change ' +
- 'parent attribute of replacement node before throwing HierarchyRequestError');
- assert_array_equals(parent4.children, [parent3], type(node1) + '.replace() ' +
- 'should not change replacement node parent children before throwing HierarchyRequestError');
- assert_equals(node2.parent, parent5, type(node1) + '.replace() should not change ' +
- 'parent attribute of replacement node before throwing HierarchyRequestError');
- assert_array_equals(parent5.children, [node2], type(node1) + '.replace() ' +
- 'should not change replacement node parent children before throwing HierarchyRequestError');
- });
- });
-}, 'HierarchyRequestError is thrown if node is replaced by its inclusive ancestor. ' +
- 'Test several arguments in replace() call');
-
-// Step 3. Let reference child be the next sibling of this animation node not in nodes.
-// Step 4. Remove this animation node from its parent animation group.
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node) {
- var parent = new parentCtor([node]);
-
- node.replace();
-
- assert_array_equals(parent.children, [], type(node) +
- ' node should be removed from parent ' + parentCtor.name);
- assert_equals(node.parent, null, type(node) +
- ' node parent attribute should be updated');
- });
- });
-}, 'AnimationNode.replace() without arguments removes the node from the parent ' +
- 'animation group');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
-
- node1.replace(node2);
-
- assert_array_equals(parent.children, [node2], type(node1) +
- ' node should be removed its parent group');
- assert_equals(node1.parent, null, type(node1) +
- ' node should be removed from its parent group');
- assert_equals(node1.previousSibling, null, type(node1) +
- ' node previousSibling attribute should be updated');
- assert_equals(node1.nextSibling, null, type(node1) +
- ' node nextSibling attribute should be updated');
- });
- });
-}, 'AnimationNode.replace() removes the node from its parent animation group');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2, node3]);
-
- node2.replace(node3);
-
- assert_array_equals(parent.children, [node1,node3], type(node2) +
- ' node should be removed from parent ' + parentCtor.name);
- assert_equals(node2.parent, null, type(node2) +
- ' node parent attribute should be updated');
- assert_equals(node2.nextSibling, null, type(node2) +
- ' node nextSibling attribute should be updated');
- assert_equals(node2.previousSibling, null, type(node2) +
- ' node previousSibling attribute should be updated');
- assert_equals(node1.nextSibling, node3,
- 'Sibling node nextSibling attribute should be updated');
- assert_equals(node3.previousSibling, node1,
- 'Sibling node previousSibling attribute should be updated');
- });
- });
-}, 'AnimationNode.replace(next sibling) removes the node from its parent ' +
- 'animation group');
-
-// Step 5. Insert nodes before reference child.
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
-
- node1.replace(node2);
-
- assert_array_equals(parent.children, [node2], type(node1) +
- ' node should be replaced');
- assert_equals(node2.parent, parent,
- 'Replacement node should be assigned to a parent group');
- });
- });
-}, 'AnimationNode.replace() replaces node in the parent animation group');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node4) {
- var node1 = newAnimation(createDiv(test));
- var node2 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3, parent1, node4]);
-
- node4.replace(node1);
-
- assert_array_equals(parent1.children, [node2],
- 'Replacement node should be removed from its previous position in the tree');
- assert_array_equals(parent2.children, [node3, parent1, node1],
- 'Replacement node should be inserted into the new position');
- assert_equals(node1.parent, parent2, 'Inserted node parent group should be assigned');
- assert_equals(node1.previousSibling, parent1,
- 'Inserted node previousSibling attribute should be updated');
- assert_equals(node1.nextSibling, null,
- 'Inserted node nextSibling attribute should be updated');
-
- assert_equals(node4.parent, null, 'Node should be removed from its parent group');
- assert_equals(node4.previousSibling, null,
- 'Replaced node previousSibling attribute should be updated');
- assert_equals(node4.nextSibling, null,
- 'Replaced node nextSibling attribute should be updated');
- });
- });
-}, 'Test AnimationNode.replace() replaces given node. The previous position ' +
- 'of the replacement node is deeper in the tree than the current node');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent1 = new parentCtor([node1, node2]);
- var parent2 = new parentCtor([node3, parent1, node4]);
-
- node2.replace(node4);
-
- assert_array_equals(parent1.children, [node1, node4],
- 'Replacement node should be inserted to the new position');
- assert_array_equals(parent2.children, [node3, parent1],
- 'Replacement node should be removed from its previous position in the tree');
- assert_equals(node4.parent, parent1, 'Inserted node parent group should be changed');
- assert_equals(node4.previousSibling, node1,
- 'Inserted node previousSibling attribute should be updated');
- assert_equals(node1.nextSibling, node4,
- 'Inserted node sibling nextSibling attribute should be updated');
-
- assert_equals(node2.parent, null, 'Replaced node parent group should be changed');
- assert_equals(node2.previousSibling, null,
- 'Replaced node previousSibling attribute should be updated');
- assert_equals(node2.nextSibling, null, 'Replaced node nextSibling attribute ' +
- 'should be updated');
- });
- });
-}, 'Test AnimationNode.replace() replaces given node. The previous position ' +
- 'of the replacement node is shallower in the tree than current node, but is not an ancestor');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.replace(node3, node4);
-
- assert_array_equals(parent.children, [node1, node3, node4], type(node2) + '.replace() ' +
- 'should replace the current node by ones passed in arguments');
- assert_equals(node1.nextSibling, node3, 'nextSibling attribute should be updated');
- assert_equals(node3.previousSibling, node1, 'Inserted node previousSibling attribute ' +
- 'should be updated');
- assert_equals(node3.nextSibling, node4, 'Inserted node nextSibling attribute ' +
- 'should be updated');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node3, 'Inserted node previousSibling attribute ' +
- 'should be updated');
- assert_equals(node4.nextSibling, null, 'Inserted node nextSibling attribute ' +
- 'should be updated');
- assert_equals(node4.parent, parent, 'Parent group of the second inserted node ' +
- 'should be changed');
- assert_equals(node2.parent, null, 'Replaced node parent group should be changed');
- assert_equals(node2.previousSibling, null,
- 'Replaced node previousSibling attribute should be updated');
- assert_equals(node2.nextSibling, null, 'Replaced node nextSibling attribute ' +
- 'should be updated');
- });
- });
-}, 'Test AnimationNode.replace() replaces given node. Test several arguments');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.replace(node3, node4, node3, node4);
-
- assert_array_equals(parent.children, [node1, node3, node4], type(node2) + '.replace() ' +
- 'should replace the current node by ones passed in arguments');
- assert_equals(node1.nextSibling, node3, 'nextSibling attribute should be updated');
- assert_equals(node3.previousSibling, node1, 'Inserted node previousSibling attribute ' +
- 'should be updated');
- assert_equals(node3.nextSibling, node4, 'Inserted node nextSibling attribute ' +
- 'should be updated');
- assert_equals(node3.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node4.previousSibling, node3, 'Inserted node previousSibling attribute ' +
- 'should be updated');
- assert_equals(node4.nextSibling, null, 'Inserted node nextSibling attribute ' +
- 'should be updated');
- assert_equals(node4.parent, parent, 'Parent group of the second inserted node ' +
- 'should be changed');
- assert_equals(node2.parent, null, 'Replaced node parent group should be changed');
- assert_equals(node2.previousSibling, null,
- 'Replaced node previousSibling attribute should be updated');
- assert_equals(node2.nextSibling, null, 'Replaced node nextSibling attribute ' +
- 'should be updated');
- });
- });
-}, 'Test AnimationNode.replace() replaces given node by several nodes, duplicate nodes are ignored');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node2) {
- var node1 = newAnimation(createDiv(test));
- var node3 = newAnimation(createDiv(test));
- var node4 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1, node2]);
-
- node2.replace(node3, node4, node3);
-
- assert_array_equals(parent.children, [node1, node4, node3], type(node2) + '.replace() ' +
- 'should replace the current node by ones passed in arguments');
- assert_equals(node1.nextSibling, node4, 'nextSibling attribute should be updated');
- assert_equals(node4.previousSibling, node1, 'Inserted node previousSibling attribute ' +
- 'should be updated');
- assert_equals(node4.nextSibling, node3, 'Inserted node nextSibling attribute ' +
- 'should be updated');
- assert_equals(node4.parent, parent, 'Parent group of the inserted node should be changed');
- assert_equals(node3.previousSibling, node4, 'Inserted node previousSibling attribute ' +
- 'should be updated');
- assert_equals(node3.nextSibling, null, 'Inserted node nextSibling attribute ' +
- 'should be updated');
- assert_equals(node3.parent, parent, 'Parent group of the second inserted node ' +
- 'should be changed');
- assert_equals(node2.parent, null, 'Replaced node parent group should be changed');
- assert_equals(node2.previousSibling, null,
- 'Replaced node previousSibling attribute should be updated');
- assert_equals(node2.nextSibling, null, 'Replaced node nextSibling attribute ' +
- 'should be updated');
- });
- });
-}, 'Test AnimationNode.replace() replaces given node by several nodes, check replacement order');
-
-test(function() {
- var test = this;
- var parents = [AnimationGroup, AnimationSequence];
- parents.forEach(function(parentCtor) {
- var nodes = [newAnimation(createDiv(test)), new AnimationGroup([]), new AnimationSequence([])];
- nodes.forEach(function(node1) {
- var node2 = newAnimation(createDiv(test));
- var parent = new parentCtor([node1]);
- var player = document.timeline.play(node2);
-
- assert_equals(player.source, node2, 'The node should be associated with its player');
- node1.replace(node2);
- assert_equals(player.source, null, 'The node should be disassociated from its player');
- });
- });
-}, 'Test AnimationNode.replace() disassociates the inserted node from the player, ' +
- 'if node is directly associated with a player');
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation-node/idlharness.html b/tests/wpt/web-platform-tests/web-animations/animation-node/idlharness.html
deleted file mode 100644
index bfa23b22204..00000000000
--- a/tests/wpt/web-platform-tests/web-animations/animation-node/idlharness.html
+++ /dev/null
@@ -1,54 +0,0 @@
-<!doctype html>
-<meta charset=utf-8>
-<title>AnimationNode IDL tests</title>
-<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
-<link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/WebIDLParser.js"></script>
-<script src="/resources/idlharness.js"></script>
-<body>
-<div id="log"></div>
-<div id="target"></div>
-<script type="text/plain" id="untested-IDL">
-interface AnimationPlayer {
-};
-
-interface AnimationTiming {
-};
-
-interface ComputedTimingProperties {
-};
-
-interface AnimationGroup {
-};
-</script>
-<script type="text/plain" id="AnimationNode-IDL">
-interface AnimationNode {
- // Timing
- readonly attribute AnimationTiming timing;
- readonly attribute ComputedTimingProperties computedTiming;
-
- // Timing hierarchy
- readonly attribute AnimationGroup? parent;
- readonly attribute AnimationNode? previousSibling;
- readonly attribute AnimationNode? nextSibling;
- void before (AnimationNode... nodes);
- void after (AnimationNode... nodes);
- void replace (AnimationNode... nodes);
- void remove ();
-};
-</script>
-<script>
-'use strict';
-
-var target = document.getElementById('target');
-var node = new Animation(target, [], 5);
-
-var idlArray = new IdlArray();
-idlArray.add_untested_idls(document.getElementById('untested-IDL').textContent);
-idlArray.add_idls(document.getElementById('AnimationNode-IDL').textContent);
-idlArray.add_objects( { AnimationNode: ['node'] } );
-idlArray.test();
-</script>
-</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/cancel.html b/tests/wpt/web-platform-tests/web-animations/animation/cancel.html
new file mode 100644
index 00000000000..992e41676e7
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/cancel.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.cancel()</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-cancel">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({transform: ['none', 'translate(100px)']},
+ 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ assert_not_equals(getComputedStyle(div).transform, 'none',
+ 'transform style is animated before cancelling');
+ animation.cancel();
+ assert_equals(getComputedStyle(div).transform, 'none',
+ 'transform style is no longer animated after cancelling');
+ });
+}, 'Animated style is cleared after calling Animation.cancel()');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({marginLeft: ['0px', '100px']},
+ 100 * MS_PER_SEC);
+ animation.effect.timing.easing = 'linear';
+ animation.cancel();
+ assert_equals(getComputedStyle(div).marginLeft, '0px',
+ 'margin-left style is not animated after cancelling');
+
+ animation.currentTime = 50 * MS_PER_SEC;
+ assert_equals(getComputedStyle(div).marginLeft, '50px',
+ 'margin-left style is updated when cancelled animation is'
+ + ' seeked');
+}, 'After cancelling an animation, it can still be seeked');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({marginLeft:['100px', '200px']},
+ 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.cancel();
+ assert_equals(getComputedStyle(div).marginLeft, '0px',
+ 'margin-left style is not animated after cancelling');
+ animation.play();
+ assert_equals(getComputedStyle(div).marginLeft, '100px',
+ 'margin-left style is animated after re-starting animation');
+ return animation.ready;
+ }).then(function() {
+ assert_equals(animation.playState, 'running',
+ 'Animation succeeds in running after being re-started');
+ });
+}, 'After cancelling an animation, it can still be re-used');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/finish.html b/tests/wpt/web-platform-tests/web-animations/animation/finish.html
new file mode 100644
index 00000000000..35bd7b0d0b0
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/finish.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.finish()</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-finish">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+var gKeyFrames = { 'marginLeft': ['100px', '200px'] };
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.playbackRate = 0;
+
+ assert_throws({name: 'InvalidStateError'}, function() {
+ animation.finish();
+ });
+}, 'Test exceptions when finishing non-running animation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames,
+ {duration : 100 * MS_PER_SEC,
+ iterations : Infinity});
+
+ assert_throws({name: 'InvalidStateError'}, function() {
+ animation.finish();
+ });
+}, 'Test exceptions when finishing infinite animation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.finish();
+
+ assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+ 'After finishing, the currentTime should be set to the end ' +
+ 'of the active duration');
+}, 'Test finishing of animation');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ // 1s past effect end
+ animation.currentTime =
+ animation.effect.getComputedTiming().endTime + 1 * MS_PER_SEC;
+ animation.finish();
+
+ assert_equals(animation.currentTime, 100 * MS_PER_SEC,
+ 'After finishing, the currentTime should be set back to the ' +
+ 'end of the active duration');
+}, 'Test finishing of animation with a current time past the effect end');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.currentTime = 100 * MS_PER_SEC;
+ return animation.finished.then(function() {
+ animation.playbackRate = -1;
+ animation.finish();
+
+ assert_equals(animation.currentTime, 0,
+ 'After finishing a reversed animation the currentTime ' +
+ 'should be set to zero');
+ });
+}, 'Test finishing of reversed animation');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.currentTime = 100 * MS_PER_SEC;
+ return animation.finished.then(function() {
+ animation.playbackRate = -1;
+ animation.currentTime = -1000;
+ animation.finish();
+
+ assert_equals(animation.currentTime, 0,
+ 'After finishing a reversed animation the currentTime ' +
+ 'should be set back to zero');
+ });
+}, 'Test finishing of reversed animation with a current time less than zero');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.pause();
+ return animation.ready.then(function() {
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a paused animation should become ' +
+ '"finished" after finish() is called');
+ assert_approx_equals(animation.startTime,
+ animation.timeline.currentTime - 100 * MS_PER_SEC,
+ 0.0001,
+ 'The start time of a paused animation should be set ' +
+ 'after calling finish()');
+ });
+}, 'Test finish() while paused');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.pause();
+ // Update playbackRate so we can test that the calculated startTime
+ // respects it
+ animation.playbackRate = 2;
+ // While animation is still pause-pending call finish()
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a pause-pending animation should become ' +
+ '"finished" after finish() is called');
+ assert_approx_equals(animation.startTime,
+ animation.timeline.currentTime - 100 * MS_PER_SEC / 2,
+ 0.0001,
+ 'The start time of a pause-pending animation should ' +
+ 'be set after calling finish()');
+}, 'Test finish() while pause-pending with positive playbackRate');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.pause();
+ animation.playbackRate = -2;
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a pause-pending animation should become ' +
+ '"finished" after finish() is called');
+ assert_equals(animation.startTime, animation.timeline.currentTime,
+ 'The start time of a pause-pending animation should be ' +
+ 'set after calling finish()');
+}, 'Test finish() while pause-pending with negative playbackRate');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ animation.playbackRate = 0.5;
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'The play state of a play-pending animation should become ' +
+ '"finished" after finish() is called');
+ assert_approx_equals(animation.startTime,
+ animation.timeline.currentTime - 100 * MS_PER_SEC / 0.5,
+ 0.0001,
+ 'The start time of a play-pending animation should ' +
+ 'be set after calling finish()');
+}, 'Test finish() while play-pending');
+
+// FIXME: Add a test for when we are play-pending without an active timeline.
+// - In that case even after calling finish() we should still be pending but
+// the current time should be updated
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.pause();
+ animation.play();
+ // We are now in the unusual situation of being play-pending whilst having
+ // a resolved start time. Check that finish() still triggers a transition
+ // to the finished state immediately.
+ animation.finish();
+
+ assert_equals(animation.playState, 'finished',
+ 'After aborting a pause then calling finish() the play ' +
+ 'state of an animation should become "finished" immediately');
+ });
+}, 'Test finish() during aborted pause');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ div.style.marginLeft = '10px';
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.finish();
+ var marginLeft = parseFloat(getComputedStyle(div).marginLeft);
+
+ assert_equals(marginLeft, 10,
+ 'The computed style should be reset when finish() is ' +
+ 'called');
+ });
+}, 'Test resetting of computed style');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate(gKeyFrames, 100 * MS_PER_SEC);
+ var resolvedFinished = false;
+ animation.finished.then(function() {
+ resolvedFinished = true;
+ });
+
+ return animation.ready.then(function() {
+ animation.finish();
+ }).then(function() {
+ assert_true(resolvedFinished,
+ 'Animation.finished should be resolved soon after ' +
+ 'Animation.finish()');
+ });
+}, 'Test finish() resolves finished promise synchronously');
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/play.html b/tests/wpt/web-platform-tests/web-animations/animation/play.html
new file mode 100644
index 00000000000..4fca2548cf8
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/play.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.play()</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-play">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({ transform: ['none', 'translate(10px)']},
+ { duration : 100 * MS_PER_SEC,
+ iterations : Infinity});
+ return animation.ready.then(function() {
+ // Seek to a time outside the active range so that play() will have to
+ // snap back to the start
+ animation.currentTime = -5 * MS_PER_SEC;
+ animation.playbackRate = -1;
+
+ assert_throws('InvalidStateError',
+ function () { animation.play(); },
+ 'Expected InvalidStateError exception on calling play() ' +
+ 'with a negative playbackRate and infinite-duration ' +
+ 'animation');
+ });
+}, 'play() throws when seeking an infinite-duration animation played in ' +
+ 'reverse');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/playState.html b/tests/wpt/web-platform-tests/web-animations/animation/playState.html
new file mode 100644
index 00000000000..670452da9f1
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/playState.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.playState</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-playstate">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+'use strict';
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+
+ assert_equals(animation.playState, 'pending');
+ return animation.ready.then(function() {
+ assert_equals(animation.playState, 'running');
+ });
+}, 'Animation.playState reports \'pending\'->\'running\' when initially ' +
+ 'played');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.pause();
+
+ assert_equals(animation.playState, 'pending');
+ return animation.ready.then(function() {
+ assert_equals(animation.playState, 'paused');
+ });
+}, 'Animation.playState reports \'pending\'->\'paused\' when pausing');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.cancel();
+ assert_equals(animation.playState, 'idle');
+}, 'Animation.playState is \'idle\' when canceled.');
+
+test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({}, 100 * MS_PER_SEC);
+ animation.cancel();
+ animation.currentTime = 50 * MS_PER_SEC;
+ assert_equals(animation.playState, 'paused',
+ 'After seeking an idle animation, it is effectively paused');
+}, 'Animation.playState is \'paused\' after cancelling an animation, ' +
+ 'seeking it makes it paused');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/animation/playbackRate.html b/tests/wpt/web-platform-tests/web-animations/animation/playbackRate.html
new file mode 100644
index 00000000000..fcb73535e27
--- /dev/null
+++ b/tests/wpt/web-platform-tests/web-animations/animation/playbackRate.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Animation.playbackRate</title>
+<link rel="help" href="https://w3c.github.io/web-animations/#dom-animation-playbackrate">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="../testcommon.js"></script>
+<link rel="stylesheet" href="/resources/testharness.css">
+<body>
+<div id="log"></div>
+<script>
+"use strict";
+
+var keyFrames = { 'marginLeft': ['100px', '200px'] };
+
+function assert_playbackrate(animation,
+ previousAnimationCurrentTime,
+ previousTimelineCurrentTime,
+ description) {
+ var accuracy = 0.001; /* accuracy of DOMHighResTimeStamp */
+ var animationCurrentTimeDifference =
+ animation.currentTime - previousAnimationCurrentTime;
+ var timelineCurrentTimeDifference =
+ animation.timeline.currentTime - previousTimelineCurrentTime;
+
+ assert_approx_equals(animationCurrentTimeDifference,
+ timelineCurrentTimeDifference * animation.playbackRate,
+ accuracy,
+ description);
+}
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({keyFrames}, 100 * MS_PER_SEC);
+ return animation.ready.then(function() {
+ animation.currentTime = 7 * MS_PER_SEC; // ms
+ animation.playbackRate = 0.5;
+
+ assert_equals(animation.currentTime, 7 * MS_PER_SEC,
+ 'Reducing Animation.playbackRate should not change the currentTime ' +
+ 'of a playing animation');
+ animation.playbackRate = 2;
+ assert_equals(animation.currentTime, 7 * MS_PER_SEC,
+ 'Increasing Animation.playbackRate should not change the currentTime ' +
+ 'of a playing animation');
+ });
+}, 'Test the initial effect of setting playbackRate on currentTime');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({keyFrames}, 100 * MS_PER_SEC);
+ animation.playbackRate = 2;
+ var previousTimelineCurrentTime;
+ var previousAnimationCurrentTime;
+ return animation.ready.then(function() {
+ previousAnimationCurrentTime = animation.currentTime;
+ previousTimelineCurrentTime = animation.timeline.currentTime;
+ return waitForAnimationFrames(1);
+ }).then(function() {
+ assert_playbackrate(animation,
+ previousAnimationCurrentTime,
+ previousTimelineCurrentTime,
+ 'animation.currentTime should be 2 times faster than timeline.');
+ });
+}, 'Test the effect of setting playbackRate on currentTime');
+
+promise_test(function(t) {
+ var div = createDiv(t);
+ var animation = div.animate({keyFrames}, 100 * MS_PER_SEC);
+ animation.playbackRate = 2;
+ var previousTimelineCurrentTime;
+ var previousAnimationCurrentTime;
+ return animation.ready.then(function() {
+ previousAnimationCurrentTime = animation.currentTime;
+ previousTimelineCurrentTime = animation.timeline.currentTime;
+ animation.playbackRate = 1;
+ return waitForAnimationFrames(1);
+ }).then(function() {
+ assert_equals(animation.playbackRate, 1,
+ 'sanity check: animation.playbackRate is still 1.');
+ assert_playbackrate(animation,
+ previousAnimationCurrentTime,
+ previousTimelineCurrentTime,
+ 'animation.currentTime should be the same speed as timeline now.');
+ });
+}, 'Test the effect of setting playbackRate while playing animation');
+
+</script>
+</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html
index 55720daffd8..50cee72ac47 100644
--- a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html
+++ b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/constructor.html
@@ -61,13 +61,8 @@ test(function(t) {
// [specified easing value, expected easing value]
var gEasingValueTests = [
- ["unrecognised", "linear"],
["linear", "linear"],
["ease-in-out", "ease-in-out"],
- ["initial", "linear"],
- ["inherit", "linear"],
- ["var(--x)", "linear"],
- ["ease-in-out, ease-out", "linear"],
["Ease\\2d in-out", "ease-in-out"],
["ease /**/", "ease"],
];
@@ -113,56 +108,57 @@ test(function(t) {
}, "easing values are parsed correctly when passed to the " +
"KeyframeEffectReadOnly constructor in KeyframeTimingOptions");
-var gGoodCompositeValueTests = [
+var gGoodKeyframeCompositeValueTests = [
+ "replace", "add", "accumulate", undefined
+];
+
+var gGoodOptionsCompositeValueTests = [
"replace", "add", "accumulate"
];
var gBadCompositeValueTests = [
- "unrecognised", "replace ", "Replace"
+ "unrecognised", "replace ", "Replace", null
];
test(function(t) {
- gGoodCompositeValueTests.forEach(function(composite) {
- var effect = new KeyframeEffectReadOnly(target, {
- left: ["10px", "20px"],
- composite: composite
- });
+ var getFrame = function(composite) {
+ return { left: [ "10px", "20px" ], composite: composite };
+ };
+ gGoodKeyframeCompositeValueTests.forEach(function(composite) {
+ var effect = new KeyframeEffectReadOnly(target, getFrame(composite));
assert_equals(effect.getFrames()[0].composite, composite,
"resulting composite for '" + composite + "'");
});
gBadCompositeValueTests.forEach(function(composite) {
assert_throws(new TypeError, function() {
- new KeyframeEffectReadOnly(target, {
- left: ["10px", "20px"],
- composite: composite
- });
+ new KeyframeEffectReadOnly(target, getFrame(composite));
});
});
}, "composite values are parsed correctly when passed to the " +
"KeyframeEffectReadOnly constructor in PropertyIndexedKeyframes");
test(function(t) {
- gGoodCompositeValueTests.forEach(function(composite) {
- var effect = new KeyframeEffectReadOnly(target, [
+ var getFrames = function(composite) {
+ return [
{ offset: 0, left: "10px", composite: composite },
{ offset: 1, left: "20px" }
- ]);
+ ];
+ };
+ gGoodKeyframeCompositeValueTests.forEach(function(composite) {
+ var effect = new KeyframeEffectReadOnly(target, getFrames(composite));
assert_equals(effect.getFrames()[0].composite, composite,
"resulting composite for '" + composite + "'");
});
gBadCompositeValueTests.forEach(function(composite) {
assert_throws(new TypeError, function() {
- new KeyframeEffectReadOnly(target, [
- { offset: 0, left: "10px", composite: composite },
- { offset: 1, left: "20px" }
- ]);
+ new KeyframeEffectReadOnly(target, getFrames(composite));
});
});
}, "composite values are parsed correctly when passed to the " +
"KeyframeEffectReadOnly constructor in Keyframe");
test(function(t) {
- gGoodCompositeValueTests.forEach(function(composite) {
+ gGoodOptionsCompositeValueTests.forEach(function(composite) {
var effect = new KeyframeEffectReadOnly(target, {
left: ["10px", "20px"]
}, { composite: composite });
@@ -182,77 +178,77 @@ test(function(t) {
var gPropertyIndexedKeyframesTests = [
{ desc: "a one property two value PropertyIndexedKeyframes specification",
input: { left: ["10px", "20px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "20px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }] },
{ desc: "a one shorthand property two value PropertyIndexedKeyframes specification",
input: { margin: ["10px", "10px 20px 30px 40px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginTop: "10px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginTop: "10px", marginRight: "20px", marginBottom: "30px", marginLeft: "40px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "10px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", marginTop: "10px", marginRight: "20px", marginBottom: "30px", marginLeft: "40px" }] },
{ desc: "a two property (one shorthand and one of its longhand components) two value PropertyIndexedKeyframes specification",
input: { marginTop: ["50px", "60px"],
margin: ["10px", "10px 20px 30px 40px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginTop: "50px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginTop: "60px", marginRight: "20px", marginBottom: "30px", marginLeft: "40px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "50px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", marginTop: "60px", marginRight: "20px", marginBottom: "30px", marginLeft: "40px" }] },
{ desc: "a two property two value PropertyIndexedKeyframes specification",
input: { left: ["10px", "20px"],
top: ["30px", "40px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px", top: "30px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "20px", top: "40px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px", top: "30px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "20px", top: "40px" }] },
{ desc: "a two property PropertyIndexedKeyframes specification with different numbers of values",
input: { left: ["10px", "20px", "30px"],
top: ["40px", "50px"] },
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear", composite: "replace", left: "10px", top: "40px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", composite: "replace", left: "20px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", composite: "replace", left: "30px", top: "50px" }] },
+ output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear", left: "10px", top: "40px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "20px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "linear", left: "30px", top: "50px" }] },
{ desc: "a PropertyIndexedKeyframes specification with an invalid value",
input: { left: ["10px", "20px", "30px", "40px", "50px"],
top: ["15px", "25px", "invalid", "45px", "55px"] },
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", composite: "replace", left: "10px", top: "15px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", composite: "replace", left: "20px", top: "25px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", composite: "replace", left: "30px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", composite: "replace", left: "40px", top: "45px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", composite: "replace", left: "50px", top: "55px" }] },
+ output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px", top: "15px" },
+ { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "20px", top: "25px" },
+ { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "30px" },
+ { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "40px", top: "45px" },
+ { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "50px", top: "55px" }] },
{ desc: "a one property two value PropertyIndexedKeyframes specification that needs to stringify its values",
input: { opacity: [0, 1] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", opacity: "0" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", opacity: "1" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", opacity: "0" },
+ { offset: 1, computedOffset: 1, easing: "linear", opacity: "1" }] },
{ desc: "a one property one value PropertyIndexedKeyframes specification",
input: { left: ["10px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "10px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "10px" }] },
{ desc: "a one property one non-array value PropertyIndexedKeyframes specification",
input: { left: "10px" },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "10px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "10px" }] },
{ desc: "a one property two value PropertyIndexedKeyframes specification where the first value is invalid",
input: { left: ["invalid", "10px"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "10px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "10px" }] },
{ desc: "a one property two value PropertyIndexedKeyframes specification where the second value is invalid",
input: { left: ["10px", "invalid"] },
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear" }] },
{ desc: "a two property PropertyIndexedKeyframes specification where one property is missing from the first Keyframe",
input: [{ offset: 0, left: "10px" },
{ offset: 1, left: "20px", top: "30px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "20px", top: "30px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "20px", top: "30px" }] },
{ desc: "a two property PropertyIndexedKeyframes specification where one property is missing from the last Keyframe",
input: [{ offset: 0, left: "10px", top: "20px" },
{ offset: 1, left: "30px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px" , top: "20px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "30px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" , top: "20px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "30px" }] },
{ desc: "a PropertyIndexedKeyframes specification with repeated values at offset 0 with different easings",
input: [{ offset: 0.0, left: "100px", easing: "ease" },
{ offset: 0.0, left: "200px", easing: "ease" },
{ offset: 0.5, left: "300px", easing: "linear" },
{ offset: 1.0, left: "400px", easing: "ease-out" },
{ offset: 1.0, left: "500px", easing: "step-end" }],
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease", composite: "replace", left: "100px" },
- { offset: 0.0, computedOffset: 0.0, easing: "ease", composite: "replace", left: "200px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", composite: "replace", left: "300px" },
- { offset: 1.0, computedOffset: 1.0, easing: "ease-out", composite: "replace", left: "400px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", composite: "replace", left: "500px" }] },
+ output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease", left: "100px" },
+ { offset: 0.0, computedOffset: 0.0, easing: "ease", left: "200px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "300px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "ease-out", left: "400px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "linear", left: "500px" }] },
];
gPropertyIndexedKeyframesTests.forEach(function(subtest) {
@@ -278,7 +274,7 @@ test(function(t) {
{ p: "left", v: "20px" },
{ p: "offset", v: "0" },
{ p: "easing", v: "linear" },
- { p: "composite", v: null }].forEach(function(e) {
+ { p: "composite", v: "replace" }].forEach(function(e) {
Object.defineProperty(kf1, e.p, {
enumerable: true,
get: function() { actualOrder.push(e.p); return e.v; }
@@ -293,33 +289,33 @@ var gKeyframeSequenceTests = [
{ desc: "a one property two Keyframe sequence",
input: [{ offset: 0, left: "10px" },
{ offset: 1, left: "20px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "20px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "20px" }] },
{ desc: "a two property two Keyframe sequence",
input: [{ offset: 0, left: "10px", top: "30px" },
{ offset: 1, left: "20px", top: "40px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px", top: "30px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "20px", top: "40px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px", top: "30px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "20px", top: "40px" }] },
{ desc: "a one shorthand property two Keyframe sequence",
input: [{ offset: 0, margin: "10px" },
{ offset: 1, margin: "20px 30px 40px 50px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginTop: "10px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginTop: "20px", marginRight: "30px", marginBottom: "40px", marginLeft: "50px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "10px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", marginTop: "20px", marginRight: "30px", marginBottom: "40px", marginLeft: "50px" }] },
{ desc: "a two property (a shorthand and one of its component longhands) two Keyframe sequence",
input: [{ offset: 0, margin: "10px", marginTop: "20px" },
{ offset: 1, marginTop: "70px", margin: "30px 40px 50px 60px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginTop: "20px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginTop: "70px", marginRight: "40px", marginBottom: "50px", marginLeft: "60px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", marginTop: "20px", marginRight: "10px", marginBottom: "10px", marginLeft: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", marginTop: "70px", marginRight: "40px", marginBottom: "50px", marginLeft: "60px" }] },
{ desc: "a Keyframe sequence with duplicate values for a given interior offset",
input: [{ offset: 0.0, left: "10px" },
{ offset: 0.5, left: "20px" },
{ offset: 0.5, left: "30px" },
{ offset: 0.5, left: "40px" },
{ offset: 1.0, left: "50px" }],
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear", composite: "replace", left: "10px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", composite: "replace", left: "20px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", composite: "replace", left: "40px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", composite: "replace", left: "50px" }] },
+ output: [{ offset: 0.0, computedOffset: 0.0, easing: "linear", left: "10px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "20px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear", left: "40px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "linear", left: "50px" }] },
{ desc: "a Keyframe sequence with duplicate values for offsets 0 and 1",
input: [{ offset: 0, left: "10px" },
{ offset: 0, left: "20px" },
@@ -327,50 +323,50 @@ var gKeyframeSequenceTests = [
{ offset: 1, left: "40px" },
{ offset: 1, left: "50px" },
{ offset: 1, left: "60px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px" },
- { offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "30px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "40px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "60px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px" },
+ { offset: 0, computedOffset: 0, easing: "linear", left: "30px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "40px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "60px" }] },
{ desc: "a two property four Keyframe sequence",
input: [{ offset: 0, left: "10px" },
{ offset: 0, top: "20px" },
{ offset: 1, top: "30px" },
{ offset: 1, left: "40px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", left: "10px", top: "20px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", left: "40px", top: "30px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", left: "10px", top: "20px" },
+ { offset: 1, computedOffset: 1, easing: "linear", left: "40px", top: "30px" }] },
{ desc: "a one property Keyframe sequence with some omitted offsets",
input: [{ offset: 0.00, left: "10px" },
{ offset: 0.25, left: "20px" },
{ left: "30px" },
{ left: "40px" },
{ offset: 1.00, left: "50px" }],
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", composite: "replace", left: "10px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", composite: "replace", left: "20px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", composite: "replace", left: "30px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", composite: "replace", left: "40px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", composite: "replace", left: "50px" }] },
+ output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px" },
+ { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "20px" },
+ { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "30px" },
+ { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "40px" },
+ { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "50px" }] },
{ desc: "a two property Keyframe sequence with some omitted offsets",
input: [{ offset: 0.00, left: "10px", top: "20px" },
{ offset: 0.25, left: "30px" },
{ left: "40px" },
{ left: "50px", top: "60px" },
{ offset: 1.00, left: "70px", top: "80px" }],
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", composite: "replace", left: "10px", top: "20px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", composite: "replace", left: "30px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", composite: "replace", left: "40px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", composite: "replace", left: "50px", top: "60px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", composite: "replace", left: "70px", top: "80px" }] },
+ output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px", top: "20px" },
+ { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "30px" },
+ { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "40px" },
+ { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "50px", top: "60px" },
+ { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "70px", top: "80px" }] },
{ desc: "a one property Keyframe sequence with all omitted offsets",
input: [{ left: "10px" },
{ left: "20px" },
{ left: "30px" },
{ left: "40px" },
{ left: "50px" }],
- output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", composite: "replace", left: "10px" },
- { offset: 0.25, computedOffset: 0.25, easing: "linear", composite: "replace", left: "20px" },
- { offset: 0.50, computedOffset: 0.50, easing: "linear", composite: "replace", left: "30px" },
- { offset: 0.75, computedOffset: 0.75, easing: "linear", composite: "replace", left: "40px" },
- { offset: 1.00, computedOffset: 1.00, easing: "linear", composite: "replace", left: "50px" }] },
+ output: [{ offset: 0.00, computedOffset: 0.00, easing: "linear", left: "10px" },
+ { offset: 0.25, computedOffset: 0.25, easing: "linear", left: "20px" },
+ { offset: 0.50, computedOffset: 0.50, easing: "linear", left: "30px" },
+ { offset: 0.75, computedOffset: 0.75, easing: "linear", left: "40px" },
+ { offset: 1.00, computedOffset: 1.00, easing: "linear", left: "50px" }] },
{ desc: "a Keyframe sequence with different easing values, but the same easing value for a given offset",
input: [{ offset: 0.0, easing: "ease", left: "10px"},
{ offset: 0.0, easing: "ease", top: "20px"},
@@ -378,9 +374,12 @@ var gKeyframeSequenceTests = [
{ offset: 0.5, easing: "linear", top: "40px" },
{ offset: 1.0, easing: "step-end", left: "50px" },
{ offset: 1.0, easing: "step-end", top: "60px" }],
- output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease", composite: "replace", left: "10px", top: "20px" },
- { offset: 0.5, computedOffset: 0.5, easing: "linear", composite: "replace", left: "30px", top: "40px" },
- { offset: 1.0, computedOffset: 1.0, easing: "linear", composite: "replace", left: "50px", top: "60px" }] },
+ output: [{ offset: 0.0, computedOffset: 0.0, easing: "ease",
+ left: "10px", top: "20px" },
+ { offset: 0.5, computedOffset: 0.5, easing: "linear",
+ left: "30px", top: "40px" },
+ { offset: 1.0, computedOffset: 1.0, easing: "linear",
+ left: "50px", top: "60px" }] },
{ desc: "a Keyframe sequence with different composite values, but the same composite value for a given offset",
input: [{ offset: 0.0, composite: "replace", left: "10px" },
{ offset: 0.0, composite: "replace", top: "20px" },
@@ -394,27 +393,27 @@ var gKeyframeSequenceTests = [
{ desc: "a one property two Keyframe sequence that needs to stringify its values",
input: [{ offset: 0, opacity: 0 },
{ offset: 1, opacity: 1 }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", opacity: "0" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", opacity: "1" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", opacity: "0" },
+ { offset: 1, computedOffset: 1, easing: "linear", opacity: "1" }] },
{ desc: "a Keyframe sequence where shorthand precedes longhand",
input: [{ offset: 0, margin: "10px", marginRight: "20px" },
{ offset: 1, margin: "30px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginBottom: "10px", marginLeft: "10px", marginRight: "20px", marginTop: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginBottom: "30px", marginLeft: "30px", marginRight: "30px", marginTop: "30px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", marginBottom: "10px", marginLeft: "10px", marginRight: "20px", marginTop: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", marginBottom: "30px", marginLeft: "30px", marginRight: "30px", marginTop: "30px" }] },
{ desc: "a Keyframe sequence where longhand precedes shorthand",
input: [{ offset: 0, marginRight: "20px", margin: "10px" },
{ offset: 1, margin: "30px" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace", marginBottom: "10px", marginLeft: "10px", marginRight: "20px", marginTop: "10px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace", marginBottom: "30px", marginLeft: "30px", marginRight: "30px", marginTop: "30px" }] },
+ output: [{ offset: 0, computedOffset: 0, easing: "linear", marginBottom: "10px", marginLeft: "10px", marginRight: "20px", marginTop: "10px" },
+ { offset: 1, computedOffset: 1, easing: "linear", marginBottom: "30px", marginLeft: "30px", marginRight: "30px", marginTop: "30px" }] },
{ desc: "a Keyframe sequence where lesser shorthand precedes greater shorthand",
input: [{ offset: 0, borderLeft: "1px solid rgb(1, 2, 3)", border: "2px dotted rgb(4, 5, 6)" },
{ offset: 1, border: "3px dashed rgb(7, 8, 9)" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
borderBottomColor: "rgb(4, 5, 6)", borderBottomWidth: "2px",
borderLeftColor: "rgb(1, 2, 3)", borderLeftWidth: "1px",
borderRightColor: "rgb(4, 5, 6)", borderRightWidth: "2px",
borderTopColor: "rgb(4, 5, 6)", borderTopWidth: "2px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace",
+ { offset: 1, computedOffset: 1, easing: "linear",
borderBottomColor: "rgb(7, 8, 9)", borderBottomWidth: "3px",
borderLeftColor: "rgb(7, 8, 9)", borderLeftWidth: "3px",
borderRightColor: "rgb(7, 8, 9)", borderRightWidth: "3px",
@@ -422,12 +421,12 @@ var gKeyframeSequenceTests = [
{ desc: "a Keyframe sequence where greater shorthand precedes lesser shorthand",
input: [{ offset: 0, border: "2px dotted rgb(4, 5, 6)", borderLeft: "1px solid rgb(1, 2, 3)" },
{ offset: 1, border: "3px dashed rgb(7, 8, 9)" }],
- output: [{ offset: 0, computedOffset: 0, easing: "linear", composite: "replace",
+ output: [{ offset: 0, computedOffset: 0, easing: "linear",
borderBottomColor: "rgb(4, 5, 6)", borderBottomWidth: "2px",
borderLeftColor: "rgb(1, 2, 3)", borderLeftWidth: "1px",
borderRightColor: "rgb(4, 5, 6)", borderRightWidth: "2px",
borderTopColor: "rgb(4, 5, 6)", borderTopWidth: "2px" },
- { offset: 1, computedOffset: 1, easing: "linear", composite: "replace",
+ { offset: 1, computedOffset: 1, easing: "linear",
borderBottomColor: "rgb(7, 8, 9)", borderBottomWidth: "3px",
borderLeftColor: "rgb(7, 8, 9)", borderLeftWidth: "3px",
borderRightColor: "rgb(7, 8, 9)", borderRightWidth: "3px",
@@ -448,6 +447,29 @@ gKeyframeSequenceTests.forEach(function(subtest) {
" roundtrips");
});
+var gInvalidEasingInKeyframeSequenceTests = [
+ { desc: "a blank easing",
+ input: [{ easing: "" }] },
+ { desc: "an unrecognized easing",
+ input: [{ easing: "unrecognized" }] },
+ { desc: "an 'initial' easing",
+ input: [{ easing: "initial" }] },
+ { desc: "an 'inherit' easing",
+ input: [{ easing: "inherit" }] },
+ { desc: "a variable easing",
+ input: [{ easing: "var(--x)" }] },
+ { desc: "a multi-value easing",
+ input: [{ easing: "ease-in-out, ease-out" }] }
+];
+
+gInvalidEasingInKeyframeSequenceTests.forEach(function(subtest) {
+ test(function(t) {
+ assert_throws(new TypeError, function() {
+ new KeyframeEffectReadOnly(target, subtest.input);
+ });
+ }, "Invalid easing [" + subtest.desc + "] in KeyframeSequence " +
+ "should be thrown");
+});
test(function(t) {
var effect = new KeyframeEffectReadOnly(target,
@@ -501,15 +523,6 @@ var gKeyframeEffectOptionTests = [
{ desc: "an Infinity iterations",
input: { iterations: Infinity },
expected: { iterations: Infinity } },
- { desc: "a negative Infinity iterations",
- input: { iterations: -Infinity },
- expected: { iterations: -Infinity } },
- { desc: "a NaN iterations",
- input: { iterations: NaN },
- expected: { iterations: NaN } },
- { desc: "a negative iterations",
- input: { iterations: -1 },
- expected: { iterations: -1 } },
{ desc: "an auto fill",
input: { fill: "auto" },
expected: { fill: "auto" } },
@@ -566,6 +579,33 @@ var gInvalidKeyframeEffectOptionTests = [
expected: { name: "TypeError" } },
{ desc: "a string duration",
input: { duration: "merrychristmas" },
+ expected: { name: "TypeError" } },
+ { desc: "a negative Infinity iterations",
+ input: { iterations: -Infinity},
+ expected: { name: "TypeError" } },
+ { desc: "a NaN iterations",
+ input: { iterations: NaN },
+ expected: { name: "TypeError" } },
+ { desc: "a negative iterations",
+ input: { iterations: -1 },
+ expected: { name: "TypeError" } },
+ { desc: "a blank easing",
+ input: { easing: "" },
+ expected: { name: "TypeError" } },
+ { desc: "an unrecognized easing",
+ input: { easing: "unrecognised" },
+ expected: { name: "TypeError" } },
+ { desc: "an 'initial' easing",
+ input: { easing: "initial" },
+ expected: { name: "TypeError" } },
+ { desc: "an 'inherit' easing",
+ input: { easing: "inherit" },
+ expected: { name: "TypeError" } },
+ { desc: "a variable easing",
+ input: { easing: "var(--x)" },
+ expected: { name: "TypeError" } },
+ { desc: "a multi-value easing",
+ input: { easing: "ease-in-out, ease-out" },
expected: { name: "TypeError" } }
];
@@ -573,7 +613,7 @@ gInvalidKeyframeEffectOptionTests.forEach(function(stest) {
test(function(t) {
assert_throws(stest.expected, function() {
new KeyframeEffectReadOnly(target,
- {left: ["10px", "20px"]},
+ { left: ["10px", "20px"] },
stest.input);
});
}, "Invalid KeyframeEffectReadOnly option by " + stest.desc);
diff --git a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html
index b3c39ad4f3b..2ecd028ce9b 100644
--- a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html
+++ b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/effect-easing.html
@@ -434,5 +434,287 @@ test(function(t) {
'the lower boundary is infinity with keyframe easing producing ' +
'negative values');
+var gStepTimingFunctionTests = [
+ {
+ description: 'Test bounds point of step-start easing',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 0 },
+ { currentTime: 999, progress: 0 },
+ { currentTime: 1000, progress: 0.5 },
+ { currentTime: 1499, progress: 0.5 },
+ { currentTime: 1500, progress: 1 },
+ { currentTime: 2000, progress: 1 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing with compositor',
+ keyframe: [ { opacity: 0 },
+ { opacity: 1 } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 0 },
+ { currentTime: 999, progress: 0 },
+ { currentTime: 1000, progress: 0.5 },
+ { currentTime: 1499, progress: 0.5 },
+ { currentTime: 1500, progress: 1 },
+ { currentTime: 2000, progress: 1 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing with reverse direction',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ direction: 'reverse',
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 1 },
+ { currentTime: 1001, progress: 1 },
+ { currentTime: 1500, progress: 1 },
+ { currentTime: 1501, progress: 0.5 },
+ { currentTime: 2000, progress: 0 },
+ { currentTime: 2500, progress: 0 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing ' +
+ 'with iterationStart not at a transition point',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ iterationStart: 0.25,
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 0.5 },
+ { currentTime: 999, progress: 0.5 },
+ { currentTime: 1000, progress: 0.5 },
+ { currentTime: 1249, progress: 0.5 },
+ { currentTime: 1250, progress: 1 },
+ { currentTime: 1749, progress: 1 },
+ { currentTime: 1750, progress: 0.5 },
+ { currentTime: 2000, progress: 0.5 },
+ { currentTime: 2500, progress: 0.5 },
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing ' +
+ 'with iterationStart and delay',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ iterationStart: 0.5,
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 0.5 },
+ { currentTime: 999, progress: 0.5 },
+ { currentTime: 1000, progress: 1 },
+ { currentTime: 1499, progress: 1 },
+ { currentTime: 1500, progress: 0.5 },
+ { currentTime: 2000, progress: 1 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing ' +
+ 'with iterationStart and reverse direction',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ iterationStart: 0.5,
+ direction: 'reverse',
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 1 },
+ { currentTime: 1000, progress: 1 },
+ { currentTime: 1001, progress: 0.5 },
+ { currentTime: 1499, progress: 0.5 },
+ { currentTime: 1500, progress: 1 },
+ { currentTime: 1999, progress: 1 },
+ { currentTime: 2000, progress: 0.5 },
+ { currentTime: 2500, progress: 0.5 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step(4, start) easing ' +
+ 'with iterationStart 0.75 and delay',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ duration: 1000,
+ fill: 'both',
+ delay: 1000,
+ iterationStart: 0.75,
+ easing: 'steps(4, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 0.75 },
+ { currentTime: 999, progress: 0.75 },
+ { currentTime: 1000, progress: 1 },
+ { currentTime: 2000, progress: 1 },
+ { currentTime: 2500, progress: 1 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing ' +
+ 'with alternate direction',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ duration: 1000,
+ fill: 'both',
+ delay: 1000,
+ iterations: 2,
+ iterationStart: 1.5,
+ direction: 'alternate',
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 1 },
+ { currentTime: 1000, progress: 1 },
+ { currentTime: 1001, progress: 0.5 },
+ { currentTime: 2999, progress: 1 },
+ { currentTime: 3000, progress: 0.5 },
+ { currentTime: 3500, progress: 0.5 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing ' +
+ 'with alternate-reverse direction',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ duration: 1000,
+ fill: 'both',
+ delay: 1000,
+ iterations: 2,
+ iterationStart: 0.5,
+ direction: 'alternate-reverse',
+ easing: 'steps(2, start)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 1 },
+ { currentTime: 1000, progress: 1 },
+ { currentTime: 1001, progress: 0.5 },
+ { currentTime: 2999, progress: 1 },
+ { currentTime: 3000, progress: 0.5 },
+ { currentTime: 3500, progress: 0.5 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-start easing in keyframe',
+ keyframe: [ { width: '0px', easing: 'steps(2, start)' },
+ { width: '100px' } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ },
+ conditions: [
+ { currentTime: 0, progress: 0, width: '0px' },
+ { currentTime: 999, progress: 0, width: '0px' },
+ { currentTime: 1000, progress: 0, width: '50px' },
+ { currentTime: 1499, progress: 0.499, width: '50px' },
+ { currentTime: 1500, progress: 0.5, width: '100px' },
+ { currentTime: 2000, progress: 1, width: '100px' },
+ { currentTime: 2500, progress: 1, width: '100px' }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-end easing ' +
+ 'with iterationStart and delay',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ duration: 1000,
+ fill: 'both',
+ delay: 1000,
+ iterationStart: 0.5,
+ easing: 'steps(2, end)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 0 },
+ { currentTime: 999, progress: 0 },
+ { currentTime: 1000, progress: 0.5 },
+ { currentTime: 1499, progress: 0.5 },
+ { currentTime: 1500, progress: 0 },
+ { currentTime: 1999, progress: 0 },
+ { currentTime: 2000, progress: 0.5 },
+ { currentTime: 2500, progress: 0.5 }
+ ]
+ },
+ {
+ description: 'Test bounds point of step-end easing ' +
+ 'with iterationStart not at a transition point',
+ keyframe: [ { width: '0px' },
+ { width: '100px' } ],
+ effect: {
+ delay: 1000,
+ duration: 1000,
+ fill: 'both',
+ iterationStart: 0.75,
+ easing: 'steps(2, end)'
+ },
+ conditions: [
+ { currentTime: 0, progress: 0.5 },
+ { currentTime: 999, progress: 0.5 },
+ { currentTime: 1000, progress: 0.5 },
+ { currentTime: 1249, progress: 0.5 },
+ { currentTime: 1250, progress: 0 },
+ { currentTime: 1749, progress: 0 },
+ { currentTime: 1750, progress: 0.5 },
+ { currentTime: 2000, progress: 0.5 },
+ { currentTime: 2500, progress: 0.5 },
+ ]
+ }
+]
+
+gStepTimingFunctionTests.forEach(function(options) {
+ test(function(t) {
+ var target = createDiv(t);
+ var animation = target.animate(options.keyframe, options.effect);
+ options.conditions.forEach(function(condition) {
+ animation.currentTime = condition.currentTime;
+ if (typeof condition.progress !== 'undefined') {
+ assert_equals(animation.effect.getComputedTiming().progress,
+ condition.progress,
+ 'Progress at ' + animation.currentTime + 'ms');
+ }
+ if (typeof condition.width !== 'undefined') {
+ assert_equals(getComputedStyle(target).width,
+ condition.width,
+ 'Progress at ' + animation.currentTime + 'ms');
+ }
+ });
+ }, options.description);
+});
+
</script>
</body>
diff --git a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/getComputedTiming.html b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/getComputedTiming.html
index 9ea723f9e72..d1b59cfd91a 100644
--- a/tests/wpt/web-platform-tests/web-animations/keyframe-effect/getComputedTiming.html
+++ b/tests/wpt/web-platform-tests/web-animations/keyframe-effect/getComputedTiming.html
@@ -62,15 +62,6 @@ var gGetComputedTimingTests = [
{ desc: "an Infinity iterations",
input: { iterations: Infinity },
expected: { iterations: Infinity } },
- { desc: "a negative Infinity iterations",
- input: { iterations: -Infinity},
- expected: { iterations: 1 } },
- { desc: "a NaN iterations",
- input: { iterations: NaN },
- expected: { iterations: 1 } },
- { desc: "a negative iterations",
- input: { iterations: -1 },
- expected: { iterations: 1 } },
{ desc: "an auto fill",
input: { fill: "auto" },
expected: { fill: "none" } },
@@ -152,10 +143,7 @@ var gActiveDurationTests = [
expected: Infinity },
{ desc: "an infinite duration and zero iteration count",
input: { duration: Infinity, iterations: 0 },
- expected: 0 },
- { desc: "a non-zero duration and invalid iteration count",
- input: { duration: 1000, iterations: "cabbage" },
- expected: 1000 }
+ expected: 0 }
];
gActiveDurationTests.forEach(function(stest) {
diff --git a/tests/wpt/web-platform-tests/web-animations/testcommon.js b/tests/wpt/web-platform-tests/web-animations/testcommon.js
index e7179cc1883..ab54202f10e 100644
--- a/tests/wpt/web-platform-tests/web-animations/testcommon.js
+++ b/tests/wpt/web-platform-tests/web-animations/testcommon.js
@@ -9,29 +9,7 @@ policies and contribution forms [3].
*/
"use strict";
-
-var ANIMATION_END_TIME = 1000;
-var ANIMATION_TOP_DEFAULT = 300;
-var ANIMATION_TOP_0 = 10;
-var ANIMATION_TOP_0_5 = 100;
-var ANIMATION_TOP_1 = 200;
-
-var KEYFRAMES = [ {
- top : ANIMATION_TOP_0 + 'px',
- offset : 0
-}, {
- top : ANIMATION_TOP_0_5 + 'px',
- offset : 1 / 2
-}, {
- top : ANIMATION_TOP_1 + 'px',
- offset : 1
-} ];
-
-// creates new animation for given target
-function newAnimation(animationTarget) {
- animationTarget.style.top = ANIMATION_TOP_DEFAULT + 'px';
- return new Animation(animationTarget, KEYFRAMES, ANIMATION_END_TIME);
-}
+var MS_PER_SEC = 1000;
// creates div element, appends it to the document body and
// removes the created element during test cleanup
@@ -91,11 +69,6 @@ function createPseudo(test, type) {
return anim.effect.target;
}
-// Returns the type name of given object
-function type(object) {
- return Object.prototype.toString.call(object).slice(8, -1);
-}
-
// Convert px unit value to a Number
function pxToNum(str) {
return Number(String(str).match(/^(-?[\d.]+)px$/)[1]);
diff --git a/tests/wpt/web-platform-tests/webgl/OWNERS b/tests/wpt/web-platform-tests/webgl/OWNERS
index fd31fb27543..0ed929edad3 100644
--- a/tests/wpt/web-platform-tests/webgl/OWNERS
+++ b/tests/wpt/web-platform-tests/webgl/OWNERS
@@ -1 +1,2 @@
@Ms2ger
+@emilio
diff --git a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-child-with-worker.html b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-child-with-worker.html
new file mode 100644
index 00000000000..f61e66a8e8f
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-child-with-worker.html
@@ -0,0 +1,78 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html style="margin: 0; padding: 0;">
+ <head>
+<meta charset="utf-8">
+ <title>Simple WebGL context with Worker</title>
+ <script src="../../resources/webgl-test-utils.js"> </script>
+</head>
+<body style="margin: 0; padding: 0; overflow: hidden;">
+ <canvas id="c"
+ width="1680" height="1050"
+ style="width: 256px; height: 256px;"> <!-- scaled to fit page better -->
+ <script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 vPosition;
+ void main()
+ {
+ gl_Position = vPosition;
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ void main()
+ {
+ gl_FragColor = vec4(1.0,0.0,0.0,1.0);
+ }
+ </script>
+
+ <script>
+ "use strict";
+ var wtu = WebGLTestUtils;
+ var myWorker = new Worker("context-release-worker.js");
+
+ var gl = wtu.create3DContext("c", { antialias: false });
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.75,0, -0.75,-0.75,0, 0.75,-0.75,0 ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ if(parent) {
+ window.glContext = gl;
+ parent.postMessage("Ready", "*");
+ }
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-upon-reload-child.html b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-upon-reload-child.html
new file mode 100644
index 00000000000..95ad1653f21
--- /dev/null
+++ b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/context/resources/context-release-upon-reload-child.html
@@ -0,0 +1,77 @@
+<!--
+
+/*
+** Copyright (c) 2012 The Khronos Group Inc.
+**
+** Permission is hereby granted, free of charge, to any person obtaining a
+** copy of this software and/or associated documentation files (the
+** "Materials"), to deal in the Materials without restriction, including
+** without limitation the rights to use, copy, modify, merge, publish,
+** distribute, sublicense, and/or sell copies of the Materials, and to
+** permit persons to whom the Materials are furnished to do so, subject to
+** the following conditions:
+**
+** The above copyright notice and this permission notice shall be included
+** in all copies or substantial portions of the Materials.
+**
+** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
+*/
+
+-->
+
+<!DOCTYPE html>
+<html style="margin: 0; padding: 0;">
+ <head>
+<meta charset="utf-8">
+ <title>Simple WebGL context</title>
+ <script src="../../resources/webgl-test-utils.js"> </script>
+</head>
+<body style="margin: 0; padding: 0; overflow: hidden;">
+ <canvas id="c"
+ width="1680" height="1050"
+ style="width: 256px; height: 256px;"> <!-- scaled to fit page better -->
+ <script id="vshader" type="x-shader/x-vertex">
+ attribute vec4 vPosition;
+ void main()
+ {
+ gl_Position = vPosition;
+ }
+ </script>
+
+ <script id="fshader" type="x-shader/x-fragment">
+ void main()
+ {
+ gl_FragColor = vec4(1.0,0.0,0.0,1.0);
+ }
+ </script>
+
+ <script>
+ "use strict";
+ var wtu = WebGLTestUtils;
+
+ var gl = wtu.create3DContext("c", { antialias: false });
+ var program = wtu.setupProgram(gl, ["vshader", "fshader"], ["vPosition"]);
+
+ var vertexObject = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0.75,0, -0.75,-0.75,0, 0.75,-0.75,0 ]), gl.STATIC_DRAW);
+ gl.enableVertexAttribArray(0);
+ gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+
+ gl.clearColor(0.0, 0.0, 0.0, 1.0);
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+ if (parent) {
+ window.glContext = gl;
+ parent.postMessage("Ready", "*");
+ }
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/extensions/oes-vertex-array-object.html b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/extensions/oes-vertex-array-object.html
index 38b606f3fd4..e138382a02d 100644
--- a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/extensions/oes-vertex-array-object.html
+++ b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/extensions/oes-vertex-array-object.html
@@ -534,8 +534,10 @@ function runDeleteTests() {
for (var ii = 0; ii < colorBuffers.length; ++ii) {
gl.deleteBuffer(colorBuffers[ii]);
gl.deleteBuffer(elementBuffers[ii]);
+ ext.bindVertexArrayOES(vaos[ii]);
+ var boundBuffer = gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING);
// The buffers should still be valid at this point, since it was attached to the VAO
- if(!gl.isBuffer(colorBuffers[ii])) {
+ if(boundBuffer != colorBuffers[ii]) {
testFailed("buffer removed even though it is still attached to a VAO");
}
}
diff --git a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/more/functions/texImage2DBadArgs.html b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/more/functions/texImage2DBadArgs.html
index 9c59421f01e..bf5b71279bb 100644
--- a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/more/functions/texImage2DBadArgs.html
+++ b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/conformance/more/functions/texImage2DBadArgs.html
@@ -63,7 +63,7 @@ Tests.testTexImage2D = function(gl) {
assertGLError(gl, gl.INVALID_ENUM, "bad target", function(){
gl.texImage2D(gl.FLOAT, 0, gl.RGBA, 1,1,0,gl.RGBA,gl.UNSIGNED_BYTE, null);
});
- assertGLError(gl, [gl.INVALID_ENUM, gl.INVALID_VALUE], "bad internal format/format", function(){
+ assertGLErrorIn(gl, [gl.INVALID_ENUM, gl.INVALID_VALUE], "bad internal format/format", function(){
gl.texImage2D(gl.TEXTURE_2D, 0, gl.FLOAT, 1,1,0,gl.FLOAT,gl.UNSIGNED_BYTE, null);
});
assertGLError(gl, gl.INVALID_VALUE, "border > 0", function(){
diff --git a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/resources/js-test-pre.js b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/resources/js-test-pre.js
index 4b902f96f25..6067e0d4608 100644
--- a/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/resources/js-test-pre.js
+++ b/tests/wpt/web-platform-tests/webgl/conformance-1.0.3/resources/js-test-pre.js
@@ -71,16 +71,25 @@ function nonKhronosFrameworkNotifyDone() {
}
}
-var WPT_TEST_ID = 0;
-function reportTestResultsToHarness(success, msg) {
- if (window.parent.webglTestHarness) {
- window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg);
- } else if (window.test) { // WPT test harness
- test(function () {
- assert_true(success, msg);
- }, "WebGL test #" + (WPT_TEST_ID++) + ": " + msg);
+(function() {
+ var WPT_TEST_ID = 0;
+
+ // Store the current WPT test harness `test` function
+ // if found, since it's overriden by some tests.
+ var wpt_test = window.test;
+ var wpt_assert_true = window.assert_true;
+
+
+ window.reportTestResultsToHarness = function reportTestResultsToHarness(success, msg) {
+ if (window.parent.webglTestHarness) {
+ window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg);
+ } else if (wpt_test) { // WPT test harness
+ wpt_test(function () {
+ wpt_assert_true(success, msg);
+ }, "WebGL test #" + (WPT_TEST_ID++) + ": " + msg);
+ }
}
-}
+}())
function notifyFinishedToHarness() {
if (window.parent.webglTestHarness) {
diff --git a/tests/wpt/web-platform-tests/webgl/tools/import-conformance-tests.py b/tests/wpt/web-platform-tests/webgl/tools/import-conformance-tests.py
index 0082e3c7dbf..8ac41a93d24 100755
--- a/tests/wpt/web-platform-tests/webgl/tools/import-conformance-tests.py
+++ b/tests/wpt/web-platform-tests/webgl/tools/import-conformance-tests.py
@@ -81,7 +81,7 @@ def main():
else:
directory = tempfile.mkdtemp()
print("Cloning WebGL repository into temporary directory {}".format(directory))
- subprocess.check_call(["git", "clone", KHRONOS_REPO_URL, directory])
+ subprocess.check_call(["git", "clone", KHRONOS_REPO_URL, directory, "--depth", "1"])
suite_dir = os.path.join(directory, "conformance-suites", version)
print("Test suite directory: {}".format(suite_dir))
@@ -109,6 +109,9 @@ def main():
# Remove html files that are not tests
for dirpath, dirnames, filenames in os.walk(destination):
+ if '/resources' in dirpath:
+ continue # Most of the files under resources directories are used
+
for f in filenames:
if not f.endswith('.html'):
continue
diff --git a/tests/wpt/web-platform-tests/webgl/tools/js-test-pre.patch b/tests/wpt/web-platform-tests/webgl/tools/js-test-pre.patch
index 9c0f7897c33..1e8a4c9581d 100644
--- a/tests/wpt/web-platform-tests/webgl/tools/js-test-pre.patch
+++ b/tests/wpt/web-platform-tests/webgl/tools/js-test-pre.patch
@@ -1,21 +1,36 @@
---- resources/js-test-pre.js 2015-06-18 23:26:41.217622000 +0200
-+++ ../conformance-1.0.3/resources/js-test-pre.js 2015-12-30 19:20:27.852467185 +0100
-@@ -71,9 +71,14 @@
+--- js-test-pre.orig.js 2016-04-08 22:35:15.629226767 +0200
++++ js-test-pre.js 2016-04-08 22:43:11.906092062 +0200
+@@ -71,11 +71,25 @@
}
}
-+var WPT_TEST_ID = 0;
- function reportTestResultsToHarness(success, msg) {
- if (window.parent.webglTestHarness) {
- window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg);
-+ } else if (window.test) { // WPT test harness
-+ test(function () {
-+ assert_true(success, msg);
-+ }, "WebGL test #" + (WPT_TEST_ID++) + ": " + msg);
+-function reportTestResultsToHarness(success, msg) {
+- if (window.parent.webglTestHarness) {
+- window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg);
++(function() {
++ var WPT_TEST_ID = 0;
++
++ // Store the current WPT test harness `test` function
++ // if found, since it's overriden by some tests.
++ var wpt_test = window.test;
++ var wpt_assert_true = window.assert_true;
++
++
++ window.reportTestResultsToHarness = function reportTestResultsToHarness(success, msg) {
++ if (window.parent.webglTestHarness) {
++ window.parent.webglTestHarness.reportResults(window.location.pathname, success, msg);
++ } else if (wpt_test) { // WPT test harness
++ wpt_test(function () {
++ wpt_assert_true(success, msg);
++ }, "WebGL test #" + (WPT_TEST_ID++) + ": " + msg);
++ }
}
- }
+-}
++}())
-@@ -92,7 +97,7 @@
+ function notifyFinishedToHarness() {
+ if (window.parent.webglTestHarness) {
+@@ -92,7 +106,7 @@
window.console.log(msg);
}
@@ -24,7 +39,7 @@
function enableJSTestPreVerboseLogging()
{
-@@ -105,31 +110,18 @@
+@@ -105,31 +119,18 @@
if (msg === undefined) {
msg = document.title;
}
@@ -58,7 +73,7 @@
}
}
-@@ -143,7 +135,7 @@
+@@ -143,7 +144,7 @@
reportTestResultsToHarness(true, msg);
_addSpan('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>');
if (_jsTestPreVerboseLogging) {
diff --git a/tests/wpt/web-platform-tests/webstorage/event_setattribute.js b/tests/wpt/web-platform-tests/webstorage/event_setattribute.js
index 9d8e328fcaf..8070938baf2 100644
--- a/tests/wpt/web-platform-tests/webstorage/event_setattribute.js
+++ b/tests/wpt/web-platform-tests/webstorage/event_setattribute.js
@@ -10,6 +10,9 @@ testStorages(function(storageString) {
function step0(msg)
{
iframe.onload = t.step_func(step1);
+ // Null out the existing handler eventTestHarness.js set up;
+ // otherwise this test won't be testing much of anything useful.
+ iframe.contentWindow.onstorage = null;
iframe.src = "resources/event_setattribute_handler.html";
}
diff --git a/tests/wpt/web-platform-tests/webstorage/resources/event_setattribute_handler.html b/tests/wpt/web-platform-tests/webstorage/resources/event_setattribute_handler.html
index f5d6f8a06ff..b9e2f040216 100644
--- a/tests/wpt/web-platform-tests/webstorage/resources/event_setattribute_handler.html
+++ b/tests/wpt/web-platform-tests/webstorage/resources/event_setattribute_handler.html
@@ -8,7 +8,7 @@ function handleStorageEvent(e) {
window.parent.storageEventList.push(e);
}
-document.body.setAttribute("onstorage", "handleStorageEvent(window.event);");
+document.body.setAttribute("onstorage", "handleStorageEvent(event);");
</script>
</body>