Home | History | Annotate | Download | only in views
      1 // Copyright (c) 2011 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 "chrome/test/ui/ui_test.h"
      6 
      7 #include "base/file_path.h"
      8 #include "base/memory/singleton.h"
      9 #include "base/message_loop.h"
     10 #include "chrome/browser/ui/views/html_dialog_view.h"
     11 #include "chrome/browser/ui/webui/html_dialog_ui.h"
     12 #include "chrome/common/url_constants.h"
     13 #include "chrome/test/in_process_browser_test.h"
     14 #include "chrome/test/ui_test_utils.h"
     15 #include "content/browser/renderer_host/render_widget_host_view.h"
     16 #include "content/browser/tab_contents/tab_contents.h"
     17 #include "testing/gmock/include/gmock/gmock.h"
     18 #include "testing/gtest/include/gtest/gtest.h"
     19 #include "views/widget/widget.h"
     20 #include "views/window/window.h"
     21 
     22 using testing::Eq;
     23 
     24 namespace {
     25 
     26 // Window non-client-area means that the minimum size for the window
     27 // won't be the actual minimum size - our layout and resizing code
     28 // makes sure the chrome is always visible.
     29 const int kMinimumWidthToTestFor = 20;
     30 const int kMinimumHeightToTestFor = 30;
     31 
     32 class TestHtmlDialogUIDelegate : public HtmlDialogUIDelegate {
     33  public:
     34   TestHtmlDialogUIDelegate() {}
     35   virtual ~TestHtmlDialogUIDelegate() {}
     36 
     37   // HTMLDialogUIDelegate implementation:
     38   virtual bool IsDialogModal() const {
     39     return true;
     40   }
     41   virtual std::wstring GetDialogTitle() const {
     42     return std::wstring(L"Test");
     43   }
     44   virtual GURL GetDialogContentURL() const {
     45     return GURL(chrome::kAboutBlankURL);
     46   }
     47   virtual void GetWebUIMessageHandlers(
     48       std::vector<WebUIMessageHandler*>* handlers) const { }
     49   virtual void GetDialogSize(gfx::Size* size) const {
     50     size->set_width(40);
     51     size->set_height(40);
     52   }
     53   virtual std::string GetDialogArgs() const {
     54     return std::string();
     55   }
     56   virtual void OnDialogClosed(const std::string& json_retval) { }
     57   virtual void OnCloseContents(TabContents* source, bool* out_close_dialog) {
     58     if (out_close_dialog)
     59       *out_close_dialog = true;
     60   }
     61   virtual bool ShouldShowDialogTitle() const { return true; }
     62 };
     63 
     64 }  // namespace
     65 
     66 class HtmlDialogBrowserTest : public InProcessBrowserTest {
     67  public:
     68   HtmlDialogBrowserTest() {}
     69 
     70 #if defined(OS_WIN)
     71   class WindowChangedObserver : public base::MessagePumpForUI::Observer {
     72    public:
     73     WindowChangedObserver() {}
     74 
     75     static WindowChangedObserver* GetInstance() {
     76       return Singleton<WindowChangedObserver>::get();
     77     }
     78 
     79     // This method is called before processing a message.
     80     virtual void WillProcessMessage(const MSG& msg) {}
     81 
     82     // This method is called after processing a message.
     83     virtual void DidProcessMessage(const MSG& msg) {
     84       // Either WM_PAINT or WM_TIMER indicates the actual work of
     85       // pushing through the window resizing messages is done since
     86       // they are lower priority (we don't get to see the
     87       // WM_WINDOWPOSCHANGED message here).
     88       if (msg.message == WM_PAINT || msg.message == WM_TIMER)
     89         MessageLoop::current()->Quit();
     90     }
     91   };
     92 #elif !defined(OS_MACOSX)
     93   class WindowChangedObserver : public base::MessagePumpForUI::Observer {
     94    public:
     95     WindowChangedObserver() {}
     96 
     97     static WindowChangedObserver* GetInstance() {
     98       return Singleton<WindowChangedObserver>::get();
     99     }
    100 
    101     // This method is called before processing a message.
    102     virtual void WillProcessEvent(GdkEvent* event) {}
    103 
    104     // This method is called after processing a message.
    105     virtual void DidProcessEvent(GdkEvent* event) {
    106       // Quit once the GDK_CONFIGURE event has been processed - seeing
    107       // this means the window sizing request that was made actually
    108       // happened.
    109       if (event->type == GDK_CONFIGURE)
    110         MessageLoop::current()->Quit();
    111     }
    112   };
    113 #endif
    114 };
    115 
    116 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
    117 #define MAYBE_SizeWindow SizeWindow
    118 #else
    119 // http://code.google.com/p/chromium/issues/detail?id=52602
    120 // Windows has some issues resizing windows- an off by one problem,
    121 // and a minimum size that seems too big.  This file isn't included in
    122 // Mac builds yet. On Chrome OS, this test doesn't apply since ChromeOS
    123 // doesn't allow resizing of windows.
    124 #define MAYBE_SizeWindow DISABLED_SizeWindow
    125 #endif
    126 
    127 IN_PROC_BROWSER_TEST_F(HtmlDialogBrowserTest, MAYBE_SizeWindow) {
    128   HtmlDialogUIDelegate* delegate = new TestHtmlDialogUIDelegate();
    129 
    130   HtmlDialogView* html_view =
    131       new HtmlDialogView(browser()->profile(), delegate);
    132   TabContents* tab_contents = browser()->GetSelectedTabContents();
    133   ASSERT_TRUE(tab_contents != NULL);
    134   views::Window::CreateChromeWindow(tab_contents->GetMessageBoxRootWindow(),
    135                                     gfx::Rect(), html_view);
    136   html_view->InitDialog();
    137   html_view->window()->Show();
    138 
    139   MessageLoopForUI::current()->AddObserver(
    140       WindowChangedObserver::GetInstance());
    141 
    142   gfx::Rect bounds = html_view->GetWidget()->GetClientAreaScreenBounds();
    143 
    144   gfx::Rect set_bounds = bounds;
    145   gfx::Rect actual_bounds, rwhv_bounds;
    146 
    147   // Bigger than the default in both dimensions.
    148   set_bounds.set_width(400);
    149   set_bounds.set_height(300);
    150 
    151   html_view->MoveContents(tab_contents, set_bounds);
    152   ui_test_utils::RunMessageLoop();
    153   actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds();
    154   EXPECT_EQ(set_bounds, actual_bounds);
    155 
    156   rwhv_bounds =
    157       html_view->tab_contents()->GetRenderWidgetHostView()->GetViewBounds();
    158   EXPECT_LT(0, rwhv_bounds.width());
    159   EXPECT_LT(0, rwhv_bounds.height());
    160   EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
    161   EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
    162 
    163   // Larger in one dimension and smaller in the other.
    164   set_bounds.set_width(550);
    165   set_bounds.set_height(250);
    166 
    167   html_view->MoveContents(tab_contents, set_bounds);
    168   ui_test_utils::RunMessageLoop();
    169   actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds();
    170   EXPECT_EQ(set_bounds, actual_bounds);
    171 
    172   rwhv_bounds =
    173       html_view->tab_contents()->GetRenderWidgetHostView()->GetViewBounds();
    174   EXPECT_LT(0, rwhv_bounds.width());
    175   EXPECT_LT(0, rwhv_bounds.height());
    176   EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
    177   EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
    178 
    179   // Get very small.
    180   set_bounds.set_width(kMinimumWidthToTestFor);
    181   set_bounds.set_height(kMinimumHeightToTestFor);
    182 
    183   html_view->MoveContents(tab_contents, set_bounds);
    184   ui_test_utils::RunMessageLoop();
    185   actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds();
    186   EXPECT_EQ(set_bounds, actual_bounds);
    187 
    188   rwhv_bounds =
    189       html_view->tab_contents()->GetRenderWidgetHostView()->GetViewBounds();
    190   EXPECT_LT(0, rwhv_bounds.width());
    191   EXPECT_LT(0, rwhv_bounds.height());
    192   EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
    193   EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
    194 
    195   // Check to make sure we can't get to 0x0
    196   set_bounds.set_width(0);
    197   set_bounds.set_height(0);
    198 
    199   html_view->MoveContents(tab_contents, set_bounds);
    200   ui_test_utils::RunMessageLoop();
    201   actual_bounds = html_view->GetWidget()->GetClientAreaScreenBounds();
    202   EXPECT_LT(0, actual_bounds.width());
    203   EXPECT_LT(0, actual_bounds.height());
    204 
    205   MessageLoopForUI::current()->RemoveObserver(
    206       WindowChangedObserver::GetInstance());
    207 }
    208