Rename desktop_cursor_loader_updater_aurax11.
[chromium-blink-merge.git] / chrome / browser / extensions / lazy_background_page_apitest.cc
blobdf1bf3dfd3290968a00ac464c4944d7b759c5e76
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.
5 #include "base/command_line.h"
6 #include "base/files/file_path.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/bookmarks/bookmark_model.h"
9 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
10 #include "chrome/browser/bookmarks/bookmark_test_helpers.h"
11 #include "chrome/browser/bookmarks/bookmark_utils.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/extensions/browser_action_test_util.h"
14 #include "chrome/browser/extensions/extension_apitest.h"
15 #include "chrome/browser/extensions/extension_host.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "chrome/browser/extensions/extension_system.h"
18 #include "chrome/browser/extensions/extension_test_message_listener.h"
19 #include "chrome/browser/extensions/lazy_background_page_test_util.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/search/search.h"
22 #include "chrome/browser/ui/browser.h"
23 #include "chrome/browser/ui/browser_window.h"
24 #include "chrome/browser/ui/omnibox/location_bar.h"
25 #include "chrome/browser/ui/tabs/tab_strip_model.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/common/extensions/extension.h"
28 #include "chrome/common/url_constants.h"
29 #include "chrome/test/base/ui_test_utils.h"
30 #include "content/public/browser/notification_service.h"
31 #include "content/public/browser/web_contents.h"
32 #include "content/public/test/browser_test_utils.h"
33 #include "net/dns/mock_host_resolver.h"
34 #include "net/test/embedded_test_server/embedded_test_server.h"
35 #include "url/gurl.h"
37 using extensions::Extension;
39 namespace {
41 // This unfortunate bit of silliness is necessary when loading an extension in
42 // incognito. The goal is to load the extension, enable incognito, then wait
43 // for both background pages to load and close. The problem is that enabling
44 // incognito involves reloading the extension - and the background pages may
45 // have already loaded once before then. So we wait until the extension is
46 // unloaded before listening to the background page notifications.
47 class LoadedIncognitoObserver : public content::NotificationObserver {
48 public:
49 explicit LoadedIncognitoObserver(Profile* profile) : profile_(profile) {
50 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
51 content::Source<Profile>(profile));
54 void Wait() {
55 ASSERT_TRUE(original_complete_.get());
56 original_complete_->Wait();
57 incognito_complete_->Wait();
60 private:
62 virtual void Observe(
63 int type,
64 const content::NotificationSource& source,
65 const content::NotificationDetails& details) OVERRIDE {
66 original_complete_.reset(new LazyBackgroundObserver(profile_));
67 incognito_complete_.reset(
68 new LazyBackgroundObserver(profile_->GetOffTheRecordProfile()));
71 Profile* profile_;
72 content::NotificationRegistrar registrar_;
73 scoped_ptr<LazyBackgroundObserver> original_complete_;
74 scoped_ptr<LazyBackgroundObserver> incognito_complete_;
77 } // namespace
79 class LazyBackgroundPageApiTest : public ExtensionApiTest {
80 public:
81 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
82 ExtensionApiTest::SetUpCommandLine(command_line);
83 // Set shorter delays to prevent test timeouts.
84 command_line->AppendSwitchASCII(switches::kEventPageIdleTime, "1");
85 command_line->AppendSwitchASCII(switches::kEventPageSuspendingTime, "1");
88 // Loads the extension, which temporarily starts the lazy background page
89 // to dispatch the onInstalled event. We wait until it shuts down again.
90 const Extension* LoadExtensionAndWait(const std::string& test_name) {
91 LazyBackgroundObserver page_complete;
92 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
93 AppendASCII(test_name);
94 const Extension* extension = LoadExtension(extdir);
95 if (extension)
96 page_complete.Wait();
97 return extension;
101 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BrowserActionCreateTab) {
102 ASSERT_TRUE(LoadExtensionAndWait("browser_action_create_tab"));
104 // Lazy Background Page doesn't exist yet.
105 ExtensionProcessManager* pm =
106 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
107 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
108 int num_tabs_before = browser()->tab_strip_model()->count();
110 // Observe background page being created and closed after
111 // the browser action is clicked.
112 LazyBackgroundObserver page_complete;
113 BrowserActionTestUtil(browser()).Press(0);
114 page_complete.Wait();
116 // Background page created a new tab before it closed.
117 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
118 EXPECT_EQ(num_tabs_before + 1, browser()->tab_strip_model()->count());
119 EXPECT_EQ(std::string(chrome::kChromeUIExtensionsURL),
120 browser()->tab_strip_model()->GetActiveWebContents()->
121 GetURL().spec());
124 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest,
125 BrowserActionCreateTabAfterCallback) {
126 ASSERT_TRUE(LoadExtensionAndWait("browser_action_with_callback"));
128 // Lazy Background Page doesn't exist yet.
129 ExtensionProcessManager* pm =
130 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
131 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
132 int num_tabs_before = browser()->tab_strip_model()->count();
134 // Observe background page being created and closed after
135 // the browser action is clicked.
136 LazyBackgroundObserver page_complete;
137 BrowserActionTestUtil(browser()).Press(0);
138 page_complete.Wait();
140 // Background page is closed after creating a new tab.
141 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
142 EXPECT_EQ(num_tabs_before + 1, browser()->tab_strip_model()->count());
145 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BroadcastEvent) {
146 ASSERT_TRUE(StartEmbeddedTestServer());
148 const Extension* extension = LoadExtensionAndWait("broadcast_event");
149 ASSERT_TRUE(extension);
151 // Lazy Background Page doesn't exist yet.
152 ExtensionProcessManager* pm =
153 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
154 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
155 int num_page_actions = browser()->window()->GetLocationBar()->
156 GetLocationBarForTesting()->PageActionVisibleCount();
158 // Open a tab to a URL that will trigger the page action to show.
159 LazyBackgroundObserver page_complete;
160 content::WindowedNotificationObserver page_action_changed(
161 chrome::NOTIFICATION_EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
162 content::NotificationService::AllSources());
163 ui_test_utils::NavigateToURL(
164 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
165 page_complete.Wait();
167 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
169 // Page action is shown.
170 page_action_changed.Wait();
171 EXPECT_EQ(num_page_actions + 1,
172 browser()->window()->GetLocationBar()->
173 GetLocationBarForTesting()->PageActionVisibleCount());
176 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Filters) {
177 ASSERT_TRUE(StartEmbeddedTestServer());
179 const Extension* extension = LoadExtensionAndWait("filters");
180 ASSERT_TRUE(extension);
182 // Lazy Background Page doesn't exist yet.
183 ExtensionProcessManager* pm =
184 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
185 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
187 // Open a tab to a URL that will fire a webNavigation event.
188 LazyBackgroundObserver page_complete;
189 ui_test_utils::NavigateToURL(
190 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
191 page_complete.Wait();
194 // Tests that the lazy background page receives the onInstalled event and shuts
195 // down.
196 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnInstalled) {
197 ResultCatcher catcher;
198 ASSERT_TRUE(LoadExtensionAndWait("on_installed"));
199 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
201 // Lazy Background Page has been shut down.
202 ExtensionProcessManager* pm =
203 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
204 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
207 // Tests that the lazy background page stays alive until all visible views are
208 // closed.
209 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForView) {
210 LazyBackgroundObserver page_complete;
211 ResultCatcher catcher;
212 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
213 AppendASCII("wait_for_view");
214 const Extension* extension = LoadExtension(extdir);
215 ASSERT_TRUE(extension);
216 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
218 // The extension should've opened a new tab to an extension page.
219 EXPECT_EQ(extension->GetResourceURL("extension_page.html").spec(),
220 browser()->tab_strip_model()->GetActiveWebContents()->
221 GetURL().spec());
223 // Lazy Background Page still exists, because the extension created a new tab
224 // to an extension page.
225 ExtensionProcessManager* pm =
226 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
227 EXPECT_TRUE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
229 // Close the new tab.
230 browser()->tab_strip_model()->CloseWebContentsAt(
231 browser()->tab_strip_model()->active_index(), TabStripModel::CLOSE_NONE);
232 page_complete.Wait();
234 // Lazy Background Page has been shut down.
235 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
238 // Tests that the lazy background page stays alive until all network requests
239 // are complete.
240 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForRequest) {
241 host_resolver()->AddRule("*", "127.0.0.1");
242 ASSERT_TRUE(StartEmbeddedTestServer());
244 LazyBackgroundObserver page_complete;
245 ResultCatcher catcher;
246 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
247 AppendASCII("wait_for_request");
248 const Extension* extension = LoadExtension(extdir);
249 ASSERT_TRUE(extension);
250 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
252 // Lazy Background Page still exists, because the extension started a request.
253 ExtensionProcessManager* pm =
254 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
255 extensions::ExtensionHost* host =
256 pm->GetBackgroundHostForExtension(last_loaded_extension_id());
257 ASSERT_TRUE(host);
259 // Abort the request.
260 bool result = false;
261 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
262 host->render_view_host(), "abortRequest()", &result));
263 EXPECT_TRUE(result);
264 page_complete.Wait();
266 // Lazy Background Page has been shut down.
267 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
270 // Tests that the lazy background page stays alive until all visible views are
271 // closed.
272 // http://crbug.com/175778; test fails frequently on OS X
273 #if defined(OS_MACOSX)
274 #define MAYBE_WaitForNTP DISABLED_WaitForNTP
275 #else
276 #define MAYBE_WaitForNTP WaitForNTP
277 #endif
278 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, MAYBE_WaitForNTP) {
279 LazyBackgroundObserver lazybg;
280 ResultCatcher catcher;
281 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
282 AppendASCII("wait_for_ntp");
283 const Extension* extension = LoadExtension(extdir);
284 ASSERT_TRUE(extension);
285 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
287 // The extension should've opened a new tab to an extension page.
288 EXPECT_TRUE(chrome::IsNTPURL(
289 browser()->tab_strip_model()->GetActiveWebContents()->GetURL(),
290 browser()->profile()));
292 // Lazy Background Page still exists, because the extension created a new tab
293 // to an extension page.
294 ExtensionProcessManager* pm =
295 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
296 EXPECT_TRUE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
298 // Navigate away from the NTP, which should close the event page.
299 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
300 lazybg.Wait();
302 // Lazy Background Page has been shut down.
303 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
306 // See crbug.com/248437
307 #if defined(OS_WIN)
308 #define MAYBE_IncognitoSplitMode DISABLED_IncognitoSplitMode
309 #else
310 #define MAYBE_IncognitoSplitMode IncognitoSplitMode
311 #endif
313 // Tests that an incognito split mode extension gets 2 lazy background pages,
314 // and they each load and unload at the proper times.
315 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, MAYBE_IncognitoSplitMode) {
316 // Open incognito window.
317 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
318 browser()->profile(), GURL("about:blank"));
320 // Load the extension with incognito enabled.
322 LoadedIncognitoObserver loaded(browser()->profile());
323 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
324 AppendASCII("incognito_split");
325 ASSERT_TRUE(LoadExtensionIncognito(extdir));
326 loaded.Wait();
329 // Lazy Background Page doesn't exist yet.
330 ExtensionProcessManager* pm =
331 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
332 ExtensionProcessManager* pmi =
333 extensions::ExtensionSystem::Get(incognito_browser->profile())->
334 process_manager();
335 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
336 EXPECT_FALSE(pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
338 // Trigger a browserAction event in the original profile and ensure only
339 // the original event page received it (since the event is scoped to the
340 // profile).
342 ExtensionTestMessageListener listener("waiting", false);
343 ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
345 LazyBackgroundObserver page_complete(browser()->profile());
346 BrowserActionTestUtil(browser()).Press(0);
347 page_complete.Wait();
349 // Only the original event page received the message.
350 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
351 EXPECT_FALSE(
352 pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
353 EXPECT_TRUE(listener.was_satisfied());
354 EXPECT_FALSE(listener_incognito.was_satisfied());
357 // Trigger a bookmark created event and ensure both pages receive it.
359 ExtensionTestMessageListener listener("waiting", false);
360 ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
362 LazyBackgroundObserver page_complete(browser()->profile()),
363 page2_complete(incognito_browser->profile());
364 BookmarkModel* bookmark_model =
365 BookmarkModelFactory::GetForProfile(browser()->profile());
366 test::WaitForBookmarkModelToLoad(bookmark_model);
367 const BookmarkNode* parent = bookmark_model->bookmark_bar_node();
368 bookmark_model->AddURL(
369 parent, 0, ASCIIToUTF16("Title"), GURL("about:blank"));
370 page_complete.Wait();
371 page2_complete.Wait();
373 // Both pages received the message.
374 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
375 EXPECT_FALSE(
376 pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
377 EXPECT_TRUE(listener.was_satisfied());
378 EXPECT_TRUE(listener_incognito.was_satisfied());
382 // Tests that messages from the content script activate the lazy background
383 // page, and keep it alive until all channels are closed.
384 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Messaging) {
385 ASSERT_TRUE(StartEmbeddedTestServer());
386 ASSERT_TRUE(LoadExtensionAndWait("messaging"));
388 // Lazy Background Page doesn't exist yet.
389 ExtensionProcessManager* pm =
390 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
391 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
392 EXPECT_EQ(1, browser()->tab_strip_model()->count());
394 // Navigate to a page that opens a message channel to the background page.
395 ResultCatcher catcher;
396 LazyBackgroundObserver lazybg;
397 ui_test_utils::NavigateToURL(
398 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
399 lazybg.WaitUntilLoaded();
401 // Background page got the content script's message and is still loaded
402 // until we close the channel.
403 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
404 EXPECT_TRUE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
406 // Navigate away, closing the message channel and therefore the background
407 // page.
408 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
409 lazybg.WaitUntilClosed();
411 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
414 // Tests that the lazy background page receives the unload event when we
415 // close it, and that it can execute simple API calls that don't require an
416 // asynchronous response.
417 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnUnload) {
418 ASSERT_TRUE(LoadExtensionAndWait("on_unload"));
420 // Lazy Background Page has been shut down.
421 ExtensionProcessManager* pm =
422 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
423 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
425 // The browser action has a new title.
426 BrowserActionTestUtil browser_action(browser());
427 ASSERT_EQ(1, browser_action.NumberOfBrowserActions());
428 EXPECT_EQ("Success", browser_action.GetTooltip(0));
431 // Tests that both a regular page and an event page will receive events when
432 // the event page is not loaded.
433 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, EventDispatchToTab) {
434 ResultCatcher catcher;
435 catcher.RestrictToProfile(browser()->profile());
437 const extensions::Extension* extension =
438 LoadExtensionAndWait("event_dispatch_to_tab");
440 ExtensionTestMessageListener page_ready("ready", true);
441 GURL page_url = extension->GetResourceURL("page.html");
442 ui_test_utils::NavigateToURL(browser(), page_url);
443 EXPECT_TRUE(page_ready.WaitUntilSatisfied());
445 // After the event is sent below, wait for the event page to have received
446 // the event before proceeding with the test. This allows the regular page
447 // to test that the event page received the event, which makes the pass/fail
448 // logic simpler.
449 ExtensionTestMessageListener event_page_ready("ready", true);
451 // Send an event by making a bookmark.
452 BookmarkModel* bookmark_model =
453 BookmarkModelFactory::GetForProfile(browser()->profile());
454 test::WaitForBookmarkModelToLoad(bookmark_model);
455 bookmark_utils::AddIfNotBookmarked(
456 bookmark_model, GURL("http://www.google.com"), UTF8ToUTF16("Google"));
458 EXPECT_TRUE(event_page_ready.WaitUntilSatisfied());
460 page_ready.Reply("go");
462 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
465 // Tests that the lazy background page updates the chrome://extensions page
466 // when it is destroyed.
467 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, UpdateExtensionsPage) {
468 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIExtensionsURL));
470 ResultCatcher catcher;
471 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
472 AppendASCII("wait_for_view");
473 const Extension* extension = LoadExtension(extdir);
474 ASSERT_TRUE(extension);
475 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
477 // The extension should've opened a new tab to an extension page.
478 EXPECT_EQ(extension->GetResourceURL("extension_page.html").spec(),
479 browser()->tab_strip_model()->GetActiveWebContents()->
480 GetURL().spec());
482 // Lazy Background Page still exists, because the extension created a new tab
483 // to an extension page.
484 ExtensionProcessManager* pm =
485 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
486 EXPECT_TRUE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
488 // Close the new tab.
489 LazyBackgroundObserver page_complete;
490 browser()->tab_strip_model()->CloseWebContentsAt(
491 browser()->tab_strip_model()->active_index(), TabStripModel::CLOSE_NONE);
492 page_complete.WaitUntilClosed();
494 // Lazy Background Page has been shut down.
495 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
497 // Verify that extensions page shows that the lazy background page is
498 // inactive.
499 bool is_inactive;
500 EXPECT_TRUE(content::ExecuteScriptInFrameAndExtractBool(
501 browser()->tab_strip_model()->GetActiveWebContents(),
502 "//iframe[starts-with(@src, 'chrome://extension')]",
503 "var ele = document.querySelectorAll('div.active-views');"
504 "window.domAutomationController.send("
505 " ele[0].innerHTML.search('(Inactive)') > 0);",
506 &is_inactive));
507 EXPECT_TRUE(is_inactive);
510 // Tests that the lazy background page will be unloaded if the onSuspend event
511 // handler calls an API function such as chrome.storage.local.set().
512 // See: http://crbug.com/296834
513 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnSuspendUseStorageApi) {
514 EXPECT_TRUE(LoadExtensionAndWait("on_suspend"));
517 // TODO: background page with timer.
518 // TODO: background page that interacts with popup.