mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Auto merge of #24555 - servo-wpt-sync:wpt_update_25-10-2019, r=servo-wpt-sync
Sync WPT with upstream (25-10-2019) Automated downstream sync of changes from upstream as of 25-10-2019. [no-wpt-sync] r? @servo-wpt-sync
This commit is contained in:
commit
6a54d60043
91 changed files with 3190 additions and 185 deletions
|
@ -14,9 +14,6 @@
|
|||
[Revoke blob URL after creating Request, will fetch]
|
||||
expected: FAIL
|
||||
|
||||
[Revoke blob URL after calling fetch, fetch should succeed]
|
||||
expected: FAIL
|
||||
|
||||
|
||||
[url-with-fetch.any.html]
|
||||
[Untitled]
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +0,0 @@
|
|||
[quirks-auto-block-size-with-percentage-item.html]
|
||||
[#container 1]
|
||||
expected: FAIL
|
||||
|
|
@ -8,9 +8,3 @@
|
|||
[throws if handleEvent is thruthy and not callable]
|
||||
expected: FAIL
|
||||
|
||||
[doesn't look up handleEvent method on callable event listeners]
|
||||
expected: FAIL
|
||||
|
||||
[looks up handleEvent method on every event dispatch]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[focus-visible-008.html]
|
||||
[CSS Test (Selectors): Keyboard focus enables :focus-visible]
|
||||
expected: FAIL
|
||||
|
|
@ -321,3 +321,15 @@
|
|||
[<iframe>: separate response Content-Type: text/plain */*;charset=gbk]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: combined response Content-Type: text/html;" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html;" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html */*]
|
||||
expected: FAIL
|
||||
|
||||
[<iframe>: separate response Content-Type: text/html;x=" text/plain]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -56,6 +56,3 @@
|
|||
[separate text/javascript x/x]
|
||||
expected: FAIL
|
||||
|
||||
[separate text/javascript;charset=windows-1252 text/javascript]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,2 +1,19 @@
|
|||
[script-resource-with-nonsniffable-types.tentative.sub.html]
|
||||
expected: TIMEOUT
|
||||
[CORB blocks 'multipart/byteranges']
|
||||
expected: FAIL
|
||||
|
||||
[CORB blocks 'application/gzip']
|
||||
expected: FAIL
|
||||
|
||||
[CORB blocks 'application/x-protobuf']
|
||||
expected: FAIL
|
||||
|
||||
[CORB blocks 'application/zip']
|
||||
expected: FAIL
|
||||
|
||||
[CORB blocks 'text/event-stream']
|
||||
expected: FAIL
|
||||
|
||||
[CORB blocks 'application/x-gzip']
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
[redirect-https-downgrade.tentative.sub.html]
|
||||
expected: ERROR
|
||||
[redirect-https-downgrade]
|
||||
expected: FAIL
|
||||
|
||||
[Https downgrade fetch() api]
|
||||
expected: NOTRUN
|
||||
|
||||
[Https downgrade script => No headers]
|
||||
expected: FAIL
|
||||
|
||||
[Https downgrade object]
|
||||
expected: NOTRUN
|
||||
|
||||
[Https downgrade embed]
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[embedded-credentials.tentative.sub.html]
|
||||
type: testharness
|
||||
expected: CRASH
|
||||
expected: TIMEOUT
|
||||
[Embedded credentials are treated as network errors.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[traverse_the_history_4.html]
|
||||
[Multiple history traversals, last would be aborted]
|
||||
expected: FAIL
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
[document_domain_access_details.sub.html]
|
||||
expected: TIMEOUT
|
||||
[Access allowed if same-origin with no 'document.domain' modification. (Sanity check)]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
[Access is revoked to Window object when we stop being same effective script origin due to document.domain.]
|
||||
expected: NOTRUN
|
||||
|
@ -13,7 +13,7 @@
|
|||
expected: NOTRUN
|
||||
|
||||
[Access not allowed if different-origin with no 'document.domain' modification. (Sanity check)]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
[Access disallowed again if same-origin, both set document-domain to existing value, then one sets to parent.]
|
||||
expected: NOTRUN
|
||||
|
@ -22,13 +22,13 @@
|
|||
expected: NOTRUN
|
||||
|
||||
[Access allowed if same-origin and both set document.domain to existing value.]
|
||||
expected: TIMEOUT
|
||||
expected: NOTRUN
|
||||
|
||||
[Access is not revoked to Document object when we stop being same effective script origin due to document.domain.]
|
||||
expected: NOTRUN
|
||||
|
||||
[Access disallowed if same-origin but only one sets document.domain.]
|
||||
expected: FAIL
|
||||
expected: NOTRUN
|
||||
|
||||
[Access evolves correctly for cross-origin objects when we join up via document.domain and then diverge again.]
|
||||
expected: NOTRUN
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
[creating_browsing_context_test_01.html]
|
||||
[first argument: absolute url]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
[iframe_sandbox_popups_escaping-3.html]
|
||||
type: testharness
|
||||
expected: TIMEOUT
|
||||
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
[non-active-document.html]
|
||||
[DOMParser]
|
||||
expected: FAIL
|
||||
|
||||
[createHTMLDocument]
|
||||
expected: FAIL
|
||||
|
||||
[<template>]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
[form-double-submit-2.html]
|
||||
expected: ERROR
|
||||
[preventDefault should allow onclick submit() to succeed]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[form-double-submit.html]
|
||||
expected: ERROR
|
||||
[default submit action should supersede onclick submit()]
|
||||
expected: FAIL
|
||||
expected: TIMEOUT
|
||||
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[toggleEvent.html]
|
||||
[Calling open twice on 'details' fires only one toggle event]
|
||||
expected: FAIL
|
||||
|
||||
[Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element]
|
||||
expected: FAIL
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[DOMContentLoaded-defer.html]
|
||||
[The end: DOMContentLoaded and defer scripts]
|
||||
expected: FAIL
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
[realtimeanalyser-fft-scaling.html]
|
||||
expected: TIMEOUT
|
||||
[X 2048-point FFT peak position is not equal to 64. Got 0.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
5
tests/wpt/metadata/webmessaging/with-ports/018.html.ini
Normal file
5
tests/wpt/metadata/webmessaging/with-ports/018.html.ini
Normal file
|
@ -0,0 +1,5 @@
|
|||
[018.html]
|
||||
expected: TIMEOUT
|
||||
[origin of the script that invoked the method, javascript:]
|
||||
expected: TIMEOUT
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
[stylesheet_media_queries.html]
|
||||
[Media queries within stylesheets]
|
||||
expected: FAIL
|
||||
|
|
@ -239,12 +239,12 @@ jobs:
|
|||
- job: results_edge_dev
|
||||
displayName: 'all tests: Edge Dev'
|
||||
condition: |
|
||||
or(eq(variables['Build.SourceBranch'], 'refs/heads/epochs/six_hourly'),
|
||||
or(eq(variables['Build.SourceBranch'], 'refs/heads/epochs/three_hourly'),
|
||||
eq(variables['Build.SourceBranch'], 'refs/heads/triggers/edge_dev'),
|
||||
and(eq(variables['Build.Reason'], 'Manual'), variables['run_all_edge_dev']))
|
||||
strategy:
|
||||
parallel: 10 # chosen to make runtime ~2h
|
||||
timeoutInMinutes: 360
|
||||
timeoutInMinutes: 180
|
||||
pool:
|
||||
name: 'Hosted Windows Client'
|
||||
steps:
|
||||
|
@ -275,12 +275,12 @@ jobs:
|
|||
- job: results_edge_canary
|
||||
displayName: 'all tests: Edge Canary'
|
||||
condition: |
|
||||
or(eq(variables['Build.SourceBranch'], 'refs/heads/epochs/six_hourly'),
|
||||
or(eq(variables['Build.SourceBranch'], 'refs/heads/epochs/three_hourly'),
|
||||
eq(variables['Build.SourceBranch'], 'refs/heads/triggers/edge_canary'),
|
||||
and(eq(variables['Build.Reason'], 'Manual'), variables['run_all_edge_canary']))
|
||||
strategy:
|
||||
parallel: 10 # chosen to make runtime ~2h
|
||||
timeoutInMinutes: 360
|
||||
timeoutInMinutes: 180
|
||||
pool:
|
||||
name: 'Hosted Windows Client'
|
||||
steps:
|
||||
|
@ -316,7 +316,7 @@ jobs:
|
|||
and(eq(variables['Build.Reason'], 'Manual'), variables['run_all_safari']))
|
||||
strategy:
|
||||
parallel: 5 # chosen to make runtime ~2h
|
||||
timeoutInMinutes: 360
|
||||
timeoutInMinutes: 180
|
||||
pool:
|
||||
vmImage: 'macOS-10.13'
|
||||
steps:
|
||||
|
@ -346,12 +346,12 @@ jobs:
|
|||
- job: results_safari_preview
|
||||
displayName: 'all tests: Safari Technology Preview'
|
||||
condition: |
|
||||
or(eq(variables['Build.SourceBranch'], 'refs/heads/epochs/six_hourly'),
|
||||
or(eq(variables['Build.SourceBranch'], 'refs/heads/epochs/three_hourly'),
|
||||
eq(variables['Build.SourceBranch'], 'refs/heads/triggers/safari_preview'),
|
||||
and(eq(variables['Build.Reason'], 'Manual'), variables['run_all_safari_preview']))
|
||||
strategy:
|
||||
parallel: 5 # chosen to make runtime ~2h
|
||||
timeoutInMinutes: 360
|
||||
timeoutInMinutes: 180
|
||||
pool:
|
||||
vmImage: 'macOS-10.14'
|
||||
steps:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
name: documentation
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
@ -11,7 +12,6 @@ on:
|
|||
- 'docs/**'
|
||||
- 'resources/**'
|
||||
- 'tools/**'
|
||||
name: documentation
|
||||
jobs:
|
||||
build-and-publish:
|
||||
runs-on: ubuntu-18.04
|
||||
|
|
16
tests/wpt/web-platform-tests/.github/workflows/epochs.yml
vendored
Normal file
16
tests/wpt/web-platform-tests/.github/workflows/epochs.yml
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
name: epochs
|
||||
on:
|
||||
schedule:
|
||||
# Trigger 10 minutes past every 3rd hour. 10 minutes is a safety margin
|
||||
# for any manifest workflow to finish, see tools/wpt/revlist.py.
|
||||
- cron: 10 */3 * * *
|
||||
jobs:
|
||||
update:
|
||||
runs-on: ubuntu-18.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
- name: Run epochs_update.sh
|
||||
run: ./tools/ci/epochs_update.sh
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@ -1,3 +1,4 @@
|
|||
name: manifest
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
|
@ -5,7 +6,6 @@ on:
|
|||
pull_request:
|
||||
paths:
|
||||
- 'tools/**'
|
||||
name: manifest
|
||||
jobs:
|
||||
build-and-tag:
|
||||
runs-on: ubuntu-18.04
|
||||
|
|
113
tests/wpt/web-platform-tests/WebIDL/tools/generate-setlike.py
Normal file
113
tests/wpt/web-platform-tests/WebIDL/tools/generate-setlike.py
Normal file
|
@ -0,0 +1,113 @@
|
|||
import os
|
||||
|
||||
here = os.path.dirname(__file__)
|
||||
|
||||
readonly_template = """\
|
||||
interface {interface}A {{
|
||||
readonly setlike<DOMString>;
|
||||
static void {method}();
|
||||
}};
|
||||
|
||||
interface {interface}B {{
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long {method};
|
||||
}};
|
||||
"""
|
||||
|
||||
readwrite_template = """\
|
||||
interface ReadOnly {{
|
||||
readonly setlike<DOMString>;
|
||||
}};
|
||||
|
||||
interface ReadWrite {{
|
||||
setlike<DOMString>;
|
||||
}};
|
||||
|
||||
interface {interface}A {{
|
||||
setlike<DOMString>;
|
||||
void {method}();
|
||||
}};
|
||||
|
||||
interface {interface}B {{
|
||||
readonly setlike<DOMString>;
|
||||
void {method}();
|
||||
}};
|
||||
|
||||
interface {interface}C {{
|
||||
readonly setlike<DOMString>;
|
||||
readonly attribute long {method};
|
||||
}};
|
||||
|
||||
interface {interface}D {{
|
||||
readonly setlike<DOMString>;
|
||||
const long {method} = 0;
|
||||
}};
|
||||
|
||||
interface {interface}E : ReadOnly {{
|
||||
void {method}();
|
||||
}};
|
||||
|
||||
interface {interface}F : ReadOnly {{
|
||||
readonly attribute long {method};
|
||||
}};
|
||||
|
||||
interface {interface}G : ReadOnly {{
|
||||
const long {method} = 0;
|
||||
}};
|
||||
|
||||
interface {interface}H {{
|
||||
readonly setlike<DOMString>;
|
||||
static void {method}();
|
||||
}};
|
||||
|
||||
interface {interface}I {{
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long {method};
|
||||
}};
|
||||
|
||||
interface {interface}J1 {{
|
||||
static void {method}();
|
||||
}};
|
||||
|
||||
interface {interface}J2 : {interface}J1 {{
|
||||
readonly setlike<DOMString>;
|
||||
}};
|
||||
|
||||
interface {interface}K1 {{
|
||||
static readonly attribute long {method};
|
||||
}};
|
||||
|
||||
interface {interface}K2 : {interface}K1 {{
|
||||
readonly setlike<DOMString>;
|
||||
}};
|
||||
"""
|
||||
|
||||
members_readonly = [
|
||||
"entries",
|
||||
"forEach",
|
||||
"has",
|
||||
"keys",
|
||||
"size",
|
||||
"values",
|
||||
]
|
||||
|
||||
members_readwrite = [
|
||||
"add",
|
||||
"clear",
|
||||
"delete",
|
||||
]
|
||||
|
||||
def transform(m):
|
||||
return m[0].upper() + m[1:]
|
||||
|
||||
tests = [
|
||||
(members_readonly, readonly_template),
|
||||
(members_readwrite, readwrite_template),
|
||||
]
|
||||
|
||||
for (members, template) in tests:
|
||||
for method in members:
|
||||
path = "{here}/../valid/idl/setlike-{method}.widl".format(here=here, method=method)
|
||||
test = template.format(method=method, interface=transform(method))
|
||||
with open(path, "wb") as f:
|
||||
f.write(test.encode("utf8"))
|
|
@ -0,0 +1,65 @@
|
|||
interface ReadOnly {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface ReadWrite {
|
||||
setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface AddA {
|
||||
setlike<DOMString>;
|
||||
void add();
|
||||
};
|
||||
|
||||
interface AddB {
|
||||
readonly setlike<DOMString>;
|
||||
void add();
|
||||
};
|
||||
|
||||
interface AddC {
|
||||
readonly setlike<DOMString>;
|
||||
readonly attribute long add;
|
||||
};
|
||||
|
||||
interface AddD {
|
||||
readonly setlike<DOMString>;
|
||||
const long add = 0;
|
||||
};
|
||||
|
||||
interface AddE : ReadOnly {
|
||||
void add();
|
||||
};
|
||||
|
||||
interface AddF : ReadOnly {
|
||||
readonly attribute long add;
|
||||
};
|
||||
|
||||
interface AddG : ReadOnly {
|
||||
const long add = 0;
|
||||
};
|
||||
|
||||
interface AddH {
|
||||
readonly setlike<DOMString>;
|
||||
static void add();
|
||||
};
|
||||
|
||||
interface AddI {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long add;
|
||||
};
|
||||
|
||||
interface AddJ1 {
|
||||
static void add();
|
||||
};
|
||||
|
||||
interface AddJ2 : AddJ1 {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface AddK1 {
|
||||
static readonly attribute long add;
|
||||
};
|
||||
|
||||
interface AddK2 : AddK1 {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
|
@ -0,0 +1,65 @@
|
|||
interface ReadOnly {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface ReadWrite {
|
||||
setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface ClearA {
|
||||
setlike<DOMString>;
|
||||
void clear();
|
||||
};
|
||||
|
||||
interface ClearB {
|
||||
readonly setlike<DOMString>;
|
||||
void clear();
|
||||
};
|
||||
|
||||
interface ClearC {
|
||||
readonly setlike<DOMString>;
|
||||
readonly attribute long clear;
|
||||
};
|
||||
|
||||
interface ClearD {
|
||||
readonly setlike<DOMString>;
|
||||
const long clear = 0;
|
||||
};
|
||||
|
||||
interface ClearE : ReadOnly {
|
||||
void clear();
|
||||
};
|
||||
|
||||
interface ClearF : ReadOnly {
|
||||
readonly attribute long clear;
|
||||
};
|
||||
|
||||
interface ClearG : ReadOnly {
|
||||
const long clear = 0;
|
||||
};
|
||||
|
||||
interface ClearH {
|
||||
readonly setlike<DOMString>;
|
||||
static void clear();
|
||||
};
|
||||
|
||||
interface ClearI {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long clear;
|
||||
};
|
||||
|
||||
interface ClearJ1 {
|
||||
static void clear();
|
||||
};
|
||||
|
||||
interface ClearJ2 : ClearJ1 {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface ClearK1 {
|
||||
static readonly attribute long clear;
|
||||
};
|
||||
|
||||
interface ClearK2 : ClearK1 {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
|
@ -0,0 +1,65 @@
|
|||
interface ReadOnly {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface ReadWrite {
|
||||
setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface DeleteA {
|
||||
setlike<DOMString>;
|
||||
void delete();
|
||||
};
|
||||
|
||||
interface DeleteB {
|
||||
readonly setlike<DOMString>;
|
||||
void delete();
|
||||
};
|
||||
|
||||
interface DeleteC {
|
||||
readonly setlike<DOMString>;
|
||||
readonly attribute long delete;
|
||||
};
|
||||
|
||||
interface DeleteD {
|
||||
readonly setlike<DOMString>;
|
||||
const long delete = 0;
|
||||
};
|
||||
|
||||
interface DeleteE : ReadOnly {
|
||||
void delete();
|
||||
};
|
||||
|
||||
interface DeleteF : ReadOnly {
|
||||
readonly attribute long delete;
|
||||
};
|
||||
|
||||
interface DeleteG : ReadOnly {
|
||||
const long delete = 0;
|
||||
};
|
||||
|
||||
interface DeleteH {
|
||||
readonly setlike<DOMString>;
|
||||
static void delete();
|
||||
};
|
||||
|
||||
interface DeleteI {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long delete;
|
||||
};
|
||||
|
||||
interface DeleteJ1 {
|
||||
static void delete();
|
||||
};
|
||||
|
||||
interface DeleteJ2 : DeleteJ1 {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface DeleteK1 {
|
||||
static readonly attribute long delete;
|
||||
};
|
||||
|
||||
interface DeleteK2 : DeleteK1 {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
interface EntriesA {
|
||||
readonly setlike<DOMString>;
|
||||
static void entries();
|
||||
};
|
||||
|
||||
interface EntriesB {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long entries;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
interface ForEachA {
|
||||
readonly setlike<DOMString>;
|
||||
static void forEach();
|
||||
};
|
||||
|
||||
interface ForEachB {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long forEach;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
interface HasA {
|
||||
readonly setlike<DOMString>;
|
||||
static void has();
|
||||
};
|
||||
|
||||
interface HasB {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long has;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
interface KeysA {
|
||||
readonly setlike<DOMString>;
|
||||
static void keys();
|
||||
};
|
||||
|
||||
interface KeysB {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long keys;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
interface SizeA {
|
||||
readonly setlike<DOMString>;
|
||||
static void size();
|
||||
};
|
||||
|
||||
interface SizeB {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long size;
|
||||
};
|
|
@ -0,0 +1,9 @@
|
|||
interface ValuesA {
|
||||
readonly setlike<DOMString>;
|
||||
static void values();
|
||||
};
|
||||
|
||||
interface ValuesB {
|
||||
readonly setlike<DOMString>;
|
||||
static readonly attribute long values;
|
||||
};
|
15
tests/wpt/web-platform-tests/WebIDL/valid/idl/setlike.widl
Normal file
15
tests/wpt/web-platform-tests/WebIDL/valid/idl/setlike.widl
Normal file
|
@ -0,0 +1,15 @@
|
|||
interface ReadOnly {
|
||||
readonly setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface ReadWrite {
|
||||
setlike<DOMString>;
|
||||
};
|
||||
|
||||
interface ReadOnlyExtAttr {
|
||||
readonly setlike<[Clamp] unsigned short>;
|
||||
};
|
||||
|
||||
interface ReadWriteExtAttr {
|
||||
setlike<[Clamp] unsigned short>;
|
||||
};
|
|
@ -62,7 +62,7 @@
|
|||
<body>
|
||||
<p>This test examines the ARIA properties for Name test case 610.</p>
|
||||
<input id="test" type="text" aria-label="bar" aria-labelledby="ID1 test">
|
||||
<div id="ID1">foo</label>
|
||||
<div id="ID1">foo</div>
|
||||
|
||||
<div id="manualMode"></div>
|
||||
<div id="log"></div>
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<p>Fieldset should contain a green div spanning the width.
|
||||
<fieldset>
|
||||
<div id="child" style="background:green; height:10px"></div>
|
||||
</fieldset>
|
|
@ -0,0 +1,6 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="match" href="webkit-box-fieldset-ref.html">
|
||||
<p>Fieldset should contain a green div spanning the width.
|
||||
<fieldset style="display: -webkit-box">
|
||||
<div id="child" style="background:green; height:10px"></div>
|
||||
</fieldset>
|
|
@ -1,4 +1,8 @@
|
|||
// META: global=worker
|
||||
// META: timeout=long
|
||||
//
|
||||
// This test isn't actually slow usually, but sometimes it takes >10 seconds on
|
||||
// Firefox with service worker for no obvious reason.
|
||||
|
||||
'use strict';
|
||||
|
|
@ -0,0 +1,193 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Grid Layout test: stretch value for align and justify properties</title>
|
||||
<link rel="author" title="Rossana Monteriso" href="mailto:rmonteriso@igalia.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-grid-1/#alignment">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-align-3/#typedef-self-position">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-align-3/#distribution-values">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-align-3/#content-distribution">
|
||||
|
||||
<meta name="assert" content="This test checks that the 'stretch' value is applied correctly for 'align' and 'justify' properties for both RTL/LTR directions and horizontal/vertical writing modes.">
|
||||
<meta name="flags" content="ahem">
|
||||
<link rel="stylesheet" href="/css/support/grid.css">
|
||||
<link rel="stylesheet" href="/css/support/alignment.css">
|
||||
<link rel="stylesheet" href="support/width-keyword-classes.css">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.grid {
|
||||
grid-template-columns: 100px 100px;
|
||||
grid-template-rows: 200px 200px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.widthAndHeightSet {
|
||||
width: 20px;
|
||||
height: 40px;
|
||||
}
|
||||
.onlyWidthSet { width: 20px; }
|
||||
.onlyHeightSet { height: 40px; }
|
||||
.maxHeight { max-height: 160px; }
|
||||
.maxWidth { max-width: 90px; }
|
||||
.minWidth { min-width: 120px; }
|
||||
.minHeight { min-height: 220px; }
|
||||
</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 style="position: relative">
|
||||
<div class="grid fit-content" data-expected-width="200" data-expected-height="400">
|
||||
<div class="alignSelfStretch justifySelfStart firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="0" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet alignSelfStretch justifySelfStart firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet alignSelfStretch justifySelfStart secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet alignSelfStretch justifySelfStart secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="0" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content" data-expected-width="200" data-expected-height="400">
|
||||
<div class="alignSelfStart justifySelfStretch firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="0"></div>
|
||||
<div class="widthAndHeightSet alignSelfStart justifySelfStretch firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet alignSelfStart justifySelfStretch secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="0"></div>
|
||||
<div class="onlyHeightSet alignSelfStart justifySelfStretch secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content" data-expected-width="200" data-expected-height="400">
|
||||
<div class="maxHeight alignSelfStretch justifySelfStart firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="0" data-expected-height="160"></div>
|
||||
<div class="minWidth widthAndHeightSet alignSelfStretch justifySelfStart firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="120" data-expected-height="40"></div>
|
||||
<div class="minHeight onlyWidthSet alignSelfStretch justifySelfStart secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="220"></div>
|
||||
<div class="maxWidth onlyHeightSet alignSelfStretch justifySelfStretch secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="90" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content" data-expected-width="200" data-expected-height="400">
|
||||
<div class="alignSelfStretch justifySelfStretch firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet alignSelfStretch justifySelfStretch firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet alignSelfStretch justifySelfStretch secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet alignSelfStretch justifySelfStretch secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content alignItemsStretch justifyItemsStart" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="0" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="0" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content alignItemsStart justifyItemsStretch" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="0"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="0"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content alignItemsStretch justifyItemsStretch" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content alignItemsAuto justifyItemsAuto" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="firstRowSecondColumn" data-offset-x="100" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="secondRowFirstColumn" data-offset-x="0" data-offset-y="200" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="secondRowSecondColumn" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="200"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RTL direction (it should not affect the block-flow direction). -->
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content directionRTL alignItemsStretch justifyItemsStretch" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn" data-offset-x="100" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="80" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="180" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="0" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- RTL direction (it should not affect the block-flow) with opposite directions grid container vs grid item. -->
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content alignItemsStretch justifyItemsStretch" data-expected-width="200" data-expected-height="400">
|
||||
<div class="firstRowFirstColumn directionRTL" data-offset-x="0" data-offset-y="0" data-expected-width="100" data-expected-height="200"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn directionRTL" data-offset-x="100" data-offset-y="0" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn directionRTL" data-offset-x="0" data-offset-y="200" data-expected-width="20" data-expected-height="200"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn directionRTL" data-offset-x="100" data-offset-y="200" data-expected-width="100" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Vertical RL writing mode. -->
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content verticalRL alignItemsStretch justifyItemsStretch" data-expected-width="400" data-expected-height="200">
|
||||
<div class="firstRowFirstColumn" data-offset-x="200" data-offset-y="0" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="380" data-offset-y="100" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="180" data-offset-y="0" data-expected-width="20" data-expected-height="100"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="0" data-offset-y="100" data-expected-width="200" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content verticalRL" data-expected-width="400" data-expected-height="200">
|
||||
<div class="firstRowFirstColumn" data-offset-x="200" data-offset-y="0" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="firstRowSecondColumn" data-offset-x="200" data-offset-y="100" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="secondRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="secondRowSecondColumn" data-offset-x="0" data-offset-y="100" data-expected-width="200" data-expected-height="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Vertical LR writing mode. -->
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content verticalLR alignItemsStretch justifyItemsStretch" data-expected-width="400" data-expected-height="200">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="widthAndHeightSet firstRowSecondColumn" data-offset-x="0" data-offset-y="100" data-expected-width="20" data-expected-height="40"></div>
|
||||
<div class="onlyWidthSet secondRowFirstColumn" data-offset-x="200" data-offset-y="0" data-expected-width="20" data-expected-height="100"></div>
|
||||
<div class="onlyHeightSet secondRowSecondColumn" data-offset-x="200" data-offset-y="100" data-expected-width="200" data-expected-height="40"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="position: relative">
|
||||
<div class="grid fit-content verticalLR" data-expected-width="400" data-expected-height="200">
|
||||
<div class="firstRowFirstColumn" data-offset-x="0" data-offset-y="0" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="firstRowSecondColumn" data-offset-x="0" data-offset-y="100" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="secondRowFirstColumn" data-offset-x="200" data-offset-y="0" data-expected-width="200" data-expected-height="100"></div>
|
||||
<div class="secondRowSecondColumn" data-offset-x="200" data-offset-y="100" data-expected-width="200" data-expected-height="100"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Take every possible line break so the box width is the width of largest
|
||||
unbreakable line box.
|
||||
*/
|
||||
.min-content {
|
||||
/* Webkit, but not actually implemented outside deprecated flexbox */
|
||||
width: min-intrinsic;
|
||||
width: -webkit-min-content;
|
||||
width: -moz-min-content;
|
||||
width: min-content;
|
||||
}
|
||||
|
||||
.max-content {
|
||||
width: -webkit-max-content;
|
||||
width: -moz-max-content;
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
/*
|
||||
Identical to auto except for elements with an instrinsic width like an
|
||||
img where this overrides the intrinsic width to get regular block "auto".
|
||||
*/
|
||||
.fill-available {
|
||||
width: -webkit-fill-available;
|
||||
/* Firefox is missing the fill- prefix because they followed an older spec */
|
||||
width: -moz-available;
|
||||
width: fill-available;
|
||||
}
|
||||
|
||||
/*
|
||||
Shrink wrap just like floating.
|
||||
max(min-content, min(max-content, fill-available))
|
||||
*/
|
||||
.fit-content {
|
||||
/* Webkit, but only outside a deprecated flexbox. */
|
||||
width: intrinsic;
|
||||
width: -webkit-fit-content;
|
||||
width: -moz-fit-content;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.max-width-min-content {
|
||||
max-width: -webkit-min-content;
|
||||
max-width: -moz-min-content;
|
||||
max-width: min-content;
|
||||
}
|
||||
|
||||
.max-width-max-content {
|
||||
max-width: -webkit-max-content;
|
||||
max-width: -moz-max-content;
|
||||
max-width: max-content;
|
||||
}
|
||||
|
||||
.max-width-fill-available {
|
||||
max-width: -webkit-fill-available;
|
||||
max-width: -moz-available;
|
||||
max-width: fill-available;
|
||||
}
|
||||
|
||||
.max-width-fit-content {
|
||||
max-width: intrinsic;
|
||||
max-width: -webkit-fit-content;
|
||||
max-width: -moz-fit-content;
|
||||
max-width: fit-content;
|
||||
}
|
||||
|
||||
.min-width-min-content {
|
||||
min-width: -webkit-min-content;
|
||||
min-width: -moz-min-content;
|
||||
min-width: min-content;
|
||||
}
|
||||
|
||||
.min-width-max-content {
|
||||
min-width: -webkit-max-content;
|
||||
min-width: -moz-max-content;
|
||||
min-width: max-content;
|
||||
}
|
||||
|
||||
.min-width-fill-available {
|
||||
min-width: -webkit-fill-available;
|
||||
min-width: -moz-available;
|
||||
min-width: fill-available;
|
||||
}
|
||||
|
||||
.min-width-fit-content {
|
||||
min-width: intrinsic;
|
||||
min-width: -webkit-fit-content;
|
||||
min-width: -moz-fit-content;
|
||||
min-width: fit-content;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>CSS Reference: String value of list-style-type with Ahem font</title>
|
||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||
<style>
|
||||
main {
|
||||
width: 300px;
|
||||
overflow: auto;
|
||||
padding: 10px 0;
|
||||
}
|
||||
pre {
|
||||
font: 10px/1 Ahem;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
padding-right: 70px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<pre> É1 1É </pre>
|
||||
<pre> XXXÉ2 2ÉXXX </pre>
|
||||
<pre> XXXpppÉ3 3ÉXXXppp </pre>
|
||||
<pre> XXX ppp É4 4É XXX ppp </pre>
|
||||
<pre> XXX pppÉ5 5ÉXXX ppp </pre>
|
||||
<pre>XX Xp pp É6 6É XX Xp pp</pre>
|
||||
<pre>X X Xp p pÉ7 7ÉX X Xp p p</pre>
|
||||
<pre>XX XXXpXXXÉ8 8ÉXXXXpXX XX</pre>
|
||||
<pre>X XXXpXXX É9 9É XXXXpXX X</pre>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>String value of list-style-type with Ahem font</title>
|
||||
<link rel="author" title="Oriol Brufau" href="mailto:obrufau@gmail.com">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-lists-3/#valdef-list-style-type-string">
|
||||
<link rel="match" href="list-style-type-string-007-ref.html">
|
||||
<meta name="assert" content="This test checks that list-style-type can set the marker string with the Ahem font.">
|
||||
<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
|
||||
<style>
|
||||
main {
|
||||
width: 300px;
|
||||
overflow: auto;
|
||||
padding: 10px 0;
|
||||
}
|
||||
.list {
|
||||
font: 10px/1 Ahem;
|
||||
padding-inline-start: 100px;
|
||||
margin: 0;
|
||||
width: 50px;
|
||||
float: left;
|
||||
}
|
||||
.rtl { direction: rtl; }
|
||||
.list > :nth-child(1) { list-style-type: ""; }
|
||||
.list > :nth-child(2) { list-style-type: "XXX"; }
|
||||
.list > :nth-child(3) { list-style-type: "XXXppp"; }
|
||||
.list > :nth-child(4) { list-style-type: " XXX ppp "; }
|
||||
.list > :nth-child(5) { list-style-type: "XXX ppp"; }
|
||||
.list > :nth-child(6) { list-style-type: " XX Xp pp "; }
|
||||
.list > :nth-child(7) { list-style-type: "X X Xp p p"; }
|
||||
.list > :nth-child(8) { list-style-type: "XXXXpXX XXXpXXX"; }
|
||||
.list > :nth-child(9) { list-style-type: " XXXXpXX XXXpXXX "; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<ol class="list">
|
||||
<li>É1</li>
|
||||
<li>É2</li>
|
||||
<li>É3</li>
|
||||
<li>É4</li>
|
||||
<li>É5</li>
|
||||
<li>É6</li>
|
||||
<li>É7</li>
|
||||
<li>É8</li>
|
||||
<li>É9</li>
|
||||
</ol>
|
||||
<ul class="list rtl">
|
||||
<li>1É</li>
|
||||
<li>2É</li>
|
||||
<li>3É</li>
|
||||
<li>4É</li>
|
||||
<li>5É</li>
|
||||
<li>6É</li>
|
||||
<li>7É</li>
|
||||
<li>8É</li>
|
||||
<li>9É</li>
|
||||
</ul>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
|
@ -284,6 +284,18 @@
|
|||
data-expected-width="238" data-expected-height="52" data-offset-y="141" data-offset-x="159"
|
||||
>
|
||||
</div>
|
||||
<!-- Viewbox + css height. Has aspect_ratio and height. Width is scaled -->
|
||||
<div class="container">
|
||||
<img class="target" style="height:20px" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E"
|
||||
data-expected-width="238" data-expected-height="52" data-offset-y="141" data-offset-x="159"
|
||||
>
|
||||
</div>
|
||||
<!-- Viewbox + css width. Has aspect_ratio and width. Height is scaled -->
|
||||
<div class="container">
|
||||
<img class="target" style="width:238px" src="data:image/svg+xml,%3Csvg viewBox='0 0 100 10' xmlns='http://www.w3.org/2000/svg' %3E%3Crect width='100%' height='100%' style='fill:rgb(0,255,0);'/%3E%3C/svg%3E"
|
||||
data-expected-width="276" data-expected-height="56" data-offset-y="137" data-offset-x="121"
|
||||
>
|
||||
</div>
|
||||
<script>
|
||||
// initialize png images with 200x150 green png
|
||||
let pngSrc="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACWAQMAAAChElVaAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABlBMVEUAgAD///8UPy9PAAAAAWJLR0QB/wIt3gAAAAd0SU1FB+MBDwkdA1Cz/EMAAAAbSURBVEjH7cGBAAAAAMOg+VPf4ARVAQAAAM8ADzwAAeM8wQsAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDEtMTVUMTc6Mjk6MDMtMDg6MDCYDy9IAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDE5LTAxLTE1VDE3OjI5OjAzLTA4OjAw6VKX9AAAAABJRU5ErkJggg=="
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<meta name="flags" content="dom">
|
||||
<title>CSS Test: CSSOM View MediaQueryListEvent</title>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<link rel="help" href="https://drafts.csswg.org/cssom-view/#mediaquerylistevent">
|
||||
<div id="log"></div>
|
||||
<script>
|
||||
"use strict";
|
||||
|
||||
test(t => {
|
||||
assert_equals(MediaQueryListEvent.length, 1);
|
||||
assert_throws(new TypeError(), () => {
|
||||
new MediaQueryListEvent();
|
||||
});
|
||||
}, "type argument is required");
|
||||
|
||||
test(t => {
|
||||
assert_equals(new MediaQueryListEvent("test").type, "test");
|
||||
}, 'type can be different from "change"');
|
||||
|
||||
test(t => {
|
||||
assert_equals(Object.getPrototypeOf(MediaQueryListEvent), Event);
|
||||
assert_true(new MediaQueryListEvent("change") instanceof Event);
|
||||
}, "extends Event");
|
||||
|
||||
test(t => {
|
||||
const event = new MediaQueryListEvent("change");
|
||||
|
||||
assert_equals(event.media, "");
|
||||
assert_false(event.matches);
|
||||
assert_false(event.bubbles);
|
||||
assert_false(event.cancelable);
|
||||
}, "init dictionary default values");
|
||||
|
||||
test(t => {
|
||||
const event = new MediaQueryListEvent("change", {
|
||||
media: "test",
|
||||
matches: true,
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
});
|
||||
|
||||
assert_equals(event.media, "test");
|
||||
assert_true(event.matches);
|
||||
assert_true(event.bubbles);
|
||||
assert_true(event.cancelable);
|
||||
}, "init dictionary overrides");
|
||||
|
||||
test(t => {
|
||||
const event = new MediaQueryListEvent("change");
|
||||
assert_idl_attribute(event, "media");
|
||||
assert_readonly(event, "media");
|
||||
}, "MediaQueryListEvent::media is read-only IDL attribute");
|
||||
|
||||
test(t => {
|
||||
const event = new MediaQueryListEvent("change");
|
||||
assert_idl_attribute(event, "matches");
|
||||
assert_readonly(event, "matches");
|
||||
}, "MediaQueryListEvent::matches is read-only IDL attribute");
|
||||
</script>
|
|
@ -29,16 +29,21 @@
|
|||
<button id="button">Tab to me and press ENTER.</button>
|
||||
<div id="el" tabindex="-1">I will be focused programmatically.</el>
|
||||
<script>
|
||||
button.addEventListener("click", () => {
|
||||
el.focus();
|
||||
});
|
||||
if ("async_test" in window) {
|
||||
async_test(function(t) {
|
||||
button.addEventListener("click", t.step_func(() => {
|
||||
el.focus();
|
||||
}));
|
||||
el.addEventListener("focus", t.step_func(function() {
|
||||
assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 100, 0)");
|
||||
t.done();
|
||||
}));
|
||||
el.focus();
|
||||
}, "Programmatic focus after keypress should match :focus-visible");
|
||||
} else {
|
||||
button.addEventListener("click", () => {
|
||||
el.focus();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,57 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>CSS Test (Selectors): Keyboard shortcut combinations do not trigger :focus-visible</title>
|
||||
<link rel="author" title="Alice Boxhall" href="aboxhall@chromium.org" />
|
||||
<link rel="help" href="https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo" />
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<style>
|
||||
:focus-visible {
|
||||
outline: 0;
|
||||
outline-color: tomato;
|
||||
background-color: tomato;
|
||||
}
|
||||
|
||||
:focus:not(:focus-visible) {
|
||||
outline: darkgreen dotted 1px; /* fallback for Edge */
|
||||
outline: darkgreen auto 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
This test checks that using keyboard combinations with [Ctrl], [Alt] or [Cmd]
|
||||
do not trigger <code>:focus-visible</code> matching.
|
||||
<ol id="instructions">
|
||||
<li>If the user-agent does not claim to support the <code>:focus-visible</code> pseudo-class then SKIP this test.</li>
|
||||
<li>Click the element below that says "Click me, then use a keyboard shortcut."</li>
|
||||
<li>Press a keyboard combination including [Ctrl], [Alt] or [Cmd], such as <code>Ctrl</code> + <code>y</code></li>
|
||||
<li>If the element has a red background, then the test result is FAILURE. If the element has a green outline, then the test result is SUCCESS.</li>
|
||||
</ol>
|
||||
<br>
|
||||
<div id="el" tabindex="0">Click me, then use a keyboard shortcut.</div>
|
||||
<script>
|
||||
var t = async_test( "Keyboard focus should match :focus-visible");
|
||||
|
||||
el.addEventListener("click", t.step_func(function(e) {
|
||||
assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 100, 0)", "after focus()");
|
||||
}), true);
|
||||
|
||||
el.addEventListener("keydown", t.step_func(function(e) {
|
||||
if (e.altKey || e.ctrlKey || e.metaKey) {
|
||||
assert_equals(getComputedStyle(el).outlineColor, "rgb(0, 100, 0)", "after kb event");
|
||||
t.done();
|
||||
return;
|
||||
}
|
||||
assert_true(false, "No modifier key");
|
||||
t.done();
|
||||
}));
|
||||
|
||||
window.setTimeout(t.step_func_done(()=> {
|
||||
assert_true(false, "timeout");
|
||||
}), 1000);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -25,7 +25,7 @@ customElements.define("test-element", TestElement);
|
|||
const element = document.getElementById("testElement");
|
||||
const properties = [
|
||||
"role",
|
||||
"ariaActiveDescendant",
|
||||
"ariaActiveDescendantElement",
|
||||
"ariaAtomic",
|
||||
"ariaAutoComplete",
|
||||
"ariaBusy",
|
||||
|
@ -33,26 +33,26 @@ const properties = [
|
|||
"ariaColCount",
|
||||
"ariaColIndex",
|
||||
"ariaColSpan",
|
||||
"ariaControls",
|
||||
"ariaControlsElements",
|
||||
"ariaCurrent",
|
||||
"ariaDescribedBy",
|
||||
"ariaDetails",
|
||||
"ariaDescribedByElements",
|
||||
"ariaDetailsElement",
|
||||
"ariaDisabled",
|
||||
"ariaErrorMessage",
|
||||
"ariaErrorMessageElement",
|
||||
"ariaExpanded",
|
||||
"ariaFlowTo",
|
||||
"ariaFlowToElements",
|
||||
"ariaHasPopup",
|
||||
"ariaHidden",
|
||||
"ariaKeyShortcuts",
|
||||
"ariaLabel",
|
||||
"ariaLabelledBy",
|
||||
"ariaLabelledByElements",
|
||||
"ariaLevel",
|
||||
"ariaLive",
|
||||
"ariaModal",
|
||||
"ariaMultiLine",
|
||||
"ariaMultiSelectable",
|
||||
"ariaOrientation",
|
||||
"ariaOwns",
|
||||
"ariaOwnsElements",
|
||||
"ariaPlaceholder",
|
||||
"ariaPosInSet",
|
||||
"ariaPressed",
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
setup({allow_uncaught_exception : true});
|
||||
|
||||
function test(mime_type, is_blocking_expected) {
|
||||
var action = is_blocking_expected ? "blocks" : "does not block";
|
||||
|
||||
async_test(function(t) {
|
||||
var script = document.createElement("script")
|
||||
var script_has_run_token = "script_has_run" + token();
|
||||
|
@ -49,7 +51,7 @@ function test(mime_type, is_blocking_expected) {
|
|||
body = `window['${script_has_run_token}'] = true;`
|
||||
script.src = src_prefix + "?type=" + mime_type + "&body=" + encodeURIComponent(body);
|
||||
document.body.appendChild(script)
|
||||
}, "CORB-blocks '" + mime_type + "' that starts with the following JSON parser breaker: " + body);
|
||||
}, "CORB " + action + " '" + mime_type + "'");
|
||||
}
|
||||
|
||||
// Some mime types should be protected by CORB without any kind
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
}, "Https downgrade font => No headers");
|
||||
});
|
||||
|
||||
promise_test(() =>
|
||||
promise_test(() => {
|
||||
return requestViaImage(secureRedirectURL + encodeURIComponent("http://{{host}}:{{ports[http][0]}}/common/security-features/subresource/image.py"))
|
||||
.then(result => {
|
||||
headers = result.headers;
|
||||
|
@ -53,7 +53,8 @@
|
|||
"user": undefined,
|
||||
"mode": undefined,
|
||||
});
|
||||
}), "Https downgrade image => No headers");
|
||||
});
|
||||
}, "Https downgrade image => No headers");
|
||||
</script>
|
||||
|
||||
<script src="https://{{host}}:{{ports[https][0]}}/fetch/api/resources/redirect.py?location=http%3A%2F%2F{{host}}%3A{{ports[http][0]}}%2Ffetch%2Fmetadata%2Fresources%2Fecho-as-script.py"></script>
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="260" height="260" viewBox="0 0 1280.000000 1276.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<!-- from https://svgsilh.com/image/303465.html , CC0 -->
|
||||
<metadata>
|
||||
Created by potrace 1.15, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,1276.000000) scale(0.100000,-0.100000)"
|
||||
fill="#003C56" stroke="none">
|
||||
<path d="M5975 12749 c-86 -6 -144 -14 -151 -22 -6 -6 -41 -111 -77 -232 -37
|
||||
-121 -107 -355 -157 -520 -50 -165 -123 -406 -162 -536 l-71 -237 -188 -46
|
||||
c-213 -52 -475 -135 -658 -208 -68 -27 -130 -47 -137 -44 -7 3 -301 221 -653
|
||||
485 -353 265 -645 481 -649 481 -13 0 -257 -149 -392 -240 -198 -132 -359
|
||||
-254 -578 -436 l-25 -21 271 -746 c150 -411 272 -752 272 -758 0 -6 -40 -56
|
||||
-88 -112 -175 -202 -337 -420 -457 -615 -32 -52 -64 -96 -72 -99 -8 -3 -366 4
|
||||
-796 16 -430 12 -794 21 -808 21 -23 0 -30 -9 -56 -67 -61 -137 -142 -353
|
||||
-202 -538 -61 -186 -145 -494 -138 -502 2 -2 303 -204 668 -448 562 -377 665
|
||||
-450 670 -473 3 -15 1 -72 -4 -127 -8 -99 -2 -525 11 -702 l7 -92 -669 -448
|
||||
c-367 -246 -672 -450 -677 -453 -9 -6 23 -147 72 -320 71 -249 180 -554 284
|
||||
-794 l16 -39 137 6 c75 4 440 14 810 24 l673 17 25 -29 c13 -17 68 -95 120
|
||||
-174 113 -169 222 -314 350 -467 l93 -111 -275 -752 c-151 -414 -274 -757
|
||||
-272 -761 5 -14 213 -185 361 -296 225 -170 606 -418 631 -412 7 2 299 219
|
||||
649 482 l637 479 47 -15 c27 -9 84 -30 128 -48 183 -74 392 -141 619 -200 81
|
||||
-21 149 -40 151 -42 3 -3 222 -724 386 -1273 38 -126 73 -239 78 -251 8 -18
|
||||
24 -22 137 -33 314 -30 1078 -22 1110 12 6 7 41 111 77 232 37 121 107 355
|
||||
157 520 50 165 123 406 162 536 l71 237 188 46 c213 52 475 135 658 208 68 27
|
||||
130 47 137 44 7 -3 301 -221 653 -485 353 -265 644 -481 649 -481 11 0 250
|
||||
145 362 220 206 137 422 299 608 456 l25 21 -271 746 c-150 411 -272 752 -272
|
||||
758 0 6 40 56 88 112 175 202 337 420 457 615 32 52 64 96 72 99 8 3 366 -4
|
||||
796 -16 430 -12 794 -21 808 -21 23 0 30 9 56 68 61 136 142 352 202 537 61
|
||||
186 145 494 138 502 -2 2 -303 204 -668 448 -562 377 -665 450 -670 473 -3 15
|
||||
-1 72 4 127 8 99 2 527 -11 702 l-7 92 668 448 c368 246 673 450 678 453 9 6
|
||||
-22 146 -72 320 -71 249 -180 554 -284 794 l-17 39 -141 -6 c-78 -4 -443 -14
|
||||
-810 -24 l-668 -17 -25 29 c-13 17 -68 95 -120 174 -113 169 -222 314 -350
|
||||
467 l-93 111 275 752 c151 414 274 757 272 761 -5 14 -213 185 -361 296 -225
|
||||
170 -606 418 -631 412 -7 -2 -299 -219 -649 -482 l-637 -479 -47 15 c-27 9
|
||||
-84 30 -128 48 -183 74 -392 141 -619 200 -81 21 -149 40 -151 42 -3 3 -222
|
||||
724 -386 1273 -38 127 -73 239 -78 251 -8 18 -24 22 -137 33 -164 16 -775 22
|
||||
-959 10z"/>
|
||||
</g>
|
||||
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 762 762">
|
||||
<rect x="183.9" y="511.4" fill="#FFFFFF" width="201.5" height="38"/>
|
||||
<path fill="#FFFFFF" d="M504.9,549.4c37.3,0,67.6-30.3,67.6-67.6v-19h-38v19c0,16.3-13.3,29.6-29.6,29.6c-16.3,0-29.6-13.3-29.6-29.6
|
||||
V287.4h-38v56.5h-51.9v-92.6h112.4c25.5,0,46.3,20.8,46.3,46.3c0,20-13,37.8-31.8,44v39.1c40-6.9,69.8-42.1,69.8-83
|
||||
c0-46.5-37.8-84.3-84.3-84.3H366.4c-10.5,0-19,8.5-19,19V386l-46.4-79.4c-3.4-5.8-9.7-9.4-16.4-9.4c-6.7,0-13,3.6-16.4,9.4
|
||||
l-46.2,79.2V213.4h-38v242.7c0,8.6,5.8,16.1,14,18.3c8.3,2.2,17.1-1.4,21.4-8.8l65.2-111.8L350,465.7c3.4,5.8,9.7,9.4,16.4,9.4
|
||||
c1.7,0,3.3-0.2,5-0.7c8.3-2.2,14-9.8,14-18.3v-74.2h51.9v99.8C437.3,519.1,467.6,549.4,504.9,549.4z"/>
|
||||
</svg>
|
||||
</svg>
|
After Width: | Height: | Size: 3.2 KiB |
|
@ -21,9 +21,9 @@ partial interface Navigator {
|
|||
|
||||
[Exposed=Window, SecureContext]
|
||||
interface CredentialsContainer {
|
||||
Promise<Credential?> get(optional CredentialRequestOptions options);
|
||||
Promise<Credential?> get(optional CredentialRequestOptions options = {});
|
||||
Promise<Credential> store(Credential credential);
|
||||
Promise<Credential?> create(optional CredentialCreationOptions options);
|
||||
Promise<Credential?> create(optional CredentialCreationOptions options = {});
|
||||
Promise<void> preventSilentAccess();
|
||||
};
|
||||
|
||||
|
@ -46,11 +46,11 @@ dictionary CredentialCreationOptions {
|
|||
AbortSignal signal;
|
||||
};
|
||||
|
||||
[Constructor(HTMLFormElement form),
|
||||
Constructor(PasswordCredentialData data),
|
||||
Exposed=Window,
|
||||
[Exposed=Window,
|
||||
SecureContext]
|
||||
interface PasswordCredential : Credential {
|
||||
constructor(HTMLFormElement form);
|
||||
constructor(PasswordCredentialData data);
|
||||
readonly attribute USVString password;
|
||||
};
|
||||
PasswordCredential includes CredentialUserData;
|
||||
|
@ -72,10 +72,10 @@ partial dictionary CredentialCreationOptions {
|
|||
PasswordCredentialInit password;
|
||||
};
|
||||
|
||||
[Constructor(FederatedCredentialInit data),
|
||||
Exposed=Window,
|
||||
[Exposed=Window,
|
||||
SecureContext]
|
||||
interface FederatedCredential : Credential {
|
||||
constructor(FederatedCredentialInit data);
|
||||
readonly attribute USVString provider;
|
||||
readonly attribute DOMString? protocol;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>enumerateDevices is returning new MediaDeviceInfo objects every time</title>
|
||||
<script src=/resources/testharness.js></script>
|
||||
<script src=/resources/testharnessreport.js></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
function doTest(callGetUserMedia, testName)
|
||||
{
|
||||
promise_test(async () => {
|
||||
if (callGetUserMedia)
|
||||
await navigator.mediaDevices.getUserMedia({audio : true, video: true});
|
||||
|
||||
const deviceList1 = await navigator.mediaDevices.enumerateDevices();
|
||||
const deviceList2 = await navigator.mediaDevices.enumerateDevices();
|
||||
|
||||
assert_equals(deviceList1.length, deviceList2.length);
|
||||
for (let i = 0; i < deviceList1.length; i++) {
|
||||
const device1 = deviceList1[i];
|
||||
const device2 = deviceList2[i];
|
||||
assert_not_equals(device1, device2);
|
||||
assert_equals(device1.deviceId, device2.deviceId, "deviceId");
|
||||
assert_equals(device1.kind, device2.kind, "kind");
|
||||
}
|
||||
}, testName);
|
||||
}
|
||||
|
||||
doTest(false, "enumerateDevices returns new objects in case device-info permission is not granted");
|
||||
doTest(true, "enumerateDevices returns new objects in case device-info permission is granted");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,6 @@
|
|||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/native-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage-BroadcastChannel.js
|
|
@ -0,0 +1,8 @@
|
|||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/native-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-blob-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage-Error.js
|
|
@ -0,0 +1,7 @@
|
|||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/native-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-blob-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage-MessagePort.js
|
|
@ -0,0 +1,7 @@
|
|||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/native-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-blob-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage.js
|
|
@ -0,0 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
importScripts(
|
||||
'test-helpers.js',
|
||||
'messaging-serialize-helpers.js',
|
||||
'message-target.js'
|
||||
);
|
||||
|
||||
add_message_event_handlers(/*receiver=*/self, /*target=*/self);
|
|
@ -0,0 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
importScripts(
|
||||
'test-helpers.js',
|
||||
'messaging-serialize-helpers.js',
|
||||
'message-target.js'
|
||||
);
|
||||
|
||||
add_message_event_handlers(/*receiver=*/self);
|
|
@ -0,0 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
importScripts(
|
||||
'test-helpers.js',
|
||||
'messaging-serialize-helpers.js',
|
||||
'message-target.js'
|
||||
);
|
||||
|
||||
self.addEventListener('connect', connect_event => {
|
||||
const message_port = connect_event.ports[0];
|
||||
add_message_event_handlers(
|
||||
/*receiver=*/message_port, /*target=*/message_port);
|
||||
message_port.start();
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<script src='test-helpers.js'></script>
|
||||
<script src='messaging-serialize-helpers.js'></script>
|
||||
<script src='message-target.js'></script>
|
||||
<script id="inline_script">
|
||||
'use strict'
|
||||
|
||||
if (window.parent !== null) {
|
||||
window.parent.postMessage('LOADED', { targetOrigin: '*' });
|
||||
}
|
||||
|
||||
if (window.opener !== null) {
|
||||
window.opener.postMessage('LOADED', { targetOrigin: '*' });
|
||||
}
|
||||
|
||||
// Use an undefined message target to send responses to
|
||||
// MessageEvent::source instead.
|
||||
const target = undefined;
|
||||
|
||||
add_message_event_handlers(
|
||||
/*receiver=*/self, target, /*target_origin=*/'*');
|
||||
</script>
|
|
@ -0,0 +1,145 @@
|
|||
'use strict';
|
||||
|
||||
// This script depends on the following scripts:
|
||||
// /native-file-system/resources/messaging-helpers.js
|
||||
// /native-file-system/resources/test-helpers.js
|
||||
|
||||
// add_message_event_handlers() is the helper function used to setup all
|
||||
// message targets, including iframes and workers.
|
||||
//
|
||||
// Adds a message event handler and a message error handler to |receiver|.
|
||||
// The 'data' property from received MessageEvents must include a 'type'
|
||||
// property. The 'type' selects the test logic to run. Most message type
|
||||
// handlers use postMessage() to respond to the sender with test results.
|
||||
// The sender then validates the test results after receiving the response.
|
||||
//
|
||||
// Both |target| and |target_origin| are optional. |target| is used
|
||||
// to send message responses back to the sender. When omitted, the
|
||||
// 'source' from received MessageEvents is used instead.
|
||||
//
|
||||
// For window messaging, |target_origin| specifies the origin to receive
|
||||
// responses. Most window tests use '*' for the |target_origin|. Worker
|
||||
// and message port tests must use undefined for |target_origin| to avoid
|
||||
// exceptions.
|
||||
function add_message_event_handlers(receiver, target, target_origin) {
|
||||
receiver.addEventListener('message', async function (message_event) {
|
||||
const message_data = message_event.data;
|
||||
|
||||
// Reply to the sender using the 'source' from the received MessageEvent.
|
||||
let message_source = message_event.source;
|
||||
if (message_source === null) {
|
||||
// However, some message senders, like DedicatedWorkers, don't include
|
||||
// a source. Fallback to the target when the source is null.
|
||||
message_source = target;
|
||||
}
|
||||
|
||||
try {
|
||||
switch (message_data.type) {
|
||||
case 'receive-message-port':
|
||||
// Receive a MessagePort to use as a message target for testing.
|
||||
add_message_event_handlers(
|
||||
/*receiver=*/message_data.message_port,
|
||||
/*target=*/message_data.message_port);
|
||||
message_data.message_port.start();
|
||||
break;
|
||||
|
||||
case 'create-broadcast-channel':
|
||||
// Create a BroadcastChannel to use as a message target for testing.
|
||||
const broadcast_channel =
|
||||
new BroadcastChannel(message_data.broadcast_channel_name);
|
||||
add_message_event_handlers(
|
||||
/*receiver=*/broadcast_channel,
|
||||
/*target=*/broadcast_channel);
|
||||
message_source.postMessage(
|
||||
{ type: 'broadcast-channel-created' },
|
||||
{ targetOrigin: target_origin });
|
||||
break;
|
||||
|
||||
case 'receive-file-system-handles':
|
||||
// Receive a list of cloned FileSystemFileHandles. Access the
|
||||
// properties of each FileSystemFileHandle by serializing the
|
||||
// handle to a JavaScript object. Then respond with the serialized
|
||||
// results, enabling the sender to verify that the cloned handle
|
||||
// produced the expected property values from this execution context.
|
||||
const serialized_handles = [];
|
||||
const cloned_handles = message_data.cloned_handles;
|
||||
for (let i = 0; i < cloned_handles.length; ++i) {
|
||||
const serialized = await serialize_handle(cloned_handles[i]);
|
||||
serialized_handles.push(serialized);
|
||||
}
|
||||
message_source.postMessage({
|
||||
type: 'receive-serialized-file-system-handles',
|
||||
serialized_handles,
|
||||
// Respond with the cloned handles to create new clones for
|
||||
// the sender to verify.
|
||||
cloned_handles,
|
||||
}, { targetOrigin: target_origin });
|
||||
break;
|
||||
|
||||
case 'receive-serialized-file-system-handles':
|
||||
// Do nothing. This message is meant for test runner validation.
|
||||
// Other message targets may receive this message while testing
|
||||
// broadcast channels.
|
||||
break;
|
||||
|
||||
case 'create-file':
|
||||
// Create a new file and then respond to the sender with it.
|
||||
const directory =
|
||||
await FileSystemDirectoryHandle.getSystemDirectory(
|
||||
{ type: 'sandbox' });
|
||||
const file_handle =
|
||||
await directory.getFile('temp-file', { create: true });
|
||||
message_source.postMessage(
|
||||
{ type: 'receive-file', file_handle },
|
||||
{ targetOrigin: target_origin });
|
||||
break;
|
||||
|
||||
case 'create-directory':
|
||||
// Create a new directory and then respond to the sender with it.
|
||||
const parent_directory =
|
||||
await FileSystemDirectoryHandle.getSystemDirectory(
|
||||
{ type: 'sandbox' });
|
||||
const directory_handle =
|
||||
await parent_directory.getDirectory('temp-directory',
|
||||
{ create: true });
|
||||
message_source.postMessage(
|
||||
{ type: 'receive-directory', directory_handle },
|
||||
{ targetOrigin: target_origin });
|
||||
break;
|
||||
|
||||
default:
|
||||
throw `Unknown message type: '${message_data.type}'`;
|
||||
}
|
||||
} catch (error) {
|
||||
// Respond with an error to trigger a failure in the sender's
|
||||
// test runner.
|
||||
message_source.postMessage(`ERROR: ${error}`,
|
||||
{ targetOrigin: target_origin });
|
||||
}
|
||||
});
|
||||
|
||||
receiver.addEventListener('messageerror', async function (message_event) {
|
||||
// Select the target for message responses (see comment in 'message' event
|
||||
// listener above).
|
||||
let message_source = message_event.source;
|
||||
if (message_source === null) {
|
||||
message_source = target;
|
||||
}
|
||||
|
||||
try {
|
||||
// Respond with the MessageEvent's property values, enabling the sender
|
||||
// to verify results.
|
||||
const serialized_message_error_event =
|
||||
serialize_message_error_event(message_event);
|
||||
message_source.postMessage({
|
||||
type: 'serialized-message-error',
|
||||
serialized_message_error_event
|
||||
}, { targetOrigin: target_origin });
|
||||
} catch (error) {
|
||||
// Respond with an error to trigger a failure in the sender's
|
||||
// test runner.
|
||||
message_source.postMessage(`ERROR: ${error}`,
|
||||
{ targetOrigin: target_origin });
|
||||
}
|
||||
});
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
'use strict';
|
||||
|
||||
// Creates a blob URL with the contents of 'message-target.html'. Use the
|
||||
// blob as an iframe src or a window.open() URL, which creates a same origin
|
||||
// message target.
|
||||
async function create_message_target_blob_url(test) {
|
||||
const html = await create_message_target_html_without_subresources(test);
|
||||
const blob = new Blob([html], { type: 'text/html' });
|
||||
return URL.createObjectURL(blob);
|
||||
}
|
||||
|
||||
// Creates a data URI with the contents of 'message-target.html'. Use the
|
||||
// data URI as an iframe src, which creates a cross origin message target.
|
||||
async function create_message_target_data_uri(test) {
|
||||
const iframe_html =
|
||||
await create_message_target_html_without_subresources(test);
|
||||
return `data:text/html,${encodeURIComponent(iframe_html)}`;
|
||||
}
|
||||
|
||||
// Constructs a version of 'message-target.html' without any subresources.
|
||||
// Enables the creation of blob URLs, data URIs and iframe srcdocs re-using
|
||||
// the contents of 'message-target.html'.
|
||||
async function create_message_target_html_without_subresources(test) {
|
||||
const test_helpers_script = await fetch_text('resources/test-helpers.js');
|
||||
|
||||
const messaging_helpers_script =
|
||||
await fetch_text('resources/messaging-helpers.js');
|
||||
|
||||
const messaging_serialize_helpers_script =
|
||||
await fetch_text('resources/messaging-serialize-helpers.js');
|
||||
|
||||
const message_target_script =
|
||||
await fetch_text('resources/message-target.js');
|
||||
|
||||
// Get the inline script code from 'message-target.html'.
|
||||
const iframe = await add_iframe(test, { src: 'resources/message-target.html' });
|
||||
const iframe_script =
|
||||
iframe.contentWindow.document.getElementById('inline_script').outerHTML;
|
||||
iframe.remove();
|
||||
|
||||
return '<!DOCTYPE html>' +
|
||||
`<script>${test_helpers_script}</script>` +
|
||||
`<script>${messaging_serialize_helpers_script}</script>` +
|
||||
`<script>${message_target_script}</script>` +
|
||||
`${iframe_script}`;
|
||||
}
|
||||
|
||||
async function fetch_text(url) {
|
||||
const response = await fetch(url);
|
||||
return await response.text();
|
||||
}
|
|
@ -0,0 +1,177 @@
|
|||
'use strict';
|
||||
|
||||
// This script depends on the following script:
|
||||
// /native-file-system/resources/test-helpers.js
|
||||
// /service-workers/service-worker/resources/test-helpers.sub.js
|
||||
|
||||
// Define the URL constants used for each type of message target, including
|
||||
// iframes and workers.
|
||||
const kDocumentMessageTarget = 'resources/message-target.html';
|
||||
const kSharedWorkerMessageTarget = 'resources/message-target-shared-worker.js';
|
||||
const kServiceWorkerMessageTarget =
|
||||
'resources/message-target-service-worker.js';
|
||||
const kDedicatedWorkerMessageTarget =
|
||||
'resources/message-target-dedicated-worker.js';
|
||||
|
||||
function create_dedicated_worker(test, url) {
|
||||
const dedicated_worker = new Worker(url);
|
||||
test.add_cleanup(() => {
|
||||
dedicated_worker.terminate();
|
||||
});
|
||||
return dedicated_worker;
|
||||
}
|
||||
|
||||
async function create_service_worker(test, script_url, scope) {
|
||||
const registration = await service_worker_unregister_and_register(
|
||||
test, script_url, scope);
|
||||
test.add_cleanup(() => {
|
||||
return registration.unregister();
|
||||
});
|
||||
return registration;
|
||||
}
|
||||
|
||||
// Creates an iframe and waits to receive a message from the iframe.
|
||||
// Valid |options| include src, srcdoc and sandbox, which mirror the
|
||||
// corresponding iframe element properties.
|
||||
async function add_iframe(test, options) {
|
||||
const iframe = document.createElement('iframe');
|
||||
|
||||
if (options.sandbox !== undefined) {
|
||||
iframe.sandbox = options.sandbox;
|
||||
}
|
||||
|
||||
if (options.src !== undefined) {
|
||||
iframe.src = options.src;
|
||||
}
|
||||
|
||||
if (options.srcdoc !== undefined) {
|
||||
iframe.srcdoc = options.srcdoc;
|
||||
}
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
test.add_cleanup(() => {
|
||||
iframe.remove();
|
||||
});
|
||||
|
||||
await wait_for_loaded_message(self);
|
||||
return iframe;
|
||||
}
|
||||
|
||||
// Creates a child window using window.open() and waits to receive a message
|
||||
// from the child window.
|
||||
async function open_window(test, url) {
|
||||
const child_window = window.open(url);
|
||||
test.add_cleanup(() => {
|
||||
child_window.close();
|
||||
});
|
||||
await wait_for_loaded_message(self);
|
||||
return child_window;
|
||||
}
|
||||
|
||||
// Wait until |receiver| gets a message event with the data set to 'LOADED'.
|
||||
// The postMessage() tests use messaging instead of the loaded event because
|
||||
// cross-origin child windows from window.open() do not dispatch the loaded
|
||||
// event to the parent window.
|
||||
async function wait_for_loaded_message(receiver) {
|
||||
const message_promise = new Promise((resolve, reject) => {
|
||||
receiver.addEventListener('message', message_event => {
|
||||
if (message_event.data === 'LOADED') {
|
||||
resolve();
|
||||
} else {
|
||||
reject('The message target must receive a "LOADED" message response.');
|
||||
}
|
||||
});
|
||||
});
|
||||
await message_promise;
|
||||
}
|
||||
|
||||
// Sets up a new message channel. Sends one port to |target| and then returns
|
||||
// the other port.
|
||||
function create_message_channel(target, target_origin) {
|
||||
const message_channel = new MessageChannel();
|
||||
|
||||
const message_data =
|
||||
{ type: 'receive-message-port', message_port: message_channel.port2 };
|
||||
target.postMessage(
|
||||
message_data,
|
||||
{
|
||||
transfer: [message_channel.port2],
|
||||
targetOrigin: target_origin
|
||||
});
|
||||
message_channel.port1.start();
|
||||
return message_channel.port1;
|
||||
}
|
||||
|
||||
// Creates a variety of different FileSystemFileHandles for testing.
|
||||
async function create_file_system_handles(test, root) {
|
||||
// Create some files to use with postMessage().
|
||||
const empty_file = await createEmptyFile(test, 'empty-file', root);
|
||||
const first_file = await createFileWithContents(
|
||||
test, 'first-file-with-contents', 'first-text-content', root);
|
||||
const second_file = await createFileWithContents(
|
||||
test, 'second-file-with-contents', 'second-text-content', root);
|
||||
|
||||
// Create an empty directory to use with postMessage().
|
||||
const empty_directory = await createDirectory(test, 'empty-directory', root);
|
||||
|
||||
// Create a directory containing both files and subdirectories to use
|
||||
// with postMessage().
|
||||
const directory_with_files =
|
||||
await createDirectory(test, 'directory-with-files', root);
|
||||
await createFileWithContents(test, 'first-file-in-directory',
|
||||
'first-directory-text-content', directory_with_files);
|
||||
await createFileWithContents(test, 'second-file-in-directory',
|
||||
'second-directory-text-content', directory_with_files);
|
||||
const subdirectory =
|
||||
await createDirectory(test, 'subdirectory', directory_with_files);
|
||||
await createFileWithContents(test, 'first-file-in-subdirectory',
|
||||
'first-subdirectory-text-content', subdirectory);
|
||||
|
||||
return [
|
||||
empty_file,
|
||||
first_file,
|
||||
second_file,
|
||||
// Include the same FileSystemFileHandle twice.
|
||||
second_file,
|
||||
empty_directory,
|
||||
// Include the Same FileSystemDirectoryHandle object twice.
|
||||
empty_directory,
|
||||
directory_with_files
|
||||
];
|
||||
}
|
||||
|
||||
// Tests sending an array of FileSystemHandles to |target| with postMessage().
|
||||
// The array includes both FileSystemFileHandles and FileSystemDirectoryHandles.
|
||||
// After receiving the message, |target| accesses all cloned handles by
|
||||
// serializing the properties of each handle to a JavaScript object.
|
||||
//
|
||||
// |target| then responds with the resulting array of serialized handles. The
|
||||
// response also includes the array of cloned handles, which creates more
|
||||
// clones. After receiving the response, this test runner verifies that both
|
||||
// the serialized handles and the cloned handles contain the expected properties.
|
||||
async function do_post_message_test(
|
||||
test, root_dir, receiver, target, target_origin) {
|
||||
// Create and send the handles to |target|.
|
||||
const handles =
|
||||
await create_file_system_handles(test, root_dir, target, target_origin);
|
||||
target.postMessage(
|
||||
{ type: 'receive-file-system-handles', cloned_handles: handles },
|
||||
{ targetOrigin: target_origin });
|
||||
|
||||
// Wait for |target| to respond with results.
|
||||
const event_watcher = new EventWatcher(test, receiver, 'message');
|
||||
const message_event = await event_watcher.wait_for('message');
|
||||
const response = message_event.data;
|
||||
|
||||
assert_equals(response.type, 'receive-serialized-file-system-handles',
|
||||
'The test runner must receive a "serialized-file-system-handles" ' +
|
||||
`message response. Actual response: ${response}`);
|
||||
|
||||
// Verify the results.
|
||||
const expected_serialized_handles = await serialize_handles(handles);
|
||||
|
||||
assert_equals_serialized_handles(
|
||||
response.serialized_handles, expected_serialized_handles);
|
||||
|
||||
await assert_equals_cloned_handles(response.cloned_handles, handles);
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
'use strict';
|
||||
|
||||
// This script depends on the following script:
|
||||
// /native-file-system/resources/test-helpers.js
|
||||
|
||||
// Serializes an array of FileSystemHandles where each element can be either a
|
||||
// FileSystemFileHandle or FileSystemDirectoryHandle.
|
||||
async function serialize_handles(handle_array) {
|
||||
const serialized_handle_array = [];
|
||||
for (let i = 0; i < handle_array.length; ++i) {
|
||||
serialized_handle_array.push(await serialize_handle(handle_array[i]));
|
||||
}
|
||||
return serialized_handle_array;
|
||||
}
|
||||
|
||||
// Serializes either a FileSystemFileHandle or FileSystemDirectoryHandle.
|
||||
async function serialize_handle(handle) {
|
||||
let serialized;
|
||||
if (handle.isDirectory) {
|
||||
serialized = await serialize_file_system_directory_handle(handle);
|
||||
} else if (handle.isFile) {
|
||||
serialized = await serialize_file_system_file_handle(handle);
|
||||
} else {
|
||||
throw 'Object is not a FileSystemFileHandle or ' +
|
||||
`FileSystemDirectoryHandle ${handle}`;
|
||||
}
|
||||
return serialized;
|
||||
}
|
||||
|
||||
// Creates a dictionary for a FileSystemHandle base, which contains
|
||||
// serialized properties shared by both FileSystemFileHandle and
|
||||
// FileSystemDirectoryHandle.
|
||||
async function serialize_file_system_handle(handle) {
|
||||
const read_permission =
|
||||
await handle.queryPermission({ writable: false });
|
||||
|
||||
const write_permission =
|
||||
await handle.queryPermission({ writable: true })
|
||||
|
||||
return {
|
||||
is_file: handle.isFile,
|
||||
is_directory: handle.isDirectory,
|
||||
name: handle.name,
|
||||
read_permission,
|
||||
write_permission
|
||||
};
|
||||
}
|
||||
|
||||
// Create a dictionary with each property value in FileSystemFileHandle.
|
||||
// Also, reads the contents of the file to include with the returned
|
||||
// dictionary. Example output:
|
||||
// {
|
||||
// is_file: true,
|
||||
// is_directory: false,
|
||||
// name: "example-file-name"
|
||||
// read_permission: "granted",
|
||||
// write_permission: "granted",
|
||||
// contents: "example-file-contents"
|
||||
// }
|
||||
async function serialize_file_system_file_handle(file_handle) {
|
||||
const contents = await getFileContents(file_handle);
|
||||
|
||||
const serialized_file_system_handle =
|
||||
await serialize_file_system_handle(file_handle);
|
||||
|
||||
return Object.assign(serialized_file_system_handle, { contents });
|
||||
}
|
||||
|
||||
// Create a dictionary with each property value in FileSystemDirectoryHandle.
|
||||
// Example output:
|
||||
// {
|
||||
// is_file: false,
|
||||
// is_directory: true,
|
||||
// name: "example-directory-name"
|
||||
// read_permission: "granted",
|
||||
// write_permission: "granted",
|
||||
// files: [<first serialized file>, ...]
|
||||
// directories: [<first serialized subdirectory>, ...]
|
||||
// }
|
||||
async function serialize_file_system_directory_handle(directory_handle) {
|
||||
// Serialize the contents of the directory.
|
||||
const serialized_files = [];
|
||||
const serialized_directories = [];
|
||||
for await (const child_handle of directory_handle.getEntries()) {
|
||||
const serialized_child_handle = await serialize_handle(child_handle);
|
||||
if (child_handle.isDirectory) {
|
||||
serialized_directories.push(serialized_child_handle);
|
||||
} else {
|
||||
serialized_files.push(serialized_child_handle);
|
||||
}
|
||||
}
|
||||
|
||||
// Order the serialized contents of the directory by name.
|
||||
serialized_files.sort((left, right) => {
|
||||
return left.name.localeCompare(right.name);
|
||||
});
|
||||
serialized_directories.sort((left, right) => {
|
||||
return left.name.localeCompare(right.name);
|
||||
});
|
||||
|
||||
// Serialize the directory's common properties shared by all
|
||||
// FileSystemHandles.
|
||||
const serialized_file_system_handle =
|
||||
await serialize_file_system_handle(directory_handle);
|
||||
|
||||
return Object.assign(
|
||||
serialized_file_system_handle,
|
||||
{ files: serialized_files, directories: serialized_directories });
|
||||
}
|
||||
|
||||
// Verifies |left_array| is a clone of |right_array| where each element
|
||||
// is a cloned FileSystemHandle with the same properties and contents.
|
||||
async function assert_equals_cloned_handles(left_array, right_array) {
|
||||
assert_equals(left_array.length, right_array.length,
|
||||
'Each array of FileSystemHandles must have the same length');
|
||||
|
||||
for (let i = 0; i < left_array.length; ++i) {
|
||||
assert_not_equals(left_array[i], right_array[i],
|
||||
'Clones must create new FileSystemHandle instances.');
|
||||
|
||||
const left_serialized = await serialize_handle(left_array[i]);
|
||||
const right_serialized = await serialize_handle(right_array[i]);
|
||||
assert_equals_serialized_handle(left_serialized, right_serialized);
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies |left_array| is the same as |right_array| where each element
|
||||
// is a serialized FileSystemHandle with the same properties.
|
||||
function assert_equals_serialized_handles(left_array, right_array) {
|
||||
assert_equals(left_array.length, right_array.length,
|
||||
'Each array of serialized handles must have the same length');
|
||||
|
||||
for (let i = 0; i < left_array.length; ++i) {
|
||||
assert_equals_serialized_handle(left_array[i], right_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Verifies each property of a serialized FileSystemFileHandle or
|
||||
// FileSystemDirectoryHandle.
|
||||
function assert_equals_serialized_handle(left, right) {
|
||||
if (left.is_directory) {
|
||||
assert_equals_serialized_file_system_directory_handle(left, right);
|
||||
} else if (left.is_file) {
|
||||
assert_equals_serialized_file_system_file_handle(left, right);
|
||||
} else {
|
||||
throw 'Object is not a FileSystemFileHandle or ' +
|
||||
`FileSystemDirectoryHandle ${handle}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Compares the output of serialize_file_system_handle() for
|
||||
// two FileSystemHandles.
|
||||
function assert_equals_serialized_file_system_handle(left, right) {
|
||||
assert_equals(left.is_file, right.is_file,
|
||||
'Each FileSystemHandle instance must use the expected "isFile".');
|
||||
|
||||
assert_equals(left.is_directory, right.is_directory,
|
||||
'Each FileSystemHandle instance must use the expected "isDirectory".');
|
||||
|
||||
assert_equals(left.name, right.name,
|
||||
'Each FileSystemHandle instance must use the expected "name" ' +
|
||||
' property.');
|
||||
|
||||
assert_equals(left.read_permission, right.read_permission,
|
||||
'Each FileSystemHandle instance must have the expected read ' +
|
||||
' permission.');
|
||||
|
||||
assert_equals(left.write_permission, right.write_permission,
|
||||
'Each FileSystemHandle instance must have the expected write ' +
|
||||
' permission.');
|
||||
}
|
||||
|
||||
// Compares the output of serialize_file_system_file_handle()
|
||||
// for two FileSystemFileHandle.
|
||||
function assert_equals_serialized_file_system_file_handle(left, right) {
|
||||
assert_equals_serialized_file_system_handle(left, right);
|
||||
assert_equals(left.contents, right.contents,
|
||||
'Each FileSystemFileHandle instance must have the same contents.');
|
||||
}
|
||||
|
||||
// Compares the output of serialize_file_system_directory_handle()
|
||||
// for two FileSystemDirectoryHandles.
|
||||
function assert_equals_serialized_file_system_directory_handle(left, right) {
|
||||
assert_equals_serialized_file_system_handle(left, right);
|
||||
|
||||
assert_equals(left.files.length, right.files.length,
|
||||
'Each FileSystemDirectoryHandle must contain the same number of ' +
|
||||
'file children');
|
||||
|
||||
for (let i = 0; i < left.files.length; ++i) {
|
||||
assert_equals_serialized_file_system_file_handle(
|
||||
left.files[i], right.files[i]);
|
||||
}
|
||||
|
||||
assert_equals(left.directories.length, right.directories.length,
|
||||
'Each FileSystemDirectoryHandle must contain the same number of ' +
|
||||
'directory children');
|
||||
|
||||
for (let i = 0; i < left.directories.length; ++i) {
|
||||
assert_equals_serialized_file_system_directory_handle(
|
||||
left.directories[i], right.directories[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates a dictionary with interesting property values from MessageEvent.
|
||||
function serialize_message_error_event(message_error_event) {
|
||||
return {
|
||||
data: message_error_event.data,
|
||||
origin: message_error_event.origin,
|
||||
last_event_id: message_error_event.lastEventId,
|
||||
has_source: (message_error_event.source !== null),
|
||||
ports_length: message_error_event.ports.length
|
||||
};
|
||||
}
|
||||
|
||||
// Compares the output of serialize_message_error_event() with an
|
||||
// expected result.
|
||||
function assert_equals_serialized_message_error_event(
|
||||
serialized_event, expected_origin, expected_has_source) {
|
||||
assert_equals(serialized_event.data, null,
|
||||
'The message error event must set the "data" property to null.');
|
||||
|
||||
assert_equals(serialized_event.origin, expected_origin,
|
||||
'The message error event must have the expected "origin" property.');
|
||||
|
||||
assert_equals(serialized_event.last_event_id, "",
|
||||
'The message error event must set the "lastEventId" property to the empty string.');
|
||||
|
||||
assert_equals(serialized_event.has_source, expected_has_source,
|
||||
'The message error event must have the expected "source" property.');
|
||||
|
||||
assert_equals(serialized_event.ports_length, 0,
|
||||
'The message error event must not contain any message ports.');
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/sandboxed-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage-BroadcastChannel.js
|
|
@ -0,0 +1,8 @@
|
|||
// META: script=/common/get-host-info.sub.js
|
||||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/sandboxed-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-blob-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage-Error.js
|
|
@ -0,0 +1,7 @@
|
|||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/sandboxed-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-blob-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage-MessagePort.js
|
|
@ -0,0 +1,7 @@
|
|||
// META: script=/service-workers/service-worker/resources/test-helpers.sub.js
|
||||
// META: script=resources/test-helpers.js
|
||||
// META: script=resources/sandboxed-fs-test-helpers.js
|
||||
// META: script=resources/messaging-helpers.js
|
||||
// META: script=resources/messaging-blob-helpers.js
|
||||
// META: script=resources/messaging-serialize-helpers.js
|
||||
// META: script=script-tests/FileSystemBaseHandle-postMessage.js
|
|
@ -0,0 +1,82 @@
|
|||
'use strict';
|
||||
|
||||
// This script depends on the following scripts:
|
||||
// /native-file-system/resources/messaging-helpers.js
|
||||
// /native-file-system/resources/messaging-serialize-helpers.js
|
||||
// /native-file-system/resources/test-helpers.js
|
||||
// /service-workers/service-worker/resources/test-helpers.sub.js
|
||||
|
||||
// Sets up a new broadcast channel in |target|. Posts a message instructing
|
||||
// |target| to open the broadcast channel using |broadcast_channel_name|.
|
||||
async function create_broadcast_channel(
|
||||
test, broadcast_channel_name, receiver, target, target_origin) {
|
||||
target.postMessage(
|
||||
{ type: 'create-broadcast-channel', broadcast_channel_name },
|
||||
{ targetOrigin: target_origin });
|
||||
const event_watcher = new EventWatcher(test, receiver, 'message');
|
||||
|
||||
// Wait until |target| is listening to the broad cast channel.
|
||||
const message_event = await event_watcher.wait_for('message');
|
||||
assert_equals(message_event.data.type, 'broadcast-channel-created',
|
||||
'The message target must receive a "broadcast-channel-created" message ' +
|
||||
'response.');
|
||||
}
|
||||
|
||||
// This test is very similar to 'FileSystemBaseHandle-postMessage.js'. It
|
||||
// starts by creating three message targets for the broadcast channel:
|
||||
// an iframe, dedicated worker and a service worker. After setup, an array
|
||||
// of FileSystemHandles is sent across the broadcast channel. The test
|
||||
// expects three responses -- one from each message target.
|
||||
directory_test(async (t, root) => {
|
||||
const broadcast_channel_name = 'file-system-file-handle-channel';
|
||||
const broadcast_channel = new BroadcastChannel(broadcast_channel_name);
|
||||
const broadcast_channel_event_watcher =
|
||||
new EventWatcher(t, broadcast_channel, 'message');
|
||||
|
||||
const iframe = await add_iframe(t, { src: kDocumentMessageTarget });
|
||||
await create_broadcast_channel(
|
||||
t, broadcast_channel_name, self, iframe.contentWindow, '*');
|
||||
|
||||
const scope = `${kServiceWorkerMessageTarget}` +
|
||||
'?post-message-to-broadcast-channel-with-file-handle';
|
||||
|
||||
const registration = await create_service_worker(
|
||||
t, kServiceWorkerMessageTarget, scope);
|
||||
|
||||
await create_broadcast_channel(
|
||||
t, broadcast_channel_name,
|
||||
navigator.serviceWorker, registration.installing);
|
||||
|
||||
const dedicated_worker =
|
||||
create_dedicated_worker(t, kDedicatedWorkerMessageTarget);
|
||||
|
||||
await create_broadcast_channel(
|
||||
t, broadcast_channel_name, dedicated_worker, dedicated_worker);
|
||||
|
||||
const handles = await create_file_system_handles(t, root);
|
||||
|
||||
broadcast_channel.postMessage(
|
||||
{ type: 'receive-file-system-handles', cloned_handles: handles });
|
||||
|
||||
const expected_response_count = 3;
|
||||
const responses = [];
|
||||
for (let i = 0; i < expected_response_count; ++i) {
|
||||
const message_event =
|
||||
await broadcast_channel_event_watcher.wait_for('message');
|
||||
responses.push(message_event.data);
|
||||
}
|
||||
|
||||
const expected_serialized_handles = await serialize_handles(handles);
|
||||
|
||||
for (let i = 0; i < responses.length; ++i) {
|
||||
assert_equals(responses[i].type, 'receive-serialized-file-system-handles',
|
||||
'The test runner must receive a "serialized-file-system-handles" ' +
|
||||
`message response. Actual response: ${responses[i]}`);
|
||||
|
||||
assert_equals_serialized_handles(
|
||||
responses[i].serialized_handles, expected_serialized_handles);
|
||||
|
||||
await assert_equals_cloned_handles(responses[i].cloned_handles, handles);
|
||||
}
|
||||
}, 'Send and receive messages using a broadcast channel in an iframe, ' +
|
||||
'dedicated worker and service worker.');
|
|
@ -0,0 +1,272 @@
|
|||
'use strict';
|
||||
|
||||
// This script depends on the following scripts:
|
||||
// /native-file-system/resources/messaging-helpers.js
|
||||
// /native-file-system/resources/messaging-blob-helpers.js
|
||||
// /native-file-system/resources/messaging-serialize-helpers.js
|
||||
// /native-file-system/resources/test-helpers.js
|
||||
// /common/get-host-info.sub.js
|
||||
// /service-workers/service-worker/resources/test-helpers.sub.js
|
||||
|
||||
// Define URL constants for cross origin windows.
|
||||
const kRemoteOrigin = get_host_info().HTTPS_REMOTE_ORIGIN;
|
||||
const kRemoteOriginDocumentMessageTarget = `${kRemoteOrigin}${base_path()}` +
|
||||
kDocumentMessageTarget;
|
||||
|
||||
// Sending a FileSystemHandle to a cross origin |target| through postMessage()
|
||||
// must dispatch the 'messageerror' event.
|
||||
//
|
||||
// This test sends a FileSystemHandle to |target|. |target| responds with a
|
||||
// serialized MessageEvent from the 'messageerror' event, allowing the test
|
||||
// runner to verify MessageEvent properties.
|
||||
async function do_send_message_error_test(
|
||||
test,
|
||||
root_dir,
|
||||
receiver,
|
||||
target,
|
||||
target_origin,
|
||||
// False when the MessageEvent's source is null.
|
||||
expected_has_source,
|
||||
// The origin of MessageEvents received by |target|.
|
||||
expected_origin) {
|
||||
const message_watcher = new EventWatcher(test, receiver, 'message');
|
||||
|
||||
// Send a file to |target|.
|
||||
const file = await createFileWithContents(
|
||||
test, 'test-error-file', 'test-error-file-contents', root_dir);
|
||||
target.postMessage(
|
||||
{ type: 'receive-file-system-handles', cloned_file_system_handles: [file] },
|
||||
{ targetOrigin: target_origin });
|
||||
|
||||
// Wait for |target| to respond with results.
|
||||
let message_event = await message_watcher.wait_for('message');
|
||||
const first_response = message_event.data;
|
||||
assert_equals(first_response.type, 'serialized-message-error',
|
||||
'The test runner must receive a "serialized-message-error" message ' +
|
||||
'in response to a FileSystemFileHandle message.');
|
||||
|
||||
// Verify the results.
|
||||
assert_equals_serialized_message_error_event(
|
||||
first_response.serialized_message_error_event,
|
||||
expected_origin, expected_has_source);
|
||||
|
||||
// Send a directory to |target|.
|
||||
const directory = await createDirectory(
|
||||
test, 'test-error-directory', root_dir);
|
||||
|
||||
target.postMessage(
|
||||
{
|
||||
type: 'receive-file-system-handles',
|
||||
cloned_file_system_handles: [directory]
|
||||
}, { targetOrigin: target_origin });
|
||||
|
||||
// Wait for |target| to respond with results.
|
||||
message_event = await message_watcher.wait_for('message');
|
||||
const second_response = message_event.data;
|
||||
assert_equals(second_response.type, 'serialized-message-error',
|
||||
'The test runner must receive a "serialized-message-error" message ' +
|
||||
'response to a FileSystemDirectoryHandle message.');
|
||||
|
||||
// Verify the results.
|
||||
assert_equals_serialized_message_error_event(
|
||||
second_response.serialized_message_error_event,
|
||||
expected_origin, expected_has_source);
|
||||
}
|
||||
|
||||
// This test receives a FileSystemHandle from |target|. This test runner
|
||||
// must dispatch the 'messageerror' event after receiving a handle from target.
|
||||
async function do_receive_message_error_test(
|
||||
test,
|
||||
receiver,
|
||||
target,
|
||||
target_origin,
|
||||
// False when the MessageEvent's source is null.
|
||||
expected_has_source,
|
||||
// The origin of MessageEvents received by this test runner.
|
||||
expected_origin) {
|
||||
const error_watcher = new EventWatcher(test, receiver, 'messageerror');
|
||||
|
||||
// Receive a file from |target|.
|
||||
target.postMessage(
|
||||
{ type: 'create-file' }, { targetOrigin: target_origin });
|
||||
const first_error = await error_watcher.wait_for('messageerror');
|
||||
const serialized_first_error = serialize_message_error_event(first_error);
|
||||
assert_equals_serialized_message_error_event(
|
||||
serialized_first_error, expected_origin, expected_has_source);
|
||||
|
||||
// Receive a directory from |target|.
|
||||
target.postMessage(
|
||||
{ type: 'create-directory' }, { targetOrigin: target_origin });
|
||||
const second_error = await error_watcher.wait_for('messageerror');
|
||||
const serialized_second_error = serialize_message_error_event(second_error);
|
||||
assert_equals_serialized_message_error_event(
|
||||
serialized_second_error, expected_origin, expected_has_source);
|
||||
}
|
||||
|
||||
// Performs the send message error test followed by the receive message error
|
||||
// test.
|
||||
async function do_send_and_receive_message_error_test(
|
||||
test,
|
||||
root_dir,
|
||||
receiver,
|
||||
target,
|
||||
target_origin,
|
||||
// False when the MessageEvent's source is null.
|
||||
expected_has_source,
|
||||
// The origin of MessageEvents received by |target|.
|
||||
expected_origin,
|
||||
// The origin of MessageEvents received by this test runner.
|
||||
expected_remote_origin) {
|
||||
await do_send_message_error_test(
|
||||
test, root_dir, receiver, target, target_origin, expected_has_source,
|
||||
expected_origin);
|
||||
await do_receive_message_error_test(
|
||||
test, receiver, target, target_origin, expected_has_source,
|
||||
expected_remote_origin);
|
||||
}
|
||||
|
||||
// Runs the same test as do_send_message_error_test(), but uses a MessagePort.
|
||||
// This test starts by establishing a message channel between the test runner
|
||||
// and |target|.
|
||||
async function do_send_message_port_error_test(
|
||||
test, root_dir, target, target_origin) {
|
||||
const message_port = create_message_channel(target, target_origin);
|
||||
await do_send_message_error_test(
|
||||
test, root_dir, /*receiver=*/message_port, /*target=*/message_port,
|
||||
/*target_origin=*/undefined, /*expected_has_source=*/false,
|
||||
/*expected_origin=*/'', /*expected_remote_origin=*/'');
|
||||
}
|
||||
|
||||
// Runs the same test as do_receive_message_error_test(), but uses a MessagePort.
|
||||
async function do_receive_message_port_error_test(
|
||||
test, target, target_origin) {
|
||||
const message_port = create_message_channel(target, target_origin);
|
||||
await do_receive_message_error_test(
|
||||
test, /*receiver=*/message_port, /*target=*/message_port,
|
||||
/*target_origin=*/undefined, /*expected_has_source=*/false,
|
||||
/*expected_origin=*/'');
|
||||
}
|
||||
|
||||
// Runs the same test as do_send_and_receive_message_error_test(), but uses a
|
||||
// MessagePort.
|
||||
async function do_send_and_receive_message_port_error_test(
|
||||
test, root_dir, target, target_origin) {
|
||||
await do_send_message_port_error_test(
|
||||
test, root_dir, target, target_origin);
|
||||
await do_receive_message_port_error_test(
|
||||
test, target, target_origin);
|
||||
}
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(
|
||||
t, { src: kRemoteOriginDocumentMessageTarget });
|
||||
await do_send_and_receive_message_error_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow,
|
||||
/*target_origin=*/'*', /*expected_has_source=*/true,
|
||||
/*expected_origin=*/location.origin,
|
||||
/*expected_remote_origin=*/kRemoteOrigin);
|
||||
}, 'Fail to send and receive messages using a cross origin iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(t, { src: kRemoteOriginDocumentMessageTarget });
|
||||
await do_send_and_receive_message_port_error_test(
|
||||
t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
}, 'Fail to send and receive messages using a cross origin message port in ' +
|
||||
'an iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(
|
||||
t, { src: kDocumentMessageTarget, sandbox: 'allow-scripts' });
|
||||
|
||||
await do_send_message_error_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow,
|
||||
/*target_origin=*/'*', /*expected_has_source*/true,
|
||||
/*expected_origin=*/location.origin);
|
||||
|
||||
// https://crbug.com/1014248 Should sandboxed iframes expose the
|
||||
// NativeFileSystem?
|
||||
//
|
||||
// await do_receive_message_error_test(
|
||||
// t, /*receiver=*/self, /*target=*/iframe.contentWindow,
|
||||
// /*target_origin=*/'*', /*expected_has_source=*/true,
|
||||
// /*expected_origin=*/kRemoteOrigin);
|
||||
}, 'Fail to send and receive messages using a sandboxed iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(
|
||||
t, { src: kDocumentMessageTarget, sandbox: 'allow-scripts' });
|
||||
await do_send_message_port_error_test(
|
||||
t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
|
||||
// https://crbug.com/1014248 Should sandboxed iframes expose the
|
||||
// NativeFileSystem?
|
||||
//
|
||||
// await do_receive_message_port_error_test(
|
||||
// t, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
}, 'Fail to send and receive messages using a message port in a sandboxed ' +
|
||||
'iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe_data_uri = await create_message_target_data_uri(t);
|
||||
const iframe = await add_iframe(t, { src: iframe_data_uri });
|
||||
await do_send_message_error_test(t, root_dir, /*receiver=*/self,
|
||||
/*target=*/iframe.contentWindow, /*target_origin=*/'*',
|
||||
/*expected_has_source*/true, /*expected_origin=*/location.origin);
|
||||
// Do not test receiving FileSystemHandles from the data URI iframe.
|
||||
// Data URI iframes are insecure and do not expose the NativeFileSystem APIs.
|
||||
}, 'Fail to send messages to a data URI iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe_data_uri = await create_message_target_data_uri(t);
|
||||
const iframe = await add_iframe(t, { src: iframe_data_uri });
|
||||
await do_send_message_port_error_test(
|
||||
t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
}, 'Fail to send messages using a message port in a data URI iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const child_window = await open_window(t, kRemoteOriginDocumentMessageTarget);
|
||||
await do_send_and_receive_message_error_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/child_window, /*target_origin=*/'*',
|
||||
/*expected_has_source=*/true, /*expected_origin=*/location.origin,
|
||||
/*expected_remote_origin=*/kRemoteOrigin);
|
||||
}, 'Fail to send and receive messages using a cross origin window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const child_window = await open_window(t, kRemoteOriginDocumentMessageTarget);
|
||||
await do_send_message_port_error_test(
|
||||
t, root_dir, /*target=*/child_window, /*target_origin=*/'*');
|
||||
}, 'Fail to send and receive messages using a cross origin message port in ' +
|
||||
'a window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const url = `${kDocumentMessageTarget}?pipe=header(Content-Security-Policy` +
|
||||
', sandbox allow-scripts)';
|
||||
const child_window = await open_window(t, url);
|
||||
await do_send_message_error_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/child_window,
|
||||
/*target_origin=*/'*', /*expected_has_source*/true,
|
||||
/*expected_origin=*/location.origin);
|
||||
|
||||
// https://crbug.com/1014248 Should sandboxed windows expose the
|
||||
// NativeFileSystem?
|
||||
//
|
||||
// await do_receive_message_error_test(
|
||||
// t, /*receiver=*/self, /*target=*/child_window,
|
||||
// /*target_origin=*/'*', /*expected_has_source=*/true,
|
||||
// /*expected_origin=*/kRemoteOrigin);
|
||||
}, 'Fail to send and receive messages using a sandboxed window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const url = `${kDocumentMessageTarget}?pipe=header(Content-Security-Policy` +
|
||||
', sandbox allow-scripts)';
|
||||
const child_window = await open_window(t, url);
|
||||
await do_send_message_port_error_test(
|
||||
t, root_dir, /*target=*/child_window, /*target_origin=*/'*');
|
||||
|
||||
// https://crbug.com/1014248 Should sandboxed windows expose the
|
||||
// NativeFileSystem?
|
||||
//
|
||||
// await do_receive_message_port_error_test(
|
||||
// t, /*target=*/child_window, /*target_origin=*/'*');
|
||||
}, 'Fail to send and receive messages using a message port in a sandboxed ' +
|
||||
'window.');
|
|
@ -0,0 +1,97 @@
|
|||
'use strict';
|
||||
|
||||
// This script depends on the following scripts:
|
||||
// /native-file-system/resources/messaging-helpers.js
|
||||
// /native-file-system/resources/messaging-blob-helpers.js
|
||||
// /native-file-system/resources/messaging-serialize-helpers.js
|
||||
// /native-file-system/resources/test-helpers.js
|
||||
// /service-workers/service-worker/resources/test-helpers.sub.js
|
||||
|
||||
// Runs the same test as do_post_message_test(), but uses a MessagePort.
|
||||
// This test starts by establishing a message channel between the test runner
|
||||
// and |target|. Afterwards, the test sends FileSystemHandles through the
|
||||
// message port channel.
|
||||
async function do_message_port_test(test, root_dir, target, target_origin) {
|
||||
const message_port = create_message_channel(target, target_origin);
|
||||
await do_post_message_test(
|
||||
test, root_dir, /*receiver=*/message_port, /*target=*/message_port);
|
||||
}
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(t, { src: kDocumentMessageTarget });
|
||||
await do_message_port_test(
|
||||
t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a message port in a same origin ' +
|
||||
'iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(t, {
|
||||
src: kDocumentMessageTarget,
|
||||
sandbox: 'allow-scripts allow-same-origin'
|
||||
});
|
||||
await do_message_port_test(
|
||||
t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a message port in a sandboxed same ' +
|
||||
'origin iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const blob_url = await create_message_target_blob_url(t);
|
||||
const iframe = await add_iframe(t, { src: blob_url });
|
||||
await do_message_port_test(
|
||||
t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a message port in a blob iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe_html = await create_message_target_html_without_subresources(t);
|
||||
const iframe = await add_iframe(t, { srcdoc: iframe_html });
|
||||
await do_message_port_test(
|
||||
t, root_dir, /*target=*/iframe.contentWindow, /*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a message port in an iframe srcdoc.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const child_window = await open_window(t, kDocumentMessageTarget);
|
||||
await do_message_port_test(
|
||||
t, root_dir, /*target=*/child_window, /*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a message port in a same origin ' +
|
||||
'window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const blob_url = await create_message_target_blob_url(t);
|
||||
const child_window = await open_window(t, blob_url);
|
||||
await do_message_port_test(
|
||||
t, root_dir, /*target=*/child_window, /*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a message port in a blob window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const url = `${kDocumentMessageTarget}?pipe=header(Content-Security-Policy` +
|
||||
', sandbox allow-scripts allow-same-origin)';
|
||||
const child_window = await open_window(t, url);
|
||||
await do_message_port_test(
|
||||
t, root_dir, /*target=*/child_window, /*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a message port in a sandboxed same ' +
|
||||
'origin window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const dedicated_worker =
|
||||
create_dedicated_worker(t, kDedicatedWorkerMessageTarget);
|
||||
await do_message_port_test(t, root_dir, /*target=*/dedicated_worker);
|
||||
}, 'Send and receive messages using a message port in a dedicated ' +
|
||||
'worker.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const scope = `${kServiceWorkerMessageTarget}` +
|
||||
'?post-message-to-message-port-with-file-handle';
|
||||
const registration = await create_service_worker(
|
||||
t, kServiceWorkerMessageTarget, scope);
|
||||
await do_message_port_test(t, root_dir, /*target=*/registration.installing);
|
||||
}, 'Send and receive messages using a message port in a service ' +
|
||||
'worker.');
|
||||
|
||||
if (self.SharedWorker !== undefined) {
|
||||
directory_test(async (t, root_dir) => {
|
||||
const shared_worker = new SharedWorker(kSharedWorkerMessageTarget);
|
||||
shared_worker.port.start();
|
||||
await do_message_port_test(t, root_dir, /*target=*/shared_worker.port);
|
||||
}, 'Send and receive messages using a message port in a shared ' +
|
||||
' worker.');
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
'use strict';
|
||||
|
||||
// This script depends on the following scripts:
|
||||
// /native-file-system/resources/messaging-helpers.js
|
||||
// /native-file-system/resources/messaging-blob-helpers.js
|
||||
// /native-file-system/resources/messaging-serialize-helpers.js
|
||||
// /native-file-system/resources/test-helpers.js
|
||||
// /service-workers/service-worker/resources/test-helpers.sub.js
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(t, { src: kDocumentMessageTarget });
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow,
|
||||
/*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a same origin iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe = await add_iframe(t, {
|
||||
src: kDocumentMessageTarget,
|
||||
sandbox: 'allow-scripts allow-same-origin'
|
||||
});
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow,
|
||||
/*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a sandboxed same origin iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const blob_url = await create_message_target_blob_url(t);
|
||||
const iframe = await add_iframe(t, { src: blob_url });
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow,
|
||||
/*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a blob iframe.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const iframe_html = await create_message_target_html_without_subresources(t);
|
||||
const iframe = await add_iframe(t, { srcdoc: iframe_html });
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/iframe.contentWindow,
|
||||
/*target_origin=*/'*');
|
||||
}, 'Send and receive messages using an iframe srcdoc.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const child_window = await open_window(t, kDocumentMessageTarget);
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/child_window,
|
||||
/*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a same origin window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const blob_url = await create_message_target_blob_url(t);
|
||||
const child_window = await open_window(t, blob_url);
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/child_window,
|
||||
/*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a blob window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const url = `${kDocumentMessageTarget}?pipe=header(Content-Security-Policy` +
|
||||
', sandbox allow-scripts allow-same-origin)';
|
||||
const child_window = await open_window(t, url);
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/self, /*target=*/child_window,
|
||||
/*target_origin=*/'*');
|
||||
}, 'Send and receive messages using a sandboxed same origin window.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const dedicated_worker =
|
||||
create_dedicated_worker(t, kDedicatedWorkerMessageTarget);
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/dedicated_worker, /*target=*/dedicated_worker);
|
||||
}, 'Send and receive messages using a dedicated worker.');
|
||||
|
||||
directory_test(async (t, root_dir) => {
|
||||
const scope = `${kServiceWorkerMessageTarget}?post-message-with-file-handle`;
|
||||
const registration = await create_service_worker(
|
||||
t, kServiceWorkerMessageTarget, scope);
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/navigator.serviceWorker,
|
||||
/*target=*/registration.installing);
|
||||
}, 'Send and receive messages using a service worker.');
|
||||
|
||||
if (self.SharedWorker !== undefined) {
|
||||
directory_test(async (t, root_dir) => {
|
||||
const shared_worker = new SharedWorker(kSharedWorkerMessageTarget);
|
||||
shared_worker.port.start();
|
||||
await do_post_message_test(
|
||||
t, root_dir, /*receiver=*/shared_worker.port,
|
||||
/*target=*/shared_worker.port);
|
||||
}, 'Send and receive messages using a shared worker.');
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
importScripts("/resources/testharness.js");
|
||||
|
||||
function doTest(event)
|
||||
{
|
||||
if (!event.request.url.includes("fetch-error-test"))
|
||||
return;
|
||||
|
||||
let counter = 0;
|
||||
const stream = new ReadableStream({ pull: controller => {
|
||||
switch (++counter) {
|
||||
case 1:
|
||||
controller.enqueue(new Uint8Array([1]));
|
||||
return;
|
||||
default:
|
||||
// We asynchronously error the stream so that there is ample time to resolve the fetch promise and call text() on the response.
|
||||
step_timeout(() => controller.error("Sorry"), 50);
|
||||
}
|
||||
}});
|
||||
event.respondWith(new Response(stream));
|
||||
}
|
||||
|
||||
self.addEventListener("fetch", doTest);
|
|
@ -0,0 +1,40 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var scope = "resources";
|
||||
var registration;
|
||||
|
||||
promise_test(async (test) => {
|
||||
registration = await navigator.serviceWorker.register("fetch-error-worker.js", { scope : scope });
|
||||
var activeWorker = registration.active;
|
||||
if (activeWorker)
|
||||
return;
|
||||
activeWorker = registration.installing;
|
||||
return new Promise(resolve => {
|
||||
activeWorker.addEventListener('statechange', () => {
|
||||
if (activeWorker.state === "activated")
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}, "Setup service worker");
|
||||
|
||||
promise_test(async (test) => {
|
||||
const iframe = await with_iframe(scope);
|
||||
|
||||
const response = await iframe.contentWindow.fetch("fetch-error-test");
|
||||
await response.text().then(assert_unreached, (error) => { assert_true(error.message.includes("Sorry")); });
|
||||
iframe.remove();
|
||||
}, "Make sure a load that makes progress does not time out");
|
||||
|
||||
promise_test(async () => {
|
||||
registration.unregister();
|
||||
}, "Unregister service worker");
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
18
tests/wpt/web-platform-tests/tools/ci/epochs_update.sh
Executable file
18
tests/wpt/web-platform-tests/tools/ci/epochs_update.sh
Executable file
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash
|
||||
set -ex
|
||||
|
||||
SCRIPT_DIR=$(cd $(dirname "$0") && pwd -P)
|
||||
WPT_ROOT=$SCRIPT_DIR/../..
|
||||
cd $WPT_ROOT
|
||||
|
||||
if [ -z "$GITHUB_TOKEN" ]; then
|
||||
echo "GITHUB_TOKEN must be set as an environment variable"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
REMOTE=https://x-access-token:$GITHUB_TOKEN@github.com/web-platform-tests/wpt.git
|
||||
|
||||
git branch epochs/three_hourly $(./wpt rev-list --epoch 3h)
|
||||
# This is safe because `git push` will by default fail for a non-fast-forward
|
||||
# push, for example if the remote branch is ahead of the local branch.
|
||||
git push $REMOTE epochs/three_hourly
|
|
@ -7,3 +7,4 @@ html/tools/build.sh
|
|||
offscreen-canvas/tools/build.sh
|
||||
python mimesniff/mime-types/resources/generated-mime-types.py
|
||||
python3 css/css-ui/tools/appearance-build-webkit-reftests.py
|
||||
python3 WebIDL/generate-setlike.py
|
||||
|
|
|
@ -76,8 +76,8 @@ var expected = [
|
|||
"IDBTransaction",
|
||||
];
|
||||
|
||||
for (var i = 0; i < unexpected.length; ++i) {
|
||||
for (var i = 0; i < expected.length; ++i) {
|
||||
test(function() {
|
||||
assert_true(unexpected[i] in self);
|
||||
}, "The " + unexpected[i] + " interface object should not be exposed");
|
||||
assert_true(expected[i] in self);
|
||||
}, "The " + expected[i] + " interface object should be exposed");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue