Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / lazy_background_page_apitest.cc
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/files/file_path.h"
6 #include "base/scoped_observer.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
9 #include "chrome/browser/extensions/browser_action_test_util.h"
10 #include "chrome/browser/extensions/extension_apitest.h"
11 #include "chrome/browser/extensions/lazy_background_page_test_util.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_window.h"
15 #include "chrome/browser/ui/location_bar/location_bar.h"
16 #include "chrome/browser/ui/tabs/tab_strip_model.h"
17 #include "chrome/common/url_constants.h"
18 #include "chrome/test/base/ui_test_utils.h"
19 #include "components/app_modal_dialogs/app_modal_dialog.h"
20 #include "components/bookmarks/browser/bookmark_model.h"
21 #include "components/bookmarks/browser/bookmark_utils.h"
22 #include "components/bookmarks/test/bookmark_test_helpers.h"
23 #include "content/public/browser/web_contents.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "extensions/browser/extension_host.h"
26 #include "extensions/browser/extension_registry.h"
27 #include "extensions/browser/extension_registry_observer.h"
28 #include "extensions/browser/process_manager.h"
29 #include "extensions/common/extension.h"
30 #include "extensions/test/extension_test_message_listener.h"
31 #include "extensions/test/result_catcher.h"
32 #include "net/dns/mock_host_resolver.h"
33 #include "net/test/embedded_test_server/embedded_test_server.h"
34 #include "url/gurl.h"
35
36 using extensions::Extension;
37 using extensions::ResultCatcher;
38
39 namespace {
40
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 extensions::ExtensionRegistryObserver {
48  public:
49   explicit LoadedIncognitoObserver(Profile* profile)
50       : profile_(profile), extension_registry_observer_(this) {
51     extension_registry_observer_.Add(
52         extensions::ExtensionRegistry::Get(profile_));
53   }
54
55   void Wait() {
56     ASSERT_TRUE(original_complete_.get());
57     original_complete_->Wait();
58     incognito_complete_->Wait();
59   }
60
61  private:
62   void OnExtensionUnloaded(
63       content::BrowserContext* browser_context,
64       const Extension* extension,
65       extensions::UnloadedExtensionInfo::Reason reason) override {
66     original_complete_.reset(new LazyBackgroundObserver(profile_));
67     incognito_complete_.reset(
68         new LazyBackgroundObserver(profile_->GetOffTheRecordProfile()));
69   }
70
71   Profile* profile_;
72   ScopedObserver<extensions::ExtensionRegistry,
73                  extensions::ExtensionRegistryObserver>
74       extension_registry_observer_;
75   scoped_ptr<LazyBackgroundObserver> original_complete_;
76   scoped_ptr<LazyBackgroundObserver> incognito_complete_;
77 };
78
79 }  // namespace
80
81 class LazyBackgroundPageApiTest : public ExtensionApiTest {
82  public:
83   LazyBackgroundPageApiTest() {}
84   ~LazyBackgroundPageApiTest() override {}
85
86   void SetUpOnMainThread() override {
87     ExtensionApiTest::SetUpOnMainThread();
88     // Set shorter delays to prevent test timeouts.
89     extensions::ProcessManager::SetEventPageIdleTimeForTesting(1);
90     extensions::ProcessManager::SetEventPageSuspendingTimeForTesting(1);
91   }
92
93   // Loads the extension, which temporarily starts the lazy background page
94   // to dispatch the onInstalled event. We wait until it shuts down again.
95   const Extension* LoadExtensionAndWait(const std::string& test_name) {
96     LazyBackgroundObserver page_complete;
97     base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
98         AppendASCII(test_name);
99     const Extension* extension = LoadExtension(extdir);
100     if (extension)
101       page_complete.Wait();
102     return extension;
103   }
104
105   // Returns true if the lazy background page for the extension with
106   // |extension_id| is still running.
107   bool IsBackgroundPageAlive(const std::string& extension_id) {
108     extensions::ProcessManager* pm =
109         extensions::ProcessManager::Get(browser()->profile());
110     return pm->GetBackgroundHostForExtension(extension_id);
111   }
112
113  private:
114   DISALLOW_COPY_AND_ASSIGN(LazyBackgroundPageApiTest);
115 };
116
117 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BrowserActionCreateTab) {
118   ASSERT_TRUE(LoadExtensionAndWait("browser_action_create_tab"));
119
120   // Lazy Background Page doesn't exist yet.
121   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
122   int num_tabs_before = browser()->tab_strip_model()->count();
123
124   // Observe background page being created and closed after
125   // the browser action is clicked.
126   LazyBackgroundObserver page_complete;
127   BrowserActionTestUtil(browser()).Press(0);
128   page_complete.Wait();
129
130   // Background page created a new tab before it closed.
131   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
132   EXPECT_EQ(num_tabs_before + 1, browser()->tab_strip_model()->count());
133   EXPECT_EQ(std::string(chrome::kChromeUIExtensionsURL),
134             browser()->tab_strip_model()->GetActiveWebContents()->
135                 GetURL().spec());
136 }
137
138 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest,
139                        BrowserActionCreateTabAfterCallback) {
140   ASSERT_TRUE(LoadExtensionAndWait("browser_action_with_callback"));
141
142   // Lazy Background Page doesn't exist yet.
143   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
144   int num_tabs_before = browser()->tab_strip_model()->count();
145
146   // Observe background page being created and closed after
147   // the browser action is clicked.
148   LazyBackgroundObserver page_complete;
149   BrowserActionTestUtil(browser()).Press(0);
150   page_complete.Wait();
151
152   // Background page is closed after creating a new tab.
153   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
154   EXPECT_EQ(num_tabs_before + 1, browser()->tab_strip_model()->count());
155 }
156
157 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BroadcastEvent) {
158   ASSERT_TRUE(StartEmbeddedTestServer());
159
160   const Extension* extension = LoadExtensionAndWait("broadcast_event");
161   ASSERT_TRUE(extension);
162
163   // Lazy Background Page doesn't exist yet.
164   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
165   int num_page_actions = browser()->window()->GetLocationBar()->
166       GetLocationBarForTesting()->PageActionVisibleCount();
167
168   // Open a tab to a URL that will trigger the page action to show.
169   LazyBackgroundObserver page_complete;
170   ui_test_utils::NavigateToURL(
171       browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
172   page_complete.Wait();
173
174   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
175
176   // Page action is shown.
177   WaitForPageActionVisibilityChangeTo(num_page_actions + 1);
178   EXPECT_EQ(num_page_actions + 1,
179             browser()->window()->GetLocationBar()->
180                 GetLocationBarForTesting()->PageActionVisibleCount());
181 }
182
183 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Filters) {
184   ASSERT_TRUE(StartEmbeddedTestServer());
185
186   const Extension* extension = LoadExtensionAndWait("filters");
187   ASSERT_TRUE(extension);
188
189   // Lazy Background Page doesn't exist yet.
190   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
191
192   // Open a tab to a URL that will fire a webNavigation event.
193   LazyBackgroundObserver page_complete;
194   ui_test_utils::NavigateToURL(
195       browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
196   page_complete.Wait();
197 }
198
199 // Tests that the lazy background page receives the onInstalled event and shuts
200 // down.
201 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnInstalled) {
202   ResultCatcher catcher;
203   ASSERT_TRUE(LoadExtensionAndWait("on_installed"));
204   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
205
206   // Lazy Background Page has been shut down.
207   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
208 }
209
210 // Tests that a JavaScript alert keeps the lazy background page alive.
211 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForDialog) {
212   LazyBackgroundObserver background_observer;
213   base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
214       AppendASCII("wait_for_dialog");
215   const Extension* extension = LoadExtension(extdir);
216   ASSERT_TRUE(extension);
217
218   // The test extension opens a dialog on installation.
219   AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
220   ASSERT_TRUE(dialog);
221
222   // With the dialog open the background page is still alive.
223   EXPECT_TRUE(IsBackgroundPageAlive(extension->id()));
224
225   // Close the dialog. The keep alive count is decremented.
226   extensions::ProcessManager* pm =
227       extensions::ProcessManager::Get(browser()->profile());
228   int previous_keep_alive_count = pm->GetLazyKeepaliveCount(extension);
229   dialog->CloseModalDialog();
230   EXPECT_EQ(previous_keep_alive_count - 1,
231             pm->GetLazyKeepaliveCount(extension));
232
233   // The background page closes now that the dialog is gone.
234   background_observer.WaitUntilClosed();
235   EXPECT_FALSE(IsBackgroundPageAlive(extension->id()));
236 }
237
238 // Tests that the lazy background page stays alive until all visible views are
239 // closed.
240 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForView) {
241   LazyBackgroundObserver page_complete;
242   ResultCatcher catcher;
243   base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
244       AppendASCII("wait_for_view");
245   const Extension* extension = LoadExtension(extdir);
246   ASSERT_TRUE(extension);
247   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
248
249   // The extension should've opened a new tab to an extension page.
250   EXPECT_EQ(extension->GetResourceURL("extension_page.html").spec(),
251             browser()->tab_strip_model()->GetActiveWebContents()->
252                 GetURL().spec());
253
254   // Lazy Background Page still exists, because the extension created a new tab
255   // to an extension page.
256   EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
257
258   // Close the new tab.
259   browser()->tab_strip_model()->CloseWebContentsAt(
260       browser()->tab_strip_model()->active_index(), TabStripModel::CLOSE_NONE);
261   page_complete.Wait();
262
263   // Lazy Background Page has been shut down.
264   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
265 }
266
267 // Tests that the lazy background page stays alive until all network requests
268 // are complete.
269 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForRequest) {
270   host_resolver()->AddRule("*", "127.0.0.1");
271   ASSERT_TRUE(StartEmbeddedTestServer());
272
273   LazyBackgroundObserver page_complete;
274   ResultCatcher catcher;
275   base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
276       AppendASCII("wait_for_request");
277   const Extension* extension = LoadExtension(extdir);
278   ASSERT_TRUE(extension);
279   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
280
281   // Lazy Background Page still exists, because the extension started a request.
282   extensions::ProcessManager* pm =
283       extensions::ProcessManager::Get(browser()->profile());
284   extensions::ExtensionHost* host =
285       pm->GetBackgroundHostForExtension(last_loaded_extension_id());
286   ASSERT_TRUE(host);
287
288   // Abort the request.
289   bool result = false;
290   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
291       host->render_view_host(), "abortRequest()", &result));
292   EXPECT_TRUE(result);
293   page_complete.Wait();
294
295   // Lazy Background Page has been shut down.
296   EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
297 }
298
299 // Tests that the lazy background page stays alive until all visible views are
300 // closed.
301 // http://crbug.com/175778; test fails frequently on OS X
302 #if defined(OS_MACOSX)
303 #define MAYBE_WaitForNTP DISABLED_WaitForNTP
304 #else
305 #define MAYBE_WaitForNTP WaitForNTP
306 #endif
307 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, MAYBE_WaitForNTP) {
308   LazyBackgroundObserver lazybg;
309   ResultCatcher catcher;
310   base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
311       AppendASCII("wait_for_ntp");
312   const Extension* extension = LoadExtension(extdir);
313   ASSERT_TRUE(extension);
314   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
315
316   // The extension should've opened a new tab to an extension page.
317   EXPECT_EQ(GURL(chrome::kChromeUINewTabURL),
318             browser()->tab_strip_model()->GetActiveWebContents()->GetURL());
319
320   // Lazy Background Page still exists, because the extension created a new tab
321   // to an extension page.
322   EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
323
324   // Navigate away from the NTP, which should close the event page.
325   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
326   lazybg.Wait();
327
328   // Lazy Background Page has been shut down.
329   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
330 }
331
332 // Tests that an incognito split mode extension gets 2 lazy background pages,
333 // and they each load and unload at the proper times.
334 // See crbug.com/248437
335 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, DISABLED_IncognitoSplitMode) {
336   // Open incognito window.
337   Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord(
338       browser()->profile(), GURL("about:blank"));
339
340   // Load the extension with incognito enabled.
341   {
342     LoadedIncognitoObserver loaded(browser()->profile());
343     base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
344         AppendASCII("incognito_split");
345     ASSERT_TRUE(LoadExtensionIncognito(extdir));
346     loaded.Wait();
347   }
348
349   // Lazy Background Page doesn't exist yet.
350   extensions::ProcessManager* pm =
351       extensions::ProcessManager::Get(browser()->profile());
352   extensions::ProcessManager* pmi =
353       extensions::ProcessManager::Get(incognito_browser->profile());
354   EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
355   EXPECT_FALSE(pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
356
357   // Trigger a browserAction event in the original profile and ensure only
358   // the original event page received it (since the event is scoped to the
359   // profile).
360   {
361     ExtensionTestMessageListener listener("waiting", false);
362     ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
363
364     LazyBackgroundObserver page_complete(browser()->profile());
365     BrowserActionTestUtil(browser()).Press(0);
366     page_complete.Wait();
367
368     // Only the original event page received the message.
369     EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
370     EXPECT_FALSE(
371         pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
372     EXPECT_TRUE(listener.was_satisfied());
373     EXPECT_FALSE(listener_incognito.was_satisfied());
374   }
375
376   // Trigger a bookmark created event and ensure both pages receive it.
377   {
378     ExtensionTestMessageListener listener("waiting", false);
379     ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
380
381     LazyBackgroundObserver page_complete(browser()->profile()),
382                            page2_complete(incognito_browser->profile());
383     BookmarkModel* bookmark_model =
384         BookmarkModelFactory::GetForProfile(browser()->profile());
385     bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
386     const BookmarkNode* parent = bookmark_model->bookmark_bar_node();
387     bookmark_model->AddURL(
388         parent, 0, base::ASCIIToUTF16("Title"), GURL("about:blank"));
389     page_complete.Wait();
390     page2_complete.Wait();
391
392     // Both pages received the message.
393     EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
394     EXPECT_FALSE(
395         pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
396     EXPECT_TRUE(listener.was_satisfied());
397     EXPECT_TRUE(listener_incognito.was_satisfied());
398   }
399 }
400
401 // Tests that messages from the content script activate the lazy background
402 // page, and keep it alive until all channels are closed.
403 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Messaging) {
404   ASSERT_TRUE(StartEmbeddedTestServer());
405   ASSERT_TRUE(LoadExtensionAndWait("messaging"));
406
407   // Lazy Background Page doesn't exist yet.
408   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
409   EXPECT_EQ(1, browser()->tab_strip_model()->count());
410
411   // Navigate to a page that opens a message channel to the background page.
412   ResultCatcher catcher;
413   LazyBackgroundObserver lazybg;
414   ui_test_utils::NavigateToURL(
415       browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
416   lazybg.WaitUntilLoaded();
417
418   // Background page got the content script's message and is still loaded
419   // until we close the channel.
420   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
421   EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
422
423   // Navigate away, closing the message channel and therefore the background
424   // page.
425   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
426   lazybg.WaitUntilClosed();
427
428   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
429 }
430
431 // Tests that a KeepaliveImpulse increments the keep alive count, but eventually
432 // times out and background page will still close.
433 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, ImpulseAddsCount) {
434   ASSERT_TRUE(StartEmbeddedTestServer());
435   const Extension* extension = LoadExtensionAndWait("messaging");
436   ASSERT_TRUE(extension);
437
438   // Lazy Background Page doesn't exist yet.
439   extensions::ProcessManager* pm =
440       extensions::ProcessManager::Get(browser()->profile());
441   EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
442   EXPECT_EQ(1, browser()->tab_strip_model()->count());
443
444   // Navigate to a page that opens a message channel to the background page.
445   ResultCatcher catcher;
446   LazyBackgroundObserver lazybg;
447   ui_test_utils::NavigateToURL(
448       browser(), embedded_test_server()->GetURL("/extensions/test_file.html"));
449   lazybg.WaitUntilLoaded();
450
451   // Add an impulse and the keep alive count increases.
452   int previous_keep_alive_count = pm->GetLazyKeepaliveCount(extension);
453   pm->KeepaliveImpulse(extension);
454   EXPECT_EQ(previous_keep_alive_count + 1,
455             pm->GetLazyKeepaliveCount(extension));
456
457   // Navigate away, closing the message channel and therefore the background
458   // page after the impulse times out.
459   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
460   lazybg.WaitUntilClosed();
461
462   EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
463 }
464
465 // Tests that the lazy background page receives the unload event when we
466 // close it, and that it can execute simple API calls that don't require an
467 // asynchronous response.
468 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnUnload) {
469   ASSERT_TRUE(LoadExtensionAndWait("on_unload"));
470
471   // Lazy Background Page has been shut down.
472   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
473
474   // The browser action has a new title.
475   BrowserActionTestUtil browser_action(browser());
476   ASSERT_EQ(1, browser_action.NumberOfBrowserActions());
477   EXPECT_EQ("Success", browser_action.GetTooltip(0));
478 }
479
480 // Tests that both a regular page and an event page will receive events when
481 // the event page is not loaded.
482 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, EventDispatchToTab) {
483   ResultCatcher catcher;
484   catcher.RestrictToBrowserContext(browser()->profile());
485
486   const extensions::Extension* extension =
487       LoadExtensionAndWait("event_dispatch_to_tab");
488
489   ExtensionTestMessageListener page_ready("ready", true);
490   GURL page_url = extension->GetResourceURL("page.html");
491   ui_test_utils::NavigateToURL(browser(), page_url);
492   EXPECT_TRUE(page_ready.WaitUntilSatisfied());
493
494   // After the event is sent below, wait for the event page to have received
495   // the event before proceeding with the test.  This allows the regular page
496   // to test that the event page received the event, which makes the pass/fail
497   // logic simpler.
498   ExtensionTestMessageListener event_page_ready("ready", true);
499
500   // Send an event by making a bookmark.
501   BookmarkModel* bookmark_model =
502       BookmarkModelFactory::GetForProfile(browser()->profile());
503   bookmarks::test::WaitForBookmarkModelToLoad(bookmark_model);
504   bookmarks::AddIfNotBookmarked(bookmark_model,
505                                 GURL("http://www.google.com"),
506                                 base::UTF8ToUTF16("Google"));
507
508   EXPECT_TRUE(event_page_ready.WaitUntilSatisfied());
509
510   page_ready.Reply("go");
511
512   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
513 }
514
515 // Tests that the lazy background page updates the chrome://extensions page
516 // when it is destroyed.
517 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, UpdateExtensionsPage) {
518   ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIExtensionsURL));
519
520   ResultCatcher catcher;
521   base::FilePath extdir = test_data_dir_.AppendASCII("lazy_background_page").
522       AppendASCII("wait_for_view");
523   const Extension* extension = LoadExtension(extdir);
524   ASSERT_TRUE(extension);
525   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
526
527   // The extension should've opened a new tab to an extension page.
528   EXPECT_EQ(extension->GetResourceURL("extension_page.html").spec(),
529             browser()->tab_strip_model()->GetActiveWebContents()->
530                 GetURL().spec());
531
532   // Lazy Background Page still exists, because the extension created a new tab
533   // to an extension page.
534   EXPECT_TRUE(IsBackgroundPageAlive(last_loaded_extension_id()));
535
536   // Close the new tab.
537   LazyBackgroundObserver page_complete;
538   browser()->tab_strip_model()->CloseWebContentsAt(
539       browser()->tab_strip_model()->active_index(), TabStripModel::CLOSE_NONE);
540   page_complete.WaitUntilClosed();
541
542   // Lazy Background Page has been shut down.
543   EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
544
545   // Verify that extensions page shows that the lazy background page is
546   // inactive.
547   content::RenderFrameHost* frame = content::FrameMatchingPredicate(
548       browser()->tab_strip_model()->GetActiveWebContents(),
549       base::Bind(&content::FrameHasSourceUrl,
550                  GURL(chrome::kChromeUIExtensionsFrameURL)));
551   bool is_inactive;
552   EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
553       frame,
554       "var ele = document.querySelectorAll('div.active-views');"
555       "window.domAutomationController.send("
556       "    ele[0].innerHTML.search('(Inactive)') > 0);",
557       &is_inactive));
558   EXPECT_TRUE(is_inactive);
559 }
560
561 // Tests that the lazy background page will be unloaded if the onSuspend event
562 // handler calls an API function such as chrome.storage.local.set().
563 // See: http://crbug.com/296834
564 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnSuspendUseStorageApi) {
565   EXPECT_TRUE(LoadExtensionAndWait("on_suspend"));
566 }
567
568 // TODO: background page with timer.
569 // TODO: background page that interacts with popup.