web_dialog_view_browsertest.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
1// Copyright (c) 2012 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 "base/bind.h"
6#include "base/bind_helpers.h"
7#include "base/files/file_path.h"
8#include "base/memory/singleton.h"
9#include "base/message_loop/message_loop.h"
10#include "base/strings/utf_string_conversions.h"
11#include "chrome/browser/profiles/profile.h"
12#include "chrome/browser/ui/browser.h"
13#include "chrome/browser/ui/tabs/tab_strip_model.h"
14#include "chrome/browser/ui/webui/chrome_web_contents_handler.h"
15#include "chrome/common/url_constants.h"
16#include "chrome/test/base/in_process_browser_test.h"
17#include "chrome/test/base/ui_test_utils.h"
18#include "content/public/browser/browser_context.h"
19#include "content/public/browser/render_widget_host_view.h"
20#include "content/public/browser/web_contents.h"
21#include "content/public/browser/web_contents_view.h"
22#include "testing/gmock/include/gmock/gmock.h"
23#include "testing/gtest/include/gtest/gtest.h"
24#include "ui/views/controls/webview/web_dialog_view.h"
25#include "ui/views/widget/widget.h"
26#include "ui/web_dialogs/test/test_web_dialog_delegate.h"
27
28using content::BrowserContext;
29using content::WebContents;
30using testing::Eq;
31using ui::WebDialogDelegate;
32
33namespace {
34
35// Initial size of WebDialog for SizeWindow test case.
36const int kInitialWidth = 40;
37const int kInitialHeight = 40;
38
39class TestWebDialogView : public views::WebDialogView {
40 public:
41  TestWebDialogView(content::BrowserContext* context,
42                    WebDialogDelegate* delegate)
43      : views::WebDialogView(context, delegate, new ChromeWebContentsHandler),
44        should_quit_on_size_change_(false) {
45    delegate->GetDialogSize(&last_size_);
46  }
47
48  void set_should_quit_on_size_change(bool should_quit) {
49    should_quit_on_size_change_ = should_quit;
50  }
51
52 private:
53  // TODO(xiyuan): Update this when WidgetDelegate has bounds change hook.
54  virtual void SaveWindowPlacement(const gfx::Rect& bounds,
55                                   ui::WindowShowState show_state) OVERRIDE {
56    if (should_quit_on_size_change_ && last_size_ != bounds.size()) {
57      // Schedule message loop quit because we could be called while
58      // the bounds change call is on the stack and not in the nested message
59      // loop.
60      base::MessageLoop::current()->PostTask(
61          FROM_HERE,
62          base::Bind(&base::MessageLoop::Quit,
63                     base::Unretained(base::MessageLoop::current())));
64    }
65
66    last_size_ = bounds.size();
67  }
68
69  virtual void OnDialogClosed(const std::string& json_retval) OVERRIDE {
70    should_quit_on_size_change_ = false;  // No quit when we are closing.
71    views::WebDialogView::OnDialogClosed(json_retval);
72  }
73
74  // Whether we should quit message loop when size change is detected.
75  bool should_quit_on_size_change_;
76  gfx::Size last_size_;
77
78  DISALLOW_COPY_AND_ASSIGN(TestWebDialogView);
79};
80
81}  // namespace
82
83class WebDialogBrowserTest : public InProcessBrowserTest {
84 public:
85  WebDialogBrowserTest() {}
86};
87
88// TODO(linux_aura) http://crbug.com/163931
89#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(USE_AURA)
90#define MAYBE_SizeWindow SizeWindow
91#else
92// http://code.google.com/p/chromium/issues/detail?id=52602
93// Windows has some issues resizing windows- an off by one problem,
94// and a minimum size that seems too big.  This file isn't included in
95// Mac builds yet. On Chrome OS, this test doesn't apply since ChromeOS
96// doesn't allow resizing of windows.
97#define MAYBE_SizeWindow DISABLED_SizeWindow
98#endif
99
100IN_PROC_BROWSER_TEST_F(WebDialogBrowserTest, MAYBE_SizeWindow) {
101  ui::test::TestWebDialogDelegate* delegate =
102      new ui::test::TestWebDialogDelegate(
103          GURL(chrome::kChromeUIChromeURLsURL));
104  delegate->set_size(kInitialWidth, kInitialHeight);
105
106  TestWebDialogView* view =
107      new TestWebDialogView(browser()->profile(), delegate);
108  WebContents* web_contents =
109      browser()->tab_strip_model()->GetActiveWebContents();
110  ASSERT_TRUE(web_contents != NULL);
111  views::Widget::CreateWindowWithParent(
112      view, web_contents->GetView()->GetTopLevelNativeWindow());
113  view->GetWidget()->Show();
114
115  // TestWebDialogView should quit current message loop on size change.
116  view->set_should_quit_on_size_change(true);
117
118  gfx::Rect bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
119
120  gfx::Rect set_bounds = bounds;
121  gfx::Rect actual_bounds, rwhv_bounds;
122
123  // Bigger than the default in both dimensions.
124  set_bounds.set_width(400);
125  set_bounds.set_height(300);
126
127  view->MoveContents(web_contents, set_bounds);
128  content::RunMessageLoop();  // TestWebDialogView will quit.
129  actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
130  EXPECT_EQ(set_bounds, actual_bounds);
131
132  rwhv_bounds =
133      view->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
134  EXPECT_LT(0, rwhv_bounds.width());
135  EXPECT_LT(0, rwhv_bounds.height());
136  EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
137  EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
138
139  // Larger in one dimension and smaller in the other.
140  set_bounds.set_width(550);
141  set_bounds.set_height(250);
142
143  view->MoveContents(web_contents, set_bounds);
144  content::RunMessageLoop();  // TestWebDialogView will quit.
145  actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
146  EXPECT_EQ(set_bounds, actual_bounds);
147
148  rwhv_bounds =
149      view->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
150  EXPECT_LT(0, rwhv_bounds.width());
151  EXPECT_LT(0, rwhv_bounds.height());
152  EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
153  EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
154
155  // Get very small.
156  gfx::Size min_size = view->GetWidget()->GetMinimumSize();
157  set_bounds.set_size(min_size);
158
159  view->MoveContents(web_contents, set_bounds);
160  content::RunMessageLoop();  // TestWebDialogView will quit.
161  actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
162  EXPECT_EQ(set_bounds, actual_bounds);
163
164  rwhv_bounds =
165      view->web_contents()->GetRenderWidgetHostView()->GetViewBounds();
166  EXPECT_LT(0, rwhv_bounds.width());
167  EXPECT_LT(0, rwhv_bounds.height());
168  EXPECT_GE(set_bounds.width(), rwhv_bounds.width());
169  EXPECT_GE(set_bounds.height(), rwhv_bounds.height());
170
171  // Check to make sure we can't get to 0x0
172  set_bounds.set_width(0);
173  set_bounds.set_height(0);
174
175  view->MoveContents(web_contents, set_bounds);
176  content::RunMessageLoop();  // TestWebDialogView will quit.
177  actual_bounds = view->GetWidget()->GetClientAreaBoundsInScreen();
178  EXPECT_LT(0, actual_bounds.width());
179  EXPECT_LT(0, actual_bounds.height());
180}
181