blob: ab8b96ff0499ed70d7feb566d8443b034924f623 [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
Devlin Cronin836f545d2018-05-09 00:25:0560namespace extensions {
61
jam1a5b5582017-05-01 16:50:1062class WindowOpenApiTest : public ExtensionApiTest {
63 void SetUpOnMainThread() override {
64 ExtensionApiTest::SetUpOnMainThread();
65 host_resolver()->AddRule("*", "127.0.0.1");
66 }
67};
68
robf8cd8ce2015-02-21 12:18:0469// The test uses the chrome.browserAction.openPopup API, which requires that the
70// window can automatically be activated.
71// See comments at BrowserActionInteractiveTest::ShouldRunPopupTest
johnme7e30b512015-04-16 14:57:3572// Fails flakily on all platforms. https://crbug.com/477691
jam1a5b5582017-05-01 16:50:1073IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, DISABLED_WindowOpen) {
yoze8dc2f12014-09-09 23:16:3274 extensions::ResultCatcher catcher;
[email protected]32b7c492010-09-01 04:15:0075 ASSERT_TRUE(LoadExtensionIncognito(test_data_dir_
76 .AppendASCII("window_open").AppendASCII("spanning")));
77 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
78}
[email protected]4026ce1e2010-09-14 19:35:0479
[email protected]f1c102b2013-02-15 07:44:1280bool WaitForTabsAndPopups(Browser* browser,
[email protected]f9e82d92011-10-29 00:50:4581 int num_tabs,
dimich566d3642016-08-23 16:39:0682 int num_popups) {
[email protected]58b349b2011-11-23 02:07:1583 SCOPED_TRACE(
dimich566d3642016-08-23 16:39:0684 base::StringPrintf("WaitForTabsAndPopups tabs:%d, popups:%d",
85 num_tabs, num_popups));
[email protected]4026ce1e2010-09-14 19:35:0486 // We start with one tab and one browser already open.
87 ++num_tabs;
[email protected]f6ffa7d2012-08-17 17:27:0888 size_t num_browsers = static_cast<size_t>(num_popups) + 1;
[email protected]4026ce1e2010-09-14 19:35:0489
[email protected]f1c102b2013-02-15 07:44:1290 const base::TimeDelta kWaitTime = base::TimeDelta::FromSeconds(10);
[email protected]0a5bdc6522011-06-08 19:04:4991 base::TimeTicks end_time = base::TimeTicks::Now() + kWaitTime;
92 while (base::TimeTicks::Now() < end_time) {
scottmg34c5dd882016-02-03 05:21:5493 if (chrome::GetBrowserCount(browser->profile()) == num_browsers &&
dimich566d3642016-08-23 16:39:0694 browser->tab_strip_model()->count() == num_tabs)
[email protected]0a5bdc6522011-06-08 19:04:4995 break;
96
[email protected]b8deecd2012-07-30 21:09:4497 content::RunAllPendingInMessageLoop();
[email protected]0a5bdc6522011-06-08 19:04:4998 }
99
scottmg34c5dd882016-02-03 05:21:54100 EXPECT_EQ(num_browsers, chrome::GetBrowserCount(browser->profile()));
[email protected]e0448872013-01-11 19:35:02101 EXPECT_EQ(num_tabs, browser->tab_strip_model()->count());
[email protected]0a5bdc6522011-06-08 19:04:49102
[email protected]f9e82d92011-10-29 00:50:45103 int num_popups_seen = 0;
scottmg8abbff832016-01-28 22:57:37104 for (auto* b : *BrowserList::GetInstance()) {
105 if (b == browser)
[email protected]4026ce1e2010-09-14 19:35:04106 continue;
[email protected]4026ce1e2010-09-14 19:35:04107
scottmg8abbff832016-01-28 22:57:37108 EXPECT_TRUE(b->is_type_popup());
[email protected]f6ffa7d2012-08-17 17:27:08109 ++num_popups_seen;
[email protected]4026ce1e2010-09-14 19:35:04110 }
[email protected]f9e82d92011-10-29 00:50:45111 EXPECT_EQ(num_popups, num_popups_seen);
[email protected]f1c102b2013-02-15 07:44:12112
scottmg34c5dd882016-02-03 05:21:54113 return ((num_browsers == chrome::GetBrowserCount(browser->profile())) &&
[email protected]f1c102b2013-02-15 07:44:12114 (num_tabs == browser->tab_strip_model()->count()) &&
[email protected]f1c102b2013-02-15 07:44:12115 (num_popups == num_popups_seen));
[email protected]4026ce1e2010-09-14 19:35:04116}
117
jam1a5b5582017-05-01 16:50:10118IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, BrowserIsApp) {
[email protected]c1dffe82013-06-26 20:59:05119 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]f112b0f2011-05-26 01:53:52120 ASSERT_TRUE(LoadExtension(
121 test_data_dir_.AppendASCII("window_open").AppendASCII("browser_is_app")));
122
dimich566d3642016-08-23 16:39:06123 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 2));
[email protected]f112b0f2011-05-26 01:53:52124
scottmg8abbff832016-01-28 22:57:37125 for (auto* b : *BrowserList::GetInstance()) {
126 if (b == browser())
127 ASSERT_FALSE(b->is_app());
[email protected]f112b0f2011-05-26 01:53:52128 else
scottmg8abbff832016-01-28 22:57:37129 ASSERT_TRUE(b->is_app());
[email protected]f112b0f2011-05-26 01:53:52130 }
131}
132
jam1a5b5582017-05-01 16:50:10133IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupDefault) {
[email protected]c1dffe82013-06-26 20:59:05134 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]0a5bdc6522011-06-08 19:04:49135 ASSERT_TRUE(LoadExtension(
136 test_data_dir_.AppendASCII("window_open").AppendASCII("popup")));
137
138 const int num_tabs = 1;
139 const int num_popups = 0;
dimich566d3642016-08-23 16:39:06140 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]0a5bdc6522011-06-08 19:04:49141}
142
jam1a5b5582017-05-01 16:50:10143IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupIframe) {
[email protected]7c6ef352013-09-26 07:23:14144 base::FilePath test_data_dir;
Avi Drissman9098f9002018-05-04 00:11:52145 base::PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
[email protected]7c6ef352013-09-26 07:23:14146 embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
martijnf9b885b72016-11-22 22:03:47147 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]7c6ef352013-09-26 07:23:14148 ASSERT_TRUE(LoadExtension(
149 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_iframe")));
150
jochenc5cfa642014-09-02 15:30:03151 const int num_tabs = 1;
152 const int num_popups = 0;
dimich566d3642016-08-23 16:39:06153 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]7c6ef352013-09-26 07:23:14154}
155
jam1a5b5582017-05-01 16:50:10156IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupLarge) {
[email protected]c1dffe82013-06-26 20:59:05157 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]0a5bdc6522011-06-08 19:04:49158 ASSERT_TRUE(LoadExtension(
159 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_large")));
160
[email protected]0a5bdc6522011-06-08 19:04:49161 // On other systems this should open a new popup window.
162 const int num_tabs = 0;
163 const int num_popups = 1;
dimich566d3642016-08-23 16:39:06164 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]0a5bdc6522011-06-08 19:04:49165}
166
jam1a5b5582017-05-01 16:50:10167IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowOpenPopupSmall) {
[email protected]c1dffe82013-06-26 20:59:05168 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]0a5bdc6522011-06-08 19:04:49169 ASSERT_TRUE(LoadExtension(
170 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_small")));
171
172 // On ChromeOS this should open a new panel (acts like a new popup window).
173 // On other systems this should open a new popup window.
174 const int num_tabs = 0;
175 const int num_popups = 1;
dimich566d3642016-08-23 16:39:06176 EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups));
[email protected]0a5bdc6522011-06-08 19:04:49177}
178
[email protected]73fa1fce2013-02-21 20:10:05179// Disabled on Windows. Often times out or fails: crbug.com/177530
180#if defined(OS_WIN)
181#define MAYBE_PopupBlockingExtension DISABLED_PopupBlockingExtension
182#else
183#define MAYBE_PopupBlockingExtension PopupBlockingExtension
184#endif
jam1a5b5582017-05-01 16:50:10185IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, MAYBE_PopupBlockingExtension) {
[email protected]c1dffe82013-06-26 20:59:05186 ASSERT_TRUE(StartEmbeddedTestServer());
[email protected]4026ce1e2010-09-14 19:35:04187
188 ASSERT_TRUE(LoadExtension(
189 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
190 .AppendASCII("extension")));
191
dimich566d3642016-08-23 16:39:06192 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 5, 3));
[email protected]4026ce1e2010-09-14 19:35:04193}
194
jam1a5b5582017-05-01 16:50:10195IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, PopupBlockingHostedApp) {
svaldeza01f7d92015-11-18 17:47:56196 ASSERT_TRUE(embedded_test_server()->Start());
[email protected]4026ce1e2010-09-14 19:35:04197
198 ASSERT_TRUE(LoadExtension(
199 test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
200 .AppendASCII("hosted_app")));
201
[email protected]fe3048872010-10-18 14:58:59202 // The app being tested owns the domain a.com . The test URLs we navigate
203 // to below must be within that domain, so that they fall within the app's
204 // web extent.
205 GURL::Replacements replace_host;
mgiuca77752c32015-02-05 07:31:18206 replace_host.SetHostStr("a.com");
[email protected]fe3048872010-10-18 14:58:59207
208 const std::string popup_app_contents_path(
svaldeza01f7d92015-11-18 17:47:56209 "/extensions/api_test/window_open/popup_blocking/hosted_app/");
[email protected]fe3048872010-10-18 14:58:59210
svaldeza01f7d92015-11-18 17:47:56211 GURL open_tab = embedded_test_server()
212 ->GetURL(popup_app_contents_path + "open_tab.html")
213 .ReplaceComponents(replace_host);
214 GURL open_popup = embedded_test_server()
215 ->GetURL(popup_app_contents_path + "open_popup.html")
216 .ReplaceComponents(replace_host);
[email protected]fe3048872010-10-18 14:58:59217
nick3b04f322016-08-31 19:29:19218 browser()->OpenURL(OpenURLParams(open_tab, Referrer(),
219 WindowOpenDisposition::NEW_FOREGROUND_TAB,
220 ui::PAGE_TRANSITION_TYPED, false));
221 browser()->OpenURL(OpenURLParams(open_popup, Referrer(),
222 WindowOpenDisposition::NEW_FOREGROUND_TAB,
223 ui::PAGE_TRANSITION_TYPED, false));
[email protected]4026ce1e2010-09-14 19:35:04224
dimich566d3642016-08-23 16:39:06225 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 3, 1));
[email protected]4026ce1e2010-09-14 19:35:04226}
[email protected]d4db6c702011-03-28 21:49:14227
jam1a5b5582017-05-01 16:50:10228IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, WindowArgumentsOverflow) {
[email protected]e7f90562011-05-23 21:38:24229 ASSERT_TRUE(RunExtensionTest("window_open/argument_overflow")) << message_;
230}
231
jam1a5b5582017-05-01 16:50:10232IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, DISABLED_WindowOpener) {
[email protected]54edcea2011-07-27 01:56:38233 ASSERT_TRUE(RunExtensionTest("window_open/opener")) << message_;
234}
[email protected]fad73672012-06-15 23:26:06235
[email protected]fa7c1602013-04-03 23:00:20236#if defined(OS_MACOSX)
237// Extension popup windows are incorrectly sized on OSX, crbug.com/225601
238#define MAYBE_WindowOpenSized DISABLED_WindowOpenSized
239#else
240#define MAYBE_WindowOpenSized WindowOpenSized
241#endif
242// Ensure that the width and height properties of a window opened with
243// chrome.windows.create match the creation parameters. See crbug.com/173831.
jam1a5b5582017-05-01 16:50:10244IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, MAYBE_WindowOpenSized) {
[email protected]fa7c1602013-04-03 23:00:20245 ASSERT_TRUE(RunExtensionTest("window_open/window_size")) << message_;
dimich566d3642016-08-23 16:39:06246 EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 1));
[email protected]fa7c1602013-04-03 23:00:20247}
248
[email protected]fad73672012-06-15 23:26:06249// Tests that an extension page can call window.open to an extension URL and
250// the new window has extension privileges.
251IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenExtension) {
252 ASSERT_TRUE(LoadExtension(
253 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));
254
[email protected]99bee642014-05-31 22:36:43255 GURL start_url(std::string(extensions::kExtensionScheme) +
[email protected]fb4fe0952014-06-05 09:44:24256 url::kStandardSchemeSeparator +
[email protected]99bee642014-05-31 22:36:43257 last_loaded_extension_id() + "/test.html");
[email protected]fad73672012-06-15 23:26:06258 ui_test_utils::NavigateToURL(browser(), start_url);
[email protected]f3e73f62012-10-20 05:35:16259 WebContents* newtab = NULL;
[email protected]e0448872013-01-11 19:35:02260 ASSERT_NO_FATAL_FAILURE(
261 OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
Devlin Croninf1afce252017-08-19 01:21:48262 start_url.Resolve("newtab.html"), true, true, &newtab));
[email protected]fad73672012-06-15 23:26:06263
264 bool result = false;
[email protected]b6987e02013-01-04 18:30:43265 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
266 &result));
[email protected]fad73672012-06-15 23:26:06267 EXPECT_TRUE(result);
268}
269
270// Tests that if an extension page calls window.open to an invalid extension
271// URL, the browser doesn't crash.
272IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenInvalidExtension) {
nick6cfe5c72017-05-22 22:00:42273 const extensions::Extension* extension = LoadExtension(
274 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
275 ASSERT_TRUE(extension);
[email protected]fad73672012-06-15 23:26:06276
nick6cfe5c72017-05-22 22:00:42277 GURL start_url = extension->GetResourceURL("/test.html");
[email protected]fad73672012-06-15 23:26:06278 ui_test_utils::NavigateToURL(browser(), start_url);
nick6cfe5c72017-05-22 22:00:42279 WebContents* newtab = nullptr;
Devlin Croninf1afce252017-08-19 01:21:48280 bool new_page_in_same_process = true;
281 bool expect_success = false;
nick6cfe5c72017-05-22 22:00:42282 ASSERT_NO_FATAL_FAILURE(OpenWindow(
283 browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]fad73672012-06-15 23:26:06284 GURL("chrome-extension://thisissurelynotavalidextensionid/newtab.html"),
Devlin Croninf1afce252017-08-19 01:21:48285 new_page_in_same_process, expect_success, &newtab));
[email protected]fad73672012-06-15 23:26:06286
Devlin Croninf1afce252017-08-19 01:21:48287 // This is expected to redirect to about:blank.
288 EXPECT_EQ(GURL(url::kAboutBlankURL), newtab->GetLastCommittedURL());
[email protected]fad73672012-06-15 23:26:06289}
290
291// Tests that calling window.open from the newtab page to an extension URL
292// gives the new window extension privileges - even though the opening page
293// does not have extension privileges, we break the script connection, so
294// there is no privilege leak.
295IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenNoPrivileges) {
296 ASSERT_TRUE(LoadExtension(
297 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));
298
299 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
[email protected]f3e73f62012-10-20 05:35:16300 WebContents* newtab = NULL;
[email protected]e0448872013-01-11 19:35:02301 ASSERT_NO_FATAL_FAILURE(
302 OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
[email protected]99bee642014-05-31 22:36:43303 GURL(std::string(extensions::kExtensionScheme) +
Devlin Croninf1afce252017-08-19 01:21:48304 url::kStandardSchemeSeparator +
305 last_loaded_extension_id() + "/newtab.html"),
306 false, true, &newtab));
[email protected]fad73672012-06-15 23:26:06307
308 // Extension API should succeed.
309 bool result = false;
[email protected]b6987e02013-01-04 18:30:43310 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
311 &result));
[email protected]fad73672012-06-15 23:26:06312 EXPECT_TRUE(result);
313}
alexmos1c3da4f2016-11-03 06:06:11314
315// Tests that calling window.open for an extension URL from a non-HTTP or HTTPS
316// URL on a new tab cannot access non-web-accessible resources.
317IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest,
318 WindowOpenInaccessibleResourceFromDataURL) {
319 base::HistogramTester uma;
alexmoscf5145bb2016-11-09 23:19:45320 const extensions::Extension* extension = LoadExtension(
321 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
322 ASSERT_TRUE(extension);
alexmos1c3da4f2016-11-03 06:06:11323
324 ui_test_utils::NavigateToURL(browser(), GURL("data:text/html,foo"));
325
326 // test.html is not web-accessible and should not be loaded.
alexmoscf5145bb2016-11-09 23:19:45327 GURL extension_url(extension->GetResourceURL("test.html"));
alexmos1c3da4f2016-11-03 06:06:11328 content::WindowedNotificationObserver windowed_observer(
329 content::NOTIFICATION_LOAD_STOP,
330 content::NotificationService::AllSources());
331 ASSERT_TRUE(content::ExecuteScript(
332 browser()->tab_strip_model()->GetActiveWebContents(),
333 "window.open('" + extension_url.spec() + "');"));
334 windowed_observer.Wait();
335 content::NavigationController* controller =
336 content::Source<content::NavigationController>(windowed_observer.source())
337 .ptr();
338 content::WebContents* newtab = controller->GetWebContents();
339 ASSERT_TRUE(newtab);
340
341 EXPECT_NE(extension_url, newtab->GetMainFrame()->GetLastCommittedURL());
342 EXPECT_FALSE(newtab->GetMainFrame()->GetSiteInstance()->GetSiteURL().SchemeIs(
343 extensions::kExtensionScheme));
344
Nick Carter1cb9c33c2018-03-30 18:40:07345 // Verify that the blocking was recorded correctly in UMA. ShouldAllowOpenURL
346 // is called twice by the content layer, once when creating the window, and
347 // again when attempting to navigate the newly-created window.
alexmos1c3da4f2016-11-03 06:06:11348 uma.ExpectUniqueSample("Extensions.ShouldAllowOpenURL.Failure",
349 2, /* FAILURE_SCHEME_NOT_HTTP_OR_HTTPS_OR_EXTENSION */
Nick Carter1cb9c33c2018-03-30 18:40:07350 2);
alexmos7f7bae62017-04-05 21:15:04351 uma.ExpectUniqueSample("Extensions.ShouldAllowOpenURL.Failure.Scheme",
Nick Carter1cb9c33c2018-03-30 18:40:07352 6 /* SCHEME_DATA */, 2);
alexmos1c3da4f2016-11-03 06:06:11353}
alexmoscf5145bb2016-11-09 23:19:45354
355// Test that navigating to an extension URL is allowed on chrome:// and
356// chrome-search:// pages, even for URLs that are not web-accessible.
357// See https://crbug.com/662602.
358IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest,
Alex Moshchuk7c7368f2018-04-25 00:49:25359 NavigateToInaccessibleResourceFromChromeURL) {
alexmoscf5145bb2016-11-09 23:19:45360 // Mint an extension URL which is not web-accessible.
361 const extensions::Extension* extension = LoadExtension(
362 test_data_dir_.AppendASCII("uitest").AppendASCII("window_open"));
363 ASSERT_TRUE(extension);
364 GURL extension_url(extension->GetResourceURL("test.html"));
365
366 content::WebContents* tab =
367 browser()->tab_strip_model()->GetActiveWebContents();
368
369 // Navigate to the non-web-accessible URL from chrome:// and
370 // chrome-search:// pages. Verify that the page loads correctly.
371 GURL history_url(chrome::kChromeUIHistoryURL);
372 GURL ntp_url(chrome::kChromeSearchLocalNtpUrl);
373 ASSERT_TRUE(history_url.SchemeIs(content::kChromeUIScheme));
374 ASSERT_TRUE(ntp_url.SchemeIs(chrome::kChromeSearchScheme));
375 GURL start_urls[] = {history_url, ntp_url};
376 for (size_t i = 0; i < arraysize(start_urls); i++) {
377 ui_test_utils::NavigateToURL(browser(), start_urls[i]);
378 EXPECT_EQ(start_urls[i], tab->GetMainFrame()->GetLastCommittedURL());
379
380 content::TestNavigationObserver observer(tab);
381 ASSERT_TRUE(content::ExecuteScript(
382 tab, "location.href = '" + extension_url.spec() + "';"));
383 observer.Wait();
384 EXPECT_EQ(extension_url, tab->GetMainFrame()->GetLastCommittedURL());
385 std::string result;
386 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
387 tab, "domAutomationController.send(document.body.innerText)", &result));
388 EXPECT_EQ("HOWDIE!!!", result);
389 }
390}
Ivan Sandrkc30341b2017-11-09 19:13:26391
392#if defined(OS_CHROMEOS)
393
394namespace {
395
Ivan Sandrkc9eb2962017-11-16 15:35:10396aura::Window* GetCurrentWindow() {
Ivan Sandrkc30341b2017-11-09 19:13:26397 extensions::WindowController* controller = nullptr;
398 for (auto* iter :
399 extensions::WindowControllerList::GetInstance()->windows()) {
400 if (iter->window()->IsActive()) {
401 controller = iter;
402 break;
403 }
404 }
405 EXPECT_TRUE(controller);
Ivan Sandrkc9eb2962017-11-16 15:35:10406 return controller->window()->GetNativeWindow();
407}
408
409ash::mojom::WindowPinType GetCurrentWindowPinType() {
410 ash::mojom::WindowPinType type =
411 GetCurrentWindow()->GetProperty(ash::kWindowPinTypeKey);
Ivan Sandrkc30341b2017-11-09 19:13:26412 return type;
413}
414
Ivan Sandrkc9eb2962017-11-16 15:35:10415void SetCurrentWindowPinType(ash::mojom::WindowPinType type) {
416 GetCurrentWindow()->SetProperty(ash::kWindowPinTypeKey, type);
417}
418
Ivan Sandrkc30341b2017-11-09 19:13:26419} // namespace
420
421IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, OpenLockedFullscreenWindow) {
422 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
423 "openLockedFullscreenWindow"))
424 << message_;
425
426 // Make sure the newly created window is "trusted pinned" (which means that
427 // it's in locked fullscreen mode).
428 EXPECT_EQ(ash::mojom::WindowPinType::TRUSTED_PINNED,
429 GetCurrentWindowPinType());
430}
431
432IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, UpdateWindowToLockedFullscreen) {
433 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
434 "updateWindowToLockedFullscreen"))
435 << message_;
436
437 // Make sure the current window is put into the "trusted pinned" state.
438 EXPECT_EQ(ash::mojom::WindowPinType::TRUSTED_PINNED,
439 GetCurrentWindowPinType());
440}
441
Ivan Sandrkc9eb2962017-11-16 15:35:10442IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, RemoveLockedFullscreenFromWindow) {
Ivan Sandrk9669d0e2017-12-15 23:50:20443 // After locking the window, do a LockedFullscreenStateChanged so the
444 // command_controller state catches up as well.
Ivan Sandrkc9eb2962017-11-16 15:35:10445 SetCurrentWindowPinType(ash::mojom::WindowPinType::TRUSTED_PINNED);
Ivan Sandrk9669d0e2017-12-15 23:50:20446 browser()->command_controller()->LockedFullscreenStateChanged();
Ivan Sandrkc9eb2962017-11-16 15:35:10447
448 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
449 "removeLockedFullscreenFromWindow"))
450 << message_;
451
452 // Make sure the current window is removed from locked-fullscreen state.
453 EXPECT_EQ(ash::mojom::WindowPinType::NONE, GetCurrentWindowPinType());
454}
455
Ivan Sandrk9669d0e2017-12-15 23:50:20456// Make sure that commands disabling code works in locked fullscreen mode.
457IN_PROC_BROWSER_TEST_F(WindowOpenApiTest, VerifyCommandsInLockedFullscreen) {
458 // IDC_EXIT is always enabled in regular mode so it's a perfect candidate for
459 // testing.
460 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_EXIT));
461 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/with_permission",
462 "updateWindowToLockedFullscreen"))
463 << message_;
464
465 // IDC_EXIT is not enabled in locked fullscreen.
466 EXPECT_FALSE(browser()->command_controller()->IsCommandEnabled(IDC_EXIT));
467
468 // Verify some whitelisted commands.
469 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_COPY));
470 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_FIND));
471 EXPECT_TRUE(browser()->command_controller()->IsCommandEnabled(IDC_ZOOM_PLUS));
472}
473
Ivan Sandrkc30341b2017-11-09 19:13:26474IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
475 OpenLockedFullscreenWindowWithoutPermission) {
476 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
477 "openLockedFullscreenWindow"))
478 << message_;
479
480 // Make sure no new windows get created (so only the one created by default
481 // exists) since the call to chrome.windows.create fails on the javascript
482 // side.
483 EXPECT_EQ(1u,
484 extensions::WindowControllerList::GetInstance()->windows().size());
485}
486
487IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
488 UpdateWindowToLockedFullscreenWithoutPermission) {
489 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
490 "updateWindowToLockedFullscreen"))
491 << message_;
492
493 // chrome.windows.update call fails since this extension doesn't have the
494 // correct permission and hence the current window has NONE as WindowPinType.
Ivan Sandrkc9eb2962017-11-16 15:35:10495 EXPECT_EQ(ash::mojom::WindowPinType::NONE, GetCurrentWindowPinType());
496}
497
498IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
499 RemoveLockedFullscreenFromWindowWithoutPermission) {
500 SetCurrentWindowPinType(ash::mojom::WindowPinType::TRUSTED_PINNED);
Ivan Sandrk9669d0e2017-12-15 23:50:20501 browser()->command_controller()->LockedFullscreenStateChanged();
Ivan Sandrkc9eb2962017-11-16 15:35:10502
503 ASSERT_TRUE(RunExtensionTestWithArg("locked_fullscreen/without_permission",
504 "removeLockedFullscreenFromWindow"))
505 << message_;
506
507 // The current window is still locked-fullscreen.
508 EXPECT_EQ(ash::mojom::WindowPinType::TRUSTED_PINNED,
Ivan Sandrkc30341b2017-11-09 19:13:26509 GetCurrentWindowPinType());
510}
511#endif // defined(OS_CHROMEOS)
512
513#if !defined(OS_CHROMEOS)
514// Loading an extension requiring the 'lockWindowFullscreenPrivate' permission
515// on non Chrome OS platforms should always fail since the API is available only
516// on Chrome OS.
517IN_PROC_BROWSER_TEST_F(WindowOpenApiTest,
518 OpenLockedFullscreenWindowNonChromeOS) {
519 const extensions::Extension* extension = LoadExtensionWithFlags(
520 test_data_dir_.AppendASCII("locked_fullscreen/with_permission"),
521 ExtensionBrowserTest::kFlagIgnoreManifestWarnings);
522 ASSERT_TRUE(extension);
523 EXPECT_EQ(1u, extension->install_warnings().size());
524 EXPECT_EQ(std::string("'lockWindowFullscreenPrivate' "
525 "is not allowed for specified platform."),
526 extension->install_warnings().front().message);
527}
528#endif
Devlin Cronin836f545d2018-05-09 00:25:05529
530} // namespace extensions