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/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"
36 using extensions::Extension;
37 using extensions::ResultCatcher;
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 {
49 explicit LoadedIncognitoObserver(Profile* profile)
50 : profile_(profile), extension_registry_observer_(this) {
51 extension_registry_observer_.Add(
52 extensions::ExtensionRegistry::Get(profile_));
56 ASSERT_TRUE(original_complete_.get());
57 original_complete_->Wait();
58 incognito_complete_->Wait();
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()));
72 ScopedObserver<extensions::ExtensionRegistry,
73 extensions::ExtensionRegistryObserver>
74 extension_registry_observer_;
75 scoped_ptr<LazyBackgroundObserver> original_complete_;
76 scoped_ptr<LazyBackgroundObserver> incognito_complete_;
81 class LazyBackgroundPageApiTest : public ExtensionApiTest {
83 LazyBackgroundPageApiTest() {}
84 ~LazyBackgroundPageApiTest() override {}
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);
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);
101 page_complete.Wait();
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);
114 DISALLOW_COPY_AND_ASSIGN(LazyBackgroundPageApiTest);
117 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BrowserActionCreateTab) {
118 ASSERT_TRUE(LoadExtensionAndWait("browser_action_create_tab"));
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();
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();
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()->
138 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest,
139 BrowserActionCreateTabAfterCallback) {
140 ASSERT_TRUE(LoadExtensionAndWait("browser_action_with_callback"));
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();
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();
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());
157 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, BroadcastEvent) {
158 ASSERT_TRUE(StartEmbeddedTestServer());
160 const Extension* extension = LoadExtensionAndWait("broadcast_event");
161 ASSERT_TRUE(extension);
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();
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();
174 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
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());
183 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, Filters) {
184 ASSERT_TRUE(StartEmbeddedTestServer());
186 const Extension* extension = LoadExtensionAndWait("filters");
187 ASSERT_TRUE(extension);
189 // Lazy Background Page doesn't exist yet.
190 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
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();
199 // Tests that the lazy background page receives the onInstalled event and shuts
201 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, OnInstalled) {
202 ResultCatcher catcher;
203 ASSERT_TRUE(LoadExtensionAndWait("on_installed"));
204 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
206 // Lazy Background Page has been shut down.
207 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
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);
218 // The test extension opens a dialog on installation.
219 AppModalDialog* dialog = ui_test_utils::WaitForAppModalDialog();
222 // With the dialog open the background page is still alive.
223 EXPECT_TRUE(IsBackgroundPageAlive(extension->id()));
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));
233 // The background page closes now that the dialog is gone.
234 background_observer.WaitUntilClosed();
235 EXPECT_FALSE(IsBackgroundPageAlive(extension->id()));
238 // Tests that the lazy background page stays alive until all visible views are
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();
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()->
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()));
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();
263 // Lazy Background Page has been shut down.
264 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
267 // Tests that the lazy background page stays alive until all network requests
269 IN_PROC_BROWSER_TEST_F(LazyBackgroundPageApiTest, WaitForRequest) {
270 host_resolver()->AddRule("*", "127.0.0.1");
271 ASSERT_TRUE(StartEmbeddedTestServer());
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();
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());
288 // Abort the request.
290 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
291 host->render_view_host(), "abortRequest()", &result));
293 page_complete.Wait();
295 // Lazy Background Page has been shut down.
296 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
299 // Tests that the lazy background page stays alive until all visible views are
301 // http://crbug.com/175778; test fails frequently on OS X
302 #if defined(OS_MACOSX)
303 #define MAYBE_WaitForNTP DISABLED_WaitForNTP
305 #define MAYBE_WaitForNTP WaitForNTP
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();
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());
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()));
324 // Navigate away from the NTP, which should close the event page.
325 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
328 // Lazy Background Page has been shut down.
329 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
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"));
340 // Load the extension with incognito enabled.
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));
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()));
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
361 ExtensionTestMessageListener listener("waiting", false);
362 ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
364 LazyBackgroundObserver page_complete(browser()->profile());
365 BrowserActionTestUtil(browser()).Press(0);
366 page_complete.Wait();
368 // Only the original event page received the message.
369 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
371 pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
372 EXPECT_TRUE(listener.was_satisfied());
373 EXPECT_FALSE(listener_incognito.was_satisfied());
376 // Trigger a bookmark created event and ensure both pages receive it.
378 ExtensionTestMessageListener listener("waiting", false);
379 ExtensionTestMessageListener listener_incognito("waiting_incognito", false);
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();
392 // Both pages received the message.
393 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
395 pmi->GetBackgroundHostForExtension(last_loaded_extension_id()));
396 EXPECT_TRUE(listener.was_satisfied());
397 EXPECT_TRUE(listener_incognito.was_satisfied());
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"));
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());
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();
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()));
423 // Navigate away, closing the message channel and therefore the background
425 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
426 lazybg.WaitUntilClosed();
428 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
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);
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());
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();
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));
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();
462 EXPECT_FALSE(pm->GetBackgroundHostForExtension(last_loaded_extension_id()));
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"));
471 // Lazy Background Page has been shut down.
472 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
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));
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());
486 const extensions::Extension* extension =
487 LoadExtensionAndWait("event_dispatch_to_tab");
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());
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
498 ExtensionTestMessageListener event_page_ready("ready", true);
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"));
508 EXPECT_TRUE(event_page_ready.WaitUntilSatisfied());
510 page_ready.Reply("go");
512 EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
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));
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();
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()->
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()));
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();
542 // Lazy Background Page has been shut down.
543 EXPECT_FALSE(IsBackgroundPageAlive(last_loaded_extension_id()));
545 // Verify that extensions page shows that the lazy background page is
547 content::RenderFrameHost* frame = content::FrameMatchingPredicate(
548 browser()->tab_strip_model()->GetActiveWebContents(),
549 base::Bind(&content::FrameHasSourceUrl,
550 GURL(chrome::kChromeUIExtensionsFrameURL)));
552 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
554 "var ele = document.querySelectorAll('div.active-views');"
555 "window.domAutomationController.send("
556 " ele[0].innerHTML.search('(Inactive)') > 0);",
558 EXPECT_TRUE(is_inactive);
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"));
568 // TODO: background page with timer.
569 // TODO: background page that interacts with popup.