188 lines
6.3 KiB
HTML
188 lines
6.3 KiB
HTML
<!DOCTYPE html>
|
|
<title>Test storage partitioning in fenced frames</title>
|
|
<meta name="timeout" content="long">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script src="/common/utils.js"></script>
|
|
<script src="/common/dispatcher/dispatcher.js"></script>
|
|
<script src="resources/utils.js"></script>
|
|
|
|
<body>
|
|
<script>
|
|
|
|
// `getter(key)` : reads the value of `key`, null if not set
|
|
// `setter(key, value)`: sets `key` to `value`
|
|
async function runTest(getter, setter) {
|
|
const key = "key";
|
|
const outer_value = "outer";
|
|
const inner_value = "inner";
|
|
|
|
// Set the value in the top-level frame, and check that it worked.
|
|
await setter(key, outer_value);
|
|
assert_equals(await getter(key), outer_value,
|
|
"Stored the value in the top-level frame.");
|
|
|
|
// Attach a fenced frame.
|
|
const frame = attachFencedFrameContext();
|
|
|
|
// Check that the outer value isn't visible.
|
|
const inner_before_set = await frame.execute(getter, [key]);
|
|
assert_equals(inner_before_set, null,
|
|
"The outer value isn't visible inside the fenced frame.");
|
|
|
|
// Set the value inside the fenced frame, and check that it worked.
|
|
await frame.execute(setter, [key, inner_value]);
|
|
const inner_after_set = await frame.execute(getter, [key]);
|
|
assert_equals(inner_after_set, inner_value,
|
|
"Stored the value in the fenced frame.");
|
|
|
|
// Check that the inner value isn't visible in the top-level frame.
|
|
assert_equals(await getter(key), outer_value,
|
|
"The inner value isn't visible outside the fenced frame.");
|
|
|
|
// Perform an embedder-initiated navigation that will fail.
|
|
const original_config = frame.config;
|
|
frame.config = new FencedFrameConfig("resources/response-204.py");
|
|
await step_timeout(() => {}, 1000);
|
|
|
|
// Check that the failed navigation didn't change the storage partition.
|
|
// (The partition nonce should be reinitialized on navigation commit.)
|
|
const inner_after_failure = await frame.execute(getter, [key]);
|
|
assert_equals(inner_after_failure, inner_value,
|
|
"The inner value is still present after the failed navigation.");
|
|
|
|
// Refresh the fenced frame from within.
|
|
await frame.execute(() => {
|
|
window.executor.suspend(() => { location.href = location.href; });
|
|
});
|
|
|
|
// Check that the storage partition is the same.
|
|
const inner_after_inner_refresh = await frame.execute(getter, [key]);
|
|
assert_equals(inner_after_inner_refresh, inner_value,
|
|
"The inner value is the same after a fencedframe-initiated refresh.");
|
|
|
|
// Refresh the fenced frame from the embedder.
|
|
await frame.execute(() => window.executor.suspend(() => {}));
|
|
frame.element.config = original_config;
|
|
|
|
// Check that there is a blank slate.
|
|
const inner_after_embedder_refresh = await frame.execute(getter, [key]);
|
|
assert_equals(inner_after_embedder_refresh, null,
|
|
"The inner value is gone after an embedder-initiated refresh.");
|
|
}
|
|
|
|
promise_test(async () => {
|
|
return runTest(
|
|
(_) => { return document.cookie || null; },
|
|
(_, value) => { document.cookie = value;}
|
|
);
|
|
}, 'document.cookie');
|
|
|
|
promise_test(async () => {
|
|
return runTest(
|
|
(key) => { return localStorage.getItem(key); },
|
|
(key, value) => { return localStorage.setItem(key, value); }
|
|
);
|
|
}, 'localStorage');
|
|
|
|
promise_test(async () => {
|
|
return runTest(
|
|
(key) => { return sessionStorage.getItem(key); },
|
|
(key, value) => { return sessionStorage.setItem(key, value); }
|
|
);
|
|
}, 'sessionStorage');
|
|
|
|
promise_test(async () => {
|
|
return runTest(
|
|
async (key) => {
|
|
const newCache = await caches.open('test-cache');
|
|
const response = await newCache.match(key);
|
|
if (!response) {
|
|
return null;
|
|
}
|
|
return response.text();
|
|
},
|
|
async (key, value) => {
|
|
const newCache = await caches.open('test-cache');
|
|
return newCache.put(key, new Response(value));
|
|
}
|
|
);
|
|
}, 'Cache API');
|
|
|
|
promise_test(async () => {
|
|
return runTest(
|
|
async (key) => {
|
|
const root = await navigator.storage.getDirectory();
|
|
const draftHandle = await root.getFileHandle(key, { create: true });
|
|
const file = await draftHandle.getFile();
|
|
const text = await file.text();
|
|
return text || null;
|
|
},
|
|
async (key, value) => {
|
|
const root = await navigator.storage.getDirectory();
|
|
const draftHandle = await root.getFileHandle(key, { create: true });
|
|
const writable = await draftHandle.createWritable()
|
|
await writable.truncate(0);
|
|
await writable.write(value);
|
|
await writable.close();
|
|
}
|
|
);
|
|
}, 'File System Access API');
|
|
|
|
promise_test(async () => {
|
|
return runTest(
|
|
async (key) => {
|
|
const openRequest = indexedDB.open('test-db', 2);
|
|
const db = await new Promise((resolve) => {
|
|
openRequest.onsuccess = (event) => {
|
|
resolve(event.target.result);
|
|
};
|
|
openRequest.onupgradeneeded = (event) => {
|
|
const db = event.target.result;
|
|
const objStore = db.createObjectStore('test-tbl', {keyPath: 'key'});
|
|
objStore.transaction.oncomplete = (event) => {
|
|
resolve(db);
|
|
};
|
|
};
|
|
});
|
|
const readRequest = db.transaction(['test-tbl'])
|
|
.objectStore('test-tbl')
|
|
.get(key);
|
|
return new Promise((resolve) => {
|
|
readRequest.onsuccess = (event) => {
|
|
if (!event.target.result) {
|
|
resolve(null);
|
|
} else {
|
|
resolve(event.target.result['value']);
|
|
}
|
|
};
|
|
});
|
|
},
|
|
async (key, value) => {
|
|
const openRequest = indexedDB.open('test-db', 2);
|
|
const db = await new Promise((resolve) => {
|
|
openRequest.onsuccess = (event) => {
|
|
resolve(event.target.result);
|
|
};
|
|
openRequest.onupgradeneeded = (event) => {
|
|
const db = event.target.result;
|
|
const objStore = db.createObjectStore('test-tbl', {keyPath: 'key'});
|
|
objStore.transaction.oncomplete = (event) => {
|
|
resolve(db);
|
|
};
|
|
};
|
|
});
|
|
const writeRequest = db.transaction(['test-tbl'], 'readwrite')
|
|
.objectStore('test-tbl')
|
|
.add({'key': key, 'value': value});
|
|
return new Promise((resolve) => {
|
|
writeRequest.onsuccess = (event) => {
|
|
resolve(event.target.result);
|
|
};
|
|
});
|
|
}
|
|
);
|
|
}, 'IndexedDB');
|
|
|
|
</script>
|
|
</body>
|