| Index: chrome/test/data/extensions/platform_apps/web_view/isolation_indexeddb/main.js
|
| diff --git a/chrome/test/data/extensions/platform_apps/web_view/isolation_indexeddb/main.js b/chrome/test/data/extensions/platform_apps/web_view/isolation_indexeddb/main.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..cde86be53be1e3b7e777bded33ed9b06fb536fdf
|
| --- /dev/null
|
| +++ b/chrome/test/data/extensions/platform_apps/web_view/isolation_indexeddb/main.js
|
| @@ -0,0 +1,254 @@
|
| +// Copyright 2015 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +var LOG = function(msg) {
|
| + window.console.log(msg);
|
| +};
|
| +
|
| +// Wrapper class for a <webview> guest.
|
| +function Guest(id, webview) {
|
| + this.id_ = id;
|
| + this.webview_ = webview;
|
| +};
|
| +
|
| +// Runs a single verification |step| for this test.
|
| +//
|
| +// A step is asynchronous and involves sending postMessage to a <webview> and
|
| +// receiving a reply postMessage back from the <webview>.
|
| +Guest.prototype.sendStepRequestAndWait = function(
|
| + step, successCallback, failureCallback) {
|
| + this.expectedMessage_ = step.expect;
|
| + this.successCallback_ = successCallback;
|
| + this.failureCallback_ = failureCallback;
|
| + this.expectingResponse_ = true;
|
| + step.id = this.id_;
|
| + this.webview_.contentWindow.postMessage(JSON.stringify(step), '*');
|
| +};
|
| +
|
| +// Runs verification steps for this test listed in |stepList|.
|
| +Guest.prototype.runIDBSteps = function(
|
| + stepList, successCallback, failureCallback) {
|
| + if (!stepList.length) {
|
| + LOG('error, runIDBSteps() require at least one step to run');
|
| + failureCallback();
|
| + return;
|
| + }
|
| +
|
| + var currentStep = 0;
|
| + // Proceeds to next step upon success.
|
| + var stepSuccessCallback = function() {
|
| + ++currentStep;
|
| + if (currentStep == stepList.length) {
|
| + // All steps succeeded.
|
| + successCallback();
|
| + return;
|
| + }
|
| + this.sendStepRequestAndWait(stepList[currentStep], stepSuccessCallback,
|
| + failureCallback);
|
| + }.bind(this);
|
| + this.sendStepRequestAndWait(stepList[currentStep], stepSuccessCallback,
|
| + failureCallback);
|
| +};
|
| +
|
| +// Post message handler for this |Guest|.
|
| +Guest.prototype.onResponse = function(responseStr) {
|
| + if (!this.expectingResponse_) {
|
| + return;
|
| + }
|
| + if (this.expectedMessage_ !== responseStr) {
|
| + LOG('Expected response from guest[' + this.id_ + ']: ' +
|
| + this.expectedMessage_ + ' but received: ' +
|
| + responseStr);
|
| + this.failureCallback_();
|
| + } else {
|
| + this.successCallback_();
|
| + }
|
| +};
|
| +
|
| +// Tester class to run test steps.
|
| +function Tester(port) {
|
| + this.port_ = port;
|
| + window.onmessage = this.onMessage_.bind(this);
|
| + this.failed_ = false;
|
| +};
|
| +
|
| +Tester.prototype.getURL = function(filename) {
|
| + return 'http://localhost:' + this.port_ +
|
| + '/extensions/platform_apps/web_view/isolation_indexeddb/' + filename;
|
| +};
|
| +
|
| +Tester.prototype.loadGuest = function(guestInfo, callback) {
|
| + var id = guestInfo.id;
|
| + var partition = guestInfo.partition;
|
| + var html = guestInfo.html;
|
| + var js = guestInfo.js;
|
| +
|
| + var webview = document.createElement('webview');
|
| + if (partition) {
|
| + webview.setAttribute('partition', partition);
|
| + }
|
| + webview.src = this.getURL(html);
|
| +
|
| + var loadFailed = false;
|
| + webview.onloadstop = function(e) {
|
| + LOG('webview.onloadstop: ' + id);
|
| + if (loadFailed) {
|
| + return;
|
| + }
|
| +
|
| + var guest = new Guest(id, webview);
|
| + webview.executeScript({file: js} , function(results) {
|
| + if (!results || !results.length) {
|
| + loadFailed = true;
|
| + callback(null);
|
| + }
|
| + callback(id, new Guest(id, webview));
|
| + }.bind(this));
|
| + }.bind(this);
|
| +
|
| + webview.onloadabort = function(e) {
|
| + loadFailed = true;
|
| + callback(undefined);
|
| + };
|
| +
|
| + webview.onconsolemessage = function(e) {
|
| + LOG('G: ' + e.message);
|
| + };
|
| + document.body.appendChild(webview);
|
| +};
|
| +
|
| +Tester.prototype.loadGuests = function(guestInfoList, doneCallback) {
|
| + var failed = false;
|
| + var responses = [];
|
| + var numResponses = 0;
|
| + var completedCallack = function(id, guest) {
|
| + if (failed) { // We've already failed.
|
| + return;
|
| + }
|
| + if (!guest) {
|
| + // guest didn't load.
|
| + failed = true;
|
| + doneCallback(undefined);
|
| + return;
|
| + }
|
| + responses[id] = guest;
|
| + ++numResponses;
|
| + if (numResponses == guestInfoList.length) {
|
| + // We are done.
|
| + doneCallback(responses);
|
| + }
|
| + };
|
| + for (var i = 0; i < guestInfoList.length; ++i) {
|
| + this.loadGuest(guestInfoList[i], completedCallack);
|
| + }
|
| +};
|
| +
|
| +Tester.prototype.runTest = function() {
|
| + var guestInfoList = [
|
| + {id: 1, html: 'storage1.html', js: 'storage.js', partition: 'partition1'},
|
| + {id: 2, html: 'storage2.html', js: 'storage.js', partition: 'partition1'},
|
| + {id: 3, html: 'storage3.html', js: 'storage.js'}
|
| + ];
|
| + this.loadGuests(guestInfoList, function doneCallback(guests) {
|
| + if (!guests) {
|
| + LOG('One or all guests failed to load');
|
| + this.testFail();
|
| + return;
|
| + }
|
| +
|
| + LOG('guests load complete');
|
| + this.guests_ = guests;
|
| + // Loaded all the guests.
|
| + this.runStep1();
|
| + }.bind(this));
|
| +};
|
| +
|
| +// Initializes the storage for the first <webview>.
|
| +Tester.prototype.runStep1 = function() {
|
| + var guest = this.guests_[1];
|
| + guest.runIDBSteps([
|
| + {name: 'init', expect: 'idb created'},
|
| + {name: 'add', params: [7, 'page1'], expect: 'addItemIDB complete'},
|
| + {name: 'read', params: [7], expect: 'readItemIDB: page1'},
|
| + ], this.runStep2.bind(this), this.testFail.bind(this));
|
| +};
|
| +
|
| +// Initializes the storage for the second <webview>, which share a storage
|
| +// partition with the first <webview>.
|
| +Tester.prototype.runStep2 = function() {
|
| + var guest = this.guests_[2];
|
| + guest.runIDBSteps([
|
| + {name: 'init', expect: 'idb open'},
|
| + {name: 'add', params: [7, 'page2'], expect: 'addItemIDB complete'},
|
| + {name: 'read', params: [7], expect: 'readItemIDB: page2'},
|
| + ], this.runStep3.bind(this), this.testFail.bind(this));
|
| +};
|
| +
|
| +// Reads through the first <webview> to ensure we have the second value.
|
| +Tester.prototype.runStep3 = function() {
|
| + var guest = this.guests_[1];
|
| + guest.runIDBSteps([
|
| + {name: 'read', params: [7], expect: 'readItemIDB: page2'},
|
| + ], this.runStep4.bind(this), this.testFail.bind(this));
|
| +};
|
| +
|
| +// Confirms that the first two <webview>s do not affect the database
|
| +// of the main browser (embedder).
|
| +Tester.prototype.runStep4 = function() {
|
| + var request = indexedDB.open('isolation');
|
| + request.onsuccess = function(e) {
|
| + var version = e.target.result.version;
|
| + // Expect version = 1.
|
| + if (version == 1) {
|
| + this.runStep5(); // Continue to next step.
|
| + } else {
|
| + this.testFail();
|
| + }
|
| + }.bind(this);
|
| + request.onerror = this.testFail.bind(this);
|
| + request.onblocked = this.testFail.bind(this);
|
| +};
|
| +
|
| +// Confirms that a third <webview>'s storage does not get affect by the
|
| +// other two <webview>s.
|
| +Tester.prototype.runStep5 = function() {
|
| + var guest = this.guests_[3];
|
| + guest.runIDBSteps([
|
| + {name: 'open', params: ['isolation'], expect: 'db not found'},
|
| + ], this.testPass(this), this.testFail.bind(this));
|
| +};
|
| +
|
| +// Central postMessage handler.
|
| +Tester.prototype.onMessage_ = function(e) {
|
| + var data = JSON.parse(e.data);
|
| + var id = data[0];
|
| + if (typeof id !== 'number' || id < 0 || id >= this.guests_.length) {
|
| + LOG('unexpeced guest id: ' + id);
|
| + this.testFail();
|
| + return;
|
| + }
|
| +
|
| + // Re-route message to the appropriate guest.
|
| + this.guests_[id].onResponse(data[1]);
|
| +};
|
| +
|
| +Tester.prototype.testFail = function() {
|
| + this.failed_ = true;
|
| + chrome.test.fail();
|
| +};
|
| +
|
| +Tester.prototype.testPass = function() {
|
| + if (this.failed_) { // We've failed already.
|
| + return;
|
| + }
|
| + chrome.test.succeed();
|
| +};
|
| +
|
| +chrome.test.getConfig(function(config) {
|
| + chrome.test.runTests([
|
| + function indexedDBIsolation() {
|
| + var tester = new Tester(config.testServer.port);
|
| + tester.runTest();
|
| + }]);
|
| +});
|
|
|