Skip to content

Commit df8ee2a

Browse files
vkrot-cellchromium-wpt-export-bot
authored andcommitted
Reland "[sub apps] enable wpt tests"
This is a reland of commit f56a10fc2ca726d6401a1c2232370faa8ce7d740 I have only changed a single file `disable-site-isolation-trials` to exclude tests that require isolated origin so that not_site_per_process_blink_wpt_tests do not run the tests. Original change's description: > [sub apps] enable wpt tests > > Re-enable the tests in third_party/blink/web_tests/external/wpt/subapps. > > - Use virtual test suits to emulate isolated context with header overrides. > - Modernized tests to fit new sub apps API shape. > - Remove insecure context test because by definition isolated context cannot be insecure. > - Add a test that checks permission policy behavior. > > Fixed: 40928236 > Change-Id: Idc3d52c01a5a4cb4f4f588ea8c6011e1e13b4901 > Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8122238 > Reviewed-by: Andrew Rayskiy <greengrape@google.com> > Reviewed-by: Vladimir Levin <vmpstr@chromium.org> > Reviewed-by: Rick Byers <rbyers@chromium.org> > Commit-Queue: Vlad Krot <vkrot@google.com> > Cr-Commit-Position: refs/heads/main@{#1668571} Bug: 40928236 Change-Id: I4c06e2489f8d8d24e91c18e05f721a2cb2252597 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/8173844 Reviewed-by: Vladimir Levin <vmpstr@chromium.org> Commit-Queue: Vlad Krot <vkrot@google.com> Reviewed-by: Rick Byers <rbyers@chromium.org> Cr-Commit-Position: refs/heads/main@{#1671765}
1 parent 91ecca8 commit df8ee2a

13 files changed

Lines changed: 208 additions & 131 deletions

interfaces/sub-apps.tentative.idl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
partial interface Window {
2+
[SameObject] readonly attribute SubApps subApps;
3+
};
4+
5+
dictionary SubAppsAddResponse {
6+
record<USVString, USVString> installedApps;
7+
record<USVString, DOMException> failedApps;
8+
};
9+
10+
dictionary SubAppsRemoveResponse {
11+
sequence<USVString> removedApps;
12+
record<USVString, DOMException> failedApps;
13+
};
14+
15+
dictionary SubAppsListResult {
16+
required DOMString appName;
17+
};
18+
19+
[
20+
Exposed=Window,
21+
SecureContext,
22+
IsolatedContext
23+
] interface SubApps {
24+
Promise<SubAppsAddResponse> add(sequence<USVString> install_paths);
25+
Promise<SubAppsRemoveResponse> remove(sequence<USVString> manifest_ids);
26+
Promise<record<USVString, SubAppsListResult>> list();
27+
};

resources/chromium/mock-subapps.js

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,37 +25,31 @@ self.SubAppsServiceTest = (() => {
2525
}
2626

2727
add(install_urls) {
28-
return Promise.resolve({
29-
resultList: {
30-
resultCode: testInternal.serviceResultCode,
31-
results: testInternal.addCallReturnValue,
32-
}
33-
});
28+
if (testInternal.serviceResultCode === -1) {
29+
return Promise.resolve(testInternal.addCallReturnValue);
30+
}
31+
throw testInternal.serviceResultCode;
3432
}
3533

3634
list() {
37-
return Promise.resolve({
38-
result: {
39-
resultCode: testInternal.serviceResultCode,
40-
subAppsList: testInternal.listCallReturnValue,
41-
}
42-
});
35+
if (testInternal.serviceResultCode === -1) {
36+
return Promise.resolve(testInternal.listCallReturnValue);
37+
}
38+
throw testInternal.serviceResultCode;
4339
}
4440

4541
remove(manifest_ids) {
46-
return Promise.resolve({
47-
resultList: {
48-
resultCode: testInternal.serviceResultCode,
49-
results: testInternal.removeCallReturnValue,
50-
}
51-
});
42+
if (testInternal.serviceResultCode === -1) {
43+
return Promise.resolve(testInternal.removeCallReturnValue);
44+
}
45+
throw testInternal.serviceResultCode;
5246
}
5347
}
5448

5549
let testInternal = {
5650
initialized: false,
5751
mockSubAppsService: null,
58-
serviceResultCode: 0,
52+
serviceResultCode: -1,
5953
addCallReturnValue: [],
6054
listCallReturnValue: [],
6155
removeCallReturnValue: [],
@@ -79,13 +73,25 @@ self.SubAppsServiceTest = (() => {
7973
};
8074
}
8175

76+
setAddCallReturnValue(value) {
77+
testInternal.addCallReturnValue = value;
78+
}
79+
80+
setListCallReturnValue(value) {
81+
testInternal.listCallReturnValue = value;
82+
}
83+
84+
setRemoveCallReturnValue(value) {
85+
testInternal.removeCallReturnValue = value;
86+
}
87+
8288
async reset() {
8389
if (testInternal.initialized) {
8490
testInternal.mockSubAppsService.reset();
8591
testInternal = {
8692
mockSubAppsService: null,
8793
initialized: false,
88-
serviceResultCode: 0,
94+
serviceResultCode: -1,
8995
addCallReturnValue: [],
9096
listCallReturnValue: [],
9197
removeCallReturnValue: [],

subapps/__dir__.headers

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Cross-Origin-Opener-Policy: same-origin
2+
Cross-Origin-Embedder-Policy: require-corp
3+
Permissions-Policy: cross-origin-isolated=(self), sub-apps=(self)
4+
Origin-Agent-Cluster: ?0

subapps/add-error.tentative.https.html

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616

1717
const iframeDOMException = iframe.contentWindow.DOMException;
1818

19-
// Detach the frame.
19+
const subApps = iframe.contentWindow.subApps;
2020
iframe.remove();
21-
22-
// At this point the iframe is detached and unloaded, and its execution
23-
// context is gone.
24-
await promise_rejects_dom(t, 'NotFoundError', iframeDOMException, iframe.contentWindow.subApps.add([]));
21+
await promise_rejects_dom(t, 'OperationError', iframeDOMException, subApps.add([]));
2522
}, "The object is no longer associated to a document.");
2623

2724
promise_test(async t => {
@@ -31,16 +28,22 @@
3128
const iframeDOMException = iframe.contentWindow.DOMException;
3229
t.add_cleanup(() => iframe.remove());
3330

34-
await promise_rejects_dom(t, 'InvalidStateError', iframeDOMException, iframe.contentWindow.subApps.add([]));
31+
await promise_rejects_dom(t, 'NotSupportedError', iframeDOMException, iframe.contentWindow.subApps.add([]));
3532
}, "API is only supported in top-level browsing contexts.");
3633

3734
promise_test(async t => {
3835
const cross_origin_url = 'https://example.com/sub-app';
3936

4037
let add_call_params = [cross_origin_url];
4138

39+
t.add_cleanup(async () => {
40+
await mockSubAppsService.reset();
41+
mockSubAppsService = null;
42+
});
43+
44+
await createMockSubAppsService(Status.SUCCESS, [], [], []);
4245
await test_driver.bless("installing subapps", async function () {
43-
await promise_rejects_dom(t, 'NotSupportedError', window.subApps.add(add_call_params));
46+
await promise_rejects_js(t, TypeError, window.subApps.add(add_call_params));
4447
});
4548
}, 'API supports only same-origin URLs.');
4649

@@ -50,17 +53,17 @@
5053

5154
let add_call_params = [url_1, url_2];
5255

53-
let mocked_response = [
54-
{ "installUrlPath": url_1, "manifestIdPath": url_1, "resultType": SubAppsServiceAddResultType.kOperationError },
55-
{ "installUrlPath": url_2, "manifestIdPath": url_2, "resultType": SubAppsServiceAddResultType.kOperationError }
56+
let mocked_response = () => [
57+
{ "installPath": url_1, "manifestId": url_1, "resultType": SubAppsServiceAddResultType.kGenericError },
58+
{ "installPath": url_2, "manifestId": url_2, "resultType": SubAppsServiceAddResultType.kGenericError }
5659
];
5760

58-
let expected_results = {
61+
let expected_results = () => ({
5962
failedApps: {
6063
[url_1]: "OperationError",
6164
[url_2]: "OperationError"
6265
}
63-
};
66+
});
6467

6568
await test_driver.bless("installing a subapp", async function () {
6669
await subapps_add_expect_success_with_result(t, add_call_params, mocked_response, expected_results);
@@ -73,19 +76,19 @@
7376

7477
let add_call_params = [url_1, url_2];
7578

76-
let mocked_response = [
77-
{ "installUrlPath": url_1, "manifestIdPath": url_1, "resultType": SubAppsServiceAddResultType.kSuccess },
78-
{ "installUrlPath": url_2, "manifestIdPath": url_2, "resultType": SubAppsServiceAddResultType.kOperationError }
79+
let mocked_response = () => [
80+
{ "installPath": url_1, "manifestId": url_1, "resultType": SubAppsServiceAddResultType.kSuccess },
81+
{ "installPath": url_2, "manifestId": url_2, "resultType": SubAppsServiceAddResultType.kGenericError }
7982
];
8083

81-
let expected_results = {
84+
let expected_results = () => ({
8285
installedApps: {
8386
[url_1]: url_1
8487
},
8588
failedApps: {
8689
[url_2]: "OperationError"
8790
}
88-
};
91+
});
8992

9093
await test_driver.bless("installing a subapp", async function () {
9194
await subapps_add_expect_success_with_result(t, add_call_params, mocked_response, expected_results);
@@ -102,8 +105,7 @@
102105
mockSubAppsService = null;
103106
});
104107

105-
// 2 corresponds to SubAppsServiceResultCode.kUserDenied
106-
await createMockSubAppsService(2, [], [], []);
108+
await createMockSubAppsService(Status.USER_DECLINED, [], [], []);
107109
await test_driver.bless("installing a subapp", async function () {
108110
await window.subApps.add(add_call_params).then(
109111
result => {

subapps/add-success.tentative.https.html

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,15 @@
1313

1414
let add_call_params = [install_url];
1515

16-
let mocked_response = [
17-
{ "installUrlPath": install_url, "manifestIdPath": install_url, "resultType": SubAppsServiceAddResultType.kSuccess }
16+
let mocked_response = () => [
17+
{ "installPath": install_url, "manifestId": install_url, "resultType": SubAppsServiceAddResultType.kSuccess }
1818
];
1919

20-
let expected_results = {
20+
let expected_results = () => ({
2121
installedApps: {
2222
[install_url]: install_url
2323
}
24-
};
24+
});
2525

2626
await test_driver.bless("installing a subapp", async function () {
2727
await subapps_add_expect_success_with_result(t, add_call_params, mocked_response, expected_results);
@@ -34,17 +34,17 @@
3434

3535
let add_call_params = [url_1, url_2];
3636

37-
let mocked_response = [
38-
{ "installUrlPath": url_1, "manifestIdPath": url_1, "resultType": SubAppsServiceAddResultType.kSuccess },
39-
{ "installUrlPath": url_2, "manifestIdPath": url_2, "resultType": SubAppsServiceAddResultType.kSuccess }
37+
let mocked_response = () => [
38+
{ "installPath": url_1, "manifestId": url_1, "resultType": SubAppsServiceAddResultType.kSuccess },
39+
{ "installPath": url_2, "manifestId": url_2, "resultType": SubAppsServiceAddResultType.kSuccess }
4040
];
4141

42-
let expected_results = {
42+
let expected_results = () => ({
4343
installedApps: {
4444
[url_1]: url_1,
4545
[url_2]: url_2
4646
}
47-
};
47+
});
4848

4949
await test_driver.bless("installing a subapp", async function () {
5050
await subapps_add_expect_success_with_result(t, add_call_params, mocked_response, expected_results);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<title>Sub Apps: disabled by permissions-policy</title>
3+
<script src="/resources/testharness.js"></script>
4+
<script src="/resources/testharnessreport.js"></script>
5+
6+
<body></body>
7+
8+
<script>
9+
promise_test(t => {
10+
return promise_rejects_dom(t, 'SecurityError', window.subApps.add(["/sub-app"]), 'add() should reject');
11+
}, 'add() disabled by permissions-policy');
12+
13+
promise_test(t => {
14+
return promise_rejects_dom(t, 'SecurityError', window.subApps.list(), 'list() should reject');
15+
}, 'list() disabled by permissions-policy');
16+
17+
promise_test(t => {
18+
return promise_rejects_dom(t, 'SecurityError', window.subApps.remove(["/sub-app"]), 'remove() should reject');
19+
}, 'remove() disabled by permissions-policy');
20+
</script>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Permissions-Policy: sub-apps=()

subapps/insecure-context-error.tentative.html

Lines changed: 0 additions & 12 deletions
This file was deleted.

subapps/list-error.tentative.https.html

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<title>Sub Apps: Error cases for list()</title>
33
<script src="/resources/testharness.js"></script>
44
<script src="/resources/testharnessreport.js"></script>
5+
<script src="/resources/testdriver.js"></script>
6+
<script src="/resources/testdriver-vendor.js"></script>
57
<script src="resources/subapps-helpers.js"></script>
68

79
<body></body>
@@ -12,14 +14,13 @@
1214
const iframe = document.createElement('iframe');
1315
document.body.appendChild(iframe);
1416

15-
const iframeDOMException = iframe.contentWindow.DOMException;
16-
17-
// Detach the frame.
17+
const subApps = iframe.contentWindow.subApps;
18+
const DOMException_constructor = iframe.contentWindow.DOMException;
1819
iframe.remove();
1920

2021
// At this point the iframe is detached and unloaded, and its execution
2122
// context is gone.
22-
await promise_rejects_dom(t, 'NotFoundError', iframeDOMException, iframe.contentWindow.subApps.list());
23+
await promise_rejects_dom(t, 'OperationError', DOMException_constructor, subApps.list());
2324
}, "The object is no longer associated to a document.");
2425

2526
promise_test(async t => {
@@ -29,16 +30,7 @@
2930
const iframeDOMException = iframe.contentWindow.DOMException;
3031
t.add_cleanup(() => iframe.remove());
3132

32-
await promise_rejects_dom(t, 'InvalidStateError', iframeDOMException, iframe.contentWindow.subApps.list());
33+
await promise_rejects_dom(t, 'NotSupportedError', iframeDOMException, iframe.contentWindow.subApps.list());
3334
}, "API is only supported in top-level browsing contexts.");
3435

35-
promise_test(async t => {
36-
t.add_cleanup(async () => {
37-
await mockSubAppsService.reset();
38-
mockSubAppsService = null;
39-
});
40-
await createMockSubAppsService(Status.FAILURE, [], []);
41-
return promise_rejects_dom(t, 'OperationError', window.subApps.list());
42-
}, 'List call failed.');
43-
4436
</script>

subapps/list-success.tentative.https.html

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
<title>Sub Apps: Valid calls for list()</title>
33
<script src="/resources/testharness.js"></script>
44
<script src="/resources/testharnessreport.js"></script>
5+
<script src="/resources/testdriver.js"></script>
6+
<script src="/resources/testdriver-vendor.js"></script>
57
<script src="resources/subapps-helpers.js"></script>
68
<script>
79

@@ -15,8 +17,8 @@
1517
const url_2 = '/sub-app-2';
1618

1719
const mocked_response = [
18-
{ "manifestIdPath": url_1, "appName": "App 1" },
19-
{ "manifestIdPath": url_2, "appName": "App 2" },
20+
{ "manifestId": url_1, "appName": "App 1" },
21+
{ "manifestId": url_2, "appName": "App 2" },
2022
];
2123

2224
let expected_results = {
@@ -55,4 +57,4 @@
5557
})
5658
}, 'List API call works with no sub apps.');
5759

58-
</script>
60+
</script>

0 commit comments

Comments
 (0)