Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions gpc/META.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
spec: https://www.w3.org/TR/gpc/
suggested_reviewers:
- AramZS
- bvandersloot-mozilla
- j-br0
- pes10k
- SebastianZimmeck
3 changes: 3 additions & 0 deletions gpc/WEB_FEATURES.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
features:
- name: gpc
files: "**"
24 changes: 24 additions & 0 deletions gpc/global_privacy_control.testdriver.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!doctype html>
<meta charset=utf-8>
<title>GPC Testdriver Validation</title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="/resources/testdriver.js"></script>
<script src='/resources/testdriver-vendor.js'></script>
<script>

promise_test(async t => {
// We do not test the initial value deliberately
const getInitial = await test_driver.get_global_privacy_control();
assert_true(getInitial.gpc === true || getInitial.gpc === false, "Initial value of GPC must be a boolean true or false.")
const setTrue = await test_driver.set_global_privacy_control(true);
assert_true(setTrue.gpc, "Setting a true global privacy control value results in a true value returned after awaiting.");
const getTrue = await test_driver.get_global_privacy_control();
assert_true(getTrue.gpc, "Reading the global privacy control value after set to true results in a true value after awaiting.");
const setFalse = await test_driver.set_global_privacy_control(false);
assert_false(setFalse.gpc, "Setting a false global privacy control value results in a false value returned after awaiting.");
const getFalse = await test_driver.get_global_privacy_control();
assert_false(getFalse.gpc, "Reading the global privacy control value after set to false results in a false value after awaiting.");
});

</script>
15 changes: 15 additions & 0 deletions gpc/idlharness.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// META: global=window,worker
// META: script=/resources/WebIDLParser.js
// META: script=/resources/idlharness.js

idl_test(
['gpc'],
['html'],
idl_array => {
if (self.Window) {
idl_array.add_objects({ Navigator: ['navigator'] });
} else {
idl_array.add_objects({ WorkerNavigator: ['navigator'] });
}
}
);
33 changes: 33 additions & 0 deletions gpc/navigator-globalPrivacyControl.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<title>Primary navigator.globalPrivacyControl test window</title>
<head>
<script src="/resources/testdriver.js"></script>
<script src='/resources/testdriver-vendor.js'></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<script>
setup({explicit_done: true});
async function run() {
const windows_to_close = [];
for (const gpcValue of [true, false]) {
await test_driver.set_global_privacy_control(gpcValue);

let child_window = window.open(`support/navigator-globalPrivacyControl.html?gpc=${gpcValue}`);
windows_to_close.push(child_window);
await fetch_tests_from_window(child_window);
}

for (const w of windows_to_close) {
w.close();
}
done();
}
run();

</script>
</body>
</html>
33 changes: 33 additions & 0 deletions gpc/sec-gpc.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<!DOCTYPE html>
<html>
<title>Primary Sec-GPC test window</title>
<head>
<script src="/resources/testdriver.js"></script>
<script src='/resources/testdriver-vendor.js'></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<script>
setup({explicit_done: true});
async function run() {
const windows_to_close = [];
for (const gpcValue of [true, false]) {
await test_driver.set_global_privacy_control(gpcValue);

let child_window = window.open(`support/getGPC.py?gpc=${gpcValue}`);
windows_to_close.push(child_window);
await fetch_tests_from_window(child_window);
}

for (const w of windows_to_close) {
w.close();
}
done();
}
run();

</script>
</body>
</html>
90 changes: 90 additions & 0 deletions gpc/support/getGPC.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
import base64

def maybeBoolToJavascriptLiteral(value):
if value == None:
return "undefined"
if value == True:
return "true"
if value == False:
return "false"
raise ValueError("Expected bool or None")

def main(request, response):
destination = request.headers.get("sec-fetch-dest").decode("utf-8")
gpcValue = request.headers.get("sec-gpc") == b'1'
expectedGPCValue = request.GET.get(b"gpc") == b"true"
inFrame = request.GET.get(b"framed") != None
destinationDescription = "framed " + destination if inFrame else destination
if destination == "document" or destination == "iframe":
response.headers.set('Content-Type', 'text/html');
return f"""
<!DOCTYPE html>
<html>
<title>Sec-GPC {destination}</title>
<head>
<script src="/resources/testharness.js"></script>
</head>
<body>
<div id="log"></div>
<img id="imageTest">
<script>
test(function(t) {{
assert_equals({maybeBoolToJavascriptLiteral(gpcValue)}, {maybeBoolToJavascriptLiteral(expectedGPCValue)}, "Expected Sec-GPC value ({maybeBoolToJavascriptLiteral(expectedGPCValue)}) is on the {destinationDescription} fetch");
}}, `Expected Sec-GPC value ({maybeBoolToJavascriptLiteral(expectedGPCValue)}) is on the {destinationDescription} fetch`);
promise_test(function(t) {{
const image = document.getElementById("imageTest");
const testResult = new Promise((resolve, reject) => {{
image.addEventListener('load', resolve);
image.addEventListener('error', reject);
}});
image.src = "getGPC.py?gpc={maybeBoolToJavascriptLiteral(expectedGPCValue)}";
return testResult;
}}, `Expected Sec-GPC value ({maybeBoolToJavascriptLiteral(expectedGPCValue)}) is on the {"framed " if destination == "iframe" or inFrame else ""}image fetch`);
</script>
""" + (f"""
<script>
const iframe = document.createElement("iframe");
iframe.src = "getGPC.py?gpc={maybeBoolToJavascriptLiteral(expectedGPCValue)}";
document.body.appendChild(iframe);
async function run() {{
await Promise.all([
fetch_tests_from_window(iframe.contentWindow),
fetch_tests_from_worker(new Worker("getGPC.py?gpc={maybeBoolToJavascriptLiteral(expectedGPCValue)}")),
fetch_tests_from_worker(new SharedWorker("getGPC.py?gpc={maybeBoolToJavascriptLiteral(expectedGPCValue)}")),
]);
let r = await navigator.serviceWorker.register(
"getGPC.py?gpc={maybeBoolToJavascriptLiteral(expectedGPCValue)}",
{{scope: "./blank.html"}});
let sw = r.active || r.installing || r.waiting;
await fetch_tests_from_worker(sw);
await r.unregister();
}}
run();
</script>
""" if destination == "document" else "") + f"""
<script src="getGPC.py?gpc={maybeBoolToJavascriptLiteral(expectedGPCValue)}{"&framed" if destination == "iframe" or inFrame else ""}"></script>
</body>
</html>
"""
elif destination == "image":
if gpcValue == expectedGPCValue:
return (200, [(b"Content-Type", b"image/png")], base64.b64decode("iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAAAAEUlEQVR42mP8nzaTAQQYYQwALssD/5ca+r8AAAAASUVORK5CYII="))
return (400, [], "")
elif destination == "script":
response.headers.set('Content-Type', 'application/javascript');
return f"""
debugger;
test(function(t) {{
assert_equals({maybeBoolToJavascriptLiteral(gpcValue)}, {maybeBoolToJavascriptLiteral(expectedGPCValue)}, "Expected Sec-GPC value ({maybeBoolToJavascriptLiteral(expectedGPCValue)}) is on the {destinationDescription} fetch");
}}, `Expected Sec-GPC value ({maybeBoolToJavascriptLiteral(expectedGPCValue)}) is on the {destinationDescription} fetch`);
"""
elif destination == "worker" or destination == "sharedworker" or destination == "serviceworker":
response.headers.set('Content-Type', 'application/javascript');
return f"""
importScripts("/resources/testharness.js");
test(function(t) {{
assert_equals({maybeBoolToJavascriptLiteral(gpcValue)}, {maybeBoolToJavascriptLiteral(expectedGPCValue)}, "Expected Sec-GPC value ({maybeBoolToJavascriptLiteral(expectedGPCValue)}) is on the {destinationDescription} fetch");
}}, `Expected Sec-GPC value ({maybeBoolToJavascriptLiteral(expectedGPCValue)}) is on the {destinationDescription} fetch`);
done();
"""
raise ValueError("Unexpected destination")
35 changes: 35 additions & 0 deletions gpc/support/navigator-globalPrivacyControl.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<title>navigator.globalPrivacyControl Window</title>
<head>
<script src="/resources/testharness.js"></script>
</head>
<body>
<div id="log"></div>
<script>
setup({explicit_done: true});
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const expectedValue = urlParams.has("gpc", "true");
test(function(t) {
assert_equals(navigator.globalPrivacyControl, expectedValue, "Expected navigator.globalPrivacyControl value is read from the window");
}, `Expected navigator.globalPrivacyControl value (${expectedValue}) is read from the window`);

async function run() {
await Promise.all([
fetch_tests_from_worker(new Worker(`navigator-globalPrivacyControl.js?gpc=${expectedValue}&workerType=dedicated`)),
fetch_tests_from_worker(new SharedWorker(`navigator-globalPrivacyControl.js?gpc=${expectedValue}&workerType=shared`)),
]);

let r = await navigator.serviceWorker.register(
`navigator-globalPrivacyControl.js?gpc=${expectedValue}&workerType=service`,
{scope: `blank.html`});
let sw = r.active || r.installing || r.waiting;
await fetch_tests_from_worker(sw),
await r.unregister();
done();
}
run();
</script>
</body>
</html>
11 changes: 11 additions & 0 deletions gpc/support/navigator-globalPrivacyControl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
importScripts("/resources/testharness.js");

const queryString = self.location.search;
const urlParams = new URLSearchParams(queryString);
const expectedValue = urlParams.has("gpc", "true");
const workerType = urlParams.get("workerType");
test(function(t) {
assert_equals(navigator.globalPrivacyControl, expectedValue, "Expected navigator.globalPrivacyControl value is read from the worker");
}, `Expected navigator.globalPrivacyControl value (${expectedValue}) is read from the ${workerType} worker`);

done();