1 // Copyright 2013 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/views/frame/browser_view.h"
7 #include "base/prefs/pref_service.h"
8 #include "chrome/browser/devtools/devtools_window_testing.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_tabstrip.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h"
13 #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view_observer.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/test/base/in_process_browser_test.h"
16 #include "chrome/test/base/ui_test_utils.h"
17 #include "components/bookmarks/common/bookmark_pref_names.h"
18 #include "content/public/browser/invalidate_type.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/browser/web_contents_observer.h"
22 class BrowserViewTest
: public InProcessBrowserTest
{
24 BrowserViewTest() : InProcessBrowserTest(), devtools_(nullptr) {}
27 BrowserView
* browser_view() {
28 return BrowserView::GetBrowserViewForBrowser(browser());
31 views::WebView
* devtools_web_view() {
32 return browser_view()->GetDevToolsWebViewForTest();
35 views::WebView
* contents_web_view() {
36 return browser_view()->GetContentsWebViewForTest();
39 void OpenDevToolsWindow(bool docked
) {
41 DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), docked
);
44 void CloseDevToolsWindow() {
45 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_
);
48 void SetDevToolsBounds(const gfx::Rect
& bounds
) {
49 DevToolsWindowTesting::Get(devtools_
)->SetInspectedPageBounds(bounds
);
52 DevToolsWindow
* devtools_
;
55 DISALLOW_COPY_AND_ASSIGN(BrowserViewTest
);
60 // Used to simulate scenario in a crash. When WebContentsDestroyed() is invoked
61 // updates the navigation state of another tab.
62 class TestWebContentsObserver
: public content::WebContentsObserver
{
64 TestWebContentsObserver(content::WebContents
* source
,
65 content::WebContents
* other
)
66 : content::WebContentsObserver(source
),
68 ~TestWebContentsObserver() override
{}
70 void WebContentsDestroyed() override
{
71 other_
->NotifyNavigationStateChanged(static_cast<content::InvalidateTypes
>(
72 content::INVALIDATE_TYPE_URL
| content::INVALIDATE_TYPE_LOAD
));
76 content::WebContents
* other_
;
78 DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver
);
83 // Verifies don't crash when CloseNow() is invoked with two tabs in a browser.
84 // Additionally when one of the tabs is destroyed NotifyNavigationStateChanged()
85 // is invoked on the other.
86 IN_PROC_BROWSER_TEST_F(BrowserViewTest
, CloseWithTabs
) {
88 new Browser(Browser::CreateParams(browser()->profile(),
89 browser()->host_desktop_type()));
90 chrome::AddTabAt(browser2
, GURL(), -1, true);
91 chrome::AddTabAt(browser2
, GURL(), -1, true);
92 TestWebContentsObserver
observer(
93 browser2
->tab_strip_model()->GetWebContentsAt(0),
94 browser2
->tab_strip_model()->GetWebContentsAt(1));
95 BrowserView::GetBrowserViewForBrowser(browser2
)->GetWidget()->CloseNow();
98 // Same as CloseWithTabs, but activates the first tab, which is the first tab
99 // BrowserView will destroy.
100 IN_PROC_BROWSER_TEST_F(BrowserViewTest
, CloseWithTabsStartWithActive
) {
102 new Browser(Browser::CreateParams(browser()->profile(),
103 browser()->host_desktop_type()));
104 chrome::AddTabAt(browser2
, GURL(), -1, true);
105 chrome::AddTabAt(browser2
, GURL(), -1, true);
106 browser2
->tab_strip_model()->ActivateTabAt(0, true);
107 TestWebContentsObserver
observer(
108 browser2
->tab_strip_model()->GetWebContentsAt(0),
109 browser2
->tab_strip_model()->GetWebContentsAt(1));
110 BrowserView::GetBrowserViewForBrowser(browser2
)->GetWidget()->CloseNow();
113 // Verifies that page and devtools WebViews are being correctly layed out
114 // when DevTools is opened/closed/updated/undocked.
115 IN_PROC_BROWSER_TEST_F(BrowserViewTest
, DevToolsUpdatesBrowserWindow
) {
116 gfx::Rect full_bounds
=
117 browser_view()->GetContentsContainerForTest()->GetLocalBounds();
118 gfx::Rect
small_bounds(10, 20, 30, 40);
120 browser_view()->UpdateDevTools();
121 EXPECT_FALSE(devtools_web_view()->web_contents());
122 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
123 EXPECT_EQ(full_bounds
, contents_web_view()->bounds());
126 OpenDevToolsWindow(true);
127 EXPECT_TRUE(devtools_web_view()->web_contents());
128 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
130 SetDevToolsBounds(small_bounds
);
131 EXPECT_TRUE(devtools_web_view()->web_contents());
132 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
133 EXPECT_EQ(small_bounds
, contents_web_view()->bounds());
135 browser_view()->UpdateDevTools();
136 EXPECT_TRUE(devtools_web_view()->web_contents());
137 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
138 EXPECT_EQ(small_bounds
, contents_web_view()->bounds());
140 CloseDevToolsWindow();
141 EXPECT_FALSE(devtools_web_view()->web_contents());
142 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
143 EXPECT_EQ(full_bounds
, contents_web_view()->bounds());
145 browser_view()->UpdateDevTools();
146 EXPECT_FALSE(devtools_web_view()->web_contents());
147 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
148 EXPECT_EQ(full_bounds
, contents_web_view()->bounds());
151 OpenDevToolsWindow(false);
152 EXPECT_TRUE(devtools_web_view()->web_contents());
153 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
155 SetDevToolsBounds(small_bounds
);
156 EXPECT_TRUE(devtools_web_view()->web_contents());
157 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
158 EXPECT_EQ(small_bounds
, contents_web_view()->bounds());
160 browser_view()->UpdateDevTools();
161 EXPECT_TRUE(devtools_web_view()->web_contents());
162 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
163 EXPECT_EQ(small_bounds
, contents_web_view()->bounds());
165 CloseDevToolsWindow();
166 EXPECT_FALSE(devtools_web_view()->web_contents());
167 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
168 EXPECT_EQ(full_bounds
, contents_web_view()->bounds());
170 browser_view()->UpdateDevTools();
171 EXPECT_FALSE(devtools_web_view()->web_contents());
172 EXPECT_EQ(full_bounds
, devtools_web_view()->bounds());
173 EXPECT_EQ(full_bounds
, contents_web_view()->bounds());
176 class BookmarkBarViewObserverImpl
: public BookmarkBarViewObserver
{
178 BookmarkBarViewObserverImpl() : change_count_(0) {
181 int change_count() const { return change_count_
; }
182 void clear_change_count() { change_count_
= 0; }
184 // BookmarkBarViewObserver:
185 void OnBookmarkBarVisibilityChanged() override
{ change_count_
++; }
190 DISALLOW_COPY_AND_ASSIGN(BookmarkBarViewObserverImpl
);
193 // Verifies we don't unnecessarily change the visibility of the BookmarkBarView.
194 IN_PROC_BROWSER_TEST_F(BrowserViewTest
, AvoidUnnecessaryVisibilityChanges
) {
195 // Create two tabs, the first empty and the second the ntp. Make it so the
196 // BookmarkBarView isn't shown (meaning it'll only be shown when on the ntp).
197 browser()->profile()->GetPrefs()->SetBoolean(
198 bookmarks::prefs::kShowBookmarkBar
, false);
199 GURL
new_tab_url(chrome::kChromeUINewTabURL
);
200 chrome::AddTabAt(browser(), GURL(), -1, true);
201 ui_test_utils::NavigateToURL(browser(), new_tab_url
);
203 ASSERT_TRUE(browser_view()->bookmark_bar());
204 BookmarkBarViewObserverImpl observer
;
205 BookmarkBarView
* bookmark_bar
= browser_view()->bookmark_bar();
206 bookmark_bar
->AddObserver(&observer
);
207 EXPECT_TRUE(bookmark_bar
->visible());
209 // Go to empty tab. Bookmark bar should hide.
210 browser()->tab_strip_model()->ActivateTabAt(0, true);
211 EXPECT_FALSE(bookmark_bar
->visible());
212 EXPECT_EQ(1, observer
.change_count());
213 observer
.clear_change_count();
215 // Go to ntp tab. Bookmark bar should show.
216 browser()->tab_strip_model()->ActivateTabAt(1, true);
217 EXPECT_TRUE(bookmark_bar
->visible());
218 EXPECT_EQ(1, observer
.change_count());
219 observer
.clear_change_count();
221 // Repeat with the bookmark bar always visible.
222 browser()->profile()->GetPrefs()->SetBoolean(
223 bookmarks::prefs::kShowBookmarkBar
, true);
224 browser()->tab_strip_model()->ActivateTabAt(1, true);
225 EXPECT_TRUE(bookmark_bar
->visible());
226 observer
.clear_change_count();
228 browser()->tab_strip_model()->ActivateTabAt(0, true);
229 EXPECT_TRUE(bookmark_bar
->visible());
230 EXPECT_EQ(0, observer
.change_count());
231 observer
.clear_change_count();
233 browser()->tab_strip_model()->ActivateTabAt(1, true);
234 EXPECT_TRUE(bookmark_bar
->visible());
235 EXPECT_EQ(0, observer
.change_count());
236 observer
.clear_change_count();
238 browser_view()->bookmark_bar()->RemoveObserver(&observer
);