mirror of
https://github.com/servo/servo.git
synced 2025-08-06 22:15:33 +01:00
Update web-platform-tests to revision cd44958a002b1ad494168e0290554644de84526e
This commit is contained in:
parent
2ed23ce4c9
commit
4443426308
103 changed files with 1740 additions and 1138 deletions
|
@ -2,6 +2,10 @@
|
|||
# macOS. Documentation to help understand this setup:
|
||||
# https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema
|
||||
# https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables
|
||||
#
|
||||
# In addition to this configuration file, the "Build pull requests from forks
|
||||
# of this repository" setting must also be enabled in the Azure DevOps project:
|
||||
# https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/github#validate-contributions-from-forks
|
||||
|
||||
trigger: none # disable builds for branches
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ tasks:
|
|||
owner: ${event.pull_request.user.login}@users.noreply.github.com
|
||||
source: ${event.repository.url}
|
||||
payload:
|
||||
image: jugglinmike/web-platform-tests:0.21
|
||||
image: harjgam/web-platform-tests:0.22
|
||||
maxRunTime: 7200
|
||||
artifacts:
|
||||
public/results:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
importScripts('/resources/testharness.js');
|
||||
importScripts('sw-helpers.js');
|
||||
|
||||
async function updateUI(event) {
|
||||
|
@ -13,10 +14,20 @@ async function updateUI(event) {
|
|||
|
||||
return Promise.all(updateParams.map(param => event.updateUI(param)))
|
||||
.then(() => 'update success')
|
||||
.catch(e => e.message);
|
||||
.catch(e => e.name);
|
||||
}
|
||||
|
||||
self.addEventListener('backgroundfetchsuccess', event => {
|
||||
if (event.registration.id === 'update-inactive') {
|
||||
// Post an async task before calling updateUI from the inactive event.
|
||||
// Any async behaviour outside `waitUntil` should mark the event as
|
||||
// inactive, and subsequent calls to `updateUI` should fail.
|
||||
new Promise(r => step_timeout(r, 0))
|
||||
.then(() => event.updateUI({ title: 'New title' }))
|
||||
.catch(e => sendMessageToDocument({ update: e.name }));
|
||||
return;
|
||||
}
|
||||
|
||||
event.waitUntil(updateUI(event)
|
||||
.then(update => sendMessageToDocument({ type: event.type, update })))
|
||||
.then(update => sendMessageToDocument({ update })));
|
||||
});
|
||||
|
|
|
@ -27,6 +27,17 @@ backgroundFetchTest(async (test, backgroundFetch) => {
|
|||
assert_equals(registration.id, registrationId);
|
||||
|
||||
const message = await getMessageFromServiceWorker();
|
||||
assert_equals(message.update, 'updateUI may only be called once.');
|
||||
assert_equals(message.update, 'InvalidStateError');
|
||||
|
||||
}, 'Background Fetch updateUI called twice fails', swName);
|
||||
|
||||
backgroundFetchTest(async (test, backgroundFetch) => {
|
||||
const registrationId = 'update-inactive';
|
||||
const registration =
|
||||
await backgroundFetch.fetch(registrationId, 'resources/feature-name.txt');
|
||||
assert_equals(registration.id, registrationId);
|
||||
|
||||
const message = await getMessageFromServiceWorker();
|
||||
assert_equals(message.update, 'InvalidStateError');
|
||||
|
||||
}, 'Background Fetch updateUI fails when event is not active', swName);
|
||||
|
|
|
@ -645,7 +645,7 @@ test(t => {
|
|||
|
||||
const expected = [
|
||||
{ offset: 0, computedOffset: 0, easing: "ease", composite: "auto",
|
||||
backgroundSize: "auto auto" },
|
||||
backgroundSize: "auto" },
|
||||
{ offset: 1, computedOffset: 1, easing: "ease", composite: "auto",
|
||||
backgroundSize: "50% auto, 6px auto, contain" },
|
||||
];
|
||||
|
@ -657,7 +657,7 @@ test(t => {
|
|||
// Test inheriting a background-size value
|
||||
|
||||
expected[0].backgroundSize = div.style.backgroundSize =
|
||||
"30px auto, 40% auto, auto auto";
|
||||
"30px auto, 40% auto, auto";
|
||||
frames = getKeyframes(div);
|
||||
|
||||
for (let i = 0; i < frames.length; i++) {
|
||||
|
|
|
@ -81,7 +81,7 @@
|
|||
document.getElementById("test").style.backgroundSize = "auto auto";
|
||||
test(function() {
|
||||
assert_equals(getComputedStyle(document.getElementById("test"), null).getPropertyValue("background-size"),
|
||||
"auto auto", "background-size supporting value");
|
||||
"auto", "background-size supporting value");
|
||||
}, "background-size_auto_auto");
|
||||
|
||||
document.getElementById("test").style.backgroundSize = "auto 15px";
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Filter Effects Module Level 2: getComputedValue().backdropFilter</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
|
||||
<meta name="assert" content="backdrop-filter supports omitted arguments'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/computed-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
#target {
|
||||
color: lime;
|
||||
}
|
||||
</style>
|
||||
<div id="target"></div>
|
||||
<script>
|
||||
test_computed_value("backdrop-filter", "none");
|
||||
|
||||
test_computed_value("backdrop-filter", "blur(100px)");
|
||||
test_computed_value("backdrop-filter", "blur()", "blur(0px)");
|
||||
|
||||
test_computed_value("backdrop-filter", "brightness(0)");
|
||||
test_computed_value("backdrop-filter", "brightness(300%)", "brightness(3)");
|
||||
test_computed_value("backdrop-filter", "brightness()", "brightness(0)");
|
||||
|
||||
test_computed_value("backdrop-filter", "contrast(0)");
|
||||
test_computed_value("backdrop-filter", "contrast(300%)", "contrast(3)");
|
||||
test_computed_value("backdrop-filter", "contrast()", "contrast(1)");
|
||||
|
||||
test_computed_value("backdrop-filter", "drop-shadow(1px 2px)", "drop-shadow(rgb(0, 255, 0) 1px 2px 0px)");
|
||||
test_computed_value("backdrop-filter", "drop-shadow(rgb(4, 5, 6) 1px 2px 0px)");
|
||||
|
||||
test_computed_value("backdrop-filter", "grayscale(50%)", "grayscale(0.5)");
|
||||
test_computed_value("backdrop-filter", "grayscale()", "grayscale(1)");
|
||||
|
||||
test_computed_value("backdrop-filter", "hue-rotate(90deg)");
|
||||
test_computed_value("backdrop-filter", "hue-rotate()", "hue-rotate(0deg)");
|
||||
|
||||
test_computed_value("backdrop-filter", "invert(0)");
|
||||
test_computed_value("backdrop-filter", "invert(100%)", "invert(1)");
|
||||
test_computed_value("backdrop-filter", "invert()", "invert(0)");
|
||||
|
||||
test_computed_value("backdrop-filter", "opacity(0)");
|
||||
test_computed_value("backdrop-filter", "opacity(100%)", "opacity(1)");
|
||||
test_computed_value("backdrop-filter", "opacity()", "opacity(1)");
|
||||
|
||||
test_computed_value("backdrop-filter", "saturate(0)");
|
||||
test_computed_value("backdrop-filter", "saturate(300%)", "saturate(3)");
|
||||
test_computed_value("backdrop-filter", "saturate()", "saturate(1)");
|
||||
|
||||
test_computed_value("backdrop-filter", "sepia(0)");
|
||||
test_computed_value("backdrop-filter", "sepia(100%)", "sepia(1)");
|
||||
test_computed_value("backdrop-filter", "sepia()", "sepia(1)");
|
||||
|
||||
test_computed_value("backdrop-filter", 'blur(10px) url("https://www.example.com/picture.svg#f") contrast(20) brightness(30)');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Filter Effects Module Level 2: parsing backdrop-filter with invalid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
|
||||
<meta name="assert" content="backdrop-filter supports only the grammar 'none | <backdrop-filter-function-list>'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
// Edge fails: expected "" but got "none"
|
||||
|
||||
test_invalid_value("backdrop-filter", "auto");
|
||||
test_invalid_value("backdrop-filter", "none hue-rotate(0deg)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "blur(10)");
|
||||
test_invalid_value("backdrop-filter", "blur(-100px)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "brightness(-20)");
|
||||
test_invalid_value("backdrop-filter", "brightness(30px)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "contrast(-20)");
|
||||
test_invalid_value("backdrop-filter", "contrast(30px)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "drop-shadow(10 20)");
|
||||
test_invalid_value("backdrop-filter", "drop-shadow(10% 20%)");
|
||||
test_invalid_value("backdrop-filter", "drop-shadow(1px)");
|
||||
test_invalid_value("backdrop-filter", "drop-shadow(1px 2px 3px 4px)");
|
||||
test_invalid_value("backdrop-filter", "drop-shadow(rgb(4, 5, 6))");
|
||||
test_invalid_value("backdrop-filter", "drop-shadow()");
|
||||
|
||||
test_invalid_value("backdrop-filter", "grayscale(-20)");
|
||||
test_invalid_value("backdrop-filter", "grayscale(30px)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "hue-rotate(90)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "invert(-20)");
|
||||
test_invalid_value("backdrop-filter", "invert(30px)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "opacity(-20)");
|
||||
test_invalid_value("backdrop-filter", "opacity(30px)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "saturate(-20)");
|
||||
test_invalid_value("backdrop-filter", "saturate(30px)");
|
||||
|
||||
test_invalid_value("backdrop-filter", "sepia(-20)");
|
||||
test_invalid_value("backdrop-filter", "sepia(30px)");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,67 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Filter Effects Module Level 2: parsing backdrop-filter with valid values</title>
|
||||
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||
<link rel="help" href="https://drafts.fxtf.org/filter-effects-2/#BackdropFilterProperty">
|
||||
<meta name="assert" content="backdrop-filter supports the full grammar 'none | <backdrop-filter-function-list>'.">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/css/support/parsing-testcommon.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
test_valid_value("backdrop-filter", "none");
|
||||
|
||||
test_valid_value("backdrop-filter", "blur(100px)");
|
||||
test_valid_value("backdrop-filter", "blur(0)", "blur(0px)");
|
||||
test_valid_value("backdrop-filter", "blur()");
|
||||
|
||||
test_valid_value("backdrop-filter", "brightness(0)");
|
||||
test_valid_value("backdrop-filter", "brightness(300%)");
|
||||
test_valid_value("backdrop-filter", "brightness()");
|
||||
|
||||
test_valid_value("backdrop-filter", "contrast(0)");
|
||||
test_valid_value("backdrop-filter", "contrast(300%)");
|
||||
test_valid_value("backdrop-filter", "contrast()");
|
||||
|
||||
test_valid_value("backdrop-filter", "drop-shadow(1px 2px)");
|
||||
test_valid_value("backdrop-filter", "drop-shadow(1px 2px 3px)");
|
||||
test_valid_value("backdrop-filter", "drop-shadow(0 0 0)", "drop-shadow(0px 0px 0px)");
|
||||
test_valid_value("backdrop-filter", "drop-shadow(rgb(4, 5, 6) 1px 2px)");
|
||||
test_valid_value("backdrop-filter", "drop-shadow(1px 2px rgb(4, 5, 6))", "drop-shadow(rgb(4, 5, 6) 1px 2px)");
|
||||
test_valid_value("backdrop-filter", "drop-shadow(rgba(4, 5, 6, 0.75) 1px 2px 3px)");
|
||||
|
||||
test_valid_value("backdrop-filter", "grayscale(0)");
|
||||
test_valid_value("backdrop-filter", "grayscale(300%)", "grayscale(100%)");
|
||||
test_valid_value("backdrop-filter", "grayscale()");
|
||||
|
||||
test_valid_value("backdrop-filter", "hue-rotate(90deg)");
|
||||
test_valid_value("backdrop-filter", "hue-rotate(0)", "hue-rotate(0deg)");
|
||||
test_valid_value("backdrop-filter", "hue-rotate()");
|
||||
|
||||
test_valid_value("backdrop-filter", "invert(0)");
|
||||
test_valid_value("backdrop-filter", "invert(300%)", "invert(100%)");
|
||||
test_valid_value("backdrop-filter", "invert()");
|
||||
|
||||
test_valid_value("backdrop-filter", "opacity(0)");
|
||||
test_valid_value("backdrop-filter", "opacity(300%)", "opacity(100%)");
|
||||
test_valid_value("backdrop-filter", "opacity()");
|
||||
|
||||
test_valid_value("backdrop-filter", "saturate(0)");
|
||||
test_valid_value("backdrop-filter", "saturate(300%)");
|
||||
test_valid_value("backdrop-filter", "saturate()");
|
||||
|
||||
test_valid_value("backdrop-filter", "sepia(0)");
|
||||
test_valid_value("backdrop-filter", "sepia(300%)", "sepia(100%)");
|
||||
test_valid_value("backdrop-filter", "sepia()");
|
||||
|
||||
test_valid_value("backdrop-filter", 'url("picture.svg#f")');
|
||||
|
||||
test_valid_value("backdrop-filter", 'url("https://www.example.com/picture.svg#f")');
|
||||
|
||||
test_valid_value("backdrop-filter", 'blur(10px) url("picture.svg#f") contrast(20) brightness(30)');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
(function() {
|
||||
|
||||
function assert_initial(property, initial) {
|
||||
test(() => {
|
||||
const target = document.getElementById('target');
|
||||
if (!getComputedStyle(target)[property])
|
||||
return;
|
||||
target.style[property] = 'initial';
|
||||
|
@ -13,6 +16,8 @@ function assert_initial(property, initial) {
|
|||
/**
|
||||
* Create tests that a CSS property inherits and has the given initial value.
|
||||
*
|
||||
* The current document must have an element #target within element #container.
|
||||
*
|
||||
* @param {string} property The name of the CSS property being tested.
|
||||
* @param {string} initial The computed value for 'initial'.
|
||||
* @param {string} other An arbitrary value for the property that round
|
||||
|
@ -22,6 +27,8 @@ function assert_inherited(property, initial, other) {
|
|||
assert_initial(property, initial);
|
||||
|
||||
test(() => {
|
||||
const container = document.getElementById('container');
|
||||
const target = document.getElementById('target');
|
||||
if (!getComputedStyle(target)[property])
|
||||
return;
|
||||
container.style[property] = 'initial';
|
||||
|
@ -45,6 +52,8 @@ function assert_inherited(property, initial, other) {
|
|||
* Create tests that a CSS property does not inherit, and that it has the
|
||||
* given initial value.
|
||||
*
|
||||
* The current document must have an element #target within element #container.
|
||||
*
|
||||
* @param {string} property The name of the CSS property being tested.
|
||||
* @param {string} initial The computed value for 'initial'.
|
||||
* @param {string} other An arbitrary value for the property that round
|
||||
|
@ -54,6 +63,8 @@ function assert_not_inherited(property, initial, other) {
|
|||
assert_initial(property, initial);
|
||||
|
||||
test(() => {
|
||||
const container = document.getElementById('container');
|
||||
const target = document.getElementById('target');
|
||||
if (!getComputedStyle(target)[property])
|
||||
return;
|
||||
container.style[property] = 'initial';
|
||||
|
@ -69,3 +80,7 @@ function assert_not_inherited(property, initial, other) {
|
|||
target.style[property] = '';
|
||||
}, 'Property ' + property + ' does not inherit');
|
||||
}
|
||||
|
||||
window.assert_inherited = assert_inherited;
|
||||
window.assert_not_inherited = assert_not_inherited;
|
||||
})();
|
||||
|
|
|
@ -10,14 +10,12 @@ function test_valid_value(property, value, serializedValue) {
|
|||
var stringifiedValue = JSON.stringify(value);
|
||||
|
||||
test(function(){
|
||||
var div = document.createElement('div');
|
||||
div.style[property] = value;
|
||||
assert_not_equals(div.style.getPropertyValue(property), "", "property should be set");
|
||||
|
||||
var div = document.createElement('div');
|
||||
var div = document.getElementById('target') || document.createElement('div');
|
||||
div.style[property] = "";
|
||||
div.style[property] = value;
|
||||
var readValue = div.style.getPropertyValue(property);
|
||||
if (serializedValue instanceof Array)
|
||||
assert_not_equals(readValue, "", "property should be set");
|
||||
if (Array.isArray(serializedValue))
|
||||
assert_in_array(readValue, serializedValue, "serialization should be sound");
|
||||
else
|
||||
assert_equals(readValue, serializedValue, "serialization should be canonical");
|
||||
|
@ -32,7 +30,8 @@ function test_invalid_value(property, value) {
|
|||
var stringifiedValue = JSON.stringify(value);
|
||||
|
||||
test(function(){
|
||||
var div = document.createElement('div');
|
||||
var div = document.getElementById('target') || document.createElement('div');
|
||||
div.style[property] = "";
|
||||
div.style[property] = value;
|
||||
assert_equals(div.style.getPropertyValue(property), "");
|
||||
}, "e.style['" + property + "'] = " + stringifiedValue + " should not set the property value");
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
# <shape-box> only
|
||||
== shape-outside-margin-box-001.html shape-outside-margin-box-001-ref.html
|
||||
== shape-outside-margin-box-002.html shape-outside-margin-box-002-ref.html
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: compare individual transform with transform functions</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<meta name="assert" content="Tests whether individaul transform works correctlyi by compare the rendering result with transfrom functions of the 'transform' property."/>
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
}
|
||||
.row_1 {
|
||||
top: 100px;
|
||||
}
|
||||
.scale_1{
|
||||
left: 100px;
|
||||
width: 50px;
|
||||
height: 100px;
|
||||
transform: scaleX(2);
|
||||
}
|
||||
.translate_1 {
|
||||
left: 150px;
|
||||
transform: translateX(150px);
|
||||
}
|
||||
.rotate_1 {
|
||||
left: 450px;
|
||||
transform-origin: 50% 50%;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.row_2 {
|
||||
top: 250px;
|
||||
}
|
||||
.scale_2{
|
||||
left: 100px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
transform: scale(2, 2);
|
||||
}
|
||||
.translate_2 {
|
||||
left: 150px;
|
||||
top: 200px;
|
||||
transform: translate(150px, 50px);
|
||||
}
|
||||
.rotate_2 {
|
||||
left: 450px;
|
||||
transform-origin: 50% 50%;
|
||||
transform: rotate3d(0, 0, 1, 90deg);
|
||||
}
|
||||
.row_3 {
|
||||
transform: perspective(500px);
|
||||
top: 400px;
|
||||
}
|
||||
.scale_3{
|
||||
left: 100px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
transform: scale3d(2, 2, 2);
|
||||
}
|
||||
.translate_3 {
|
||||
left: 150px;
|
||||
transform: translate3d(150px, 10px, 10px);
|
||||
}
|
||||
.rotate_3 {
|
||||
left: 450px;
|
||||
transform-origin: 50% 50%;
|
||||
transform: rotate3d(0, 1, 0, 45deg);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="scale_1 row_1"></div>
|
||||
<div class="translate_1 row_1"></div>
|
||||
<div class="rotate_1 row_1"></div>
|
||||
<div class="scale_2 row_2"></div>
|
||||
<div class="translate_2 row_2"></div>
|
||||
<div class="rotate_2 row_2"></div>
|
||||
<div class="scale_3 row_3"></div>
|
||||
<div class="translate_3 row_3"></div>
|
||||
<div class="rotate_3 row_3"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,100 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: compare individual transform with transform functions</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<meta name="assert" content="Tests whether individaul transform works correctlyi by compare the rendering result with transfrom functions of the 'transform' property."/>
|
||||
<link rel="match" href="individual-transform-1-ref.html">
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
}
|
||||
.row_1 {
|
||||
top: 100px;
|
||||
}
|
||||
.scale_1{
|
||||
left: 100px;
|
||||
width: 50px;
|
||||
height: 100px;
|
||||
/* test 'scale: <number>' */
|
||||
scale: 2;
|
||||
}
|
||||
.translate_1 {
|
||||
left: 150px;
|
||||
/* test 'translate: <length-percentage>' */
|
||||
translate: 150px;
|
||||
}
|
||||
.rotate_1 {
|
||||
left: 450px;
|
||||
transform-origin: 50% 50%;
|
||||
/* test 'rota: te<angle>' */
|
||||
rotate: 90deg;
|
||||
}
|
||||
|
||||
.row_2 {
|
||||
top: 250px;
|
||||
}
|
||||
.scale_2{
|
||||
left: 100px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* test 'scale: <number>{2}'' */
|
||||
scale: 2 2;
|
||||
}
|
||||
.translate_2 {
|
||||
left: 150px;
|
||||
top: 200px;
|
||||
/* test 'translate: <length-percentage><length-percentage>' */
|
||||
translate: 150px 50px;
|
||||
}
|
||||
.rotate_2 {
|
||||
left: 450px;
|
||||
transform-origin: 50% 50%;
|
||||
/* test 'rotate: <number>{3}<angle>'*/
|
||||
rotate: 0 0 1 90deg;
|
||||
}
|
||||
.row_3 {
|
||||
transform: perspective(500px);
|
||||
top: 400px;
|
||||
}
|
||||
.scale_3{
|
||||
left: 100px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
/* test 'scale: <number>{3}'' */
|
||||
scale: 2 2 2;
|
||||
}
|
||||
.translate_3 {
|
||||
left: 150px;
|
||||
/* test 'translate: <length-percentage><length>' */
|
||||
translate: 150px 10px 10px;
|
||||
}
|
||||
.rotate_3 {
|
||||
left: 450px;
|
||||
transform-origin: 50% 50%;
|
||||
/* test 'rotate: <number>{3}<angle>'*/
|
||||
rotate: 0 1 0 45deg;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="scale_1 row_1"></div>
|
||||
<div class="translate_1 row_1"></div>
|
||||
<div class="rotate_1 row_1"></div>
|
||||
<div class="scale_2 row_2"></div>
|
||||
<div class="translate_2 row_2"></div>
|
||||
<div class="rotate_2 row_2"></div>
|
||||
<div class="scale_3 row_3"></div>
|
||||
<div class="translate_3 row_3"></div>
|
||||
<div class="rotate_3 row_3"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,30 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: combine individual transform properties</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
|
||||
<meta name="assert" content="Tests that we combine transforms in the correct order."/>
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
transform: translate(50px, 50px) rotate(45deg) scale(2, 2);
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: combine individual transform properties</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
|
||||
<meta name="assert" content="Tests that we combine transforms in the correct order."/>
|
||||
<link rel="match" href="individual-transform-2-ref.html">
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
translate: 50px 50px;
|
||||
rotate: 45deg;
|
||||
scale: 2 2;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: combine individual transform properties</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
|
||||
<meta name="assert" content="Tests that we combine transforms in the correct order."/>
|
||||
<link rel="match" href="individual-transform-2-ref.html">
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
rotate: 45deg;
|
||||
scale: 2 2;
|
||||
translate: 50px 50px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,32 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: combine individual transform properties</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
|
||||
<meta name="assert" content="Tests that we combine transforms in the correct order."/>
|
||||
<link rel="match" href="individual-transform-2-ref.html">
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
translate: 50px 50px;
|
||||
rotate: 45deg;
|
||||
transform: scale(2, 2);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,31 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: combine individual transform properties</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
|
||||
<meta name="assert" content="Tests that we combine transforms in the correct order."/>
|
||||
<link rel="match" href="individual-transform-2-ref.html">
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
translate: 50px 50px;
|
||||
transform: rotate(45deg) scale(2, 2);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,31 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Individual transform: combine individual transform properties</title>
|
||||
<link rel="author" title="CJ Ku" href="mailto:cku@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#individual-transforms">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-transforms-2/#ctm">
|
||||
<meta name="assert" content="Tests that we combine transforms in the correct order."/>
|
||||
<link rel="match" href="individual-transform-2-ref.html">
|
||||
<style>
|
||||
div {
|
||||
position: fixed;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
top: 200px;
|
||||
left: 200px;
|
||||
transform-origin: 0 0;
|
||||
border-style: solid;
|
||||
border-width: 10px 0px 10px 0px;
|
||||
border-color: lime;
|
||||
translate: 0px 50px;
|
||||
transform: translateX(50px) rotate(45deg) scale(2, 2);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
</body>
|
||||
</html>
|
|
@ -5,10 +5,3 @@
|
|||
== perspective-zero.html reference/green.html
|
||||
== perspective-zero-2.html perspective-zero-2-ref.html
|
||||
== perspective-untransformable-no-stacking-context.html perspective-untransformable-no-stacking-context-ref.html
|
||||
|
||||
== individual-transform-1.html individual-transform-1-ref.html
|
||||
== individual-transform-2a.html individual-transform-2-ref.html
|
||||
== individual-transform-2b.html individual-transform-2-ref.html
|
||||
== individual-transform-2c.html individual-transform-2-ref.html
|
||||
== individual-transform-2d.html individual-transform-2-ref.html
|
||||
== individual-transform-2e.html individual-transform-2-ref.html
|
||||
|
|
|
@ -9,6 +9,12 @@ To run Safari on macOS, some manual setup is required:
|
|||
* Allow pop-up windows:
|
||||
`defaults write com.apple.Safari WebKitJavaScriptCanOpenWindowsAutomatically 1`
|
||||
|
||||
* Turn on experimental features that are "off" by default:
|
||||
|
||||
* `defaults write com.apple.Safari ExperimentalServerTimingEnabled -bool true`
|
||||
|
||||
[//]: # (TODO\(cvazac\) Remove this if/when Server-Timing is enabled by default in Safari)
|
||||
|
||||
* Trust the certificate:
|
||||
`security add-trusted-cert -k "$(security default-keychain | cut -d\" -f2)" tools/certs/cacert.pem`
|
||||
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<script src=/feature-policy/resources/featurepolicy.js></script>
|
||||
<!-- Feature-Policy: fullscreen *; -->
|
||||
<script>
|
||||
|
@ -143,3 +147,4 @@
|
|||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<script src=/feature-policy/resources/featurepolicy.js></script>
|
||||
<!-- Feature-Policy: fullscreen 'self'; -->
|
||||
<script>
|
||||
|
@ -177,3 +181,4 @@
|
|||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<script src=/feature-policy/resources/featurepolicy.js></script>
|
||||
<!-- Feature-Policy: fullscreen 'self' cross_origin https://www.example.com; -->
|
||||
<script>
|
||||
|
@ -184,3 +188,4 @@
|
|||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<body>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="timeout" content="long">
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<script src=/feature-policy/resources/featurepolicy.js></script>
|
||||
<!-- Feature-Policy: fullscreen 'none'; -->
|
||||
<script>
|
||||
|
@ -143,3 +147,4 @@
|
|||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
<script src="/common/PrefixedPostMessage.js"></script>
|
||||
<script>
|
||||
var prefixedMessage = new PrefixedMessageResource();
|
||||
var max = 50, attempts = 0;
|
||||
var max = 150, attempts = 0;
|
||||
function sendCoordinates() {
|
||||
// Certain windowing systems position windows asynchronously.
|
||||
// As a result, the window may not be positioned yet when the
|
||||
// load event fires. To accommodate this, allow waiting up to
|
||||
// 5 seconds for positioning to take place.
|
||||
// 15 seconds for positioning to take place.
|
||||
if (!window.screenX && !window.screenY && ++attempts < max) {
|
||||
setTimeout(sendCoordinates, 100);
|
||||
return;
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>MediaDevices and SecureContext</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
assert_false(window.isSecureContext, "This test must be run in a non secure context");
|
||||
assert_false('MediaDevices' in window, "MediaDevices is not exposed");
|
||||
assert_false('getUserMedia' in navigator, "getUserMedia is not exposed");
|
||||
assert_false('mediaDevices' in navigator, "mediaDevices is not exposed");
|
||||
|
||||
done();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
div {
|
||||
font-size: 10px;
|
||||
line-height: 50px;
|
||||
border: 1px solid blue;
|
||||
}
|
||||
img {
|
||||
width: 1em;
|
||||
height: 2em;
|
||||
background: orange;
|
||||
border: 1px solid black;
|
||||
}
|
||||
.text-top {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
.text-bottom {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
.top {
|
||||
vertical-align: top;
|
||||
}
|
||||
.bottom {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div>
|
||||
<img class="text-top" src="../../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="text-bottom" src="../../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="top" src="../../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="bottom" src="../../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="text-top" src="../../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
<div>
|
||||
<img class="text-bottom" src="../../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
<div>
|
||||
<img class="top" src="../../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
<div>
|
||||
<img class="bottom" src="../../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
</body>
|
|
@ -0,0 +1,56 @@
|
|||
<meta charset="utf-8">
|
||||
<title>CSS Text level 3 Test: letter spacing after bidi</title>
|
||||
<link rel="author" href="kojii@chromium.org">
|
||||
<link rel="match" href="reference/vertical-align-in-quirks-ref.html">
|
||||
<meta name="assert" content="Tests some vertical-align values match in quirks and standard modes.">
|
||||
<style>
|
||||
div {
|
||||
font-size: 10px;
|
||||
line-height: 50px;
|
||||
border: 1px solid blue;
|
||||
}
|
||||
img {
|
||||
width: 1em;
|
||||
height: 2em;
|
||||
background: orange;
|
||||
border: 1px solid black;
|
||||
}
|
||||
.text-top {
|
||||
vertical-align: text-top;
|
||||
}
|
||||
.text-bottom {
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
.top {
|
||||
vertical-align: top;
|
||||
}
|
||||
.bottom {
|
||||
vertical-align: bottom;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
<div>
|
||||
<img class="text-top" src="../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="text-bottom" src="../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="top" src="../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="bottom" src="../css/support/60x60-red.png">Y
|
||||
</div>
|
||||
<div>
|
||||
<img class="text-top" src="../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
<div>
|
||||
<img class="text-bottom" src="../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
<div>
|
||||
<img class="top" src="../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
<div>
|
||||
<img class="bottom" src="../css/support/60x60-red.png"><span>Y</span>
|
||||
</div>
|
||||
</body>
|
|
@ -4,46 +4,13 @@
|
|||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
const base_url = 'resources/blank.html'; // This is out-of-scope.
|
||||
const scope = base_url + '?clients-matchAll-includeUncontrolled';
|
||||
let frames = [];
|
||||
|
||||
// Creates 3 iframes, 2 for in-scope and 1 for out-of-scope. Returns the frame
|
||||
// opened for scope + '#2'.
|
||||
async function create_iframes(scope) {
|
||||
frames.push(await with_iframe(base_url));
|
||||
frames.push(await with_iframe(scope + '#1'));
|
||||
frames.push(await with_iframe(scope + '#2'));
|
||||
return frames[2];
|
||||
}
|
||||
|
||||
const expected_without_include_uncontrolled = [
|
||||
// visibilityState, focused, url, type, frameType
|
||||
['visible', false, new URL(scope + '#1', location).toString(), 'window', 'nested'],
|
||||
['visible', true, new URL(scope + '#2', location).toString(), 'window', 'nested']
|
||||
];
|
||||
|
||||
const expected_with_include_uncontrolled = [
|
||||
// visibilityState, focused, url, type, frameType
|
||||
['visible', true, location.href, 'window', 'top-level'],
|
||||
['visible', false, new URL(scope + '#1', location).toString(), 'window', 'nested'],
|
||||
['visible', true, new URL(scope + '#2', location).toString(), 'window', 'nested'],
|
||||
['visible', false, new URL(base_url, location).toString(), 'window', '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();
|
||||
function test_matchall(service_worker, expected, query_options) {
|
||||
expected.sort((a, b) => a[2] > b[2] ? 1 : -1);
|
||||
return new Promise((resolve, reject) => {
|
||||
const channel = new MessageChannel();
|
||||
channel.port1.onmessage = e => {
|
||||
// Ignore hidden clients which may be coming from background tabs, or
|
||||
// clients unrelated to this test.
|
||||
const data = e.data.filter(info => {
|
||||
return info[0] == 'visible' &&
|
||||
info[2].indexOf('service-worker') > -1;
|
||||
return info[2].indexOf('clients-matchall') > -1;
|
||||
});
|
||||
data.sort((a, b) => a[2] > b[2] ? 1 : -1);
|
||||
assert_equals(data.length, expected.length);
|
||||
|
@ -51,9 +18,8 @@ function test_matchall(frame, expected, query_options) {
|
|||
assert_array_equals(data[i], expected[i]);
|
||||
resolve();
|
||||
};
|
||||
frame.contentWindow.navigator.serviceWorker.controller.postMessage(
|
||||
{port:channel.port2, options:query_options},
|
||||
[channel.port2]);
|
||||
service_worker.postMessage({port:channel.port2, options:query_options},
|
||||
[channel.port2]);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -61,14 +27,91 @@ function test_matchall(frame, expected, query_options) {
|
|||
// (We want to run the two tests sequentially in the same promise_test
|
||||
// so that we can use the same set of iframes without intefering each other.
|
||||
promise_test(async t => {
|
||||
// |base_url| is out-of-scope.
|
||||
const base_url = 'resources/blank.html?clients-matchall';
|
||||
const scope = base_url + '-includeUncontrolled';
|
||||
|
||||
const registration =
|
||||
await service_worker_unregister_and_register(
|
||||
t, 'resources/clients-matchall-worker.js', scope);
|
||||
t.add_cleanup(() => service_worker_unregister(t, scope));
|
||||
await wait_for_state(t, registration.installing, 'activated');
|
||||
const frame = await create_iframes(scope);
|
||||
await test_matchall(frame, expected_without_include_uncontrolled);
|
||||
await test_matchall(frame, expected_with_include_uncontrolled,
|
||||
{includeUncontrolled:true});
|
||||
}, 'Verify matchAll() respect includeUncontrolled');
|
||||
const service_worker = registration.installing;
|
||||
await wait_for_state(t, service_worker, 'activated');
|
||||
|
||||
// Creates 3 iframes, 2 for in-scope and 1 for out-of-scope.
|
||||
let frames = [];
|
||||
frames.push(await with_iframe(base_url));
|
||||
frames.push(await with_iframe(scope + '#1'));
|
||||
frames.push(await with_iframe(scope + '#2'));
|
||||
|
||||
// Make sure we have focus for '#2' frame and its parent window.
|
||||
frames[2].focus();
|
||||
frames[2].contentWindow.focus();
|
||||
|
||||
const expected_without_include_uncontrolled = [
|
||||
// visibilityState, focused, url, type, frameType
|
||||
['visible', false, new URL(scope + '#1', location).toString(), 'window', 'nested'],
|
||||
['visible', true, new URL(scope + '#2', location).toString(), 'window', 'nested']
|
||||
];
|
||||
const expected_with_include_uncontrolled = [
|
||||
// visibilityState, focused, url, type, frameType
|
||||
['visible', true, location.href, 'window', 'top-level'],
|
||||
['visible', false, new URL(scope + '#1', location).toString(), 'window', 'nested'],
|
||||
['visible', true, new URL(scope + '#2', location).toString(), 'window', 'nested'],
|
||||
['visible', false, new URL(base_url, location).toString(), 'window', 'nested']
|
||||
];
|
||||
|
||||
await test_matchall(service_worker, expected_without_include_uncontrolled);
|
||||
await test_matchall(service_worker, expected_with_include_uncontrolled,
|
||||
{ includeUncontrolled: true });
|
||||
}, 'Verify matchAll() with windows respect includeUncontrolled');
|
||||
|
||||
// TODO: Add tests for clients.matchAll for dedicated workers.
|
||||
|
||||
async function create_shared_worker(script_url) {
|
||||
const shared_worker = new SharedWorker(script_url);
|
||||
const msgEvent = await new Promise(r => shared_worker.port.onmessage = r);
|
||||
assert_equals(msgEvent.data, 'started');
|
||||
return shared_worker;
|
||||
}
|
||||
|
||||
// Run clients.matchAll for shared workers without and with
|
||||
// includeUncontrolled=true.
|
||||
promise_test(async t => {
|
||||
const script_url = 'resources/clients-matchall-client-types-shared-worker.js';
|
||||
const uncontrolled_script_url =
|
||||
new URL(script_url + '?uncontrolled', location).toString();
|
||||
const controlled_script_url =
|
||||
new URL(script_url + '?controlled', location).toString();
|
||||
|
||||
// Start a shared worker that is not controlled by a service worker.
|
||||
const uncontrolled_shared_worker =
|
||||
await create_shared_worker(uncontrolled_script_url);
|
||||
|
||||
// Register a service worker.
|
||||
const registration =
|
||||
await service_worker_unregister_and_register(
|
||||
t, 'resources/clients-matchall-worker.js', script_url);
|
||||
t.add_cleanup(() => service_worker_unregister(t, script_url));
|
||||
const service_worker = registration.installing;
|
||||
await wait_for_state(t, service_worker, 'activated');
|
||||
|
||||
// Start another shared worker controlled by the service worker.
|
||||
await create_shared_worker(controlled_script_url);
|
||||
|
||||
const expected_without_include_uncontrolled = [
|
||||
// visibilityState, focused, url, type, frameType
|
||||
[undefined, undefined, controlled_script_url, 'sharedworker', 'none'],
|
||||
];
|
||||
const expected_with_include_uncontrolled = [
|
||||
// visibilityState, focused, url, type, frameType
|
||||
[undefined, undefined, controlled_script_url, 'sharedworker', 'none'],
|
||||
[undefined, undefined, uncontrolled_script_url, 'sharedworker', 'none'],
|
||||
];
|
||||
|
||||
await test_matchall(service_worker, expected_without_include_uncontrolled,
|
||||
{ type: 'sharedworker' });
|
||||
await test_matchall(service_worker, expected_with_include_uncontrolled,
|
||||
{ includeUncontrolled: true, type: 'sharedworker' });
|
||||
}, 'Verify matchAll() with shared workers respect includeUncontrolled');
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>abort.js dedicated worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new Worker('abort.js'));
|
||||
</script>
|
11
tests/wpt/web-platform-tests/streams/piping/abort.html
Normal file
11
tests/wpt/web-platform-tests/streams/piping/abort.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>abort.js browser context wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script src="../resources/recording-streams.js"></script>
|
||||
<script src="../resources/test-utils.js"></script>
|
||||
|
||||
<script src="abort.js"></script>
|
365
tests/wpt/web-platform-tests/streams/piping/abort.js
Normal file
365
tests/wpt/web-platform-tests/streams/piping/abort.js
Normal file
|
@ -0,0 +1,365 @@
|
|||
'use strict';
|
||||
|
||||
// Tests for the use of pipeTo with AbortSignal.
|
||||
// There is some extra complexity to avoid timeouts in environments where abort is not implemented.
|
||||
|
||||
if (self.importScripts) {
|
||||
self.importScripts('/resources/testharness.js');
|
||||
self.importScripts('../resources/recording-streams.js');
|
||||
self.importScripts('../resources/test-utils.js');
|
||||
}
|
||||
|
||||
const error1 = new Error('error1');
|
||||
error1.name = 'error1';
|
||||
const error2 = new Error('error2');
|
||||
error2.name = 'error2';
|
||||
|
||||
const errorOnPull = {
|
||||
pull(controller) {
|
||||
// This will cause the test to error if pipeTo abort is not implemented.
|
||||
controller.error('failed to abort');
|
||||
}
|
||||
};
|
||||
|
||||
// To stop pull() being called immediately when the stream is created, we need to set highWaterMark to 0.
|
||||
const hwm0 = { highWaterMark: 0 };
|
||||
|
||||
for (const invalidSignal of [null, 'AbortSignal', true, -1, Object.create(AbortSignal.prototype)]) {
|
||||
promise_test(t => {
|
||||
const rs = recordingReadableStream(errorOnPull, hwm0);
|
||||
const ws = recordingWritableStream();
|
||||
return promise_rejects(t, new TypeError(), rs.pipeTo(ws, { signal: invalidSignal }), 'pipeTo should reject')
|
||||
.then(() => {
|
||||
assert_equals(rs.events.length, 0, 'no ReadableStream methods should have been called');
|
||||
assert_equals(ws.events.length, 0, 'no WritableStream methods should have been called');
|
||||
});
|
||||
}, `a signal argument '${invalidSignal}' should cause pipeTo() to reject`);
|
||||
}
|
||||
|
||||
promise_test(t => {
|
||||
const rs = recordingReadableStream(errorOnPull, hwm0);
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject')
|
||||
.then(() => Promise.all([
|
||||
rs.getReader().closed,
|
||||
promise_rejects(t, 'AbortError', ws.getWriter().closed, 'writer.closed should reject')
|
||||
]))
|
||||
.then(() => {
|
||||
assert_equals(rs.events.length, 2, 'cancel should have been called');
|
||||
assert_equals(rs.events[0], 'cancel', 'first event should be cancel');
|
||||
assert_equals(rs.events[1].name, 'AbortError', 'the argument to cancel should be an AbortError');
|
||||
assert_equals(rs.events[1].constructor.name, 'DOMException',
|
||||
'the argument to cancel should be a DOMException');
|
||||
});
|
||||
}, 'an aborted signal should cause the writable stream to reject with an AbortError');
|
||||
|
||||
promise_test(() => {
|
||||
let error;
|
||||
const rs = recordingReadableStream(errorOnPull, hwm0);
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return rs.pipeTo(ws, { signal })
|
||||
.catch(e => {
|
||||
error = e;
|
||||
})
|
||||
.then(() => Promise.all([
|
||||
rs.getReader().closed,
|
||||
ws.getWriter().closed.catch(e => {
|
||||
assert_equals(e, error, 'the writable should be errored with the same object');
|
||||
})
|
||||
]))
|
||||
.then(() => {
|
||||
assert_equals(rs.events.length, 2, 'cancel should have been called');
|
||||
assert_equals(rs.events[0], 'cancel', 'first event should be cancel');
|
||||
assert_equals(rs.events[1], error, 'the readable should be canceled with the same object');
|
||||
});
|
||||
}, 'all the AbortError objects should be the same object');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = recordingReadableStream(errorOnPull, hwm0);
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal, preventCancel: true }), 'pipeTo should reject')
|
||||
.then(() => assert_equals(rs.events.length, 0, 'cancel should not be called'));
|
||||
}, 'preventCancel should prevent canceling the readable');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream(errorOnPull, hwm0);
|
||||
const ws = recordingWritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal, preventAbort: true }), 'pipeTo should reject')
|
||||
.then(() => {
|
||||
assert_equals(ws.events.length, 0, 'writable should not have been aborted');
|
||||
return ws.getWriter().ready;
|
||||
});
|
||||
}, 'preventAbort should prevent aborting the readable');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.enqueue('a');
|
||||
controller.enqueue('b');
|
||||
controller.close();
|
||||
}
|
||||
});
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const ws = recordingWritableStream({
|
||||
write() {
|
||||
abortController.abort();
|
||||
}
|
||||
});
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject')
|
||||
.then(() => {
|
||||
assert_equals(ws.events.length, 4, 'only chunk "a" should have been written');
|
||||
assert_array_equals(ws.events.slice(0, 3), ['write', 'a', 'abort'], 'events should match');
|
||||
assert_equals(ws.events[3].name, 'AbortError', 'abort reason should be an AbortError');
|
||||
});
|
||||
}, 'abort should prevent further reads');
|
||||
|
||||
promise_test(t => {
|
||||
let readController;
|
||||
const rs = new ReadableStream({
|
||||
start(c) {
|
||||
readController = c;
|
||||
c.enqueue('a');
|
||||
c.enqueue('b');
|
||||
}
|
||||
});
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
let resolveWrite;
|
||||
const writePromise = new Promise(resolve => {
|
||||
resolveWrite = resolve;
|
||||
});
|
||||
const ws = recordingWritableStream({
|
||||
write() {
|
||||
return writePromise;
|
||||
}
|
||||
}, new CountQueuingStrategy({ highWaterMark: Infinity }));
|
||||
const pipeToPromise = rs.pipeTo(ws, { signal });
|
||||
return delay(0).then(() => {
|
||||
abortController.abort();
|
||||
readController.close(); // Make sure the test terminates when signal is not implemented.
|
||||
resolveWrite();
|
||||
return promise_rejects(t, 'AbortError', pipeToPromise, 'pipeTo should reject');
|
||||
}).then(() => {
|
||||
assert_equals(ws.events.length, 6, 'chunks "a" and "b" should have been written');
|
||||
assert_array_equals(ws.events.slice(0, 5), ['write', 'a', 'write', 'b', 'abort'], 'events should match');
|
||||
assert_equals(ws.events[5].name, 'AbortError', 'abort reason should be an AbortError');
|
||||
});
|
||||
}, 'all pending writes should complete on abort');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream({
|
||||
pull(controller) {
|
||||
controller.error('failed to abort');
|
||||
},
|
||||
cancel() {
|
||||
return Promise.reject(error1);
|
||||
}
|
||||
}, hwm0);
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, error1, rs.pipeTo(ws, { signal }), 'pipeTo should reject');
|
||||
}, 'a rejection from underlyingSource.cancel() should be returned by pipeTo()');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream(errorOnPull, hwm0);
|
||||
const ws = new WritableStream({
|
||||
abort() {
|
||||
return Promise.reject(error1);
|
||||
}
|
||||
});
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, error1, rs.pipeTo(ws, { signal }), 'pipeTo should reject');
|
||||
}, 'a rejection from underlyingSink.abort() should be returned by pipeTo()');
|
||||
|
||||
promise_test(t => {
|
||||
const events = [];
|
||||
const rs = new ReadableStream({
|
||||
pull(controller) {
|
||||
controller.error('failed to abort');
|
||||
},
|
||||
cancel() {
|
||||
events.push('cancel');
|
||||
return Promise.reject(error1);
|
||||
}
|
||||
}, hwm0);
|
||||
const ws = new WritableStream({
|
||||
abort() {
|
||||
events.push('abort');
|
||||
return Promise.reject(error2);
|
||||
}
|
||||
});
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, error2, rs.pipeTo(ws, { signal }), 'pipeTo should reject')
|
||||
.then(() => assert_array_equals(events, ['abort', 'cancel'], 'abort() should be called before cancel()'));
|
||||
}, 'a rejection from underlyingSink.abort() should be preferred to one from underlyingSource.cancel()');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.close();
|
||||
}
|
||||
});
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
|
||||
}, 'abort signal takes priority over closed readable');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream({
|
||||
start(controller) {
|
||||
controller.error(error1);
|
||||
}
|
||||
});
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
|
||||
}, 'abort signal takes priority over errored readable');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream({
|
||||
pull(controller) {
|
||||
controller.error('failed to abort');
|
||||
}
|
||||
}, hwm0);
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
const writer = ws.getWriter();
|
||||
return writer.close().then(() => {
|
||||
writer.releaseLock();
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
|
||||
});
|
||||
}, 'abort signal takes priority over closed writable');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = new ReadableStream({
|
||||
pull(controller) {
|
||||
controller.error('failed to abort');
|
||||
}
|
||||
}, hwm0);
|
||||
const ws = new WritableStream({
|
||||
start(controller) {
|
||||
controller.error(error1);
|
||||
}
|
||||
});
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
abortController.abort();
|
||||
return promise_rejects(t, 'AbortError', rs.pipeTo(ws, { signal }), 'pipeTo should reject');
|
||||
}, 'abort signal takes priority over errored writable');
|
||||
|
||||
promise_test(() => {
|
||||
let readController;
|
||||
const rs = new ReadableStream({
|
||||
start(c) {
|
||||
readController = c;
|
||||
}
|
||||
});
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const pipeToPromise = rs.pipeTo(ws, { signal, preventClose: true });
|
||||
readController.close();
|
||||
return Promise.resolve().then(() => {
|
||||
abortController.abort();
|
||||
return pipeToPromise;
|
||||
}).then(() => ws.getWriter().write('this should succeed'));
|
||||
}, 'abort should do nothing after the readable is closed');
|
||||
|
||||
promise_test(t => {
|
||||
let readController;
|
||||
const rs = new ReadableStream({
|
||||
start(c) {
|
||||
readController = c;
|
||||
}
|
||||
});
|
||||
const ws = new WritableStream();
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const pipeToPromise = rs.pipeTo(ws, { signal, preventAbort: true });
|
||||
readController.error(error1);
|
||||
return Promise.resolve().then(() => {
|
||||
abortController.abort();
|
||||
return promise_rejects(t, error1, pipeToPromise, 'pipeTo should reject');
|
||||
}).then(() => ws.getWriter().write('this should succeed'));
|
||||
}, 'abort should do nothing after the readable is errored');
|
||||
|
||||
promise_test(t => {
|
||||
let readController;
|
||||
const rs = new ReadableStream({
|
||||
start(c) {
|
||||
readController = c;
|
||||
}
|
||||
});
|
||||
let resolveWrite;
|
||||
const writePromise = new Promise(resolve => {
|
||||
resolveWrite = resolve;
|
||||
});
|
||||
const ws = new WritableStream({
|
||||
write() {
|
||||
readController.error(error1);
|
||||
return writePromise;
|
||||
}
|
||||
});
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const pipeToPromise = rs.pipeTo(ws, { signal, preventAbort: true });
|
||||
readController.enqueue('a');
|
||||
return delay(0).then(() => {
|
||||
abortController.abort();
|
||||
resolveWrite();
|
||||
return promise_rejects(t, error1, pipeToPromise, 'pipeTo should reject');
|
||||
}).then(() => ws.getWriter().write('this should succeed'));
|
||||
}, 'abort should do nothing after the readable is errored, even with pending writes');
|
||||
|
||||
promise_test(t => {
|
||||
const rs = recordingReadableStream({
|
||||
pull(controller) {
|
||||
return delay(0).then(() => controller.close());
|
||||
}
|
||||
});
|
||||
let writeController;
|
||||
const ws = new WritableStream({
|
||||
start(c) {
|
||||
writeController = c;
|
||||
}
|
||||
});
|
||||
const abortController = new AbortController();
|
||||
const signal = abortController.signal;
|
||||
const pipeToPromise = rs.pipeTo(ws, { signal, preventCancel: true });
|
||||
return Promise.resolve().then(() => {
|
||||
writeController.error(error1);
|
||||
return Promise.resolve();
|
||||
}).then(() => {
|
||||
abortController.abort();
|
||||
return promise_rejects(t, error1, pipeToPromise, 'pipeTo should reject');
|
||||
}).then(() => {
|
||||
assert_array_equals(rs.events, ['pull'], 'cancel should not have been called');
|
||||
});
|
||||
}, 'abort should do nothing after the writable is errored');
|
||||
|
||||
done();
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>abort.js service worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
service_worker_test('abort.js', 'Service worker test setup');
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>abort.js shared worker wrapper file</title>
|
||||
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
|
||||
<script>
|
||||
'use strict';
|
||||
fetch_tests_from_worker(new SharedWorker('abort.js'));
|
||||
</script>
|
22
tests/wpt/web-platform-tests/svg/interact/inheritance.svg
Normal file
22
tests/wpt/web-platform-tests/svg/interact/inheritance.svg
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:h="http://www.w3.org/1999/xhtml"
|
||||
width="800px" height="8000px">
|
||||
<title>Inheritance of pointer-events</title>
|
||||
<metadata>
|
||||
<h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty"/>
|
||||
<h:meta name="assert" content="pointer-events inherits according to the spec."/>
|
||||
<h:meta name="assert" content="pointer-events has initial value auto."/>
|
||||
</metadata>
|
||||
<g id="container">
|
||||
<g id="target"></g>
|
||||
</g>
|
||||
<h:script src="/resources/testharness.js"/>
|
||||
<h:script src="/resources/testharnessreport.js"/>
|
||||
<h:script src="/css/support/inheritance-testcommon.js"/>
|
||||
<script><![CDATA[
|
||||
|
||||
assert_inherited('pointer-events', 'auto', 'none');
|
||||
|
||||
]]></script>
|
||||
</svg>
|
After Width: | Height: | Size: 799 B |
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:h="http://www.w3.org/1999/xhtml"
|
||||
width="800px" height="8000px">
|
||||
<title>SVG Scripting and Interactivity: parsing pointer-events with invalid values</title>
|
||||
<metadata>
|
||||
<h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty"/>
|
||||
<h:meta name="assert" content="pointer-events supports only the grammar 'auto | bounding-box | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | none'."/>
|
||||
</metadata>
|
||||
<g id="target"></g>
|
||||
<h:script src="/resources/testharness.js"/>
|
||||
<h:script src="/resources/testharnessreport.js"/>
|
||||
<h:script src="/css/support/parsing-testcommon.js"/>
|
||||
<script><![CDATA[
|
||||
|
||||
test_invalid_value("pointer-events", "markers");
|
||||
test_invalid_value("pointer-events", "0");
|
||||
test_invalid_value("pointer-events", "visiblePainted visibleFill");
|
||||
|
||||
]]></script>
|
||||
</svg>
|
After Width: | Height: | Size: 953 B |
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:h="http://www.w3.org/1999/xhtml"
|
||||
width="800px" height="8000px">
|
||||
<title>SVG Scripting and Interactivity: parsing pointer-events with valid values</title>
|
||||
<metadata>
|
||||
<h:link rel="help" href="https://svgwg.org/svg2-draft/interact.html#PointerEventsProperty"/>
|
||||
<h:meta name="assert" content="pointer-events supports the full grammar 'auto | bounding-box | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | none'."/>
|
||||
</metadata>
|
||||
<g id="target"></g>
|
||||
<h:script src="/resources/testharness.js"/>
|
||||
<h:script src="/resources/testharnessreport.js"/>
|
||||
<h:script src="/css/support/parsing-testcommon.js"/>
|
||||
<script><![CDATA[
|
||||
|
||||
test_valid_value("pointer-events", "auto");
|
||||
test_valid_value("pointer-events", "bounding-box");
|
||||
test_valid_value("pointer-events", "visiblePainted");
|
||||
test_valid_value("pointer-events", "visibleFill");
|
||||
test_valid_value("pointer-events", "visibleStroke");
|
||||
test_valid_value("pointer-events", "visible");
|
||||
test_valid_value("pointer-events", "painted");
|
||||
test_valid_value("pointer-events", "fill");
|
||||
test_valid_value("pointer-events", "stroke");
|
||||
test_valid_value("pointer-events", "all");
|
||||
test_valid_value("pointer-events", "none");
|
||||
|
||||
]]></script>
|
||||
</svg>
|
After Width: | Height: | Size: 1.3 KiB |
|
@ -89,7 +89,11 @@ def run(*args, **kwargs):
|
|||
logger.info(path)
|
||||
|
||||
|
||||
def __main__():
|
||||
def main():
|
||||
kwargs = get_parser().parse_args()
|
||||
|
||||
run(None, vars(kwargs))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -11,10 +11,14 @@ select = E,W,F,N
|
|||
# E305: expected 2 blank lines after end of function or class
|
||||
# E402: module level import not at top of file
|
||||
# E731: do not assign a lambda expression, use a def
|
||||
# W504: line break after binary operator
|
||||
# W601: .has_key() is deprecated, use ‘in’
|
||||
# W605: invalid escape sequence
|
||||
# W606: 'async' and 'await' are reserved keywords starting with Python 3.7
|
||||
# N801: class names should use CapWords convention
|
||||
# N802: function name should be lowercase
|
||||
ignore = E128,E129,E226,E231,E251,E265,E302,E303,E305,E402,E731,W601,N801,N802
|
||||
# N806: variable in function should be lowercase
|
||||
ignore = E128,E129,E226,E231,E251,E265,E302,E303,E305,E402,E731,W504,W601,W605,W606,N801,N802,N806
|
||||
exclude =
|
||||
.tox,
|
||||
pywebsocket,
|
||||
|
|
|
@ -11,9 +11,11 @@ select = E,W,F,N
|
|||
# E305: expected 2 blank lines after end of function or class
|
||||
# E402: module level import not at top of file
|
||||
# E731: do not assign a lambda expression, use a def
|
||||
# W504: line break after binary operator
|
||||
# W605: invalid escape sequence
|
||||
# N801: class names should use CapWords convention
|
||||
# N802: function name should be lowercase
|
||||
ignore = E128,E129,E226,E231,E251,E265,E302,E303,E305,E402,E731,N801,N802
|
||||
ignore = E128,E129,E226,E231,E251,E265,E302,E303,E305,E402,E731,W504,W605,N801,N802
|
||||
exclude =
|
||||
.tox,
|
||||
pywebsocket,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
flake8==3.5.0
|
||||
pycodestyle==2.3.1
|
||||
pyflakes==1.6.0
|
||||
pep8-naming==0.4.1
|
||||
flake8==3.6.0
|
||||
pycodestyle==2.4.0
|
||||
pyflakes==2.0.0
|
||||
pep8-naming==0.7.0
|
||||
|
|
|
@ -210,7 +210,7 @@ class FennecBrowser(FirefoxBrowser):
|
|||
process_class=ProcessHandler,
|
||||
process_args={"processOutputLine": [self.on_output]})
|
||||
|
||||
self.logger.debug("Starting Fennec")
|
||||
self.logger.debug("Starting %s" % self.package_name)
|
||||
# connect to a running emulator
|
||||
self.runner.device.connect()
|
||||
|
||||
|
@ -222,7 +222,7 @@ class FennecBrowser(FirefoxBrowser):
|
|||
local="tcp:{}".format(self.marionette_port),
|
||||
remote="tcp:{}".format(self.marionette_port))
|
||||
|
||||
self.logger.debug("Fennec Started")
|
||||
self.logger.debug("%s Started" % self.package_name)
|
||||
|
||||
def stop(self, force=False):
|
||||
if self.runner is not None:
|
||||
|
|
|
@ -15,7 +15,8 @@ __wptrunner__ = {"product": "webkit",
|
|||
"wdspec": "WebKitDriverWdspecExecutor"},
|
||||
"executor_kwargs": "executor_kwargs",
|
||||
"env_extras": "env_extras",
|
||||
"env_options": "env_options"}
|
||||
"env_options": "env_options",
|
||||
"run_info_extras": "run_info_extras"}
|
||||
|
||||
|
||||
def check_args(**kwargs):
|
||||
|
@ -31,22 +32,22 @@ def browser_kwargs(test_type, run_info_data, config, **kwargs):
|
|||
|
||||
|
||||
def capabilities_for_port(server_config, **kwargs):
|
||||
if kwargs["webkit_port"] == "gtk":
|
||||
capabilities = {
|
||||
port_name = kwargs["webkit_port"]
|
||||
if port_name in ["gtk", "wpe"]:
|
||||
port_key_map = {"gtk": "webkitgtk"}
|
||||
browser_options_port = port_key_map.get(port_name, port_name)
|
||||
browser_options_key = "%s:browserOptions" % browser_options_port
|
||||
|
||||
return {
|
||||
"browserName": "MiniBrowser",
|
||||
"browserVersion": "2.20",
|
||||
"platformName": "ANY",
|
||||
"webkitgtk:browserOptions": {
|
||||
browser_options_key: {
|
||||
"binary": kwargs["binary"],
|
||||
"args": kwargs.get("binary_args", []),
|
||||
"certificates": [
|
||||
{"host": server_config["browser_host"],
|
||||
"certificateFile": kwargs["host_cert_path"]}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
return capabilities
|
||||
"certificateFile": kwargs["host_cert_path"]}]}}
|
||||
|
||||
return {}
|
||||
|
||||
|
@ -69,6 +70,10 @@ def env_options():
|
|||
return {}
|
||||
|
||||
|
||||
def run_info_extras(**kwargs):
|
||||
return {"webkit_port": kwargs["webkit_port"]}
|
||||
|
||||
|
||||
class WebKitBrowser(Browser):
|
||||
"""Generic WebKit browser is backed by WebKit's WebDriver implementation,
|
||||
which is supplied through ``wptrunner.webdriver.WebKitDriverServer``.
|
||||
|
|
|
@ -1,8 +1,55 @@
|
|||
import json
|
||||
import re
|
||||
import sys
|
||||
|
||||
from mozlog.structured.formatters.base import BaseFormatter
|
||||
|
||||
|
||||
LONE_SURROGATE_RE = re.compile(u"[\uD800-\uDFFF]")
|
||||
|
||||
|
||||
def surrogate_replacement_ucs4(match):
|
||||
return "U+" + hex(ord(match.group()))[2:]
|
||||
|
||||
|
||||
class SurrogateReplacementUcs2(object):
|
||||
def __init__(self):
|
||||
self.skip = False
|
||||
|
||||
def __call__(self, match):
|
||||
char = match.group()
|
||||
|
||||
if self.skip:
|
||||
self.skip = False
|
||||
return char
|
||||
|
||||
is_low = 0xD800 <= ord(char) <= 0xDBFF
|
||||
|
||||
escape = True
|
||||
if is_low:
|
||||
next_idx = match.end()
|
||||
if next_idx < len(match.string):
|
||||
next_char = match.string[next_idx]
|
||||
if 0xDC00 <= ord(next_char) <= 0xDFFF:
|
||||
escape = False
|
||||
|
||||
if not escape:
|
||||
self.skip = True
|
||||
return char
|
||||
|
||||
return "U+" + hex(ord(match.group()))[2:]
|
||||
|
||||
|
||||
if sys.maxunicode == 0x10FFFF:
|
||||
surrogate_replacement = surrogate_replacement_ucs4
|
||||
else:
|
||||
surrogate_replacement = SurrogateReplacementUcs2()
|
||||
|
||||
|
||||
def replace_lone_surrogate(data):
|
||||
return LONE_SURROGATE_RE.subn(surrogate_replacement, data)[0]
|
||||
|
||||
|
||||
class WptreportFormatter(BaseFormatter):
|
||||
"""Formatter that produces results in the format that wpreport expects."""
|
||||
|
||||
|
@ -40,7 +87,7 @@ class WptreportFormatter(BaseFormatter):
|
|||
|
||||
def create_subtest(self, data):
|
||||
test = self.find_or_create_test(data)
|
||||
subtest_name = data["subtest"]
|
||||
subtest_name = replace_lone_surrogate(data["subtest"])
|
||||
|
||||
subtest = {
|
||||
"name": subtest_name,
|
||||
|
@ -57,7 +104,7 @@ class WptreportFormatter(BaseFormatter):
|
|||
if "expected" in data:
|
||||
subtest["expected"] = data["expected"]
|
||||
if "message" in data:
|
||||
subtest["message"] = data["message"]
|
||||
subtest["message"] = replace_lone_surrogate(data["message"])
|
||||
|
||||
def test_end(self, data):
|
||||
test = self.find_or_create_test(data)
|
||||
|
@ -67,7 +114,7 @@ class WptreportFormatter(BaseFormatter):
|
|||
if "expected" in data:
|
||||
test["expected"] = data["expected"]
|
||||
if "message" in data:
|
||||
test["message"] = data["message"]
|
||||
test["message"] = replace_lone_surrogate(data["message"])
|
||||
|
||||
def assertion_count(self, data):
|
||||
test = self.find_or_create_test(data)
|
||||
|
|
|
@ -4,10 +4,13 @@ import time
|
|||
from os.path import dirname, join
|
||||
from StringIO import StringIO
|
||||
|
||||
import mock
|
||||
|
||||
from mozlog import handlers, structuredlog
|
||||
|
||||
sys.path.insert(0, join(dirname(__file__), "..", ".."))
|
||||
|
||||
from wptrunner import formatters
|
||||
from wptrunner.formatters import WptreportFormatter
|
||||
|
||||
|
||||
|
@ -62,3 +65,73 @@ def test_wptreport_run_info_optional(capfd):
|
|||
output.seek(0)
|
||||
output_obj = json.load(output)
|
||||
assert "run_info" not in output_obj or output_obj["run_info"] == {}
|
||||
|
||||
|
||||
def test_wptreport_lone_surrogate(capfd):
|
||||
output = StringIO()
|
||||
logger = structuredlog.StructuredLogger("test_a")
|
||||
logger.add_handler(handlers.StreamHandler(output, WptreportFormatter()))
|
||||
|
||||
# output a bunch of stuff
|
||||
logger.suite_start(["test-id-1"]) # no run_info arg!
|
||||
logger.test_start("test-id-1")
|
||||
logger.test_status("test-id-1",
|
||||
subtest=u"Name with surrogate\uD800",
|
||||
status="FAIL",
|
||||
message=u"\U0001F601 \uDE0A\uD83D")
|
||||
logger.test_end("test-id-1",
|
||||
status="PASS",
|
||||
message=u"\uDE0A\uD83D \U0001F601")
|
||||
logger.suite_end()
|
||||
|
||||
# check nothing got output to stdout/stderr
|
||||
# (note that mozlog outputs exceptions during handling to stderr!)
|
||||
captured = capfd.readouterr()
|
||||
assert captured.out == ""
|
||||
assert captured.err == ""
|
||||
|
||||
# check the actual output of the formatter
|
||||
output.seek(0)
|
||||
output_obj = json.load(output)
|
||||
test = output_obj["results"][0]
|
||||
assert test["message"] == u"U+de0aU+d83d \U0001F601"
|
||||
subtest = test["subtests"][0]
|
||||
assert subtest["name"] == u"Name with surrogateU+d800"
|
||||
assert subtest["message"] == u"\U0001F601 U+de0aU+d83d"
|
||||
|
||||
|
||||
def test_wptreport_lone_surrogate_ucs2(capfd):
|
||||
# Since UCS4 is a superset of UCS2 we can meaningfully test the UCS2 code on a
|
||||
# UCS4 build, but not the reverse. However UCS2 is harder to handle and UCS4 is
|
||||
# the commonest (and sensible) configuration, so that's OK.
|
||||
output = StringIO()
|
||||
logger = structuredlog.StructuredLogger("test_a")
|
||||
logger.add_handler(handlers.StreamHandler(output, WptreportFormatter()))
|
||||
|
||||
with mock.patch.object(formatters, 'surrogate_replacement', formatters.SurrogateReplacementUcs2()):
|
||||
# output a bunch of stuff
|
||||
logger.suite_start(["test-id-1"]) # no run_info arg!
|
||||
logger.test_start("test-id-1")
|
||||
logger.test_status("test-id-1",
|
||||
subtest=u"Name with surrogate\uD800",
|
||||
status="FAIL",
|
||||
message=u"\U0001F601 \uDE0A\uD83D \uD83D\uDE0A")
|
||||
logger.test_end("test-id-1",
|
||||
status="PASS",
|
||||
message=u"\uDE0A\uD83D \uD83D\uDE0A \U0001F601")
|
||||
logger.suite_end()
|
||||
|
||||
# check nothing got output to stdout/stderr
|
||||
# (note that mozlog outputs exceptions during handling to stderr!)
|
||||
captured = capfd.readouterr()
|
||||
assert captured.out == ""
|
||||
assert captured.err == ""
|
||||
|
||||
# check the actual output of the formatter
|
||||
output.seek(0)
|
||||
output_obj = json.load(output)
|
||||
test = output_obj["results"][0]
|
||||
assert test["message"] == u"U+de0aU+d83d \U0001f60a \U0001F601"
|
||||
subtest = test["subtests"][0]
|
||||
assert subtest["name"] == u"Name with surrogateU+d800"
|
||||
assert subtest["message"] == u"\U0001F601 U+de0aU+d83d \U0001f60a"
|
||||
|
|
|
@ -7,8 +7,6 @@ import traceback
|
|||
from six.moves.urllib.parse import parse_qs, quote, unquote, urljoin
|
||||
from six import iteritems
|
||||
|
||||
from h2.events import RequestReceived, DataReceived
|
||||
|
||||
from .constants import content_types
|
||||
from .pipes import Pipeline, template
|
||||
from .ranges import RangeParser
|
||||
|
@ -79,7 +77,7 @@ class DirectoryHandler(object):
|
|||
%(items)s
|
||||
</ul>
|
||||
""" % {"path": cgi.escape(url_path),
|
||||
"items": "\n".join(self.list_items(url_path, path))} # flake8: noqa
|
||||
"items": "\n".join(self.list_items(url_path, path))} # noqa: E122
|
||||
|
||||
def list_items(self, base_path, path):
|
||||
assert base_path.endswith("/")
|
||||
|
|
|
@ -548,7 +548,7 @@ class Http1WebTestRequestHandler(BaseWebTestRequestHandler):
|
|||
self.close_connection = True
|
||||
return
|
||||
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
err = traceback.format_exc()
|
||||
if response:
|
||||
response.set_error(500, err)
|
||||
|
|
|
@ -196,7 +196,7 @@ const gCSSProperties = {
|
|||
'border-image-repeat': {
|
||||
// https://drafts.csswg.org/css-backgrounds-3/#border-image-repeat
|
||||
types: [
|
||||
{ type: 'discrete', options: [ [ 'stretch stretch', 'repeat repeat' ] ] }
|
||||
{ type: 'discrete', options: [ [ 'stretch repeat', 'round space' ] ] }
|
||||
]
|
||||
},
|
||||
'border-image-slice': {
|
||||
|
|
|
@ -1,10 +1 @@
|
|||
def retrieve_element_rect(session, element):
|
||||
return session.execute_script("""
|
||||
let rect = arguments[0].getBoundingClientRect();
|
||||
return {
|
||||
x: rect.left + window.pageXOffset,
|
||||
y: rect.top + window.pageYOffset,
|
||||
width: rect.width,
|
||||
height: rect.height,
|
||||
};
|
||||
""", args=(element,))
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
from tests.support.asserts import assert_error, assert_success
|
||||
from tests.support.helpers import element_rect
|
||||
from tests.support.inline import inline
|
||||
|
||||
from . import retrieve_element_rect
|
||||
|
||||
|
||||
def get_element_rect(session, element_id):
|
||||
return session.transport.send(
|
||||
|
@ -38,4 +37,4 @@ def test_basic(session):
|
|||
element = session.find.css("input", all=False)
|
||||
|
||||
result = get_element_rect(session, element.id)
|
||||
assert_success(result, retrieve_element_rect(session, element))
|
||||
assert_success(result, element_rect(session, element))
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
import pytest
|
||||
|
||||
from tests.support.asserts import assert_error, assert_success, assert_dialog_handled
|
||||
from tests.support.helpers import element_rect
|
||||
from tests.support.inline import inline
|
||||
|
||||
from . import retrieve_element_rect
|
||||
|
||||
|
||||
def get_element_rect(session, element_id):
|
||||
return session.transport.send(
|
||||
|
@ -27,7 +26,7 @@ def check_user_prompt_closed_without_exception(session, create_dialog):
|
|||
create_dialog(dialog_type, text=dialog_type)
|
||||
|
||||
response = get_element_rect(session, element.id)
|
||||
assert_success(response, retrieve_element_rect(session, element))
|
||||
assert_success(response, element_rect(session, element))
|
||||
|
||||
assert_dialog_handled(session, expected_text=dialog_type, expected_retval=retval)
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import base64
|
||||
import imghdr
|
||||
import struct
|
||||
|
||||
from webdriver import Element, NoSuchAlertException, WebDriverException
|
||||
|
||||
|
|
|
@ -231,4 +231,3 @@ def closed_window(session, create_window):
|
|||
yield new_handle
|
||||
|
||||
session.window_handle = original_handle
|
||||
|
||||
|
|
|
@ -105,6 +105,34 @@ def clear_all_cookies(session):
|
|||
session.transport.send("DELETE", "session/%s/cookie" % session.session_id)
|
||||
|
||||
|
||||
def document_dimensions(session):
|
||||
return tuple(session.execute_script("""
|
||||
let {width, height} = document.documentElement.getBoundingClientRect();
|
||||
return [width, height];
|
||||
"""))
|
||||
|
||||
|
||||
def document_hidden(session):
|
||||
"""Polls for the document to become hidden."""
|
||||
def hidden(session):
|
||||
return session.execute_script("return document.hidden")
|
||||
return Poll(session, timeout=3, raises=None).until(hidden)
|
||||
|
||||
|
||||
def element_rect(session, element):
|
||||
return session.execute_script("""
|
||||
let element = arguments[0];
|
||||
let {height, left, top, width} = element.getBoundingClientRect();
|
||||
|
||||
return {
|
||||
x: left + window.pageXOffset,
|
||||
y: top + window.pageYOffset,
|
||||
width: width,
|
||||
height: height,
|
||||
};
|
||||
""", args=(element,))
|
||||
|
||||
|
||||
def is_element_in_viewport(session, element):
|
||||
"""Check if element is outside of the viewport"""
|
||||
return session.execute_script("""
|
||||
|
@ -121,13 +149,6 @@ def is_element_in_viewport(session, element):
|
|||
""", args=(element,))
|
||||
|
||||
|
||||
def document_hidden(session):
|
||||
"""Polls for the document to become hidden."""
|
||||
def hidden(session):
|
||||
return session.execute_script("return document.hidden")
|
||||
return Poll(session, timeout=3, raises=None).until(hidden)
|
||||
|
||||
|
||||
def is_fullscreen(session):
|
||||
# At the time of writing, WebKit does not conform to the
|
||||
# Fullscreen API specification.
|
||||
|
@ -137,11 +158,3 @@ def is_fullscreen(session):
|
|||
return session.execute_script("""
|
||||
return !!(window.fullScreen || document.webkitIsFullScreen)
|
||||
""")
|
||||
|
||||
|
||||
def document_dimensions(session):
|
||||
return tuple(session.execute_script("""
|
||||
let {devicePixelRatio} = window;
|
||||
let {width, height} = document.documentElement.getBoundingClientRect();
|
||||
return [width * devicePixelRatio, height * devicePixelRatio];
|
||||
"""))
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import base64
|
||||
import math
|
||||
import struct
|
||||
|
||||
from tests.support.asserts import assert_png
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
def element_rect(session, element):
|
||||
return session.execute_script("""
|
||||
let {devicePixelRatio} = window;
|
||||
let rect = arguments[0].getBoundingClientRect();
|
||||
|
||||
return {
|
||||
x: Math.floor((rect.left + window.pageXOffset) * devicePixelRatio),
|
||||
y: Math.floor((rect.top + window.pageYOffset) * devicePixelRatio),
|
||||
width: Math.floor(rect.width * devicePixelRatio),
|
||||
height: Math.floor(rect.height * devicePixelRatio),
|
||||
};
|
||||
""", args=(element,))
|
|
@ -1,9 +1,9 @@
|
|||
import base64
|
||||
import imghdr
|
||||
|
||||
from tests.support.asserts import assert_error, assert_success
|
||||
from tests.support.asserts import assert_error, assert_png, assert_success
|
||||
from tests.support.image import png_dimensions
|
||||
from tests.support.inline import inline
|
||||
|
||||
from . import element_rect
|
||||
|
||||
|
||||
def take_element_screenshot(session, element_id):
|
||||
return session.transport.send(
|
||||
|
@ -20,17 +20,6 @@ def test_no_browsing_context(session, closed_window):
|
|||
assert_error(response, "no such window")
|
||||
|
||||
|
||||
def test_screenshot(session):
|
||||
session.url = inline("<input>")
|
||||
element = session.find.css("input", all=False)
|
||||
|
||||
response = take_element_screenshot(session, element.id)
|
||||
value = assert_success(response)
|
||||
|
||||
image = base64.decodestring(value)
|
||||
assert imghdr.what("", image) == "png"
|
||||
|
||||
|
||||
def test_stale(session):
|
||||
session.url = inline("<input>")
|
||||
element = session.find.css("input", all=False)
|
||||
|
@ -38,3 +27,15 @@ def test_stale(session):
|
|||
|
||||
result = take_element_screenshot(session, element.id)
|
||||
assert_error(result, "stale element reference")
|
||||
|
||||
|
||||
def test_format_and_dimensions(session):
|
||||
session.url = inline("<input>")
|
||||
element = session.find.css("input", all=False)
|
||||
rect = element_rect(session, element)
|
||||
|
||||
response = take_element_screenshot(session, element.id)
|
||||
value = assert_success(response)
|
||||
|
||||
assert_png(value)
|
||||
assert png_dimensions(value) == (rect["width"], rect["height"])
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
# META: timeout=long
|
||||
|
||||
import base64
|
||||
import imghdr
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.support.asserts import assert_success
|
||||
from tests.support.asserts import assert_png, assert_success
|
||||
from tests.support.inline import inline
|
||||
|
||||
|
||||
|
@ -30,8 +27,7 @@ def check_user_prompt_not_closed_without_exception(session, create_dialog):
|
|||
response = take_element_screenshot(session, element.id)
|
||||
value = assert_success(response)
|
||||
|
||||
image = base64.decodestring(value)
|
||||
assert imghdr.what("", image) == "png"
|
||||
assert_png(value)
|
||||
|
||||
assert session.alert.text == dialog_type
|
||||
session.alert.dismiss()
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
def document_dimensions(session):
|
||||
return tuple(session.execute_script("""
|
||||
let {devicePixelRatio} = window;
|
||||
let {width, height} = document.documentElement.getBoundingClientRect();
|
||||
return [Math.floor(width * devicePixelRatio), Math.floor(height * devicePixelRatio)];
|
||||
"""))
|
|
@ -1,9 +1,9 @@
|
|||
import base64
|
||||
import imghdr
|
||||
|
||||
from tests.support.asserts import assert_error, assert_success
|
||||
from tests.support.asserts import assert_error, assert_png, assert_success
|
||||
from tests.support.image import png_dimensions
|
||||
from tests.support.inline import inline
|
||||
|
||||
from . import document_dimensions
|
||||
|
||||
|
||||
def take_screenshot(session):
|
||||
return session.transport.send(
|
||||
|
@ -15,11 +15,11 @@ def test_no_browsing_context(session, closed_window):
|
|||
assert_error(response, "no such window")
|
||||
|
||||
|
||||
def test_screenshot(session):
|
||||
def test_format_and_dimensions(session):
|
||||
session.url = inline("<input>")
|
||||
|
||||
response = take_screenshot(session)
|
||||
value = assert_success(response)
|
||||
|
||||
image = base64.decodestring(value)
|
||||
assert imghdr.what("", image) == "png"
|
||||
assert_png(value)
|
||||
assert png_dimensions(value) == document_dimensions(session)
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
# META: timeout=long
|
||||
|
||||
import base64
|
||||
import imghdr
|
||||
|
||||
import pytest
|
||||
|
||||
from tests.support.asserts import assert_success
|
||||
from tests.support.asserts import assert_png, assert_success
|
||||
from tests.support.inline import inline
|
||||
|
||||
|
||||
|
@ -24,8 +21,7 @@ def check_user_prompt_not_closed_without_exception(session, create_dialog):
|
|||
response = take_screenshot(session)
|
||||
value = assert_success(response)
|
||||
|
||||
image = base64.decodestring(value)
|
||||
assert imghdr.what("", image) == "png"
|
||||
assert_png(value)
|
||||
|
||||
assert session.alert.text == dialog_type
|
||||
session.alert.dismiss()
|
||||
|
|
|
@ -247,7 +247,7 @@
|
|||
// tonechange event, to make sure that tonechange is triggered
|
||||
// then stopped
|
||||
if(tone === 'A') {
|
||||
transceiver.setDirection('recvonly');
|
||||
transceiver.direction = 'recvonly';
|
||||
|
||||
pc.createOffer()
|
||||
.then(offer =>
|
||||
|
|
|
@ -85,57 +85,27 @@
|
|||
}));
|
||||
}, 'replaceTrack() rejects when the peer connection is closed.');
|
||||
|
||||
async_test(t => {
|
||||
const expectedException = 'InvalidModificationError';
|
||||
promise_test(async t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
t.add_cleanup(() => caller.close());
|
||||
return getUserMediaTracksAndStreams(2)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
const sender = caller.addTrack(tracks[0], streams[0]);
|
||||
caller.removeTrack(sender);
|
||||
// replaceTrack() should fail because the sender should be inactive after
|
||||
// removeTrack().
|
||||
return sender.replaceTrack(tracks[1])
|
||||
.then(t.step_func(() => {
|
||||
assert_unreached('Expected replaceTrack() to be rejected with ' +
|
||||
expectedException + ' but the promise was resolved.');
|
||||
}),
|
||||
t.step_func(e => {
|
||||
assert_equals(e.name, expectedException);
|
||||
t.done();
|
||||
}));
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'replaceTrack() rejects when invoked after removeTrack().');
|
||||
const [tracks, streams] = await getUserMediaTracksAndStreams(2);
|
||||
const sender = caller.addTrack(tracks[0], streams[0]);
|
||||
caller.removeTrack(sender);
|
||||
await sender.replaceTrack(tracks[1]);
|
||||
assert_equals(sender.track, tracks[1], "Make sure track gets updated");
|
||||
}, 'replaceTrack() does not reject when invoked after removeTrack().');
|
||||
|
||||
async_test(t => {
|
||||
const expectedException = 'InvalidModificationError';
|
||||
|
||||
promise_test(async t => {
|
||||
const caller = new RTCPeerConnection();
|
||||
t.add_cleanup(() => caller.close());
|
||||
return getUserMediaTracksAndStreams(2)
|
||||
.then(t.step_func(([tracks, streams]) => {
|
||||
const sender = caller.addTrack(tracks[0], streams[0]);
|
||||
let p = sender.replaceTrack(tracks[1])
|
||||
caller.removeTrack(sender);
|
||||
// replaceTrack() should fail because it executes steps in parallel and
|
||||
// queues a task to execute after removeTrack() has occurred. The sender
|
||||
// should be inactive. If this can be racy, update or remove the test.
|
||||
// https://github.com/w3c/webrtc-pc/issues/1728
|
||||
return p.then(t.step_func(() => {
|
||||
assert_unreached('Expected replaceTrack() to be rejected with ' +
|
||||
expectedException + ' but the promise was resolved.');
|
||||
}),
|
||||
t.step_func(e => {
|
||||
assert_equals(e.name, expectedException);
|
||||
t.done();
|
||||
}));
|
||||
}))
|
||||
.catch(t.step_func(reason => {
|
||||
assert_unreached(reason);
|
||||
}));
|
||||
}, 'replaceTrack() rejects after a subsequent removeTrack().');
|
||||
const [tracks, streams] = await getUserMediaTracksAndStreams(2);
|
||||
const sender = caller.addTrack(tracks[0], streams[0]);
|
||||
let p = sender.replaceTrack(tracks[1])
|
||||
caller.removeTrack(sender);
|
||||
await p;
|
||||
assert_equals(sender.track, tracks[1], "Make sure track gets updated");
|
||||
}, 'replaceTrack() does not reject after a subsequent removeTrack().');
|
||||
|
||||
// TODO(hbos): Verify that replaceTrack() changes what media is received on
|
||||
// the remote end of two connected peer connections. For video tracks, this
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>RTCRtpTransceiver.prototype.setDirection</title>
|
||||
<title>RTCRtpTransceiver.prototype.direction</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="RTCPeerConnection-helper.js"></script>
|
||||
|
@ -8,7 +8,7 @@
|
|||
'use strict';
|
||||
|
||||
// Test is based on the following editor draft:
|
||||
// https://rawgit.com/w3c/webrtc-pc/cc8d80f455b86c8041d63bceb8b457f45c72aa89/webrtc.html
|
||||
// https://rawgit.com/w3c/webrtc-pc/8495678808d126d8bc764bf944996f32981fa6fd/webrtc.html
|
||||
|
||||
// The following helper functions are called from RTCPeerConnection-helper.js:
|
||||
// generateAnswer
|
||||
|
@ -16,16 +16,15 @@
|
|||
/*
|
||||
5.4. RTCRtpTransceiver Interface
|
||||
interface RTCRtpTransceiver {
|
||||
readonly attribute RTCRtpTransceiverDirection direction;
|
||||
attribute RTCRtpTransceiverDirection direction;
|
||||
readonly attribute RTCRtpTransceiverDirection? currentDirection;
|
||||
void setDirection(RTCRtpTransceiverDirection direction);
|
||||
...
|
||||
};
|
||||
*/
|
||||
|
||||
/*
|
||||
5.4. setDirection
|
||||
4. Set transceiver's [[Direction]] slot to newDirection.
|
||||
5.4. direction
|
||||
7. Set transceiver's [[Direction]] slot to newDirection.
|
||||
*/
|
||||
test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
@ -33,15 +32,15 @@
|
|||
assert_equals(transceiver.direction, 'sendrecv');
|
||||
assert_equals(transceiver.currentDirection, null);
|
||||
|
||||
transceiver.setDirection('recvonly');
|
||||
transceiver.direction = 'recvonly';
|
||||
assert_equals(transceiver.direction, 'recvonly');
|
||||
assert_equals(transceiver.currentDirection, null,
|
||||
'Expect transceiver.currentDirection to not change');
|
||||
|
||||
}, 'setDirection should change transceiver.direction');
|
||||
}, 'setting direction should change transceiver.direction');
|
||||
|
||||
/*
|
||||
5.4. setDirection
|
||||
5.4. direction
|
||||
3. If newDirection is equal to transceiver's [[Direction]] slot, abort
|
||||
these steps.
|
||||
*/
|
||||
|
@ -49,10 +48,10 @@
|
|||
const pc = new RTCPeerConnection();
|
||||
const transceiver = pc.addTransceiver('audio', { direction: 'sendonly' });
|
||||
assert_equals(transceiver.direction, 'sendonly');
|
||||
transceiver.setDirection('sendonly');
|
||||
transceiver.direction = 'sendonly';
|
||||
assert_equals(transceiver.direction, 'sendonly');
|
||||
|
||||
}, 'setDirection with same direction should have no effect');
|
||||
}, 'setting direction with same direction should have no effect');
|
||||
|
||||
promise_test(t => {
|
||||
const pc = new RTCPeerConnection();
|
||||
|
@ -67,22 +66,22 @@
|
|||
.then(() => generateAnswer(offer)))
|
||||
.then(answer => pc.setRemoteDescription(answer))
|
||||
.then(() => {
|
||||
assert_equals(transceiver.currentDirection, 'recvonly');
|
||||
transceiver.setDirection('sendrecv');
|
||||
assert_equals(transceiver.currentDirection, 'inactive');
|
||||
transceiver.direction = 'sendrecv';
|
||||
assert_equals(transceiver.direction, 'sendrecv');
|
||||
assert_equals(transceiver.currentDirection, 'recvonly');
|
||||
assert_equals(transceiver.currentDirection, 'inactive');
|
||||
});
|
||||
}, 'setDirection should change transceiver.direction independent of transceiver.currentDirection');
|
||||
}, 'setting direction should change transceiver.direction independent of transceiver.currentDirection');
|
||||
|
||||
/*
|
||||
TODO
|
||||
Calls to setDirection() do not take effect immediately. Instead, future calls
|
||||
An update of directionality does not take effect immediately. Instead, future calls
|
||||
to createOffer and createAnswer mark the corresponding media description as
|
||||
sendrecv, sendonly, recvonly or inactive as defined in [JSEP] (section 5.2.2.
|
||||
and section 5.3.2.).
|
||||
|
||||
Tested in RTCPeerConnection-onnegotiationneeded.html
|
||||
5.4. setDirection
|
||||
5.4. direction
|
||||
6. Update the negotiation-needed flag for connection.
|
||||
|
||||
Coverage Report
|
|
@ -1181,7 +1181,7 @@
|
|||
"InvalidStateError", "replaceTrack on stopped transceiver");
|
||||
|
||||
checkThrows(() => transceiver.direction = "sendrecv",
|
||||
"InvalidStateError", "setDirection on stopped transceiver");
|
||||
"InvalidStateError", "set direction on stopped transceiver");
|
||||
|
||||
checkThrows(() => transceiver.sender.dtmf.insertDTMF("111"),
|
||||
"InvalidStateError", "insertDTMF on stopped transceiver");
|
||||
|
@ -1775,7 +1775,7 @@
|
|||
await pc2.setRemoteDescription({type: "rollback"});
|
||||
|
||||
// Transceiver should be _gone_, again. replaceTrack doesn't prevent this,
|
||||
// nor does setDirection.
|
||||
// nor does setting direction.
|
||||
hasProps(pc2.getTransceivers(), []);
|
||||
|
||||
// Setting the same offer for a _third_ time should do the same thing
|
||||
|
|
|
@ -24,6 +24,14 @@ test(function() {
|
|||
}, "RTCPeerConnection member " + name + " should not exist");
|
||||
});
|
||||
|
||||
[
|
||||
"setDirection",
|
||||
].forEach(function(name) {
|
||||
test(function() {
|
||||
assert_false(name in RTCRtpTransceiver.prototype);
|
||||
}, "RTCRtpTransceiver member " + name + " should not exist");
|
||||
});
|
||||
|
||||
[
|
||||
"DataChannel",
|
||||
"mozRTCIceCandidate",
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/basic.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/regionanchor_x_50_percent.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/regionanchor_y_50_percent.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshotDelayed(3000);">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/scroll_up.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/single_line_top_left.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/viewportanchor_x_50_percent.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/viewportanchor_y_50_percent.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -12,8 +12,8 @@ body { margin:0 }
|
|||
</style>
|
||||
<script src="/common/reftest-wait.js"></script>
|
||||
<video width="320" height="180" autoplay onplaying="this.onplaying = null; this.pause(); takeScreenshot();">
|
||||
<source src="../media/white.webm" type="video/webm">
|
||||
<source src="../media/white.mp4" type="video/mp4">
|
||||
<source src="/media/white.webm" type="video/webm">
|
||||
<source src="/media/white.mp4" type="video/mp4">
|
||||
<track src="support/width_50_percent.vtt">
|
||||
<script>
|
||||
document.getElementsByTagName('track')[0].track.mode = 'showing';
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<title>DedicatedWorker: import failure</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script> setup({allow_uncaught_exception: true}); </script>
|
||||
<script>
|
||||
|
||||
promise_test(async () => {
|
||||
|
|
|
@ -9,7 +9,10 @@ let worker;
|
|||
window.onmessage = e => {
|
||||
worker = new Worker(e.data, { type: 'module' });
|
||||
worker.onmessage = msg => window.opener.postMessage(msg.data, '*');
|
||||
worker.onerror = err => window.opener.postMessage(['ERROR'], '*');
|
||||
worker.onerror = err => {
|
||||
window.opener.postMessage(['ERROR'], '*');
|
||||
err.preventDefault();
|
||||
};
|
||||
};
|
||||
window.opener.postMessage('LOADED', '*');
|
||||
</script>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue