chromium/chrome/test/data/extensions/platform_apps/web_view/dom_storage_isolation/tests.js

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// The main logic of the DOM Storage Isolation test is implemented here.

var FILE_NAME = 'page.html';
var APP_PATH = 'extensions/platform_apps/web_view/dom_storage_isolation';
var HOST_NAME = 'localhost';

function onAllTestsSucceeded() {
  chrome.test.succeed('DOM Storage Isolation');
}

function onTestFailed() {
  chrome.test.fail('DOM Storage Isolation');
}

// Initializes a given webview's DOM storage and invokes the callback
// after.
function askWebviewToInitDOM(webview, name, callback) {
  var messageHandler = new Messaging.Handler();
  // Listen for 'INIT_COMPLETE'
  messageHandler.addHandler(INIT_DOM_STORAGE_COMPLETE, function(message, port) {
    // Remove this handler since it is no longer needed.
    messageHandler.removeHandler(INIT_DOM_STORAGE_COMPLETE);
    callback();
  });
  // Send the request to Init.
  messageHandler.sendMessage(
      new Messaging.Message(INIT_DOM_STORAGE, {pageName: name}),
      webview.contentWindow);
};

// Reads a given webview's DOM storage information and invokes the callback
// by passing the information after.
function askWebviewForStorageInfo(webview, callback) {
  var messageHandler = new Messaging.Handler();
  // Listen for 'GET_INFO_COMPLETE'
  messageHandler.addHandler(GET_DOM_STORAGE_INFO_COMPLETE,
      function(message, port) {
        // Remove this handler since it is no longer needed.
        messageHandler.removeHandler(GET_DOM_STORAGE_INFO_COMPLETE);
        callback(message.local, message.session);
      });
  // Send the request for storage info.
  messageHandler.sendMessage(
      new Messaging.Message(GET_DOM_STORAGE_INFO, {}),
      webview.contentWindow);
}

// Initializes a webview's DOM storage and then reads the storage information
// and verifies if they are what was expected. Then it invokes a callback with
// the result.
function askWebviewToInitDOMAndVerifyResults(webview, name, callback) {
  askWebviewToInitDOM(webview, name, function() {
    askWebviewForStorageInfo(webview, function(local, session) {
      var localOK = (local === ('local-' + name));
      var sessionOK = (session === ('session-' + name));
      callback(localOK, sessionOK);
    });
  });
}

// The test logics are defined here.
function addTests(webviews) {
  // The first test initializes the DOM storage for |webviews[0]| and verifies
  // the correctness of the storage names.
  var test1 = new Testing.Test('init_dom_in_webview[0]',
      function(callBack) {
        askWebviewToInitDOMAndVerifyResults(webviews[0], 'page1',
            function(localOK, sessionOK) {
              callBack(localOK && sessionOK);
            });
      });
  // The second test initializes and verifies the DOM storage for |webviews[1]|
  // and then reads the storage info from |webviews[0]| (on the same parition)
  // to confirm that the local storage name is the same for both.
  // Also note that the session storages should be different.
  var test2 = new Testing.Test(
      'init_dom_in_webview[1]_and_verify_in_webview[0]', function(callBack) {
        // Initialie DOM and verify storage info for |webviews[1]|.
        askWebviewToInitDOMAndVerifyResults(webviews[1], 'page2',
            function(localOK, sessionOK) {
              if (localOK && sessionOK) {
                // Verify the storage info for webviews[0].
                askWebviewForStorageInfo(webviews[0], function(local, session) {
                  if (local !== 'local-page2') {
                    console.log('Error in "' + test2.name + '": bad local ' +
                        'storage name for |webviews[0]|.');
                  } else if (session !== 'session-page1') {
                    console.log('Error in "' + test2.name + '": bad session' +
                        ' storage name for |webviews[0].');
                  } else {
                    return callBack(true);
                  }
                  callBack(false);
                });
              } else {
                console.log('Error in DOM initialization for |webviews[1]|.');
                callBack(false);
              }
            });
      });
  // The third test reads the DOM storage information from |webviews[2]| which
  // is on the default parition and verifies its isolation from |webviews[0]|
  // and |webviews[1]|.
  test3 = new Testing.Test('read_dom_storage_info_from_webviews[2]',
      function(callBack) {
        askWebviewForStorageInfo(webviews[2], function(local, session) {
          if (local !== 'badval') {
            console.log('Error! Local storage is "' + local + '" while it was' +
                ' expected to be "badval".');
          } else if (session !== 'badval') {
            console.log('Error! Session storage is "' + session + '" while it' +
                ' was expected to be "badval".');
          } else {
            return callBack(true);
          }
          callBack(false);
        });
      });
  // Link the tests so that they will run one after another.
  test1.setNextTest(test2);
  test2.setNextTest(test3);
  test3.setNextTest(null); // End of all tests.
  window.firstTest = test1; // The first test to run.
}

function getURL(port) {
  return 'http://' + HOST_NAME  + ':' + port + '/' + APP_PATH + '/' + FILE_NAME;
}

function createWebViews() {
  var webviews = [];
  var container = document.getElementById('container');
  for (var index = 0; index < 3; ++index) {
    webviews.push(document.createElement('webview'));
    webviews[index].id = 'webview_' + index;
    webviews[index].onconsolemessage = function(e) {
      console.log(this.id + ': ' + e.message);
    };
    container.appendChild(webviews[index]);
  }
  // The first two webviews will share a persistent parition.
  webviews[0].partition = 'persist:p';
  webviews[1].partition = 'persist:p';
  return webviews;
}

function loadURLInWebViews(webviews, url, callback) {
  var loadedCount = 0;
  for (var index = 0; index < webviews.length; index++) {
    webviews[index].onloadstop = function() {
      loadedCount++;
      if (loadedCount === webviews.length) {
        callback();
      }
    }
    webviews[index].src = url;
  }
}

function run() {
  var webviews = createWebViews();
  addTests(webviews); // Define tests here.
  chrome.test.getConfig(function(config) {
    loadURLInWebViews(webviews, getURL(config.testServer.port), function() {
      // Start with the first test and the chain of tests will run.
      firstTest.run(onAllTestsSucceeded, onTestFailed);
    });
  });
}
window.onload = run;