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:
bors-servo 2019-10-25 20:10:30 -04:00 committed by GitHub
commit 6a54d60043
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
91 changed files with 3190 additions and 185 deletions

View file

@ -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

View file

@ -1,4 +0,0 @@
[quirks-auto-block-size-with-percentage-item.html]
[#container 1]
expected: FAIL

View file

@ -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

View file

@ -1,4 +0,0 @@
[focus-visible-008.html]
[CSS Test (Selectors): Keyboard focus enables :focus-visible]
expected: FAIL

View file

@ -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

View file

@ -56,6 +56,3 @@
[separate text/javascript x/x]
expected: FAIL
[separate text/javascript;charset=windows-1252 text/javascript]
expected: FAIL

View file

@ -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

View file

@ -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

View file

@ -1,6 +1,6 @@
[embedded-credentials.tentative.sub.html]
type: testharness
expected: CRASH
expected: TIMEOUT
[Embedded credentials are treated as network errors.]
expected: FAIL

View file

@ -1,4 +0,0 @@
[traverse_the_history_4.html]
[Multiple history traversals, last would be aborted]
expected: FAIL

View file

@ -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

View file

@ -1,4 +0,0 @@
[creating_browsing_context_test_01.html]
[first argument: absolute url]
expected: FAIL

View file

@ -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

View file

@ -0,0 +1,10 @@
[non-active-document.html]
[DOMParser]
expected: FAIL
[createHTMLDocument]
expected: FAIL
[<template>]
expected: FAIL

View file

@ -1,5 +1,5 @@
[form-double-submit-2.html]
expected: ERROR
[preventDefault should allow onclick submit() to succeed]
expected: FAIL
expected: TIMEOUT

View file

@ -1,5 +1,5 @@
[form-double-submit.html]
expected: ERROR
[default submit action should supersede onclick submit()]
expected: FAIL
expected: TIMEOUT

View file

@ -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

View file

@ -1,4 +0,0 @@
[DOMContentLoaded-defer.html]
[The end: DOMContentLoaded and defer scripts]
expected: FAIL

View file

@ -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

View file

@ -0,0 +1,5 @@
[018.html]
expected: TIMEOUT
[origin of the script that invoked the method, javascript:]
expected: TIMEOUT

View file

@ -1,4 +0,0 @@
[stylesheet_media_queries.html]
[Media queries within stylesheets]
expected: FAIL

View file

@ -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:

View file

@ -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

View 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 }}

View file

@ -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

View 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"))

View file

@ -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>;
};

View file

@ -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>;
};

View file

@ -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>;
};

View file

@ -0,0 +1,9 @@
interface EntriesA {
readonly setlike<DOMString>;
static void entries();
};
interface EntriesB {
readonly setlike<DOMString>;
static readonly attribute long entries;
};

View file

@ -0,0 +1,9 @@
interface ForEachA {
readonly setlike<DOMString>;
static void forEach();
};
interface ForEachB {
readonly setlike<DOMString>;
static readonly attribute long forEach;
};

View file

@ -0,0 +1,9 @@
interface HasA {
readonly setlike<DOMString>;
static void has();
};
interface HasB {
readonly setlike<DOMString>;
static readonly attribute long has;
};

View file

@ -0,0 +1,9 @@
interface KeysA {
readonly setlike<DOMString>;
static void keys();
};
interface KeysB {
readonly setlike<DOMString>;
static readonly attribute long keys;
};

View file

@ -0,0 +1,9 @@
interface SizeA {
readonly setlike<DOMString>;
static void size();
};
interface SizeB {
readonly setlike<DOMString>;
static readonly attribute long size;
};

View file

@ -0,0 +1,9 @@
interface ValuesA {
readonly setlike<DOMString>;
static void values();
};
interface ValuesB {
readonly setlike<DOMString>;
static readonly attribute long values;
};

View 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>;
};

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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';

View file

@ -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>

View file

@ -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;
}

View file

@ -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>

View file

@ -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></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
</main>
</body>
</html>

View file

@ -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=="

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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",

View file

@ -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

View file

@ -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>

View file

@ -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

View file

@ -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;
};

View file

@ -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>

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -0,0 +1,9 @@
'use strict';
importScripts(
'test-helpers.js',
'messaging-serialize-helpers.js',
'message-target.js'
);
add_message_event_handlers(/*receiver=*/self);

View file

@ -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();
});

View file

@ -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>

View file

@ -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 });
}
});
}

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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.');
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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.');

View file

@ -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.');

View file

@ -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.');
}

View file

@ -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.');
}

View file

@ -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);

View file

@ -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>

View 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

View file

@ -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

View file

@ -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");
}