blob: 1b633342fa8635db179f5db142183f278a925854 [file] [log] [blame]
[email protected]35abc332012-02-24 23:48:381// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]32b7c492010-09-01 04:15:002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avia2f4804a2015-12-24 23:11:135#include <stddef.h>
6
[email protected]7c6ef352013-09-26 07:23:147#include "base/path_service.h"
[email protected]46acbf12013-06-10 18:43:428#include "base/strings/stringprintf.h"
alexmos1c3da4f2016-11-03 06:06:119#include "base/test/histogram_tester.h"
avia2f4804a2015-12-24 23:11:1310#include "build/build_config.h"
[email protected]32b7c492010-09-01 04:15:0011#include "chrome/browser/extensions/extension_apitest.h"
[email protected]01996a592013-09-13 06:55:0412#include "chrome/browser/profiles/profile.h"
[email protected]2ad4a902010-11-17 06:05:1313#include "chrome/browser/ui/browser.h"
[email protected]d8748142012-05-16 21:13:4314#include "chrome/browser/ui/browser_finder.h"
scottmg8abbff832016-01-28 22:57:3715#include "chrome/browser/ui/browser_list.h"
[email protected]e0448872013-01-11 19:35:0216#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]7c6ef352013-09-26 07:23:1417#include "chrome/common/chrome_paths.h"
alexmoscf5145bb2016-11-09 23:19:4518#include "chrome/common/url_constants.h"
[email protected]af44e7fb2011-07-29 18:32:3219#include "chrome/test/base/ui_test_utils.h"
nick6cfe5c72017-05-22 22:00:4220#include "content/public/browser/navigation_entry.h"
alexmos1c3da4f2016-11-03 06:06:1121#include "content/public/browser/notification_service.h"
22#include "content/public/browser/notification_types.h"
23#include "content/public/browser/render_frame_host.h"
[email protected]1dd66b72012-09-19 20:41:4824#include "content/public/browser/render_process_host.h"
[email protected]fad73672012-06-15 23:26:0625#include "content/public/browser/web_contents.h"
nick6cfe5c72017-05-22 22:00:4226#include "content/public/common/browser_side_navigation_policy.h"
[email protected]1dd66b72012-09-19 20:41:4827#include "content/public/common/result_codes.h"
[email protected]99bee642014-05-31 22:36:4328#include "content/public/common/url_constants.h"
[email protected]7d478cb2012-07-24 17:19:4229#include "content/public/test/browser_test_utils.h"
alexmoscf5145bb2016-11-09 23:19:4530#include "content/public/test/test_navigation_observer.h"
[email protected]22401dc2014-03-21 01:38:5731#include "extensions/browser/extension_host.h"
[email protected]98b6d942013-11-10 00:34:0732#include "extensions/browser/process_manager.h"
[email protected]99bee642014-05-31 22:36:4333#include "extensions/common/constants.h"
[email protected]e4452d32013-11-15 23:07:4134#include "extensions/common/extension.h"
lfg910f2f92014-09-19 05:31:0935#include "extensions/test/extension_test_message_listener.h"
yoze8dc2f12014-09-09 23:16:3236#include "extensions/test/result_catcher.h"
[email protected]f2cb3cf2013-03-21 01:40:5337#include "net/dns/mock_host_resolver.h"
[email protected]7c6ef352013-09-26 07:23:1438#include "net/test/embedded_test_server/embedded_test_server.h"
[email protected]bc44f4142013-02-12 06:15:5639#include "testing/gtest/include/gtest/gtest.h"
Ivan Sandrkc30341b2017-11-09 19:13:2640#include "ui/base/base_window.h"
41
42#if defined(OS_CHROMEOS)
43#include "ash/public/cpp/window_properties.h"
44#include "ash/public/interfaces/window_pin_type.mojom.h"
Ivan Sandrk9669d0e2017-12-15 23:50:2045#include "chrome/app/chrome_command_ids.h"
Ivan Sandrkc30341b2017-11-09 19:13:2646#include "chrome/browser/extensions/window_controller.h"
47#include "chrome/browser/extensions/window_controller_list.h"
Ivan Sandrk9669d0e2017-12-15 23:50:2048#include "chrome/browser/ui/browser_command_controller.h"
Ivan Sandrkc30341b2017-11-09 19:13:2649#include "ui/aura/window.h"
50#endif
[email protected]32b7c492010-09-01 04:15:0051
[email protected]e5d549d2011-12-28 01:29:2052using content::OpenURLParams;
53using content::Referrer;
[email protected]fad73672012-06-15 23:26:0654using content::WebContents;
[email protected]e5d549d2011-12-28 01:29:2055
Ivan Sandrkc30341b2017-11-09 19:13:2656namespace aura {
57class Window;
58}
59
jam1a5b5582017-05-01 16:50:1060class WindowOpenApiTest : public ExtensionApiTest {
61 void SetUpOnMainThread() override {
62 ExtensionApiTest::SetUpOnMainThread();
63 host_resolver()->AddRule("*", "127.0.0.1");
64 }
65};
66
robf8cd8ce2015-02-21 12:18:0467// The test uses the chrome.browserAction.openPopup API, which requires that the
68// window can automatically be activated.
69// See comments at BrowserActionInteractiveTest::ShouldRunPopupTest
johnme7e30b512015-04-16 14:57:3570// Fails flakily on all platforms. https://crbug.com/477691
jam1a5b5582017-05-01 16:50:1071IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, DISABLED_WindowOpen) {
yoze8dc2f12014-09-09 23:16:3272 extensions::ResultCatcher catcher;
[email protected]32b7c492010-09-01 04:15:0073 ASSERT_TRUE(LoadExtensionIncognito(test_data_dir_
74 .AppendASCII("window_open").AppendASCII("spanning")));
75 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
76}
[email protected]4026ce1e2010-09-14 19:35:0477
[email protected]f1c102b2013-02-15 07:44:1278bool WaitForTabsAndPopups(Browser* browser,
[email protected]f9e82d92011-10-29 00:50:4579 int num_tabs,
dimich566d3642016-08-23 16:39:0680 int num_popups) {
[email protected]58b349b2011-11-23 02:07:1581 SCOPED_TRACE(
dimich566d3642016-08-23 16:39:0682 base::StringPrintf("WaitForTabsAndPopups tabs:%d, popups:%d",
83 num_tabs, num_popups));
[email protected]4026ce1e2010-09-14 19:35:0484 // We start with one tab and one browser already open.
85 ++num_tabs;
[email protected]f6ffa7d2012-08-17 17:27:0886 size_t num_browsers = static_cast<size_t>(num_popups) + 1;
[email protected]4026ce1e2010-09-14 19:35:0487
[email protected]f1c102b2013-02-15 07:44:1288 const base::TimeDelta kWaitTime = base::TimeDelta::FromSeconds(10);
[email protected]0a5bdc6522011-06-08 19:04:4989 base::TimeTicks end_time = base::TimeTicks::Now() + kWaitTime;
90 while (base::TimeTicks::Now() < end_time) {
scottmg34c5dd882016-02-03 05:21:5491 if (chrome::GetBrowserCount(browser->profile()) == num_browsers &&
dimich566d3642016-08-23 16:39:0692 browser->tab_strip_model()->count() == num_tabs)
[email protected]0a5bdc6522011-06-08 19:04:4993 break;
94
[email protected]b8deecd2012-07-30 21:09:4495 content::RunAllPendingInMessageLoop();
[email protected]0a5bdc6522011-06-08 19:04:4996 }
97
scottmg34c5dd882016-02-03 05:21:5498 EXPECT_EQ(num_browsers, chrome::GetBrowserCount(browser->profile()));
[email protected]e0448872013-01-11 19:35:0299 EXPECT_EQ(num_tabs, browser->tab_strip_model()->count());
[email protected]0a5bdc6522011-06-08 19:04:49100
[email protected]f9e82d92011-10-29 00:50:45101 int num_popups_seen = 0;
scottmg8abbff832016-01-28 22:57:37102 for (auto* b : *BrowserList::GetInstance()) {
103 if (b == browser)
[email protected]4026ce1e2010-09-14 19:35:04104 continue;
[email protected]4026ce1e2010-09-14 19:35:04105
scottmg8abbff832016-01-28 22:57:37106 EXPECT_TRUE(b->is_type_popup());
[email protected]f6ffa7d2012-08-17 17:27:08107 ++num_popups_seen;
[email protected]4026ce1e2010-09-14 19:35:04108 }
[email protected]f9e82d92011-10-29 00:50:45109 EXPECT_EQ(num_popups, num_popups_seen);
[email protected]f1c102b2013-02-15 07:44:12110
scottmg34c5dd882016-02-03 05:21:54111 return ((num_browsers == chrome::GetBrowserCount(browser->profile())) &&
[email protected]f1c102b2013-02-15 07:44:12112 (num_tabs == browser->tab_strip_model()->count()) &&
[email protected]f1c102b2013-02-15 07:44:12113 (num_popups == num_popups_seen));
[email protected]4026ce1e2010-09-14 19:35:04114}
115
jam1a5b5582017-05-01 16:50:10116IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, BrowserIsApp) {
[email protected]c1dffe82013-06-26 20:59:05117 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]f112b0f2011-05-26 01:53:52118 ASSERT_TRUE(LoadExtension(
119 test_data_dir_.AppendASCII("window_open").AppendASCII("browser_is_app")));
120
dimich566d3642016-08-23 16:39:06121 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 2));
[email protected]f112b0f2011-05-26 01:53:52122
scottmg8abbff832016-01-28 22:57:37123 for (auto* b : *BrowserList::GetInstance()) {
124 if (b == browser())
125 ASSERT_FALSE(b->is_app());
[email protected]f112b0f2011-05-26 01:53:52126 else
scottmg8abbff832016-01-28 22:57:37127 ASSERT_TRUE(b->is_app());
[email protected]f112b0f2011-05-26 01:53:52128 }
129}
130
jam1a5b5582017-05-01 16:50:10131IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupDefault) {
[email protected]c1dffe82013-06-26 20:59:05132 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]0a5bdc6522011-06-08 19:04:49133 ASSERT_TRUE(LoadExtension(
134 test_data_dir_.AppendASCII("window_open").AppendASCII("popup")));
135
136 const int num_tabs = 1;
137 const int num_popups = 0;
dimich566d3642016-08-23 16:39:06138 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]0a5bdc6522011-06-08 19:04:49139}
140
jam1a5b5582017-05-01 16:50:10141IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupIframe) {
[email protected]7c6ef352013-09-26 07:23:14142 base::FilePath test_data_dir;
143 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
144 embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
martijnf9b885b72016-11-22 22:03:47145 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]7c6ef352013-09-26 07:23:14146 ASSERT_TRUE(LoadExtension(
147 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_iframe")));
148
jochenc5cfa642014-09-02 15:30:03149 const int num_tabs = 1;
150 const int num_popups = 0;
dimich566d3642016-08-23 16:39:06151 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]7c6ef352013-09-26 07:23:14152}
153
jam1a5b5582017-05-01 16:50:10154IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupLarge) {
[email protected]c1dffe82013-06-26 20:59:05155 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]0a5bdc6522011-06-08 19:04:49156 ASSERT_TRUE(LoadExtension(
157 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_large")));
158
[email protected]0a5bdc6522011-06-08 19:04:49159 // On other systems this should open a new popup window.
160 const int num_tabs = 0;
161 const int num_popups = 1;
dimich566d3642016-08-23 16:39:06162 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]0a5bdc6522011-06-08 19:04:49163}
164
jam1a5b5582017-05-01 16:50:10165IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupSmall) {
[email protected]c1dffe82013-06-26 20:59:05166 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]0a5bdc6522011-06-08 19:04:49167 ASSERT_TRUE(LoadExtension(
168 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_small")));
169
170 // On ChromeOS this should open a new panel (acts like a new popup window).
171 // On other systems this should open a new popup window.
172 const int num_tabs = 0;
173 const int num_popups = 1;
dimich566d3642016-08-23 16:39:06174 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]0a5bdc6522011-06-08 19:04:49175}
176
[email protected]73fa1fce2013-02-21 20:10:05177// Disabled on Windows. Often times out or fails: crbug.com/177530
178#if defined(OS_WIN)
179#define MAYBE_PopupBlockingExtension DISABLED_PopupBlockingExtension
180#else
181#define MAYBE_PopupBlockingExtension PopupBlockingExtension
182#endif
jam1a5b5582017-05-01 16:50:10183IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, MAYBE_PopupBlockingExtension) {
[email protected]c1dffe82013-06-26 20:59:05184 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]4026ce1e2010-09-14 19:35:04185
186 ASSERT_TRUE(LoadExtension(
187 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
188 .AppendASCII("extension")));
189
dimich566d3642016-08-23 16:39:06190 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 5, 3));
[email protected]4026ce1e2010-09-14 19:35:04191}
192
jam1a5b5582017-05-01 16:50:10193IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, PopupBlockingHostedApp) {
svaldeza01f7d92015-11-18 17:47:56194 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]4026ce1e2010-09-14 19:35:04195
196 ASSERT_TRUE(LoadExtension(
197 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
198 .AppendASCII("hosted_app")));
199
[email protected]fe3048872010-10-18 14:58:59200 // The app being tested owns the domain a.com . The test URLs we navigate
201 // to below must be within that domain, so that they fall within the app's
202 // web extent.
203 GURL::Replacements replace_host;
mgiuca77752c32015-02-05 07:31:18204 replace_host.SetHostStr("a.com");
[email protected]fe3048872010-10-18 14:58:59205
206 const std::string popup_app_contents_path(
svaldeza01f7d92015-11-18 17:47:56207 "/extensions/api_test/window_open/popup_blocking/hosted_app/");
[email protected]fe3048872010-10-18 14:58:59208
svaldeza01f7d92015-11-18 17:47:56209 GURL open_tab = embedded_test_server()
210 ->GetURL(popup_app_contents_path + "open_tab.html")
211 .ReplaceComponents(replace_host);
212 GURL open_popup = embedded_test_server()
213 ->GetURL(popup_app_contents_path + "open_popup.html")
214 .ReplaceComponents(replace_host);
[email protected]fe3048872010-10-18 14:58:59215
nick3b04f322016-08-31 19:29:19216 browser()->OpenURL(OpenURLParams(open_tab, Referrer(),
217 WindowOpenDisposition::NEW_FOREGROUND_TAB,
218 ui::PAGE_TRANSITION_TYPED, false));
219 browser()->OpenURL(OpenURLParams(open_popup, Referrer(),
220 WindowOpenDisposition::NEW_FOREGROUND_TAB,
221 ui::PAGE_TRANSITION_TYPED, false));
[email protected]4026ce1e2010-09-14 19:35:04222
dimich566d3642016-08-23 16:39:06223 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 3, 1));
[email protected]4026ce1e2010-09-14 19:35:04224}
[email protected]d4db6c702011-03-28 21:49:14225
jam1a5b5582017-05-01 16:50:10226IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowArgumentsOverflow) {
[email protected]e7f90562011-05-23 21:38:24227 ASSERT_TRUE(RunExtensionTest("window_open/argument_overflow")) << message_;
228}
229
jam1a5b5582017-05-01 16:50:10230IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, DISABLED_WindowOpener) {
[email protected]54edcea2011-07-27 01:56:38231 ASSERT_TRUE(RunExtensionTest("window_open/opener")) << message_;
232}
[email protected]fad73672012-06-15 23:26:06233
[email protected]fa7c1602013-04-03 23:00:20234#if defined(OS_MACOSX)
235// Extension popup windows are incorrectly sized on OSX, crbug.com/225601
236#define MAYBE_WindowOpenSized DISABLED_WindowOpenSized
237#else
238#define MAYBE_WindowOpenSized WindowOpenSized
239#endif
240// Ensure that the width and height properties of a window opened with
241// chrome.windows.create match the creation parameters. See crbug.com/173831.
jam1a5b5582017-05-01 16:50:10242IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, MAYBE_WindowOpenSized) {
[email protected]fa7c1602013-04-03 23:00:20243 ASSERT_TRUE(RunExtensionTest("window_open/window_size")) << message_;
dimich566d3642016-08-23 16:39:06244 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 1));
[email protected]fa7c1602013-04-03 23:00:20245}
246
[email protected]fad73672012-06-15 23:26:06247// Tests that an extension page can call window.open to an extension URL and
248// the new window has extension privileges.
249IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenExtension) {
250 ASSERT_TRUE(LoadExtension(
251 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));
252
[email protected]99bee642014-05-31 22:36:43253 GURL start_url(std::string(extensions::kExtensionScheme) +
[email protected]fb4fe0952014-06-05 09:44:24254 url::kStandardSchemeSeparator +
[email protected]99bee642014-05-31 22:36:43255 last_loaded_extension_id() + "/test.html");
[email protected]fad73672012-06-15 23:26:06256 ui_test_utils::NavigateToURL(browser(), start_url);
[email protected]f3e73f62012-10-20 05:35:16257 WebContents* newtab = NULL;
[email protected]e0448872013-01-11 19:35:02258 ASSERT_NO_FATAL_FAILURE(
259 OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
Devlin Croninf1afce252017-08-19 01:21:48260 start_url.Resolve("newtab.html"), true, true, &newtab));
[email protected]fad73672012-06-15 23:26:06261
262 bool result = false;
[email protected]b6987e02013-01-04 18:30:43263 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
264 &result));
[email protected]fad73672012-06-15 23:26:06265 EXPECT_TRUE(result);
266}
267
268// Tests that if an extension page calls window.open to an invalid extension
269// URL, the browser doesn't crash.
270IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenInvalidExtension) {
nick6cfe5c72017-05-22 22:00:42271 const extensions::Extension* extension = LoadExtension(
272 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
273 ASSERT_TRUE(extension);
[email protected]fad73672012-06-15 23:26:06274
nick6cfe5c72017-05-22 22:00:42275 GURL start_url = extension->GetResourceURL("/test.html");
[email protected]fad73672012-06-15 23:26:06276 ui_test_utils::NavigateToURL(browser(), start_url);
nick6cfe5c72017-05-22 22:00:42277 WebContents* newtab = nullptr;
Devlin Croninf1afce252017-08-19 01:21:48278 bool new_page_in_same_process = true;
279 bool expect_success = false;
nick6cfe5c72017-05-22 22:00:42280 ASSERT_NO_FATAL_FAILURE(OpenWindow(
281 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]fad73672012-06-15 23:26:06282 GURL("chrome-extension://thisissurelynotavalidextensionid/newtab.html"),
Devlin Croninf1afce252017-08-19 01:21:48283 new_page_in_same_process, expect_success, &newtab));
[email protected]fad73672012-06-15 23:26:06284
Devlin Croninf1afce252017-08-19 01:21:48285 // This is expected to redirect to about:blank.
286 EXPECT_EQ(GURL(url::kAboutBlankURL), newtab->GetLastCommittedURL());
[email protected]fad73672012-06-15 23:26:06287}
288
289// Tests that calling window.open from the newtab page to an extension URL
290// gives the new window extension privileges - even though the opening page
291// does not have extension privileges, we break the script connection, so
292// there is no privilege leak.
293IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenNoPrivileges) {
294 ASSERT_TRUE(LoadExtension(
295 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));
296
297 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
[email protected]f3e73f62012-10-20 05:35:16298 WebContents* newtab = NULL;
[email protected]e0448872013-01-11 19:35:02299 ASSERT_NO_FATAL_FAILURE(
300 OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]99bee642014-05-31 22:36:43301 GURL(std::string(extensions::kExtensionScheme) +
Devlin Croninf1afce252017-08-19 01:21:48302 url::kStandardSchemeSeparator +
303 last_loaded_extension_id() + "/newtab.html"),
304 false, true, &newtab));
[email protected]fad73672012-06-15 23:26:06305
306 // Extension API should succeed.
307 bool result = false;
[email protected]b6987e02013-01-04 18:30:43308 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
309 &result));
[email protected]fad73672012-06-15 23:26:06310 EXPECT_TRUE(result);
311}
alexmos1c3da4f2016-11-03 06:06:11312
313// Tests that calling window.open for an extension URL from a non-HTTP or HTTPS
314// URL on a new tab cannot access non-web-accessible resources.
315IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest,
316 WindowOpenInaccessibleResourceFromDataURL) {
317 base::HistogramTester uma;
alexmoscf5145bb2016-11-09 23:19:45318 const extensions::Extension* extension = LoadExtension(
319 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
320 ASSERT_TRUE(extension);
alexmos1c3da4f2016-11-03 06:06:11321
322 ui_test_utils::NavigateToURL(browser(), GURL("data:text/html,foo"));
323
324 // test.html is not web-accessible and should not be loaded.
alexmoscf5145bb2016-11-09 23:19:45325 GURL extension_url(extension->GetResourceURL("test.html"));
alexmos1c3da4f2016-11-03 06:06:11326 content::WindowedNotificationObserver windowed_observer(
327 content::NOTIFICATION_LOAD_STOP,
328 content::NotificationService::AllSources());
329 ASSERT_TRUE(content::ExecuteScript(
330 browser()->tab_strip_model()->GetActiveWebContents(),
331 "window.open('" + extension_url.spec() + "');"));
332 windowed_observer.Wait();
333 content::NavigationController* controller =
334 content::Source<content::NavigationController>(windowed_observer.source())
335 .ptr();
336 content::WebContents* newtab = controller->GetWebContents();
337 ASSERT_TRUE(newtab);
338
339 EXPECT_NE(extension_url, newtab->GetMainFrame()->GetLastCommittedURL());
340 EXPECT_FALSE(newtab->GetMainFrame()->GetSiteInstance()->GetSiteURL().SchemeIs(
341 extensions::kExtensionScheme));
342
343 // Verify that the blocking was recorded correctly in UMA.
344 uma.ExpectUniqueSample("Extensions.ShouldAllowOpenURL.Failure",
345 2, /* FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION */
346 1);
alexmos7f7bae62017-04-05 21:15:04347 uma.ExpectUniqueSample("Extensions.ShouldAllowOpenURL.Failure.Scheme",
348 6 /* SCHEME_DATA */, 1);
alexmos1c3da4f2016-11-03 06:06:11349}
alexmoscf5145bb2016-11-09 23:19:45350
351// Test that navigating to an extension URL is allowed on chrome:// and
352// chrome-search:// pages, even for URLs that are not web-accessible.
353// See https://crbug.com/662602.
354IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest,
355 NavigateToInaccessibleResourceFromChromeURL) {
356 // Mint an extension URL which is not web-accessible.
357 const extensions::Extension* extension = LoadExtension(
358 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
359 ASSERT_TRUE(extension);
360 GURL extension_url(extension->GetResourceURL("test.html"));
361
362 content::WebContents* tab =
363 browser()->tab_strip_model()->GetActiveWebContents();
364
365 // Navigate to the non-web-accessible URL from chrome:// and
366 // chrome-search:// pages. Verify that the page loads correctly.
367 GURL history_url(chrome::kChromeUIHistoryURL);
368 GURL ntp_url(chrome::kChromeSearchLocalNtpUrl);
369 ASSERT_TRUE(history_url.SchemeIs(content::kChromeUIScheme));
370 ASSERT_TRUE(ntp_url.SchemeIs(chrome::kChromeSearchScheme));
371 GURL start_urls[] = {history_url, ntp_url};
372 for (size_t i = 0; i < arraysize(start_urls); i++) {
373 ui_test_utils::NavigateToURL(browser(), start_urls[i]);
374 EXPECT_EQ(start_urls[i], tab->GetMainFrame()->GetLastCommittedURL());
375
376 content::TestNavigationObserver observer(tab);
377 ASSERT_TRUE(content::ExecuteScript(
378 tab, "location.href = '" + extension_url.spec() + "';"));
379 observer.Wait();
380 EXPECT_EQ(extension_url, tab->GetMainFrame()->GetLastCommittedURL());
381 std::string result;
382 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
383 tab, "domAutomationController.send(document.body.innerText)", &result));
384 EXPECT_EQ("HOWDIE!!!", result);
385 }
386}
Ivan Sandrkc30341b2017-11-09 19:13:26387
388#if defined(OS_CHROMEOS)
389
390namespace {
391
Ivan Sandrkc9eb2962017-11-16 15:35:10392aura::Window* GetCurrentWindow() {
Ivan Sandrkc30341b2017-11-09 19:13:26393 extensions::WindowController* controller = nullptr;
394 for (auto* iter :
395 extensions::WindowControllerList::GetInstance()->windows()) {
396 if (iter->window()->IsActive()) {
397 controller = iter;
398 break;
399 }
400 }
401 EXPECT_TRUE(controller);
Ivan Sandrkc9eb2962017-11-16 15:35:10402 return controller->window()->GetNativeWindow();
403}
404
405ash::mojom::WindowPinType GetCurrentWindowPinType() {
406 ash::mojom::WindowPinType type =
407 GetCurrentWindow()->GetProperty(ash::kWindowPinTypeKey);
Ivan Sandrkc30341b2017-11-09 19:13:26408 return type;
409}
410
Ivan Sandrkc9eb2962017-11-16 15:35:10411void SetCurrentWindowPinType(ash::mojom::WindowPinType type) {
412 GetCurrentWindow()->SetProperty(ash::kWindowPinTypeKey, type);
413}
414
Ivan Sandrkc30341b2017-11-09 19:13:26415} // namespace
416
417IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, OpenLockedFullscreenWindow) {
418 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
419 "openLockedFullscreenWindow"))
420 << message_;
421
422 // Make sure the newly created window is "trusted pinned" (which means that
423 // it's in locked fullscreen mode).
424 EXPECT_EQ(ash::mojom::WindowPinType::TRUSTED_PINNED,
425 GetCurrentWindowPinType());
426}
427
428IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, UpdateWindowToLockedFullscreen) {
429 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
430 "updateWindowToLockedFullscreen"))
431 << message_;
432
433 // Make sure the current window is put into the "trusted pinned" state.
434 EXPECT_EQ(ash::mojom::WindowPinType::TRUSTED_PINNED,
435 GetCurrentWindowPinType());
436}
437
Ivan Sandrkc9eb2962017-11-16 15:35:10438IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, RemoveLockedFullscreenFromWindow) {
Ivan Sandrk9669d0e2017-12-15 23:50:20439 // After locking the window, do a LockedFullscreenStateChanged so the
440 // command_controller state catches up as well.
Ivan Sandrkc9eb2962017-11-16 15:35:10441 SetCurrentWindowPinType(ash::mojom::WindowPinType::TRUSTED_PINNED);
Ivan Sandrk9669d0e2017-12-15 23:50:20442 browser()->command_controller()->LockedFullscreenStateChanged();
Ivan Sandrkc9eb2962017-11-16 15:35:10443
444 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
445 "removeLockedFullscreenFromWindow"))
446 << message_;
447
448 // Make sure the current window is removed from locked-fullscreen state.
449 EXPECT_EQ(ash::mojom::WindowPinType::NONE, GetCurrentWindowPinType());
450}
451
Ivan Sandrk9669d0e2017-12-15 23:50:20452// Make sure that commands disabling code works in locked fullscreen mode.
453IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, VerifyCommandsInLockedFullscreen) {
454 // IDC_EXIT is always enabled in regular mode so it's a perfect candidate for
455 // testing.
456 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_EXIT));
457 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
458 "updateWindowToLockedFullscreen"))
459 << message_;
460
461 // IDC_EXIT is not enabled in locked fullscreen.
462 EXPECT_FALSE(browser()->command_controller()->IsCommandEnabled(IDC_EXIT));
463
464 // Verify some whitelisted commands.
465 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_COPY));
466 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_FIND));
467 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_ZOOM_PLUS));
468}
469
Ivan Sandrkc30341b2017-11-09 19:13:26470IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
471 OpenLockedFullscreenWindowWithoutPermission) {
472 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
473 "openLockedFullscreenWindow"))
474 << message_;
475
476 // Make sure no new windows get created (so only the one created by default
477 // exists) since the call to chrome.windows.create fails on the javascript
478 // side.
479 EXPECT_EQ(1u,
480 extensions::WindowControllerList::GetInstance()->windows().size());
481}
482
483IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
484 UpdateWindowToLockedFullscreenWithoutPermission) {
485 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
486 "updateWindowToLockedFullscreen"))
487 << message_;
488
489 // chrome.windows.update call fails since this extension doesn't have the
490 // correct permission and hence the current window has NONE as WindowPinType.
Ivan Sandrkc9eb2962017-11-16 15:35:10491 EXPECT_EQ(ash::mojom::WindowPinType::NONE, GetCurrentWindowPinType());
492}
493
494IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
495 RemoveLockedFullscreenFromWindowWithoutPermission) {
496 SetCurrentWindowPinType(ash::mojom::WindowPinType::TRUSTED_PINNED);
Ivan Sandrk9669d0e2017-12-15 23:50:20497 browser()->command_controller()->LockedFullscreenStateChanged();
Ivan Sandrkc9eb2962017-11-16 15:35:10498
499 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
500 "removeLockedFullscreenFromWindow"))
501 << message_;
502
503 // The current window is still locked-fullscreen.
504 EXPECT_EQ(ash::mojom::WindowPinType::TRUSTED_PINNED,
Ivan Sandrkc30341b2017-11-09 19:13:26505 GetCurrentWindowPinType());
506}
507#endif // defined(OS_CHROMEOS)
508
509#if !defined(OS_CHROMEOS)
510// Loading an extension requiring the 'lockWindowFullscreenPrivate' permission
511// on non Chrome OS platforms should always fail since the API is available only
512// on Chrome OS.
513IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
514 OpenLockedFullscreenWindowNonChromeOS) {
515 const extensions::Extension* extension = LoadExtensionWithFlags(
516 test_data_dir_.AppendASCII("locked_fullscreen/with_permission"),
517 ExtensionBrowserTest::kFlagIgnoreManifestWarnings);
518 ASSERT_TRUE(extension);
519 EXPECT_EQ(1u, extension->install_warnings().size());
520 EXPECT_EQ(std::string("'lockWindowFullscreenPrivate' "
521 "is not allowed for specified platform."),
522 extension->install_warnings().front().message);
523}
524#endif