// Copyright (c) 2012 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 "base/bind.h" #include "base/bind_helpers.h" #include "base/file_path.h" #include "base/memory/singleton.h" #include "base/message_loop.h" #include "base/utf_string_conversions.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/views/html_dialog_view.h" #include "chrome/browser/ui/webui/test_html_dialog_ui_delegate.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 "content/browser/renderer_host/render_widget_host_view.h" #include "content/public/browser/web_contents.h" #include "content/public/browser/web_contents_view.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/views/widget/widget.h" using content::WebContents; using testing::Eq; namespace { // Initial size of HTMLDialog for SizeWindow test case. const int kInitialWidth = 40; const int kInitialHeight = 40; class TestHtmlDialogView: public HtmlDialogView { public: TestHtmlDialogView(Profile* profile, Browser* browser, HtmlDialogUIDelegate* delegate) : HtmlDialogView(profile, browser, delegate), painted_(false), should_quit_on_size_change_(false) { delegate->GetDialogSize(&last_size_); } bool painted() const { return painted_; } void set_should_quit_on_size_change(bool should_quit) { should_quit_on_size_change_ = should_quit; } private: // TODO(xiyuan): Update this when WidgetDelegate has bounds change hook. virtual void SaveWindowPlacement(const gfx::Rect& bounds, ui::WindowShowState show_state) OVERRIDE { if (should_quit_on_size_change_ && last_size_ != bounds.size()) { // Schedule message loop quit because we could be called while // the bounds change call is on the stack and not in the nested message // loop. MessageLoop::current()->PostTask(FROM_HERE, base::Bind( &MessageLoop::Quit, base::Unretained(MessageLoop::current()))); } last_size_ = bounds.size(); } virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE { should_quit_on_size_change_ = false; // No quit when we are closing. HtmlDialogView::OnDialogClosed(json_retval); } virtual void OnTabMainFrameFirstRender() OVERRIDE { HtmlDialogView::OnTabMainFrameFirstRender(); painted_ = true; MessageLoop::current()->Quit(); } // Whether first rendered notification is received. bool painted_; // Whether we should quit message loop when size change is detected. bool should_quit_on_size_change_; gfx::Size last_size_; DISALLOW_COPY_AND_ASSIGN(TestHtmlDialogView); }; } // namespace class HtmlDialogBrowserTest : public InProcessBrowserTest { public: HtmlDialogBrowserTest() {} }; #if defined(OS_LINUX) && !defined(OS_CHROMEOS) #define MAYBE_SizeWindow SizeWindow #else // http://code.google.com/p/chromium/issues/detail?id=52602 // Windows has some issues resizing windows- an off by one problem, // and a minimum size that seems too big. This file isn't included in // Mac builds yet. On Chrome OS, this test doesn't apply since ChromeOS // doesn't allow resizing of windows. #define MAYBE_SizeWindow DISABLED_SizeWindow #endif IN_PROC_BROWSER_TEST_F(HtmlDialogBrowserTest, MAYBE_SizeWindow) { test::TestHtmlDialogUIDelegate* delegate = new test::TestHtmlDialogUIDelegate( GURL(chrome::kChromeUIChromeURLsURL)); delegate->set_size(kInitialWidth, kInitialHeight); TestHtmlDialogView* html_view = new TestHtmlDialogView(browser()->profile(), browser(), delegate); WebContents* web_contents = browser()->GetSelectedWebContents(); ASSERT_TRUE(web_contents != NULL); views::Widget::CreateWindowWithParent( html_view, web_contents->GetView()->GetTopLevelNativeWindow()); html_view->InitDialog(); html_view->GetWidget()->Show(); // TestHtmlDialogView should quit current message loop on size change. html_view->set_should_quit_on_size_change(true); gfx::Rect bounds = html_view->GetWidget()->GetClientAreaScreenBounds(); gfx::Rect set_bounds = bounds; gfx::Rect actual_bounds, rwhv_bounds; // Bigger than the default in both dimensions. set_bounds.set_width(400); set_bounds.set_height(300); html_view->MoveContents(web_contents, set_bounds); ui_test_utils::RunMessageLoop(); // TestHtmlDialogView will quit. actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds(); EXPECT_EQ(set_bounds, actual_bounds); rwhv_bounds = html_view->dom_contents()->web_contents()-> GetRenderWidgetHostView()->GetViewBounds(); EXPECT_LT(0, rwhv_bounds.width()); EXPECT_LT(0, rwhv_bounds.height()); EXPECT_GE(set_bounds.width(), rwhv_bounds.width()); EXPECT_GE(set_bounds.height(), rwhv_bounds.height()); // Larger in one dimension and smaller in the other. set_bounds.set_width(550); set_bounds.set_height(250); html_view->MoveContents(web_contents, set_bounds); ui_test_utils::RunMessageLoop(); // TestHtmlDialogView will quit. actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds(); EXPECT_EQ(set_bounds, actual_bounds); rwhv_bounds = html_view->dom_contents()->web_contents()-> GetRenderWidgetHostView()->GetViewBounds(); EXPECT_LT(0, rwhv_bounds.width()); EXPECT_LT(0, rwhv_bounds.height()); EXPECT_GE(set_bounds.width(), rwhv_bounds.width()); EXPECT_GE(set_bounds.height(), rwhv_bounds.height()); // Get very small. gfx::Size min_size = html_view->GetWidget()->GetMinimumSize(); set_bounds.set_size(min_size); html_view->MoveContents(web_contents, set_bounds); ui_test_utils::RunMessageLoop(); // TestHtmlDialogView will quit. actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds(); EXPECT_EQ(set_bounds, actual_bounds); rwhv_bounds = html_view->dom_contents()->web_contents()-> GetRenderWidgetHostView()->GetViewBounds(); EXPECT_LT(0, rwhv_bounds.width()); EXPECT_LT(0, rwhv_bounds.height()); EXPECT_GE(set_bounds.width(), rwhv_bounds.width()); EXPECT_GE(set_bounds.height(), rwhv_bounds.height()); // Check to make sure we can't get to 0x0 set_bounds.set_width(0); set_bounds.set_height(0); html_view->MoveContents(web_contents, set_bounds); ui_test_utils::RunMessageLoop(); // TestHtmlDialogView will quit. actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds(); EXPECT_LT(0, actual_bounds.width()); EXPECT_LT(0, actual_bounds.height()); } // This is timing out about 5~10% of runs. See crbug.com/86059. IN_PROC_BROWSER_TEST_F(HtmlDialogBrowserTest, DISABLED_WebContentRendered) { HtmlDialogUIDelegate* delegate = new test::TestHtmlDialogUIDelegate( GURL(chrome::kChromeUIChromeURLsURL)); TestHtmlDialogView* html_view = new TestHtmlDialogView(browser()->profile(), browser(), delegate); WebContents* web_contents = browser()->GetSelectedWebContents(); ASSERT_TRUE(web_contents != NULL); views::Widget::CreateWindowWithParent( html_view, web_contents->GetView()->GetTopLevelNativeWindow()); EXPECT_TRUE(html_view->initialized_); html_view->InitDialog(); html_view->GetWidget()->Show(); // TestHtmlDialogView::OnTabMainFrameFirstRender() will Quit(). MessageLoopForUI::current()->Run(); EXPECT_TRUE(html_view->painted()); html_view->GetWidget()->Close(); }