Add ICU message format support
[chromium-blink-merge.git] / chrome / browser / extensions / lazy_background_page_apitest.cc
blobbb80d1da1d1075ddfa9a4899e4b12191ea242e31
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/path_service.h"
8 #include "base/scoped_observer.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
11 #include "chrome/browser/extensions/browser_action_test_util.h"
12 #include "chrome/browser/extensions/extension_apitest.h"
13 #include "chrome/browser/extensions/lazy_background_page_test_util.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/ui/browser.h"
16 #include "chrome/browser/ui/browser_window.h"
17 #include "chrome/browser/ui/location_bar/location_bar.h"
18 #include "chrome/browser/ui/tabs/tab_strip_model.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/url_constants.h"
22 #include "chrome/test/base/ui_test_utils.h"
23 #include "components/app_modal/app_modal_dialog.h"
24 #include "components/bookmarks/browser/bookmark_model.h"
25 #include "components/bookmarks/browser/bookmark_utils.h"
26 #include "components/bookmarks/test/bookmark_test_helpers.h"
27 #include "content/public/browser/web_contents.h"
28 #include "content/public/test/browser_test_utils.h"
29 #include "content/public/test/test_utils.h"
30 #include "extensions/browser/extension_host.h"
31 #include "extensions/browser/extension_registry.h"
32 #include "extensions/browser/extension_registry_observer.h"
33 #include "extensions/browser/process_manager.h"
34 #include "extensions/common/extension.h"
35 #include "extensions/test/extension_test_message_listener.h"
36 #include "extensions/test/result_catcher.h"
37 #include "net/dns/mock_host_resolver.h"
38 #include "net/test/embedded_test_server/embedded_test_server.h"
39 #include "testing/gtest/include/gtest/gtest.h"
40 #include "url/gurl.h"
42 using bookmarks::BookmarkModel;
43 using bookmarks::BookmarkNode;
44 using extensions::Extension;
45 using extensions::ResultCatcher;
47 namespace {
49 // This unfortunate bit of silliness is necessary when loading an extension in
50 // incognito. The goal is to load the extension, enable incognito, then wait
51 // for both background pages to load and close. The problem is that enabling
52 // incognito involves reloading the extension - and the background pages may
53 // have already loaded once before then. So we wait until the extension is
54 // unloaded before listening to the background page notifications.
55 class LoadedIncognitoObserver : public extensions::ExtensionRegistryObserver {
56 public:
57 explicit LoadedIncognitoObserver(Profile* profile)
58 : profile_(profile), extension_registry_observer_(this) {
59 extension_registry_observer_.Add(
60 extensions::ExtensionRegistry::Get(profile_));
63 void Wait() {
64 ASSERT_TRUE(original_complete_.get());
65 original_complete_->Wait();
66 incognito_complete_->Wait();
69 private:
70 void OnExtensionUnloaded(
71 content::BrowserContext* browser_context,
72 const Extension* extension,
73 extensions::UnloadedExtensionInfo::Reason reason) override {
74 original_complete_.reset(new LazyBackgroundObserver(profile_));
75 incognito_complete_.reset(
76 new LazyBackgroundObserver(profile_->GetOffTheRecordProfile()));
79 Profile* profile_;
80 ScopedObserver<extensions::ExtensionRegistry,
81 extensions::ExtensionRegistryObserver>
82 extension_registry_observer_;
83 scoped_ptr<LazyBackgroundObserver> original_complete_;
84 scoped_ptr<LazyBackgroundObserver> incognito_complete_;
87 } // namespace
89 class LazyBackgroundPageApiTest : public ExtensionApiTest {
90 public:
91 LazyBackgroundPageApiTest() {}
92 ~LazyBackgroundPageApiTest() override {}
94 void SetUpInProcessBrowserTestFixture() override {
95 ExtensionApiTest::SetUpInProcessBrowserTestFixture();
96 // Set shorter delays to prevent test timeouts.
97 extensions::ProcessManager::SetEventPageIdleTimeForTesting(1);
98 extensions::ProcessManager::SetEventPageSuspendingTimeForTesting(1);
101 void SetUpCommandLine(base::CommandLine* command_line) override {
102 ExtensionApiTest::SetUpCommandLine(command_line);
103 // Disable background network activity as it can suddenly bring the Lazy
104 // Background Page alive.
105 command_line->AppendSwitch(switches::kDisableBackgroundNetworking);
106 command_line->AppendSwitch(switches::kNoProxyServer);
109 // Loads the extension, which temporarily starts the lazy background page
110 // to dispatch the onInstalled event. We wait until it shuts down again.
111 const Extension* LoadExtensionAndWait(const std::string& test_name) {
112 LazyBackgroundObserver page_complete;
113 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
114 AppendASCII(test_name);
115 const Extension* extension = LoadExtension(extdir);
116 if (extension)
117 page_complete.Wait();
118 return extension;
121 // Returns true if the lazy background page for the extension with
122 // |extension_id| is still running.
123 bool IsBackgroundPageAlive(const std::string& extension_id) {
124 extensions::ProcessManager* pm =
125 extensions::ProcessManager::Get(browser()->profile());
126 return pm->GetBackgroundHostForExtension(extension_id);
129 private:
130 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundPageApiTest);
133 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BrowserActionCreateTab) {
134 ASSERT_TRUE(LoadExtensionAndWait("browser_action_create_tab"));
136 // Lazy Background Page doesn't exist yet.
137 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
138 int num_tabs_before = browser()->tab_strip_model()->count();
140 // Observe background page being created and closed after
141 // the browser action is clicked.
142 LazyBackgroundObserver page_complete;
143 BrowserActionTestUtil(browser()).Press(0);
144 page_complete.Wait();
146 // Background page created a new tab before it closed.
147 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
148 EXPECT_EQ(num_tabs_before + 1, browser()->tab_strip_model()->count());
149 EXPECT_EQ(std::string(chrome::kChromeUIExtensionsURL),
150 browser()->tab_strip_model()->GetActiveWebContents()->
151 GetURL().spec());
154 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest,
155 BrowserActionCreateTabAfterCallback) {
156 ASSERT_TRUE(LoadExtensionAndWait("browser_action_with_callback"));
158 // Lazy Background Page doesn't exist yet.
159 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
160 int num_tabs_before = browser()->tab_strip_model()->count();
162 // Observe background page being created and closed after
163 // the browser action is clicked.
164 LazyBackgroundObserver page_complete;
165 BrowserActionTestUtil(browser()).Press(0);
166 page_complete.Wait();
168 // Background page is closed after creating a new tab.
169 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
170 EXPECT_EQ(num_tabs_before + 1, browser()->tab_strip_model()->count());
173 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BroadcastEvent) {
174 ASSERT_TRUE(StartEmbeddedTestServer());
176 const Extension* extension = LoadExtensionAndWait("broadcast_event");
177 ASSERT_TRUE(extension);
179 // Lazy Background Page doesn't exist yet.
180 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
181 int num_page_actions = browser()->window()->GetLocationBar()->
182 GetLocationBarForTesting()->PageActionVisibleCount();
184 // Open a tab to a URL that will trigger the page action to show.
185 LazyBackgroundObserver page_complete;
186 ui_test_utils::NavigateToURL(
187 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
188 page_complete.Wait();
190 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
192 // Page action is shown.
193 WaitForPageActionVisibilityChangeTo(num_page_actions + 1);
194 EXPECT_EQ(num_page_actions + 1,
195 browser()->window()->GetLocationBar()->
196 GetLocationBarForTesting()->PageActionVisibleCount());
199 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Filters) {
200 ASSERT_TRUE(StartEmbeddedTestServer());
202 const Extension* extension = LoadExtensionAndWait("filters");
203 ASSERT_TRUE(extension);
205 // Lazy Background Page doesn't exist yet.
206 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
208 // Open a tab to a URL that will fire a webNavigation event.
209 LazyBackgroundObserver page_complete;
210 ui_test_utils::NavigateToURL(
211 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
212 page_complete.Wait();
215 // Tests that the lazy background page receives the onInstalled event and shuts
216 // down.
217 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnInstalled) {
218 ResultCatcher catcher;
219 ASSERT_TRUE(LoadExtensionAndWait("on_installed"));
220 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
222 // Lazy Background Page has been shut down.
223 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
226 // Tests that a JavaScript alert keeps the lazy background page alive.
227 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForDialog) {
228 LazyBackgroundObserver background_observer;
229 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
230 AppendASCII("wait_for_dialog");
231 const Extension* extension = LoadExtension(extdir);
232 ASSERT_TRUE(extension);
234 // The test extension opens a dialog on installation.
235 app_modal::AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
236 ASSERT_TRUE(dialog);
238 // With the dialog open the background page is still alive.
239 EXPECT_TRUE(IsBackgroundPageAlive(extension->id()));
241 // Close the dialog. The keep alive count is decremented.
242 extensions::ProcessManager* pm =
243 extensions::ProcessManager::Get(browser()->profile());
244 int previous_keep_alive_count = pm->GetLazyKeepaliveCount(extension);
245 dialog->CloseModalDialog();
246 EXPECT_EQ(previous_keep_alive_count - 1,
247 pm->GetLazyKeepaliveCount(extension));
249 // The background page closes now that the dialog is gone.
250 background_observer.WaitUntilClosed();
251 EXPECT_FALSE(IsBackgroundPageAlive(extension->id()));
254 // Tests that the lazy background page stays alive until all visible views are
255 // closed.
256 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForView) {
257 LazyBackgroundObserver page_complete;
258 ResultCatcher catcher;
259 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
260 AppendASCII("wait_for_view");
261 const Extension* extension = LoadExtension(extdir);
262 ASSERT_TRUE(extension);
263 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
265 // The extension should've opened a new tab to an extension page.
266 EXPECT_EQ(extension->GetResourceURL("extension_page.html").spec(),
267 browser()->tab_strip_model()->GetActiveWebContents()->
268 GetURL().spec());
270 // Lazy Background Page still exists, because the extension created a new tab
271 // to an extension page.
272 EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
274 // Close the new tab.
275 browser()->tab_strip_model()->CloseWebContentsAt(
276 browser()->tab_strip_model()->active_index(), TabStripModel::CLOSE_NONE);
277 page_complete.Wait();
279 // Lazy Background Page has been shut down.
280 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
283 // Tests that the lazy background page stays alive until all network requests
284 // are complete.
285 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForRequest) {
286 host_resolver()->AddRule("*", "127.0.0.1");
287 ASSERT_TRUE(StartEmbeddedTestServer());
289 LazyBackgroundObserver page_complete;
290 ResultCatcher catcher;
291 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
292 AppendASCII("wait_for_request");
293 const Extension* extension = LoadExtension(extdir);
294 ASSERT_TRUE(extension);
295 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
297 // Lazy Background Page still exists, because the extension started a request.
298 extensions::ProcessManager* pm =
299 extensions::ProcessManager::Get(browser()->profile());
300 extensions::ExtensionHost* host =
301 pm->GetBackgroundHostForExtension(last_loaded_extension_id());
302 ASSERT_TRUE(host);
304 // Abort the request.
305 bool result = false;
306 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
307 host->render_view_host(), "abortRequest()", &result));
308 EXPECT_TRUE(result);
309 page_complete.Wait();
311 // Lazy Background Page has been shut down.
312 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
315 // Tests that the lazy background page stays alive while a NaCl module exists in
316 // its DOM.
317 #if !defined(DISABLE_NACL)
318 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, NaCl) {
320 base::FilePath extdir;
321 ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA, &extdir));
322 extdir = extdir.AppendASCII("ppapi/tests/extensions/load_unload/newlib");
323 LazyBackgroundObserver page_complete;
324 ASSERT_TRUE(LoadExtension(extdir));
325 page_complete.Wait();
328 // The NaCl module is loaded, and the Lazy Background Page stays alive.
330 ExtensionTestMessageListener nacl_module_loaded("nacl_module_loaded",
331 false);
332 BrowserActionTestUtil(browser()).Press(0);
333 nacl_module_loaded.WaitUntilSatisfied();
334 content::RunAllBlockingPoolTasksUntilIdle();
335 EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
338 // The NaCl module is detached from DOM, and the Lazy Background Page shuts
339 // down.
341 LazyBackgroundObserver page_complete;
342 BrowserActionTestUtil(browser()).Press(0);
343 page_complete.WaitUntilClosed();
346 // The Lazy Background Page has been shut down.
347 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
349 #endif
351 // Tests that the lazy background page stays alive until all visible views are
352 // closed.
353 // http://crbug.com/175778; test fails frequently on OS X
354 #if defined(OS_MACOSX)
355 #define MAYBE_WaitForNTP DISABLED_WaitForNTP
356 #else
357 #define MAYBE_WaitForNTP WaitForNTP
358 #endif
359 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, MAYBE_WaitForNTP) {
360 LazyBackgroundObserver lazybg;
361 ResultCatcher catcher;
362 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
363 AppendASCII("wait_for_ntp");
364 const Extension* extension = LoadExtension(extdir);
365 ASSERT_TRUE(extension);
366 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
368 // The extension should've opened a new tab to an extension page.
369 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
370 browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
372 // Lazy Background Page still exists, because the extension created a new tab
373 // to an extension page.
374 EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
376 // Navigate away from the NTP, which should close the event page.
377 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
378 lazybg.Wait();
380 // Lazy Background Page has been shut down.
381 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
384 // Tests that an incognito split mode extension gets 2 lazy background pages,
385 // and they each load and unload at the proper times.
386 // See crbug.com/248437
387 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, DISABLED_IncognitoSplitMode) {
388 // Open incognito window.
389 Browser* incognito_browser =
390 OpenURLOffTheRecord(browser()->profile(), GURL("about:blank"));
392 // Load the extension with incognito enabled.
394 LoadedIncognitoObserver loaded(browser()->profile());
395 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
396 AppendASCII("incognito_split");
397 ASSERT_TRUE(LoadExtensionIncognito(extdir));
398 loaded.Wait();
401 // Lazy Background Page doesn't exist yet.
402 extensions::ProcessManager* pm =
403 extensions::ProcessManager::Get(browser()->profile());
404 extensions::ProcessManager* pmi =
405 extensions::ProcessManager::Get(incognito_browser->profile());
406 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
407 EXPECT_FALSE(pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
409 // Trigger a browserAction event in the original profile and ensure only
410 // the original event page received it (since the event is scoped to the
411 // profile).
413 ExtensionTestMessageListener listener("waiting", false);
414 ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
416 LazyBackgroundObserver page_complete(browser()->profile());
417 BrowserActionTestUtil(browser()).Press(0);
418 page_complete.Wait();
420 // Only the original event page received the message.
421 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
422 EXPECT_FALSE(
423 pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
424 EXPECT_TRUE(listener.was_satisfied());
425 EXPECT_FALSE(listener_incognito.was_satisfied());
428 // Trigger a bookmark created event and ensure both pages receive it.
430 ExtensionTestMessageListener listener("waiting", false);
431 ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
433 LazyBackgroundObserver page_complete(browser()->profile()),
434 page2_complete(incognito_browser->profile());
435 BookmarkModel* bookmark_model =
436 BookmarkModelFactory::GetForProfile(browser()->profile());
437 bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
438 const BookmarkNode* parent = bookmark_model->bookmark_bar_node();
439 bookmark_model->AddURL(
440 parent, 0, base::ASCIIToUTF16("Title"), GURL("about:blank"));
441 page_complete.Wait();
442 page2_complete.Wait();
444 // Both pages received the message.
445 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
446 EXPECT_FALSE(
447 pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
448 EXPECT_TRUE(listener.was_satisfied());
449 EXPECT_TRUE(listener_incognito.was_satisfied());
453 // Tests that messages from the content script activate the lazy background
454 // page, and keep it alive until all channels are closed.
455 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Messaging) {
456 ASSERT_TRUE(StartEmbeddedTestServer());
457 ASSERT_TRUE(LoadExtensionAndWait("messaging"));
459 // Lazy Background Page doesn't exist yet.
460 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
461 EXPECT_EQ(1, browser()->tab_strip_model()->count());
463 // Navigate to a page that opens a message channel to the background page.
464 ResultCatcher catcher;
465 LazyBackgroundObserver lazybg;
466 ui_test_utils::NavigateToURL(
467 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
468 lazybg.WaitUntilLoaded();
470 // Background page got the content script's message and is still loaded
471 // until we close the channel.
472 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
473 EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
475 // Navigate away, closing the message channel and therefore the background
476 // page.
477 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
478 lazybg.WaitUntilClosed();
480 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
483 // Tests that a KeepaliveImpulse increments the keep alive count, but eventually
484 // times out and background page will still close.
485 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, ImpulseAddsCount) {
486 ASSERT_TRUE(StartEmbeddedTestServer());
487 const Extension* extension = LoadExtensionAndWait("messaging");
488 ASSERT_TRUE(extension);
490 // Lazy Background Page doesn't exist yet.
491 extensions::ProcessManager* pm =
492 extensions::ProcessManager::Get(browser()->profile());
493 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
494 EXPECT_EQ(1, browser()->tab_strip_model()->count());
496 // Navigate to a page that opens a message channel to the background page.
497 ResultCatcher catcher;
498 LazyBackgroundObserver lazybg;
499 ui_test_utils::NavigateToURL(
500 browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
501 lazybg.WaitUntilLoaded();
503 // Add an impulse and the keep alive count increases.
504 int previous_keep_alive_count = pm->GetLazyKeepaliveCount(extension);
505 pm->KeepaliveImpulse(extension);
506 EXPECT_EQ(previous_keep_alive_count + 1,
507 pm->GetLazyKeepaliveCount(extension));
509 // Navigate away, closing the message channel and therefore the background
510 // page after the impulse times out.
511 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
512 lazybg.WaitUntilClosed();
514 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
517 // Tests that the lazy background page receives the unload event when we
518 // close it, and that it can execute simple API calls that don't require an
519 // asynchronous response.
520 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnUnload) {
521 ASSERT_TRUE(LoadExtensionAndWait("on_unload"));
523 // Lazy Background Page has been shut down.
524 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
526 // The browser action has a new title.
527 BrowserActionTestUtil browser_action(browser());
528 ASSERT_EQ(1, browser_action.NumberOfBrowserActions());
529 EXPECT_EQ("Success", browser_action.GetTooltip(0));
532 // Tests that both a regular page and an event page will receive events when
533 // the event page is not loaded.
534 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, EventDispatchToTab) {
535 ResultCatcher catcher;
536 catcher.RestrictToBrowserContext(browser()->profile());
538 const extensions::Extension* extension =
539 LoadExtensionAndWait("event_dispatch_to_tab");
541 ExtensionTestMessageListener page_ready("ready", true);
542 GURL page_url = extension->GetResourceURL("page.html");
543 ui_test_utils::NavigateToURL(browser(), page_url);
544 EXPECT_TRUE(page_ready.WaitUntilSatisfied());
546 // After the event is sent below, wait for the event page to have received
547 // the event before proceeding with the test. This allows the regular page
548 // to test that the event page received the event, which makes the pass/fail
549 // logic simpler.
550 ExtensionTestMessageListener event_page_ready("ready", true);
552 // Send an event by making a bookmark.
553 BookmarkModel* bookmark_model =
554 BookmarkModelFactory::GetForProfile(browser()->profile());
555 bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
556 bookmarks::AddIfNotBookmarked(bookmark_model,
557 GURL("http://www.google.com"),
558 base::UTF8ToUTF16("Google"));
560 EXPECT_TRUE(event_page_ready.WaitUntilSatisfied());
562 page_ready.Reply("go");
564 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
567 // Tests that the lazy background page updates the chrome://extensions page
568 // when it is destroyed.
569 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, UpdateExtensionsPage) {
570 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIExtensionsURL));
572 ResultCatcher catcher;
573 base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
574 AppendASCII("wait_for_view");
575 const Extension* extension = LoadExtension(extdir);
576 ASSERT_TRUE(extension);
577 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
579 // The extension should've opened a new tab to an extension page.
580 EXPECT_EQ(extension->GetResourceURL("extension_page.html").spec(),
581 browser()->tab_strip_model()->GetActiveWebContents()->
582 GetURL().spec());
584 // Lazy Background Page still exists, because the extension created a new tab
585 // to an extension page.
586 EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
588 // Close the new tab.
589 LazyBackgroundObserver page_complete;
590 browser()->tab_strip_model()->CloseWebContentsAt(
591 browser()->tab_strip_model()->active_index(), TabStripModel::CLOSE_NONE);
592 page_complete.WaitUntilClosed();
594 // Lazy Background Page has been shut down.
595 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
597 // Verify that extensions page shows that the lazy background page is
598 // inactive.
599 content::RenderFrameHost* frame = content::FrameMatchingPredicate(
600 browser()->tab_strip_model()->GetActiveWebContents(),
601 base::Bind(&content::FrameHasSourceUrl,
602 GURL(chrome::kChromeUIExtensionsFrameURL)));
604 // Updating the extensions page is a process that has back-and-forth
605 // communication (i.e., backend tells extensions page something changed,
606 // extensions page requests updated data, backend responds with updated data,
607 // and so forth). This makes it difficult to know for sure when the page is
608 // done updating, so just try a few times. We limit the total number of
609 // attempts so that a) the test *fails* (instead of times out), and b) we
610 // know we're not making a ridiculous amount of trips to update the page.
611 bool is_inactive = false;
612 int kMaxTries = 10;
613 int num_tries = 0;
614 while (!is_inactive && num_tries++ < kMaxTries) {
615 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
616 frame,
617 "var ele = document.querySelectorAll('div.active-views');"
618 "window.domAutomationController.send("
619 " ele[0].innerHTML.search('(Inactive)') > 0);",
620 &is_inactive));
624 // Tests that the lazy background page will be unloaded if the onSuspend event
625 // handler calls an API function such as chrome.storage.local.set().
626 // See: http://crbug.com/296834
627 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnSuspendUseStorageApi) {
628 EXPECT_TRUE(LoadExtensionAndWait("on_suspend"));
631 // TODO: background page with timer.
632 // TODO: background page that interacts with popup.