mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Update web-platform-tests to revision d011702f368b88b3bae86e7a8fd2ddd22e18b33c
This commit is contained in:
parent
f9608022ca
commit
299ad0f9d0
573 changed files with 38776 additions and 14942 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,5 +0,0 @@
|
|||
[setrequestheader-bogus-value.htm]
|
||||
type: testharness
|
||||
[XMLHttpRequest: setRequestHeader() value argument checks 4]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
[HTMLCollection-as-proto-length-get-throws.html]
|
||||
type: testharness
|
||||
[HTMLcollection as a prototype should not allow getting .length on the base object]
|
||||
expected: FAIL
|
||||
|
|
@ -207,3 +207,9 @@
|
|||
[Node interface: document.createComment("abc") must inherit property "rootNode" with the proper type (16)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: element must inherit property "query" with the proper type (36)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: element must inherit property "queryAll" with the proper type (37)]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -3,3 +3,9 @@
|
|||
[Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)]
|
||||
expected: FAIL
|
||||
|
||||
[Element in non-HTML namespace, prefix, lowercase name]
|
||||
expected: FAIL
|
||||
|
||||
[Element in non-HTML namespace, prefix, uppercase name]
|
||||
expected: FAIL
|
||||
|
||||
|
|
8
tests/wpt/metadata/dom/nodes/Element-classlist.html.ini
Normal file
8
tests/wpt/metadata/dom/nodes/Element-classlist.html.ini
Normal file
|
@ -0,0 +1,8 @@
|
|||
[Element-classlist.html]
|
||||
type: testharness
|
||||
[.contains(empty_string) must return false]
|
||||
expected: FAIL
|
||||
|
||||
[.contains(string_with_spaces) must return false]
|
||||
expected: FAIL
|
||||
|
|
@ -3,3 +3,9 @@
|
|||
[Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)]
|
||||
expected: FAIL
|
||||
|
||||
[Element in non-HTML namespace, prefix, lowercase name]
|
||||
expected: FAIL
|
||||
|
||||
[Element in non-HTML namespace, prefix, uppercase name]
|
||||
expected: FAIL
|
||||
|
||||
|
|
17
tests/wpt/metadata/dom/nodes/case.html.ini
Normal file
17
tests/wpt/metadata/dom/nodes/case.html.ini
Normal file
|
@ -0,0 +1,17 @@
|
|||
[case.html]
|
||||
type: testharness
|
||||
[getElementsByTagName a:abc]
|
||||
expected: FAIL
|
||||
|
||||
[getElementsByTagName a:Abc]
|
||||
expected: FAIL
|
||||
|
||||
[getElementsByTagName a:ABC]
|
||||
expected: FAIL
|
||||
|
||||
[getElementsByTagName a:ä]
|
||||
expected: FAIL
|
||||
|
||||
[getElementsByTagName a:Ä]
|
||||
expected: FAIL
|
||||
|
5
tests/wpt/metadata/dom/nodes/remove-unscopable.html.ini
Normal file
5
tests/wpt/metadata/dom/nodes/remove-unscopable.html.ini
Normal file
|
@ -0,0 +1,5 @@
|
|||
[remove-unscopable.html]
|
||||
type: testharness
|
||||
[remove() should be unscopable]
|
||||
expected: FAIL
|
||||
|
|
@ -12,3 +12,12 @@
|
|||
[Encode/decode round trip: utf-16]
|
||||
expected: FAIL
|
||||
|
||||
[Decode sample: utf-16le]
|
||||
expected: FAIL
|
||||
|
||||
[Decode sample: utf-16be]
|
||||
expected: FAIL
|
||||
|
||||
[Decode sample: utf-16]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -18,3 +18,30 @@
|
|||
[Streaming decode: utf-16be, 5 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 1 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 2 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 3 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 4 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-8, 5 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16le, 2 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16le, 4 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16be, 2 byte window]
|
||||
expected: FAIL
|
||||
|
||||
[Streaming decode: utf-16be, 4 byte window]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
[textencoder-constructor-non-utf.html]
|
||||
type: testharness
|
||||
[Encoding argument not considered for encode: ibm866]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-2]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-3]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-4]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-5]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-6]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-7]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-8]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-8-i]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-10]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-13]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-14]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-15]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-8859-16]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: koi8-r]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: koi8-u]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: macintosh]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-874]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1250]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1251]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1252]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1253]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1254]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1255]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1256]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1257]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: windows-1258]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: x-mac-cyrillic]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: gbk]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: gb18030]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: big5]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: euc-jp]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: iso-2022-jp]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: shift_jis]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: euc-kr]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: replacement]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: utf-16be]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: utf-16le]
|
||||
expected: FAIL
|
||||
|
||||
[Encoding argument not considered for encode: x-user-defined]
|
||||
expected: FAIL
|
||||
|
|
@ -1 +1 @@
|
|||
0397e2a24d3e5c988b089ef100002397f4cabdfa
|
||||
f9608022caf7f223dfdfe960c31fb5fe7eb0d1f1
|
|
@ -792,3 +792,9 @@
|
|||
[Parsing: <h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <?a=b&c=d> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <??a=b&c=d> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -792,3 +792,9 @@
|
|||
[Parsing: <h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <?a=b&c=d> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <??a=b&c=d> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -198,3 +198,15 @@
|
|||
[Parsing: <h\tt\nt\rp://h\to\ns\rt:9\t0\n0\r0/p\ta\nt\rh?q\tu\ne\rry#f\tr\na\rg> against <about:blank>]
|
||||
expected: FAIL
|
||||
|
||||
[URL.searchParams updating, clearing]
|
||||
expected: FAIL
|
||||
|
||||
[URL.searchParams and URL.search setters, update propagation]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <?a=b&c=d> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
[Parsing: <??a=b&c=d> against <http://example.org/foo/bar>]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -12,16 +12,20 @@
|
|||
<script>
|
||||
function try_value(value) {
|
||||
test(function() {
|
||||
var client = new XMLHttpRequest()
|
||||
client.open("GET", "...")
|
||||
assert_throws("SyntaxError", function() { client.setRequestHeader("x-test", value) }, ' given value ' + value+', ')
|
||||
})
|
||||
var client = new XMLHttpRequest();
|
||||
client.open("GET", "...");
|
||||
assert_throws("SyntaxError", function() { client.setRequestHeader("x-test", value) }, ' given value ' + value+', ');
|
||||
});
|
||||
}
|
||||
try_value("t\rt")
|
||||
try_value("t\nt")
|
||||
try_value("t\rt");
|
||||
try_value("t\nt");
|
||||
try_value("t\bt");
|
||||
try_value("\x7f");
|
||||
try_value("テスト")
|
||||
test(function() {
|
||||
var client = new XMLHttpRequest();
|
||||
client.open("GET", "...");
|
||||
assert_throws(new TypeError(), function() { client.setRequestHeader("x-test", "テスト") }, ' given value テスト,');
|
||||
});
|
||||
|
||||
test(function() {
|
||||
var client = new XMLHttpRequest()
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>webkit-text-fill-color: untouched</title>
|
||||
<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<div style="color: green">These texts should be green</div>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>webkit-text-fill-color: green</title>
|
||||
<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
|
||||
<meta name="assert" content="The color of texts should be green">
|
||||
<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
|
||||
<div style="-webkit-text-fill-color: green;">These texts should be green</div>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>webkit-text-fill-color: green</title>
|
||||
<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
|
||||
<meta name="assert" content="The color of texts should be green">
|
||||
<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
|
||||
<div style="color: red; -webkit-text-fill-color: green;">These texts should be green</div>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>webkit-text-fill-color: green</title>
|
||||
<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
|
||||
<meta name="assert" content="The color of texts should be green">
|
||||
<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
|
||||
<div style="color: red; -webkit-text-fill-color: green;">These texts <span style="color: red">should be green</span></div>
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>webkit-text-fill-color: green</title>
|
||||
<link rel="author" title="Jeremy Chen" href="jeremychen@mozilla.com">
|
||||
<link rel="author" title="Mozilla" href="https://www.mozilla.org">
|
||||
<link rel="help" href="https://compat.spec.whatwg.org/#the-webkit-text-fill-color">
|
||||
<meta name="assert" content="The color of texts should be green">
|
||||
<link rel="match" href="webkit-text-fill-color-property-001-ref.html">
|
||||
<div style="color: transparent; -webkit-text-fill-color: green;">These texts should be green</div>
|
|
@ -0,0 +1,13 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title>Make sure browsers throw when getting .length on some random object whose proto is an HTMLCollection</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<script>
|
||||
test(function() {
|
||||
var obj = Object.create(document.getElementsByTagName("script"));
|
||||
assert_throws(new TypeError(), function() {
|
||||
obj.length;
|
||||
});
|
||||
}, "HTMLcollection as a prototype should not allow getting .length on the base object")
|
||||
</script>
|
|
@ -310,6 +310,9 @@ interface Element : Node {
|
|||
HTMLCollection getElementsByTagName(DOMString localName);
|
||||
HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
|
||||
HTMLCollection getElementsByClassName(DOMString classNames);
|
||||
|
||||
Element? insertAdjacentElement(DOMString where, Element element); // historical
|
||||
void insertAdjacentText(DOMString where, DOMString data); // historical
|
||||
};
|
||||
|
||||
interface NamedNodeMap {
|
||||
|
|
|
@ -127,17 +127,19 @@ function test_getElementsByTagName(context, element) {
|
|||
test(function() {
|
||||
var t = element.appendChild(document.createElementNS("test", "te:st"))
|
||||
this.add_cleanup(function() {element.removeChild(t)})
|
||||
assert_array_equals(context.getElementsByTagName("st"), [t])
|
||||
assert_array_equals(context.getElementsByTagName("st"), [])
|
||||
assert_array_equals(context.getElementsByTagName("ST"), [])
|
||||
assert_array_equals(context.getElementsByTagName("te:st"), [t])
|
||||
assert_array_equals(context.getElementsByTagName("te:ST"), [])
|
||||
}, "Element in non-HTML namespace, prefix, lowercase name")
|
||||
|
||||
test(function() {
|
||||
var t = element.appendChild(document.createElementNS("test", "te:ST"))
|
||||
this.add_cleanup(function() {element.removeChild(t)})
|
||||
assert_array_equals(context.getElementsByTagName("ST"), [t])
|
||||
assert_array_equals(context.getElementsByTagName("st"), [])
|
||||
assert_array_equals(context.getElementsByTagName("ST"), [])
|
||||
assert_array_equals(context.getElementsByTagName("te:st"), [])
|
||||
assert_array_equals(context.getElementsByTagName("te:ST"), [])
|
||||
assert_array_equals(context.getElementsByTagName("te:ST"), [t])
|
||||
}, "Element in non-HTML namespace, prefix, uppercase name")
|
||||
|
||||
test(function() {
|
||||
|
|
|
@ -37,17 +37,19 @@ test(function() {
|
|||
test(function() {
|
||||
var t = document.body.appendChild(document.createElementNS("test", "te:st"))
|
||||
this.add_cleanup(function() {document.body.removeChild(t)})
|
||||
assert_array_equals(document.getElementsByTagName("st"), [t])
|
||||
assert_array_equals(document.getElementsByTagName("st"), [])
|
||||
assert_array_equals(document.getElementsByTagName("ST"), [])
|
||||
assert_array_equals(document.getElementsByTagName("te:st"), [t])
|
||||
assert_array_equals(document.getElementsByTagName("te:ST"), [])
|
||||
}, "Element in non-HTML namespace, prefix, lowercase name")
|
||||
|
||||
test(function() {
|
||||
var t = document.body.appendChild(document.createElementNS("test", "te:ST"))
|
||||
this.add_cleanup(function() {document.body.removeChild(t)})
|
||||
assert_array_equals(document.getElementsByTagName("ST"), [t])
|
||||
assert_array_equals(document.getElementsByTagName("ST"), [])
|
||||
assert_array_equals(document.getElementsByTagName("st"), [])
|
||||
assert_array_equals(document.getElementsByTagName("te:st"), [])
|
||||
assert_array_equals(document.getElementsByTagName("te:ST"), [])
|
||||
assert_array_equals(document.getElementsByTagName("te:ST"), [t])
|
||||
}, "Element in non-HTML namespace, prefix, uppercase name")
|
||||
|
||||
test(function() {
|
||||
|
|
|
@ -66,8 +66,8 @@ test(function () {
|
|||
assert_equals( elem.classList.toString(), ' ', 'explicit' );
|
||||
}, 'classList should contain initial markup whitespace');
|
||||
test(function () {
|
||||
assert_throws( 'SYNTAX_ERR', function () { elem.classList.contains(''); } );
|
||||
}, '.contains(empty_string) must throw a SYNTAX_ERR');
|
||||
assert_false( elem.classList.contains('') );
|
||||
}, '.contains(empty_string) must return false');
|
||||
test(function () {
|
||||
assert_throws( 'SYNTAX_ERR', function () { elem.classList.add(''); } );
|
||||
}, '.add(empty_string) must throw a SYNTAX_ERR');
|
||||
|
@ -85,8 +85,8 @@ test(function () {
|
|||
assert_throws( 'SYNTAX_ERR', function () { elem.classList.replace('', ''); } );
|
||||
}, '.replace with empty_string must throw a SYNTAX_ERR');
|
||||
test(function () {
|
||||
assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.contains('a b'); } );
|
||||
}, '.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
|
||||
assert_false( elem.classList.contains('a b') );
|
||||
}, '.contains(string_with_spaces) must return false');
|
||||
test(function () {
|
||||
assert_throws( 'INVALID_CHARACTER_ERR', function () { elem.classList.add('a b'); } );
|
||||
}, '.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title></title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
||||
<div id="target"></div>
|
||||
<div id="parent"><span id=target2></span></div>
|
||||
<div id="log" style="visibility:visible"></div>
|
||||
<span id="test1"></span>
|
||||
<span id="test2"></span>
|
||||
<span id="test3"></span>
|
||||
<span id="test4"></span>
|
||||
<script>
|
||||
var target = document.getElementById("target");
|
||||
var target2 = document.getElementById("target2");
|
||||
|
||||
test(function() {
|
||||
assert_throws("SyntaxError", function() {
|
||||
target.insertAdjacentElement("test", document.getElementById("test1"))
|
||||
});
|
||||
|
||||
assert_throws("SyntaxError", function() {
|
||||
target2.insertAdjacentElement("test", document.getElementById("test1"))
|
||||
});
|
||||
}, "Inserting to an invalid location should cause a Syntax Error exception")
|
||||
|
||||
test(function() {
|
||||
var el = target.insertAdjacentElement("beforebegin", document.getElementById("test1"));
|
||||
assert_equals(target.previousSibling.id, "test1");
|
||||
assert_equals(el.id, "test1");
|
||||
|
||||
el = target2.insertAdjacentElement("beforebegin", document.getElementById("test1"));
|
||||
assert_equals(target2.previousSibling.id, "test1");
|
||||
assert_equals(el.id, "test1");
|
||||
}, "Inserted element should be target element's previous sibling for 'beforebegin' case")
|
||||
|
||||
test(function() {
|
||||
var el = target.insertAdjacentElement("afterbegin", document.getElementById("test2"));
|
||||
assert_equals(target.firstChild.id, "test2");
|
||||
assert_equals(el.id, "test2");
|
||||
|
||||
el = target2.insertAdjacentElement("afterbegin", document.getElementById("test2"));
|
||||
assert_equals(target2.firstChild.id, "test2");
|
||||
assert_equals(el.id, "test2");
|
||||
}, "Inserted element should be target element's first child for 'afterbegin' case")
|
||||
|
||||
test(function() {
|
||||
var el = target.insertAdjacentElement("beforeend", document.getElementById("test3"));
|
||||
assert_equals(target.lastChild.id, "test3");
|
||||
assert_equals(el.id, "test3");
|
||||
|
||||
el = target2.insertAdjacentElement("beforeend", document.getElementById("test3"));
|
||||
assert_equals(target2.lastChild.id, "test3");
|
||||
assert_equals(el.id, "test3");
|
||||
}, "Inserted element should be target element's last child for 'beforeend' case")
|
||||
|
||||
test(function() {
|
||||
var el = target.insertAdjacentElement("afterend", document.getElementById("test4"));
|
||||
assert_equals(target.nextSibling.id, "test4");
|
||||
assert_equals(el.id, "test4");
|
||||
|
||||
el = target2.insertAdjacentElement("afterend", document.getElementById("test4"));
|
||||
assert_equals(target2.nextSibling.id, "test4");
|
||||
assert_equals(el.id, "test4");
|
||||
}, "Inserted element should be target element's next sibling for 'afterend' case")
|
||||
|
||||
test(function() {
|
||||
var docElement = document.documentElement;
|
||||
docElement.style.visibility="hidden";
|
||||
|
||||
assert_throws("HierarchyRequestError", function() {
|
||||
var el = docElement.insertAdjacentElement("beforebegin", document.getElementById("test1"));
|
||||
assert_equals(el, null);
|
||||
});
|
||||
|
||||
var el = docElement.insertAdjacentElement("afterbegin", document.getElementById("test2"));
|
||||
assert_equals(docElement.firstChild.id, "test2");
|
||||
assert_equals(el.id, "test2");
|
||||
|
||||
el = docElement.insertAdjacentElement("beforeend", document.getElementById("test3"));
|
||||
assert_equals(docElement.lastChild.id, "test3");
|
||||
assert_equals(el.id, "test3");
|
||||
|
||||
assert_throws("HierarchyRequestError", function() {
|
||||
var el = docElement.insertAdjacentElement("afterend", document.getElementById("test4"));
|
||||
assert_equals(el, null);
|
||||
});
|
||||
}, "Adding more than one child to document should cause a HierarchyRequestError exception")
|
||||
|
||||
</script>
|
|
@ -0,0 +1,76 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title></title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<body style="visibility:hidden">
|
||||
<div id="target"></div>
|
||||
<div id="parent"><span id=target2></span></div>
|
||||
<div id="log" style="visibility:visible"></div>
|
||||
</body>
|
||||
<script>
|
||||
var target = document.getElementById("target");
|
||||
var target2 = document.getElementById("target2");
|
||||
|
||||
test(function() {
|
||||
assert_throws("SyntaxError", function() {
|
||||
target.insertAdjacentText("test", "text")
|
||||
});
|
||||
|
||||
assert_throws("SyntaxError", function() {
|
||||
target2.insertAdjacentText("test", "test")
|
||||
});
|
||||
}, "Inserting to an invalid location should cause a Syntax Error exception")
|
||||
|
||||
test(function() {
|
||||
target.insertAdjacentText("beforebegin", "test1");
|
||||
assert_equals(target.previousSibling.nodeValue, "test1");
|
||||
|
||||
target2.insertAdjacentText("beforebegin", "test1");
|
||||
assert_equals(target2.previousSibling.nodeValue, "test1");
|
||||
}, "Inserted text node should be target element's previous sibling for 'beforebegin' case")
|
||||
|
||||
test(function() {
|
||||
target.insertAdjacentText("afterbegin", "test2");
|
||||
assert_equals(target.firstChild.nodeValue, "test2");
|
||||
|
||||
target2.insertAdjacentText("afterbegin", "test2");
|
||||
assert_equals(target2.firstChild.nodeValue, "test2");
|
||||
}, "Inserted text node should be target element's first child for 'afterbegin' case")
|
||||
|
||||
test(function() {
|
||||
target.insertAdjacentText("beforeend", "test3");
|
||||
assert_equals(target.lastChild.nodeValue, "test3");
|
||||
|
||||
target2.insertAdjacentText("beforeend", "test3");
|
||||
assert_equals(target2.lastChild.nodeValue, "test3");
|
||||
}, "Inserted text node should be target element's last child for 'beforeend' case")
|
||||
|
||||
test(function() {
|
||||
target.insertAdjacentText("afterend", "test4");
|
||||
assert_equals(target.nextSibling.nodeValue, "test4");
|
||||
|
||||
target2.insertAdjacentText("afterend", "test4");
|
||||
assert_equals(target.nextSibling.nodeValue, "test4");
|
||||
}, "Inserted text node should be target element's next sibling for 'afterend' case")
|
||||
|
||||
test(function() {
|
||||
var docElement = document.documentElement;
|
||||
docElement.style.visibility="hidden";
|
||||
|
||||
assert_throws("HierarchyRequestError", function() {
|
||||
docElement.insertAdjacentText("beforebegin", "text1")
|
||||
});
|
||||
|
||||
docElement.insertAdjacentText("afterbegin", "test2");
|
||||
assert_equals(docElement.firstChild.nodeValue, "test2");
|
||||
|
||||
docElement.insertAdjacentText("beforeend", "test3");
|
||||
assert_equals(docElement.lastChild.nodeValue, "test3");
|
||||
|
||||
assert_throws("HierarchyRequestError", function() {
|
||||
docElement.insertAdjacentText("afterend", "test4")
|
||||
});
|
||||
}, "Adding more than one child to document should cause a HierarchyRequestError exception")
|
||||
|
||||
</script>
|
|
@ -73,6 +73,13 @@ function ascii_lowercase(input) {
|
|||
});
|
||||
}
|
||||
|
||||
function get_qualified_name(el) {
|
||||
if (el.prefix) {
|
||||
return el.prefix + ":" + el.localName;
|
||||
}
|
||||
return el.localName;
|
||||
}
|
||||
|
||||
function test_create_element(name) {
|
||||
var node = document.createElement(name);
|
||||
assert_equals(node.localName, expected_case(name));
|
||||
|
@ -133,9 +140,9 @@ function test_get_elements_tag_name(elements_to_create, search_string) {
|
|||
var expected = Array.prototype.filter.call(container.childNodes,
|
||||
function(node) {
|
||||
if (is_html && node.namespaceURI === "http://www.w3.org/1999/xhtml") {
|
||||
return node.localName === expected_case(search_string);
|
||||
return get_qualified_name(node) === expected_case(search_string);
|
||||
} else {
|
||||
return node.localName === search_string;
|
||||
return get_qualified_name(node) === search_string;
|
||||
}
|
||||
});
|
||||
document.documentElement.appendChild(container);
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title></title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<div id="testDiv" onclick="result1 = remove; result2 = this.remove;"></div>
|
||||
<script>
|
||||
var remove = "Hello there";
|
||||
var result1;
|
||||
var result2;
|
||||
test(function() {
|
||||
assert_true(Element.prototype[Symbol.unscopables].remove);
|
||||
var div = document.querySelector("#testDiv");
|
||||
div.dispatchEvent(new Event("click"));
|
||||
assert_equals(typeof result1, "string");
|
||||
assert_equals(typeof result2, "function");
|
||||
}, "remove() should be unscopable")
|
||||
</script>
|
|
@ -15,13 +15,11 @@ test(function() {
|
|||
}, 'Default inputs');
|
||||
|
||||
|
||||
function testEncodeDecodeSample(encoding, string, bytes) {
|
||||
function testDecodeSample(encoding, string, bytes) {
|
||||
test(function() {
|
||||
var encoded = new TextEncoder(encoding).encode(string);
|
||||
assert_array_equals([].slice.call(encoded), bytes);
|
||||
assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes)), string);
|
||||
assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes).buffer), string);
|
||||
}, 'Encode/decode round trip: ' + encoding);
|
||||
}, 'Decode sample: ' + encoding);
|
||||
}
|
||||
|
||||
// z (ASCII U+007A), cent (Latin-1 U+00A2), CJK water (BMP U+6C34),
|
||||
|
@ -29,25 +27,29 @@ function testEncodeDecodeSample(encoding, string, bytes) {
|
|||
// byte-swapped BOM (non-character U+FFFE)
|
||||
var sample = 'z\xA2\u6C34\uD834\uDD1E\uF8FF\uDBFF\uDFFD\uFFFE';
|
||||
|
||||
testEncodeDecodeSample(
|
||||
'utf-8',
|
||||
sample,
|
||||
[0x7A, 0xC2, 0xA2, 0xE6, 0xB0, 0xB4, 0xF0, 0x9D, 0x84, 0x9E, 0xEF, 0xA3, 0xBF, 0xF4, 0x8F, 0xBF, 0xBD, 0xEF, 0xBF, 0xBE]
|
||||
);
|
||||
test(function() {
|
||||
var encoding = 'utf-8';
|
||||
var string = sample;
|
||||
var bytes = [0x7A, 0xC2, 0xA2, 0xE6, 0xB0, 0xB4, 0xF0, 0x9D, 0x84, 0x9E, 0xEF, 0xA3, 0xBF, 0xF4, 0x8F, 0xBF, 0xBD, 0xEF, 0xBF, 0xBE];
|
||||
var encoded = new TextEncoder().encode(string);
|
||||
assert_array_equals([].slice.call(encoded), bytes);
|
||||
assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes)), string);
|
||||
assert_equals(new TextDecoder(encoding).decode(new Uint8Array(bytes).buffer), string);
|
||||
}, 'Encode/decode round trip: utf-8');
|
||||
|
||||
testEncodeDecodeSample(
|
||||
testDecodeSample(
|
||||
'utf-16le',
|
||||
sample,
|
||||
[0x7A, 0x00, 0xA2, 0x00, 0x34, 0x6C, 0x34, 0xD8, 0x1E, 0xDD, 0xFF, 0xF8, 0xFF, 0xDB, 0xFD, 0xDF, 0xFE, 0xFF]
|
||||
);
|
||||
|
||||
testEncodeDecodeSample(
|
||||
testDecodeSample(
|
||||
'utf-16be',
|
||||
sample,
|
||||
[0x00, 0x7A, 0x00, 0xA2, 0x6C, 0x34, 0xD8, 0x34, 0xDD, 0x1E, 0xF8, 0xFF, 0xDB, 0xFF, 0xDF, 0xFD, 0xFF, 0xFE]
|
||||
);
|
||||
|
||||
testEncodeDecodeSample(
|
||||
testDecodeSample(
|
||||
'utf-16',
|
||||
sample,
|
||||
[0x7A, 0x00, 0xA2, 0x00, 0x34, 0x6C, 0x34, 0xD8, 0x1E, 0xDD, 0xFF, 0xF8, 0xFF, 0xDB, 0xFD, 0xDF, 0xFE, 0xFF]
|
||||
|
|
|
@ -23,10 +23,6 @@ setup(function() {
|
|||
});
|
||||
|
||||
tests.forEach(function(input) {
|
||||
test(function() {
|
||||
assert_throws(new RangeError(), function() { new TextEncoder(input); });
|
||||
}, 'Invalid label ' + format_value(input) + ' should be rejected by TextEncoder.');
|
||||
|
||||
test(function() {
|
||||
assert_throws(new RangeError(), function() { new TextDecoder(input); });
|
||||
}, 'Invalid label ' + format_value(input) + ' should be rejected by TextDecoder.');
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
<script>
|
||||
|
||||
test(function() {
|
||||
assert_throws(new RangeError(), function() { new TextEncoder('replacement'); });
|
||||
assert_throws(new RangeError(), function() { new TextDecoder('replacement'); });
|
||||
}, 'The "replacement" label should not be a known encoding.');
|
||||
|
||||
|
@ -16,7 +15,6 @@ encodings_table.forEach(function(section) {
|
|||
}).forEach(function(encoding) {
|
||||
encoding.labels.forEach(function(label) {
|
||||
test(function() {
|
||||
assert_throws(new RangeError(), function() { new TextEncoder(label); });
|
||||
assert_throws(new RangeError(), function() { new TextDecoder(label); });
|
||||
}, 'Label for "replacement" should be rejected by API: ' + label);
|
||||
});
|
||||
|
|
|
@ -38,7 +38,7 @@ interface TextDecoder {
|
|||
|
||||
// 8.2 Interface TextDecoder
|
||||
|
||||
[Constructor(optional DOMString utfLabel = "utf-8"),
|
||||
[Constructor,
|
||||
Exposed=Window,Worker]
|
||||
interface TextEncoder {
|
||||
readonly attribute DOMString encoding;
|
||||
|
|
|
@ -5,12 +5,23 @@
|
|||
<script src="resources/encodings.js"></script>
|
||||
<script>
|
||||
|
||||
var string = '\\x00123ABCabc\\x80\\xFF\\u0100\\u1000\\uFFFD\\uD800\\uDC00\\uDBFF\\uDFFF';
|
||||
var string = '\x00123ABCabc\x80\xFF\u0100\u1000\uFFFD\uD800\uDC00\uDBFF\uDFFF';
|
||||
var octets = {
|
||||
'utf-16le': [0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42,0x00,
|
||||
0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF,0x00,
|
||||
0x00,0x01,0x00,0x10,0xFD,0xFF,0x00,0xD8,0x00,0xDC,0xFF,0xDB,
|
||||
0xFF,0xDF],
|
||||
'utf-16be': [0x00,0x00,0x00,0x31,0x00,0x32,0x00,0x33,0x00,0x41,0x00,0x42,
|
||||
0x00,0x43,0x00,0x61,0x00,0x62,0x00,0x63,0x00,0x80,0x00,0xFF,
|
||||
0x01,0x00,0x10,0x00,0xFF,0xFD,0xD8,0x00,0xDC,0x00,0xDB,0xFF,
|
||||
0xDF,0xFF]
|
||||
};
|
||||
|
||||
utf_encodings.forEach(function (encoding) {
|
||||
for (var len = 1; len <= 5; ++len) {
|
||||
test(function() {
|
||||
var encoded = new TextEncoder(encoding).encode(string);
|
||||
var encoded = octets[encoding] ||
|
||||
new TextEncoder(encoding).encode(string);
|
||||
|
||||
var out = '';
|
||||
var decoder = new TextDecoder(encoding);
|
||||
|
|
|
@ -6,20 +6,16 @@
|
|||
<script>
|
||||
|
||||
encodings_table.forEach(function(section) {
|
||||
section.encodings.filter(function(encoding) {
|
||||
return encoding.name !== 'replacement';
|
||||
}).forEach(function(encoding) {
|
||||
if (utf_encodings.indexOf(encoding.name) !== -1) {
|
||||
section.encodings.forEach(function(encoding) {
|
||||
if (encoding.name !== 'replacement') {
|
||||
test(function() {
|
||||
assert_equals(new TextDecoder(encoding.name).encoding, encoding.name);
|
||||
assert_equals(new TextEncoder(encoding.name).encoding, encoding.name);
|
||||
}, 'UTF encodings are supported for encode and decode: ' + encoding.name);
|
||||
} else {
|
||||
test(function() {
|
||||
assert_equals(new TextDecoder(encoding.name).encoding, encoding.name);
|
||||
assert_throws(new RangeError(), function() { new TextEncoder(encoding.name); });
|
||||
}, 'Non-UTF encodings supported only for decode, not encode: ' + encoding.name);
|
||||
}, 'Encoding argument supported for decode: ' + encoding.name);
|
||||
}
|
||||
|
||||
test(function() {
|
||||
assert_equals(new TextEncoder(encoding.name).encoding, 'utf-8');
|
||||
}, 'Encoding argument not considered for encode: ' + encoding.name);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -3,14 +3,14 @@ if (this.document === undefined) {
|
|||
importScripts("../resources/utils.js");
|
||||
}
|
||||
|
||||
var origin = "http://{{host}}:{{ports[http][0]}}";
|
||||
var referrerOrigin = "http://{{host}}:{{ports[http][0]}}/";
|
||||
var fetchedUrl = RESOURCES_DIR + "inspect-headers.py?headers=referer";
|
||||
|
||||
promise_test(function(test) {
|
||||
return fetch(fetchedUrl).then(function(resp) {
|
||||
assert_equals(resp.status, 200, "HTTP status is 200");
|
||||
assert_equals(resp.type , "basic", "Response's type is basic");
|
||||
assert_equals(resp.headers.get("x-request-referer"), origin, "request's referrer is " + origin);
|
||||
assert_equals(resp.headers.get("x-request-referer"), referrerOrigin, "request's referrer is " + referrerOrigin);
|
||||
});
|
||||
}, "Request's referrer is origin");
|
||||
|
||||
|
|
|
@ -29,8 +29,8 @@ if (window.location.search) {
|
|||
}
|
||||
|
||||
var testContainer = document.querySelector('#testContainer');
|
||||
var outerWidth = testContainer.getBoundingClientRect().width;
|
||||
var outerHeight = testContainer.getBoundingClientRect().height;
|
||||
var testContainerWidth = testContainer.getBoundingClientRect().width;
|
||||
var testContainerHeight = testContainer.getBoundingClientRect().height;
|
||||
|
||||
SVGSizing.doCombinationTest(
|
||||
[["placeholder", [ null ]],
|
||||
|
@ -45,7 +45,8 @@ SVGSizing.doCombinationTest(
|
|||
var testData = new SVGSizing.TestData(config);
|
||||
|
||||
var expectedRect =
|
||||
testData.computeInlineReplacedSize(outerWidth, outerHeight);
|
||||
testData.computeInlineReplacedSize(testContainerWidth,
|
||||
testContainerHeight);
|
||||
var svgElement = testData.buildSVGOrPlaceholder();
|
||||
var container =
|
||||
testData.buildContainer(svgElement);
|
||||
|
|
|
@ -157,10 +157,6 @@ function assert_nodelist_contents_equal_noorder(actual, expected, message) {
|
|||
}
|
||||
}
|
||||
|
||||
function isVisible(el) {
|
||||
return el.offsetTop != 0;
|
||||
}
|
||||
|
||||
function isVoidElement(elementName) {
|
||||
return HTML5_VOID_ELEMENTS.indexOf(elementName) >= 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<iframe src="{{location[scheme]}}://{{domains[www2]}}:{{ports[http][0]}}{{location[path]}}/../Promise-incumbent-global-subsubframe.sub.html"></iframe>
|
||||
<script>
|
||||
document.domain = "{{host}}";
|
||||
onmessage = function(e) {
|
||||
if (e.data == "start") {
|
||||
frames[0].Promise.resolve().then(frames[0].postMessage.bind(frames[0], "start", "*"));
|
||||
} else {
|
||||
parent.postMessage(e.data, "*");
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html>
|
||||
<script>
|
||||
document.domain = "{{host}}";
|
||||
onmessage = function (e) {
|
||||
parent.postMessage(
|
||||
{
|
||||
actual: e.origin,
|
||||
expected: "{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}",
|
||||
reason: "Incumbent should have been the caller of then()"
|
||||
},
|
||||
"*");
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,20 @@
|
|||
<!doctype html>
|
||||
<meta charset=utf-8>
|
||||
<title></title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
<iframe src="{{location[scheme]}}://{{domains[www1]}}:{{ports[http][0]}}{{location[path]}}/../Promise-incumbent-global-subframe.sub.html"></iframe>
|
||||
<script>
|
||||
|
||||
var t = async_test("Check the incumbent global Promise callbacks are called with");
|
||||
|
||||
onload = t.step_func(function() {
|
||||
onmessage = t.step_func_done(function(e) {
|
||||
var d = e.data;
|
||||
assert_equals(d.actual, d.expected, d.reason);
|
||||
});
|
||||
|
||||
frames[0].postMessage("start", "*");
|
||||
});
|
||||
|
||||
</script>
|
|
@ -105,6 +105,9 @@ W3C-TEST.ORG:subresource-integrity/refresh-header.js.headers
|
|||
|
||||
# semi-legitimate use of console.*
|
||||
CONSOLE:streams/resources/test-utils.js
|
||||
CONSOLE:service-workers/service-worker/resources/navigation-redirect-other-origin.html
|
||||
CONSOLE:service-workers/service-worker/navigation-redirect.https.html
|
||||
CONSOLE:service-workers/service-worker/resources/clients-get-other-origin.html
|
||||
|
||||
# Lint doesn't know about sub.svg I guess
|
||||
PARSE-FAILED:content-security-policy/svg/including.sub.svg
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<!doctype html>
|
||||
<title>Selection.collapse() tests</title>
|
||||
<meta name=timeout content=long>
|
||||
<div id=log></div>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<!doctype html>
|
||||
<title>Selection extend() tests</title>
|
||||
<meta charset=utf-8>
|
||||
<meta name=timeout content=long>
|
||||
<body>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ServiceWorkerGlobalScope: close operation</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="../resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
|
||||
service_worker_test(
|
||||
'resources/close-worker.js', 'ServiceWorkerGlobalScope: close operation');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ServiceWorkerGlobalScope: registration</title>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<script src='../resources/test-helpers.sub.js'></script>
|
||||
<script>
|
||||
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/registration-attribute-worker.js';
|
||||
var scope = 'resources/scope/registration-attribute';
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
var expected_events_seen = [
|
||||
'updatefound',
|
||||
'install',
|
||||
'statechange(installed)',
|
||||
'statechange(activating)',
|
||||
'activate',
|
||||
'statechange(activated)',
|
||||
'fetch',
|
||||
];
|
||||
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
expected_events_seen.toString(),
|
||||
'Service Worker should respond to fetch');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Verify registration attribute on ServiceWorkerGlobalScope');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,8 @@
|
|||
importScripts('../../resources/interfaces.js');
|
||||
importScripts('../../resources/worker-testharness.js');
|
||||
|
||||
test(function() {
|
||||
assert_throws({name: 'InvalidAccessError'}, function() {
|
||||
self.close();
|
||||
});
|
||||
}, 'ServiceWorkerGlobalScope close operation');
|
|
@ -0,0 +1,132 @@
|
|||
importScripts('../../resources/test-helpers.sub.js');
|
||||
importScripts('../../resources/worker-testharness.js');
|
||||
|
||||
var events_seen = [];
|
||||
|
||||
assert_equals(
|
||||
self.registration.scope,
|
||||
normalizeURL('scope/registration-attribute'),
|
||||
'On worker script evaluation, registration attribute should be set');
|
||||
assert_equals(
|
||||
self.registration.installing,
|
||||
null,
|
||||
'On worker script evaluation, installing worker should be null');
|
||||
assert_equals(
|
||||
self.registration.waiting,
|
||||
null,
|
||||
'On worker script evaluation, waiting worker should be null');
|
||||
assert_equals(
|
||||
self.registration.active,
|
||||
null,
|
||||
'On worker script evaluation, active worker should be null');
|
||||
|
||||
self.registration.addEventListener('updatefound', function() {
|
||||
events_seen.push('updatefound');
|
||||
|
||||
assert_equals(
|
||||
self.registration.scope,
|
||||
normalizeURL('scope/registration-attribute'),
|
||||
'On updatefound event, registration attribute should be set');
|
||||
assert_equals(
|
||||
self.registration.installing.scriptURL,
|
||||
normalizeURL('registration-attribute-worker.js'),
|
||||
'On updatefound event, installing worker should be set');
|
||||
assert_equals(
|
||||
self.registration.waiting,
|
||||
null,
|
||||
'On updatefound event, waiting worker should be null');
|
||||
assert_equals(
|
||||
self.registration.active,
|
||||
null,
|
||||
'On updatefound event, active worker should be null');
|
||||
|
||||
assert_equals(
|
||||
self.registration.installing.state,
|
||||
'installing',
|
||||
'On updatefound event, worker should be in the installing state');
|
||||
|
||||
var worker = self.registration.installing;
|
||||
self.registration.installing.addEventListener('statechange', function() {
|
||||
events_seen.push('statechange(' + worker.state + ')');
|
||||
});
|
||||
});
|
||||
|
||||
self.addEventListener('install', function(e) {
|
||||
events_seen.push('install');
|
||||
|
||||
assert_equals(
|
||||
self.registration.scope,
|
||||
normalizeURL('scope/registration-attribute'),
|
||||
'On install event, registration attribute should be set');
|
||||
assert_equals(
|
||||
self.registration.installing.scriptURL,
|
||||
normalizeURL('registration-attribute-worker.js'),
|
||||
'On install event, installing worker should be set');
|
||||
assert_equals(
|
||||
self.registration.waiting,
|
||||
null,
|
||||
'On install event, waiting worker should be null');
|
||||
assert_equals(
|
||||
self.registration.active,
|
||||
null,
|
||||
'On install event, active worker should be null');
|
||||
|
||||
assert_equals(
|
||||
self.registration.installing.state,
|
||||
'installing',
|
||||
'On install event, worker should be in the installing state');
|
||||
});
|
||||
|
||||
self.addEventListener('activate', function(e) {
|
||||
events_seen.push('activate');
|
||||
|
||||
assert_equals(
|
||||
self.registration.scope,
|
||||
normalizeURL('scope/registration-attribute'),
|
||||
'On activate event, registration attribute should be set');
|
||||
assert_equals(
|
||||
self.registration.installing,
|
||||
null,
|
||||
'On activate event, installing worker should be null');
|
||||
assert_equals(
|
||||
self.registration.waiting,
|
||||
null,
|
||||
'On activate event, waiting worker should be null');
|
||||
assert_equals(
|
||||
self.registration.active.scriptURL,
|
||||
normalizeURL('registration-attribute-worker.js'),
|
||||
'On activate event, active worker should be set');
|
||||
|
||||
assert_equals(
|
||||
self.registration.active.state,
|
||||
'activating',
|
||||
'On activate event, worker should be in the activating state');
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', function(e) {
|
||||
events_seen.push('fetch');
|
||||
|
||||
assert_equals(
|
||||
self.registration.scope,
|
||||
normalizeURL('scope/registration-attribute'),
|
||||
'On fetch event, registration attribute should be set');
|
||||
assert_equals(
|
||||
self.registration.installing,
|
||||
null,
|
||||
'On fetch event, installing worker should be null');
|
||||
assert_equals(
|
||||
self.registration.waiting,
|
||||
null,
|
||||
'On fetch event, waiting worker should be null');
|
||||
assert_equals(
|
||||
self.registration.active.scriptURL,
|
||||
normalizeURL('registration-attribute-worker.js'),
|
||||
'On fetch event, active worker should be set');
|
||||
|
||||
assert_equals(
|
||||
self.registration.active.state,
|
||||
'activated',
|
||||
'On fetch event, worker should be in the activated state');
|
||||
|
||||
e.respondWith(new Response(events_seen));
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
function matchQuery(query) {
|
||||
return self.location.href.indexOf(query) != -1;
|
||||
}
|
||||
|
||||
if (matchQuery('?evaluation'))
|
||||
self.registration.unregister();
|
||||
|
||||
self.addEventListener('install', function(e) {
|
||||
if (matchQuery('?install'))
|
||||
self.registration.unregister();
|
||||
});
|
||||
|
||||
self.addEventListener('activate', function(e) {
|
||||
if (matchQuery('?activate'))
|
||||
self.registration.unregister();
|
||||
});
|
||||
|
||||
self.addEventListener('message', function(e) {
|
||||
self.registration.unregister()
|
||||
.then(function(result) {
|
||||
e.data.port.postMessage({result: result});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,25 @@
|
|||
importScripts('../../resources/test-helpers.sub.js');
|
||||
importScripts('../../resources/worker-testharness.js');
|
||||
|
||||
var events_seen = [];
|
||||
|
||||
self.registration.addEventListener('updatefound', function() {
|
||||
events_seen.push('updatefound');
|
||||
});
|
||||
|
||||
self.addEventListener('activate', function(e) {
|
||||
events_seen.push('activate');
|
||||
});
|
||||
|
||||
self.addEventListener('fetch', function(e) {
|
||||
events_seen.push('fetch');
|
||||
e.respondWith(new Response(events_seen));
|
||||
});
|
||||
|
||||
self.addEventListener('message', function(e) {
|
||||
events_seen.push('message');
|
||||
self.registration.update();
|
||||
});
|
||||
|
||||
// update() during the script evaluation should be ignored.
|
||||
self.registration.update();
|
|
@ -0,0 +1,14 @@
|
|||
import os
|
||||
import time
|
||||
|
||||
def main(request, response):
|
||||
# update() does not bypass cache so set the max-age to 0 such that update()
|
||||
# can find a new version in the network.
|
||||
headers = [('Cache-Control', 'max-age: 0'),
|
||||
('Content-Type', 'application/javascript')]
|
||||
with open(os.path.join(os.path.dirname(__file__),
|
||||
'update-worker.js'), 'r') as file:
|
||||
script = file.read()
|
||||
# Return a different script for each access.
|
||||
return headers, '// %s\n%s' % (time.time(), script)
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ServiceWorkerGlobalScope: unregister</title>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<script src='../resources/test-helpers.sub.js'></script>
|
||||
<script>
|
||||
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/unregister-worker.js?evaluation';
|
||||
var scope = 'resources/scope/unregister-on-script-evaluation';
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'redundant');
|
||||
})
|
||||
.then(function() {
|
||||
return navigator.serviceWorker.getRegistration(scope);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result,
|
||||
undefined,
|
||||
'After unregister(), the registration should not found');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Unregister on script evaluation');
|
||||
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/unregister-worker.js?install';
|
||||
var scope = 'resources/scope/unregister-on-install-event';
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'redundant');
|
||||
})
|
||||
.then(function() {
|
||||
return navigator.serviceWorker.getRegistration(scope);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result,
|
||||
undefined,
|
||||
'After unregister(), the registration should not found');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Unregister on installing event');
|
||||
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/unregister-worker.js?activate';
|
||||
var scope = 'resources/scope/unregister-on-activate-event';
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'redundant');
|
||||
})
|
||||
.then(function() {
|
||||
return navigator.serviceWorker.getRegistration(scope);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result,
|
||||
undefined,
|
||||
'After unregister(), the registration should not found');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Unregister on activate event');
|
||||
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/unregister-worker.js';
|
||||
var scope = 'resources/unregister-controlling-worker.html';
|
||||
|
||||
var controller;
|
||||
var frame;
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
controller = frame.contentWindow.navigator.serviceWorker.controller;
|
||||
|
||||
assert_equals(
|
||||
controller.scriptURL,
|
||||
normalizeURL(script),
|
||||
'Service worker should control a new document')
|
||||
|
||||
// Wait for the completion of unregister() on the worker.
|
||||
var channel = new MessageChannel();
|
||||
var promise = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_true(e.data.result,
|
||||
'unregister() should successfully finish');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
controller.postMessage({port: channel.port2}, [channel.port2]);
|
||||
return promise;
|
||||
})
|
||||
.then(function() {
|
||||
return navigator.serviceWorker.getRegistration(scope);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result,
|
||||
undefined,
|
||||
'After unregister(), the registration should not found');
|
||||
assert_equals(
|
||||
frame.contentWindow.navigator.serviceWorker.controller,
|
||||
controller,
|
||||
'After unregister(), the worker should still control the document');
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(new_frame) {
|
||||
assert_equals(
|
||||
new_frame.contentWindow.navigator.serviceWorker.controller,
|
||||
null,
|
||||
'After unregister(), the worker should not control a new document');
|
||||
|
||||
frame.remove();
|
||||
new_frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
}, 'Unregister controlling service worker');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ServiceWorkerGlobalScope: update</title>
|
||||
<script src='/resources/testharness.js'></script>
|
||||
<script src='/resources/testharnessreport.js'></script>
|
||||
<script src='../resources/test-helpers.sub.js'></script>
|
||||
<script>
|
||||
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/update-worker.py';
|
||||
var scope = 'resources/scope/update';
|
||||
var registration;
|
||||
var frame1;
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(r) {
|
||||
registration = r;
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(f) {
|
||||
frame1 = f;
|
||||
registration.active.postMessage('update');
|
||||
return wait_for_update(t, registration);
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame2) {
|
||||
var expected_events_seen = [
|
||||
'updatefound', // by register().
|
||||
'activate',
|
||||
'fetch',
|
||||
'message',
|
||||
'updatefound', // by update() in the message handler.
|
||||
'fetch',
|
||||
];
|
||||
assert_equals(
|
||||
frame2.contentDocument.body.textContent,
|
||||
expected_events_seen.toString(),
|
||||
'events seen by the worker');
|
||||
frame1.remove();
|
||||
frame2.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Update a registration on ServiceWorkerGlobalScope');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: registration events</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/empty-worker.js';
|
||||
var scope = 'resources/blank.html';
|
||||
var registration;
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
var sw = registration.installing;
|
||||
|
||||
return new Promise(t.step_func(function(resolve) {
|
||||
sw.onstatechange = t.step_func(function() {
|
||||
if (sw.state === 'installed') {
|
||||
assert_equals(registration.active, null,
|
||||
'installed event should be fired before activating service worker');
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}));
|
||||
})
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'installed event should be fired before activating service worker');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Activation occurs after registration</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test('activation occurs after registration');
|
||||
t.step(function() {
|
||||
var scope = 'resources/blank.html';
|
||||
var registration;
|
||||
|
||||
service_worker_unregister_and_register(
|
||||
t, 'resources/empty-worker.js', scope)
|
||||
.then(function(r) {
|
||||
registration = r;
|
||||
assert_equals(
|
||||
r.installing.state,
|
||||
'installing',
|
||||
'worker should be in the "installing" state upon registration');
|
||||
return wait_for_state(t, r.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ServiceWorker: navigator.serviceWorker.active</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
// "active" is set
|
||||
async_test(function(t) {
|
||||
var step = t.step_func.bind(t);
|
||||
var url = 'resources/empty-worker.js';
|
||||
var scope = 'resources/blank.html';
|
||||
var frame;
|
||||
var registration;
|
||||
|
||||
service_worker_unregister(t, scope)
|
||||
.then(step(function() { return with_iframe(scope); }))
|
||||
.then(step(function(f) {
|
||||
frame = f;
|
||||
return navigator.serviceWorker.register(url, {scope: scope});
|
||||
}))
|
||||
.then(step(function(r) {
|
||||
registration = r;
|
||||
return wait_for_state(t, r.installing, 'activating');
|
||||
}))
|
||||
.then(step(function() {
|
||||
var container = frame.contentWindow.navigator.serviceWorker;
|
||||
assert_equals(
|
||||
container.controller,
|
||||
null,
|
||||
'On activating state a document should not have a controller');
|
||||
assert_equals(
|
||||
registration.active.scriptURL,
|
||||
normalizeURL(url),
|
||||
'On activating state a document should have an active worker ');
|
||||
assert_equals(
|
||||
registration.waiting,
|
||||
null,
|
||||
'On activating state a document should not have a waiting worker');
|
||||
assert_equals(
|
||||
registration.installing,
|
||||
null,
|
||||
'On activating state a document should not have an installing ' +
|
||||
'worker');
|
||||
|
||||
// FIXME: Add a test for a frame created after installation.
|
||||
// Should the existing frame ("frame") block activation?
|
||||
}))
|
||||
.then(step(function() {
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
}))
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'active is set');
|
||||
</script>
|
|
@ -0,0 +1,91 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
var INSTALL_APPCACHE_URL = "resources/appcache-ordering.install.html";
|
||||
var IS_APPCACHED_URL = "resources/appcache-ordering.is-appcached.html";
|
||||
var SERVICE_WORKER_SCOPE = "resources/appcache-ordering";
|
||||
var SERVICE_WORKER_SCRIPT = "resources/empty-worker.js";
|
||||
|
||||
var resolve_install_appcache = undefined;
|
||||
var reject_install_appcache = undefined;
|
||||
|
||||
var frames = [];
|
||||
|
||||
// Called by the INSTALL_APPCACHE_URL child frame.
|
||||
function notify_appcache_installed(success) {
|
||||
if (success)
|
||||
resolve_install_appcache();
|
||||
else
|
||||
reject_install_appcache();
|
||||
}
|
||||
|
||||
function install_appcache() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var frame = document.createElement('iframe');
|
||||
frames.push(frame);
|
||||
frame.src = INSTALL_APPCACHE_URL;
|
||||
document.body.appendChild(frame);
|
||||
resolve_install_appcache = function() {
|
||||
document.body.removeChild(frame);
|
||||
resolve();
|
||||
};
|
||||
reject_install_appcache = function() {
|
||||
document.body.removeChild(frame);
|
||||
reject();
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
var resolve_is_appcached = undefined;
|
||||
|
||||
// Called by the IS_APPCACHED_URL child frame.
|
||||
function notify_is_appcached(is) {
|
||||
resolve_is_appcached(is);
|
||||
}
|
||||
|
||||
function is_appcached() {
|
||||
return new Promise(function(resolve) {
|
||||
var frame = document.createElement('iframe');
|
||||
frames.push(frame);
|
||||
frame.src = IS_APPCACHED_URL;
|
||||
document.body.appendChild(frame);
|
||||
resolve_is_appcached = function(is) {
|
||||
document.body.removeChild(frame);
|
||||
resolve(is);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
service_worker_unregister(t, SERVICE_WORKER_SCOPE)
|
||||
.then(function() {
|
||||
return install_appcache();
|
||||
})
|
||||
.then(function() {
|
||||
return is_appcached();
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_true(result, 'appcache should initially be utilized');
|
||||
return service_worker_unregister_and_register(
|
||||
t, SERVICE_WORKER_SCRIPT, SERVICE_WORKER_SCOPE);
|
||||
})
|
||||
.then(function(r) {
|
||||
return wait_for_state(t, r.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return is_appcached();
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_false(result, 'but serviceworkers should take priority');
|
||||
frames.forEach(function(f) { f.remove(); });
|
||||
service_worker_unregister_and_done(t, SERVICE_WORKER_SCOPE);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'serviceworkers take priority over appcaches');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,123 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: claim client not using registration</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
promise_test(function(t) {
|
||||
var init_scope = 'resources/blank.html?not-using-init';
|
||||
var claim_scope = 'resources/blank.html?not-using';
|
||||
var init_worker_url = 'resources/empty.js';
|
||||
var claim_worker_url = 'resources/claim-worker.js';
|
||||
var claim_worker, claim_registration, frame1, frame2;
|
||||
return service_worker_unregister_and_register(
|
||||
t, init_worker_url, init_scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return Promise.all(
|
||||
[with_iframe(init_scope), with_iframe(claim_scope)]);
|
||||
})
|
||||
.then(function(frames) {
|
||||
frame1 = frames[0];
|
||||
frame2 = frames[1];
|
||||
assert_equals(
|
||||
frame1.contentWindow.navigator.serviceWorker.controller.scriptURL,
|
||||
normalizeURL(init_worker_url),
|
||||
'Frame1 controller should not be null');
|
||||
assert_equals(
|
||||
frame2.contentWindow.navigator.serviceWorker.controller, null,
|
||||
'Frame2 controller should be null');
|
||||
return navigator.serviceWorker.register(claim_worker_url,
|
||||
{scope: claim_scope});
|
||||
})
|
||||
.then(function(registration) {
|
||||
claim_worker = registration.installing;
|
||||
claim_registration = registration;
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var saw_controllerchanged = new Promise(function(resolve) {
|
||||
frame2.contentWindow.navigator.serviceWorker.oncontrollerchange =
|
||||
function() { resolve(); }
|
||||
});
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data, 'PASS',
|
||||
'Worker call to claim() should fulfill.');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
claim_worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
return Promise.all([saw_controllerchanged, saw_message]);
|
||||
})
|
||||
.then(function() {
|
||||
assert_equals(
|
||||
frame1.contentWindow.navigator.serviceWorker.controller.scriptURL,
|
||||
normalizeURL(init_worker_url),
|
||||
'Frame1 should not be influenced');
|
||||
assert_equals(
|
||||
frame2.contentWindow.navigator.serviceWorker.controller.scriptURL,
|
||||
normalizeURL(claim_worker_url),
|
||||
'Frame2 should be controlled by the new registration');
|
||||
frame1.remove();
|
||||
frame2.remove();
|
||||
return claim_registration.unregister();
|
||||
})
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_done(t, init_scope);
|
||||
});
|
||||
}, 'Test claim client which is not using registration');
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope = 'resources/blank.html?longer-matched';
|
||||
var claim_scope = 'resources/blank.html?longer';
|
||||
var claim_worker_url = 'resources/claim-worker.js';
|
||||
var installing_worker_url = 'resources/empty-worker.js';
|
||||
var frame, claim_worker;
|
||||
return with_iframe(scope)
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return navigator.serviceWorker.register(
|
||||
claim_worker_url, {scope: claim_scope});
|
||||
})
|
||||
.then(function(registration) {
|
||||
claim_worker = registration.installing;
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return navigator.serviceWorker.register(
|
||||
installing_worker_url, {scope: scope});
|
||||
})
|
||||
.then(function() {
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data, 'PASS',
|
||||
'Worker call to claim() should fulfill.');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
claim_worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
return saw_message;
|
||||
})
|
||||
.then(function() {
|
||||
assert_equals(
|
||||
frame.contentWindow.navigator.serviceWorker.controller, null,
|
||||
'Frame should not be claimed when a longer-matched ' +
|
||||
'registration exists');
|
||||
frame.remove();
|
||||
return service_worker_unregister(t, claim_scope);
|
||||
})
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Test claim client when there\'s a longer-matched registration not ' +
|
||||
'already used by the page');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,100 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: claim client using registration</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope = 'resources/';
|
||||
var frame_url = 'resources/blank.html?using-different-registration';
|
||||
var url1 = 'resources/empty.js';
|
||||
var url2 = 'resources/claim-worker.js';
|
||||
var worker, sw_registration, frame;
|
||||
return service_worker_unregister_and_register(t, url1, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return with_iframe(frame_url);
|
||||
})
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return navigator.serviceWorker.register(url2, {scope: frame_url});
|
||||
})
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
sw_registration = registration;
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var saw_controllerchanged = new Promise(function(resolve) {
|
||||
frame.contentWindow.navigator.serviceWorker.oncontrollerchange =
|
||||
function() { resolve(); }
|
||||
});
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data, 'PASS',
|
||||
'Worker call to claim() should fulfill.');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
return Promise.all([saw_controllerchanged, saw_message]);
|
||||
})
|
||||
.then(function() {
|
||||
assert_equals(
|
||||
frame.contentWindow.navigator.serviceWorker.controller.scriptURL,
|
||||
normalizeURL(url2),
|
||||
'Frame1 controller scriptURL should be changed to url2');
|
||||
frame.remove();
|
||||
return sw_registration.unregister();
|
||||
})
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Test worker claims client which is using another registration');
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope = 'resources/blank.html?using-same-registration';
|
||||
var url1 = 'resources/empty.js';
|
||||
var url2 = 'resources/claim-worker.js';
|
||||
var frame, worker;
|
||||
return service_worker_unregister_and_register(t, url1, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return navigator.serviceWorker.register(url2, {scope: scope});
|
||||
})
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, registration.installing, 'installed');
|
||||
})
|
||||
.then(function() {
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data, 'FAIL: exception: InvalidStateError',
|
||||
'Worker call to claim() should reject with ' +
|
||||
'InvalidStateError');
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
return saw_message;
|
||||
})
|
||||
.then(function() {
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Test for the waiting worker claims a client which is using the the ' +
|
||||
'same registration');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Clients.get across origins</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
var host_info = get_host_info();
|
||||
|
||||
var scope = 'resources/blank.html?clients-get';
|
||||
var t = async_test('Test Clients.get() cross origin');
|
||||
var other_origin_iframe = host_info['HTTPS_REMOTE_ORIGIN'] + base_path() +
|
||||
'resources/clients-get-other-origin.html';
|
||||
var myOriginClientId;
|
||||
t.step(function() {
|
||||
service_worker_unregister_and_register(
|
||||
t, 'resources/clients-get-worker.js', scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(frame1) {
|
||||
myOriginClientId = frame1.contentDocument.body.textContent;
|
||||
return with_iframe(other_origin_iframe);
|
||||
})
|
||||
.then(function(frame2) {
|
||||
window.addEventListener('message', on_message_other_origin, false);
|
||||
frame2.contentWindow.postMessage(
|
||||
{clientId: myOriginClientId,
|
||||
message: 'get_client_id'},
|
||||
host_info['HTTPS_REMOTE_ORIGIN']);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
});
|
||||
|
||||
function on_message_other_origin(e) {
|
||||
assert_equals(e.data.result, undefined);
|
||||
t.done();
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,70 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Clients.get</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
var host_info = get_host_info();
|
||||
|
||||
var scope = 'resources/clients-get-frame.html';
|
||||
var t = async_test('Test Clients.get()');
|
||||
var clientIds = [];
|
||||
var frame;
|
||||
t.step(function() {
|
||||
service_worker_unregister_and_register(
|
||||
t, 'resources/clients-get-worker.js', scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return with_iframe(scope + '#1');
|
||||
})
|
||||
.then(function(frame1) {
|
||||
frame1.focus();
|
||||
return wait_for_clientId();
|
||||
})
|
||||
.then(function(clientId) {
|
||||
clientIds.push(clientId);
|
||||
return with_iframe(scope + '#2');
|
||||
})
|
||||
.then(function(frame2) {
|
||||
frame = frame2;
|
||||
return wait_for_clientId();
|
||||
})
|
||||
.then(function(clientId) {
|
||||
clientIds.push(clientId);
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(on_message);
|
||||
frame.contentWindow.navigator.serviceWorker.controller.postMessage(
|
||||
{port:channel.port2, clientIds:clientIds,
|
||||
message: 'get_client_ids'}, [channel.port2]);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
});
|
||||
|
||||
function wait_for_clientId() {
|
||||
return new Promise(function(resolve, reject) {
|
||||
function get_client_id(e) {
|
||||
window.removeEventListener("message", get_client_id);
|
||||
resolve(e.data.clientId);
|
||||
}
|
||||
window.addEventListener("message", get_client_id, false);
|
||||
});
|
||||
}
|
||||
|
||||
var expected = [
|
||||
/* visibilityState, focused, url, frameType */
|
||||
['visible', true, new URL(scope + '#1', location).toString(), 'nested'],
|
||||
['visible', false, new URL(scope + '#2', location).toString(), 'nested'],
|
||||
undefined
|
||||
];
|
||||
|
||||
function on_message(e) {
|
||||
assert_equals(e.data.length, 3);
|
||||
assert_array_equals(e.data[0], expected[0]);
|
||||
assert_array_equals(e.data[1], expected[1]);
|
||||
assert_equals(e.data[2], expected[2]);
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,78 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Clients.matchAll with various clientTypes</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
var scope = 'resources/clients-matchall-client-types';
|
||||
var iframe_url = scope + '-iframe.html';
|
||||
var shared_worker_url = scope + '-shared-worker.js';
|
||||
|
||||
/* visibilityState, focused, url, frameType */
|
||||
var expected_without_type = [
|
||||
['visible', true, new URL(iframe_url, location).href, 'nested']
|
||||
];
|
||||
var expected_with_window = [
|
||||
['visible', true, new URL(iframe_url, location).href, 'nested']
|
||||
];
|
||||
var expected_with_shared_worker = [
|
||||
[,,new URL(shared_worker_url, location).href, 'none']
|
||||
];
|
||||
var expected_with_all = [
|
||||
['visible', true, new URL(iframe_url, location).href, 'nested'],
|
||||
[,,new URL(shared_worker_url, location).href, 'none']
|
||||
];
|
||||
|
||||
function test_matchall(frame, expected, query_options) {
|
||||
// Make sure the frame gets focus.
|
||||
frame.focus();
|
||||
expected.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = function(e) {
|
||||
assert_equals(e.data.length, expected.length);
|
||||
for (var i = 0; i < e.data.length; i++)
|
||||
assert_array_equals(e.data[i], expected[i]);
|
||||
resolve();
|
||||
};
|
||||
frame.contentWindow.navigator.serviceWorker.controller.postMessage(
|
||||
{port:channel.port2, options:query_options},
|
||||
[channel.port2]);
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(function(t) {
|
||||
var frame;
|
||||
return service_worker_unregister_and_register(
|
||||
t, 'resources/clients-matchall-worker.js', scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(iframe_url); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return new Promise(function(resolve, reject) {
|
||||
var w = new SharedWorker(shared_worker_url);
|
||||
w.port.onmessage = resolve;
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
return test_matchall(frame, expected_without_type, {});
|
||||
})
|
||||
.then(function() {
|
||||
return test_matchall(frame, expected_with_window, {type:'window'});
|
||||
})
|
||||
//.then(function() {
|
||||
// return test_matchall(frame, expected_with_shared_worker,
|
||||
// {type:'sharedworker'});
|
||||
// })
|
||||
//.then(function() {
|
||||
// return test_matchall(frame, expected_with_all, {type:'all'});
|
||||
// })
|
||||
.then(function() {
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Verify matchAll() with various client types');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,93 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Clients.matchAll with includeUncontrolled</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
var base_url = 'resources/blank.html'; // This is out-of-scope.
|
||||
var scope = base_url + '?clients-matchAll-includeUncontrolled';
|
||||
var frames = [];
|
||||
|
||||
// Creates 3 iframes, 2 for in-scope and 1 for out-of-scope.
|
||||
// The frame opened for scope + '#2' is returned via a promise.
|
||||
function create_iframes(scope) {
|
||||
return with_iframe(base_url)
|
||||
.then(function(frame0) {
|
||||
frames.push(frame0);
|
||||
return with_iframe(scope + '#1');
|
||||
})
|
||||
.then(function(frame1) {
|
||||
frames.push(frame1);
|
||||
return with_iframe(scope + '#2');
|
||||
})
|
||||
.then(function(frame2) {
|
||||
frames.push(frame2);
|
||||
return frame2;
|
||||
})
|
||||
}
|
||||
|
||||
var expected_without_include_uncontrolled = [
|
||||
/* visibilityState, focused, url, frameType */
|
||||
['visible', false, new URL(scope + '#1', location).toString(), 'nested'],
|
||||
['visible', true, new URL(scope + '#2', location).toString(), 'nested']
|
||||
];
|
||||
|
||||
var expected_with_include_uncontrolled = [
|
||||
/* visibilityState, focused, url, frameType */
|
||||
['visible', true, location.href, 'top-level'],
|
||||
['visible', false, new URL(scope + '#1', location).toString(), 'nested'],
|
||||
['visible', true, new URL(scope + '#2', location).toString(), 'nested'],
|
||||
['visible', false, new URL(base_url, location).toString(), 'nested']
|
||||
];
|
||||
|
||||
function test_matchall(frame, expected, query_options) {
|
||||
// Make sure we have focus for '#2' frame and its parent window.
|
||||
frame.focus();
|
||||
frame.contentWindow.focus();
|
||||
expected.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = function(e) {
|
||||
// Ignore hidden clients which may be coming from background tabs, or
|
||||
// clients unrelated to this test.
|
||||
var data = e.data.filter(function(info) {
|
||||
return info[0] == 'visible' &&
|
||||
info[2].indexOf('service-worker') > -1;
|
||||
});
|
||||
data.sort(function(a, b) { return a[2] > b[2] ? 1 : -1; });
|
||||
assert_equals(data.length, expected.length);
|
||||
for (var i = 0; i < data.length; i++)
|
||||
assert_array_equals(data[i], expected[i]);
|
||||
resolve(frame);
|
||||
};
|
||||
frame.contentWindow.navigator.serviceWorker.controller.postMessage(
|
||||
{port:channel.port2, options:query_options},
|
||||
[channel.port2]);
|
||||
});
|
||||
}
|
||||
|
||||
// Run clients.matchAll without and with includeUncontrolled=true.
|
||||
// (We want to run the two tests sequentially in the same async_test
|
||||
// so that we can use the same set of iframes without intefering each other.
|
||||
async_test(function(t) {
|
||||
service_worker_unregister_and_register(
|
||||
t, 'resources/clients-matchall-worker.js', scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return create_iframes(scope); })
|
||||
.then(function(frame) {
|
||||
return test_matchall(frame, expected_without_include_uncontrolled);
|
||||
})
|
||||
.then(function(frame) {
|
||||
return test_matchall(frame, expected_with_include_uncontrolled,
|
||||
{includeUncontrolled:true});
|
||||
})
|
||||
.then(function() {
|
||||
frames.forEach(function(f) { f.remove() });
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify matchAll() respect includeUncontrolled');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Clients.matchAll</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
var scope = 'resources/blank.html?clients-matchAll';
|
||||
var t = async_test('Test Clients.matchAll()');
|
||||
var frames = [];
|
||||
t.step(function() {
|
||||
service_worker_unregister_and_register(
|
||||
t, 'resources/clients-matchall-worker.js', scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope + '#1'); })
|
||||
.then(function(frame1) {
|
||||
frames.push(frame1);
|
||||
frame1.focus();
|
||||
return with_iframe(scope + '#2');
|
||||
})
|
||||
.then(function(frame2) {
|
||||
frames.push(frame2);
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(onMessage);
|
||||
frame2.contentWindow.navigator.serviceWorker.controller.postMessage(
|
||||
{port:channel.port2}, [channel.port2]);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
});
|
||||
|
||||
var expected = [
|
||||
/* visibilityState, focused, url, frameType */
|
||||
['visible', true, new URL(scope + '#1', location).toString(), 'nested'],
|
||||
['visible', false, new URL(scope + '#2', location).toString(), 'nested']
|
||||
];
|
||||
|
||||
function onMessage(e) {
|
||||
assert_equals(e.data.length, 2);
|
||||
assert_array_equals(e.data[0], expected[0]);
|
||||
assert_array_equals(e.data[1], expected[1]);
|
||||
frames.forEach(function(f) { f.remove(); });
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,45 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Controller on load</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
var t = async_test('controller is set for a controlled document');
|
||||
t.step(function() {
|
||||
var url = 'resources/empty-worker.js';
|
||||
var scope = 'resources/blank.html';
|
||||
var registration;
|
||||
var controller;
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, url, scope)
|
||||
.then(t.step_func(function(swr) {
|
||||
registration = swr;
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
}))
|
||||
.then(t.step_func(function() {
|
||||
return with_iframe(scope)
|
||||
}))
|
||||
.then(t.step_func(function(f) {
|
||||
frame = f;
|
||||
var w = frame.contentWindow;
|
||||
controller = w.navigator.serviceWorker.controller;
|
||||
assert_true(controller instanceof w.ServiceWorker,
|
||||
'controller should be a ServiceWorker object');
|
||||
assert_equals(controller.scriptURL, normalizeURL(url));
|
||||
|
||||
// objects from different windows should not be equal
|
||||
assert_not_equals(controller, registration.active);
|
||||
|
||||
return w.navigator.serviceWorker.getRegistration();
|
||||
}))
|
||||
.then(t.step_func(function(frameRegistration) {
|
||||
// SW objects from same window should be equal
|
||||
assert_equals(frameRegistration.active, controller);
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
}))
|
||||
.catch(unreached_rejection(t));
|
||||
});
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,54 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Controller on reload</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
promise_test(function(t) {
|
||||
var scope = 'resources/blank.html';
|
||||
var frame;
|
||||
var registration;
|
||||
var controller;
|
||||
return service_worker_unregister(t, scope)
|
||||
.then(function() {
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return frame.contentWindow.navigator.serviceWorker.register(
|
||||
'resources/empty-worker.js', {scope: scope});
|
||||
})
|
||||
.then(function(swr) {
|
||||
registration = swr;
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var w = frame.contentWindow;
|
||||
assert_equals(w.navigator.serviceWorker.controller, null,
|
||||
'controller should be null until the document is ' +
|
||||
'reloaded');
|
||||
return new Promise(function(resolve) {
|
||||
frame.onload = function() { resolve(); }
|
||||
w.location.reload();
|
||||
});
|
||||
})
|
||||
.then(function() {
|
||||
var w = frame.contentWindow;
|
||||
controller = w.navigator.serviceWorker.controller;
|
||||
assert_true(controller instanceof w.ServiceWorker,
|
||||
'controller should be a ServiceWorker object upon reload');
|
||||
|
||||
// objects from separate windows should not be equal
|
||||
assert_not_equals(controller, registration.active);
|
||||
|
||||
return w.navigator.serviceWorker.getRegistration();
|
||||
})
|
||||
.then(function(frameRegistration) {
|
||||
assert_equals(frameRegistration.active, controller);
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'controller is set upon reload after registration');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/extendable-event-async-waituntil.js';
|
||||
var scope = 'resources/async-waituntil';
|
||||
var worker;
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = function(e) { resolve(e.data); }
|
||||
});
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
return saw_message;
|
||||
})
|
||||
.then(function(message) {
|
||||
assert_equals(message, 'PASS');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
}, 'Calling waitUntil asynchronously throws an exception');
|
||||
</script>
|
|
@ -0,0 +1,125 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ExtendableEvent: waitUntil</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
function runTest(test, scope, onRegister) {
|
||||
var script = 'resources/extendable-event-waituntil.js?' + scope;
|
||||
service_worker_unregister_and_register(test, script, scope)
|
||||
.then(function(registration) {
|
||||
onRegister(registration.installing);
|
||||
});
|
||||
}
|
||||
|
||||
// Sends a SYN to the worker and asynchronously listens for an ACK; sets
|
||||
// |obj.synced| to true once ack'd.
|
||||
function syncWorker(test, worker, obj) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = test.step_func(function(e) {
|
||||
var message = e.data;
|
||||
assert_equals(message, 'SYNC',
|
||||
'Should receive sync message from worker.');
|
||||
obj.synced = true;
|
||||
channel.port1.postMessage('ACK');
|
||||
});
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
// Passing scope as the test switch for worker script.
|
||||
var scope = 'resources/install-fulfilled';
|
||||
var onRegister = function(worker) {
|
||||
var obj = {};
|
||||
wait_for_state(t, worker, 'installed')
|
||||
.then(function() {
|
||||
assert_true(
|
||||
obj.synced,
|
||||
'state should be "installed" after the waitUntil promise ' +
|
||||
'for "oninstall" is fulfilled.');
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
syncWorker(t, worker, obj);
|
||||
};
|
||||
runTest(t, scope, onRegister);
|
||||
}, 'Test install event waitUntil fulfilled');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/install-multiple-fulfilled';
|
||||
var onRegister = function(worker) {
|
||||
var obj1 = {};
|
||||
var obj2 = {};
|
||||
wait_for_state(t, worker, 'installed')
|
||||
.then(function() {
|
||||
assert_true(
|
||||
obj1.synced && obj2.synced,
|
||||
'state should be "installed" after all waitUntil promises ' +
|
||||
'for "oninstall" are fulfilled.');
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
syncWorker(t, worker, obj1);
|
||||
syncWorker(t, worker, obj2);
|
||||
};
|
||||
runTest(t, scope, onRegister);
|
||||
}, 'Test ExtendableEvent multiple waitUntil fulfilled.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/install-reject-precedence';
|
||||
var onRegister = function(worker) {
|
||||
wait_for_state(t, worker, 'redundant')
|
||||
.then(function() {
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
};
|
||||
runTest(t, scope, onRegister);
|
||||
}, 'Test ExtendableEvent waitUntil reject precedence.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/activate-fulfilled';
|
||||
var onRegister = function(worker) {
|
||||
var obj = {};
|
||||
wait_for_state(t, worker, 'activating')
|
||||
.then(function() {
|
||||
syncWorker(t, worker, obj);
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
assert_true(
|
||||
obj.synced,
|
||||
'state should be "activated" after the waitUntil promise ' +
|
||||
'for "onactivate" is fulfilled.');
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
};
|
||||
runTest(t, scope, onRegister);
|
||||
}, 'Test activate event waitUntil fulfilled');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/install-rejected';
|
||||
var onRegister = function(worker) {
|
||||
wait_for_state(t, worker, 'redundant')
|
||||
.then(function() {
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
};
|
||||
runTest(t, scope, onRegister);
|
||||
}, 'Test install event waitUntil rejected');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/activate-rejected';
|
||||
var onRegister = function(worker) {
|
||||
wait_for_state(t, worker, 'activated')
|
||||
.then(function() {
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
};
|
||||
runTest(t, scope, onRegister);
|
||||
}, 'Test activate event waitUntil rejected.');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: canvas tainting of the fetched image using cached responses</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<body>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-canvas-tainting-iframe.html?cache';
|
||||
var SCRIPT = 'resources/fetch-rewrite-worker.js';
|
||||
var host_info = get_host_info();
|
||||
|
||||
login_https(t)
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
|
||||
})
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
frame.contentWindow.postMessage({},
|
||||
host_info['HTTPS_ORIGIN'],
|
||||
[channel.port2]);
|
||||
});
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify canvas tainting of fetched image in a Service Worker');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: canvas tainting of the fetched image</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<body>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-canvas-tainting-iframe.html';
|
||||
var SCRIPT = 'resources/fetch-rewrite-worker.js';
|
||||
var host_info = get_host_info();
|
||||
|
||||
login_https(t)
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
|
||||
})
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
frame.contentWindow.postMessage({},
|
||||
host_info['HTTPS_ORIGIN'],
|
||||
[channel.port2]);
|
||||
});
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify canvas tainting of fetched image in a Service Worker');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,38 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: CORS XHR of fetch()</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<body>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-cors-xhr-iframe.html';
|
||||
var SCRIPT = 'resources/fetch-rewrite-worker.js';
|
||||
var host_info = get_host_info();
|
||||
|
||||
login_https(t)
|
||||
.then(function() {
|
||||
return service_worker_unregister_and_register(t, SCRIPT, SCOPE);
|
||||
})
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
frame.contentWindow.postMessage({},
|
||||
host_info['HTTPS_ORIGIN'],
|
||||
[channel.port2]);
|
||||
});
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify CORS XHR of fetch() in a Service Worker');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: CSP control of fetch()</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-csp-iframe.html';
|
||||
var SCRIPT = 'resources/fetch-rewrite-worker.js';
|
||||
var host_info = get_host_info();
|
||||
service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
frame.contentWindow.postMessage({},
|
||||
host_info['HTTPS_ORIGIN'],
|
||||
[channel.port2]);
|
||||
});
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify CSP control of fetch() in a Service Worker');
|
||||
</script>
|
|
@ -0,0 +1,65 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ServiceWorker: navigator.serviceWorker.waiting</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope =
|
||||
'resources/fetch-event-after-navigation-within-page-iframe.html' +
|
||||
'?hashchange';
|
||||
var worker = 'resources/simple-intercept-worker.js';
|
||||
var frame;
|
||||
|
||||
return service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return frame.contentWindow.fetch_url('simple.txt');
|
||||
})
|
||||
.then(function(response) {
|
||||
assert_equals(response, 'intercepted by service worker');
|
||||
frame.contentWindow.location.hash = 'foo';
|
||||
return frame.contentWindow.fetch_url('simple.txt');
|
||||
})
|
||||
.then(function(response) {
|
||||
assert_equals(response, 'intercepted by service worker');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
}, 'Service Worker should respond to fetch event after the hash changes');
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope =
|
||||
'resources/fetch-event-after-navigation-within-page-iframe.html' +
|
||||
'?pushState';
|
||||
var worker = 'resources/simple-intercept-worker.js';
|
||||
var frame;
|
||||
|
||||
return service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return frame.contentWindow.fetch_url('simple.txt');
|
||||
})
|
||||
.then(function(response) {
|
||||
assert_equals(response, 'intercepted by service worker');
|
||||
frame.contentWindow.history.pushState('', '', 'bar');
|
||||
return frame.contentWindow.fetch_url('simple.txt');
|
||||
})
|
||||
.then(function(response) {
|
||||
assert_equals(response, 'intercepted by service worker');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
}, 'Service Worker should respond to fetch event after the pushState');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/fetch-event-async-respond-with-worker.js';
|
||||
var scope = 'resources/simple.html';
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(frame) {
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = function(e) { resolve(e.data); }
|
||||
});
|
||||
var worker = frame.contentWindow.navigator.serviceWorker.controller;
|
||||
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
frame.remove();
|
||||
return saw_message;
|
||||
})
|
||||
.then(function(message) {
|
||||
assert_equals(message, 'PASS');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
}, 'Calling respondWith asynchronously throws an exception');
|
||||
</script>
|
|
@ -0,0 +1,42 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Fetch event network error</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
var resolve_test_done;
|
||||
|
||||
var test_done_promise = new Promise(function(resolve) {
|
||||
resolve_test_done = resolve;
|
||||
});
|
||||
|
||||
// Called by the child frame.
|
||||
function notify_test_done(result) {
|
||||
resolve_test_done(result);
|
||||
}
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope = 'resources/fetch-event-network-error-controllee-iframe.html';
|
||||
var script = 'resources/fetch-event-network-error-worker.js';
|
||||
var frame;
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return test_done_promise;
|
||||
})
|
||||
.then(function(result) {
|
||||
frame.remove();
|
||||
assert_equals(result, 'PASS');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
}, 'Rejecting the fetch event or using preventDefault() causes a network ' +
|
||||
'error');
|
||||
</script>
|
|
@ -0,0 +1,997 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Fetch Event Redirect Handling</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
// ------------------------
|
||||
// Utilities for testing non-navigation requests that are intercepted with
|
||||
// a redirect.
|
||||
|
||||
var host_info = get_host_info();
|
||||
var worker = 'resources/fetch-rewrite-worker.js';
|
||||
var frameURL = host_info['HTTPS_ORIGIN'] + base_path() +
|
||||
'resources/fetch-event-redirect-iframe.html';
|
||||
var baseScope = 'resources/';
|
||||
var redirect = 'redirect.py';
|
||||
var success = base_path() + 'resources/success.py';
|
||||
|
||||
function redirect_fetch_test(t, test) {
|
||||
var scope = baseScope + test.name;
|
||||
service_worker_unregister_and_register(t, worker, scope).then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
}).then(function() {
|
||||
return with_iframe(scope + '?url=' + encodeURIComponent(frameURL));
|
||||
}).then(function(frame) {
|
||||
var hostKeySuffix = test['url_credentials'] ? '_WITH_CREDS' : '';
|
||||
|
||||
var acaorigin = '';
|
||||
var host = host_info['HTTPS_ORIGIN' + hostKeySuffix];
|
||||
if (test['redirect_dest'] === 'no-cors') {
|
||||
host = host_info['HTTPS_REMOTE_ORIGIN' + hostKeySuffix]
|
||||
} else if (test['redirect_dest'] === 'cors') {
|
||||
acaorigin = '?ACAOrigin=' + encodeURIComponent(host_info['HTTPS_ORIGIN']);
|
||||
host = host_info['HTTPS_REMOTE_ORIGIN' + hostKeySuffix]
|
||||
}
|
||||
|
||||
var dest = '?Redirect=' + encodeURIComponent(host + success + acaorigin);
|
||||
|
||||
var expectedTypeParam = test['expected_type']
|
||||
? '&expected_type=' + test['expected_type']
|
||||
: '';
|
||||
|
||||
var url = scope +
|
||||
'?url=' + encodeURIComponent(redirect + dest) +
|
||||
expectedTypeParam
|
||||
|
||||
var p = new Promise(function(resolve, reject) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = function(e) {
|
||||
frame.remove();
|
||||
if (e.data.result === 'reject') {
|
||||
reject(e.data.detail);
|
||||
} else if (e.data.result === 'success') {
|
||||
resolve(e.data.result);
|
||||
} else {
|
||||
resolve(e.data.detail);
|
||||
}
|
||||
};
|
||||
frame.contentWindow.postMessage({
|
||||
url: url,
|
||||
request_init: test.request_init,
|
||||
redirect_dest: test.redirect_dest,
|
||||
}, '*', [channel.port2]);
|
||||
});
|
||||
|
||||
if (test.should_reject) {
|
||||
return assert_promise_rejects(p);
|
||||
}
|
||||
|
||||
return p.then(function(result) {
|
||||
if (result !== 'success') {
|
||||
throw(new Error(result));
|
||||
}
|
||||
});
|
||||
}).then(function() {
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
}).catch(unreached_rejection(t));
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// Test every combination of:
|
||||
// - RequestMode (same-origin, cors, no-cors)
|
||||
// - RequestRedirect (manual, follow, error)
|
||||
// - redirect destination origin (same-origin, cors, no-cors)
|
||||
// - redirect destination credentials (no user/pass, user/pass)
|
||||
//
|
||||
// TODO: add navigation requests
|
||||
// TODO: add redirects to data URI and verify same-origin data-URL flag behavior
|
||||
// TODO: add test where original redirect URI is cross-origin
|
||||
// TODO: verify final method is correct for 301, 302, and 303
|
||||
// TODO: verify CORS redirect results in all further redirects being
|
||||
// considered cross origin
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-cors-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
|
||||
'same-origin without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-cors-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
|
||||
'no-cors without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-cors-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
|
||||
'cors without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-sameorigin-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
|
||||
'same-origin without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-sameorigin-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
|
||||
'no-cors without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-sameorigin-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
|
||||
'cors without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-nocors-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
|
||||
'same-origin without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-nocors-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
|
||||
'no-cors without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-nocors-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
|
||||
'cors without credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-cors-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
|
||||
'same-origin with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-cors-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
|
||||
'no-cors with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-cors-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, cors mode Request redirected to ' +
|
||||
'cors with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-sameorigin-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
|
||||
'same-origin with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-sameorigin-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
|
||||
'no-cors with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-sameorigin-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, same-origin mode Request redirected to ' +
|
||||
'cors with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-nocors-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
|
||||
'same-origin with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-nocors-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
|
||||
'no-cors with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-manual-nocors-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaqueredirect',
|
||||
request_init: {
|
||||
redirect: 'manual',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because only navigations can be intercepted with
|
||||
// opaqueredirect responses
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, manual redirect, no-cors mode Request redirected to ' +
|
||||
'cors with credentials should fail opaqueredirect interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-cors-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'basic',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
|
||||
'same-origin without credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-cors-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'should-not-get-a-response',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because CORS requests require CORS headers on cross-origin
|
||||
// resources
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
|
||||
'no-cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-cors-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'cors',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
|
||||
'cors without credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-sameorigin-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'basic',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
|
||||
'same-origin without credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-sameorigin-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'should-not-get-a-response',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because same-origin requests cannot load cross-origin
|
||||
// resources
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
|
||||
'no-cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-sameorigin-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'should-not-get-a-response',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because same-origin requests cannot load cross-origin
|
||||
// resources
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
|
||||
'cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-nocors-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'basic',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
|
||||
'same-origin without credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-nocors-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaque',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
|
||||
'no-cors without credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-nocors-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'opaque',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
|
||||
'cors without credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-cors-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'basic',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
|
||||
'same-origin with credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-cors-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'should-not-get-a-response',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because CORS requests require CORS headers on cross-origin
|
||||
// resources
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
|
||||
'no-cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-cors-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'cors',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because CORS requests do not allow user/pass entries in
|
||||
// cross-origin URLs
|
||||
// NOTE: https://github.com/whatwg/fetch/issues/112
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, cors mode Request redirected to ' +
|
||||
'cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-sameorigin-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'basic',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
|
||||
'same-origin with credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-sameorigin-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'should-not-get-a-response',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because same-origin requests cannot load cross-origin
|
||||
// resources
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
|
||||
'no-cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-sameorigin-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'should-not-get-a-response',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because same-origin requests cannot load cross-origin
|
||||
// resources
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, same-origin mode Request redirected to ' +
|
||||
'cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-nocors-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'basic',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
|
||||
'same-origin with credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-nocors-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaque',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
|
||||
'no-cors with credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-follow-nocors-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'opaque',
|
||||
request_init: {
|
||||
redirect: 'follow',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
should_reject: false
|
||||
});
|
||||
}, 'Non-navigation, follow redirect, no-cors mode Request redirected to ' +
|
||||
'cors with credentials should succeed interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-cors-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
|
||||
'same-origin without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-cors-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
|
||||
'no-cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-cors-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
|
||||
'cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-sameorigin-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
|
||||
'same-origin without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-sameorigin-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
|
||||
'no-cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-sameorigin-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
|
||||
'cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-nocors-redirects-to-sameorigin-nocreds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
|
||||
'same-origin without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-nocors-redirects-to-nocors-nocreds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
|
||||
'no-cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-nocors-redirects-to-cors-nocreds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: false,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
|
||||
'cors without credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-cors-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
|
||||
'same-origin with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-cors-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
|
||||
'no-cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-cors-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, cors mode Request redirected to ' +
|
||||
'cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-sameorigin-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
|
||||
'same-origin with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-sameorigin-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
|
||||
'no-cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-sameorigin-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'same-origin'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, same-origin mode Request redirected to ' +
|
||||
'cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-nocors-redirects-to-sameorigin-creds',
|
||||
redirect_dest: 'same-origin',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
|
||||
'same-origin with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-nocors-redirects-to-nocors-creds',
|
||||
redirect_dest: 'no-cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
|
||||
'no-cors with credentials should fail interception');
|
||||
|
||||
async_test(function(t) {
|
||||
redirect_fetch_test(t, {
|
||||
name: 'nonav-error-nocors-redirects-to-cors-creds',
|
||||
redirect_dest: 'cors',
|
||||
url_credentials: true,
|
||||
expected_type: 'error',
|
||||
request_init: {
|
||||
redirect: 'error',
|
||||
mode: 'no-cors'
|
||||
},
|
||||
// should reject because requests with 'error' RequestRedirect cannot be
|
||||
// redirected.
|
||||
should_reject: true
|
||||
});
|
||||
}, 'Non-navigation, error redirect, no-cors mode Request redirected to ' +
|
||||
'cors with credentials should fail interception');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
promise_test(function(t) {
|
||||
var script =
|
||||
'resources/fetch-event-respond-with-stops-propagation-worker.js';
|
||||
var scope = 'resources/simple.html';
|
||||
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(frame) {
|
||||
var channel = new MessageChannel();
|
||||
var saw_message = new Promise(function(resolve) {
|
||||
channel.port1.onmessage = function(e) { resolve(e.data); }
|
||||
});
|
||||
var worker = frame.contentWindow.navigator.serviceWorker.controller;
|
||||
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
frame.remove();
|
||||
return saw_message;
|
||||
})
|
||||
.then(function(message) {
|
||||
assert_equals(message, 'PASS');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
}, 'respondWith() invokes stopImmediatePropagation()');
|
||||
</script>
|
|
@ -0,0 +1,466 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
var worker = 'resources/fetch-event-test-worker.js';
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?string';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'Test string',
|
||||
'Service Worker should respond to fetch with a test string');
|
||||
assert_equals(
|
||||
frame.contentDocument.contentType,
|
||||
'text/plain',
|
||||
'The content type of the response created with a string should be text/plain');
|
||||
assert_equals(
|
||||
frame.contentDocument.characterSet,
|
||||
'UTF-8',
|
||||
'The character set of the response created with a string should be UTF-8');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with string');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?blob';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'Test blob',
|
||||
'Service Worker should respond to fetch with a test string');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with blob body');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?referrer';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'Referrer: ' + document.location.href,
|
||||
'Service Worker should respond to fetch with the referrer URL');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with the referrer URL');
|
||||
|
||||
function run_referrer_policy_tests(frame, referrer, href, origin) {
|
||||
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
||||
{method: "GET", referrer: referrer})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + href + '\n' +
|
||||
'ReferrerPolicy: no-referrer-when-downgrade',
|
||||
'Service Worker should respond to fetch with the referrer URL when a member of RequestInit is present');
|
||||
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
||||
'/resources/simple.html?referrerFull';
|
||||
return frame.contentWindow.fetch(http_url,
|
||||
{method: "GET", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: about:client\n' +
|
||||
'ReferrerPolicy: no-referrer-when-downgrade',
|
||||
'Service Worker should respond to fetch with no referrer when a member of RequestInit is present with an HTTP request');
|
||||
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
||||
{referrerPolicy: "", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + href + '\n' +
|
||||
'ReferrerPolicy: no-referrer-when-downgrade',
|
||||
'Service Worker should respond to fetch with the referrer with ""');
|
||||
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
||||
'/resources/simple.html?referrerFull';
|
||||
return frame.contentWindow.fetch(http_url,
|
||||
{referrerPolicy: "", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: about:client\n' +
|
||||
'ReferrerPolicy: no-referrer-when-downgrade',
|
||||
'Service Worker should respond to fetch with no referrer with ""');
|
||||
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
||||
{referrerPolicy: "origin-only", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + origin + '/' + '\n' +
|
||||
'ReferrerPolicy: origin-only',
|
||||
'Service Worker should respond to fetch with the referrer origin with "origin-only" and a same origin request');
|
||||
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
||||
'/resources/simple.html?referrerFull';
|
||||
return frame.contentWindow.fetch(http_url,
|
||||
{referrerPolicy: "origin-only", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + origin + '/' + '\n' +
|
||||
'ReferrerPolicy: origin-only',
|
||||
'Service Worker should respond to fetch with the referrer origin with "origin-only" and a cross origin request');
|
||||
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
||||
{referrerPolicy: "origin-when-cross-origin", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + href + '\n' +
|
||||
'ReferrerPolicy: origin-when-cross-origin',
|
||||
'Service Worker should respond to fetch with the referrer URL with "origin-when-cross-origin" and a same origin request');
|
||||
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
||||
'/resources/simple.html?referrerFull';
|
||||
return frame.contentWindow.fetch(http_url,
|
||||
{referrerPolicy: "origin-when-cross-origin", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + origin + '/' + '\n' +
|
||||
'ReferrerPolicy: origin-when-cross-origin',
|
||||
'Service Worker should respond to fetch with the referrer origin with "origin-when-cross-origin" and a cross origin request');
|
||||
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
||||
{referrerPolicy: "no-referrer-when-downgrade", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + href + '\n' +
|
||||
'ReferrerPolicy: no-referrer-when-downgrade',
|
||||
'Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and a same origin request');
|
||||
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
||||
'/resources/simple.html?referrerFull';
|
||||
return frame.contentWindow.fetch(http_url,
|
||||
{referrerPolicy: "no-referrer-when-downgrade", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: about:client\n' +
|
||||
'ReferrerPolicy: no-referrer-when-downgrade',
|
||||
'Service Worker should respond to fetch with no referrer with "no-referrer-when-downgrade" and an HTTP request');
|
||||
var http_url = get_host_info()['HTTP_ORIGIN'] + base_path() +
|
||||
'/resources/simple.html?referrerFull';
|
||||
return frame.contentWindow.fetch(http_url, {referrerPolicy: "unsafe-url", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: ' + href + '\n' +
|
||||
'ReferrerPolicy: unsafe-url',
|
||||
'Service Worker should respond to fetch with no referrer with "unsafe-url"');
|
||||
return frame.contentWindow.fetch('resources/simple.html?referrerFull',
|
||||
{referrerPolicy: "no-referrer", referrer: referrer});
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
assert_equals(
|
||||
response_text,
|
||||
'Referrer: about:client\n' +
|
||||
'ReferrerPolicy: no-referrer',
|
||||
'Service Worker should respond to fetch with no referrer URL with "no-referrer"');
|
||||
});
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?referrerPolicy';
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'ReferrerPolicy: no-referrer-when-downgrade',
|
||||
'Service Worker should respond to fetch with the default referrer policy');
|
||||
// First, run the referrer policy tests without passing a referrer in RequestInit.
|
||||
return run_referrer_policy_tests(frame, undefined, frame.contentDocument.location.href,
|
||||
frame.contentDocument.location.origin);
|
||||
})
|
||||
.then(function() {
|
||||
// Now, run the referrer policy tests while passing a referrer in RequestInit.
|
||||
var referrer = get_host_info()['HTTPS_ORIGIN'] + base_path() + 'fake-referrer';
|
||||
return run_referrer_policy_tests(frame, 'fake-referrer', referrer,
|
||||
frame.contentDocument.location.origin);
|
||||
})
|
||||
.then(function() {
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with the referrer URL');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?clientId';
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'Client ID Not Found',
|
||||
'Service Worker should respond to fetch with a client id');
|
||||
return frame.contentWindow.fetch('resources/other.html?clientId');
|
||||
})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
var new_client_id = response_text.substr(17);
|
||||
assert_equals(
|
||||
response_text.substr(0, 15),
|
||||
'Client ID Found',
|
||||
'Service Worker should respond to fetch with an existing client id');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with an existing client id');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?ignore';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(frame.contentDocument.body.textContent,
|
||||
'Here\'s a simple html file.\n',
|
||||
'Response should come from fallback to native fetch');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker does not respond to fetch event');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?null';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(frame.contentDocument.body.textContent,
|
||||
'',
|
||||
'Response should be the empty string');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with null response body');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?fetch';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(frame.contentDocument.body.textContent,
|
||||
'Here\'s an other html file.\n',
|
||||
'Response should come from fetched other file');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker fetches other file in fetch event');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?form-post';
|
||||
var frame_name = 'xhr-post-frame';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function(sw) {
|
||||
return new Promise(function(resolve) {
|
||||
var frame = document.createElement('iframe');
|
||||
frame.name = frame_name;
|
||||
document.body.appendChild(frame);
|
||||
var form = document.createElement('form');
|
||||
form.target = frame_name;
|
||||
form.action = scope;
|
||||
form.method = 'post';
|
||||
var input1 = document.createElement('input');
|
||||
input1.type = 'text';
|
||||
input1.value = 'testValue1';
|
||||
input1.name = 'testName1'
|
||||
form.appendChild(input1);
|
||||
var input2 = document.createElement('input');
|
||||
input2.type = 'text';
|
||||
input2.value = 'testValue2';
|
||||
input2.name = 'testName2'
|
||||
form.appendChild(input2);
|
||||
document.body.appendChild(form);
|
||||
frame.onload = function() {
|
||||
document.body.removeChild(form);
|
||||
resolve(frame);
|
||||
};
|
||||
form.submit();
|
||||
});
|
||||
})
|
||||
.then(function(frame) {
|
||||
assert_equals(frame.contentDocument.body.textContent,
|
||||
'POST:application/x-www-form-urlencoded:' +
|
||||
'testName1=testValue1&testName2=testValue2');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with POST form');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?multiple-respond-with';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'(0)(1)[InvalidStateError](2)[InvalidStateError]',
|
||||
'Multiple calls of respondWith must throw InvalidStateErrors.');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Multiple calls of respondWith must throw InvalidStateErrors');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?used-check';
|
||||
var first_frame;
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(frame) {
|
||||
assert_equals(frame.contentDocument.body.textContent,
|
||||
'Here\'s an other html file.\n',
|
||||
'Response should come from fetched other file');
|
||||
first_frame = frame;
|
||||
return with_iframe(scope);
|
||||
})
|
||||
.then(function(frame) {
|
||||
// When we access to the scope in the second time, the content of the
|
||||
// response is generated inside the ServiceWorker. The body contains
|
||||
// the value of bodyUsed of the first response which is already
|
||||
// consumed by FetchEvent.respondWith method.
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'bodyUsed: true',
|
||||
'event.respondWith must set the used flag.');
|
||||
first_frame.remove();
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker event.respondWith must set the used flag');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?fragment-check';
|
||||
var fragment = '#/some/fragment';
|
||||
var first_frame;
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope + fragment); })
|
||||
.then(function(frame) {
|
||||
assert_equals(
|
||||
frame.contentDocument.body.textContent,
|
||||
'Fragment Not Found',
|
||||
'Service worker should not expose URL fragments.');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker must not expose FetchEvent URL fragments.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/simple.html?cache';
|
||||
var frame;
|
||||
var cacheTypes = [
|
||||
undefined, 'default', 'no-store', 'reload', 'no-cache', 'force-cache'
|
||||
];
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(scope); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
var tests = cacheTypes.map(function(type) {
|
||||
return new Promise(function(resolve) {
|
||||
return frame.contentWindow.fetch(scope + '=' + type,
|
||||
{cache: type})
|
||||
.then(function(response) { return response.text(); })
|
||||
.then(function(response_text) {
|
||||
var expected = (type === undefined) ? 'default' : type;
|
||||
assert_equals(response_text, expected,
|
||||
'Service Worker should respond to fetch with the correct type');
|
||||
})
|
||||
.then(resolve);
|
||||
});
|
||||
});
|
||||
return Promise.all(tests);
|
||||
})
|
||||
.then(function() {
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Service Worker responds to fetch event with the correct cache types');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,221 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Fetch for the frame loading.</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
var worker = 'resources/fetch-rewrite-worker.js';
|
||||
var path = base_path() + 'resources/fetch-access-control.py';
|
||||
var host_info = get_host_info();
|
||||
|
||||
if (window.testRunner) {
|
||||
testRunner.setCanOpenWindows();
|
||||
}
|
||||
|
||||
function getLoadedObject(win, contentFunc, closeFunc) {
|
||||
return new Promise(function(resolve) {
|
||||
function done(contentString) {
|
||||
var result = null;
|
||||
// fetch-access-control.py returns a string like "report( <json> )".
|
||||
// Eval the returned string with a report functionto get the json
|
||||
// object.
|
||||
try {
|
||||
function report(obj) { result = obj };
|
||||
eval(contentString);
|
||||
} catch(e) {
|
||||
// just resolve null if we get unexpected page content
|
||||
}
|
||||
closeFunc(win);
|
||||
resolve(result);
|
||||
}
|
||||
|
||||
// We can't catch the network error on window. So we use the timer.
|
||||
var timeout = setTimeout(function() {
|
||||
// Failure pages are considered cross-origin in some browsers. This
|
||||
// means you cannot even .resolve() the window because the check for
|
||||
// the .then property will throw. Instead, treat cross-origin
|
||||
// failure pages as the empty string which will fail to parse as the
|
||||
// expected json result.
|
||||
var content = '';
|
||||
try {
|
||||
content = contentFunc(win);
|
||||
} catch(e) {
|
||||
// use default empty string for cross-domain window
|
||||
}
|
||||
done(content);
|
||||
}, 10000);
|
||||
|
||||
win.onload = function() {
|
||||
clearTimeout(timeout);
|
||||
var content = contentFunc(win);
|
||||
done(content);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getLoadedFrameAsObject(frame) {
|
||||
return getLoadedObject(frame, function(f) {
|
||||
return f.contentDocument.body.textContent;
|
||||
}, function(f) {
|
||||
f.parentNode.removeChild(f);
|
||||
});
|
||||
}
|
||||
|
||||
function getLoadedWindowAsObject(win) {
|
||||
return getLoadedObject(win, function(w) {
|
||||
return w.document.body.textContent
|
||||
}, function(w) {
|
||||
w.close();
|
||||
});
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/fetch-frame-resource/frame-basic';
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
frame = document.createElement('iframe');
|
||||
frame.src =
|
||||
scope + '?url=' +
|
||||
encodeURIComponent(host_info['HTTPS_ORIGIN'] + path);
|
||||
document.body.appendChild(frame);
|
||||
return getLoadedFrameAsObject(frame);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result.jsonpResult,
|
||||
'success',
|
||||
'Basic type response could be loaded in the iframe.');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Basic type response could be loaded in the iframe.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/fetch-frame-resource/frame-cors';
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
frame = document.createElement('iframe');
|
||||
frame.src =
|
||||
scope + '?mode=cors&url=' +
|
||||
encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path +
|
||||
'?ACAOrigin=' + host_info['HTTPS_ORIGIN']);
|
||||
document.body.appendChild(frame);
|
||||
return getLoadedFrameAsObject(frame);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result.jsonpResult,
|
||||
'success',
|
||||
'CORS type response could be loaded in the iframe.');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'CORS type response could be loaded in the iframe.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/fetch-frame-resource/frame-opaque';
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
frame = document.createElement('iframe');
|
||||
frame.src =
|
||||
scope + '?mode=no-cors&url=' +
|
||||
encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path);
|
||||
document.body.appendChild(frame);
|
||||
return getLoadedFrameAsObject(frame);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result,
|
||||
null,
|
||||
'Opaque type response could not be loaded in the iframe.');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Opaque type response could not be loaded in the iframe.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/fetch-frame-resource/window-basic';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var win = window.open(
|
||||
scope + '?url=' +
|
||||
encodeURIComponent(host_info['HTTPS_ORIGIN'] + path));
|
||||
return getLoadedWindowAsObject(win);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result.jsonpResult,
|
||||
'success',
|
||||
'Basic type response could be loaded in the new window.');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Basic type response could be loaded in the new window.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/fetch-frame-resource/window-cors';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var win = window.open(
|
||||
scope + '?mode=cors&url=' +
|
||||
encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path +
|
||||
'?ACAOrigin=' + host_info['HTTPS_ORIGIN']));
|
||||
return getLoadedWindowAsObject(win);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result.jsonpResult,
|
||||
'success',
|
||||
'CORS type response could be loaded in the new window.');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'CORS type response could be loaded in the new window.');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/fetch-frame-resource/window-opaque';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
var win = window.open(
|
||||
scope + '?mode=no-cors&url=' +
|
||||
encodeURIComponent(host_info['HTTPS_REMOTE_ORIGIN'] + path));
|
||||
return getLoadedWindowAsObject(win);
|
||||
})
|
||||
.then(function(result) {
|
||||
assert_equals(
|
||||
result,
|
||||
null,
|
||||
'Opaque type response could not be loaded in the new window.');
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Opaque type response could not be loaded in the new window.');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,52 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Visibility of headers during fetch.</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
var worker = 'resources/fetch-rewrite-worker.js';
|
||||
var path = base_path() + 'resources/fetch-access-control.py';
|
||||
var host_info = get_host_info();
|
||||
var frame;
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/fetch-header-visibility-iframe.html';
|
||||
service_worker_unregister_and_register(t, worker, scope)
|
||||
.then(function(reg) {
|
||||
return wait_for_state(t, reg.installing, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
frame = document.createElement('iframe');
|
||||
frame.src = scope;
|
||||
document.body.appendChild(frame);
|
||||
|
||||
// Resolve a promise when we recieve 2 success messages
|
||||
return new Promise(function(resolve, reject) {
|
||||
var remaining = 4;
|
||||
function onMessage(e) {
|
||||
if (e.data == 'PASS') {
|
||||
remaining--;
|
||||
if (remaining == 0) {
|
||||
resolve();
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
reject(e.data);
|
||||
}
|
||||
|
||||
window.removeEventListener('message', onMessage);
|
||||
}
|
||||
window.addEventListener('message', onMessage);
|
||||
});
|
||||
})
|
||||
.then(function(result) {
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Visibility of defaulted headers during interception');
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Mixed content of fetch()</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<body></body>
|
||||
<script>
|
||||
if (window.testRunner) {
|
||||
// In Chromium we need to change the setting to disallow displaying insecure
|
||||
// contents.
|
||||
testRunner.overridePreference('WebKitAllowDisplayingInsecureContent', false);
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var host_info = get_host_info();
|
||||
window.addEventListener('message', t.step_func(on_message), false);
|
||||
with_iframe(
|
||||
host_info['HTTPS_ORIGIN'] + base_path() +
|
||||
'resources/fetch-mixed-content-iframe.html?target=inscope');
|
||||
function on_message(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
t.done();
|
||||
}
|
||||
}, 'Verify Mixed content of fetch() in a Service Worker');
|
||||
</script>
|
|
@ -0,0 +1,27 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Mixed content of fetch()</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<body></body>
|
||||
<script>
|
||||
if (window.testRunner) {
|
||||
// In Chromium we need to change the setting to disallow displaying insecure
|
||||
// contents.
|
||||
testRunner.overridePreference('WebKitAllowDisplayingInsecureContent', false);
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var host_info = get_host_info();
|
||||
window.addEventListener('message', t.step_func(on_message), false);
|
||||
with_iframe(
|
||||
host_info['HTTPS_ORIGIN'] + base_path() +
|
||||
'resources/fetch-mixed-content-iframe.html?target=outscope');
|
||||
function on_message(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
t.done();
|
||||
}
|
||||
}, 'Verify Mixed content of fetch() in a Service Worker');
|
||||
</script>
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: CSS's base URL must be the request URL even when fetched from other URL</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-request-css-base-url-iframe.html';
|
||||
var SCRIPT = 'resources/fetch-request-css-base-url-worker.js';
|
||||
var worker;
|
||||
var testDonePromise;
|
||||
|
||||
return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return new Promise(function(resolve) {
|
||||
var channel = new MessageChannel();
|
||||
testDonePromise = new Promise(function(resolveTestDone) {
|
||||
channel.port1.onmessage = t.step_func(function(msg) {
|
||||
if (msg.data.ready) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
var result = msg.data;
|
||||
var base = get_host_info()['HTTPS_ORIGIN'] + base_path();
|
||||
assert_equals(
|
||||
result.url,
|
||||
base + 'resources/dummy.png',
|
||||
'The base URL while loading the images referred from CSS ' +
|
||||
'must be the request URL of CSS.');
|
||||
assert_equals(
|
||||
result.referrer,
|
||||
base + 'resources/fetch-request-css-base-url-style.css',
|
||||
'While loading the image defined in CSS the referrer must ' +
|
||||
'be the request URL of CSS.');
|
||||
resolveTestDone();
|
||||
});
|
||||
});
|
||||
worker.postMessage(
|
||||
{port: channel.port2}, [channel.port2]);
|
||||
});
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(f) {
|
||||
return testDonePromise.then(function() {
|
||||
f.remove();
|
||||
return service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'CSS\'s base URL must be the request URL even when fetched from other URL.');
|
||||
</script>
|
|
@ -0,0 +1,99 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: FetchEvent for css image</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
var url_count = 0;
|
||||
var expected_results = {};
|
||||
|
||||
function css_image_test(frame, url, type, expexted_mode,
|
||||
expected_credentials) {
|
||||
var actual_url = url + (++url_count);
|
||||
expected_results[actual_url] = {
|
||||
url: actual_url,
|
||||
mode: expexted_mode,
|
||||
credentials: expected_credentials,
|
||||
message: 'CSSImage load (url:' + actual_url + ' type:' + type + ')'
|
||||
};
|
||||
return frame.contentWindow.load_css_image(actual_url, type);
|
||||
}
|
||||
|
||||
function css_image_set_test(frame, url, type, expexted_mode,
|
||||
expected_credentials) {
|
||||
var actual_url = url + (++url_count);
|
||||
expected_results[actual_url] = {
|
||||
url: actual_url,
|
||||
mode: expexted_mode,
|
||||
credentials: expected_credentials,
|
||||
message: 'CSSImageSet load (url:' + actual_url + ' type:' + type + ')'
|
||||
};
|
||||
return frame.contentWindow.load_css_image_set(actual_url, type);
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-request-resources-iframe.https.html';
|
||||
var SCRIPT = 'resources/fetch-request-resources-worker.js';
|
||||
var host_info = get_host_info();
|
||||
var LOCAL_URL =
|
||||
host_info['HTTPS_ORIGIN'] + base_path() + 'resources/dummy?test';
|
||||
var REMOTE_URL =
|
||||
host_info['HTTPS_REMOTE_ORIGIN'] + base_path() + 'resources/dummy?test';
|
||||
var worker;
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return new Promise(function(resolve) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(msg) {
|
||||
if (msg.data.ready) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
var result = msg.data;
|
||||
var expected = expected_results[result.url];
|
||||
if (!expected) {
|
||||
return;
|
||||
}
|
||||
assert_equals(
|
||||
result.mode, expected.mode,
|
||||
'mode of ' + expected.message + ' must be ' +
|
||||
expected.mode + '.');
|
||||
assert_equals(
|
||||
result.credentials, expected.credentials,
|
||||
'credentials of ' + expected.message + ' must be ' +
|
||||
expected.credentials + '.');
|
||||
--url_count;
|
||||
delete expected_results[result.url];
|
||||
if (url_count == 0) {
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
}
|
||||
});
|
||||
worker.postMessage(
|
||||
{port: channel.port2}, [channel.port2]);
|
||||
});
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
|
||||
css_image_test(f, LOCAL_URL, 'backgroundImage', 'no-cors', 'include');
|
||||
css_image_test(f, REMOTE_URL, 'backgroundImage', 'no-cors', 'include');
|
||||
|
||||
css_image_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'same-origin');
|
||||
css_image_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'same-origin');
|
||||
|
||||
css_image_set_test(f, LOCAL_URL, 'backgroundImage', 'no-cors', 'include');
|
||||
css_image_set_test(f, REMOTE_URL, 'backgroundImage', 'no-cors', 'include');
|
||||
css_image_set_test(f, LOCAL_URL, 'shapeOutside', 'cors', 'same-origin');
|
||||
css_image_set_test(f, REMOTE_URL, 'shapeOutside', 'cors', 'same-origin');
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify FetchEvent for css images.');
|
||||
</script>
|
|
@ -0,0 +1,113 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: the fallback behavior of FetchEvent</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
var expected_urls = [];
|
||||
|
||||
function xhr_fail_test(frame, url) {
|
||||
expected_urls.push(url);
|
||||
return new Promise(function(resolve, reject) {
|
||||
frame.contentWindow.xhr(url)
|
||||
.then(function(){
|
||||
reject(url + ' should fail.');
|
||||
})
|
||||
.catch(function(){
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function xhr_succeed_test(frame, url) {
|
||||
expected_urls.push(url);
|
||||
return new Promise(function(resolve, reject) {
|
||||
frame.contentWindow.xhr(url)
|
||||
.then(function(){
|
||||
resolve();
|
||||
})
|
||||
.catch(function(){
|
||||
reject(url + ' should succeed.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var path = new URL(".", window.location).pathname;
|
||||
var SCOPE = 'resources/fetch-request-fallback-iframe.html';
|
||||
var SCRIPT = 'resources/fetch-request-fallback-worker.js';
|
||||
var host_info = get_host_info();
|
||||
var BASE_URL = host_info['HTTPS_ORIGIN'] +
|
||||
path + 'resources/fetch-access-control.py?';
|
||||
var OTHER_BASE_URL = host_info['HTTPS_REMOTE_ORIGIN'] +
|
||||
path + 'resources/fetch-access-control.py?';
|
||||
var REDIRECT_URL = host_info['HTTPS_ORIGIN'] +
|
||||
path + 'resources/redirect.py?Redirect=';
|
||||
var frame;
|
||||
var worker;
|
||||
service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return xhr_succeed_test(frame, BASE_URL);
|
||||
})
|
||||
.then(function(f) {
|
||||
return xhr_fail_test(frame, OTHER_BASE_URL);
|
||||
})
|
||||
.then(function(f) {
|
||||
return xhr_succeed_test(frame, OTHER_BASE_URL + 'ACAOrigin=*');
|
||||
})
|
||||
.then(function(f) {
|
||||
return xhr_succeed_test(frame,
|
||||
REDIRECT_URL + encodeURIComponent(BASE_URL));
|
||||
})
|
||||
.then(function() {
|
||||
return xhr_fail_test(
|
||||
frame,
|
||||
REDIRECT_URL + encodeURIComponent(OTHER_BASE_URL));
|
||||
})
|
||||
.then(function() {
|
||||
return xhr_succeed_test(
|
||||
frame,
|
||||
REDIRECT_URL +
|
||||
encodeURIComponent(OTHER_BASE_URL + 'ACAOrigin=*'));
|
||||
})
|
||||
.then(function() {
|
||||
return new Promise(function(resolve) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(msg) {
|
||||
frame.remove();
|
||||
resolve(msg);
|
||||
});
|
||||
worker.postMessage({port: channel.port2}, [channel.port2]);
|
||||
});
|
||||
})
|
||||
.then(function(msg) {
|
||||
var requests = msg.data.requests;
|
||||
assert_equals(requests.length, expected_urls.length + 1,
|
||||
'The count of the requests which are passed to the ' +
|
||||
'ServiceWorker must be correct.');
|
||||
assert_equals(requests[0].url, new URL(SCOPE, location).toString(),
|
||||
'The first request to the SW must be the request for ' +
|
||||
'the page.');
|
||||
assert_equals(requests[0].mode, 'navigate',
|
||||
'The mode of the first request to the SW must be ' +
|
||||
'navigate');
|
||||
for (var i = 0; i < expected_urls.length; ++i) {
|
||||
assert_equals(requests[i + 1].url, expected_urls[i],
|
||||
'The URL of the request which was passed from XHR ' +
|
||||
'to the ServiceWorker must be correct.');
|
||||
assert_equals(requests[i + 1].mode, 'cors',
|
||||
'The mode of the request which was passed from XHR ' +
|
||||
'to the ServiceWorker must be cors.');
|
||||
}
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify the fallback behavior of FetchEvent');
|
||||
</script>
|
|
@ -0,0 +1,53 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: the headers of FetchEvent shouldn't contain freshness headers</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-request-no-freshness-headers-iframe.html';
|
||||
var SCRIPT = 'resources/fetch-request-no-freshness-headers-worker.js';
|
||||
var worker;
|
||||
service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
return new Promise(function(resolve) {
|
||||
frame.onload = function() {
|
||||
resolve(frame);
|
||||
};
|
||||
frame.contentWindow.location.reload();
|
||||
});
|
||||
})
|
||||
.then(function(frame) {
|
||||
return new Promise(function(resolve) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(msg) {
|
||||
frame.remove();
|
||||
resolve(msg);
|
||||
});
|
||||
worker.postMessage(
|
||||
{port: channel.port2}, [channel.port2]);
|
||||
});
|
||||
})
|
||||
.then(function(msg) {
|
||||
var freshness_headers = {
|
||||
'if-none-match': true,
|
||||
'if-modified-since': true
|
||||
};
|
||||
msg.data.requests.forEach(t.step_func(function(request) {
|
||||
request.headers.forEach(t.step_func(function(header) {
|
||||
assert_false(
|
||||
!!freshness_headers[header[0]],
|
||||
header[0] + ' header must not be set in the ' +
|
||||
'FetchEvent\'s request. (url = ' + request.url + ')');
|
||||
}));
|
||||
}))
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'The headers of FetchEvent shouldn\'t contain freshness headers.');
|
||||
</script>
|
|
@ -0,0 +1,176 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: FetchEvent for resources</title>
|
||||
<meta name="timeout" content="long">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
|
||||
function assert_resolves(promise, description) {
|
||||
return promise.catch(function(reason) {
|
||||
throw new Error(description + ' - ' + reason.message);
|
||||
});
|
||||
}
|
||||
|
||||
function assert_rejects(promise, description) {
|
||||
return promise.then(
|
||||
function() { throw new Error(description); },
|
||||
function() {});
|
||||
}
|
||||
|
||||
function iframe_test(url, timeout_enabled) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var frame = document.createElement('iframe');
|
||||
frame.src = url;
|
||||
if (timeout_enabled) {
|
||||
// We can't catch the network error on iframe. So we use the timer for
|
||||
// failure detection.
|
||||
var timer = setTimeout(function() {
|
||||
reject(new Error('iframe load timeout'));
|
||||
frame.remove();
|
||||
}, 10000);
|
||||
}
|
||||
frame.onload = function() {
|
||||
if (timeout_enabled)
|
||||
clearTimeout(timer);
|
||||
if (frame.contentDocument.body.textContent == 'Hello world\n')
|
||||
resolve();
|
||||
else
|
||||
reject(new Error('content mismatch'));
|
||||
frame.remove();
|
||||
};
|
||||
document.body.appendChild(frame);
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-request-redirect-iframe.html';
|
||||
var SCRIPT = 'resources/fetch-rewrite-worker.js';
|
||||
var REDIRECT_URL = base_path() + 'resources/redirect.py?Redirect=';
|
||||
var IMAGE_URL = base_path() + 'resources/square.png';
|
||||
var AUDIO_URL = base_path() + 'resources/silence.oga';
|
||||
var XHR_URL = base_path() + 'resources/simple.txt';
|
||||
var HTML_URL = base_path() + 'resources/dummy.html';
|
||||
|
||||
var REDIRECT_TO_IMAGE_URL = REDIRECT_URL + encodeURIComponent(IMAGE_URL);
|
||||
var REDIRECT_TO_AUDIO_URL = REDIRECT_URL + encodeURIComponent(AUDIO_URL);
|
||||
var REDIRECT_TO_XHR_URL = REDIRECT_URL + encodeURIComponent(XHR_URL);
|
||||
var REDIRECT_TO_HTML_URL = REDIRECT_URL + encodeURIComponent(HTML_URL);
|
||||
|
||||
var worker;
|
||||
var frame;
|
||||
return service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return Promise.all([
|
||||
// XMLHttpRequest tests.
|
||||
assert_resolves(frame.contentWindow.xhr(XHR_URL),
|
||||
'Normal XHR should succeed.'),
|
||||
assert_resolves(frame.contentWindow.xhr(REDIRECT_TO_XHR_URL),
|
||||
'Redirected XHR should succeed.'),
|
||||
assert_resolves(
|
||||
frame.contentWindow.xhr(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_XHR_URL) +
|
||||
'&redirect-mode=follow'),
|
||||
'Redirected XHR with Request.redirect=follow should succeed.'),
|
||||
assert_rejects(
|
||||
frame.contentWindow.xhr(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_XHR_URL) +
|
||||
'&redirect-mode=error'),
|
||||
'Redirected XHR with Request.redirect=error should fail.'),
|
||||
assert_rejects(
|
||||
frame.contentWindow.xhr(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_XHR_URL) +
|
||||
'&redirect-mode=manual'),
|
||||
'Redirected XHR with Request.redirect=manual should fail.'),
|
||||
|
||||
// Image loading tests.
|
||||
assert_resolves(frame.contentWindow.load_image(IMAGE_URL),
|
||||
'Normal image resource should be loaded.'),
|
||||
assert_resolves(
|
||||
frame.contentWindow.load_image(REDIRECT_TO_IMAGE_URL),
|
||||
'Redirected image resource should be loaded.'),
|
||||
assert_resolves(
|
||||
frame.contentWindow.load_image(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_IMAGE_URL) +
|
||||
'&redirect-mode=follow'),
|
||||
'Loading redirected image with Request.redirect=follow should' +
|
||||
' succeed.'),
|
||||
assert_rejects(
|
||||
frame.contentWindow.load_image(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_IMAGE_URL) +
|
||||
'&redirect-mode=error'),
|
||||
'Loading redirected image with Request.redirect=error should ' +
|
||||
'fail.'),
|
||||
assert_rejects(
|
||||
frame.contentWindow.load_image(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_IMAGE_URL) +
|
||||
'&redirect-mode=manual'),
|
||||
'Loading redirected image with Request.redirect=manual should' +
|
||||
' fail.'),
|
||||
|
||||
// Audio loading tests.
|
||||
assert_resolves(frame.contentWindow.load_audio(AUDIO_URL),
|
||||
'Normal audio resource should be loaded.'),
|
||||
assert_resolves(
|
||||
frame.contentWindow.load_audio(REDIRECT_TO_AUDIO_URL),
|
||||
'Redirected audio resource should be loaded.'),
|
||||
assert_resolves(
|
||||
frame.contentWindow.load_audio(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_AUDIO_URL) +
|
||||
'&redirect-mode=follow'),
|
||||
'Loading redirected audio with Request.redirect=follow should' +
|
||||
' succeed.'),
|
||||
assert_rejects(
|
||||
frame.contentWindow.load_audio(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_AUDIO_URL) +
|
||||
'&redirect-mode=error'),
|
||||
'Loading redirected audio with Request.redirect=error should ' +
|
||||
'fail.'),
|
||||
assert_rejects(
|
||||
frame.contentWindow.load_audio(
|
||||
'./?url=' + encodeURIComponent(REDIRECT_TO_AUDIO_URL) +
|
||||
'&redirect-mode=manual'),
|
||||
'Loading redirected audio with Request.redirect=manual should' +
|
||||
' fail.'),
|
||||
|
||||
// Iframe tests.
|
||||
assert_resolves(iframe_test(HTML_URL),
|
||||
'Normal iframe loading should succeed.'),
|
||||
assert_resolves(
|
||||
iframe_test(REDIRECT_TO_HTML_URL),
|
||||
'Normal redirected iframe loading should succeed.'),
|
||||
assert_resolves(
|
||||
iframe_test(SCOPE + '?url=' +
|
||||
encodeURIComponent(REDIRECT_TO_HTML_URL) +
|
||||
'&redirect-mode=follow'),
|
||||
'Redirected iframe loading with Request.redirect=follow should'+
|
||||
' succeed.'),
|
||||
assert_rejects(
|
||||
iframe_test(SCOPE + '?url=' +
|
||||
encodeURIComponent(REDIRECT_TO_HTML_URL) +
|
||||
'&redirect-mode=error',
|
||||
true /* timeout_enabled */),
|
||||
'Redirected iframe loading with Request.redirect=error should '+
|
||||
'fail.'),
|
||||
assert_resolves(
|
||||
iframe_test(SCOPE + '?url=' +
|
||||
encodeURIComponent(REDIRECT_TO_HTML_URL) +
|
||||
'&redirect-mode=manual',
|
||||
true /* timeout_enabled */),
|
||||
'Redirected iframe loading with Request.redirect=manual should'+
|
||||
' succeed.'),
|
||||
]);
|
||||
})
|
||||
.then(function() {
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
}, 'Verify redirect mode of Fetch API and ServiceWorker FetchEvent.');
|
||||
</script>
|
|
@ -0,0 +1,142 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: FetchEvent for resources</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
var url_count = 0;
|
||||
var expected_results = {};
|
||||
|
||||
function image_test(frame, url, cross_origin, expexted_mode,
|
||||
expected_credentials) {
|
||||
var actual_url = url + (++url_count);
|
||||
expected_results[actual_url] = {
|
||||
cross_origin: cross_origin,
|
||||
mode: expexted_mode,
|
||||
credentials: expected_credentials,
|
||||
message: 'Image load (url:' +
|
||||
actual_url + ' cross_origin:' + cross_origin + ')'
|
||||
};
|
||||
return frame.contentWindow.load_image(actual_url, cross_origin);
|
||||
}
|
||||
|
||||
function script_test(frame, url, cross_origin, expexted_mode,
|
||||
expected_credentials) {
|
||||
var actual_url = url + (++url_count);
|
||||
expected_results[actual_url] = {
|
||||
cross_origin: cross_origin,
|
||||
mode: expexted_mode,
|
||||
credentials: expected_credentials,
|
||||
message: 'Script load (url:' +
|
||||
actual_url + ' cross_origin:' + cross_origin + ')'
|
||||
};
|
||||
return frame.contentWindow.load_script(actual_url, cross_origin);
|
||||
}
|
||||
|
||||
function css_test(frame, url, cross_origin, expexted_mode,
|
||||
expected_credentials) {
|
||||
var actual_url = url + (++url_count);
|
||||
expected_results[actual_url] = {
|
||||
cross_origin: cross_origin,
|
||||
mode: expexted_mode,
|
||||
credentials: expected_credentials,
|
||||
message: 'CSS load (url:' +
|
||||
actual_url + ' cross_origin:' + cross_origin + ')'
|
||||
};
|
||||
return frame.contentWindow.load_css(actual_url, cross_origin);
|
||||
}
|
||||
|
||||
function font_face_test(frame, url, expexted_mode, expected_credentials) {
|
||||
var actual_url = url + (++url_count);
|
||||
expected_results[actual_url] = {
|
||||
url: actual_url,
|
||||
mode: expexted_mode,
|
||||
credentials: expected_credentials,
|
||||
message: 'FontFace load (url:' + actual_url + ')'
|
||||
};
|
||||
return frame.contentWindow.load_font(actual_url);
|
||||
}
|
||||
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-request-resources-iframe.https.html';
|
||||
var SCRIPT = 'resources/fetch-request-resources-worker.js';
|
||||
var host_info = get_host_info();
|
||||
var LOCAL_URL =
|
||||
host_info['HTTPS_ORIGIN'] + base_path() + 'resources/dummy?test';
|
||||
var REMOTE_URL =
|
||||
host_info['HTTPS_REMOTE_ORIGIN'] + base_path() + 'resources/dummy?test';
|
||||
var worker;
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
worker = registration.installing;
|
||||
return wait_for_state(t, worker, 'activated');
|
||||
})
|
||||
.then(function() {
|
||||
return new Promise(function(resolve) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(msg) {
|
||||
if (msg.data.ready) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
var result = msg.data;
|
||||
var expected = expected_results[result.url];
|
||||
if (!expected) {
|
||||
return;
|
||||
}
|
||||
assert_equals(
|
||||
result.mode, expected.mode,
|
||||
'mode of ' + expected.message + ' must be ' +
|
||||
expected.mode + '.');
|
||||
assert_equals(
|
||||
result.credentials, expected.credentials,
|
||||
'credentials of ' + expected.message + ' must be ' +
|
||||
expected.credentials + '.');
|
||||
--url_count;
|
||||
delete expected_results[result.url];
|
||||
if (url_count == 0) {
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
}
|
||||
});
|
||||
worker.postMessage(
|
||||
{port: channel.port2}, [channel.port2]);
|
||||
});
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
|
||||
// TODO: Disable 'no-cors' tests for image until
|
||||
// AsyncOpen2 and cookie policy is supported.
|
||||
// image_test(f, LOCAL_URL, '', 'no-cors', 'include');
|
||||
// image_test(f, REMOTE_URL, '', 'no-cors', 'include');
|
||||
css_test(f, LOCAL_URL, '', 'no-cors', 'include');
|
||||
css_test(f, REMOTE_URL, '', 'no-cors', 'include');
|
||||
|
||||
image_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
|
||||
image_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
|
||||
image_test(f, REMOTE_URL, 'anonymous', 'cors', 'omit');
|
||||
image_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
|
||||
|
||||
script_test(f, LOCAL_URL, '', 'no-cors', 'include');
|
||||
script_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
|
||||
script_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
|
||||
script_test(f, REMOTE_URL, '', 'no-cors', 'include');
|
||||
script_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
|
||||
script_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
|
||||
|
||||
css_test(f, LOCAL_URL, 'anonymous', 'cors', 'same-origin');
|
||||
css_test(f, LOCAL_URL, 'use-credentials', 'cors', 'include');
|
||||
css_test(f, REMOTE_URL, 'anonymous', 'cors', 'same-origin');
|
||||
css_test(f, REMOTE_URL, 'use-credentials', 'cors', 'include');
|
||||
|
||||
font_face_test(f, LOCAL_URL, 'cors', 'same-origin');
|
||||
font_face_test(f, REMOTE_URL, 'cors', 'same-origin');
|
||||
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify FetchEvent for resources.');
|
||||
</script>
|
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: the body of FetchEvent using XMLHttpRequest</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-request-xhr-iframe.https.html';
|
||||
var SCRIPT = 'resources/fetch-request-xhr-worker.js';
|
||||
var host_info = get_host_info();
|
||||
service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
if (e.data.results === 'finish') {
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
} else if (e.data.results == 'equals') {
|
||||
assert_equals(e.data.got, e.data.expected);
|
||||
}
|
||||
});
|
||||
frame.contentWindow.postMessage({},
|
||||
host_info['HTTPS_ORIGIN'],
|
||||
[channel.port2]);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify the body of FetchEvent using XMLHttpRequest');
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: the response of FetchEvent using XMLHttpRequest</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js?pipe=sub"></script>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var SCOPE = 'resources/fetch-response-xhr-iframe.https.html';
|
||||
var SCRIPT = 'resources/fetch-response-xhr-worker.js';
|
||||
var host_info = get_host_info();
|
||||
|
||||
window.addEventListener('message', t.step_func(on_message), false);
|
||||
function on_message(e) {
|
||||
assert_equals(e.data.results, 'foo, bar');
|
||||
t.done();
|
||||
}
|
||||
|
||||
service_worker_unregister_and_register(t, SCRIPT, SCOPE)
|
||||
.then(function(registration) {
|
||||
return wait_for_state(t, registration.installing, 'activated');
|
||||
})
|
||||
.then(function() { return with_iframe(SCOPE); })
|
||||
.then(function(frame) {
|
||||
var channel = new MessageChannel();
|
||||
channel.port1.onmessage = t.step_func(function(e) {
|
||||
assert_equals(e.data.results, 'finish');
|
||||
frame.remove();
|
||||
service_worker_unregister_and_done(t, SCOPE);
|
||||
});
|
||||
frame.contentWindow.postMessage({},
|
||||
host_info['HTTPS_ORIGIN'],
|
||||
[channel.port2]);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Verify the response of FetchEvent using XMLHttpRequest');
|
||||
</script>
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Fetch Event Waits for Activate Event</title>
|
||||
<meta name=timeout content=long>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
|
||||
var worker = 'resources/fetch-waits-for-activate-worker.js';
|
||||
var expected_url = normalizeURL(worker);
|
||||
var scope = 'resources/fetch-waits-for-activate/';
|
||||
|
||||
async_test(function(t) {
|
||||
var registration;
|
||||
var frameLoadPromise;
|
||||
var frame;
|
||||
service_worker_unregister_and_register(t, worker, scope).then(function(reg) {
|
||||
registration = reg;
|
||||
return wait_for_state(t, reg.installing, 'activating');
|
||||
}).then(function() {
|
||||
assert_equals(registration.active.scriptURL, expected_url,
|
||||
'active worker should be present');
|
||||
assert_equals(registration.active.state, 'activating',
|
||||
'active worker should be in activating state');
|
||||
|
||||
// This should block until we message the worker to tell it to complete
|
||||
// the activate event.
|
||||
frameLoadPromise = with_iframe(scope).then(function(f) {
|
||||
frame = f;
|
||||
});
|
||||
|
||||
// Wait some time to allow frame loading to proceed. It should not,
|
||||
// however, if the fetch event is blocked on the activate. I don't
|
||||
// see any way to force this race without a timeout, unfortunately.
|
||||
return new Promise(function(resolve) {
|
||||
setTimeout(resolve, 1000);
|
||||
});
|
||||
}).then(function() {
|
||||
assert_equals(frame, undefined, 'frame should not be loaded');
|
||||
assert_equals(registration.active.scriptURL, expected_url,
|
||||
'active worker should be present');
|
||||
assert_equals(registration.active.state, 'activating',
|
||||
'active worker should be in activating state');
|
||||
|
||||
// This signals the activate event to complete. The frame should now
|
||||
// load.
|
||||
registration.active.postMessage('GO');
|
||||
return frameLoadPromise;
|
||||
}).then(function() {
|
||||
assert_equals(frame.contentWindow.navigator.serviceWorker.controller.scriptURL,
|
||||
expected_url, 'frame should now be loaded and controlled');
|
||||
assert_equals(registration.active.state, 'activated',
|
||||
'active worker should be in activated state');
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
}).catch(unreached_rejection(t));
|
||||
}, 'Fetch events should wait for the activate event to complete.');
|
||||
|
||||
</script>
|
||||
</body>
|
|
@ -0,0 +1,87 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var documentURL = 'no-such-worker';
|
||||
navigator.serviceWorker.getRegistration(documentURL)
|
||||
.then(function(value) {
|
||||
assert_equals(value, undefined,
|
||||
'getRegistration should resolve with undefined');
|
||||
t.done();
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'getRegistration');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/scope/getregistration/normal';
|
||||
var registration;
|
||||
service_worker_unregister_and_register(t, 'resources/empty-worker.js',
|
||||
scope)
|
||||
.then(function(r) {
|
||||
registration = r;
|
||||
return navigator.serviceWorker.getRegistration(scope);
|
||||
})
|
||||
.then(function(value) {
|
||||
assert_equals(
|
||||
value, registration,
|
||||
'getRegistration should resolve to the same registration object');
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Register then getRegistration');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/scope/getregistration/url-with-fragment';
|
||||
var documentURL = scope + '#ref';
|
||||
var registration;
|
||||
service_worker_unregister_and_register(t, 'resources/empty-worker.js',
|
||||
scope)
|
||||
.then(function(r) {
|
||||
registration = r;
|
||||
return navigator.serviceWorker.getRegistration(documentURL);
|
||||
})
|
||||
.then(function(value) {
|
||||
assert_equals(
|
||||
value, registration,
|
||||
'getRegistration should resolve to the same registration object');
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Register then getRegistration with a URL having a fragment');
|
||||
|
||||
async_test(function(t) {
|
||||
var documentURL = 'http://example.com/';
|
||||
navigator.serviceWorker.getRegistration(documentURL)
|
||||
.then(function() {
|
||||
assert_unreached(
|
||||
'getRegistration with an out of origin URL should fail');
|
||||
}, function(reason) {
|
||||
assert_equals(
|
||||
reason.name, 'SecurityError',
|
||||
'getRegistration with an out of origin URL should fail');
|
||||
t.done();
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'getRegistration with a cross origin URL');
|
||||
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/scope/getregistration/register-unregister';
|
||||
service_worker_unregister_and_register(t, 'resources/empty-worker.js',
|
||||
scope)
|
||||
.then(function(registration) {
|
||||
return registration.unregister();
|
||||
})
|
||||
.then(function() {
|
||||
return navigator.serviceWorker.getRegistration(scope);
|
||||
})
|
||||
.then(function(value) {
|
||||
assert_equals(value, undefined,
|
||||
'getRegistration should resolve with undefined');
|
||||
t.done();
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Register then Unregister then getRegistration');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,159 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: getRegistrations()</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script src="resources/get-host-info.sub.js"></script>
|
||||
<script src="../fetch/resources/fetch-test-helpers.sub.js"></script>
|
||||
<script>
|
||||
// Purge the existing registrations for the origin.
|
||||
// getRegistrations() is used in order to avoid adding additional complexity
|
||||
// e.g. adding an internal function.
|
||||
promise_test(function(t) {
|
||||
return navigator.serviceWorker.getRegistrations()
|
||||
.then(function(registrations) {
|
||||
return registrations.reduce(function(sequence, registration) {
|
||||
return sequence.then(function() {
|
||||
return registration.unregister();
|
||||
});
|
||||
}, Promise.resolve());
|
||||
});
|
||||
}, 'Purge the existing registrations.');
|
||||
|
||||
promise_test(function(t) {
|
||||
return navigator.serviceWorker.getRegistrations()
|
||||
.then(function(value) {
|
||||
assert_array_equals(
|
||||
value,
|
||||
[],
|
||||
'getRegistrations should resolve with an empty array.');
|
||||
});
|
||||
}, 'getRegistrations');
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope = 'resources/scope/getregistrations/normal';
|
||||
var script = 'resources/empty-worker.js';
|
||||
var registrations = [];
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(r) {
|
||||
registrations.push(r);
|
||||
return navigator.serviceWorker.getRegistrations();
|
||||
})
|
||||
.then(function(value) {
|
||||
assert_array_equals(
|
||||
value,
|
||||
registrations,
|
||||
'getRegistrations should resolve with array of registrations.');
|
||||
return service_worker_unregister(t, scope);
|
||||
});
|
||||
}, 'Register then getRegistrations');
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope1 = 'resources/scope/getregistrations/scope1';
|
||||
var scope2 = 'resources/scope/getregistrations/scope2';
|
||||
var script = 'resources/empty-worker.js';
|
||||
var registrations = [];
|
||||
return service_worker_unregister_and_register(t, script, scope1)
|
||||
.then(function(r) {
|
||||
registrations.push(r);
|
||||
return service_worker_unregister_and_register(t, script, scope2);
|
||||
})
|
||||
.then(function(r) {
|
||||
registrations.push(r);
|
||||
return navigator.serviceWorker.getRegistrations();
|
||||
})
|
||||
.then(function(value) {
|
||||
assert_array_equals(
|
||||
value,
|
||||
registrations,
|
||||
'getRegistrations should resolve with array of registrations.');
|
||||
return service_worker_unregister(t, scope1);
|
||||
})
|
||||
.then(function() {
|
||||
return service_worker_unregister(t, scope2);
|
||||
});
|
||||
}, 'Register multiple times then getRegistrations');
|
||||
|
||||
promise_test(function(t) {
|
||||
var scope = 'resources/scope/getregistrations/register-unregister';
|
||||
var script = 'resources/empty-worker.js';
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return registration.unregister();
|
||||
})
|
||||
.then(function() {
|
||||
return navigator.serviceWorker.getRegistrations();
|
||||
})
|
||||
.then(function(value) {
|
||||
assert_array_equals(
|
||||
value,
|
||||
[],
|
||||
'getRegistrations should resolve with an empty array.');
|
||||
});
|
||||
}, 'Register then Unregister then getRegistrations');
|
||||
|
||||
promise_test(function(t) {
|
||||
var host_info = get_host_info();
|
||||
// Rewrite the url to point to remote origin.
|
||||
var frame_same_origin_url = new URL("resources/frame-for-getregistrations.html", window.location);
|
||||
var frame_url = host_info['HTTPS_REMOTE_ORIGIN'] + frame_same_origin_url.pathname;
|
||||
var scope = 'resources/scope-for-getregistrations';
|
||||
var script = 'resources/empty-worker.js';
|
||||
var frame;
|
||||
var registrations = [];
|
||||
|
||||
// Loads an iframe and waits for 'ready' message from it to resolve promise.
|
||||
// Caller is responsible for removing frame.
|
||||
function with_iframe_ready(url) {
|
||||
return new Promise(function(resolve) {
|
||||
var frame = document.createElement('iframe');
|
||||
frame.src = url;
|
||||
window.addEventListener('message', function onMessage(e) {
|
||||
window.removeEventListener('message', onMessage);
|
||||
if (e.data == 'ready') {
|
||||
resolve(frame);
|
||||
}
|
||||
});
|
||||
document.body.appendChild(frame);
|
||||
});
|
||||
}
|
||||
|
||||
// We need this special frame loading function because the frame is going
|
||||
// to register it's own service worker and there is the possibility that that
|
||||
// register() finishes after the register() for the same domain later in the
|
||||
// test. So we have to wait until the cross origin register() is done, and not
|
||||
// just until the frame loads.
|
||||
return with_iframe_ready(frame_url)
|
||||
.then(function(f) {
|
||||
frame = f;
|
||||
return service_worker_unregister_and_register(t, script, scope);
|
||||
})
|
||||
.then(function(r) {
|
||||
registrations.push(r);
|
||||
return navigator.serviceWorker.getRegistrations();
|
||||
})
|
||||
.then(function(value) {
|
||||
assert_array_equals(
|
||||
value,
|
||||
registrations,
|
||||
'getRegistrations should only return same origin registrations.');
|
||||
|
||||
var channel = new MessageChannel();
|
||||
var resolve;
|
||||
var p = new Promise(function(r) { resolve = r; });
|
||||
|
||||
channel.port1.onmessage = function(e) {
|
||||
if (e.data == 'unregistered')
|
||||
resolve();
|
||||
};
|
||||
frame.contentWindow.postMessage('unregister', '*', [channel.port2]);
|
||||
return p;
|
||||
})
|
||||
.then(function() {
|
||||
frame.remove();
|
||||
return service_worker_unregister(t, scope);
|
||||
});
|
||||
}, 'getRegistrations promise resolves only with same origin registrations.');
|
||||
|
||||
done();
|
||||
</script>
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Indexed DB</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
async_test(function(t) {
|
||||
var scope = 'resources/blank.html';
|
||||
service_worker_unregister_and_register(
|
||||
t, 'resources/indexeddb-worker.js', scope)
|
||||
.then(function(registration) {
|
||||
var sw = registration.installing;
|
||||
var messageChannel = new MessageChannel();
|
||||
messageChannel.port1.onmessage = t.step_func(onMessage);
|
||||
sw.postMessage({port: messageChannel.port2}, [messageChannel.port2]);
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
|
||||
function onMessage() {
|
||||
var openRequest = indexedDB.open('db');
|
||||
openRequest.onsuccess = t.step_func(function() {
|
||||
var db = openRequest.result;
|
||||
var tx = db.transaction('store');
|
||||
var store = tx.objectStore('store');
|
||||
var getRequest = store.get('key');
|
||||
getRequest.onsuccess = t.step_func(function() {
|
||||
assert_equals(
|
||||
getRequest.result, 'value',
|
||||
'The get() result should match what the worker put().');
|
||||
service_worker_unregister_and_done(t, scope);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, 'Verify Indexed DB operation in a Service Worker');
|
||||
</script>
|
|
@ -0,0 +1,30 @@
|
|||
<!DOCTYPE html>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="resources/testharness-helpers.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
function wait_for_install_event(worker) {
|
||||
return new Promise(function(resolve) {
|
||||
worker.addEventListener('statechange', function(event) {
|
||||
if (worker.state == 'installed')
|
||||
resolve(true);
|
||||
else if (worker.state == 'redundant')
|
||||
resolve(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
promise_test(function(t) {
|
||||
var script = 'resources/install-event-type-worker.js';
|
||||
var scope = 'resources/install-event-type';
|
||||
return service_worker_unregister_and_register(t, script, scope)
|
||||
.then(function(registration) {
|
||||
return wait_for_install_event(registration.installing);
|
||||
})
|
||||
.then(function(did_install) {
|
||||
assert_true(did_install, 'The worker was installed');
|
||||
})
|
||||
}, 'install event type');
|
||||
|
||||
</script>
|
|
@ -0,0 +1,37 @@
|
|||
<!DOCTYPE html>
|
||||
<title>ServiceWorker: navigator.serviceWorker.installing</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<body>
|
||||
<script>
|
||||
// "installing" is set
|
||||
async_test(function(t) {
|
||||
var step = t.step_func.bind(t);
|
||||
var url = 'resources/empty-worker.js';
|
||||
var scope = 'resources/blank.html';
|
||||
var frame;
|
||||
|
||||
service_worker_unregister(t, scope)
|
||||
.then(step(function() { return with_iframe(scope); }))
|
||||
.then(step(function(f) {
|
||||
frame = f;
|
||||
return navigator.serviceWorker.register(url, {scope: scope});
|
||||
}))
|
||||
.then(step(function(registration) {
|
||||
var container = frame.contentWindow.navigator.serviceWorker;
|
||||
assert_equals(container.controller, null);
|
||||
assert_equals(registration.active, null);
|
||||
assert_equals(registration.waiting, null);
|
||||
assert_equals(registration.installing.scriptURL, normalizeURL(url));
|
||||
|
||||
// FIXME: Add a test for a frame created after installation.
|
||||
// Should the existing frame ("frame") block activation?
|
||||
}))
|
||||
.then(step(function() {
|
||||
frame.remove();
|
||||
return service_worker_unregister_and_done(t, scope);
|
||||
}))
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'installing is set');
|
||||
</script>
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Service Worker: Interfaces</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/interfaces.js"></script>
|
||||
<script src="resources/test-helpers.sub.js"></script>
|
||||
<script>
|
||||
|
||||
test(function() {
|
||||
var EVENT_HANDLER = 'object';
|
||||
verify_interface(
|
||||
'ServiceWorkerContainer', navigator.serviceWorker,
|
||||
{
|
||||
register: 'function',
|
||||
getRegistration: 'function',
|
||||
oncontrollerchange: EVENT_HANDLER
|
||||
});
|
||||
}, 'Interfaces and attributes of ServiceWorkerContainer');
|
||||
|
||||
async_test(function(t) {
|
||||
var EVENT_HANDLER = 'object';
|
||||
var scope = 'resources/scope/interfaces-and-attributes';
|
||||
|
||||
service_worker_unregister_and_register(
|
||||
t, 'resources/empty-worker.js', scope)
|
||||
.then(function(registration) {
|
||||
verify_interface(
|
||||
'ServiceWorkerRegistration', registration,
|
||||
{
|
||||
installing: 'object',
|
||||
waiting: 'object',
|
||||
active: 'object',
|
||||
scope: 'string',
|
||||
unregister: 'function',
|
||||
onupdatefound: EVENT_HANDLER
|
||||
});
|
||||
verify_interface(
|
||||
'ServiceWorker', registration.installing,
|
||||
{
|
||||
scriptURL: 'string',
|
||||
state: 'string',
|
||||
onstatechange: EVENT_HANDLER
|
||||
});
|
||||
return registration.unregister();
|
||||
})
|
||||
.then(function() {
|
||||
t.done();
|
||||
})
|
||||
.catch(unreached_rejection(t));
|
||||
}, 'Interfaces and attributes of ServiceWorker');
|
||||
|
||||
service_worker_test(
|
||||
'resources/interfaces-worker.sub.js',
|
||||
'Interfaces and attributes in ServiceWorkerGlobalScope');
|
||||
|
||||
</script>
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue