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

// Copyright 2018 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 Findability Isolation test is implemented here.

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

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

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

// Sets window.name of the given webview.  |callback| will be called with no
// arguments upon completion.
function askWebviewToSetWindowName(webview, name, callback) {
  var messageHandler = new Messaging.Handler();
  // Listen for 'SET_WINDOW_NAME_COMPLETE'
  messageHandler.addHandler(SET_WINDOW_NAME_COMPLETE, function(message, port) {
    // Remove this handler since it is no longer needed.
    messageHandler.removeHandler(SET_WINDOW_NAME_COMPLETE);
    callback();
  });
  // Send the request to set the window name.
  messageHandler.sendMessage(
      new Messaging.Message(SET_WINDOW_NAME, {windowName: name}),
      webview.contentWindow);
}

// Checks if |webview| can find a window/frame named |name|.
// |callback| will be called with a boolean |found| argument upon completion.
function askWebviewToFindWindowByName(webview, name, callback) {
  var messageHandler = new Messaging.Handler();
  // Listen for 'FIND_WINDOW_BY_NAME_COMPLETE'
  messageHandler.addHandler(
      FIND_WINDOW_BY_NAME_COMPLETE,
      function(message, port) {
        // Remove this handler since it is no longer needed.
        messageHandler.removeHandler(FIND_WINDOW_BY_NAME_COMPLETE);
        callback(message.found);
      });
  // Send the request to set the window name.
  messageHandler.sendMessage(
      new Messaging.Message(FIND_WINDOW_BY_NAME, {windowName: name}),
      webview.contentWindow);
}

// The test logics are defined here.
function addTests(webviews) {
  // The first test makes sure that the webviews in the same storage partition
  // (webviews[0] and webviews[1]) can find each other via
  // window.open('', <frame name>).  This is a regression test for
  // https://crbug.com/794079.
  test1 = new Testing.Test('window.open_findability_between_webview[0]and[1]',
      function(callBack) {
        askWebviewToSetWindowName(webviews[1], "test1-webviews1", function() {
          askWebviewToFindWindowByName(
              webviews[0], "test1-webviews1", function(found) {
                // Windows should be findable if they are in the same storage
                // partition.
                callBack(found == true);
              });
        });
      });
  // The second test makes sure that the webviews in a different storage
  // partition (webviews[0] and webviews[2]) can NOT find each other via
  // window.open('', <frame name>).
  test2 = new Testing.Test('window.open_findability_between_webview[0]and[2]',
      function(callBack) {
        askWebviewToSetWindowName(webviews[2], "test2-webviews2", function() {
          askWebviewToFindWindowByName(
              webviews[0], "test2-webviews2", function(found) {
                // Windows shouldn't be findable across different storage
                // partitions.
                callBack(found == false);
              });
        });
      });
  // Link the tests so that they will run one after another.
  test1.setNextTest(test2);
  test2.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;