webview_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1// Copyright 2014 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. 4 5#include "ui/views/controls/webview/webview.h" 6 7#include "base/memory/scoped_ptr.h" 8#include "content/browser/web_contents/web_contents_impl.h" 9#include "content/public/browser/web_contents_observer.h" 10#include "content/public/test/test_browser_context.h" 11#include "content/public/test/test_browser_thread.h" 12#include "content/public/test/web_contents_tester.h" 13#include "content/test/test_content_browser_client.h" 14#include "ui/aura/window.h" 15#include "ui/views/test/test_views_delegate.h" 16#include "ui/views/test/widget_test.h" 17 18namespace { 19 20// Provides functionality to create a test WebContents. 21class WebViewTestViewsDelegate : public views::TestViewsDelegate { 22 public: 23 WebViewTestViewsDelegate() {} 24 virtual ~WebViewTestViewsDelegate() {} 25 26 // Overriden from TestViewsDelegate. 27 virtual content::WebContents* CreateWebContents( 28 content::BrowserContext* browser_context, 29 content::SiteInstance* site_instance) OVERRIDE { 30 return content::WebContentsTester::CreateTestWebContents(browser_context, 31 site_instance); 32 } 33 34 private: 35 DISALLOW_COPY_AND_ASSIGN(WebViewTestViewsDelegate); 36}; 37 38// Provides functionality to test a WebView. 39class WebViewUnitTest : public views::test::WidgetTest { 40 public: 41 WebViewUnitTest() 42 : ui_thread_(content::BrowserThread::UI, base::MessageLoop::current()), 43 file_blocking_thread_(content::BrowserThread::FILE_USER_BLOCKING, 44 base::MessageLoop::current()), 45 io_thread_(content::BrowserThread::IO, base::MessageLoop::current()) {} 46 47 virtual ~WebViewUnitTest() {} 48 49 virtual void SetUp() OVERRIDE { 50 // The ViewsDelegate is deleted when the ViewsTestBase class is torn down. 51 WidgetTest::set_views_delegate(new WebViewTestViewsDelegate); 52 browser_context_.reset(new content::TestBrowserContext); 53 WidgetTest::SetUp(); 54 // Set the test content browser client to avoid pulling in needless 55 // dependencies from content. 56 SetBrowserClientForTesting(&test_browser_client_); 57 } 58 59 virtual void TearDown() OVERRIDE { 60 browser_context_.reset(NULL); 61 // Flush the message loop to execute pending relase tasks as this would 62 // upset ASAN and Valgrind. 63 RunPendingMessages(); 64 WidgetTest::TearDown(); 65 } 66 67 protected: 68 content::BrowserContext* browser_context() { return browser_context_.get(); } 69 70 private: 71 content::TestBrowserThread ui_thread_; 72 content::TestBrowserThread file_blocking_thread_; 73 content::TestBrowserThread io_thread_; 74 scoped_ptr<content::TestBrowserContext> browser_context_; 75 scoped_ptr<WebViewTestViewsDelegate> views_delegate_; 76 content::TestContentBrowserClient test_browser_client_; 77 78 DISALLOW_COPY_AND_ASSIGN(WebViewUnitTest); 79}; 80 81// Provides functionaity to observe events on a WebContents like WasShown/ 82// WasHidden/WebContentsDestroyed. 83class WebViewTestWebContentsObserver : public content::WebContentsObserver { 84 public: 85 WebViewTestWebContentsObserver(content::WebContents* web_contents) 86 : web_contents_(static_cast<content::WebContentsImpl*>(web_contents)), 87 was_shown_(false), 88 shown_count_(0), 89 hidden_count_(0) { 90 content::WebContentsObserver::Observe(web_contents); 91 } 92 93 virtual ~WebViewTestWebContentsObserver() { 94 if (web_contents_) 95 content::WebContentsObserver::Observe(NULL); 96 } 97 98 virtual void WebContentsDestroyed() OVERRIDE { 99 DCHECK(web_contents_); 100 content::WebContentsObserver::Observe(NULL); 101 web_contents_ = NULL; 102 } 103 104 virtual void WasShown() OVERRIDE { 105 valid_root_while_shown_ = 106 web_contents()->GetNativeView()->GetRootWindow() != NULL; 107 was_shown_ = true; 108 ++shown_count_; 109 } 110 111 virtual void WasHidden() OVERRIDE { 112 was_shown_ = false; 113 ++hidden_count_; 114 } 115 116 bool was_shown() const { return was_shown_; } 117 118 int shown_count() const { return shown_count_; } 119 120 int hidden_count() const { return hidden_count_; } 121 122 bool valid_root_while_shown() const { return valid_root_while_shown_; } 123 124 private: 125 content::WebContentsImpl* web_contents_; 126 bool was_shown_; 127 int32 shown_count_; 128 int32 hidden_count_; 129 // Set to true if the view containing the webcontents has a valid root window. 130 bool valid_root_while_shown_; 131 132 DISALLOW_COPY_AND_ASSIGN(WebViewTestWebContentsObserver); 133}; 134 135// Tests that attaching and detaching a WebContents to a WebView makes the 136// WebContents visible and hidden respectively. 137TEST_F(WebViewUnitTest, TestWebViewAttachDetachWebContents) { 138 // Create a top level widget and a webview as its content. 139 views::Widget* widget = CreateTopLevelFramelessPlatformWidget(); 140 widget->SetBounds(gfx::Rect(0, 10, 100, 100)); 141 views::WebView* webview = new views::WebView(browser_context()); 142 widget->SetContentsView(webview); 143 widget->Show(); 144 145 // Case 1: Create a new WebContents and set it in the webview via 146 // SetWebContents. This should make the WebContents visible. 147 content::WebContents::CreateParams params(browser_context()); 148 scoped_ptr<content::WebContents> web_contents1( 149 content::WebContents::Create(params)); 150 WebViewTestWebContentsObserver observer1(web_contents1.get()); 151 EXPECT_FALSE(observer1.was_shown()); 152 153 webview->SetWebContents(web_contents1.get()); 154 EXPECT_TRUE(observer1.was_shown()); 155 EXPECT_TRUE(web_contents1->GetNativeView()->IsVisible()); 156 EXPECT_EQ(observer1.shown_count(), 1); 157 EXPECT_EQ(observer1.hidden_count(), 0); 158 EXPECT_TRUE(observer1.valid_root_while_shown()); 159 160 // Case 2: Create another WebContents and replace the current WebContents 161 // via SetWebContents(). This should hide the current WebContents and show 162 // the new one. 163 content::WebContents::CreateParams params2(browser_context()); 164 scoped_ptr<content::WebContents> web_contents2( 165 content::WebContents::Create(params2)); 166 167 WebViewTestWebContentsObserver observer2(web_contents2.get()); 168 EXPECT_FALSE(observer2.was_shown()); 169 170 // Setting the new WebContents should hide the existing one. 171 webview->SetWebContents(web_contents2.get()); 172 EXPECT_FALSE(observer1.was_shown()); 173 EXPECT_TRUE(observer2.was_shown()); 174 EXPECT_TRUE(observer2.valid_root_while_shown()); 175 176 // WebContents1 should not get stray show calls when WebContents2 is set. 177 EXPECT_EQ(observer1.shown_count(), 1); 178 EXPECT_EQ(observer1.hidden_count(), 1); 179 EXPECT_EQ(observer2.shown_count(), 1); 180 EXPECT_EQ(observer2.hidden_count(), 0); 181 182 widget->Close(); 183 RunPendingMessages(); 184} 185 186} // namespace 187