summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorekaramad <ekaramad@chromium.org>2015-06-03 15:15:18 -0700
committerCommit bot <commit-bot@chromium.org>2015-06-03 22:16:36 +0000
commitf8b22b4f30a16a16d44b187062f1d044c9821dd5 (patch)
tree6913c088844edea72682f0ae2b3160a61d765a3b
parent0ac44dc9f45c3353fee5075dbc9812a77f06e0b4 (diff)
downloadchromium_src-f8b22b4f30a16a16d44b187062f1d044c9821dd5.zip
chromium_src-f8b22b4f30a16a16d44b187062f1d044c9821dd5.tar.gz
chromium_src-f8b22b4f30a16a16d44b187062f1d044c9821dd5.tar.bz2
Webview browser test for cookie isolation.
Moved the previously disabled |WebViewTest.CookieIsolation| test from C++ to javascript. BUG=294196 Review URL: https://codereview.chromium.org/1153723004 Cr-Commit-Position: refs/heads/master@{#332707}
-rw-r--r--chrome/browser/apps/guest_view/web_view_browsertest.cc59
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/background.js14
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/cookie.js56
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/manifest.json10
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message.js91
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message_types.js13
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.html17
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.js41
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/set_cookie.html21
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/tests.js262
-rw-r--r--chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/window.html17
11 files changed, 551 insertions, 50 deletions
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index 9ab6697..7e023e5 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -1523,68 +1523,27 @@ IN_PROC_BROWSER_TEST_F(WebViewTest, TaskManagerNewWebView) {
// the main browser window to a page that sets a cookie and loads an app with
// multiple webview tags. Each tag sets a cookie and the test checks the proper
// storage isolation is enforced.
-// This test is flaky. See http://crbug.com/294196.
-IN_PROC_BROWSER_TEST_F(WebViewTest, DISABLED_CookieIsolation) {
+IN_PROC_BROWSER_TEST_F(WebViewTest, CookieIsolation) {
ASSERT_TRUE(StartEmbeddedTestServer());
- const std::string kExpire =
- "var expire = new Date(Date.now() + 24 * 60 * 60 * 1000);";
- std::string cookie_script1(kExpire);
- cookie_script1.append(
- "document.cookie = 'guest1=true; path=/; expires=' + expire + ';';");
- std::string cookie_script2(kExpire);
- cookie_script2.append(
- "document.cookie = 'guest2=true; path=/; expires=' + expire + ';';");
-
+ // Navigate the browser to a page which writes a sample cookie
+ // The cookie is "testCookie=1"
+ GURL set_cookie_url = embedded_test_server()->GetURL(
+ "/extensions/platform_apps/web_view/cookie_isolation/set_cookie.html");
GURL::Replacements replace_host;
replace_host.SetHostStr("localhost");
-
- GURL set_cookie_url = embedded_test_server()->GetURL(
- "/extensions/platform_apps/isolation/set_cookie.html");
set_cookie_url = set_cookie_url.ReplaceComponents(replace_host);
- // The first two partitions will be used to set cookies and ensure they are
- // shared. The named partition is used to ensure that cookies are isolated
- // between partitions within the same app.
- content::WebContents* cookie_contents1;
- content::WebContents* cookie_contents2;
- content::WebContents* named_partition_contents1;
- content::WebContents* named_partition_contents2;
-
- NavigateAndOpenAppForIsolation(set_cookie_url, &cookie_contents1,
- &cookie_contents2, &named_partition_contents1,
- &named_partition_contents2, NULL, NULL, NULL);
-
- EXPECT_TRUE(content::ExecuteScript(cookie_contents1, cookie_script1));
- EXPECT_TRUE(content::ExecuteScript(cookie_contents2, cookie_script2));
-
+ ui_test_utils::NavigateToURL(browser(), set_cookie_url);
+ ASSERT_TRUE(RunPlatformAppTest("platform_apps/web_view/cookie_isolation"))
+ << message_;
+ // Finally, verify that the browser cookie has not changed.
int cookie_size;
std::string cookie_value;
- // Test the regular browser context to ensure we have only one cookie.
ui_test_utils::GetCookies(GURL("http://localhost"),
browser()->tab_strip_model()->GetWebContentsAt(0),
&cookie_size, &cookie_value);
EXPECT_EQ("testCookie=1", cookie_value);
-
- // The default behavior is to combine webview tags with no explicit partition
- // declaration into the same in-memory partition. Test the webview tags to
- // ensure we have properly set the cookies and we have both cookies in both
- // tags.
- ui_test_utils::GetCookies(GURL("http://localhost"),
- cookie_contents1,
- &cookie_size, &cookie_value);
- EXPECT_EQ("guest1=true; guest2=true", cookie_value);
-
- ui_test_utils::GetCookies(GURL("http://localhost"),
- cookie_contents2,
- &cookie_size, &cookie_value);
- EXPECT_EQ("guest1=true; guest2=true", cookie_value);
-
- // The third tag should not have any cookies as it is in a separate partition.
- ui_test_utils::GetCookies(GURL("http://localhost"),
- named_partition_contents1,
- &cookie_size, &cookie_value);
- EXPECT_EQ("", cookie_value);
}
// This tests that in-memory storage partitions are reset on browser restart,
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/background.js b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/background.js
new file mode 100644
index 0000000..4ca1f68
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/background.js
@@ -0,0 +1,14 @@
+// Copyright (c) 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.
+
+function createMainWindow() {
+ chrome.app.window.create("window.html", {
+ 'bounds': {
+ 'width' : 800,
+ 'height' : 800
+ }
+ });
+}
+
+chrome.app.runtime.onLaunched.addListener(createMainWindow);
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/cookie.js b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/cookie.js
new file mode 100644
index 0000000..a68bf98
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/cookie.js
@@ -0,0 +1,56 @@
+// Copyright (c) 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.
+Cookie = {};
+// Holds the basic information to write a simple cookie.
+Cookie.CookieData = function(key, value, path, expire) {
+ this.key = key;
+ this.value = value;
+ this.path = path;
+ this.expire = expire + '';
+};
+
+/**
+ * @param {CookieDate} cdata - The new cookie information which includes
+ * |expire| and |path| fields.
+ * @returns {String} A string which represents this cookie and can be used
+ * to insert
+ * cookie by using |document.cookie = VALUE|.
+ */
+Cookie.convertCookieDataToString = function(cdata) {
+ return cdata.key + '=' + cdata.value + ';' + ' path=' + cdata.path + ";" +
+ ' expires=' + cdata.expire + ';';
+}
+
+/**
+ * Parses a cookie string obtained from |document.cookie| and converts it into
+ * an object (dictionary) of key-value's.
+ * @param {String} str - The input cookie string.
+ * @returns {Object} A dictionary of key values representing the cookies inside
+ * the given string.
+ */
+Cookie.convertStringToCookies = function(str) {
+ var cookies = {};
+ var tokens = str.split(';');
+ for (var i = 0; i < tokens.length; i++) {
+ var parts = tokens[i].split('=');
+ if (parts.length != 2) {
+ continue;
+ }
+ var key = parts[0].trim();
+ var value = parts[1].trim();
+ cookies[key] = value;
+ }
+ return cookies;
+}
+
+/**
+ * Deletes all the cookies stored on this page.
+ */
+Cookie.deleteAllCookies = function() {
+ var cookies = document.cookie.split(';');
+ for (var i = 0; i < cookies.length; i++) {
+ var key = cookies[i].split("=")[0];
+ document.cookie = key + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT;";
+ }
+}
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/manifest.json b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/manifest.json
new file mode 100644
index 0000000..c732097
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/manifest.json
@@ -0,0 +1,10 @@
+{
+ "name": "Platform API Test: Cookie Isolation Across Multiple webviews",
+ "version": "0.0.1",
+ "permissions": ["webview"],
+ "app": {
+ "background": {
+ "scripts": [ "background.js"]
+ }
+ }
+}
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message.js b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message.js
new file mode 100644
index 0000000..79b7f7d
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message.js
@@ -0,0 +1,91 @@
+// Copyright (c) 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.
+
+// This namespace automates the process of running taks which require
+// communication in between different |window|'s. Communication is through
+// posting "Messaging.Message" objects to different windows. The messages are
+// handled by the "Messaging.Handler" which will in turn dispatch it to the
+// corresponding agent. Agents communicate in pairs. When an agent requires a
+// task to be done by another agent in a different window, a message is posted
+// and on the other side, it is dispatched to the corresponding agent to do the
+// task.
+Messaging = {};
+
+// A simple message between |source| and |destination| agents.
+Messaging.Message = function (source, destination, content) {
+ this.source = source;
+ this.destination = destination;
+ this.content = content;
+};
+
+// A Singleton class which listens to |window.onmessage| event and upon
+// receiving a message, dispatches the message to the corresponding agent. The
+// agents are registered using |Messaging.Handler.addAgent|.
+Messaging.GetHandler = function() {
+ if (arguments.callee._singletonInstance) {
+ return arguments.callee._singletonInstance;
+ }
+ arguments.callee._singletonInstance = this;
+ var agents = {};
+ this.hasAgent = function(agentName) {
+ return !!agents[agentName];
+ };
+ this.addAgent = function(agent) {
+ agents[agent.getName()] = agent;
+ };
+ this.sendMessage = function(message, portTo) {
+ console.log('Sending message from "' + message.source + '" to "' +
+ message.destination + '".');
+ portTo.postMessage(message, '*');
+ };
+ var handler = this;
+ function onMessage(msg) {
+ var message = msg.data;
+ var from = msg.source;
+ console.log('Received message from "'+ message.source + '" to "' +
+ message.destination + '".');
+ if (handler.hasAgent(message.destination)) {
+ console.log('Dispatching message to agent: ' + message.destination)
+ agents[message.destination].receive(message, from);
+ } else {
+ console.log('Unknown agent "' + message.destination + '".');
+ }
+ }
+ window.onmessage = onMessage;
+ return handler;
+};
+
+// An agent is a point of communication within a |window|. Agent's communicate
+// with each other to make requests. The request is identified in the
+// |Messaging.Message.type| field. Each agent must have a handler function
+// registered for each type of incoming message it receives.
+Messaging.Agent = function(name) {
+ var agentName = name;
+ this.getName = function() {
+ return agentName;
+ };
+ var types = {};
+ this.handlesType = function(type) {
+ return !!types[type];
+ };
+ this.addTask = function(type, handler) {
+ types[type] = handler;
+ };
+ this.getHandler = function(type) {
+ return types[type];
+ };
+};
+
+// The message handler function for each agent. |portFrom| is the
+// window/contentWindow of the origin of the message.
+Messaging.Agent.prototype.receive = function(message, portFrom) {
+ if (this.handlesType(message.content.type)) {
+ console.log('Agent "' + this.getName() + '" will handle the message type"' +
+ message.content.type + '".');
+ this.getHandler(message.content.type)(message, portFrom);
+ } else {
+ console.log('Agent "' + this.getName() + '" cannot handle message type "' +
+ message.content.type + '".');
+ }
+};
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message_types.js b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message_types.js
new file mode 100644
index 0000000..56dc8ec
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/message_types.js
@@ -0,0 +1,13 @@
+// Copyright (c) 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.
+
+// Different message types for the host app and the guest webviews.
+var START_TEST = 'Start the test.';
+var TEST_ENDED = 'Test ended.';
+var SET_COOKIES = 'Set the given cookie.';
+var SET_COOKIES_COMPLETE = 'Cookie was set to the given value.';
+var GET_COOKIES = 'Get cookies.';
+var GET_COOKIES_COMPLETE = 'Cookies are ready.';
+var CLEAR_COOKIES = 'Clear all cookies.'
+var CLEAR_COOKIES_COMPLETE = 'Cookies cleard.';
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.html b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.html
new file mode 100644
index 0000000..ccfe8a1
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.html
@@ -0,0 +1,17 @@
+<!--
+ * 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+ <h4> Sample page which stores cookies upon command. </h4>
+ <script src="cookie.js"></script>
+ <script src="message_types.js"></script>
+ <script src="message.js"></script>
+ <script src="page.js"></script>
+</body>
+</html>
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.js b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.js
new file mode 100644
index 0000000..b13e3fa
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/page.js
@@ -0,0 +1,41 @@
+// Copyright (c) 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.
+
+function initialize() {
+ var messageHandler = Messaging.GetHandler();
+ var cookieAgent = new Messaging.Agent('agent_cookie');
+ messageHandler.addAgent(cookieAgent);
+ // Handles the request to set cookies to this page.
+ cookieAgent.addTask(SET_COOKIES, function(message, portFrom) {
+ console.log('Message received: ' + SET_COOKIES);
+ var cookieString =
+ Cookie.convertCookieDataToString(message.content.cookieData);
+ console.log('Setting cookie to: ' + cookieString);
+ document.cookie = cookieString;
+ messageHandler.sendMessage(
+ new Messaging.Message(
+ 'agent_cookie', message.source, {type: SET_COOKIES_COMPLETE}),
+ portFrom);
+ });
+ // Handles the request to read cookies.
+ cookieAgent.addTask(GET_COOKIES, function(message, portFrom) {
+ console.log('Cookie requested. We have: ' + document.cookie);
+ messageHandler.sendMessage(
+ new Messaging.Message('agent_cookies', message.source, {
+ type: GET_COOKIES_COMPLETE,
+ cookies: Cookie.convertStringToCookies(document.cookie)
+ }),
+ portFrom);
+ });
+ // Handles the request to clear all cookies for this page.
+ cookieAgent.addTask(CLEAR_COOKIES, function(message, portFrom) {
+ Cookie.deleteAllCookies();
+ console.log('Deleted all cookies.');
+ messageHandler.sendMessage(
+ new Messaging.Message(
+ 'agent_cookie', message.source, {type: CLEAR_COOKIES_COMPLETE}),
+ portFrom);
+ });
+}
+window.onload = initialize;
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/set_cookie.html b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/set_cookie.html
new file mode 100644
index 0000000..6801a36
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/set_cookie.html
@@ -0,0 +1,21 @@
+<!--
+ Copyright (c) 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.
+ -->
+
+<!DOCTYPE html>
+<html>
+ <head>
+ </head>
+ <body>
+ <p> This document writes the following cookie: 'testCookie=1' </p>
+ </body>
+ <script>
+var expire = new Date();
+expire.setDate(expire.getDate() + 1);
+document.cookie = 'testCookie=1;path=/;expire=' + expire + ';';
+ </script>
+
+</html>
+
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/tests.js b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/tests.js
new file mode 100644
index 0000000..adf79ff
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/tests.js
@@ -0,0 +1,262 @@
+// Copyright (c) 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 HOST_NAME = 'localhost';
+var APP_PATH = 'extensions/platform_apps/web_view/cookie_isolation';
+var FILE_NAME = 'page.html';
+var webviews = [];
+var TEST_FAILED = false; // Result of a test that failed.
+var TEST_SUCCEEDED = true; // Result of a test that succeeded.
+
+function getURL(port) {
+ return 'http://' + HOST_NAME + ':' + port + '/' + APP_PATH + '/' + FILE_NAME;
+}
+
+function tomorrow() {
+ var date = new Date();
+ date.setDate(date.getDate() + 1);
+ return date;
+}
+
+// Announces the test result to the test manager.
+function announceTestEnd(testName, testResult) {
+ var messageHandler = Messaging.GetHandler();
+ messageHandler.sendMessage(
+ new Messaging.Message(
+ testName, 'test_manager', {type: TEST_ENDED, result: testResult}),
+ window);
+}
+
+// Send a request on behalf of 'test_manager' to a given test and asks it to
+// start their test.
+function requestTestStart(testName) {
+ var messageHandler = Messaging.GetHandler();
+ messageHandler.sendMessage(
+ new Messaging.Message('test_manager', testName, {type: START_TEST}),
+ window);
+}
+
+// Tests that webview and the embedder app do not share cookie.
+// Note: Before running this chrome app, the test has written
+// a sample cookie: "testCookie=1" on a browser page.
+function createTestWebviewDoesNotSeeBrowserTab() {
+ var agent = new Messaging.Agent('first_test');
+ var messageHandler = Messaging.GetHandler();
+
+ // Verifies that |webviews[0]| does not see the browser cookies.
+ agent.addTask(START_TEST, function(message, portFrom) {
+ // Send a message to |webviews[0]| to receive their cookie.
+ console.log('Asking |webviews[0]| for their cookies.');
+ messageHandler.sendMessage(
+ new Messaging.Message(
+ agent.getName(), 'agent_cookie', {type: GET_COOKIES}),
+ webviews[0].contentWindow);
+ });
+
+ // Handles the message from |webviews[0]| with its cookies.
+ agent.addTask(GET_COOKIES_COMPLETE, function(message, portFrom) {
+ // |webviews[0]|'s cookie should NOT include "testCookie=1".
+ var testResult = (message.content.cookies.hasOwnProperty('testCookie')) ?
+ TEST_FAILED : TEST_SUCCEEDED;
+ console.log('Read the cookies from |webviews[0]|.');
+ announceTestEnd(agent.getName(), testResult);
+ });
+ // End of the first test.
+
+ messageHandler.addAgent(agent);
+};
+
+// Tests that the two webviews on the same in-memory partition share cookies.
+function createTestForWebviewsOnSamePartition() {
+ var agent = new Messaging.Agent('second_test');
+ var messageHandler = Messaging.GetHandler();
+
+ // Requests |webviews[0]| and |webviews[1]| to delete all their cookies.
+ agent.addTask(START_TEST, function(message, portFrom) {
+ for (var i = 0; i < 2; ++i) {
+ messageHandler.sendMessage(
+ new Messaging.Message(
+ agent.getName(), 'agent_cookie', {type: CLEAR_COOKIES}),
+ webviews[i].contentWindow);
+ }
+ });
+
+ // Handles the reponse from |webviews[0]| and |webviews[1]| regarding their
+ // cookies being deleted.
+ var numWebviewsClearedCookies = 0;
+ agent.addTask(CLEAR_COOKIES_COMPLETE, function(message, portFrom) {
+ // A webview cleared its cookies. Keeping track of their number.
+ numWebviewsClearedCookies++;
+ // Create a unique cookie for this webview.
+ var cookieName = 'guest' + numWebviewsClearedCookies;
+ // Request the webview to write their cookie.
+ messageHandler.sendMessage(
+ new Messaging.Message( agent.getName(), 'agent_cookie', {
+ type: SET_COOKIES,
+ cookieData: new Cookie.CookieData(cookieName, 'true', '/',
+ tomorrow())
+ }),
+ portFrom);
+ });
+
+ // Handles the response from |webviews[0]| and |webviews[1]| acknowledging
+ // the cookie writing task.
+ var numCookiesWritten = 0;
+ agent.addTask(SET_COOKIES_COMPLETE, function(message, portFrom) {
+ numCookiesWritten++; // Keeping track of how many webviews finished writing.
+ if (numCookiesWritten == 2) {
+ // Both finished writing. Ask for their cookie value.
+ for (var i = 0; i < 2; ++i) {
+ console.log('Both webviews finished writing their cookies.' +
+ ' Asking them to read us their cookie now.');
+ messageHandler.sendMessage(
+ new Messaging.Message(
+ agent.getName(), 'agent_cookie', {type: GET_COOKIES}),
+ webviews[i].contentWindow);
+ }
+ }
+ });
+
+ // Handles the response from webviews reporting their cookie value.
+ var numCookiesRead = 0;
+ var wrongCookieCount = false;
+ agent.addTask(GET_COOKIES_COMPLETE, function(message, portFrom) {
+ numCookiesRead++; // Keeping track of how many webviews have reported.
+ if (wrongCookieCount) {
+ // Already failed the test.
+ return;
+ }
+ console.log('Some webview sent us its cookie(s).');
+ console.log('Cookie: ' + JSON.stringify(message.content.cookies) + '.');
+ var count = Object.keys(message.content.cookies).length;
+ // Expecting two cookies. If less or more, test fails.
+ if (count !== 2) {
+ wrongCookieCount = true;
+ announceTestEnd(agent.getName(), TEST_FAILED);
+ return;
+ }
+ console.log("Read exactly two cookies.");
+ if (numCookiesRead == 2) {
+ // Read from both webviews with no errors.
+ // Test is over.
+ announceTestEnd(agent.getName(), TEST_SUCCEEDED);
+ }
+
+ });
+ // End of the second Test.
+
+ messageHandler.addAgent(agent);
+}
+
+// Tests if the third webview which is on a separate partition has empty cookie.
+function createTestForWebviewOnDifferentParition() {
+ var agent = new Messaging.Agent('third_test');
+ var messageHandler = Messaging.GetHandler();
+
+ // Handles the test start message.
+ agent.addTask(START_TEST, function(message, portFrom) {
+ console.log('Asking the webview on a different partition to send us' +
+ ' its cookies.');
+ // Ask |webviews[2]| to report its cookies.
+ messageHandler.sendMessage(
+ new Messaging.Message(
+ agent.getName(), 'agent_cookie', {type: GET_COOKIES}),
+ webviews[2].contentWindow);
+ });
+
+ // Handles the response from |webviews[2]| regarding the value of its cookies.
+ agent.addTask(GET_COOKIES_COMPLETE, function(message, portFrom) {
+ console.log('The webview on a different partition sent us its' +
+ ' cookies.');
+ var count = Object.keys(message.content.cookies).length;
+ var result = (count === 0);
+ // Test succeeds only if no cookies are reported.
+ announceTestEnd(agent.getName(), result);
+ });
+ // End of the third test.
+
+ messageHandler.addAgent(agent);
+}
+
+// Creates an agent which manages the tests.
+function createTestManager() {
+ var agent = new Messaging.Agent('test_manager');
+ var messageHandler = Messaging.GetHandler();
+
+ // Handles the repsonse from test agents which have finished their test.
+ agent.addTask(TEST_ENDED, function(message, portFrom) {
+ // Early return if test failed.
+ if (message.result === TEST_FAILED) {
+ chrome.test.failed();
+ return;
+ }
+ switch (message.source) {
+ case 'first_test':
+ console.log('First test ended.');
+ requestTestStart('second_test');
+ break;
+ case 'second_test':
+ console.log('Second test ended.');
+ requestTestStart('third_test');
+ break;
+ case 'third_test':
+ console.log('Third test ended.');
+ chrome.test.succeed();
+ break;
+ }
+ });
+
+ messageHandler.addAgent(agent);
+}
+
+function loadContentIntoWebviews(webviews, url, onLoadCallBack) {
+ var loadedWebviewsCount = 0;
+ for (var index = 0; index < webviews.length; ++index) {
+ webviews[index].onloadstop = function() {
+ loadedWebviewsCount++;
+ if (loadedWebviewsCount === webviews.length) {
+ onLoadCallBack();
+ }
+ };
+ webviews[index].src = url;
+ }
+}
+
+// Defines the tests agents and implements the test logic.
+function createTestAgents() {
+ createTestWebviewDoesNotSeeBrowserTab();
+ createTestForWebviewsOnSamePartition();
+ createTestForWebviewOnDifferentParition();
+ createTestManager();
+}
+
+function createWebViews() {
+ var webviews = [];
+ var container = document.getElementById('container');
+ for (var i = 0; i < 3; ++i) {
+ webviews.push(document.createElement('webview'));
+ webviews[i].id = 'webview_' + i;
+ container.appendChild(webviews[i]);
+ webviews[i].onconsolemessage = function(e) {
+ console.log(this.id + ': ' + e.message);
+ };
+ }
+ // Put the last webview on a unique separate partition
+ webviews[2].partition = 'persist:p3';
+ return webviews;
+}
+
+// Creates the required DOM elements and runs the tests.
+function run() {
+ createTestAgents();
+ window.webviews = createWebViews();
+ chrome.test.getConfig(function(config) {
+ loadContentIntoWebviews(webviews, getURL(config.testServer.port),
+ function() {
+ // Start the first test.
+ requestTestStart('first_test');
+ });
+ });
+}
+window.onload = run;
diff --git a/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/window.html b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/window.html
new file mode 100644
index 0000000..2213c3f
--- /dev/null
+++ b/chrome/test/data/extensions/platform_apps/web_view/cookie_isolation/window.html
@@ -0,0 +1,17 @@
+<!--
+Copyright (c) 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.
+-->
+<!DOCTYPE html>
+<html>
+ <head>
+ </head>
+ <body>
+ <div id="container"></div>
+ <script src="message_types.js"></script>
+ <script src="cookie.js"></script>
+ <script src="message.js"></script>
+ <script src="tests.js"></script>
+ </body>
+</html>