Auto merge of #20510 - servo-wpt-sync:wpt_update_02-04-2018, r=jdm

Sync WPT with upstream (02-04-2018)

Automated downstream sync of changes from upstream as of 02-04-2018.
[no-wpt-sync]

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/20510)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2018-04-03 03:54:22 -04:00 committed by GitHub
commit 20db733f8e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
94 changed files with 2583 additions and 2211 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,2 @@
[vh_not_refreshing_on_chrome.html]
expected: FAIL

View file

@ -0,0 +1,4 @@
[img-mime-types-coverage.tentative.sub.html]
[Untitled]
expected: FAIL

View file

@ -0,0 +1,5 @@
[preload-image-png-mislabeled-as-html-nosniff.tentative.sub.html]
expected: TIMEOUT
[Untitled]
expected: TIMEOUT

View file

@ -0,0 +1,4 @@
[image.html]
[URL query: image/svg+xml]
expected: FAIL

View file

@ -0,0 +1,4 @@
[010.html]
[Salvagability of document.opened document]
expected: FAIL

View file

@ -0,0 +1,5 @@
[context-release-with-workers.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -0,0 +1,5 @@
[atan_001_to_008.html]
expected: TIMEOUT
[Overall test]
expected: NOTRUN

View file

@ -423,7 +423,7 @@ is [archived][ircarchive].
[contributing]: https://github.com/w3c/web-platform-tests/blob/master/CONTRIBUTING.md [contributing]: https://github.com/w3c/web-platform-tests/blob/master/CONTRIBUTING.md
[ircw3org]: https://www.w3.org/wiki/IRC [ircw3org]: https://www.w3.org/wiki/IRC
[ircarchive]: http://logs.glob.uno/?c=w3%23testing [ircarchive]: https://w3.logbot.info/testing
[mailarchive]: https://lists.w3.org/Archives/Public/public-test-infra/ [mailarchive]: https://lists.w3.org/Archives/Public/public-test-infra/
Documentation Documentation

View file

@ -1,2 +1,28 @@
This directory contains tests for the This directory contains tests for the
[Async Cookies API](https://github.com/WICG/cookie-store). [Async Cookies API](https://github.com/WICG/cookie-store).
## Note on cookie naming conventions
A simple origin cookie is a cookie named with the `__Host-` prefix
which is always secure-flagged, always implicit-domain, always
`/`-scoped, and hence always unambiguous in the cookie jar serialization
and origin-scoped. It can be treated as a simple key/value pair.
`"LEGACY"` in a cookie name here means it is an old-style unprefixed
cookie name, so you can't tell e.g. whether it is Secure-flagged or
`/`-pathed just by looking at it, and its flags, domain and path may
vary even in a single cookie jar serialization leading to apparent
duplicate entries, ambiguities, and complexity (i.e. it cannot be
treated as a simple key/value pair.)
Cookie names used in the tests are intended to be
realistic. Traditional session cookie names are typically
all-upper-case for broad framework compatibility. The more modern
`"__Host-"` prefix has only one allowed casing. An expected upgrade
path from traditional "legacy" cookie names to simple origin cookie
names is simply to prefix the traditional name with the `"__Host-"`
prefix.
Many of the used cookie names are non-ASCII to ensure
straightforward internationalization is possible at every API surface.
These work in many modern browsers, though not yet all of them.

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Basic tests for cookieStore</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite();
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Basic tests for cookieStore (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite();
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Basic tests for cookieStore (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite();
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Basic tests for cookieStore (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite();
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: delete cookies</title> <title>Async Cookies: delete cookies</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/delete_cookies.js"></script>
<script>
'use strict';
suite({testName: 'testDeleteCookies'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: delete cookies (HTTPS)</title> <title>Async Cookies: delete cookies (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/delete_cookies.js"></script>
<script>
'use strict';
suite({testName: 'testDeleteCookies'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: delete cookies (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testDeleteCookies'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: delete cookies (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testDeleteCookies'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: document.cookie</title> <title>Async Cookies: document.cookie</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/document_cookie.js"></script>
<script>
'use strict';
suite({testName: 'testDocumentCookie'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: document.cookie (HTTPS)</title> <title>Async Cookies: document.cookie (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/document_cookie.js"></script>
<script>
'use strict';
suite({testName: 'testDocumentCookie'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: document.cookie (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testDocumentCookie'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: document.cookie (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testDocumentCookie'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: expiration</title> <title>Async Cookies: expiration</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/expiration.js"></script>
<script>
'use strict';
suite({testName: 'testExpiration'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: expiration (HTTPS)</title> <title>Async Cookies: expiration (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/expiration.js"></script>
<script>
'use strict';
suite({testName: 'testExpiration'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: expiration (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testExpiration'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: expiration (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testExpiration'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: get, set, getAll</title> <title>Async Cookies: get, set, getAll</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/get_set_get_all.js"></script>
<script>
'use strict';
suite({testName: 'testGetSetGetAll'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: get, set, getAll (HTTPS)</title> <title>Async Cookies: get, set, getAll (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/get_set_get_all.js"></script>
<script>
'use strict';
suite({testName: 'testGetSetGetAll'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: get, set, getAll (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testGetSetGetAll'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: get, set, getAll (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testGetSetGetAll'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: HTTP Cookie and Set-Cookie headers</title> <title>Async Cookies: HTTP Cookie and Set-Cookie headers</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/http_cookie_and_set_cookie_headers.js"></script>
<script>
'use strict';
suite({testName: 'testHttpCookieAndSetCookieHeaders'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: HTTP Cookie and Set-Cookie headers (HTTPS)</title> <title>Async Cookies: HTTP Cookie and Set-Cookie headers (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/http_cookie_and_set_cookie_headers.js"></script>
<script>
'use strict';
suite({testName: 'testHttpCookieAndSetCookieHeaders'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt;</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testMetaHttpEquivSetCookie'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt; (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testMetaHttpEquivSetCookie'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt; (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testMetaHttpEquivSetCookie'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: <title>Async Cookies: document.cookie</title>lt;Meta Http-Equiv="Set-Cookie" ... <title>Async Cookies: document.cookie</title>gt; (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testMetaHttpEquivSetCookie'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name and No Value</title> <title>Async Cookies: Test No Name and No Value</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/no_name_and_no_value.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameAndNoValue'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name and No Value (HTTPS)</title> <title>Async Cookies: Test No Name and No Value (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/no_name_and_no_value.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameAndNoValue'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name and No Value (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameAndNoValue'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name and No Value (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameAndNoValue'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, '=' in Value</title> <title>Async Cookies: Test No Name, '=' in Value</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/no_name_equals_in_value.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameEqualsInValue'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, '=' in Value (HTTPS)</title> <title>Async Cookies: Test No Name, '=' in Value (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/no_name_equals_in_value.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameEqualsInValue'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, '=' in Value (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameEqualsInValue'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, '=' in Value (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameEqualsInValue'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, Multiple Values</title> <title>Async Cookies: Test No Name, Multiple Values</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/no_name_multiple_values.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameMultipleValues'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, Multiple Values (HTTPS)</title> <title>Async Cookies: Test No Name, Multiple Values (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/no_name_multiple_values.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameMultipleValues'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, Multiple Values (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameMultipleValues'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test No Name, Multiple Values (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testNoNameMultipleValues'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test Observation</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testObservation'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test Observation (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testObservation'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test Observation (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testObservation'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: Test Observation (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testObservation'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: One simple origin cookie</title> <title>Async Cookies: One simple origin cookie</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/one_simple_origin_cookie.js"></script>
<script>
'use strict';
suite({testName: 'testOneSimpleOriginCookie'});
</script>

View file

@ -1,14 +1,8 @@
<!DOCTYPE html> <!DOCTYPE html>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: One simple origin cookie (HTTPS)</title> <title>Async Cookies: One simple origin cookie (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md"> <meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script> <script src="resources/cookie-test-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script> <script src="resources/one_simple_origin_cookie.js"></script>
<script>
'use strict';
suite({testName: 'testOneSimpleOriginCookie'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: One simple origin cookie (Static)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testOneSimpleOriginCookie'});
</script>

View file

@ -1,14 +0,0 @@
<!DOCTYPE html>
<meta charset="utf-8">
<meta name="timeout" content="long">
<title>Async Cookies: One simple origin cookie (Static; HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/blob/gh-pages/explainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/testharness-helpers.js"></script>
<script src="resources/cookie-store-tests.js"></script>
<script>
'use strict';
suite({testName: 'testOneSimpleOriginCookie'});
</script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Async Cookies: ordering (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/cookie-test-helpers.js"></script>
<script src="resources/ordering.js"></script>

View file

@ -1,71 +1,14 @@
'use strict'; 'use strict';
// Length of final setTimeout when observer callback has not fired. // TODO(jsbell): Once ServiceWorker is supported, add arbitrary path coverage.
// const kPath = location.pathname.replace(/[^/]+$/, '');
const kExtraObserverDelay = 0; // For builtin implementation
// NOTE: A polyfill was used for pre-implementation testing. To revive
// it uncomment these and comment out the preceding line:
//
// const kExtraObserverDelay = 200; // Polyfill when not running on battery
// // const kExtraObserverDelay = 5000; // ... when running on battery
// document.open();
// document.write(`
// <script>delete cookieStore</script>
// <script src="https://wicg.github.io/cookie-store/cookies.js">
// </script>
// `);
// document.close()
// See https://github.com/whatwg/html/pull/3011#issuecomment-331187136
// and https://www.chromestatus.com/feature/6170540112871424
const kMetaHttpEquivSetCookieIsGone = true;
// True when running in a document context as opposed to a worker context // True when running in a document context as opposed to a worker context
const kHasDocument = typeof document !== 'undefined'; const kHasDocument = typeof document !== 'undefined';
// Override for named test inclusion. Set by suite().
let testOverride = undefined;
// Determines whether the named test should be included in this run of the
// suite. Only usable in a test runner context as this uses assert_equals.
//
// Parameters:
//
// - testName: (string) test name; must be an identifier starting with 'test'
// - opt_excludeFromAll: (optional; boolean) if true, explicit or implicit
// #...&test=all (which is the default) will not activate this test.
const includeTest = (testName, opt_excludeFromAll) => {
assert_equals(!!testName.match(/^test\w+/), true, 'includeTest: ' + testName);
assert_equals(typeof eval(testName), 'function', 'includeTest: ' + testName);
let testParams =
(location.hash || '#').substr(1).split('&').filter(
x => x.match(/^test=/)).map(x => decodeURIComponent(x));
if (!testParams.length) {
testParams = ['test=all'];
if (testOverride !== undefined) {
testParams = ['test=' + testOverride];
}
}
const filterSet =
testParams.map(x => x.split('=', 2)[1]).join(',').split(',').reduce(
(set, name) => Object.assign(set, {[name]: true}), {});
for (let name in filterSet) {
if (name === 'all' || !filterSet.hasOwnProperty(name)) continue;
assert_equals(!!name.match(/^test\w+/), true, '#test=' + testName);
assert_equals(typeof eval(name), 'function', '#test=' + testName);
}
return (filterSet.all && !opt_excludeFromAll) ||
filterSet.hasOwnProperty(testName) && filterSet[testName];
}
// True when running on unsecured 'http:' rather than secured 'https:'. // True when running on unsecured 'http:' rather than secured 'https:'.
const kIsUnsecured = location.protocol !== 'https:'; const kIsUnsecured = location.protocol !== 'https:';
// True when no CGI/no active wptserve handlers should be used.
const kIsStatic = !!((location.hash || '#').match(/(^#|&)static=true(&|$)/) ||
location.pathname.match(/_static\./));
const kCookieHelperCgi = 'resources/cookie_helper.py'; const kCookieHelperCgi = 'resources/cookie_helper.py';
// Async wrapper for an async function or promise that is expected // Async wrapper for an async function or promise that is expected
@ -79,13 +22,13 @@ const kCookieHelperCgi = 'resources/cookie_helper.py';
// - promise: (thenable) test code // - promise: (thenable) test code
// - message: (optional; string) message to forward to promise_rejects in // - message: (optional; string) message to forward to promise_rejects in
// unsecured context // unsecured context
const promise_rejects_when_unsecured = async ( async function promise_rejects_when_unsecured(
testCase, testCase,
code, code,
promise, promise,
message = 'Feature unavailable from unsecured contexts' message = 'Feature unavailable from unsecured contexts') {
) => { if (kIsUnsecured)
if (kIsUnsecured) await promise_rejects(testCase, code, promise, message); await promise_rejects(testCase, code, promise, message);
else await promise; else await promise;
}; };
@ -97,9 +40,11 @@ const promise_rejects_when_unsecured = async (
// //
// Returns a string serializing the records, or undefined if no records were // Returns a string serializing the records, or undefined if no records were
// given. // given.
const cookieString = cookies => cookies.length ? cookies.map(( function cookieString(cookies) {
return cookies.length ? cookies.map((
{name, value}) => (name ? (name + '=') : '') + value).join('; ') : {name, value}) => (name ? (name + '=') : '') + value).join('; ') :
undefined; undefined;
}
// Approximate async equivalent to the document.cookie getter but with // Approximate async equivalent to the document.cookie getter but with
// important differences: optional additional getAll arguments are // important differences: optional additional getAll arguments are
@ -110,7 +55,7 @@ const cookieString = cookies => cookies.length ? cookies.map((
// assert_equals in failing cases than assert_object_equals would // assert_equals in failing cases than assert_object_equals would
// using parsed cookie jar contents and also allows expectations to be // using parsed cookie jar contents and also allows expectations to be
// written more compactly. // written more compactly.
const getCookieString = async (...args) => { async function getCookieString(...args) {
return cookieString(await cookieStore.getAll(...args)); return cookieString(await cookieStore.getAll(...args));
} }
@ -120,8 +65,7 @@ const getCookieString = async (...args) => {
// //
// Unlike document.cookie, this returns undefined when no cookies are // Unlike document.cookie, this returns undefined when no cookies are
// present. // present.
const getCookieStringHttp = async (extraPath = null) => { async function getCookieStringHttp(extraPath = null) {
if (kIsStatic) throw 'CGI not available in static HTML test';
const url = const url =
kCookieHelperCgi + ((extraPath == null) ? '' : ('/' + extraPath)); kCookieHelperCgi + ((extraPath == null) ? '' : ('/' + extraPath));
const response = await fetch(url, { credentials: 'include' }); const response = await fetch(url, { credentials: 'include' });
@ -134,7 +78,8 @@ const getCookieStringHttp = async (extraPath = null) => {
response.headers.get('content-type'), response.headers.get('content-type'),
'text/plain; charset=utf-8', 'text/plain; charset=utf-8',
'CGI did not return UTF-8 text in getCookieStringHttp'); 'CGI did not return UTF-8 text in getCookieStringHttp');
if (text === '') return undefined; if (text === '')
return undefined;
assert_equals( assert_equals(
text.indexOf('cookie='), text.indexOf('cookie='),
0, 0,
@ -148,8 +93,7 @@ const getCookieStringHttp = async (extraPath = null) => {
// //
// Unlike document.cookie, this returns undefined when no cookies are // Unlike document.cookie, this returns undefined when no cookies are
// present. // present.
const getCookieBinaryHttp = async (extraPath = null) => { async function getCookieBinaryHttp(extraPath = null) {
if (kIsStatic) throw 'CGI not available in static HTML test';
const url = const url =
kCookieHelperCgi + kCookieHelperCgi +
((extraPath == null) ? ((extraPath == null) ?
@ -165,7 +109,8 @@ const getCookieBinaryHttp = async (extraPath = null) => {
response.headers.get('content-type'), response.headers.get('content-type'),
'text/plain; charset=iso-8859-1', 'text/plain; charset=iso-8859-1',
'CGI did not return ISO 8859-1 text in getCookieBinaryHttp'); 'CGI did not return ISO 8859-1 text in getCookieBinaryHttp');
if (text === '') return undefined; if (text === '')
return undefined;
assert_equals( assert_equals(
text.indexOf('cookie='), text.indexOf('cookie='),
0, 0,
@ -175,8 +120,7 @@ const getCookieBinaryHttp = async (extraPath = null) => {
// Approximate async equivalent to the document.cookie setter but from // Approximate async equivalent to the document.cookie setter but from
// the server's point of view. // the server's point of view.
const setCookieStringHttp = async setCookie => { async function setCookieStringHttp(setCookie) {
if (kIsStatic) throw 'CGI not available in static HTML test';
const encodedSetCookie = encodeURIComponent(setCookie); const encodedSetCookie = encodeURIComponent(setCookie);
const url = kCookieHelperCgi; const url = kCookieHelperCgi;
const headers = new Headers(); const headers = new Headers();
@ -205,13 +149,12 @@ const setCookieStringHttp = async setCookie => {
text, text,
'set-cookie=' + encodedSetCookie, 'set-cookie=' + encodedSetCookie,
'CGI did not faithfully echo the set-cookie value'); 'CGI did not faithfully echo the set-cookie value');
}; }
// Approximate async equivalent to the document.cookie setter but from // Approximate async equivalent to the document.cookie setter but from
// the server's point of view. This version sets a binary cookie rather // the server's point of view. This version sets a binary cookie rather
// than a UTF-8 one. // than a UTF-8 one.
const setCookieBinaryHttp = async setCookie => { async function setCookieBinaryHttp(setCookie) {
if (kIsStatic) throw 'CGI not available in static HTML test';
const encodedSetCookie = escape(setCookie).split('/').join('%2F'); const encodedSetCookie = escape(setCookie).split('/').join('%2F');
const url = kCookieHelperCgi + '?charset=iso-8859-1'; const url = kCookieHelperCgi + '?charset=iso-8859-1';
const headers = new Headers(); const headers = new Headers();
@ -238,49 +181,90 @@ const setCookieBinaryHttp = async setCookie => {
text, text,
'set-cookie=' + encodedSetCookie, 'set-cookie=' + encodedSetCookie,
'CGI did not faithfully echo the set-cookie value'); 'CGI did not faithfully echo the set-cookie value');
}; }
// Approximate async equivalent to the document.cookie setter but using
// <meta http-equiv="set-cookie" content="..."> written into a temporary
// IFRAME. Merely appending the node to HEAD works in some browsers (e.g.
// Chromium) but not others (e.g. Firefox.)
const setCookieStringMeta = async setCookie => {
if (document.readyState !== 'complete') {
await new Promise(resolve => addEventListener('load', resolve, true));
}
const meta = Object.assign(document.createElement('meta'), {
httpEquiv: 'set-cookie',
content: setCookie
});
const ifr = document.createElement('iframe');
await new Promise(resolve => document.body.appendChild(Object.assign(
ifr,
{
onload: resolve
})));
try {
ifr.contentWindow.document.open('text/html; charset=utf-8');
ifr.contentWindow.document.write([
'<!DOCTYPE html>',
'<meta charset="utf-8">',
meta.outerHTML
].join('\r\n'));
ifr.contentWindow.document.close();
} finally {
if (ifr.parentNode) ifr.parentNode.removeChild(ifr);
}
};
// Async document.cookie getter; converts '' to undefined which loses // Async document.cookie getter; converts '' to undefined which loses
// information in the edge case where a single ''-valued anonymous // information in the edge case where a single ''-valued anonymous
// cookie is visible. // cookie is visible.
const getCookieStringDocument = async () => { async function getCookieStringDocument() {
if (!kHasDocument) throw 'document.cookie not available in this context'; if (!kHasDocument)
throw 'document.cookie not available in this context';
return String(document.cookie || '') || undefined; return String(document.cookie || '') || undefined;
}; }
// Async document.cookie setter // Async document.cookie setter
const setCookieStringDocument = async setCookie => { async function setCookieStringDocument(setCookie) {
if (!kHasDocument) throw 'document.cookie not available in this context'; if (!kHasDocument)
throw 'document.cookie not available in this context';
document.cookie = setCookie; document.cookie = setCookie;
}; }
// Observe the next 'change' event on the cookieStore. Typical usage:
//
// const eventPromise = observeNextCookieChangeEvent();
// await /* something that modifies cookies */
// await verifyCookieChangeEvent(
// eventPromise, {changed: [{name: 'name', value: 'value'}]});
//
function observeNextCookieChangeEvent() {
return new Promise(resolve => {
cookieStore.addEventListener('change', e => resolve(e), {once: true});
});
}
async function verifyCookieChangeEvent(eventPromise, expected, description) {
description = description ? description + ': ' : '';
expected = Object.assign({changed:[], deleted:[]}, expected);
const event = await eventPromise;
assert_equals(event.changed.length, expected.changed.length,
description + 'number of changed cookies');
for (let i = 0; i < event.changed.length; ++i) {
assert_equals(event.changed[i].name, expected.changed[i].name,
description + 'changed cookie name');
assert_equals(event.changed[i].value, expected.changed[i].value,
description + 'changed cookie value');
}
assert_equals(event.deleted.length, expected.deleted.length,
description + 'number of deleted cookies');
for (let i = 0; i < event.deleted.length; ++i) {
assert_equals(event.deleted[i].name, expected.deleted[i].name,
description + 'deleted cookie name');
assert_equals(event.deleted[i].value, expected.deleted[i].value,
description + 'deleted cookie value');
}
}
// Helper function for promise_test with cookies; cookies
// named in these tests are cleared before/after the test
// body function is executed.
async function cookie_test(func, description) {
// Wipe cookies used by tests before and after the test.
async function deleteTestCookies() {
await cookieStore.delete('');
await cookieStore.delete('TEST');
await cookieStore.delete('META-🍪');
await cookieStore.delete('DOCUMENT-🍪');
await cookieStore.delete('HTTP-🍪');
await setCookieStringHttp(
'HTTPONLY-🍪=DELETED; path=/; max-age=0; httponly');
if (!kIsUnsecured) {
await cookieStore.delete('__Host-COOKIENAME');
await cookieStore.delete('__Host-1🍪');
await cookieStore.delete('__Host-2🌟');
await cookieStore.delete('__Host-3🌱');
await cookieStore.delete('__Host-unordered1🍪');
await cookieStore.delete('__Host-unordered2🌟');
await cookieStore.delete('__Host-unordered3🌱');
}
}
return promise_test(async t => {
await deleteTestCookies();
try {
return await func(t);
} finally {
await deleteTestCookies();
}
}, description);
}

View file

@ -0,0 +1,44 @@
'use strict';
cookie_test(async testCase => {
// TODO: This test doesn't create cookies and doesn't assert
// the behavior of delete(). Improve or remove it.
await cookieStore.delete('');
await cookieStore.delete('TEST');
await cookieStore.delete('META-🍪');
await cookieStore.delete('DOCUMENT-🍪');
await cookieStore.delete('HTTP-🍪');
await setCookieStringHttp(
'HTTPONLY-🍪=DELETED; path=/; max-age=0; httponly');
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
cookieStore.delete('__Host-COOKIENAME'));
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
cookieStore.delete('__Host-1🍪'));
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
cookieStore.delete('__Host-2🌟'));
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
cookieStore.delete('__Host-3🌱'));
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
cookieStore.delete('__Host-unordered1🍪'));
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
cookieStore.delete('__Host-unordered2🌟'));
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
cookieStore.delete('__Host-unordered3🌱'));
}, 'Test cookieStore.delete');

View file

@ -0,0 +1,43 @@
'use strict';
cookie_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await setCookieStringDocument('DOCUMENT-🍪=🔵; path=/');
assert_equals(
await getCookieString(),
'DOCUMENT-🍪=🔵',
'Cookie we wrote using document.cookie in cookie jar');
assert_equals(
await getCookieStringHttp(),
'DOCUMENT-🍪=🔵',
'Cookie we wrote using document.cookie in HTTP cookie jar');
assert_equals(
await getCookieStringDocument(),
'DOCUMENT-🍪=🔵',
'Cookie we wrote using document.cookie in document.cookie');
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: 'DOCUMENT-🍪', value: '🔵'}]},
'Cookie we wrote using document.cookie is observed');
eventPromise = observeNextCookieChangeEvent();
await setCookieStringDocument('DOCUMENT-🍪=DELETED; path=/; max-age=0');
assert_equals(
await getCookieString(),
undefined,
'Empty cookie jar after document.cookie' +
' cookie-clearing using max-age=0');
assert_equals(
await getCookieStringHttp(),
undefined,
'Empty HTTP cookie jar after document.cookie' +
' cookie-clearing using max-age=0');
assert_equals(
await getCookieStringDocument(),
undefined,
'Empty document.cookie cookie jar after document.cookie' +
' cookie-clearing using max-age=0');
await verifyCookieChangeEvent(
eventPromise, {deleted: [{name: 'DOCUMENT-🍪'}]},
'Deletion observed after document.cookie cookie-clearing' +
' using max-age=0');
}, 'Verify interoperability of document.cookie with other APIs.');

View file

@ -0,0 +1,89 @@
'use strict';
// Set the secure example.org-domain cookie __Secure-COOKIENAME with
// value cookie-value on path /cgi-bin/ and 24 hour duration; domain
// and path will be rewritten below.
//
// This uses a Date object for expiration.
async function setOneDaySecureCookieWithDate() {
// one day ahead, ignoring a possible leap-second
let inTwentyFourHours = new Date(Date.now() + 24 * 60 * 60 * 1000);
await cookieStore.set('__Secure-COOKIENAME', 'cookie-value', {
path: kPath,
expires: inTwentyFourHours,
secure: true,
domain: location.hostname
});
}
// Set the secured example.org-domain cookie __Secure-COOKIENAME with
// value cookie-value on path /cgi-bin/ and expiration in June of next
// year; domain and path will be rewritten below.
//
// This uses an HTTP-style date string for expiration.
async function setSecureCookieWithHttpLikeExpirationString() {
const year = (new Date()).getUTCFullYear() + 1;
const date = new Date('07 Jun ' + year + ' 07:07:07 UTC');
const day = ('Sun Mon Tue Wed Thu Fri Sat'.split(' '))[date.getUTCDay()];
await cookieStore.set('__Secure-COOKIENAME', 'cookie-value', {
path: kPath,
expires: day + ', 07 Jun ' + year + ' 07:07:07 GMT',
secure: true,
domain: location.hostname
});
}
// Set the unsecured example.org-domain cookie LEGACYCOOKIENAME with
// value cookie-value on path /cgi-bin/ and 24 hour duration; domain
// and path will be rewritten below.
//
// This uses milliseconds since the start of the Unix epoch for
// expiration.
async function setOneDayUnsecuredCookieWithMillisecondsSinceEpoch() {
// one day ahead, ignoring a possible leap-second
let inTwentyFourHours = Date.now() + 24 * 60 * 60 * 1000;
await cookieStore.set('LEGACYCOOKIENAME', 'cookie-value', {
path: kPath,
expires: inTwentyFourHours,
secure: false,
domain: location.hostname
});
}
// Delete the cookie written by
// setOneDayUnsecuredCookieWithMillisecondsSinceEpoch.
async function deleteUnsecuredCookieWithDomainAndPath() {
await cookieStore.delete('LEGACYCOOKIENAME', {
path: kPath,
secure: false,
domain: location.hostname
});
}
cookie_test(async testCase => {
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
setOneDaySecureCookieWithDate(),
'Secure cookies only writable from secure contexts');
const eventPromise = observeNextCookieChangeEvent();
await setOneDayUnsecuredCookieWithMillisecondsSinceEpoch();
assert_equals(
await getCookieString('LEGACYCOOKIENAME'),
'LEGACYCOOKIENAME=cookie-value',
'Ensure unsecured cookie we set is visible');
await verifyCookieChangeEvent(
eventPromise,
{changed: [{name: 'LEGACYCOOKIENAME', value: 'cookie-value'}]},
'Ensure unsecured cookie we set is visible to observer');
await deleteUnsecuredCookieWithDomainAndPath();
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
setSecureCookieWithHttpLikeExpirationString(),
'Secure cookies only writable from secure contexts');
}, 'expiration');

View file

@ -0,0 +1,74 @@
'use strict';
cookie_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await cookieStore.set('TEST', 'value0');
assert_equals(
await getCookieString(),
'TEST=value0',
'Cookie jar contains only cookie we set');
assert_equals(
await getCookieStringHttp(),
'TEST=value0',
'HTTP cookie jar contains only cookie we set');
await verifyCookieChangeEvent(
eventPromise,
{changed: [{name: 'TEST', value: 'value0'}]},
'Observed value that was set');
eventPromise = observeNextCookieChangeEvent();
await cookieStore.set('TEST', 'value');
assert_equals(
await getCookieString(),
'TEST=value',
'Cookie jar contains only cookie we overwrote');
await verifyCookieChangeEvent(
eventPromise,
{changed: [{name: 'TEST', value: 'value'}]},
'Observed value that was overwritten');
let allCookies = await cookieStore.getAll();
assert_equals(
allCookies[0].name,
'TEST',
'First entry in allCookies should be named TEST');
assert_equals(
allCookies[0].value,
'value',
'First entry in allCookies should have value "value"');
assert_equals(
allCookies.length,
1,
'Only one cookie should exist in allCookies');
let firstCookie = await cookieStore.get();
assert_equals(
firstCookie.name,
'TEST',
'First cookie should be named TEST');
assert_equals(
firstCookie.value,
'value',
'First cookie should have value "value"');
let allCookies_TEST = await cookieStore.getAll('TEST');
assert_equals(
allCookies_TEST[0].name,
'TEST',
'First entry in allCookies_TEST should be named TEST');
assert_equals(
allCookies_TEST[0].value,
'value',
'First entry in allCookies_TEST should have value "value"');
assert_equals(
allCookies_TEST.length,
1,
'Only one cookie should exist in allCookies_TEST');
let firstCookie_TEST = await cookieStore.get('TEST');
assert_equals(
firstCookie_TEST.name,
'TEST',
'First TEST cookie should be named TEST');
assert_equals(
firstCookie_TEST.value,
'value',
'First TEST cookie should have value "value"');
}, 'Get/set/get all cookies in store');

View file

@ -0,0 +1,112 @@
'use strict';
cookie_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await setCookieStringHttp('HTTP-🍪=🔵; path=/');
assert_equals(
await getCookieString(),
'HTTP-🍪=🔵',
'Cookie we wrote using HTTP in cookie jar');
assert_equals(
await getCookieStringHttp(),
'HTTP-🍪=🔵',
'Cookie we wrote using HTTP in HTTP cookie jar');
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: 'HTTP-🍪', value: '🔵'}]},
'Cookie we wrote using HTTP is observed');
eventPromise = observeNextCookieChangeEvent();
await setCookieStringHttp('HTTP-🍪=DELETED; path=/; max-age=0');
assert_equals(
await getCookieString(),
undefined,
'Empty cookie jar after HTTP cookie-clearing using max-age=0');
assert_equals(
await getCookieStringHttp(),
undefined,
'Empty HTTP cookie jar after HTTP cookie-clearing using max-age=0');
await verifyCookieChangeEvent(
eventPromise, {deleted: [{name: 'HTTP-🍪'}]},
'Deletion observed after HTTP cookie-clearing using max-age=0');
await cookieStore.delete('HTTP-🍪');
}, 'Interoperability of HTTP Set-Cookie: with other APIs');
cookie_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await setCookieStringHttp('HTTPONLY-🍪=🔵; path=/; httponly');
assert_equals(
await getCookieString(),
undefined,
'HttpOnly cookie we wrote using HTTP in cookie jar' +
' is invisible to script');
assert_equals(
await getCookieStringHttp(),
'HTTPONLY-🍪=🔵',
'HttpOnly cookie we wrote using HTTP in HTTP cookie jar');
eventPromise = observeNextCookieChangeEvent();
await setCookieStringHttp(
'HTTPONLY-🍪=DELETED; path=/; max-age=0; httponly');
assert_equals(
await getCookieString(),
undefined,
'Empty cookie jar after HTTP cookie-clearing using max-age=0');
assert_equals(
await getCookieStringHttp(),
undefined,
'Empty HTTP cookie jar after HTTP cookie-clearing using max-age=0');
// HTTPONLY cookie changes should not have been observed; perform
// a dummy change to verify that nothing else was queued up.
await cookieStore.set('TEST', 'dummy');
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: 'TEST', value: 'dummy'}]},
'HttpOnly cookie deletion was not observed');
}, 'HttpOnly cookies are not observed');
cookie_test(async t => {
// Non-UTF-8 byte sequences cause the Set-Cookie to be dropped.
let eventPromise = observeNextCookieChangeEvent();
await setCookieBinaryHttp(
unescape(encodeURIComponent('HTTP-🍪=🔵')) + '\xef\xbf\xbd; path=/');
assert_equals(
await getCookieString(),
'HTTP-🍪=🔵\ufffd',
'Binary cookie we wrote using HTTP in cookie jar');
assert_equals(
await getCookieStringHttp(),
'HTTP-🍪=🔵\ufffd',
'Binary cookie we wrote using HTTP in HTTP cookie jar');
assert_equals(
decodeURIComponent(escape(await getCookieBinaryHttp())),
'HTTP-🍪=🔵\ufffd',
'Binary cookie we wrote in binary HTTP cookie jar');
assert_equals(
await getCookieBinaryHttp(),
unescape(encodeURIComponent('HTTP-🍪=🔵')) + '\xef\xbf\xbd',
'Binary cookie we wrote in binary HTTP cookie jar');
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: 'HTTP-🍪', value: '🔵\ufffd'}]},
'Binary cookie we wrote using HTTP is observed');
eventPromise = observeNextCookieChangeEvent();
await setCookieBinaryHttp(
unescape(encodeURIComponent('HTTP-🍪=DELETED; path=/; max-age=0')));
assert_equals(
await getCookieString(),
undefined,
'Empty cookie jar after binary HTTP cookie-clearing using max-age=0');
assert_equals(
await getCookieStringHttp(),
undefined,
'Empty HTTP cookie jar after' +
' binary HTTP cookie-clearing using max-age=0');
assert_equals(
await getCookieBinaryHttp(),
undefined,
'Empty binary HTTP cookie jar after' +
' binary HTTP cookie-clearing using max-age=0');
await verifyCookieChangeEvent(
eventPromise, {deleted: [{name: 'HTTP-🍪'}]},
'Deletion observed after binary HTTP cookie-clearing using max-age=0');
}, 'Binary HTTP cookies');

View file

@ -0,0 +1,45 @@
'use strict';
cookie_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await cookieStore.set('', 'first-value');
const actual1 =
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
const expected1 = 'first-value';
assert_equals(actual1, expected1);
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: '', value: 'first-value'}]},
'Observed no-name change');
eventPromise = observeNextCookieChangeEvent();
await cookieStore.set('', '');
const actual2 =
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
const expected2 = '';
assert_equals(actual2, expected2);
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: '', value: ''}]},
'Observed no-name change');
eventPromise = observeNextCookieChangeEvent();
await cookieStore.delete('');
await verifyCookieChangeEvent(
eventPromise, {deleted: [{name: ''}]},
'Observed no-name deletion');
assert_equals(
await getCookieString(),
undefined,
'Empty cookie jar');
assert_equals(
await getCookieStringHttp(),
undefined,
'Empty HTTP cookie jar');
if (kHasDocument) {
assert_equals(
await getCookieStringDocument(),
undefined,
'Empty document.cookie cookie jar');
}
}, 'Verify behavior of no-name and no-value cookies.');

View file

@ -0,0 +1,46 @@
'use strict';
cookie_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await cookieStore.set('', 'first-value');
const actual1 =
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
const expected1 = 'first-value';
assert_equals(actual1, expected1);
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: '', value: 'first-value'}]},
'Observed no-name change');
await promise_rejects(
t,
new TypeError(),
cookieStore.set('', 'suspicious-value=resembles-name-and-value'),
'Expected promise rejection when setting a cookie with' +
' no name and "=" in value');
const actual2 =
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
const expected2 = 'first-value';
assert_equals(actual2, expected2);
assert_equals(
await getCookieString(),
'first-value',
'Earlier cookie jar after rejected');
eventPromise = observeNextCookieChangeEvent();
await cookieStore.delete('');
await verifyCookieChangeEvent(
eventPromise, {deleted: [{name: '', value: ''}]},
'Observed no-name deletion');
assert_equals(
await getCookieString(),
undefined,
'Empty cookie jar after cleanup');
assert_equals(
await getCookieStringHttp(),
undefined,
'Empty HTTP cookie jar after cleanup');
}, "Verify that attempting to set a cookie with no name and with '=' in" +
" the value does not work.");

View file

@ -0,0 +1,38 @@
'use strict';
cookie_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await cookieStore.set('', 'first-value');
let actual1 =
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
let expected1 = 'first-value';
assert_equals(actual1, expected1);
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: '', value: 'first-value'}]},
'Observed no-name change');
eventPromise = observeNextCookieChangeEvent();
await cookieStore.set('', 'second-value');
let actual2 =
(await cookieStore.getAll('')).map(({ value }) => value).join(';');
let expected2 = 'second-value';
assert_equals(actual2, expected2);
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: '', value: 'second-value'}]},
'Observed no-name change');
eventPromise = observeNextCookieChangeEvent();
await cookieStore.delete('');
await verifyCookieChangeEvent(
eventPromise, {deleted: [{name: ''}]},
'Observed no-name change');
assert_equals(
await getCookieString(),
undefined,
'Empty cookie jar after testNoNameMultipleValues');
assert_equals(
await getCookieStringHttp(),
undefined,
'Empty HTTP cookie jar after testNoNameMultipleValues');
}, 'Verify behavior of multiple no-name cookies');

View file

@ -0,0 +1,57 @@
'use strict';
// Helper to verify first-of-name get using async/await.
//
// Returns the first script-visible value of the __Host-COOKIENAME cookie or
// undefined if no matching cookies are script-visible.
async function getOneSimpleOriginCookie() {
let cookie = await cookieStore.get('__Host-COOKIENAME');
if (!cookie) return undefined;
return cookie.value;
}
// Returns the number of script-visible cookies whose names start with
// __Host-COOKIEN
async function countMatchingSimpleOriginCookies() {
let cookieList = await cookieStore.getAll({
name: '__Host-COOKIEN',
matchType: 'startsWith'
});
return cookieList.length;
}
// Set the secure implicit-domain cookie __Host-COOKIENAME with value
// cookie-value on path / and session duration.
async function setOneSimpleOriginSessionCookie() {
await cookieStore.set('__Host-COOKIENAME', 'cookie-value');
};
cookie_test(async testCase => {
await promise_rejects_when_unsecured(
testCase,
new TypeError(),
setOneSimpleOriginSessionCookie(),
'__Host- prefix only writable from secure contexts');
if (!kIsUnsecured) {
assert_equals(
await getOneSimpleOriginCookie(),
'cookie-value',
'__Host-COOKIENAME cookie should be found in a secure context');
} else {
assert_equals(
await getOneSimpleOriginCookie(),
undefined,
'__Host-COOKIENAME cookie should not be found in an unsecured context');
}
if (kIsUnsecured) {
assert_equals(
await countMatchingSimpleOriginCookies(),
0,
'No __Host-COOKIEN* cookies should be found in an unsecured context');
} else {
assert_equals(
await countMatchingSimpleOriginCookies(),
1,
'One __Host-COOKIEN* cookie should be found in a secure context');
}
}, 'One simple origin cookie');

View file

@ -0,0 +1,41 @@
'use strict';
// TODO(jsbell): Does this test really need simple origin ('__Host-') cookies?
cookie_test(async t => {
await cookieStore.set('__Host-1🍪', '🔵cookie-value1🔴');
await cookieStore.set('__Host-2🌟', '🌠cookie-value2🌠');
await cookieStore.set('__Host-3🌱', '🔶cookie-value3🔷');
// NOTE: this assumes no concurrent writes from elsewhere; it also
// uses three separate cookie jar read operations where a single getAll
// would be more efficient, but this way the CookieStore does the filtering
// for us.
const matchingValues = await Promise.all([ '1🍪', '2🌟', '3🌱' ].map(
async suffix => (await cookieStore.get('__Host-' + suffix)).value));
const actual = matchingValues.join(';');
const expected = '🔵cookie-value1🔴;🌠cookie-value2🌠;🔶cookie-value3🔷';
assert_equals(actual, expected);
}, 'Set three simple origin session cookies sequentially and ensure ' +
'they all end up in the cookie jar in order.');
cookie_test(async t => {
await Promise.all([
cookieStore.set('__Host-unordered1🍪', '🔵unordered-cookie-value1🔴'),
cookieStore.set('__Host-unordered2🌟', '🌠unordered-cookie-value2🌠'),
cookieStore.set('__Host-unordered3🌱', '🔶unordered-cookie-value3🔷')
]);
// NOTE: this assumes no concurrent writes from elsewhere; it also
// uses three separate cookie jar read operations where a single getAll
// would be more efficient, but this way the CookieStore does the filtering
// for us and we do not need to sort.
const matchingCookies = await Promise.all([ '1🍪', '2🌟', '3🌱' ].map(
suffix => cookieStore.get('__Host-unordered' + suffix)));
const actual = matchingCookies.map(({ value }) => value).join(';');
const expected =
'🔵unordered-cookie-value1🔴;' +
'🌠unordered-cookie-value2🌠;' +
'🔶unordered-cookie-value3🔷';
assert_equals(actual, expected);
}, 'Set three simple origin session cookies in undefined order using ' +
'Promise.all and ensure they all end up in the cookie jar in any ' +
'order. ');

View file

@ -0,0 +1,46 @@
cookie_test(async t => {
const theVeryRecentPast = Date.now();
const expiredCookieSentinelValue = 'EXPIRED';
await promise_rejects_when_unsecured(
t,
new TypeError(),
cookieStore.set('__Secure-COOKIENAME', expiredCookieSentinelValue, {
path: kPath,
expires: theVeryRecentPast,
secure: true,
domain: location.hostname
}),
'Secure cookies only writable from secure contexts');
}, 'Set an already-expired secure cookie');
['__Host-', '__Secure-'].forEach(prefix => {
cookie_test(async t => {
const name = prefix + 'COOKIENAME';
const value = 'cookie-value';
await promise_rejects_when_unsecured(
t,
new TypeError(),
cookieStore.set(name, value),
`Setting ${prefix} cookies should fail in non-secure contexts`);
// Getting does not produce an exception, even in non-secure contexts.
const pair = await cookieStore.get(name);
if (kIsUnsecured) {
assert_equals(pair, null);
} else {
assert_equals(pair.value, value);
}
await promise_rejects_when_unsecured(
t,
new TypeError(),
cookieStore.delete(name),
`Deleting ${prefix} cookies should fail in non-secure contexts`);
assert_equals(await cookieStore.get(name), null);
}, `${prefix} cookies only writable from secure context`);
});

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Async Cookies: __Secure- and __Host- cookies</title>
<meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/cookie-test-helpers.js"></script>
<script src="resources/secure_cookies.js"></script>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Async Cookies: __Secure- and __Host- cookies (HTTPS)</title>
<meta name="help" href="https://github.com/WICG/cookie-store/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/cookie-test-helpers.js"></script>
<script src="resources/secure_cookies.js"></script>

View file

@ -0,0 +1,95 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage margins</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a fixed size track).">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: 100px;
width: 500px;
justify-items: start;
position: relative;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 100%;
height: 10px;
}
.marginLeft50Percent { margin-left: 50%; }
.marginRight50Percent { margin-right: 50%; }
.marginTop50Percent { margin-top: 50%; }
.marginBottom50Percent { margin-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid directionRTL">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="490" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid directionRTL">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="440" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid directionRTL">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>

View file

@ -0,0 +1,95 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage margins</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min).">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: minmax(auto, 100px);
width: 500px;
justify-items: start;
position: relative;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 100%;
height: 10px;
}
.marginLeft50Percent { margin-left: 50%; }
.marginRight50Percent { margin-right: 50%; }
.marginTop50Percent { margin-top: 50%; }
.marginBottom50Percent { margin-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid directionRTL">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="490" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid directionRTL">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="440" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid directionRTL">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-lr</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a fixed size track) in a vertical-lr grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: 100px;
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-lr;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.marginLeft50Percent { margin-left: 50%; }
.marginRight50Percent { margin-right: 50%; }
.marginTop50Percent { margin-top: 50%; }
.marginBottom50Percent { margin-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid directionRTL">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid directionRTL">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid directionRTL">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="490" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="440" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-lr</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-lr grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: minmax(auto, 100px);
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-lr;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.marginLeft50Percent { margin-left: 50%; }
.marginRight50Percent { margin-right: 50%; }
.marginTop50Percent { margin-top: 50%; }
.marginBottom50Percent { margin-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid directionRTL">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid directionRTL">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid directionRTL">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="490" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="440" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-rl</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a fixed size track) in a vertical-rl grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: 100px;
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-rl;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.marginLeft50Percent { margin-left: 50%; }
.marginRight50Percent { margin-right: 50%; }
.marginTop50Percent { margin-top: 50%; }
.marginBottom50Percent { margin-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="60" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="10" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid directionRTL">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-expected-x="60" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid directionRTL">
<div class="marginRight50Percent" data-expected-margin-right="50" data-expected-x="10" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid directionRTL">
<div class="marginTop50Percent" data-expected-margin-top="50" data-expected-y="490" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-expected-y="440" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage margins vertical-rl</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage margins are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-rl grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: minmax(auto, 100px);
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-rl;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.marginLeft50Percent { margin-left: 50%; }
.marginRight50Percent { margin-right: 50%; }
.marginTop50Percent { margin-top: 50%; }
.marginBottom50Percent { margin-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-offset-x="60" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid">
<div class="marginRight50Percent" data-expected-margin-right="50" data-offset-x="10" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid">
<div class="marginTop50Percent" data-expected-margin-top="50" data-offset-y="50" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-offset-y="0" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item margin-left: 50%;</pre>
<div class="grid directionRTL">
<div class="marginLeft50Percent" data-expected-margin-left="50" data-expected-x="60" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-right: 50%;</pre>
<div class="grid directionRTL">
<div class="marginRight50Percent" data-expected-margin-right="50" data-expected-x="10" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-top: 50%;</pre>
<div class="grid directionRTL">
<div class="marginTop50Percent" data-expected-margin-top="50" data-expected-y="490" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item margin-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="marginBottom50Percent" data-expected-margin-bottom="50" data-expected-y="440" data-expected-width="10" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -0,0 +1,95 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage paddings</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a fixed size track).">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: 100px;
width: 500px;
justify-items: start;
position: relative;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 100%;
height: 10px;
}
.paddingLeft50Percent { padding-left: 50%; }
.paddingRight50Percent { padding-right: 50%; }
.paddingTop50Percent { padding-top: 50%; }
.paddingBottom50Percent { padding-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>

View file

@ -0,0 +1,95 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage paddings</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min).">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: minmax(auto, 100px);
width: 500px;
justify-items: start;
position: relative;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 100%;
height: 10px;
}
.paddingLeft50Percent { padding-left: 50%; }
.paddingRight50Percent { padding-right: 50%; }
.paddingTop50Percent { padding-top: 50%; }
.paddingBottom50Percent { padding-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="400" data-offset-y="10" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="400" data-offset-y="60" data-expected-width="100" data-expected-height="10"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-lr</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a fixed size track) in a vertical-lr grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: 100px;
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-lr;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.paddingLeft50Percent { padding-left: 50%; }
.paddingRight50Percent { padding-right: 50%; }
.paddingTop50Percent { padding-top: 50%; }
.paddingBottom50Percent { padding-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-lr</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-lr grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: minmax(auto, 100px);
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-lr;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.paddingLeft50Percent { padding-left: 50%; }
.paddingRight50Percent { padding-right: 50%; }
.paddingTop50Percent { padding-top: 50%; }
.paddingBottom50Percent { padding-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="60" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="10" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-rl</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a fixed size track) in a vertical-rl grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: 100px;
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-rl;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.paddingLeft50Percent { padding-left: 50%; }
.paddingRight50Percent { padding-right: 50%; }
.paddingTop50Percent { padding-top: 50%; }
.paddingBottom50Percent { padding-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -0,0 +1,96 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>CSS Grid Layout Test: Grid items with percentage paddings vertical-rl</title>
<link rel="author" title="Manuel Rego Casasnovas" href="mailto:rego@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#item-margins">
<meta name="assert" content="Checks grid items percentage paddings are resolved against the inline size of their grid area (in a track with fixed max sizing function and intrinsic min) in a vertical-rl grid container.">
<link rel="stylesheet" href="support/grid.css">
<style>
.grid {
font: 10px/1 Ahem;
grid-template-columns: minmax(auto, 100px);
height: 500px;
justify-items: start;
position: relative;
writing-mode: vertical-rl;
}
.grid > div:nth-child(1) { background: cyan; }
.grid > div:nth-child(2) {
background: magenta;
width: 10px;
height: 100%;
}
.paddingLeft50Percent { padding-left: 50%; }
.paddingRight50Percent { padding-right: 50%; }
.paddingTop50Percent { padding-top: 50%; }
.paddingBottom50Percent { padding-bottom: 50%; }
</style>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/check-layout-th.js"></script>
<body onload="checkLayout('.grid')">
<div id="log"></div>
<h3>Direction LTR</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="0" data-expected-width="10" data-expected-height="100"></div>
</div>
<h3>Direction RTL</h3>
<pre>Item padding-left: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingLeft50Percent" data-expected-padding-left="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-right: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingRight50Percent" data-expected-padding-right="50" data-expected-width="60" data-expected-height="10">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-top: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingTop50Percent" data-expected-padding-top="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>
<pre>Item padding-bottom: 50%;</pre>
<div class="grid directionRTL">
<div class="paddingBottom50Percent" data-expected-padding-bottom="50" data-expected-width="10" data-expected-height="60">X</div>
<div data-offset-x="0" data-offset-y="400" data-expected-width="10" data-expected-height="100"></div>
</div>

View file

@ -84,10 +84,9 @@
assert_readonly(styleSheet, "parentStyleSheet"); assert_readonly(styleSheet, "parentStyleSheet");
assert_readonly(styleSheet, "href"); assert_readonly(styleSheet, "href");
assert_readonly(styleSheet, "title"); assert_readonly(styleSheet, "title");
assert_readonly(styleSheet, "media");
}, "StyleSheet_properties", }, "StyleSheet_properties",
{ assert: [ "type, disabled, ownerNode, parentStyleSheet, href, title, and media properties exist on StyleSheet", { assert: [ "type, disabled, ownerNode, parentStyleSheet, href, title, and media properties exist on StyleSheet",
"type, ownerNode, parentStyleSheet, href, title, media properties are read only" ] }); "type, ownerNode, parentStyleSheet, href, and title properties are read only" ] });
test(function() { test(function() {
assert_equals(styleSheet.type, "text/css"); assert_equals(styleSheet.type, "text/css");

View file

@ -145,10 +145,13 @@ test(() => {
customElements.upgrade(template.content); customElements.upgrade(template.content);
assert_true(el1 instanceof Element1, "element 1 must now be upgraded"); // Template contents owner documents don't have a browsing context, so
assert_true(el2 instanceof Element2, "element 2 must now be upgraded"); // https://html.spec.whatwg.org/multipage/custom-elements.html#look-up-a-custom-element-definition does not find any
assert_true(el3 instanceof Element3, "element 3 must now be upgraded"); // custom element definition.
assert_true(el4 instanceof Element4, "element 4 must now be upgraded"); assert_false(el1 instanceof Element1, "element 1 must still not be upgraded after upgrading the template contents");
assert_true(el5 instanceof Element5, "element 5 must now be upgraded"); assert_false(el2 instanceof Element2, "element 2 must still not be upgraded after upgrading the template contents");
assert_false(el3 instanceof Element3, "element 3 must still not be upgraded after upgrading the template contents");
assert_false(el4 instanceof Element4, "element 4 must still not be upgraded after upgrading the template contents");
assert_false(el5 instanceof Element5, "element 5 must still not be upgraded after upgrading the template contents");
}, "Elements inside a template contents DocumentFragment node"); }, "Elements inside a template contents DocumentFragment node");
</script> </script>

View file

@ -5,6 +5,7 @@
<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org"> <meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
<meta name="assert" content="HTML parser must set the attributes and append the children on a custom element"> <meta name="assert" content="HTML parser must set the attributes and append the children on a custom element">
<link rel="help" href="https://html.spec.whatwg.org/#create-an-element-for-the-token"> <link rel="help" href="https://html.spec.whatwg.org/#create-an-element-for-the-token">
<link rel="help" href="https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element">
<link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element"> <link rel="help" href="https://dom.spec.whatwg.org/#concept-create-element">
<script src="/resources/testharness.js"></script> <script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script> <script src="/resources/testharnessreport.js"></script>
@ -14,8 +15,10 @@
<div id="log"></div> <div id="log"></div>
<script> <script>
var numberOfAttributesInConstructor; var numberOfAttributesInConstructor = 0;
var numberOfChildNodesInConstructor; var numberOfChildNodesInConstructor = 0;
var numberOfChildNodesInAttributeChangedCallback = 0;
var numberOfChildNodesInConnectedCallback = 0;
var attributesChangedCalls = []; var attributesChangedCalls = [];
class MyCustomElement extends HTMLElement { class MyCustomElement extends HTMLElement {
@ -27,11 +30,16 @@ class MyCustomElement extends HTMLElement {
attributeChangedCallback(...args) { attributeChangedCallback(...args) {
attributesChangedCalls.push(create_attribute_changed_callback_log(this, ...args)); attributesChangedCalls.push(create_attribute_changed_callback_log(this, ...args));
numberOfChildNodesInAttributeChangedCallback = this.childNodes.length;
} }
static get observedAttributes() { static get observedAttributes() {
return ['id', 'class']; return ['id', 'class'];
} }
connectedCallback() {
numberOfChildNodesInConnectedCallback = this.childNodes.length;
}
}; };
customElements.define('my-custom-element', MyCustomElement); customElements.define('my-custom-element', MyCustomElement);
@ -64,10 +72,22 @@ test(function () {
assert_equals(numberOfChildNodesInConstructor, 0, 'HTML parser must not append child nodes to a custom element before invoking the constructor'); assert_equals(numberOfChildNodesInConstructor, 0, 'HTML parser must not append child nodes to a custom element before invoking the constructor');
}, 'HTML parser must set the attributes or append children before calling constructor'); }, 'HTML parser must set the attributes or append children before calling constructor');
test(function () {
// https://html.spec.whatwg.org/multipage/parsing.html#insert-a-foreign-element
// 3.3. Pop the element queue from the custom element reactions
// stack, and invoke custom element reactions in that queue.
assert_equals(numberOfChildNodesInConnectedCallback, 0);
}, 'HTML parser should call connectedCallback before appending child nodes.');
test(function () { test(function () {
assert_equals(attributesChangedCalls.length, 2); assert_equals(attributesChangedCalls.length, 2);
assert_attribute_log_entry(attributesChangedCalls[0], {name: 'id', oldValue: null, newValue: 'custom-element-id', namespace: null}); assert_attribute_log_entry(attributesChangedCalls[0], {name: 'id', oldValue: null, newValue: 'custom-element-id', namespace: null});
assert_attribute_log_entry(attributesChangedCalls[1], {name: 'class', oldValue: null, newValue: 'class1 class2', namespace: null}); assert_attribute_log_entry(attributesChangedCalls[1], {name: 'class', oldValue: null, newValue: 'class1 class2', namespace: null});
// https://html.spec.whatwg.org/multipage/parsing.html#create-an-element-for-the-token
// 9.2. Invoke custom element reactions in queue.
assert_equals(numberOfChildNodesInAttributeChangedCallback, 0,
'attributeChangedCallback should be called ' +
'before appending a child');
}, 'HTML parser must enqueue attributeChanged reactions'); }, 'HTML parser must enqueue attributeChanged reactions');
</script> </script>

View file

@ -0,0 +1,75 @@
<!-- Test verifies that cross-origin, nosniff images are 1) blocked when their
MIME type is covered by CORB and 2) allowed otherwise.
This test is very similar to fetch/nosniff/images.html, except that
1) it deals with cross-origin images (CORB ignores same-origin fetches),
2) it focuses on MIME types relevant to CORB.
There are opportunities to unify the test here with nosniff tests *if*
we can also start blocking same-origin (or cors-allowed) images. We
should try to gather data to quantify the impact of such change.
-->
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
var passes = [
// Empty or non-sensical MIME types
null, "", "x", "x/x",
// MIME-types not protected by CORB
"image/gif", "image/png", "image/png;blah", "image/svg+xml",
"application/javascript", "application/jsonp",
// MIME types that may seem to be JSON or XML, but really aren't - i.e.
// these MIME types are not covered by:
// - https://mimesniff.spec.whatwg.org/#json-mime-type
// - https://mimesniff.spec.whatwg.org/#xml-mime-type
// - https://tools.ietf.org/html/rfc6839
// - https://tools.ietf.org/html/rfc7303
"text/x-json", "text/json+blah", "application/json+blah",
"text/xml+blah", "application/xml+blah",
"application/blahjson", "text/blahxml",
var fails = [
// CORB-protected MIME-types - i.e. ones covered by:
// - https://mimesniff.spec.whatwg.org/#html-mime-type
// - https://mimesniff.spec.whatwg.org/#json-mime-type
// - https://mimesniff.spec.whatwg.org/#xml-mime-type
"text/html",
"text/json", "application/json", "text/xml", "application/xml",
"application/blah+json", "text/blah+json",
"application/blah+xml", "text/blah+xml",
"TEXT/HTML", "TEXT/JSON", "TEXT/BLAH+JSON", "APPLICATION/BLAH+XML"]
const get_url = (mime) => {
// www1 is cross-origin, so the HTTP response is CORB-eligible -->
url = "http://{{domains[www1]}}:{{ports[http][0]}}"
url = url + "/fetch/nosniff/resources/image.py"
if (mime != null) {
url += "?type=" + encodeURIComponent(mime)
}
return url
}
passes.forEach(function(mime) {
async_test(function(t) {
var img = document.createElement("img")
img.onerror = t.unreached_func("Unexpected error event")
img.onload = t.step_func_done(function(){
assert_equals(img.width, 96)
})
img.src = get_url(mime)
document.body.appendChild(img)
}, "CORB should allow the response if Content-Type is: '" + mime + "'. ")
})
fails.forEach(function(mime) {
async_test(function(t) {
var img = document.createElement("img")
img.onerror = t.step_func_done()
img.onload = t.unreached_func("Unexpected load event")
img.src = get_url(mime)
document.body.appendChild(img)
}, "CORB should block the response if Content-Type is: '" + mime + "'. ")
})
</script>

View file

@ -0,0 +1,24 @@
<!DOCTYPE html>
<!-- This test verifies observable CORB impact on <link rel="preload"> elements.
-->
<meta charset="utf-8">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<div id=log></div>
<script>
async_test(function(t) {
// With CORB the link.onerror event will be reached
// (because CORB will block the cross-origin preload).
window.preloadErrorEvent = t.step_func_done();
// Without CORB the link.onload event will be reached.
window.preloadLoadEvent = t.unreached_func("link/preload onload event reached.");
});
</script>
<!-- www1 is cross-origin, so the HTTP response is CORB-eligible -->
<link rel="preload" as="image"
onerror="window.preloadErrorEvent()"
onload="window.preloadLoadEvent()"
href="http://{{domains[www1]}}:{{ports[http][0]}}/fetch/corb/resources/png-mislabeled-as-html-nosniff.png">

View file

@ -3,7 +3,19 @@
<div id=log></div> <div id=log></div>
<script> <script>
// Note: images get always sniffed, nosniff doesn't do anything // Note: images get always sniffed, nosniff doesn't do anything
var passes = [null, "", "x", "x/x", "image/gif", "image/png", "image/png;blah"] // (but note the tentative Cross-Origin Read Blocking (CORB) tests
// - for example wpt/fetch/corb/img-mime-types-coverage.tentative.sub.html).
var passes = [
// Empty or non-sensical MIME types
null, "", "x", "x/x",
// Image MIME types
"image/gif", "image/png", "image/png;blah", "image/svg+xml",
// CORB-protected MIME types (but note that CORB doesn't apply here,
// because CORB ignores same-origin requests).
"text/html", "application/xml", "application/blah+xml"
]
const get_url = (mime) => { const get_url = (mime) => {
let url = "resources/image.py" let url = "resources/image.py"

View file

@ -3,7 +3,13 @@ import os.path
def main(request, response): def main(request, response):
type = request.GET.first("type", None) type = request.GET.first("type", None)
body = open(os.path.join(os.path.dirname(__file__), "../../../images/blue96x96.png"), "rb").read() if type != None and "svg" in type:
filename = "green-96x96.svg"
else:
filename = "blue96x96.png"
path = os.path.join(os.path.dirname(__file__), "../../../images", filename)
body = open(path, "rb").read()
response.add_required_headers = False response.add_required_headers = False
response.writer.write_status(200) response.writer.write_status(200)

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="96" height="96">
<rect fill="lime" width="96" height="96"/>
</svg>

After

Width:  |  Height:  |  Size: 116 B

View file

@ -0,0 +1,41 @@
<!DOCTYPE html>
<title>Service Worker: Synchronous XHR on Worker is intercepted</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/test-helpers.sub.js"></script>
<script>
'use strict';
promise_test((t) => {
const url = 'resources/fetch-request-xhr-sync-on-worker-worker.js';
const scope = 'resources/fetch-request-xhr-sync-on-worker-scope/';
const non_existent_file = 'non-existent-file.txt';
// In Chromium, the service worker scope matching for workers is based on
// the URL of the parent HTML. So this test creates an iframe which is
// controlled by the service worker first, and creates a worker from the
// iframe.
return service_worker_unregister_and_register(t, url, scope)
.then((registration) => {
t.add_cleanup(() => registration.unregister());
return wait_for_state(t, registration.installing, 'activated');
})
.then(() => { return with_iframe(scope + 'iframe_page'); })
.then((frame) => {
t.add_cleanup(() => frame.remove());
return frame.contentWindow.performSyncXHROnWorker(non_existent_file);
})
.then((result) => {
assert_equals(
result.status,
200,
'HTTP response status code for intercepted request'
);
assert_equals(
result.responseText,
'Response from service worker',
'HTTP response text for intercepted request'
);
});
}, 'Verify SyncXHR on Worker is intercepted');
</script>

View file

@ -0,0 +1,41 @@
'use strict';
self.onfetch = function(event) {
if (event.request.url.indexOf('non-existent-file.txt') !== -1) {
event.respondWith(new Response('Response from service worker'));
} else if (event.request.url.indexOf('/iframe_page') !== -1) {
event.respondWith(new Response(
'<!DOCTYPE html>\n' +
'<script>\n' +
'function performSyncXHROnWorker(url) {\n' +
' return new Promise((resolve) => {\n' +
' var worker =\n' +
' new Worker(\'./worker_script\');\n' +
' worker.addEventListener(\'message\', (msg) => {\n' +
' resolve(msg.data);\n' +
' });\n' +
' worker.postMessage({\n' +
' url: url\n' +
' });\n' +
' });\n' +
'}\n' +
'</script>',
{
headers: [['content-type', 'text/html']]
}));
} else if (event.request.url.indexOf('/worker_script') !== -1) {
event.respondWith(new Response(
'self.onmessage = (msg) => {' +
' const syncXhr = new XMLHttpRequest();' +
' syncXhr.open(\'GET\', msg.data.url, false);' +
' syncXhr.send();' +
' self.postMessage({' +
' status: syncXhr.status,' +
' responseText: syncXhr.responseText' +
' });' +
'}',
{
headers: [['content-type', 'application/javascript']]
}));
}
};