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
44 #define MAYBE_ExtensionCrashRecoveryTest ExtensionCrashRecoveryTest
45 #endif // defined(OS_MACOSX) || defined(USE_AURA) || defined(OS_LINUX)
47 class ExtensionCrashRecoveryTestBase
: public ExtensionBrowserTest
{
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())->
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(
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
{
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
)
143 std::string id
= (*it
)->id();
144 message_center
->ClickOnNotification(id
);
146 Balloon
* balloon
= GetNotificationDelegate(index
);
147 ASSERT_TRUE(balloon
);
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()));
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();
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();
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();
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.
225 #define MAYBE_ReloadIndependently DISABLED_ReloadIndependently
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();
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
247 ASSERT_EQ(0U, CountBalloons());
250 // Test is timing out on Windows http://crbug.com/174705.
252 #define MAYBE_ReloadIndependentlyChangeTabs DISABLED_ReloadIndependentlyChangeTabs
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();
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
284 ASSERT_EQ(0U, CountBalloons());
287 IN_PROC_BROWSER_TEST_F(MAYBE_ExtensionCrashRecoveryTest
,
288 DISABLED_ReloadIndependentlyNavigatePage
) {
289 const size_t count_before
= GetEnabledExtensionCount();
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
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
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();
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();
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();
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();
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();
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
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();
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();
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();
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
495 #define MAYBE_CrashAndUninstall DISABLED_CrashAndUninstall
497 #define MAYBE_CrashAndUninstall CrashAndUninstall
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();
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
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();
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
545 #define MAYBE_ReloadTabsWithBackgroundPage ReloadTabsWithBackgroundPage
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();
558 // Open a tab extension.
559 chrome::NewTab(browser());
560 ui_test_utils::NavigateToURL(
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()->
578 chrome::Reload(browser(), CURRENT_TAB
);
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());