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.
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"
28 using content::BrowserContext
;
29 using content::WebContents
;
31 using ui::WebDialogDelegate
;
35 // Initial size of WebDialog for SizeWindow test case.
36 const int kInitialWidth
= 40;
37 const int kInitialHeight
= 40;
39 class TestWebDialogView
: public views::WebDialogView
{
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_
);
48 void set_should_quit_on_size_change(bool should_quit
) {
49 should_quit_on_size_change_
= should_quit
;
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
60 base::MessageLoop::current()->PostTask(
62 base::Bind(&base::MessageLoop::Quit
,
63 base::Unretained(base::MessageLoop::current())));
66 last_size_
= bounds
.size();
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
);
74 // Whether we should quit message loop when size change is detected.
75 bool should_quit_on_size_change_
;
78 DISALLOW_COPY_AND_ASSIGN(TestWebDialogView
);
83 class WebDialogBrowserTest
: public InProcessBrowserTest
{
85 WebDialogBrowserTest() {}
88 // TODO(linux_aura) http://crbug.com/163931
89 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && !defined(USE_AURA)
90 #define MAYBE_SizeWindow SizeWindow
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
100 IN_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
);
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();
115 // TestWebDialogView should quit current message loop on size change.
116 view
->set_should_quit_on_size_change(true);
118 gfx::Rect bounds
= view
->GetWidget()->GetClientAreaBoundsInScreen();
120 gfx::Rect set_bounds
= bounds
;
121 gfx::Rect actual_bounds
, rwhv_bounds
;
123 // Bigger than the default in both dimensions.
124 set_bounds
.set_width(400);
125 set_bounds
.set_height(300);
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
);
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());
139 // Larger in one dimension and smaller in the other.
140 set_bounds
.set_width(550);
141 set_bounds
.set_height(250);
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
);
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());
156 gfx::Size min_size
= view
->GetWidget()->GetMinimumSize();
157 set_bounds
.set_size(min_size
);
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
);
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());
171 // Check to make sure we can't get to 0x0
172 set_bounds
.set_width(0);
173 set_bounds
.set_height(0);
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());