mirror of
https://github.com/servo/servo.git
synced 2025-08-04 05:00:08 +01:00
Update web-platform-tests to revision 3678c44dfe811f93a796285e9531ee34d7d15682
This commit is contained in:
parent
6fbf2c1e3c
commit
b3ccbe1a35
27 changed files with 808 additions and 100 deletions
|
@ -14773,6 +14773,18 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"payment-request/show-method-optional-promise-rejects-manual.https.html": [
|
||||||
|
[
|
||||||
|
"/payment-request/show-method-optional-promise-rejects-manual.https.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"payment-request/show-method-optional-promise-resolves-manual.https.html": [
|
||||||
|
[
|
||||||
|
"/payment-request/show-method-optional-promise-resolves-manual.https.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"payment-request/updateWith-method-pmi-handling-manual.https.html": [
|
"payment-request/updateWith-method-pmi-handling-manual.https.html": [
|
||||||
[
|
[
|
||||||
"/payment-request/updateWith-method-pmi-handling-manual.https.html",
|
"/payment-request/updateWith-method-pmi-handling-manual.https.html",
|
||||||
|
@ -306060,7 +306072,9 @@
|
||||||
"acid/acid3/numbered-tests.html": [
|
"acid/acid3/numbered-tests.html": [
|
||||||
[
|
[
|
||||||
"/acid/acid3/numbered-tests.html",
|
"/acid/acid3/numbered-tests.html",
|
||||||
{}
|
{
|
||||||
|
"timeout": "long"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"ambient-light/AmbientLightSensor-disabled-by-feature-policy.https.html": [
|
"ambient-light/AmbientLightSensor-disabled-by-feature-policy.https.html": [
|
||||||
|
@ -316219,12 +316233,6 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
"css/css-typed-om/the-stylepropertymap/properties/whitespace.html": [
|
|
||||||
[
|
|
||||||
"/css/css-typed-om/the-stylepropertymap/properties/whitespace.html",
|
|
||||||
{}
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"css/css-typed-om/the-stylepropertymap/properties/width.html": [
|
"css/css-typed-om/the-stylepropertymap/properties/width.html": [
|
||||||
[
|
[
|
||||||
"/css/css-typed-om/the-stylepropertymap/properties/width.html",
|
"/css/css-typed-om/the-stylepropertymap/properties/width.html",
|
||||||
|
@ -389401,7 +389409,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"./.travis.yml": [
|
"./.travis.yml": [
|
||||||
"975f331eb3438e5b66ccd721e1afce796b6af0d5",
|
"82073bf454e8b5bd5466222849d0f123f550c1a2",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"./CONTRIBUTING.md": [
|
"./CONTRIBUTING.md": [
|
||||||
|
@ -396941,7 +396949,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"acid/acid3/numbered-tests.html": [
|
"acid/acid3/numbered-tests.html": [
|
||||||
"b715328b9b59f27f51c070011528d29103783f42",
|
"24baf04e2bd2516aad4189950d768a368c495b13",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"acid/acid3/reference.png": [
|
"acid/acid3/reference.png": [
|
||||||
|
@ -479577,7 +479585,7 @@
|
||||||
"manual"
|
"manual"
|
||||||
],
|
],
|
||||||
"css/build-css-testsuites.sh": [
|
"css/build-css-testsuites.sh": [
|
||||||
"97cc415658e55acdc98c10db219bd832abf37ca5",
|
"0f1d955402449b61d134265ea5962d6ed93836f4",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"css/compositing/Blending_in_a_group_with_filter-ref.html": [
|
"css/compositing/Blending_in_a_group_with_filter-ref.html": [
|
||||||
|
@ -520205,10 +520213,6 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"css/css-typed-om/the-stylepropertymap/properties/white-space.html": [
|
"css/css-typed-om/the-stylepropertymap/properties/white-space.html": [
|
||||||
"f8afed394e920abbaa9eb8d2e6f4405ae4453c2c",
|
|
||||||
"testharness"
|
|
||||||
],
|
|
||||||
"css/css-typed-om/the-stylepropertymap/properties/whitespace.html": [
|
|
||||||
"b51dea7a7d0f93f13fda93c0f27e5084fa4c3b3e",
|
"b51dea7a7d0f93f13fda93c0f27e5084fa4c3b3e",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
|
@ -531897,7 +531901,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"css/requirements.txt": [
|
"css/requirements.txt": [
|
||||||
"d62efcaa0e8ba6782088f0468774a935e4461e73",
|
"8a4e55be1e7e92dd25d87976c92098294a7cc04d",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"css/selectors/CHANGES": [
|
"css/selectors/CHANGES": [
|
||||||
|
@ -534013,7 +534017,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"css/tools/w3ctestlib/Sources.py": [
|
"css/tools/w3ctestlib/Sources.py": [
|
||||||
"36436dff53c614783778a373223c07be4f70fc1d",
|
"082c7b33d16c1a109894293d495f83b21c15c21b",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"css/tools/w3ctestlib/Suite.py": [
|
"css/tools/w3ctestlib/Suite.py": [
|
||||||
|
@ -572541,7 +572545,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"notifications/interfaces.html": [
|
"notifications/interfaces.html": [
|
||||||
"0a653fc93d0d01761fb642d426461130134d9cbf",
|
"95c5c3bb1e952c4adec92c65f7d09f147b119c9c",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"notifications/lang.html": [
|
"notifications/lang.html": [
|
||||||
|
@ -579076,6 +579080,14 @@
|
||||||
"db68756c6cc3cc2146f608a04988cd938a2dd0de",
|
"db68756c6cc3cc2146f608a04988cd938a2dd0de",
|
||||||
"manual"
|
"manual"
|
||||||
],
|
],
|
||||||
|
"payment-request/show-method-optional-promise-rejects-manual.https.html": [
|
||||||
|
"62542519059ab38ee0753deff5e7e6e587f8adbf",
|
||||||
|
"manual"
|
||||||
|
],
|
||||||
|
"payment-request/show-method-optional-promise-resolves-manual.https.html": [
|
||||||
|
"cc65cc042e4eca1c6e70aa2fcc1f48b6ea0e1fa0",
|
||||||
|
"manual"
|
||||||
|
],
|
||||||
"payment-request/updateWith-method-pmi-handling-manual.https.html": [
|
"payment-request/updateWith-method-pmi-handling-manual.https.html": [
|
||||||
"b473073ad106e9e0732adb6bfbed5f54d6ec3194",
|
"b473073ad106e9e0732adb6bfbed5f54d6ec3194",
|
||||||
"manual"
|
"manual"
|
||||||
|
@ -591825,7 +591837,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"streams/piping/close-propagation-forward.js": [
|
"streams/piping/close-propagation-forward.js": [
|
||||||
"0af3e390230c35baf08ef8c97ffcccc7a7304b3b",
|
"7840ff0fabf15c8c86b91fbc57a8fca105af4c91",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"streams/piping/close-propagation-forward.serviceworker.https.html": [
|
"streams/piping/close-propagation-forward.serviceworker.https.html": [
|
||||||
|
@ -591865,7 +591877,7 @@
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"streams/piping/error-propagation-forward.js": [
|
"streams/piping/error-propagation-forward.js": [
|
||||||
"2cd0c4476388f6a6fd104f1e00e08bf2fe8706bb",
|
"eb8e24af040ea6c09e5fe6754ef942af5dc4b46e",
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"streams/piping/error-propagation-forward.serviceworker.https.html": [
|
"streams/piping/error-propagation-forward.serviceworker.https.html": [
|
||||||
|
@ -604561,7 +604573,7 @@
|
||||||
"support"
|
"support"
|
||||||
],
|
],
|
||||||
"workers/data-url-shared.html": [
|
"workers/data-url-shared.html": [
|
||||||
"7fae8fa78f0e66ffa8cf0dd1bf3e887fae349e4e",
|
"2414958d6e5635c8093b8d677636d30ca9fee5fe",
|
||||||
"testharness"
|
"testharness"
|
||||||
],
|
],
|
||||||
"workers/data-url.html": [
|
"workers/data-url.html": [
|
||||||
|
|
|
@ -2,4 +2,3 @@
|
||||||
type: reftest
|
type: reftest
|
||||||
expected:
|
expected:
|
||||||
if os == "linux": FAIL
|
if os == "linux": FAIL
|
||||||
|
|
||||||
|
|
|
@ -2,4 +2,3 @@
|
||||||
type: reftest
|
type: reftest
|
||||||
expected:
|
expected:
|
||||||
if os == "linux": FAIL
|
if os == "linux": FAIL
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
[vh_not_refreshing_on_chrome.html]
|
||||||
|
expected: FAIL
|
|
@ -1,4 +1,3 @@
|
||||||
[border-image-linear-gradient.html]
|
[border-image-linear-gradient.html]
|
||||||
type: reftest
|
type: reftest
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
[hide_after_load.html]
|
|
||||||
expected: TIMEOUT
|
|
|
@ -1,6 +1,5 @@
|
||||||
[shader-with-non-reserved-words.html]
|
[shader-with-non-reserved-words.html]
|
||||||
type: testharness
|
type: testharness
|
||||||
expected: TIMEOUT
|
|
||||||
[WebGL test #1696: shader with: 'dmat2' failed to compile]
|
[WebGL test #1696: shader with: 'dmat2' failed to compile]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -145,6 +144,3 @@
|
||||||
[WebGL test #1862: shader with: 'dmat4x4' failed to compile]
|
[WebGL test #1862: shader with: 'dmat4x4' failed to compile]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[Overall test]
|
|
||||||
expected: NOTRUN
|
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ addons:
|
||||||
jwt:
|
jwt:
|
||||||
secure: N9lvgkqUPtFlz6Vpa6qTPFhymEsDCsbaCsT64/hj3vlHRxK94r5+ugVJ3zm99zC0q2j1ish8yJC7mN/W4wRfBE4sAwmdxrlowxF1DDGCkaLE9i/GWW92s0fBVGJmXLh8kwNkQ31hMOsaGfHIMpeLFS7Se741te7YqsHIzmBCdQs=
|
secure: N9lvgkqUPtFlz6Vpa6qTPFhymEsDCsbaCsT64/hj3vlHRxK94r5+ugVJ3zm99zC0q2j1ish8yJC7mN/W4wRfBE4sAwmdxrlowxF1DDGCkaLE9i/GWW92s0fBVGJmXLh8kwNkQ31hMOsaGfHIMpeLFS7Se741te7YqsHIzmBCdQs=
|
||||||
before_install:
|
before_install:
|
||||||
|
# This needs be sourced as it sets various env vars
|
||||||
- . ./tools/ci/before_install.sh
|
- . ./tools/ci/before_install.sh
|
||||||
install:
|
install:
|
||||||
- ./tools/ci/install.sh
|
- ./tools/ci/install.sh
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<title>Acid3 numbered tests</title>
|
<title>Acid3 numbered tests</title>
|
||||||
|
<meta name="timeout" content="long">
|
||||||
<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>
|
<script>
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
set -ex
|
set -ex
|
||||||
|
|
||||||
SCRIPT_DIR=$(dirname $(readlink -f "$0"))
|
SCRIPT_DIR=$(dirname $(readlink -f "$0"))
|
||||||
WPT_ROOT=$(readlink -f $SCRIPT_DIR/../..)
|
WPT_ROOT=$(readlink -f $SCRIPT_DIR/..)
|
||||||
cd $WPT_ROOT
|
cd $WPT_ROOT
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
cd css
|
cd $WPT_ROOT/css
|
||||||
|
|
||||||
if [ -z $VENV ]; then
|
if [ -z $VENV ]; then
|
||||||
VENV=tools/_virtualenv
|
VENV=tools/_virtualenv
|
||||||
|
@ -41,17 +41,14 @@ main() {
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
$VENV/bin/pip install -r requirements.txt
|
$VENV/bin/pip install -r requirements.txt
|
||||||
|
|
||||||
# Fetch hg submodules if they're not there
|
# Error if submodules are not there
|
||||||
if [ ! -d tools/apiclient ]; then
|
if [ ! -d tools/apiclient -o ! -d tools/w3ctestlib ]; then
|
||||||
$VENV/bin/hg clone https://hg.csswg.org/dev/apiclient tools/apiclient
|
echo 'Please run `git submodule update --init --recursive`'
|
||||||
fi
|
exit 1
|
||||||
|
|
||||||
if [ ! -d tools/w3ctestlib ]; then
|
|
||||||
$VENV/bin/hg clone https://hg.csswg.org/dev/w3ctestlib tools/w3ctestlib
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run the build script
|
# Run the build script
|
||||||
$VENV/bin/python tools/build.py "$@"
|
$VENV/bin/python tools/build.py "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
main
|
main "$@"
|
||||||
|
|
|
@ -15,8 +15,10 @@
|
||||||
|
|
||||||
runPropertyTests('white-space', [
|
runPropertyTests('white-space', [
|
||||||
{ syntax: 'normal'},
|
{ syntax: 'normal'},
|
||||||
{ syntax: 'nowrap' }
|
{ syntax: 'pre' },
|
||||||
// and other keywords
|
{ syntax: 'nowrap' },
|
||||||
|
{ syntax: 'pre-wrap' },
|
||||||
|
{ syntax: 'pre-line' },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
<!doctype html>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>'white-space' property</title>
|
|
||||||
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-get">
|
|
||||||
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#dom-stylepropertymap-set">
|
|
||||||
<link rel="help" href="https://drafts.css-houdini.org/css-typed-om-1/#property-stle-value-normalization">
|
|
||||||
<script src="/resources/testharness.js"></script>
|
|
||||||
<script src="/resources/testharnessreport.js"></script>
|
|
||||||
<script src="../../resources/testhelper.js"></script>
|
|
||||||
<script src="resources/testsuite.js"></script>
|
|
||||||
<body>
|
|
||||||
<div id="log"></div>
|
|
||||||
<script>
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
runPropertyTests('white-space', [
|
|
||||||
{ syntax: 'normal'},
|
|
||||||
{ syntax: 'pre' },
|
|
||||||
{ syntax: 'nowrap' },
|
|
||||||
{ syntax: 'pre-wrap' },
|
|
||||||
{ syntax: 'pre-line' },
|
|
||||||
]);
|
|
||||||
|
|
||||||
</script>
|
|
|
@ -1,5 +1,6 @@
|
||||||
six==1.10.0
|
|
||||||
Template-Python==0.1.post1
|
Template-Python==0.1.post1
|
||||||
html5lib==0.9999999
|
html5lib==1.0.1
|
||||||
lxml==3.7.3
|
lxml==4.1.1
|
||||||
mercurial==4.1
|
mercurial==4.5
|
||||||
|
six==1.11.0
|
||||||
|
webencodings==0.5.1
|
||||||
|
|
|
@ -12,7 +12,7 @@ import codecs
|
||||||
import collections
|
import collections
|
||||||
from xml import dom
|
from xml import dom
|
||||||
import html5lib
|
import html5lib
|
||||||
from html5lib import treebuilders, inputstream
|
from html5lib import treebuilders
|
||||||
from lxml import etree
|
from lxml import etree
|
||||||
from lxml.etree import ParseError
|
from lxml.etree import ParseError
|
||||||
from Utils import getMimeFromExt, escapeToNamedASCII, basepath, isPathInsideBase, relativeURL, assetName
|
from Utils import getMimeFromExt, escapeToNamedASCII, basepath, isPathInsideBase, relativeURL, assetName
|
||||||
|
@ -1363,10 +1363,8 @@ class HTMLSource(XMLSource):
|
||||||
if data:
|
if data:
|
||||||
with warnings.catch_warnings():
|
with warnings.catch_warnings():
|
||||||
warnings.simplefilter("ignore")
|
warnings.simplefilter("ignore")
|
||||||
htmlStream = html5lib.inputstream.HTMLInputStream(data)
|
self.tree = self.__parser.parse(data)
|
||||||
if ('utf-8-sig' != self.encoding): # if we found a BOM, respect it
|
self.encoding = self.__parser.documentEncoding
|
||||||
self.encoding = htmlStream.detectEncoding()[0]
|
|
||||||
self.tree = self.__parser.parse(data, encoding = self.encoding)
|
|
||||||
self.injectedTags = {}
|
self.injectedTags = {}
|
||||||
else:
|
else:
|
||||||
self.tree = None
|
self.tree = None
|
||||||
|
|
|
@ -17,10 +17,13 @@ callback EventHandlerNonNull = any (Event event);
|
||||||
typedef EventHandlerNonNull? EventHandler;
|
typedef EventHandlerNonNull? EventHandler;
|
||||||
</script>
|
</script>
|
||||||
<script type=text/plain>
|
<script type=text/plain>
|
||||||
[Constructor(DOMString title, optional NotificationOptions options)]
|
[Constructor(DOMString title, optional NotificationOptions options),
|
||||||
|
Exposed=(Window,Worker)]
|
||||||
interface Notification : EventTarget {
|
interface Notification : EventTarget {
|
||||||
static readonly attribute NotificationPermission permission;
|
static readonly attribute NotificationPermission permission;
|
||||||
static Promise<NotificationPermission> requestPermission(optional NotificationPermissionCallback callback);
|
[Exposed=Window] static Promise<NotificationPermission> requestPermission(optional NotificationPermissionCallback deprecatedCallback);
|
||||||
|
|
||||||
|
static readonly attribute unsigned long maxActions;
|
||||||
|
|
||||||
attribute EventHandler onclick;
|
attribute EventHandler onclick;
|
||||||
attribute EventHandler onshow;
|
attribute EventHandler onshow;
|
||||||
|
@ -32,7 +35,17 @@ interface Notification : EventTarget {
|
||||||
readonly attribute DOMString lang;
|
readonly attribute DOMString lang;
|
||||||
readonly attribute DOMString body;
|
readonly attribute DOMString body;
|
||||||
readonly attribute DOMString tag;
|
readonly attribute DOMString tag;
|
||||||
readonly attribute DOMString icon;
|
readonly attribute USVString image;
|
||||||
|
readonly attribute USVString icon;
|
||||||
|
readonly attribute USVString badge;
|
||||||
|
readonly attribute USVString sound;
|
||||||
|
[SameObject] readonly attribute FrozenArray<unsigned long> vibrate;
|
||||||
|
readonly attribute DOMTimeStamp timestamp;
|
||||||
|
readonly attribute boolean renotify;
|
||||||
|
readonly attribute boolean silent;
|
||||||
|
readonly attribute boolean requireInteraction;
|
||||||
|
[SameObject] readonly attribute any data;
|
||||||
|
[SameObject] readonly attribute FrozenArray<NotificationAction> actions;
|
||||||
|
|
||||||
void close();
|
void close();
|
||||||
};
|
};
|
||||||
|
@ -40,13 +53,19 @@ interface Notification : EventTarget {
|
||||||
dictionary NotificationOptions {
|
dictionary NotificationOptions {
|
||||||
NotificationDirection dir = "auto";
|
NotificationDirection dir = "auto";
|
||||||
DOMString lang = "";
|
DOMString lang = "";
|
||||||
DOMString body;
|
DOMString body = "";
|
||||||
DOMString tag;
|
DOMString tag = "";
|
||||||
DOMString icon;
|
USVString image;
|
||||||
};
|
USVString icon;
|
||||||
|
USVString badge;
|
||||||
dictionary GetNotificationsOptions {
|
USVString sound;
|
||||||
DOMString tag;
|
VibratePattern vibrate;
|
||||||
|
DOMTimeStamp timestamp;
|
||||||
|
boolean renotify = false;
|
||||||
|
boolean silent = false;
|
||||||
|
boolean requireInteraction = false;
|
||||||
|
any data = null;
|
||||||
|
sequence<NotificationAction> actions = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
enum NotificationPermission {
|
enum NotificationPermission {
|
||||||
|
@ -55,13 +74,19 @@ enum NotificationPermission {
|
||||||
"granted"
|
"granted"
|
||||||
};
|
};
|
||||||
|
|
||||||
callback NotificationPermissionCallback = void (NotificationPermission permission);
|
|
||||||
|
|
||||||
enum NotificationDirection {
|
enum NotificationDirection {
|
||||||
"auto",
|
"auto",
|
||||||
"ltr",
|
"ltr",
|
||||||
"rtl"
|
"rtl"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
dictionary NotificationAction {
|
||||||
|
required DOMString action;
|
||||||
|
required DOMString title;
|
||||||
|
USVString icon;
|
||||||
|
};
|
||||||
|
|
||||||
|
callback NotificationPermissionCallback = void (NotificationPermission permission);
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
|
@ -0,0 +1,281 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for PaymentRequest.show(optional detailsPromise) method</title>
|
||||||
|
<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
// See function testBadUpdate() for test details!
|
||||||
|
setup({
|
||||||
|
allow_uncaught_exception: true,
|
||||||
|
explicit_done: true,
|
||||||
|
explicit_timeout: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// == TEST DATA ===
|
||||||
|
// PaymentMethod
|
||||||
|
const validMethod = Object.freeze({
|
||||||
|
supportedMethods: "valid-but-wont-ever-match",
|
||||||
|
});
|
||||||
|
|
||||||
|
const validMethodBasicCard = Object.freeze({
|
||||||
|
supportedMethods: "basic-card",
|
||||||
|
});
|
||||||
|
|
||||||
|
const validMethodApplePay = Object.freeze({
|
||||||
|
supportedMethods: "https://apple.com/pay",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
const validMethods = Object.freeze([
|
||||||
|
validMethodBasicCard,
|
||||||
|
validMethod,
|
||||||
|
validMethodApplePay,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Amounts
|
||||||
|
const validAmount = Object.freeze({
|
||||||
|
currency: "USD",
|
||||||
|
value: "1.00",
|
||||||
|
});
|
||||||
|
|
||||||
|
const invalidAmount = Object.freeze({
|
||||||
|
currency: "¡INVALID!",
|
||||||
|
value: "A1.0",
|
||||||
|
});
|
||||||
|
|
||||||
|
const negativeAmount = Object.freeze({
|
||||||
|
currency: "USD",
|
||||||
|
value: "-1.00",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Totals
|
||||||
|
const validTotal = Object.freeze({
|
||||||
|
label: "Valid Total",
|
||||||
|
amount: validAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
const invalidTotal = Object.freeze({
|
||||||
|
label: "Invalid Total",
|
||||||
|
amount: invalidAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
const invalidNegativeTotal = Object.freeze({
|
||||||
|
label: "Invalid negative total",
|
||||||
|
amount: negativeAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
// PaymentDetailsInit
|
||||||
|
const validDetails = Object.freeze({
|
||||||
|
total: validTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
const invalidDetailsNegativeTotal = Object.freeze({
|
||||||
|
total: invalidNegativeTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
// PaymentOptions
|
||||||
|
const validOptions = Object.freeze({
|
||||||
|
requestShipping: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// PaymentItem
|
||||||
|
const validPaymentItem = Object.freeze({
|
||||||
|
amount: validAmount,
|
||||||
|
label: "Valid payment item",
|
||||||
|
});
|
||||||
|
|
||||||
|
const invalidPaymentItem = Object.freeze({
|
||||||
|
amount: invalidAmount,
|
||||||
|
label: "Invalid payment item",
|
||||||
|
});
|
||||||
|
|
||||||
|
// PaymentItem
|
||||||
|
const validPaymentItems = Object.freeze([validPaymentItem]);
|
||||||
|
const invalidPaymentItems = Object.freeze([invalidPaymentItem]);
|
||||||
|
|
||||||
|
// PaymentShippingOption
|
||||||
|
const invalidShippingOption = Object.freeze({
|
||||||
|
id: "abc",
|
||||||
|
label: "Invalid shipping option",
|
||||||
|
amount: invalidAmount,
|
||||||
|
selected: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// PaymentShippingOptions
|
||||||
|
const validShippingOption = Object.freeze({
|
||||||
|
id: "abc",
|
||||||
|
label: "valid shipping option",
|
||||||
|
amount: validAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
const validShippingOptions = Object.freeze([validShippingOption]);
|
||||||
|
const invalidShippingOptions = Object.freeze([invalidShippingOption]);
|
||||||
|
|
||||||
|
// PaymentDetailsModifier
|
||||||
|
const validModifier = Object.freeze({
|
||||||
|
additionalDisplayItems: validPaymentItems,
|
||||||
|
supportedMethods: "valid-but-wont-ever-match",
|
||||||
|
total: validTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modifierWithInvalidDisplayItems = Object.freeze({
|
||||||
|
additionalDisplayItems: invalidPaymentItems,
|
||||||
|
supportedMethods: "basic-card",
|
||||||
|
total: validTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modifierWithValidDisplayItems = Object.freeze({
|
||||||
|
additionalDisplayItems: validPaymentItems,
|
||||||
|
supportedMethods: "basic-card",
|
||||||
|
total: validTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
const modifierWithInvalidTotal = Object.freeze({
|
||||||
|
additionalDisplayItems: validPaymentItems,
|
||||||
|
supportedMethods: "basic-card",
|
||||||
|
total: invalidTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
const recursiveData = {};
|
||||||
|
recursiveData.foo = recursiveData;
|
||||||
|
Object.freeze(recursiveData);
|
||||||
|
|
||||||
|
const modifierWithRecursiveData = Object.freeze({
|
||||||
|
supportedMethods: validMethodBasicCard,
|
||||||
|
total: validTotal,
|
||||||
|
data: recursiveData,
|
||||||
|
});
|
||||||
|
// == END OF TEST DATA ===
|
||||||
|
/*
|
||||||
|
These test work by creating a "valid" payment request and then
|
||||||
|
performing a bad update via `show(detailsPromise)`.
|
||||||
|
The `badDetails` cause detailsPromise to reject with `expectedError`.
|
||||||
|
*/
|
||||||
|
function testBadUpdate(testAssertion, badDetails, expectedError) {
|
||||||
|
promise_test(async t => {
|
||||||
|
const request = new PaymentRequest(
|
||||||
|
validMethods,
|
||||||
|
validDetails,
|
||||||
|
validOptions
|
||||||
|
);
|
||||||
|
const detailsPromise = Promise.resolve(badDetails);
|
||||||
|
const acceptPromise = request.show(detailsPromise);
|
||||||
|
await promise_rejects(
|
||||||
|
t,
|
||||||
|
expectedError,
|
||||||
|
acceptPromise,
|
||||||
|
"badDetails must cause acceptPromise to reject with expectedError"
|
||||||
|
);
|
||||||
|
}, testAssertion);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<h2>
|
||||||
|
PaymentRequest <code>.show(optional detailsPromise)</code> tests
|
||||||
|
</h2>
|
||||||
|
<h3>
|
||||||
|
Bad details - causes `detailsPromise` to reject.
|
||||||
|
</h3>
|
||||||
|
<p>
|
||||||
|
Click on each button in sequence from top to bottom without refreshing the page.
|
||||||
|
No payment sheet should be shown, as all provided values cause an error.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>
|
||||||
|
If you see a payment sheet, it means the test has failed.
|
||||||
|
</strong>
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li><button onclick="
|
||||||
|
const rejectedPromise = Promise.reject(new SyntaxError('test'))
|
||||||
|
.catch(err => err);
|
||||||
|
testBadUpdate(this.textContent, rejectedPromise, 'AbortError');
|
||||||
|
">
|
||||||
|
Rejection of detailsPromise must abort the update with an 'AbortError' DOMException.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
const invalidDetails = { total: `this will cause a TypeError!` };
|
||||||
|
testBadUpdate(this.textContent, invalidDetails, new TypeError());
|
||||||
|
">
|
||||||
|
Total in the update is a string, so converting to IDL must abort the update with a TypeError.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
const invalidDetails = { total: recursiveData };
|
||||||
|
testBadUpdate(this.textContent, invalidDetails, new TypeError());
|
||||||
|
">
|
||||||
|
Total is recursive, so converting to IDL must abort the update with a TypeError.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
testBadUpdate(this.textContent, invalidDetailsNegativeTotal, new TypeError());
|
||||||
|
">
|
||||||
|
Updating with a negative total results in a TypeError.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
const badDetails = Object.assign({}, validDetails, {
|
||||||
|
displayItems: invalidPaymentItems
|
||||||
|
});
|
||||||
|
testBadUpdate(this.textContent, badDetails, new RangeError());
|
||||||
|
">
|
||||||
|
Updating with a displayItem with an invalid currency results in TypeError.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
const duplicateShippingOptions = [validShippingOption, validShippingOption];
|
||||||
|
const badDetails = Object.assign({}, validDetails, {
|
||||||
|
shippingOptions: duplicateShippingOptions,
|
||||||
|
});
|
||||||
|
testBadUpdate(this.textContent, badDetails, new TypeError());
|
||||||
|
">
|
||||||
|
Updating with duplicate shippingOptions (same IDs) results in a TypeError.
|
||||||
|
</button></li>
|
||||||
|
<li><button onclick="
|
||||||
|
const badDetails = Object.assign({}, validDetails, {
|
||||||
|
shippingOptions: invalidShippingOptions,
|
||||||
|
});
|
||||||
|
testBadUpdate(this.textContent, badDetails, new RangeError());
|
||||||
|
">
|
||||||
|
Updating with a shippingOption with an invalid currency value results in a RangError.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
// validModifier is there as to avoid false positives
|
||||||
|
const badModifiers = { modifiers: [modifierWithInvalidTotal, validModifier] };
|
||||||
|
const badDetails = Object.assign({}, validDetails, badModifiers);
|
||||||
|
testBadUpdate(this.textContent, badDetails, new RangeError());
|
||||||
|
">
|
||||||
|
Must throw a RangeError when a modifier's total item has an invalid currency.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
// validModifier is there as to avoid false positives
|
||||||
|
const badModifiers = {
|
||||||
|
modifiers: [modifierWithInvalidDisplayItems, validModifier],
|
||||||
|
};
|
||||||
|
const badDetails = Object.assign({}, validDetails, badModifiers);
|
||||||
|
testBadUpdate(this.textContent, badDetails, new RangeError());
|
||||||
|
">
|
||||||
|
Must throw a RangeError when a modifier display item has an invalid currency.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="
|
||||||
|
// validModifier is there as to avoid false positives
|
||||||
|
const badModifiers = {
|
||||||
|
modifiers: [modifierWithRecursiveData, validModifier],
|
||||||
|
};
|
||||||
|
const badDetails = Object.assign({}, validDetails, badModifiers);
|
||||||
|
testBadUpdate(this.textContent, badDetails, new TypeError());
|
||||||
|
">
|
||||||
|
Must throw as Modifier has a recursive dictionary.
|
||||||
|
</button></li>
|
||||||
|
|
||||||
|
<li><button onclick="done();">Done!</button></li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<small>
|
||||||
|
If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a>
|
||||||
|
and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>.
|
||||||
|
</small>
|
|
@ -0,0 +1,319 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test for PaymentRequest.show(optional promise) method</title>
|
||||||
|
<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script>
|
||||||
|
"use strict";
|
||||||
|
setup({
|
||||||
|
allow_uncaught_exception: true,
|
||||||
|
explicit_done: true,
|
||||||
|
explicit_timeout: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// DATA USED BY TESTS
|
||||||
|
// PaymentMethods
|
||||||
|
const validMethods = Object.freeze([
|
||||||
|
{
|
||||||
|
supportedMethods: "valid-but-wont-ever-match",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
supportedMethods: "basic-card",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
supportedMethods: "https://apple.com/pay",
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Amounts
|
||||||
|
const failAmount = Object.freeze({
|
||||||
|
currency: "USD",
|
||||||
|
value: "1.00",
|
||||||
|
});
|
||||||
|
const passAmount = Object.freeze({
|
||||||
|
currency: "CAD",
|
||||||
|
value: "50.00",
|
||||||
|
});
|
||||||
|
const neutralAmount = Object.freeze({
|
||||||
|
currency: "AUD",
|
||||||
|
value: "0.00",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Labels
|
||||||
|
const failLabel = "💥 TEST HAS FAILED 💥";
|
||||||
|
const passLabel = "✅ TEST HAS PASSED ✅";
|
||||||
|
const neutralLabel = "Ignore this label";
|
||||||
|
// Totals
|
||||||
|
const failTotal = Object.freeze({
|
||||||
|
label: failLabel,
|
||||||
|
amount: failAmount,
|
||||||
|
});
|
||||||
|
const passTotal = Object.freeze({
|
||||||
|
label: passLabel,
|
||||||
|
amount: passAmount,
|
||||||
|
});
|
||||||
|
const neutralTotal = Object.freeze({
|
||||||
|
label: neutralLabel,
|
||||||
|
amount: passAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
// PaymentItem
|
||||||
|
const failPaymentItem = Object.freeze({
|
||||||
|
amount: failAmount,
|
||||||
|
label: failLabel,
|
||||||
|
});
|
||||||
|
const failPaymentItems = Object.freeze([failPaymentItem]);
|
||||||
|
|
||||||
|
const passPaymentItem = Object.freeze({
|
||||||
|
amount: passAmount,
|
||||||
|
label: passLabel,
|
||||||
|
});
|
||||||
|
const passPaymentItems = Object.freeze([passPaymentItem]);
|
||||||
|
|
||||||
|
// PaymentShippingOptions
|
||||||
|
const failShippingOption = Object.freeze({
|
||||||
|
id: "fail",
|
||||||
|
label: failLabel,
|
||||||
|
amount: failAmount,
|
||||||
|
});
|
||||||
|
const failShippingOptions = Object.freeze([failShippingOption]);
|
||||||
|
|
||||||
|
const neutralShippingOption = Object.freeze({
|
||||||
|
id: "neutral",
|
||||||
|
label: neutralLabel,
|
||||||
|
amount: neutralAmount,
|
||||||
|
});
|
||||||
|
|
||||||
|
const updatedShippingOption1 = Object.freeze({
|
||||||
|
id: "updated-1",
|
||||||
|
label: `${passLabel} - option 1`,
|
||||||
|
amount: passAmount,
|
||||||
|
});
|
||||||
|
const updatedShippingOption2 = Object.freeze({
|
||||||
|
id: "updated-2",
|
||||||
|
label: `${passLabel} - option 2 (MUST BE SELECTED!)`,
|
||||||
|
amount: passAmount,
|
||||||
|
selected: true,
|
||||||
|
});
|
||||||
|
const passShippingOptions = Object.freeze([
|
||||||
|
updatedShippingOption1,
|
||||||
|
updatedShippingOption2,
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Modifiers
|
||||||
|
// create a modifier objects for each validMethods
|
||||||
|
// and single additional display item
|
||||||
|
const failModifiers = validMethods.map(modifier => {
|
||||||
|
const label = `${failLabel} - (${modifier.supportedMethods})`;
|
||||||
|
return {
|
||||||
|
...modifier,
|
||||||
|
total: {
|
||||||
|
...failTotal,
|
||||||
|
label,
|
||||||
|
},
|
||||||
|
additionalDisplayItems: [
|
||||||
|
{
|
||||||
|
...failPaymentItem,
|
||||||
|
label,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
// Updates the total for each, and changes the additionalDisplayItems
|
||||||
|
const passModifiers = failModifiers.map(modifier => {
|
||||||
|
const label = `${passLabel} - (${modifier.supportedMethods})`;
|
||||||
|
return {
|
||||||
|
...modifier,
|
||||||
|
total: {
|
||||||
|
...passTotal,
|
||||||
|
label,
|
||||||
|
},
|
||||||
|
additionalDisplayItems: [
|
||||||
|
{
|
||||||
|
...passPaymentItem,
|
||||||
|
label,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// PaymentDetailsInit
|
||||||
|
const validDetails = Object.freeze({
|
||||||
|
displayItems: failPaymentItems,
|
||||||
|
id: "this cannot be changed",
|
||||||
|
modifiers: failModifiers,
|
||||||
|
shippingOptions: failShippingOptions,
|
||||||
|
total: failTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
const neutralDetails = Object.freeze({
|
||||||
|
displayItems: [],
|
||||||
|
modifiers: [],
|
||||||
|
shippingOptions: [neutralShippingOption],
|
||||||
|
total: neutralTotal,
|
||||||
|
});
|
||||||
|
|
||||||
|
function smokeTest() {
|
||||||
|
promise_test(async t => {
|
||||||
|
const request = new PaymentRequest(validMethods, validDetails);
|
||||||
|
await promise_rejects(
|
||||||
|
t,
|
||||||
|
new TypeError(),
|
||||||
|
request.show({
|
||||||
|
total: "This throws a TypeError",
|
||||||
|
}),
|
||||||
|
"expected TypeError"
|
||||||
|
);
|
||||||
|
}, "smoke test - checks if the optional details are supported on show() method");
|
||||||
|
}
|
||||||
|
|
||||||
|
function runUpdateDetailsAlgorithm(
|
||||||
|
buttonElement,
|
||||||
|
details,
|
||||||
|
options = {
|
||||||
|
requestShipping: true,
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const testAssertion = buttonElement.textContent.trim();
|
||||||
|
buttonElement.disabled = true;
|
||||||
|
promise_test(async t => {
|
||||||
|
const request = new PaymentRequest(validMethods, validDetails, options);
|
||||||
|
const detailsPromise = Promise.resolve(details);
|
||||||
|
const acceptPromise = request.show(detailsPromise);
|
||||||
|
assert_equals(request.id, "this cant be changed", "id must never change.");
|
||||||
|
await promise_rejects(
|
||||||
|
t,
|
||||||
|
"AbortError",
|
||||||
|
acceptPromise,
|
||||||
|
"expected AbortError"
|
||||||
|
);
|
||||||
|
}, testAssertion);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<h2>
|
||||||
|
PaymentRequest <code>.show(optional detailsPromise)</code> tests
|
||||||
|
</h2>
|
||||||
|
<p>
|
||||||
|
These test cause <code>detailsPromise</code> to resolve successfully with some updated value. As such, that will cause
|
||||||
|
something in the payment sheet to change. Each test describes what is expected to change - if anything.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Instructions:</strong> Click on each button in sequence from top to bottom without refreshing the page. The payment
|
||||||
|
sheet will be shown. If required, confirm that the expected value appears in the payment sheet. Finally, manually abort/cancel
|
||||||
|
the payment request by closing the payment sheet.
|
||||||
|
</p>
|
||||||
|
<ol>
|
||||||
|
<li><button onclick="smokeTest()">If the payment sheet is shown, the test has failed.</button></li>
|
||||||
|
<li><button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
id: 'fail',
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, the provided `id` must have no effect on the payment request.
|
||||||
|
</button></li>
|
||||||
|
<li><button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
total: passTotal
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, the total must be CAD$50 with the label "✅ TEST HAS PASSED ✅".
|
||||||
|
</button></li>
|
||||||
|
<li><button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
displayItems: passPaymentItems,
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, there must be a one display item with a value of CAD$50 with the label "✅ TEST HAS PASSED ✅".
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li><button onclick="
|
||||||
|
const auItem = {
|
||||||
|
...passPaymentItem,
|
||||||
|
amount: { value: '40', currency: 'AUD'},
|
||||||
|
pending: true
|
||||||
|
}
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
displayItems: passPaymentItems.concat(auItem),
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, there must be
|
||||||
|
two display items: One with a value of CAD$50, another with
|
||||||
|
value AUD$40 that is pending.
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li><button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
shippingOptions: [updatedShippingOption1],
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, there must be a one shipping option
|
||||||
|
with a value of CAD$50.
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li><button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
shippingOptions: passShippingOptions,
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, there must be
|
||||||
|
two shipping options: One with a value of CAD$50, another with
|
||||||
|
value AUD$40 that is selected.
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li><button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
modifiers: passModifiers,
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, the total should be CAD$50.
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
shippingOptions: [],
|
||||||
|
error: passLabel,
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details);
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, the string "✅ TEST HAS PASSED ✅" should be shown
|
||||||
|
somewhere in the user interface. Alternatively, the payment sheet must indicate to the
|
||||||
|
end user that it's not possible to ship their order.
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onclick="
|
||||||
|
const details = {
|
||||||
|
...neutralDetails,
|
||||||
|
error: failLabel,
|
||||||
|
};
|
||||||
|
runUpdateDetailsAlgorithm(this, details, {requestShipping: false});
|
||||||
|
">
|
||||||
|
When the payment sheet is shown, there should not be any errors shown.
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<button onclick="done();">Done!</button>
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<small>
|
||||||
|
If you find a buggy test, please <a href="https://github.com/w3c/web-platform-tests/issues">file a bug</a>
|
||||||
|
and tag one of the <a href="https://github.com/w3c/web-platform-tests/blob/master/payment-request/OWNERS">owners</a>.
|
||||||
|
</small>
|
|
@ -448,12 +448,15 @@ promise_test(() => {
|
||||||
// Flush async events and verify that no shutdown occurs.
|
// Flush async events and verify that no shutdown occurs.
|
||||||
return flushAsyncEvents().then(() => {
|
return flushAsyncEvents().then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a'],
|
assert_array_equals(ws.events, ['write', 'a'],
|
||||||
'the chunk must have been written, but close must not have happened yet');
|
'the chunk must have been written, but close must not have happened');
|
||||||
assert_equals(pipeComplete, false, 'the pipe must not be complete');
|
assert_equals(pipeComplete, false, 'the pipe must not be complete');
|
||||||
|
|
||||||
resolveWritePromise();
|
resolveWritePromise();
|
||||||
|
|
||||||
return pipePromise;
|
return pipePromise;
|
||||||
|
}).then(() => flushAsyncEvents()).then(() => {
|
||||||
|
assert_array_equals(ws.events, ['write', 'a'],
|
||||||
|
'the chunk must have been written, but close must not have happened');
|
||||||
});
|
});
|
||||||
|
|
||||||
}, 'Closing must be propagated forward: shutdown must not occur until the final write completes; preventClose = true');
|
}, 'Closing must be propagated forward: shutdown must not occur until the final write completes; preventClose = true');
|
||||||
|
@ -488,7 +491,7 @@ promise_test(() => {
|
||||||
|
|
||||||
return writeCalledPromise.then(() => flushAsyncEvents()).then(() => {
|
return writeCalledPromise.then(() => flushAsyncEvents()).then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a'],
|
assert_array_equals(ws.events, ['write', 'a'],
|
||||||
'the chunk must have been written, but close must not have happened yet');
|
'the first chunk must have been written, but close must not have happened yet');
|
||||||
assert_false(pipeComplete, 'the pipe should not complete while the first write is pending');
|
assert_false(pipeComplete, 'the pipe should not complete while the first write is pending');
|
||||||
|
|
||||||
rs.controller.close();
|
rs.controller.close();
|
||||||
|
@ -537,21 +540,21 @@ promise_test(() => {
|
||||||
|
|
||||||
return writeCalledPromise.then(() => flushAsyncEvents()).then(() => {
|
return writeCalledPromise.then(() => flushAsyncEvents()).then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a'],
|
assert_array_equals(ws.events, ['write', 'a'],
|
||||||
'the chunk must have been written, but close must not have happened yet');
|
'the first chunk must have been written, but close must not have happened');
|
||||||
assert_false(pipeComplete, 'the pipe should not complete while the first write is pending');
|
assert_false(pipeComplete, 'the pipe should not complete while the first write is pending');
|
||||||
|
|
||||||
rs.controller.close();
|
rs.controller.close();
|
||||||
resolveWritePromise();
|
resolveWritePromise();
|
||||||
}).then(() => flushAsyncEvents()).then(() => {
|
}).then(() => flushAsyncEvents()).then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
||||||
'the second chunk must have been written, but close must not have happened yet');
|
'the second chunk must have been written, but close must not have happened');
|
||||||
assert_false(pipeComplete, 'the pipe should not complete while the second write is pending');
|
assert_false(pipeComplete, 'the pipe should not complete while the second write is pending');
|
||||||
|
|
||||||
resolveWritePromise();
|
resolveWritePromise();
|
||||||
return pipePromise;
|
return pipePromise;
|
||||||
}).then(() => flushAsyncEvents()).then(() => {
|
}).then(() => flushAsyncEvents()).then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
||||||
'all chunks must have been written, but close must not have happened yet');
|
'all chunks must have been written, but close must not have happened');
|
||||||
});
|
});
|
||||||
|
|
||||||
}, 'Closing must be propagated forward: shutdown must not occur until the final write completes; becomes closed after first write; preventClose = true');
|
}, 'Closing must be propagated forward: shutdown must not occur until the final write completes; becomes closed after first write; preventClose = true');
|
||||||
|
|
|
@ -428,6 +428,50 @@ promise_test(t => {
|
||||||
|
|
||||||
}, 'Errors must be propagated forward: shutdown must not occur until the final write completes');
|
}, 'Errors must be propagated forward: shutdown must not occur until the final write completes');
|
||||||
|
|
||||||
|
promise_test(t => {
|
||||||
|
|
||||||
|
const rs = recordingReadableStream();
|
||||||
|
|
||||||
|
let resolveWriteCalled;
|
||||||
|
const writeCalledPromise = new Promise(resolve => {
|
||||||
|
resolveWriteCalled = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
|
let resolveWritePromise;
|
||||||
|
const ws = recordingWritableStream({
|
||||||
|
write() {
|
||||||
|
resolveWriteCalled();
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
resolveWritePromise = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let pipeComplete = false;
|
||||||
|
const pipePromise = promise_rejects(t, error1, rs.pipeTo(ws, { preventAbort: true })).then(() => {
|
||||||
|
pipeComplete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
rs.controller.enqueue('a');
|
||||||
|
|
||||||
|
return writeCalledPromise.then(() => {
|
||||||
|
rs.controller.error(error1);
|
||||||
|
|
||||||
|
// Flush async events and verify that no shutdown occurs.
|
||||||
|
return flushAsyncEvents();
|
||||||
|
}).then(() => {
|
||||||
|
assert_array_equals(ws.events, ['write', 'a']); // no 'abort'
|
||||||
|
assert_equals(pipeComplete, false, 'the pipe must not be complete');
|
||||||
|
|
||||||
|
resolveWritePromise();
|
||||||
|
return pipePromise;
|
||||||
|
}).then(() => flushAsyncEvents()).then(() => {
|
||||||
|
assert_array_equals(ws.events, ['write', 'a']); // no 'abort'
|
||||||
|
});
|
||||||
|
|
||||||
|
}, 'Errors must be propagated forward: shutdown must not occur until the final write completes; preventAbort = true');
|
||||||
|
|
||||||
promise_test(t => {
|
promise_test(t => {
|
||||||
|
|
||||||
const rs = recordingReadableStream();
|
const rs = recordingReadableStream();
|
||||||
|
@ -457,7 +501,8 @@ promise_test(t => {
|
||||||
rs.controller.enqueue('b');
|
rs.controller.enqueue('b');
|
||||||
|
|
||||||
return writeCalledPromise.then(() => flushAsyncEvents()).then(() => {
|
return writeCalledPromise.then(() => flushAsyncEvents()).then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a'], 'abort should not be called before the first write completes');
|
assert_array_equals(ws.events, ['write', 'a'],
|
||||||
|
'the first chunk must have been written, but abort must not have happened yet');
|
||||||
assert_false(pipeComplete, 'the pipe should not complete while the first write is pending');
|
assert_false(pipeComplete, 'the pipe should not complete while the first write is pending');
|
||||||
|
|
||||||
rs.controller.error(error1);
|
rs.controller.error(error1);
|
||||||
|
@ -465,15 +510,65 @@ promise_test(t => {
|
||||||
return flushAsyncEvents();
|
return flushAsyncEvents();
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
||||||
'abort should not be called before the second write completes');
|
'the second chunk must have been written, but abort must not have happened yet');
|
||||||
assert_false(pipeComplete, 'the pipe should not complete while the second write is pending');
|
assert_false(pipeComplete, 'the pipe should not complete while the second write is pending');
|
||||||
|
|
||||||
resolveWritePromise();
|
resolveWritePromise();
|
||||||
return pipePromise;
|
return pipePromise;
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
assert_array_equals(ws.events, ['write', 'a', 'write', 'b', 'abort', error1], 'sink abort should be called');
|
assert_array_equals(ws.events, ['write', 'a', 'write', 'b', 'abort', error1],
|
||||||
|
'all chunks must have been written and abort must have happened');
|
||||||
});
|
});
|
||||||
|
|
||||||
}, 'Errors must be propagated forward: abort should not happen until all queued writes complete');
|
}, 'Errors must be propagated forward: shutdown must not occur until the final write completes; becomes errored after first write');
|
||||||
|
|
||||||
|
promise_test(t => {
|
||||||
|
|
||||||
|
const rs = recordingReadableStream();
|
||||||
|
|
||||||
|
let resolveWriteCalled;
|
||||||
|
const writeCalledPromise = new Promise(resolve => {
|
||||||
|
resolveWriteCalled = resolve;
|
||||||
|
});
|
||||||
|
|
||||||
|
let resolveWritePromise;
|
||||||
|
const ws = recordingWritableStream({
|
||||||
|
write() {
|
||||||
|
resolveWriteCalled();
|
||||||
|
|
||||||
|
return new Promise(resolve => {
|
||||||
|
resolveWritePromise = resolve;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, new CountQueuingStrategy({ highWaterMark: 2 }));
|
||||||
|
|
||||||
|
let pipeComplete = false;
|
||||||
|
const pipePromise = promise_rejects(t, error1, rs.pipeTo(ws, { preventAbort: true })).then(() => {
|
||||||
|
pipeComplete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
rs.controller.enqueue('a');
|
||||||
|
rs.controller.enqueue('b');
|
||||||
|
|
||||||
|
return writeCalledPromise.then(() => flushAsyncEvents()).then(() => {
|
||||||
|
assert_array_equals(ws.events, ['write', 'a'],
|
||||||
|
'the first chunk must have been written, but abort must not have happened');
|
||||||
|
assert_false(pipeComplete, 'the pipe should not complete while the first write is pending');
|
||||||
|
|
||||||
|
rs.controller.error(error1);
|
||||||
|
resolveWritePromise();
|
||||||
|
}).then(() => flushAsyncEvents()).then(() => {
|
||||||
|
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
||||||
|
'the second chunk must have been written, but abort must not have happened');
|
||||||
|
assert_false(pipeComplete, 'the pipe should not complete while the second write is pending');
|
||||||
|
|
||||||
|
resolveWritePromise();
|
||||||
|
return pipePromise;
|
||||||
|
}).then(() => flushAsyncEvents()).then(() => {
|
||||||
|
assert_array_equals(ws.events, ['write', 'a', 'write', 'b'],
|
||||||
|
'all chunks must have been written, but abort must not have happened');
|
||||||
|
});
|
||||||
|
|
||||||
|
}, 'Errors must be propagated forward: shutdown must not occur until the final write completes; becomes errored after first write; preventAbort = true');
|
||||||
|
|
||||||
done();
|
done();
|
||||||
|
|
4
tests/wpt/web-platform-tests/tools/ci/before_install.sh
Executable file → Normal file
4
tests/wpt/web-platform-tests/tools/ci/before_install.sh
Executable file → Normal file
|
@ -1,13 +1,13 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [[ $(./wpt test-jobs --includes $JOB; echo $?) -eq 0 ]]; then
|
if [[ -z ${RUN_JOB+x} && $(./wpt test-jobs --includes $JOB; echo $?) -eq 0 ]] || [[ $RUN_JOB -eq 1 ]]; then
|
||||||
export RUN_JOB=1
|
export RUN_JOB=1
|
||||||
git submodule update --init --recursive 1>&2
|
git submodule update --init --recursive 1>&2
|
||||||
export DISPLAY=:99.0
|
export DISPLAY=:99.0
|
||||||
sh -e /etc/init.d/xvfb start 1>&2
|
sh -e /etc/init.d/xvfb start 1>&2
|
||||||
# For uploading the manifest
|
# For uploading the manifest
|
||||||
export WPT_MANIFEST_FILE=$HOME/meta/MANIFEST-$(git rev-parse HEAD).json
|
export WPT_MANIFEST_FILE=$HOME/meta/MANIFEST-$(git rev-parse HEAD).json
|
||||||
else
|
elif [[ -z ${RUN_JOB+x} ]]; then
|
||||||
export RUN_JOB=0
|
export RUN_JOB=0
|
||||||
fi
|
fi
|
||||||
|
|
0
tests/wpt/web-platform-tests/tools/ci/ci_lint.sh
Normal file → Executable file
0
tests/wpt/web-platform-tests/tools/ci/ci_lint.sh
Normal file → Executable file
0
tests/wpt/web-platform-tests/tools/ci/ci_manifest.sh
Normal file → Executable file
0
tests/wpt/web-platform-tests/tools/ci/ci_manifest.sh
Normal file → Executable file
0
tests/wpt/web-platform-tests/tools/ci/ci_stability.sh
Normal file → Executable file
0
tests/wpt/web-platform-tests/tools/ci/ci_stability.sh
Normal file → Executable file
0
tests/wpt/web-platform-tests/tools/ci/ci_wpt.sh
Normal file → Executable file
0
tests/wpt/web-platform-tests/tools/ci/ci_wpt.sh
Normal file → Executable file
|
@ -6,5 +6,5 @@ WPT_ROOT=$(readlink -f $SCRIPT_DIR/../..)
|
||||||
cd $WPT_ROOT
|
cd $WPT_ROOT
|
||||||
|
|
||||||
if [[ $RUN_JOB -eq 1 ]]; then
|
if [[ $RUN_JOB -eq 1 ]]; then
|
||||||
. $SCRIPT
|
$SCRIPT
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -14,7 +14,11 @@ class Git(object):
|
||||||
def get_func(repo_path):
|
def get_func(repo_path):
|
||||||
def git(cmd, *args):
|
def git(cmd, *args):
|
||||||
full_cmd = ["git", cmd] + list(args)
|
full_cmd = ["git", cmd] + list(args)
|
||||||
return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT)
|
try:
|
||||||
|
return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT)
|
||||||
|
except WindowsError:
|
||||||
|
full_cmd[0] = "git.bat"
|
||||||
|
return subprocess.check_output(full_cmd, cwd=repo_path, stderr=subprocess.STDOUT)
|
||||||
return git
|
return git
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -40,7 +40,7 @@ assert_worker_throws('indexedDB is inaccessible', 'self.indexedDB.open("someDBNa
|
||||||
assert_worker_sends_pass('cross-origin worker', '', 'fetch("/").then(() => port.postMessage("FAIL"), () => port.postMessage("PASS"))');
|
assert_worker_sends_pass('cross-origin worker', '', 'fetch("/").then(() => port.postMessage("FAIL"), () => port.postMessage("PASS"))');
|
||||||
|
|
||||||
// 'data:' workers have opaque origin
|
// 'data:' workers have opaque origin
|
||||||
assert_worker_sends_pass('worker has opaque origin', 'application/javascript', 'if (self.location.origin == "null") port.postMessage("PASS"); else { port.postMessage("FAIL"); }');
|
assert_worker_sends_pass('worker has opaque origin', 'application/javascript', 'port.postMessage(self.location.origin == "null" ? "PASS" : "FAIL")');
|
||||||
|
|
||||||
function openWindow(url) {
|
function openWindow(url) {
|
||||||
return new Promise(resolve => {
|
return new Promise(resolve => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue