Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_crash_recovery_browsertest.cc
blobffc1d7842eb3bb05da99fa90c45929caa3e48bc0
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 "chrome/browser/browser_process.h"
6 #include "chrome/browser/extensions/extension_browsertest.h"
7 #include "chrome/browser/extensions/extension_host.h"
8 #include "chrome/browser/extensions/extension_service.h"
9 #include "chrome/browser/extensions/extension_system.h"
10 #include "chrome/browser/notifications/balloon.h"
11 #include "chrome/browser/notifications/balloon_collection.h"
12 #include "chrome/browser/notifications/balloon_host.h"
13 #include "chrome/browser/notifications/balloon_notification_ui_manager.h"
14 #include "chrome/browser/notifications/notification.h"
15 #include "chrome/browser/notifications/notification_delegate.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/browser/ui/browser_commands.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "content/public/browser/navigation_controller.h"
22 #include "content/public/browser/render_process_host.h"
23 #include "content/public/browser/render_view_host.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/common/result_codes.h"
26 #include "extensions/browser/extension_registry.h"
27 #include "extensions/browser/process_manager.h"
28 #include "extensions/browser/process_map.h"
29 #include "ui/message_center/message_center.h"
30 #include "ui/message_center/message_center_switches.h"
31 #include "ui/message_center/message_center_util.h"
32 #include "ui/message_center/notification_list.h"
34 using content::NavigationController;
35 using content::WebContents;
36 using extensions::Extension;
37 using extensions::ExtensionRegistry;
39 // Tests are timing out waiting for extension to crash.
40 // http://crbug.com/174705
41 #if defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX)
42 #define MAYBE_ExtensionCrashRecoveryTest DISABLED_ExtensionCrashRecoveryTest
43 #else
44 #define MAYBE_ExtensionCrashRecoveryTest ExtensionCrashRecoveryTest
45 #endif // defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX)
47 class ExtensionCrashRecoveryTestBase : public ExtensionBrowserTest {
48 protected:
49 virtual void AcceptNotification(size_t index) = 0;
50 virtual void CancelNotification(size_t index) = 0;
51 virtual size_t CountBalloons() = 0;
53 ExtensionService* GetExtensionService() {
54 return browser()->profile()->GetExtensionService();
57 extensions::ProcessManager* GetProcessManager() {
58 return extensions::ExtensionSystem::Get(browser()->profile())->
59 process_manager();
62 size_t GetEnabledExtensionCount() {
63 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
64 return registry->enabled_extensions().size();
67 size_t GetTerminatedExtensionCount() {
68 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
69 return registry->terminated_extensions().size();
72 void CrashExtension(std::string extension_id) {
73 const Extension* extension =
74 GetExtensionService()->GetExtensionById(extension_id, false);
75 ASSERT_TRUE(extension);
76 extensions::ExtensionHost* extension_host = GetProcessManager()->
77 GetBackgroundHostForExtension(extension_id);
78 ASSERT_TRUE(extension_host);
80 base::KillProcess(extension_host->render_process_host()->GetHandle(),
81 content::RESULT_CODE_KILLED, false);
82 ASSERT_TRUE(WaitForExtensionCrash(extension_id));
83 ASSERT_FALSE(GetProcessManager()->
84 GetBackgroundHostForExtension(extension_id));
86 // Wait for extension crash balloon to appear.
87 base::MessageLoop::current()->RunUntilIdle();
90 void CheckExtensionConsistency(std::string extension_id) {
91 const Extension* extension =
92 GetExtensionService()->extensions()->GetByID(extension_id);
93 ASSERT_TRUE(extension);
94 extensions::ExtensionHost* extension_host = GetProcessManager()->
95 GetBackgroundHostForExtension(extension_id);
96 ASSERT_TRUE(extension_host);
97 extensions::ProcessManager::ViewSet all_views =
98 GetProcessManager()->GetAllViews();
99 extensions::ProcessManager::ViewSet::const_iterator it =
100 all_views.find(extension_host->host_contents()->GetRenderViewHost());
101 ASSERT_FALSE(it == all_views.end());
102 ASSERT_TRUE(extension_host->IsRenderViewLive());
103 extensions::ProcessMap* process_map =
104 extensions::ProcessMap::Get(browser()->profile());
105 ASSERT_TRUE(process_map->Contains(
106 extension_id,
107 extension_host->render_view_host()->GetProcess()->GetID()));
110 void LoadTestExtension() {
111 ExtensionBrowserTest::SetUpInProcessBrowserTestFixture();
112 const Extension* extension = LoadExtension(
113 test_data_dir_.AppendASCII("common").AppendASCII("background_page"));
114 ASSERT_TRUE(extension);
115 first_extension_id_ = extension->id();
116 CheckExtensionConsistency(first_extension_id_);
119 void LoadSecondExtension() {
120 const Extension* extension = LoadExtension(
121 test_data_dir_.AppendASCII("install").AppendASCII("install"));
122 ASSERT_TRUE(extension);
123 second_extension_id_ = extension->id();
124 CheckExtensionConsistency(second_extension_id_);
127 std::string first_extension_id_;
128 std::string second_extension_id_;
131 class MAYBE_ExtensionCrashRecoveryTest
132 : public ExtensionCrashRecoveryTestBase {
133 protected:
134 virtual void AcceptNotification(size_t index) OVERRIDE {
135 if (message_center::IsRichNotificationEnabled()) {
136 message_center::MessageCenter* message_center =
137 message_center::MessageCenter::Get();
138 ASSERT_GT(message_center->NotificationCount(), index);
139 message_center::NotificationList::Notifications::reverse_iterator it =
140 message_center->GetVisibleNotifications().rbegin();
141 for (size_t i=0; i < index; ++i)
142 it++;
143 std::string id = (*it)->id();
144 message_center->ClickOnNotification(id);
145 } else {
146 Balloon* balloon = GetNotificationDelegate(index);
147 ASSERT_TRUE(balloon);
148 balloon->OnClick();
150 WaitForExtensionLoad();
153 virtual void CancelNotification(size_t index) OVERRIDE {
154 if (message_center::IsRichNotificationEnabled()) {
155 message_center::MessageCenter* message_center =
156 message_center::MessageCenter::Get();
157 ASSERT_GT(message_center->NotificationCount(), index);
158 message_center::NotificationList::Notifications::reverse_iterator it =
159 message_center->GetVisibleNotifications().rbegin();
160 for (size_t i=0; i < index; i++) { it++; }
161 ASSERT_TRUE(g_browser_process->notification_ui_manager()->
162 CancelById((*it)->id()));
163 } else {
164 Balloon* balloon = GetNotificationDelegate(index);
165 ASSERT_TRUE(balloon);
166 std::string id = balloon->notification().notification_id();
167 ASSERT_TRUE(g_browser_process->notification_ui_manager()->CancelById(id));
171 virtual size_t CountBalloons() OVERRIDE {
172 if (message_center::IsRichNotificationEnabled())
173 return message_center::MessageCenter::Get()->NotificationCount();
175 return BalloonNotificationUIManager::GetInstanceForTesting()->
176 balloon_collection()->GetActiveBalloons().size();
179 private:
180 Balloon* GetNotificationDelegate(size_t index) {
181 BalloonNotificationUIManager* manager =
182 BalloonNotificationUIManager::GetInstanceForTesting();
183 BalloonCollection::Balloons balloons =
184 manager->balloon_collection()->GetActiveBalloons();
185 return index < balloons.size() ? balloons.at(index) : NULL;
189 // Flaky: http://crbug.com/242167.
190 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest, DISABLED_Basic) {
191 const size_t count_before = GetEnabledExtensionCount();
192 const size_t crash_count_before = GetTerminatedExtensionCount();
193 LoadTestExtension();
194 CrashExtension(first_extension_id_);
195 ASSERT_EQ(count_before, GetEnabledExtensionCount());
196 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
197 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
199 SCOPED_TRACE("after clicking the balloon");
200 CheckExtensionConsistency(first_extension_id_);
201 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
204 // Flaky, http://crbug.com/241191.
205 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
206 DISABLED_CloseAndReload) {
207 const size_t count_before = GetEnabledExtensionCount();
208 const size_t crash_count_before = GetTerminatedExtensionCount();
209 LoadTestExtension();
210 CrashExtension(first_extension_id_);
212 ASSERT_EQ(count_before, GetEnabledExtensionCount());
213 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
215 ASSERT_NO_FATAL_FAILURE(CancelNotification(0));
216 ReloadExtension(first_extension_id_);
218 SCOPED_TRACE("after reloading");
219 CheckExtensionConsistency(first_extension_id_);
220 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
223 // Test is timing out on Windows http://crbug.com/174705.
224 #if defined(OS_WIN)
225 #define MAYBE_ReloadIndependently DISABLED_ReloadIndependently
226 #else
227 #define MAYBE_ReloadIndependently ReloadIndependently
228 #endif // defined(OS_WIN)
229 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
230 MAYBE_ReloadIndependently) {
231 const size_t count_before = GetEnabledExtensionCount();
232 LoadTestExtension();
233 CrashExtension(first_extension_id_);
234 ASSERT_EQ(count_before, GetEnabledExtensionCount());
236 ReloadExtension(first_extension_id_);
238 SCOPED_TRACE("after reloading");
239 CheckExtensionConsistency(first_extension_id_);
241 WebContents* current_tab =
242 browser()->tab_strip_model()->GetActiveWebContents();
243 ASSERT_TRUE(current_tab);
245 // The balloon should automatically hide after the extension is successfully
246 // reloaded.
247 ASSERT_EQ(0U, CountBalloons());
250 // Test is timing out on Windows http://crbug.com/174705.
251 #if defined(OS_WIN)
252 #define MAYBE_ReloadIndependentlyChangeTabs DISABLED_ReloadIndependentlyChangeTabs
253 #else
254 #define MAYBE_ReloadIndependentlyChangeTabs ReloadIndependentlyChangeTabs
255 #endif // defined(OS_WIN)
257 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
258 MAYBE_ReloadIndependentlyChangeTabs) {
259 const size_t count_before = GetEnabledExtensionCount();
260 LoadTestExtension();
261 CrashExtension(first_extension_id_);
262 ASSERT_EQ(count_before, GetEnabledExtensionCount());
264 WebContents* original_tab =
265 browser()->tab_strip_model()->GetActiveWebContents();
266 ASSERT_TRUE(original_tab);
267 ASSERT_EQ(1U, CountBalloons());
269 // Open a new tab, but the balloon will still be there.
270 chrome::NewTab(browser());
271 WebContents* new_current_tab =
272 browser()->tab_strip_model()->GetActiveWebContents();
273 ASSERT_TRUE(new_current_tab);
274 ASSERT_NE(new_current_tab, original_tab);
275 ASSERT_EQ(1U, CountBalloons());
277 ReloadExtension(first_extension_id_);
279 SCOPED_TRACE("after reloading");
280 CheckExtensionConsistency(first_extension_id_);
282 // The balloon should automatically hide after the extension is successfully
283 // reloaded.
284 ASSERT_EQ(0U, CountBalloons());
287 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
288 DISABLED_ReloadIndependentlyNavigatePage) {
289 const size_t count_before = GetEnabledExtensionCount();
290 LoadTestExtension();
291 CrashExtension(first_extension_id_);
292 ASSERT_EQ(count_before, GetEnabledExtensionCount());
294 WebContents* current_tab =
295 browser()->tab_strip_model()->GetActiveWebContents();
296 ASSERT_TRUE(current_tab);
297 ASSERT_EQ(1U, CountBalloons());
299 // Navigate to another page.
300 ui_test_utils::NavigateToURL(
301 browser(), ui_test_utils::GetTestUrl(
302 base::FilePath(base::FilePath::kCurrentDirectory),
303 base::FilePath(FILE_PATH_LITERAL("title1.html"))));
304 ASSERT_EQ(1U, CountBalloons());
306 ReloadExtension(first_extension_id_);
308 SCOPED_TRACE("after reloading");
309 CheckExtensionConsistency(first_extension_id_);
311 // The balloon should automatically hide after the extension is successfully
312 // reloaded.
313 ASSERT_EQ(0U, CountBalloons());
316 // Make sure that when we don't do anything about the crashed extension
317 // and close the browser, it doesn't crash. The browser is closed implicitly
318 // at the end of each browser test.
320 // http://crbug.com/84719
321 #if defined(OS_LINUX)
322 #define MAYBE_ShutdownWhileCrashed DISABLED_ShutdownWhileCrashed
323 #else
324 #define MAYBE_ShutdownWhileCrashed ShutdownWhileCrashed
325 #endif // defined(OS_LINUX)
327 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
328 MAYBE_ShutdownWhileCrashed) {
329 const size_t count_before = GetEnabledExtensionCount();
330 LoadTestExtension();
331 CrashExtension(first_extension_id_);
332 ASSERT_EQ(count_before, GetEnabledExtensionCount());
335 // Flaky, http://crbug.com/241245.
336 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
337 DISABLED_TwoExtensionsCrashFirst) {
338 const size_t count_before = GetEnabledExtensionCount();
339 LoadTestExtension();
340 LoadSecondExtension();
341 CrashExtension(first_extension_id_);
342 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
343 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
345 SCOPED_TRACE("after clicking the balloon");
346 CheckExtensionConsistency(first_extension_id_);
347 CheckExtensionConsistency(second_extension_id_);
350 // Flaky: http://crbug.com/242196
351 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
352 DISABLED_TwoExtensionsCrashSecond) {
353 const size_t count_before = GetEnabledExtensionCount();
354 LoadTestExtension();
355 LoadSecondExtension();
356 CrashExtension(second_extension_id_);
357 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
358 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
360 SCOPED_TRACE("after clicking the balloon");
361 CheckExtensionConsistency(first_extension_id_);
362 CheckExtensionConsistency(second_extension_id_);
365 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
366 TwoExtensionsCrashBothAtOnce) {
367 const size_t count_before = GetEnabledExtensionCount();
368 const size_t crash_count_before = GetTerminatedExtensionCount();
369 LoadTestExtension();
370 LoadSecondExtension();
371 CrashExtension(first_extension_id_);
372 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
373 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
374 CrashExtension(second_extension_id_);
375 ASSERT_EQ(count_before, GetEnabledExtensionCount());
376 ASSERT_EQ(crash_count_before + 2, GetTerminatedExtensionCount());
379 SCOPED_TRACE("first balloon");
380 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
381 CheckExtensionConsistency(first_extension_id_);
385 SCOPED_TRACE("second balloon");
386 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
387 CheckExtensionConsistency(first_extension_id_);
388 CheckExtensionConsistency(second_extension_id_);
392 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
393 TwoExtensionsOneByOne) {
394 const size_t count_before = GetEnabledExtensionCount();
395 LoadTestExtension();
396 CrashExtension(first_extension_id_);
397 ASSERT_EQ(count_before, GetEnabledExtensionCount());
398 LoadSecondExtension();
399 CrashExtension(second_extension_id_);
400 ASSERT_EQ(count_before, GetEnabledExtensionCount());
403 SCOPED_TRACE("first balloon");
404 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
405 CheckExtensionConsistency(first_extension_id_);
409 SCOPED_TRACE("second balloon");
410 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
411 CheckExtensionConsistency(first_extension_id_);
412 CheckExtensionConsistency(second_extension_id_);
416 // http://crbug.com/84719
417 #if defined(OS_LINUX)
418 #define MAYBE_TwoExtensionsShutdownWhileCrashed \
419 DISABLED_TwoExtensionsShutdownWhileCrashed
420 #else
421 #define MAYBE_TwoExtensionsShutdownWhileCrashed \
422 TwoExtensionsShutdownWhileCrashed
423 #endif // defined(OS_LINUX)
425 // Make sure that when we don't do anything about the crashed extensions
426 // and close the browser, it doesn't crash. The browser is closed implicitly
427 // at the end of each browser test.
428 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
429 MAYBE_TwoExtensionsShutdownWhileCrashed) {
430 const size_t count_before = GetEnabledExtensionCount();
431 LoadTestExtension();
432 CrashExtension(first_extension_id_);
433 ASSERT_EQ(count_before, GetEnabledExtensionCount());
434 LoadSecondExtension();
435 CrashExtension(second_extension_id_);
436 ASSERT_EQ(count_before, GetEnabledExtensionCount());
439 // Flaky, http://crbug.com/241573.
440 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
441 DISABLED_TwoExtensionsIgnoreFirst) {
442 const size_t count_before = GetEnabledExtensionCount();
443 LoadTestExtension();
444 LoadSecondExtension();
445 CrashExtension(first_extension_id_);
446 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
447 CrashExtension(second_extension_id_);
448 ASSERT_EQ(count_before, GetEnabledExtensionCount());
450 // Accept notification 1 before canceling notification 0.
451 // Otherwise, on Linux and Windows, there is a race here, in which
452 // canceled notifications do not immediately go away.
453 ASSERT_NO_FATAL_FAILURE(AcceptNotification(1));
454 ASSERT_NO_FATAL_FAILURE(CancelNotification(0));
456 SCOPED_TRACE("balloons done");
457 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
458 CheckExtensionConsistency(second_extension_id_);
461 // Flaky, http://crbug.com/241164.
462 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
463 DISABLED_TwoExtensionsReloadIndependently) {
464 const size_t count_before = GetEnabledExtensionCount();
465 LoadTestExtension();
466 LoadSecondExtension();
467 CrashExtension(first_extension_id_);
468 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
469 CrashExtension(second_extension_id_);
470 ASSERT_EQ(count_before, GetEnabledExtensionCount());
473 SCOPED_TRACE("first: reload");
474 WebContents* current_tab =
475 browser()->tab_strip_model()->GetActiveWebContents();
476 ASSERT_TRUE(current_tab);
477 // At the beginning we should have one balloon displayed for each extension.
478 ASSERT_EQ(2U, CountBalloons());
479 ReloadExtension(first_extension_id_);
480 // One of the balloons should hide after the extension is reloaded.
481 ASSERT_EQ(1U, CountBalloons());
482 CheckExtensionConsistency(first_extension_id_);
486 SCOPED_TRACE("second: balloon");
487 ASSERT_NO_FATAL_FAILURE(AcceptNotification(0));
488 CheckExtensionConsistency(first_extension_id_);
489 CheckExtensionConsistency(second_extension_id_);
493 // http://crbug.com/243648
494 #if defined(OS_WIN)
495 #define MAYBE_CrashAndUninstall DISABLED_CrashAndUninstall
496 #else
497 #define MAYBE_CrashAndUninstall CrashAndUninstall
498 #endif
499 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
500 MAYBE_CrashAndUninstall) {
501 const size_t count_before = GetEnabledExtensionCount();
502 const size_t crash_count_before = GetTerminatedExtensionCount();
503 LoadTestExtension();
504 LoadSecondExtension();
505 CrashExtension(first_extension_id_);
506 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
507 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
509 ASSERT_EQ(1U, CountBalloons());
510 UninstallExtension(first_extension_id_);
511 base::MessageLoop::current()->RunUntilIdle();
513 SCOPED_TRACE("after uninstalling");
514 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
515 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
516 ASSERT_EQ(0U, CountBalloons());
519 // http://crbug.com/84719
520 #if defined(OS_LINUX)
521 #define MAYBE_CrashAndUnloadAll DISABLED_CrashAndUnloadAll
522 #else
523 #define MAYBE_CrashAndUnloadAll CrashAndUnloadAll
524 #endif // defined(OS_LINUX)
526 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
527 MAYBE_CrashAndUnloadAll) {
528 const size_t count_before = GetEnabledExtensionCount();
529 const size_t crash_count_before = GetTerminatedExtensionCount();
530 LoadTestExtension();
531 LoadSecondExtension();
532 CrashExtension(first_extension_id_);
533 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
534 ASSERT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
536 GetExtensionService()->UnloadAllExtensionsForTest();
537 ASSERT_EQ(crash_count_before, GetTerminatedExtensionCount());
540 // Fails a DCHECK on Aura and Linux: http://crbug.com/169622
541 // Failing on Windows: http://crbug.com/232340
542 #if defined(USE_AURA) || defined(OS_WIN) || defined(OS_LINUX)
543 #define MAYBE_ReloadTabsWithBackgroundPage DISABLED_ReloadTabsWithBackgroundPage
544 #else
545 #define MAYBE_ReloadTabsWithBackgroundPage ReloadTabsWithBackgroundPage
546 #endif
548 // Test that when an extension with a background page that has a tab open
549 // crashes, the tab stays open, and reloading it reloads the extension.
550 // Regression test for issue 71629.
551 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest,
552 MAYBE_ReloadTabsWithBackgroundPage) {
553 TabStripModel* tab_strip = browser()->tab_strip_model();
554 const size_t count_before = GetEnabledExtensionCount();
555 const size_t crash_count_before = GetTerminatedExtensionCount();
556 LoadTestExtension();
558 // Open a tab extension.
559 chrome::NewTab(browser());
560 ui_test_utils::NavigateToURL(
561 browser(),
562 GURL("chrome-extension://" + first_extension_id_ + "/background.html"));
564 const int tabs_before = tab_strip->count();
565 CrashExtension(first_extension_id_);
567 // Tab should still be open, and extension should be crashed.
568 EXPECT_EQ(tabs_before, tab_strip->count());
569 EXPECT_EQ(count_before, GetEnabledExtensionCount());
570 EXPECT_EQ(crash_count_before + 1, GetTerminatedExtensionCount());
573 content::WindowedNotificationObserver observer(
574 content::NOTIFICATION_LOAD_STOP,
575 content::Source<NavigationController>(
576 &browser()->tab_strip_model()->GetActiveWebContents()->
577 GetController()));
578 chrome::Reload(browser(), CURRENT_TAB);
579 observer.Wait();
581 // Extension should now be loaded.
582 SCOPED_TRACE("after reloading the tab");
583 CheckExtensionConsistency(first_extension_id_);
584 ASSERT_EQ(count_before + 1, GetEnabledExtensionCount());
585 ASSERT_EQ(0U, CountBalloons());