Move Webstore URL concepts to //extensions and out
[chromium-blink-merge.git] / chrome / browser / ui / panels / base_panel_browser_test.cc
blob1f53d2793cda49d8fd5463a62b1b18e946b06206
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/ui/panels/base_panel_browser_test.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/memory/weak_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/path_service.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "chrome/browser/chrome_notification_types.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_window.h"
18 #include "chrome/browser/ui/panels/detached_panel_collection.h"
19 #include "chrome/browser/ui/panels/native_panel.h"
20 #include "chrome/browser/ui/panels/panel_collection.h"
21 #include "chrome/browser/ui/panels/panel_mouse_watcher.h"
22 #include "chrome/browser/ui/panels/stacked_panel_collection.h"
23 #include "chrome/browser/ui/panels/test_panel_active_state_observer.h"
24 #include "chrome/browser/ui/panels/test_panel_mouse_watcher.h"
25 #include "chrome/common/chrome_paths.h"
26 #include "chrome/common/chrome_switches.h"
27 #include "chrome/test/base/interactive_test_utils.h"
28 #include "chrome/test/base/ui_test_utils.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/common/url_constants.h"
31 #include "content/public/test/web_contents_tester.h"
32 #include "extensions/browser/extension_prefs.h"
33 #include "extensions/browser/extension_system.h"
34 #include "extensions/browser/install_flag.h"
35 #include "extensions/common/manifest_constants.h"
36 #include "sync/api/string_ordinal.h"
38 #if defined(OS_LINUX)
39 #include "ui/base/x/x11_util.h"
40 #endif
42 #if defined(OS_MACOSX)
43 #include "base/mac/scoped_nsautorelease_pool.h"
44 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
45 #endif
47 using content::WebContentsTester;
48 using extensions::Extension;
50 namespace {
52 const gfx::Rect kTestingPrimaryDisplayArea = gfx::Rect(0, 0, 800, 600);
53 const gfx::Rect kTestingPrimaryWorkArea = gfx::Rect(0, 0, 800, 580);
55 struct MockDesktopBar {
56 bool auto_hiding_enabled;
57 DisplaySettingsProvider::DesktopBarVisibility visibility;
58 int thickness;
61 class MockDisplaySettingsProviderImpl :
62 public BasePanelBrowserTest::MockDisplaySettingsProvider {
63 public:
64 explicit MockDisplaySettingsProviderImpl();
65 virtual ~MockDisplaySettingsProviderImpl() { }
67 // Overridden from DisplaySettingsProvider:
68 virtual gfx::Rect GetPrimaryDisplayArea() const OVERRIDE;
69 virtual gfx::Rect GetPrimaryWorkArea() const OVERRIDE;
70 virtual gfx::Rect GetDisplayAreaMatching(
71 const gfx::Rect& bounds) const OVERRIDE;
72 virtual gfx::Rect GetWorkAreaMatching(
73 const gfx::Rect& bounds) const OVERRIDE;
74 virtual bool IsAutoHidingDesktopBarEnabled(
75 DesktopBarAlignment alignment) OVERRIDE;
76 virtual int GetDesktopBarThickness(
77 DesktopBarAlignment alignment) const OVERRIDE;
78 virtual DesktopBarVisibility GetDesktopBarVisibility(
79 DesktopBarAlignment alignment) const OVERRIDE;
80 virtual bool IsFullScreen() OVERRIDE;
82 // Overridden from MockDisplaySettingsProvider:
83 virtual void SetPrimaryDisplay(
84 const gfx::Rect& display_area, const gfx::Rect& work_area) OVERRIDE;
85 virtual void SetSecondaryDisplay(
86 const gfx::Rect& display_area, const gfx::Rect& work_area) OVERRIDE;
87 virtual void EnableAutoHidingDesktopBar(DesktopBarAlignment alignment,
88 bool enabled,
89 int thickness) OVERRIDE;
90 virtual void SetDesktopBarVisibility(
91 DesktopBarAlignment alignment, DesktopBarVisibility visibility) OVERRIDE;
92 virtual void SetDesktopBarThickness(DesktopBarAlignment alignment,
93 int thickness) OVERRIDE;
94 virtual void EnableFullScreenMode(bool enabled) OVERRIDE;
96 private:
97 gfx::Rect primary_display_area_;
98 gfx::Rect primary_work_area_;
99 gfx::Rect secondary_display_area_;
100 gfx::Rect secondary_work_area_;
101 MockDesktopBar mock_desktop_bars[3];
102 bool full_screen_enabled_;
104 DISALLOW_COPY_AND_ASSIGN(MockDisplaySettingsProviderImpl);
108 MockDisplaySettingsProviderImpl::MockDisplaySettingsProviderImpl()
109 : full_screen_enabled_(false) {
110 memset(mock_desktop_bars, 0, sizeof(mock_desktop_bars));
113 gfx::Rect MockDisplaySettingsProviderImpl::GetPrimaryDisplayArea() const {
114 return primary_display_area_;
117 gfx::Rect MockDisplaySettingsProviderImpl::GetPrimaryWorkArea() const {
118 return primary_work_area_;
121 gfx::Rect MockDisplaySettingsProviderImpl::GetDisplayAreaMatching(
122 const gfx::Rect& bounds) const {
123 if (secondary_display_area_.IsEmpty())
124 return primary_display_area_;
126 gfx::Rect primary_intersection =
127 gfx::IntersectRects(bounds, primary_display_area_);
128 int primary_intersection_size =
129 primary_intersection.width() * primary_intersection.height();
131 gfx::Rect secondary_intersection =
132 gfx::IntersectRects(bounds, secondary_display_area_);
133 int secondary_intersection_size =
134 secondary_intersection.width() * secondary_intersection.height();
136 return primary_intersection_size >= secondary_intersection_size ?
137 primary_display_area_ : secondary_display_area_;
140 gfx::Rect MockDisplaySettingsProviderImpl::GetWorkAreaMatching(
141 const gfx::Rect& bounds) const {
142 if (secondary_work_area_.IsEmpty())
143 return primary_work_area_;
145 gfx::Rect primary_intersection =
146 gfx::IntersectRects(bounds, primary_work_area_);
147 int primary_intersection_size =
148 primary_intersection.width() * primary_intersection.height();
150 gfx::Rect secondary_intersection =
151 gfx::IntersectRects(bounds, secondary_work_area_);
152 int secondary_intersection_size =
153 secondary_intersection.width() * secondary_intersection.height();
155 return primary_intersection_size >= secondary_intersection_size ?
156 primary_work_area_ : secondary_work_area_;
159 bool MockDisplaySettingsProviderImpl::IsAutoHidingDesktopBarEnabled(
160 DesktopBarAlignment alignment) {
161 return mock_desktop_bars[static_cast<int>(alignment)].auto_hiding_enabled;
164 int MockDisplaySettingsProviderImpl::GetDesktopBarThickness(
165 DesktopBarAlignment alignment) const {
166 return mock_desktop_bars[static_cast<int>(alignment)].thickness;
169 DisplaySettingsProvider::DesktopBarVisibility
170 MockDisplaySettingsProviderImpl::GetDesktopBarVisibility(
171 DesktopBarAlignment alignment) const {
172 return mock_desktop_bars[static_cast<int>(alignment)].visibility;
175 bool MockDisplaySettingsProviderImpl::IsFullScreen() {
176 return full_screen_enabled_;
179 void MockDisplaySettingsProviderImpl::EnableAutoHidingDesktopBar(
180 DesktopBarAlignment alignment, bool enabled, int thickness) {
181 MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]);
182 bar->auto_hiding_enabled = enabled;
183 bar->thickness = thickness;
186 void MockDisplaySettingsProviderImpl::SetPrimaryDisplay(
187 const gfx::Rect& display_area, const gfx::Rect& work_area) {
188 DCHECK(display_area.Contains(work_area));
189 primary_display_area_ = display_area;
190 primary_work_area_ = work_area;
191 OnDisplaySettingsChanged();
194 void MockDisplaySettingsProviderImpl::SetSecondaryDisplay(
195 const gfx::Rect& display_area, const gfx::Rect& work_area) {
196 DCHECK(display_area.Contains(work_area));
197 secondary_display_area_ = display_area;
198 secondary_work_area_ = work_area;
199 OnDisplaySettingsChanged();
202 void MockDisplaySettingsProviderImpl::SetDesktopBarVisibility(
203 DesktopBarAlignment alignment, DesktopBarVisibility visibility) {
204 MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]);
205 if (!bar->auto_hiding_enabled)
206 return;
207 if (visibility == bar->visibility)
208 return;
209 bar->visibility = visibility;
210 FOR_EACH_OBSERVER(
211 DesktopBarObserver,
212 desktop_bar_observers(),
213 OnAutoHidingDesktopBarVisibilityChanged(alignment, visibility));
216 void MockDisplaySettingsProviderImpl::SetDesktopBarThickness(
217 DesktopBarAlignment alignment, int thickness) {
218 MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]);
219 if (!bar->auto_hiding_enabled)
220 return;
221 if (thickness == bar->thickness)
222 return;
223 bar->thickness = thickness;
224 FOR_EACH_OBSERVER(
225 DesktopBarObserver,
226 desktop_bar_observers(),
227 OnAutoHidingDesktopBarThicknessChanged(alignment, thickness));
230 void MockDisplaySettingsProviderImpl::EnableFullScreenMode(bool enabled) {
231 full_screen_enabled_ = enabled;
232 CheckFullScreenMode(PERFORM_FULLSCREEN_CHECK);
235 } // namespace
237 const base::FilePath::CharType* BasePanelBrowserTest::kTestDir =
238 FILE_PATH_LITERAL("panels");
240 BasePanelBrowserTest::BasePanelBrowserTest()
241 : InProcessBrowserTest(),
242 mock_display_settings_enabled_(true) {
245 BasePanelBrowserTest::~BasePanelBrowserTest() {
248 void BasePanelBrowserTest::SetUpCommandLine(CommandLine* command_line) {
249 command_line->AppendSwitch(switches::kEnablePanels);
252 void BasePanelBrowserTest::SetUpOnMainThread() {
253 InProcessBrowserTest::SetUpOnMainThread();
255 // Setup the work area and desktop bar so that we have consistent testing
256 // environment for all panel related tests.
257 if (mock_display_settings_enabled_) {
258 mock_display_settings_provider_ = new MockDisplaySettingsProviderImpl();
259 mock_display_settings_provider_->SetPrimaryDisplay(
260 kTestingPrimaryDisplayArea, kTestingPrimaryWorkArea);
261 PanelManager::SetDisplaySettingsProviderForTesting(
262 mock_display_settings_provider_);
265 PanelManager* panel_manager = PanelManager::GetInstance();
266 panel_manager->enable_auto_sizing(false);
268 PanelManager::shorten_time_intervals_for_testing();
270 // Simulate the mouse movement so that tests are not affected by actual mouse
271 // events.
272 PanelMouseWatcher* mouse_watcher = new TestPanelMouseWatcher();
273 panel_manager->SetMouseWatcherForTesting(mouse_watcher);
275 // This is needed so the subsequently created panels can be activated.
276 // On a Mac, it transforms background-only test process into foreground one.
277 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser()));
280 void BasePanelBrowserTest::WaitForPanelActiveState(
281 Panel* panel, ActiveState expected_state) {
282 DCHECK(expected_state == SHOW_AS_ACTIVE ||
283 expected_state == SHOW_AS_INACTIVE);
285 #if defined(OS_MACOSX)
286 scoped_ptr<NativePanelTesting> panel_testing(
287 CreateNativePanelTesting(panel));
288 ASSERT_TRUE(panel_testing->EnsureApplicationRunOnForeground()) <<
289 "Failed to bring application to foreground. Bail out.";
290 #endif
292 PanelActiveStateObserver signal(panel, expected_state == SHOW_AS_ACTIVE);
293 signal.Wait();
296 void BasePanelBrowserTest::WaitForWindowSizeAvailable(Panel* panel) {
297 scoped_ptr<NativePanelTesting> panel_testing(
298 CreateNativePanelTesting(panel));
299 content::WindowedNotificationObserver signal(
300 chrome::NOTIFICATION_PANEL_WINDOW_SIZE_KNOWN,
301 content::Source<Panel>(panel));
302 if (panel_testing->IsWindowSizeKnown())
303 return;
304 signal.Wait();
305 EXPECT_TRUE(panel_testing->IsWindowSizeKnown());
308 void BasePanelBrowserTest::WaitForBoundsAnimationFinished(Panel* panel) {
309 scoped_ptr<NativePanelTesting> panel_testing(
310 CreateNativePanelTesting(panel));
311 // Sometimes there are several animations in sequence due to content
312 // auto resizing. Wait for all animations to finish.
313 while (panel_testing->IsAnimatingBounds()) {
314 content::WindowedNotificationObserver signal(
315 chrome::NOTIFICATION_PANEL_BOUNDS_ANIMATIONS_FINISHED,
316 content::Source<Panel>(panel));
317 if (!panel_testing->IsAnimatingBounds())
318 return;
319 signal.Wait();
323 BasePanelBrowserTest::CreatePanelParams::CreatePanelParams(
324 const std::string& name,
325 const gfx::Rect& bounds,
326 ActiveState show_flag)
327 : name(name),
328 bounds(bounds),
329 show_flag(show_flag),
330 wait_for_fully_created(true),
331 expected_active_state(show_flag),
332 create_mode(PanelManager::CREATE_AS_DOCKED),
333 profile(NULL) {
336 Panel* BasePanelBrowserTest::CreatePanelWithParams(
337 const CreatePanelParams& params) {
338 #if defined(OS_MACOSX)
339 // Opening panels on a Mac causes NSWindowController of the Panel window
340 // to be autoreleased. We need a pool drained after it's done so the test
341 // can close correctly. The NSWindowController of the Panel window controls
342 // lifetime of the Panel object so we want to release it as soon as
343 // possible. In real Chrome, this is done by message pump.
344 // On non-Mac platform, this is an empty class.
345 base::mac::ScopedNSAutoreleasePool autorelease_pool;
346 #endif
348 content::WindowedNotificationObserver observer(
349 content::NOTIFICATION_LOAD_STOP,
350 content::NotificationService::AllSources());
352 PanelManager* manager = PanelManager::GetInstance();
353 Panel* panel = manager->CreatePanel(
354 params.name,
355 params.profile ? params.profile : browser()->profile(),
356 params.url,
357 params.bounds,
358 params.create_mode);
360 if (!params.url.is_empty())
361 observer.Wait();
363 if (!manager->auto_sizing_enabled() ||
364 params.bounds.width() || params.bounds.height()) {
365 EXPECT_FALSE(panel->auto_resizable());
366 } else {
367 EXPECT_TRUE(panel->auto_resizable());
370 if (params.show_flag == SHOW_AS_ACTIVE) {
371 panel->Show();
372 } else {
373 panel->ShowInactive();
376 if (params.wait_for_fully_created) {
377 base::MessageLoopForUI::current()->RunUntilIdle();
379 #if defined(OS_LINUX) && defined(USE_X11)
380 // On bots, we might have a simple window manager which always activates new
381 // windows, and can't always deactivate them. Re-activate the main tabbed
382 // browser to "deactivate" the newly created panel.
383 if (params.expected_active_state == SHOW_AS_INACTIVE &&
384 ui::GuessWindowManager() == ui::WM_ICE_WM) {
385 // Wait for new panel to become active before deactivating to ensure
386 // the activated notification is consumed before we wait for the panel
387 // to become inactive.
388 WaitForPanelActiveState(panel, SHOW_AS_ACTIVE);
389 browser()->window()->Activate();
391 #endif
392 // More waiting, because gaining or losing focus may require inter-process
393 // asynchronous communication, and it is not enough to just run the local
394 // message loop to make sure this activity has completed.
395 WaitForPanelActiveState(panel, params.expected_active_state);
397 // On Linux, window size is not available right away and we should wait
398 // before moving forward with the test.
399 WaitForWindowSizeAvailable(panel);
401 // Wait for the bounds animations on creation to finish.
402 WaitForBoundsAnimationFinished(panel);
405 return panel;
408 Panel* BasePanelBrowserTest::CreatePanelWithBounds(
409 const std::string& panel_name, const gfx::Rect& bounds) {
410 CreatePanelParams params(panel_name, bounds, SHOW_AS_ACTIVE);
411 return CreatePanelWithParams(params);
414 Panel* BasePanelBrowserTest::CreatePanel(const std::string& panel_name) {
415 CreatePanelParams params(panel_name, gfx::Rect(), SHOW_AS_ACTIVE);
416 return CreatePanelWithParams(params);
419 Panel* BasePanelBrowserTest::CreateDockedPanel(const std::string& name,
420 const gfx::Rect& bounds) {
421 Panel* panel = CreatePanelWithBounds(name, bounds);
422 EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type());
423 return panel;
426 Panel* BasePanelBrowserTest::CreateDetachedPanel(const std::string& name,
427 const gfx::Rect& bounds) {
428 Panel* panel = CreatePanelWithBounds(name, bounds);
429 PanelManager* panel_manager = panel->manager();
430 panel_manager->MovePanelToCollection(panel,
431 panel_manager->detached_collection(),
432 PanelCollection::DEFAULT_POSITION);
433 EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type());
434 // The panel is first created as docked panel, which ignores the specified
435 // origin in |bounds|. We need to reposition the panel after it becomes
436 // detached.
437 panel->SetPanelBounds(bounds);
438 WaitForBoundsAnimationFinished(panel);
439 return panel;
442 Panel* BasePanelBrowserTest::CreateStackedPanel(const std::string& name,
443 const gfx::Rect& bounds,
444 StackedPanelCollection* stack) {
445 Panel* panel = CreateDetachedPanel(name, bounds);
446 panel->manager()->MovePanelToCollection(
447 panel,
448 stack,
449 static_cast<PanelCollection::PositioningMask>(
450 PanelCollection::DEFAULT_POSITION |
451 PanelCollection::COLLAPSE_TO_FIT));
452 EXPECT_EQ(PanelCollection::STACKED, panel->collection()->type());
453 WaitForBoundsAnimationFinished(panel);
454 return panel;
457 Panel* BasePanelBrowserTest::CreateInactivePanel(const std::string& name) {
458 // Create an active panel first, instead of inactive panel. This is because
459 // certain window managers on Linux, like icewm, will always activate the
460 // new window.
461 Panel* panel = CreatePanel(name);
463 DeactivatePanel(panel);
464 WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
466 return panel;
469 Panel* BasePanelBrowserTest::CreateInactiveDockedPanel(
470 const std::string& name, const gfx::Rect& bounds) {
471 // Create an active panel first, instead of inactive panel. This is because
472 // certain window managers on Linux, like icewm, will always activate the
473 // new window.
474 Panel* panel = CreateDockedPanel(name, bounds);
476 DeactivatePanel(panel);
477 WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
479 return panel;
482 Panel* BasePanelBrowserTest::CreateInactiveDetachedPanel(
483 const std::string& name, const gfx::Rect& bounds) {
484 // Create an active panel first, instead of inactive panel. This is because
485 // certain window managers on Linux, like icewm, will always activate the
486 // new window.
487 Panel* panel = CreateDetachedPanel(name, bounds);
489 DeactivatePanel(panel);
490 WaitForPanelActiveState(panel, SHOW_AS_INACTIVE);
492 return panel;
495 void BasePanelBrowserTest::ActivatePanel(Panel* panel) {
496 // For certain window managers on Linux, the window activation/deactivation
497 // signals might not be sent. To work around this, we explicitly deactivate
498 // all other panels first.
499 #if defined(OS_LINUX)
500 std::vector<Panel*> panels = PanelManager::GetInstance()->panels();
501 for (std::vector<Panel*>::const_iterator iter = panels.begin();
502 iter != panels.end(); ++iter) {
503 Panel* current_panel = *iter;
504 if (panel != current_panel)
505 current_panel->Deactivate();
507 #endif
509 panel->Activate();
512 void BasePanelBrowserTest::DeactivatePanel(Panel* panel) {
513 #if defined(OS_LINUX)
514 // For certain window managers on Linux, like icewm, panel activation and
515 // deactivation notification might not get tiggered when non-panel window is
516 // activated or deactivated. So we deactivate the panel directly.
517 panel->Deactivate();
518 #else
519 // Make the panel lose focus by activating the browser window. This is
520 // because:
521 // 1) On Windows, deactivating the panel window might cause the application
522 // to lose the foreground status. When this occurs, trying to activate
523 // the panel window again will not be allowed by the system.
524 // 2) On MacOS, deactivating a window is not supported by Cocoa.
525 browser()->window()->Activate();
526 #endif
529 // static
530 NativePanelTesting* BasePanelBrowserTest::CreateNativePanelTesting(
531 Panel* panel) {
532 return panel->native_panel()->CreateNativePanelTesting();
535 scoped_refptr<Extension> BasePanelBrowserTest::CreateExtension(
536 const base::FilePath::StringType& path,
537 extensions::Manifest::Location location,
538 const base::DictionaryValue& extra_value) {
539 extensions::ExtensionPrefs* extension_prefs =
540 extensions::ExtensionPrefs::Get(browser()->profile());
541 base::FilePath full_path = extension_prefs->install_directory().Append(path);
543 scoped_ptr<base::DictionaryValue> input_value(extra_value.DeepCopy());
544 input_value->SetString(extensions::manifest_keys::kVersion, "1.0.0.0");
545 input_value->SetString(extensions::manifest_keys::kName, "Sample Extension");
547 std::string error;
548 scoped_refptr<Extension> extension = Extension::Create(
549 full_path, location, *input_value, Extension::NO_FLAGS, &error);
550 EXPECT_TRUE(extension.get());
551 EXPECT_STREQ("", error.c_str());
552 extensions::ExtensionSystem::Get(
553 browser()->profile())->extension_service()->OnExtensionInstalled(
554 extension.get(),
555 syncer::StringOrdinal(),
556 extensions::kInstallFlagInstallImmediately);
557 return extension;
560 void BasePanelBrowserTest::CloseWindowAndWait(Panel* panel) {
561 // Closing a panel may involve several async tasks. Need to use
562 // message pump and wait for the notification.
563 PanelManager* manager = PanelManager::GetInstance();
564 int panel_count = manager->num_panels();
565 content::WindowedNotificationObserver signal(
566 chrome::NOTIFICATION_PANEL_CLOSED,
567 content::Source<Panel>(panel));
568 panel->Close();
569 signal.Wait();
570 // Now we have one less panel.
571 EXPECT_EQ(panel_count - 1, manager->num_panels());
573 #if defined(OS_MACOSX)
574 // Mac window controllers may be autoreleased, and in the non-test
575 // environment, may actually depend on the autorelease pool being recycled
576 // with the run loop in order to perform important work. Replicate this in
577 // the test environment.
578 AutoreleasePool()->Recycle();
580 // Make sure that everything has a chance to run.
581 chrome::testing::NSRunLoopRunAllPending();
582 #endif // OS_MACOSX
585 void BasePanelBrowserTest::MoveMouseAndWaitForExpansionStateChange(
586 Panel* panel,
587 const gfx::Point& position) {
588 content::WindowedNotificationObserver signal(
589 chrome::NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE,
590 content::Source<Panel>(panel));
591 MoveMouse(position);
592 signal.Wait();
595 void BasePanelBrowserTest::MoveMouse(const gfx::Point& position) {
596 PanelManager::GetInstance()->mouse_watcher()->NotifyMouseMovement(position);
599 std::string BasePanelBrowserTest::MakePanelName(int index) {
600 std::string panel_name("Panel");
601 return panel_name + base::IntToString(index);
604 bool BasePanelBrowserTest::WmSupportWindowActivation() {
605 return true;