Skip to content

Commit

Permalink
Prerender: Upstream tests for storage APIs in same-origin prerendered…
Browse files Browse the repository at this point in the history
… pages (2)

This CL upstreams tests for storage APIs (Storage Foundation,
Web Database) in same-origin prerendered pages to the WPT. The behavior
of these APIs is not defined in the spec yet, but we already reached a
consensus that the storage APIs in same-origin prerendered pages are
just allowed.

See the GitHub issue for details:
WICG/nav-speculation#7 (comment)

Bug: 1253158
Change-Id: If34e4f325341a95f036beff43af19dde3504a8ac
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3226531
Reviewed-by: Kouhei Ueno <[email protected]>
Reviewed-by: Lingqi Chi <[email protected]>
Commit-Queue: Hiroki Nakagawa <[email protected]>
Cr-Commit-Position: refs/heads/main@{#932416}
  • Loading branch information
nhiroki authored and Gabisampaio committed Nov 18, 2021
1 parent 2f9a193 commit caa53a5
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>

async function readFromFile(f) {
const {buffer, readBytes} = await f.read(new Uint8Array(4), 0);
return buffer;
}

async function writeToFile(f) {
const writeBuffer = new Uint8Array(4);
writeBuffer.set([75, 76, 77, 78]);

await storageFoundation.requestCapacity(4);

const {writtenBytes} = await f.write(writeBuffer, 0);
await f.flush();
return writtenBytes == 4;
}

async function readWriteTest() {
const bc = new BroadcastChannel('prerender-channel');
assert_true(document.prerendering);

let f = await storageFoundation.open('test_file');
const readBuffer = await readFromFile(f);
const writeResult = await writeToFile(f);
assert_true(writeResult);

const writtenBuffer = await readFromFile(f);
await f.close();

bc.postMessage({
readBuffer : readBuffer,
writtenBuffer : writtenBuffer
});
bc.close();
}

readWriteTest();
</script>
21 changes: 21 additions & 0 deletions speculation-rules/prerender/resources/web-database-access.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!DOCTYPE html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>

const bc = new BroadcastChannel('prerender-channel');
assert_true(document.prerendering);

let result = "Success";
const db = openDatabase("test", "1.0", "test database", 1024);
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS foo (text)');
tx.executeSql('INSERT INTO foo (text) VALUES ("bar")');
}, function(error) {
result = error;
}, function() {
bc.postMessage(result);
bc.close();
});

</script>
67 changes: 67 additions & 0 deletions speculation-rules/prerender/storage-foundation.https.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<title>Same-origin prerendering can access Storage Foundation API</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/utils.js"></script>
<body>
<script>

setup(() => assertSpeculationRulesIsSupported());

const expectedReadBuffer = [65, 66, 67, 68];

async function writeToFile() {
let f = await storageFoundation.open('test_file');
const writeBuffer = new Uint8Array(4);
writeBuffer.set(expectedReadBuffer);

await storageFoundation.requestCapacity(4);

const {writtenBytes} = await f.write(writeBuffer, 0);
await f.flush();
await f.close();
return writtenBytes == 4;
}

async function readFromFile() {
let f = await storageFoundation.open('test_file');
const {buffer, readBytes} = await f.read(new Uint8Array(4), 0);
await f.close();
return buffer;
}

promise_test(async t => {
const bc = new BroadcastChannel('prerender-channel');

const gotMessage = new Promise(resolve => {
bc.addEventListener('message', e => {
resolve(e.data);
}, {
once: true
});
});

const writeResult = await writeToFile();
assert_true(
writeResult,
'primary page should be able to write to storage foundation API.');

// Start prerendering a page that attempts to access storage foundation API.
startPrerendering(`resources/storage-foundation-access.https.html`);
const result = await gotMessage;

assert_array_equals(
result.readBuffer, expectedReadBuffer,
'prerendering page should be able to read from storage foundation API');

const readBufferWrittenByPrerender = await readFromFile();
assert_array_equals(
result.writtenBuffer, readBufferWrittenByPrerender,
'prerendering page should be able to write to storage foundation API');

await storageFoundation.delete('test_file');
}, 'prerendering page should be able to access storage foundation API');

</script>
</body>
70 changes: 70 additions & 0 deletions speculation-rules/prerender/web-database.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<!DOCTYPE html>
<title>Same-origin prerendering can access Web Database</title>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="resources/utils.js"></script>
<body>
<script>

setup(() => assertSpeculationRulesIsSupported());

async function insertQuery() {
return new Promise(resolve => {
const db = openDatabase("test", "1.0", "test database", 1024);
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS foo (text)');
tx.executeSql('INSERT INTO foo (text) VALUES ("bar")');
}, function(error) {
resolve(error);
}, function() {
resolve("Success");
});
});
}

async function selectQuery() {
return new Promise(resolve => {
const db = openDatabase("test", "1.0", "test database", 1024);
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS foo (text)');
tx.executeSql('SELECT * FROM foo', [], function (tx, results) {
resolve(results.rows.length);
});
}, function(tx, error) {
resolve(error);
});
});
}

promise_test(async t => {
const bc = new BroadcastChannel('prerender-channel');

const gotMessage = new Promise(resolve => {
bc.addEventListener('message', e => {
resolve(e.data);
}, {
once: true
});
});

const insertResult = await insertQuery();
assert_equals(insertResult, "Success",
'primary page should be able to execute statements from Web Database.');

// Start prerendering a page that attempts to access Web Database.
startPrerendering('resources/web-database-access.html');
const result = await gotMessage;

assert_equals(
result, "Success",
'prerendering page should be able to read from Web Database');

const selectResult = await selectQuery();
assert_equals(
selectResult, 2,
'prerendering page should be able to write to Web Database');
}, 'prerendering page should be able to access Web Database');

</script>
</body>

0 comments on commit caa53a5

Please sign in to comment.