1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "base/command_line.h" 6#include "chrome/browser/chrome_notification_types.h" 7#include "chrome/browser/extensions/extension_apitest.h" 8#include "chrome/browser/extensions/extension_service.h" 9#include "chrome/browser/profiles/profile.h" 10#include "chrome/browser/ui/browser.h" 11#include "chrome/browser/ui/login/login_prompt.h" 12#include "chrome/browser/ui/tabs/tab_strip_model.h" 13#include "chrome/test/base/ui_test_utils.h" 14#include "content/public/browser/notification_registrar.h" 15#include "content/public/browser/notification_service.h" 16#include "content/public/browser/render_view_host.h" 17#include "content/public/browser/web_contents.h" 18#include "content/public/test/browser_test_utils.h" 19#include "extensions/browser/api/web_request/web_request_api.h" 20#include "extensions/browser/extension_system.h" 21#include "extensions/common/features/feature.h" 22#include "extensions/test/extension_test_message_listener.h" 23#include "extensions/test/result_catcher.h" 24#include "net/dns/mock_host_resolver.h" 25#include "net/test/embedded_test_server/embedded_test_server.h" 26#include "third_party/WebKit/public/web/WebInputEvent.h" 27 28using content::WebContents; 29using extensions::Feature; 30using extensions::ResultCatcher; 31 32namespace { 33 34class CancelLoginDialog : public content::NotificationObserver { 35 public: 36 CancelLoginDialog() { 37 registrar_.Add(this, 38 chrome::NOTIFICATION_AUTH_NEEDED, 39 content::NotificationService::AllSources()); 40 } 41 42 virtual ~CancelLoginDialog() {} 43 44 virtual void Observe(int type, 45 const content::NotificationSource& source, 46 const content::NotificationDetails& details) OVERRIDE { 47 LoginHandler* handler = 48 content::Details<LoginNotificationDetails>(details).ptr()->handler(); 49 handler->CancelAuth(); 50 } 51 52 private: 53 content::NotificationRegistrar registrar_; 54 55 DISALLOW_COPY_AND_ASSIGN(CancelLoginDialog); 56}; 57 58} // namespace 59 60class ExtensionWebRequestApiTest : public ExtensionApiTest { 61 public: 62 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 63 ExtensionApiTest::SetUpInProcessBrowserTestFixture(); 64 host_resolver()->AddRule("*", "127.0.0.1"); 65 } 66 67 void RunPermissionTest( 68 const char* extension_directory, 69 bool load_extension_with_incognito_permission, 70 bool wait_for_extension_loaded_in_incognito, 71 const char* expected_content_regular_window, 72 const char* exptected_content_incognito_window); 73}; 74 75IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestApi) { 76 ASSERT_TRUE(StartEmbeddedTestServer()); 77 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_api.html")) << message_; 78} 79 80// Fails often on Windows dbg bots. http://crbug.com/177163 81#if defined(OS_WIN) 82#define MAYBE_WebRequestSimple DISABLED_WebRequestSimple 83#else 84#define MAYBE_WebRequestSimple WebRequestSimple 85#endif // defined(OS_WIN) 86IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MAYBE_WebRequestSimple) { 87 ASSERT_TRUE(StartEmbeddedTestServer()); 88 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_simple.html")) << 89 message_; 90} 91 92IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestComplex) { 93 ASSERT_TRUE(StartEmbeddedTestServer()); 94 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_complex.html")) << 95 message_; 96} 97 98// Flaky (sometimes crash): http://crbug.com/140976 99IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, 100 DISABLED_WebRequestAuthRequired) { 101 CancelLoginDialog login_dialog_helper; 102 103 ASSERT_TRUE(StartEmbeddedTestServer()); 104 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_auth_required.html")) << 105 message_; 106} 107 108// This test times out regularly on win_rel trybots. See http://crbug.com/122178 109#if defined(OS_WIN) 110#define MAYBE_WebRequestBlocking DISABLED_WebRequestBlocking 111#else 112#define MAYBE_WebRequestBlocking WebRequestBlocking 113#endif 114IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MAYBE_WebRequestBlocking) { 115 ASSERT_TRUE(StartEmbeddedTestServer()); 116 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_blocking.html")) << 117 message_; 118} 119 120// Fails often on Windows dbg bots. http://crbug.com/177163 121#if defined(OS_WIN) 122#define MAYBE_WebRequestNewTab DISABLED_WebRequestNewTab 123#else 124#define MAYBE_WebRequestNewTab WebRequestNewTab 125#endif // defined(OS_WIN) 126IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MAYBE_WebRequestNewTab) { 127 ASSERT_TRUE(StartEmbeddedTestServer()); 128 // Wait for the extension to set itself up and return control to us. 129 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_newTab.html")) 130 << message_; 131 132 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 133 content::WaitForLoadStop(tab); 134 135 ResultCatcher catcher; 136 137 ExtensionService* service = extensions::ExtensionSystem::Get( 138 browser()->profile())->extension_service(); 139 const extensions::Extension* extension = 140 service->GetExtensionById(last_loaded_extension_id(), false); 141 GURL url = extension->GetResourceURL("newTab/a.html"); 142 143 ui_test_utils::NavigateToURL(browser(), url); 144 145 // There's a link on a.html with target=_blank. Click on it to open it in a 146 // new tab. 147 blink::WebMouseEvent mouse_event; 148 mouse_event.type = blink::WebInputEvent::MouseDown; 149 mouse_event.button = blink::WebMouseEvent::ButtonLeft; 150 mouse_event.x = 7; 151 mouse_event.y = 7; 152 mouse_event.clickCount = 1; 153 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 154 mouse_event.type = blink::WebInputEvent::MouseUp; 155 tab->GetRenderViewHost()->ForwardMouseEvent(mouse_event); 156 157 ASSERT_TRUE(catcher.GetNextResult()) << catcher.message(); 158} 159 160IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, WebRequestDeclarative1) { 161 ASSERT_TRUE(StartEmbeddedTestServer()); 162 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_declarative1.html")) 163 << message_; 164} 165 166// This test times out on XP. See http://crbug.com/178296 167#if defined(OS_WIN) 168#define MAYBE_WebRequestDeclarative2 DISABLED_WebRequestDeclarative2 169#else 170#define MAYBE_WebRequestDeclarative2 WebRequestDeclarative2 171#endif 172IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, 173 MAYBE_WebRequestDeclarative2) { 174 ASSERT_TRUE(StartEmbeddedTestServer()); 175 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_declarative2.html")) 176 << message_; 177} 178 179void ExtensionWebRequestApiTest::RunPermissionTest( 180 const char* extension_directory, 181 bool load_extension_with_incognito_permission, 182 bool wait_for_extension_loaded_in_incognito, 183 const char* expected_content_regular_window, 184 const char* exptected_content_incognito_window) { 185 ResultCatcher catcher; 186 catcher.RestrictToBrowserContext(browser()->profile()); 187 ResultCatcher catcher_incognito; 188 catcher_incognito.RestrictToBrowserContext( 189 browser()->profile()->GetOffTheRecordProfile()); 190 191 ExtensionTestMessageListener listener("done", true); 192 ExtensionTestMessageListener listener_incognito("done_incognito", true); 193 194 int load_extension_flags = kFlagNone; 195 if (load_extension_with_incognito_permission) 196 load_extension_flags |= kFlagEnableIncognito; 197 ASSERT_TRUE(LoadExtensionWithFlags( 198 test_data_dir_.AppendASCII("webrequest_permissions") 199 .AppendASCII(extension_directory), 200 load_extension_flags)); 201 202 // Test that navigation in regular window is properly redirected. 203 EXPECT_TRUE(listener.WaitUntilSatisfied()); 204 205 // This navigation should be redirected. 206 ui_test_utils::NavigateToURL( 207 browser(), 208 embedded_test_server()->GetURL("/extensions/test_file.html")); 209 210 std::string body; 211 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 212 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 213 tab, 214 "window.domAutomationController.send(document.body.textContent)", 215 &body)); 216 EXPECT_EQ(expected_content_regular_window, body); 217 218 // Test that navigation in OTR window is properly redirected. 219 Browser* otr_browser = ui_test_utils::OpenURLOffTheRecord( 220 browser()->profile(), GURL("about:blank")); 221 222 if (wait_for_extension_loaded_in_incognito) 223 EXPECT_TRUE(listener_incognito.WaitUntilSatisfied()); 224 225 // This navigation should be redirected if 226 // load_extension_with_incognito_permission is true. 227 ui_test_utils::NavigateToURL( 228 otr_browser, 229 embedded_test_server()->GetURL("/extensions/test_file.html")); 230 231 body.clear(); 232 WebContents* otr_tab = otr_browser->tab_strip_model()->GetActiveWebContents(); 233 ASSERT_TRUE(content::ExecuteScriptAndExtractString( 234 otr_tab, 235 "window.domAutomationController.send(document.body.textContent)", 236 &body)); 237 EXPECT_EQ(exptected_content_incognito_window, body); 238} 239 240IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, 241 WebRequestDeclarativePermissionSpanning1) { 242 // Test spanning with incognito permission. 243 ASSERT_TRUE(StartEmbeddedTestServer()); 244 RunPermissionTest("spanning", true, false, "redirected1", "redirected1"); 245} 246 247IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, 248 WebRequestDeclarativePermissionSpanning2) { 249 // Test spanning without incognito permission. 250 ASSERT_TRUE(StartEmbeddedTestServer()); 251 RunPermissionTest("spanning", false, false, "redirected1", ""); 252} 253 254 255IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, 256 WebRequestDeclarativePermissionSplit1) { 257 // Test split with incognito permission. 258 ASSERT_TRUE(StartEmbeddedTestServer()); 259 RunPermissionTest("split", true, true, "redirected1", "redirected2"); 260} 261 262IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, 263 WebRequestDeclarativePermissionSplit2) { 264 // Test split without incognito permission. 265 ASSERT_TRUE(StartEmbeddedTestServer()); 266 RunPermissionTest("split", false, false, "redirected1", ""); 267} 268 269// TODO(vabr): Cure these flaky tests, http://crbug.com/238179. 270#if !defined(NDEBUG) 271#define MAYBE_PostData1 DISABLED_PostData1 272#define MAYBE_PostData2 DISABLED_PostData2 273#else 274#define MAYBE_PostData1 PostData1 275#define MAYBE_PostData2 PostData2 276#endif 277IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MAYBE_PostData1) { 278 // Test HTML form POST data access with the default and "url" encoding. 279 ASSERT_TRUE(StartEmbeddedTestServer()); 280 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_post1.html")) << 281 message_; 282} 283 284IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, MAYBE_PostData2) { 285 // Test HTML form POST data access with the multipart and plaintext encoding. 286 ASSERT_TRUE(StartEmbeddedTestServer()); 287 ASSERT_TRUE(RunExtensionSubtest("webrequest", "test_post2.html")) << 288 message_; 289} 290 291IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, 292 DeclarativeSendMessage) { 293 ASSERT_TRUE(StartEmbeddedTestServer()); 294 ASSERT_TRUE(RunExtensionTest("webrequest_sendmessage")) << message_; 295} 296 297// Check that reloading an extension that runs in incognito split mode and 298// has two active background pages with registered events does not crash the 299// browser. Regression test for http://crbug.com/224094 300IN_PROC_BROWSER_TEST_F(ExtensionWebRequestApiTest, IncognitoSplitModeReload) { 301 ASSERT_TRUE(StartEmbeddedTestServer()); 302 // Wait for rules to be set up. 303 ExtensionTestMessageListener listener("done", true); 304 ExtensionTestMessageListener listener_incognito("done_incognito", true); 305 306 const extensions::Extension* extension = LoadExtensionWithFlags( 307 test_data_dir_.AppendASCII("webrequest_reload"), 308 kFlagEnableIncognito); 309 ASSERT_TRUE(extension); 310 ui_test_utils::OpenURLOffTheRecord(browser()->profile(), GURL("about:blank")); 311 312 EXPECT_TRUE(listener.WaitUntilSatisfied()); 313 EXPECT_TRUE(listener_incognito.WaitUntilSatisfied()); 314 315 // Reload extension and wait for rules to be set up again. This should not 316 // crash the browser. 317 ExtensionTestMessageListener listener2("done", true); 318 ExtensionTestMessageListener listener_incognito2("done_incognito", true); 319 320 ReloadExtension(extension->id()); 321 322 EXPECT_TRUE(listener2.WaitUntilSatisfied()); 323 EXPECT_TRUE(listener_incognito2.WaitUntilSatisfied()); 324} 325