| // Copyright 2013 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/ui/views/frame/browser_view.h" |
| |
| #include "base/prefs/pref_service.h" |
| #include "chrome/browser/devtools/devtools_window_testing.h" |
| #include "chrome/browser/ui/browser.h" |
| #include "chrome/browser/ui/browser_tabstrip.h" |
| #include "chrome/browser/ui/tabs/tab_strip_model.h" |
| #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view.h" |
| #include "chrome/browser/ui/views/bookmarks/bookmark_bar_view_observer.h" |
| #include "chrome/common/url_constants.h" |
| #include "chrome/test/base/in_process_browser_test.h" |
| #include "chrome/test/base/ui_test_utils.h" |
| #include "components/bookmarks/common/bookmark_pref_names.h" |
| #include "content/public/browser/invalidate_type.h" |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_contents_observer.h" |
| |
| class BrowserViewTest : public InProcessBrowserTest { |
| public: |
| BrowserViewTest() : InProcessBrowserTest(), devtools_(NULL) {} |
| |
| protected: |
| BrowserView* browser_view() { |
| return BrowserView::GetBrowserViewForBrowser(browser()); |
| } |
| |
| views::WebView* devtools_web_view() { |
| return browser_view()->GetDevToolsWebViewForTest(); |
| } |
| |
| views::WebView* contents_web_view() { |
| return browser_view()->GetContentsWebViewForTest(); |
| } |
| |
| void OpenDevToolsWindow(bool docked) { |
| devtools_ = |
| DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), docked); |
| } |
| |
| void CloseDevToolsWindow() { |
| DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_); |
| } |
| |
| void SetDevToolsBounds(const gfx::Rect& bounds) { |
| DevToolsWindowTesting::Get(devtools_)->SetInspectedPageBounds(bounds); |
| } |
| |
| DevToolsWindow* devtools_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(BrowserViewTest); |
| }; |
| |
| namespace { |
| |
| // Used to simulate scenario in a crash. When WebContentsDestroyed() is invoked |
| // updates the navigation state of another tab. |
| class TestWebContentsObserver : public content::WebContentsObserver { |
| public: |
| TestWebContentsObserver(content::WebContents* source, |
| content::WebContents* other) |
| : content::WebContentsObserver(source), |
| other_(other) {} |
| virtual ~TestWebContentsObserver() {} |
| |
| virtual void WebContentsDestroyed() override { |
| other_->NotifyNavigationStateChanged(static_cast<content::InvalidateTypes>( |
| content::INVALIDATE_TYPE_URL | content::INVALIDATE_TYPE_LOAD)); |
| } |
| |
| private: |
| content::WebContents* other_; |
| |
| DISALLOW_COPY_AND_ASSIGN(TestWebContentsObserver); |
| }; |
| |
| } // namespace |
| |
| // Verifies don't crash when CloseNow() is invoked with two tabs in a browser. |
| // Additionally when one of the tabs is destroyed NotifyNavigationStateChanged() |
| // is invoked on the other. |
| IN_PROC_BROWSER_TEST_F(BrowserViewTest, CloseWithTabs) { |
| Browser* browser2 = |
| new Browser(Browser::CreateParams(browser()->profile(), |
| browser()->host_desktop_type())); |
| chrome::AddTabAt(browser2, GURL(), -1, true); |
| chrome::AddTabAt(browser2, GURL(), -1, true); |
| TestWebContentsObserver observer( |
| browser2->tab_strip_model()->GetWebContentsAt(0), |
| browser2->tab_strip_model()->GetWebContentsAt(1)); |
| BrowserView::GetBrowserViewForBrowser(browser2)->GetWidget()->CloseNow(); |
| } |
| |
| // Same as CloseWithTabs, but activates the first tab, which is the first tab |
| // BrowserView will destroy. |
| IN_PROC_BROWSER_TEST_F(BrowserViewTest, CloseWithTabsStartWithActive) { |
| Browser* browser2 = |
| new Browser(Browser::CreateParams(browser()->profile(), |
| browser()->host_desktop_type())); |
| chrome::AddTabAt(browser2, GURL(), -1, true); |
| chrome::AddTabAt(browser2, GURL(), -1, true); |
| browser2->tab_strip_model()->ActivateTabAt(0, true); |
| TestWebContentsObserver observer( |
| browser2->tab_strip_model()->GetWebContentsAt(0), |
| browser2->tab_strip_model()->GetWebContentsAt(1)); |
| BrowserView::GetBrowserViewForBrowser(browser2)->GetWidget()->CloseNow(); |
| } |
| |
| // Verifies that page and devtools WebViews are being correctly layed out |
| // when DevTools is opened/closed/updated/undocked. |
| IN_PROC_BROWSER_TEST_F(BrowserViewTest, DevToolsUpdatesBrowserWindow) { |
| gfx::Rect full_bounds = |
| browser_view()->GetContentsContainerForTest()->GetLocalBounds(); |
| gfx::Rect small_bounds(10, 20, 30, 40); |
| |
| browser_view()->UpdateDevTools(); |
| EXPECT_FALSE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(full_bounds, contents_web_view()->bounds()); |
| |
| // Docked. |
| OpenDevToolsWindow(true); |
| EXPECT_TRUE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| |
| SetDevToolsBounds(small_bounds); |
| EXPECT_TRUE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(small_bounds, contents_web_view()->bounds()); |
| |
| browser_view()->UpdateDevTools(); |
| EXPECT_TRUE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(small_bounds, contents_web_view()->bounds()); |
| |
| CloseDevToolsWindow(); |
| EXPECT_FALSE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(full_bounds, contents_web_view()->bounds()); |
| |
| browser_view()->UpdateDevTools(); |
| EXPECT_FALSE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(full_bounds, contents_web_view()->bounds()); |
| |
| // Undocked. |
| OpenDevToolsWindow(false); |
| EXPECT_TRUE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| |
| SetDevToolsBounds(small_bounds); |
| EXPECT_TRUE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(small_bounds, contents_web_view()->bounds()); |
| |
| browser_view()->UpdateDevTools(); |
| EXPECT_TRUE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(small_bounds, contents_web_view()->bounds()); |
| |
| CloseDevToolsWindow(); |
| EXPECT_FALSE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(full_bounds, contents_web_view()->bounds()); |
| |
| browser_view()->UpdateDevTools(); |
| EXPECT_FALSE(devtools_web_view()->web_contents()); |
| EXPECT_EQ(full_bounds, devtools_web_view()->bounds()); |
| EXPECT_EQ(full_bounds, contents_web_view()->bounds()); |
| } |
| |
| class BookmarkBarViewObserverImpl : public BookmarkBarViewObserver { |
| public: |
| BookmarkBarViewObserverImpl() : change_count_(0) { |
| } |
| |
| int change_count() const { return change_count_; } |
| void clear_change_count() { change_count_ = 0; } |
| |
| // BookmarkBarViewObserver: |
| virtual void OnBookmarkBarVisibilityChanged() override { |
| change_count_++; |
| } |
| |
| private: |
| int change_count_; |
| |
| DISALLOW_COPY_AND_ASSIGN(BookmarkBarViewObserverImpl); |
| }; |
| |
| // Verifies we don't unnecessarily change the visibility of the BookmarkBarView. |
| IN_PROC_BROWSER_TEST_F(BrowserViewTest, AvoidUnnecessaryVisibilityChanges) { |
| // Create two tabs, the first empty and the second the ntp. Make it so the |
| // BookmarkBarView isn't shown (meaning it'll only be shown when on the ntp). |
| browser()->profile()->GetPrefs()->SetBoolean( |
| bookmarks::prefs::kShowBookmarkBar, false); |
| GURL new_tab_url(chrome::kChromeUINewTabURL); |
| chrome::AddTabAt(browser(), GURL(), -1, true); |
| ui_test_utils::NavigateToURL(browser(), new_tab_url); |
| |
| ASSERT_TRUE(browser_view()->bookmark_bar()); |
| BookmarkBarViewObserverImpl observer; |
| BookmarkBarView* bookmark_bar = browser_view()->bookmark_bar(); |
| bookmark_bar->AddObserver(&observer); |
| EXPECT_TRUE(bookmark_bar->visible()); |
| |
| // Go to empty tab. Bookmark bar should hide. |
| browser()->tab_strip_model()->ActivateTabAt(0, true); |
| EXPECT_FALSE(bookmark_bar->visible()); |
| EXPECT_EQ(1, observer.change_count()); |
| observer.clear_change_count(); |
| |
| // Go to ntp tab. Bookmark bar should show. |
| browser()->tab_strip_model()->ActivateTabAt(1, true); |
| EXPECT_TRUE(bookmark_bar->visible()); |
| EXPECT_EQ(1, observer.change_count()); |
| observer.clear_change_count(); |
| |
| // Repeat with the bookmark bar always visible. |
| browser()->profile()->GetPrefs()->SetBoolean( |
| bookmarks::prefs::kShowBookmarkBar, true); |
| browser()->tab_strip_model()->ActivateTabAt(1, true); |
| EXPECT_TRUE(bookmark_bar->visible()); |
| observer.clear_change_count(); |
| |
| browser()->tab_strip_model()->ActivateTabAt(0, true); |
| EXPECT_TRUE(bookmark_bar->visible()); |
| EXPECT_EQ(0, observer.change_count()); |
| observer.clear_change_count(); |
| |
| browser()->tab_strip_model()->ActivateTabAt(1, true); |
| EXPECT_TRUE(bookmark_bar->visible()); |
| EXPECT_EQ(0, observer.change_count()); |
| observer.clear_change_count(); |
| |
| browser_view()->bookmark_bar()->RemoveObserver(&observer); |
| } |