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