Home | History | Annotate | Download | only in extensions
      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/command_line.h"
      6 #include "base/memory/scoped_vector.h"
      7 #include "base/path_service.h"
      8 #include "base/strings/stringprintf.h"
      9 #include "chrome/browser/extensions/extension_apitest.h"
     10 #include "chrome/browser/profiles/profile.h"
     11 #include "chrome/browser/ui/browser.h"
     12 #include "chrome/browser/ui/browser_finder.h"
     13 #include "chrome/browser/ui/browser_iterator.h"
     14 #include "chrome/browser/ui/panels/panel_manager.h"
     15 #include "chrome/browser/ui/tabs/tab_strip_model.h"
     16 #include "chrome/common/chrome_paths.h"
     17 #include "chrome/common/chrome_switches.h"
     18 #include "chrome/test/base/test_switches.h"
     19 #include "chrome/test/base/ui_test_utils.h"
     20 #include "content/public/browser/render_process_host.h"
     21 #include "content/public/browser/web_contents.h"
     22 #include "content/public/common/result_codes.h"
     23 #include "content/public/common/url_constants.h"
     24 #include "content/public/test/browser_test_utils.h"
     25 #include "extensions/browser/extension_host.h"
     26 #include "extensions/browser/extension_system.h"
     27 #include "extensions/browser/process_manager.h"
     28 #include "extensions/common/constants.h"
     29 #include "extensions/common/extension.h"
     30 #include "extensions/common/switches.h"
     31 #include "extensions/test/extension_test_message_listener.h"
     32 #include "extensions/test/result_catcher.h"
     33 #include "net/dns/mock_host_resolver.h"
     34 #include "net/test/embedded_test_server/embedded_test_server.h"
     35 #include "testing/gtest/include/gtest/gtest.h"
     36 
     37 #if defined(USE_ASH)
     38 #include "extensions/browser/app_window/app_window_registry.h"
     39 #endif
     40 
     41 #if defined(USE_ASH) && defined(OS_CHROMEOS)
     42 // TODO(stevenjb): Figure out the correct behavior for Ash + Win
     43 #define USE_ASH_PANELS
     44 #endif
     45 
     46 using content::OpenURLParams;
     47 using content::Referrer;
     48 using content::WebContents;
     49 
     50 // Disabled, http://crbug.com/64899.
     51 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_WindowOpen) {
     52   CommandLine::ForCurrentProcess()->AppendSwitch(
     53       extensions::switches::kEnableExperimentalExtensionApis);
     54 
     55   extensions::ResultCatcher catcher;
     56   ASSERT_TRUE(LoadExtensionIncognito(test_data_dir_
     57       .AppendASCII("window_open").AppendASCII("spanning")));
     58   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
     59 }
     60 
     61 int GetPanelCount(Browser* browser) {
     62 #if defined(USE_ASH_PANELS)
     63   return static_cast<int>(extensions::AppWindowRegistry::Get(
     64       browser->profile())->app_windows().size());
     65 #else
     66   return PanelManager::GetInstance()->num_panels();
     67 #endif
     68 }
     69 
     70 bool WaitForTabsAndPopups(Browser* browser,
     71                           int num_tabs,
     72                           int num_popups,
     73                           int num_panels) {
     74   SCOPED_TRACE(
     75       base::StringPrintf("WaitForTabsAndPopups tabs:%d, popups:%d, panels:%d",
     76                          num_tabs, num_popups, num_panels));
     77   // We start with one tab and one browser already open.
     78   ++num_tabs;
     79   size_t num_browsers = static_cast<size_t>(num_popups) + 1;
     80 
     81   const base::TimeDelta kWaitTime = base::TimeDelta::FromSeconds(10);
     82   base::TimeTicks end_time = base::TimeTicks::Now() + kWaitTime;
     83   while (base::TimeTicks::Now() < end_time) {
     84     if (chrome::GetBrowserCount(browser->profile(),
     85                                 browser->host_desktop_type()) == num_browsers &&
     86         browser->tab_strip_model()->count() == num_tabs &&
     87         GetPanelCount(browser) == num_panels)
     88       break;
     89 
     90     content::RunAllPendingInMessageLoop();
     91   }
     92 
     93   EXPECT_EQ(num_browsers,
     94             chrome::GetBrowserCount(browser->profile(),
     95                                     browser->host_desktop_type()));
     96   EXPECT_EQ(num_tabs, browser->tab_strip_model()->count());
     97   EXPECT_EQ(num_panels, GetPanelCount(browser));
     98 
     99   int num_popups_seen = 0;
    100   for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
    101     if (*iter == browser)
    102       continue;
    103 
    104     EXPECT_TRUE((*iter)->is_type_popup());
    105     ++num_popups_seen;
    106   }
    107   EXPECT_EQ(num_popups, num_popups_seen);
    108 
    109   return ((num_browsers ==
    110                chrome::GetBrowserCount(browser->profile(),
    111                                        browser->host_desktop_type())) &&
    112           (num_tabs == browser->tab_strip_model()->count()) &&
    113           (num_panels == GetPanelCount(browser)) &&
    114           (num_popups == num_popups_seen));
    115 }
    116 
    117 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, BrowserIsApp) {
    118   host_resolver()->AddRule("a.com", "127.0.0.1");
    119   ASSERT_TRUE(StartEmbeddedTestServer());
    120   ASSERT_TRUE(LoadExtension(
    121       test_data_dir_.AppendASCII("window_open").AppendASCII("browser_is_app")));
    122 
    123   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 2, 0));
    124 
    125   for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
    126     if (*iter == browser())
    127       ASSERT_FALSE(iter->is_app());
    128     else
    129       ASSERT_TRUE(iter->is_app());
    130   }
    131 }
    132 
    133 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WindowOpenPopupDefault) {
    134   ASSERT_TRUE(StartEmbeddedTestServer());
    135   ASSERT_TRUE(LoadExtension(
    136       test_data_dir_.AppendASCII("window_open").AppendASCII("popup")));
    137 
    138   const int num_tabs = 1;
    139   const int num_popups = 0;
    140   EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups, 0));
    141 }
    142 
    143 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WindowOpenPopupIframe) {
    144   ASSERT_TRUE(StartEmbeddedTestServer());
    145   base::FilePath test_data_dir;
    146   PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
    147   embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
    148   ASSERT_TRUE(LoadExtension(
    149       test_data_dir_.AppendASCII("window_open").AppendASCII("popup_iframe")));
    150 
    151   const int num_tabs = 1;
    152   const int num_popups = 0;
    153   EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups, 0));
    154 }
    155 
    156 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WindowOpenPopupLarge) {
    157   ASSERT_TRUE(StartEmbeddedTestServer());
    158   ASSERT_TRUE(LoadExtension(
    159       test_data_dir_.AppendASCII("window_open").AppendASCII("popup_large")));
    160 
    161   // On other systems this should open a new popup window.
    162   const int num_tabs = 0;
    163   const int num_popups = 1;
    164   EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups, 0));
    165 }
    166 
    167 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WindowOpenPopupSmall) {
    168   ASSERT_TRUE(StartEmbeddedTestServer());
    169   ASSERT_TRUE(LoadExtension(
    170       test_data_dir_.AppendASCII("window_open").AppendASCII("popup_small")));
    171 
    172   // On ChromeOS this should open a new panel (acts like a new popup window).
    173   // On other systems this should open a new popup window.
    174   const int num_tabs = 0;
    175   const int num_popups = 1;
    176   EXPECT_TRUE(WaitForTabsAndPopups(browser(), num_tabs, num_popups, 0));
    177 }
    178 
    179 // Disabled on Windows. Often times out or fails: crbug.com/177530
    180 #if defined(OS_WIN)
    181 #define MAYBE_PopupBlockingExtension DISABLED_PopupBlockingExtension
    182 #else
    183 #define MAYBE_PopupBlockingExtension PopupBlockingExtension
    184 #endif
    185 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_PopupBlockingExtension) {
    186   host_resolver()->AddRule("*", "127.0.0.1");
    187   ASSERT_TRUE(StartEmbeddedTestServer());
    188 
    189   ASSERT_TRUE(LoadExtension(
    190       test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
    191       .AppendASCII("extension")));
    192 
    193   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 5, 3, 0));
    194 }
    195 
    196 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, PopupBlockingHostedApp) {
    197   host_resolver()->AddRule("*", "127.0.0.1");
    198   ASSERT_TRUE(test_server()->Start());
    199 
    200   ASSERT_TRUE(LoadExtension(
    201       test_data_dir_.AppendASCII("window_open").AppendASCII("popup_blocking")
    202       .AppendASCII("hosted_app")));
    203 
    204   // The app being tested owns the domain a.com .  The test URLs we navigate
    205   // to below must be within that domain, so that they fall within the app's
    206   // web extent.
    207   GURL::Replacements replace_host;
    208   std::string a_dot_com = "a.com";
    209   replace_host.SetHostStr(a_dot_com);
    210 
    211   const std::string popup_app_contents_path(
    212     "files/extensions/api_test/window_open/popup_blocking/hosted_app/");
    213 
    214   GURL open_tab =
    215       test_server()->GetURL(popup_app_contents_path + "open_tab.html")
    216           .ReplaceComponents(replace_host);
    217   GURL open_popup =
    218       test_server()->GetURL(popup_app_contents_path + "open_popup.html")
    219           .ReplaceComponents(replace_host);
    220 
    221   browser()->OpenURL(OpenURLParams(
    222       open_tab, Referrer(), NEW_FOREGROUND_TAB, ui::PAGE_TRANSITION_TYPED,
    223       false));
    224   browser()->OpenURL(OpenURLParams(
    225       open_popup, Referrer(), NEW_FOREGROUND_TAB,
    226       ui::PAGE_TRANSITION_TYPED, false));
    227 
    228   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 3, 1, 0));
    229 }
    230 
    231 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, WindowArgumentsOverflow) {
    232   ASSERT_TRUE(RunExtensionTest("window_open/argument_overflow")) << message_;
    233 }
    234 
    235 class WindowOpenPanelDisabledTest : public ExtensionApiTest {
    236   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    237     ExtensionApiTest::SetUpCommandLine(command_line);
    238     // TODO(jennb): Re-enable when panels are enabled by default.
    239     // command_line->AppendSwitch(switches::kDisablePanels);
    240   }
    241 };
    242 
    243 IN_PROC_BROWSER_TEST_F(WindowOpenPanelDisabledTest,
    244                        DISABLED_WindowOpenPanelNotEnabled) {
    245   ASSERT_TRUE(RunExtensionTest("window_open/panel_not_enabled")) << message_;
    246 }
    247 
    248 class WindowOpenPanelTest : public ExtensionApiTest {
    249   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    250     ExtensionApiTest::SetUpCommandLine(command_line);
    251     command_line->AppendSwitch(switches::kEnablePanels);
    252   }
    253 };
    254 
    255 #if defined(USE_ASH_PANELS)
    256 // On Ash, this currently fails because we're currently opening new panel
    257 // windows as popup windows instead.
    258 #define MAYBE_WindowOpenPanel DISABLED_WindowOpenPanel
    259 #else
    260 #define MAYBE_WindowOpenPanel WindowOpenPanel
    261 #endif
    262 IN_PROC_BROWSER_TEST_F(WindowOpenPanelTest, MAYBE_WindowOpenPanel) {
    263   ASSERT_TRUE(RunExtensionTest("window_open/panel")) << message_;
    264 }
    265 
    266 #if defined(USE_ASH_PANELS) || defined(OS_LINUX)
    267 // On Ash, this currently fails because we're currently opening new panel
    268 // windows as popup windows instead.
    269 // We're also failing on Linux-aura due to the panel is not opened in the
    270 // right origin.
    271 #define MAYBE_WindowOpenPanelDetached DISABLED_WindowOpenPanelDetached
    272 #else
    273 #define MAYBE_WindowOpenPanelDetached WindowOpenPanelDetached
    274 #endif
    275 IN_PROC_BROWSER_TEST_F(WindowOpenPanelTest, MAYBE_WindowOpenPanelDetached) {
    276   ASSERT_TRUE(RunExtensionTest("window_open/panel_detached")) << message_;
    277 }
    278 
    279 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
    280 // TODO(erg): Bring up ash http://crbug.com/300084
    281 #define MAYBE_CloseNonExtensionPanelsOnUninstall \
    282   DISABLED_CloseNonExtensionPanelsOnUninstall
    283 #else
    284 #define MAYBE_CloseNonExtensionPanelsOnUninstall \
    285   CloseNonExtensionPanelsOnUninstall
    286 #endif
    287 IN_PROC_BROWSER_TEST_F(WindowOpenPanelTest,
    288                        MAYBE_CloseNonExtensionPanelsOnUninstall) {
    289 #if defined(OS_WIN) && defined(USE_ASH)
    290   // Disable this test in Metro+Ash for now (http://crbug.com/262796).
    291   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests))
    292     return;
    293 #endif
    294 
    295 #if defined(USE_ASH_PANELS)
    296   // On Ash, new panel windows open as popup windows instead.
    297   int num_popups, num_panels;
    298   if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels)) {
    299     num_popups = 2;
    300     num_panels = 2;
    301   } else {
    302     num_popups = 4;
    303     num_panels = 0;
    304   }
    305 #else
    306   int num_popups = 2;
    307   int num_panels = 2;
    308 #endif
    309   ASSERT_TRUE(StartEmbeddedTestServer());
    310 
    311   // Setup listeners to wait on strings we expect the extension pages to send.
    312   std::vector<std::string> test_strings;
    313   test_strings.push_back("content_tab");
    314   if (num_panels)
    315     test_strings.push_back("content_panel");
    316   test_strings.push_back("content_popup");
    317 
    318   ScopedVector<ExtensionTestMessageListener> listeners;
    319   for (size_t i = 0; i < test_strings.size(); ++i) {
    320     listeners.push_back(
    321         new ExtensionTestMessageListener(test_strings[i], false));
    322   }
    323 
    324   const extensions::Extension* extension = LoadExtension(
    325       test_data_dir_.AppendASCII("window_open").AppendASCII(
    326           "close_panels_on_uninstall"));
    327   ASSERT_TRUE(extension);
    328 
    329   // Two tabs. One in extension domain and one in non-extension domain.
    330   // Two popups - one in extension domain and one in non-extension domain.
    331   // Two panels - one in extension domain and one in non-extension domain.
    332   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 2, num_popups, num_panels));
    333 
    334   // Wait on test messages to make sure the pages loaded.
    335   for (size_t i = 0; i < listeners.size(); ++i)
    336     ASSERT_TRUE(listeners[i]->WaitUntilSatisfied());
    337 
    338   UninstallExtension(extension->id());
    339 
    340   // Wait for the tabs and popups in non-extension domain to stay open.
    341   // Expect everything else, including panels, to close.
    342   num_popups -= 1;
    343 #if defined(USE_ASH_PANELS)
    344   if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePanels)) {
    345     // On Ash, new panel windows open as popup windows instead, so there are 2
    346     // extension domain popups that will close (instead of 1 popup on non-Ash).
    347     num_popups -= 1;
    348   }
    349 #endif
    350 #if defined(USE_ASH)
    351 #if !defined(OS_WIN)
    352   // On linux ash we close all popup applications when closing its extension.
    353   num_popups = 0;
    354 #endif
    355 #endif
    356   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 1, num_popups, 0));
    357 }
    358 
    359 // This test isn't applicable on Chrome OS, which automatically reloads crashed
    360 // pages.
    361 #if !defined(OS_CHROMEOS)
    362 IN_PROC_BROWSER_TEST_F(WindowOpenPanelTest, ClosePanelsOnExtensionCrash) {
    363 #if defined(USE_ASH_PANELS)
    364   // On Ash, new panel windows open as popup windows instead.
    365   int num_popups = 4;
    366   int num_panels = 0;
    367 #else
    368   int num_popups = 2;
    369   int num_panels = 2;
    370 #endif
    371   ASSERT_TRUE(StartEmbeddedTestServer());
    372 
    373   // Setup listeners to wait on strings we expect the extension pages to send.
    374   std::vector<std::string> test_strings;
    375   test_strings.push_back("content_tab");
    376   if (num_panels)
    377     test_strings.push_back("content_panel");
    378   test_strings.push_back("content_popup");
    379 
    380   ScopedVector<ExtensionTestMessageListener> listeners;
    381   for (size_t i = 0; i < test_strings.size(); ++i) {
    382     listeners.push_back(
    383         new ExtensionTestMessageListener(test_strings[i], false));
    384   }
    385 
    386   const extensions::Extension* extension = LoadExtension(
    387       test_data_dir_.AppendASCII("window_open").AppendASCII(
    388           "close_panels_on_uninstall"));
    389   ASSERT_TRUE(extension);
    390 
    391   // Two tabs. One in extension domain and one in non-extension domain.
    392   // Two popups - one in extension domain and one in non-extension domain.
    393   // Two panels - one in extension domain and one in non-extension domain.
    394   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 2, num_popups, num_panels));
    395 
    396   // Wait on test messages to make sure the pages loaded.
    397   for (size_t i = 0; i < listeners.size(); ++i)
    398     ASSERT_TRUE(listeners[i]->WaitUntilSatisfied());
    399 
    400   // Crash the extension.
    401   extensions::ExtensionHost* extension_host =
    402       extensions::ExtensionSystem::Get(browser()->profile())->
    403           process_manager()->GetBackgroundHostForExtension(extension->id());
    404   ASSERT_TRUE(extension_host);
    405   base::KillProcess(extension_host->render_process_host()->GetHandle(),
    406                     content::RESULT_CODE_KILLED, false);
    407   WaitForExtensionCrash(extension->id());
    408 
    409   // Only expect panels to close. The rest stay open to show a sad-tab.
    410   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 2, num_popups, 0));
    411 }
    412 #endif  // !defined(OS_CHROMEOS)
    413 
    414 #if defined(USE_ASH_PANELS)
    415 // This test is not applicable on Ash. The modified window.open behavior only
    416 // applies to non-Ash panel windows.
    417 #define MAYBE_WindowOpenFromPanel DISABLED_WindowOpenFromPanel
    418 #else
    419 #define MAYBE_WindowOpenFromPanel WindowOpenFromPanel
    420 #endif
    421 IN_PROC_BROWSER_TEST_F(WindowOpenPanelTest, MAYBE_WindowOpenFromPanel) {
    422   ASSERT_TRUE(StartEmbeddedTestServer());
    423 
    424   // Load the extension that will open a panel which then calls window.open.
    425   ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("window_open").
    426                             AppendASCII("panel_window_open")));
    427 
    428   // Expect one panel (opened by extension) and one tab (from the panel calling
    429   // window.open). Panels modify the WindowOpenDisposition in window.open
    430   // to always open in a tab.
    431   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 1, 0, 1));
    432 }
    433 
    434 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_WindowOpener) {
    435   ASSERT_TRUE(RunExtensionTest("window_open/opener")) << message_;
    436 }
    437 
    438 #if defined(OS_MACOSX)
    439 // Extension popup windows are incorrectly sized on OSX, crbug.com/225601
    440 #define MAYBE_WindowOpenSized DISABLED_WindowOpenSized
    441 #else
    442 #define MAYBE_WindowOpenSized WindowOpenSized
    443 #endif
    444 // Ensure that the width and height properties of a window opened with
    445 // chrome.windows.create match the creation parameters. See crbug.com/173831.
    446 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, MAYBE_WindowOpenSized) {
    447   ASSERT_TRUE(RunExtensionTest("window_open/window_size")) << message_;
    448   EXPECT_TRUE(WaitForTabsAndPopups(browser(), 0, 1, 0));
    449 }
    450 
    451 // Tests that an extension page can call window.open to an extension URL and
    452 // the new window has extension privileges.
    453 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenExtension) {
    454   ASSERT_TRUE(LoadExtension(
    455       test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));
    456 
    457   GURL start_url(std::string(extensions::kExtensionScheme) +
    458                      url::kStandardSchemeSeparator +
    459                      last_loaded_extension_id() + "/test.html");
    460   ui_test_utils::NavigateToURL(browser(), start_url);
    461   WebContents* newtab = NULL;
    462   ASSERT_NO_FATAL_FAILURE(
    463       OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
    464       start_url.Resolve("newtab.html"), true, &newtab));
    465 
    466   bool result = false;
    467   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
    468                                                    &result));
    469   EXPECT_TRUE(result);
    470 }
    471 
    472 // Tests that if an extension page calls window.open to an invalid extension
    473 // URL, the browser doesn't crash.
    474 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenInvalidExtension) {
    475   ASSERT_TRUE(LoadExtension(
    476       test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));
    477 
    478   GURL start_url(std::string(extensions::kExtensionScheme) +
    479                      url::kStandardSchemeSeparator +
    480                      last_loaded_extension_id() + "/test.html");
    481   ui_test_utils::NavigateToURL(browser(), start_url);
    482   ASSERT_NO_FATAL_FAILURE(
    483       OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
    484       GURL("chrome-extension://thisissurelynotavalidextensionid/newtab.html"),
    485       false, NULL));
    486 
    487   // If we got to this point, we didn't crash, so we're good.
    488 }
    489 
    490 // Tests that calling window.open from the newtab page to an extension URL
    491 // gives the new window extension privileges - even though the opening page
    492 // does not have extension privileges, we break the script connection, so
    493 // there is no privilege leak.
    494 IN_PROC_BROWSER_TEST_F(ExtensionBrowserTest, WindowOpenNoPrivileges) {
    495   ASSERT_TRUE(LoadExtension(
    496       test_data_dir_.AppendASCII("uitest").AppendASCII("window_open")));
    497 
    498   ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
    499   WebContents* newtab = NULL;
    500   ASSERT_NO_FATAL_FAILURE(
    501       OpenWindow(browser()->tab_strip_model()->GetActiveWebContents(),
    502                  GURL(std::string(extensions::kExtensionScheme) +
    503                      url::kStandardSchemeSeparator +
    504                      last_loaded_extension_id() + "/newtab.html"),
    505                  false,
    506                  &newtab));
    507 
    508   // Extension API should succeed.
    509   bool result = false;
    510   ASSERT_TRUE(content::ExecuteScriptAndExtractBool(newtab, "testExtensionApi()",
    511                                                    &result));
    512   EXPECT_TRUE(result);
    513 }
    514