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.
5 #include "base/callback.h"
6 #include "base/location.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/ui/browser.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/browser/ui/webui/constrained_web_dialog_ui.h"
13 #include "chrome/common/url_constants.h"
14 #include "chrome/test/base/in_process_browser_test.h"
15 #include "components/web_modal/web_contents_modal_dialog_manager.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_contents_observer.h"
18 #include "content/public/test/browser_test_utils.h"
19 #include "content/public/test/test_navigation_observer.h"
20 #include "ui/web_dialogs/test/test_web_dialog_delegate.h"
22 using content::WebContents
;
23 using ui::WebDialogDelegate
;
24 using web_modal::WebContentsModalDialogManager
;
28 #if !defined(OS_MACOSX)
29 static const char kTestDataURL
[] = "data:text/html,<!doctype html>"
32 "body { height: 150px; width: 150px; }"
35 bool IsEqualSizes(gfx::Size expected
,
36 ConstrainedWebDialogDelegate
* dialog_delegate
) {
37 return expected
== dialog_delegate
->GetPreferredSize();
40 std::string
GetChangeDimensionsScript(int dimension
) {
41 return base::StringPrintf("window.document.body.style.width = %d + 'px';"
42 "window.document.body.style.height = %d + 'px';", dimension
, dimension
);
46 class ConstrainedWebDialogBrowserTestObserver
47 : public content::WebContentsObserver
{
49 explicit ConstrainedWebDialogBrowserTestObserver(WebContents
* contents
)
50 : content::WebContentsObserver(contents
),
51 contents_destroyed_(false) {
53 ~ConstrainedWebDialogBrowserTestObserver() override
{}
55 bool contents_destroyed() { return contents_destroyed_
; }
58 void WebContentsDestroyed() override
{ contents_destroyed_
= true; }
60 bool contents_destroyed_
;
65 class ConstrainedWebDialogBrowserTest
: public InProcessBrowserTest
{
67 ConstrainedWebDialogBrowserTest() {}
69 // Runs the current MessageLoop until |condition| is true or timeout.
70 bool RunLoopUntil(const base::Callback
<bool()>& condition
) {
71 const base::TimeTicks start_time
= base::TimeTicks::Now();
72 while (!condition
.Run()) {
73 const base::TimeTicks current_time
= base::TimeTicks::Now();
74 if (current_time
- start_time
> base::TimeDelta::FromSeconds(5)) {
75 ADD_FAILURE() << "Condition not met within five seconds.";
79 base::MessageLoop::current()->task_runner()->PostDelayedTask(
80 FROM_HERE
, base::MessageLoop::QuitClosure(),
81 base::TimeDelta::FromMilliseconds(20));
82 content::RunMessageLoop();
88 bool IsShowingWebContentsModalDialog(WebContents
* web_contents
) const {
89 WebContentsModalDialogManager
* web_contents_modal_dialog_manager
=
90 WebContentsModalDialogManager::FromWebContents(web_contents
);
91 return web_contents_modal_dialog_manager
->IsDialogActive();
95 // Tests that opening/closing the constrained window won't crash it.
96 IN_PROC_BROWSER_TEST_F(ConstrainedWebDialogBrowserTest
, BasicTest
) {
97 // The delegate deletes itself.
98 WebDialogDelegate
* delegate
= new ui::test::TestWebDialogDelegate(
99 GURL(chrome::kChromeUIConstrainedHTMLTestURL
));
100 WebContents
* web_contents
=
101 browser()->tab_strip_model()->GetActiveWebContents();
102 ASSERT_TRUE(web_contents
);
104 ConstrainedWebDialogDelegate
* dialog_delegate
=
105 ShowConstrainedWebDialog(browser()->profile(), delegate
, web_contents
);
106 ASSERT_TRUE(dialog_delegate
);
107 EXPECT_TRUE(dialog_delegate
->GetNativeDialog());
108 EXPECT_TRUE(IsShowingWebContentsModalDialog(web_contents
));
111 // Tests that ReleaseWebContentsOnDialogClose() works.
112 IN_PROC_BROWSER_TEST_F(ConstrainedWebDialogBrowserTest
,
113 ReleaseWebContentsOnDialogClose
) {
114 // The delegate deletes itself.
115 WebDialogDelegate
* delegate
= new ui::test::TestWebDialogDelegate(
116 GURL(chrome::kChromeUIConstrainedHTMLTestURL
));
117 WebContents
* web_contents
=
118 browser()->tab_strip_model()->GetActiveWebContents();
119 ASSERT_TRUE(web_contents
);
121 ConstrainedWebDialogDelegate
* dialog_delegate
=
122 ShowConstrainedWebDialog(browser()->profile(), delegate
, web_contents
);
123 ASSERT_TRUE(dialog_delegate
);
124 scoped_ptr
<WebContents
> new_tab(dialog_delegate
->GetWebContents());
125 ASSERT_TRUE(new_tab
.get());
126 ASSERT_TRUE(IsShowingWebContentsModalDialog(web_contents
));
128 ConstrainedWebDialogBrowserTestObserver
observer(new_tab
.get());
129 dialog_delegate
->ReleaseWebContentsOnDialogClose();
130 dialog_delegate
->OnDialogCloseFromWebUI();
132 ASSERT_FALSE(observer
.contents_destroyed());
133 EXPECT_FALSE(IsShowingWebContentsModalDialog(web_contents
));
135 EXPECT_TRUE(observer
.contents_destroyed());
138 #if !defined(OS_MACOSX)
139 // Tests that dialog autoresizes based on web contents when autoresizing
141 IN_PROC_BROWSER_TEST_F(ConstrainedWebDialogBrowserTest
,
142 ContentResizeInAutoResizingDialog
) {
143 // During auto-resizing, dialogs size to (WebContents size) + 16.
144 const int dialog_border_space
= 16;
146 // Expected dialog sizes after auto-resizing.
147 const int initial_size
= 150 + dialog_border_space
;
148 const int new_size
= 175 + dialog_border_space
;
150 // The delegate deletes itself.
151 WebDialogDelegate
* delegate
=
152 new ui::test::TestWebDialogDelegate(GURL(kTestDataURL
));
153 WebContents
* web_contents
=
154 browser()->tab_strip_model()->GetActiveWebContents();
155 ASSERT_TRUE(web_contents
);
157 // Observes the next created WebContents.
158 content::TestNavigationObserver
observer(NULL
);
159 observer
.StartWatchingNewWebContents();
161 gfx::Size min_size
= gfx::Size(100, 100);
162 gfx::Size max_size
= gfx::Size(200, 200);
163 gfx::Size initial_dialog_size
;
164 delegate
->GetDialogSize(&initial_dialog_size
);
166 ConstrainedWebDialogDelegate
* dialog_delegate
=
167 ShowConstrainedWebDialogWithAutoResize(browser()->profile(), delegate
,
168 web_contents
, min_size
,
170 ASSERT_TRUE(dialog_delegate
);
171 EXPECT_TRUE(dialog_delegate
->GetNativeDialog());
172 ASSERT_FALSE(IsShowingWebContentsModalDialog(web_contents
));
173 EXPECT_EQ(min_size
, dialog_delegate
->GetMinimumSize());
174 EXPECT_EQ(max_size
, dialog_delegate
->GetMaximumSize());
176 // Check for initial sizing. Dialog was created as a 400x400 dialog.
177 EXPECT_EQ(gfx::Size(), web_contents
->GetPreferredSize());
178 ASSERT_EQ(initial_dialog_size
, dialog_delegate
->GetPreferredSize());
182 // Wait until the entire WebContents has loaded.
183 WaitForLoadStop(dialog_delegate
->GetWebContents());
185 ASSERT_TRUE(IsShowingWebContentsModalDialog(web_contents
));
187 // Resize to content's originally set dimensions.
188 ASSERT_TRUE(RunLoopUntil(base::Bind(
190 gfx::Size(initial_size
, initial_size
),
193 // Resize to dimensions within expected bounds.
194 EXPECT_TRUE(ExecuteScript(dialog_delegate
->GetWebContents(),
195 GetChangeDimensionsScript(175)));
196 ASSERT_TRUE(RunLoopUntil(base::Bind(
198 gfx::Size(new_size
, new_size
),
201 // Resize to dimensions smaller than the minimum bounds.
202 EXPECT_TRUE(ExecuteScript(dialog_delegate
->GetWebContents(),
203 GetChangeDimensionsScript(50)));
204 ASSERT_TRUE(RunLoopUntil(base::Bind(
209 // Resize to dimensions greater than the maximum bounds.
210 EXPECT_TRUE(ExecuteScript(dialog_delegate
->GetWebContents(),
211 GetChangeDimensionsScript(250)));
212 ASSERT_TRUE(RunLoopUntil(base::Bind(
218 // Tests that dialog does not autoresize when autoresizing is not enabled.
219 IN_PROC_BROWSER_TEST_F(ConstrainedWebDialogBrowserTest
,
220 ContentResizeInNonAutoResizingDialog
) {
221 // The delegate deletes itself.
222 WebDialogDelegate
* delegate
=
223 new ui::test::TestWebDialogDelegate(GURL(kTestDataURL
));
224 WebContents
* web_contents
=
225 browser()->tab_strip_model()->GetActiveWebContents();
226 ASSERT_TRUE(web_contents
);
228 ConstrainedWebDialogDelegate
* dialog_delegate
=
229 ShowConstrainedWebDialog(browser()->profile(), delegate
, web_contents
);
230 ASSERT_TRUE(dialog_delegate
);
231 EXPECT_TRUE(dialog_delegate
->GetNativeDialog());
232 EXPECT_TRUE(IsShowingWebContentsModalDialog(web_contents
));
234 // Wait until the entire WebContents has loaded.
235 WaitForLoadStop(dialog_delegate
->GetWebContents());
237 gfx::Size initial_dialog_size
;
238 delegate
->GetDialogSize(&initial_dialog_size
);
240 // Check for initial sizing. Dialog was created as a 400x400 dialog.
241 EXPECT_EQ(gfx::Size(), web_contents
->GetPreferredSize());
242 ASSERT_EQ(initial_dialog_size
, dialog_delegate
->GetPreferredSize());
244 // Resize <body> to dimension smaller than dialog.
245 EXPECT_TRUE(ExecuteScript(dialog_delegate
->GetWebContents(),
246 GetChangeDimensionsScript(100)));
247 ASSERT_TRUE(RunLoopUntil(base::Bind(
252 // Resize <body> to dimension larger than dialog.
253 EXPECT_TRUE(ExecuteScript(dialog_delegate
->GetWebContents(),
254 GetChangeDimensionsScript(500)));
255 ASSERT_TRUE(RunLoopUntil(base::Bind(