• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights
2 // reserved. Use of this source code is governed by a BSD-style license that
3 // can be found in the LICENSE file.
4 
5 #include "include/base/cef_callback.h"
6 #include "include/test/cef_test_helpers.h"
7 #include "include/wrapper/cef_closure_task.h"
8 #include "tests/ceftests/routing_test_handler.h"
9 #include "tests/gtest/include/gtest/gtest.h"
10 
11 namespace {
12 
13 const char kLifeSpanUrl[] = "http://tests-life-span/test.html";
14 const char kUnloadDialogText[] = "Are you sure?";
15 const char kUnloadMsg[] = "LifeSpanTestHandler.Unload";
16 
17 // Browser side.
18 class LifeSpanTestHandler : public RoutingTestHandler {
19  public:
20   struct Settings {
Settings__anonbd5efbf60111::LifeSpanTestHandler::Settings21     Settings()
22         : force_close(false),
23           add_onunload_handler(false),
24           allow_do_close(true),
25           accept_before_unload_dialog(true) {}
26 
27     bool force_close;
28     bool add_onunload_handler;
29     bool allow_do_close;
30     bool accept_before_unload_dialog;
31   };
32 
LifeSpanTestHandler(const Settings & settings)33   explicit LifeSpanTestHandler(const Settings& settings)
34       : settings_(settings), executing_delay_close_(false) {
35     // By default no LifeSpan tests call DestroyTest().
36     SetDestroyTestExpected(false);
37   }
38 
RunTest()39   void RunTest() override {
40     // Add the resources that we will navigate to/from.
41     std::string page = "<html><script>";
42 
43     page += "window.onunload = function() { window.testQuery({request:'" +
44             std::string(kUnloadMsg) + "'}); };";
45 
46     if (settings_.add_onunload_handler) {
47       page += "window.onbeforeunload = function() { return '" +
48               std::string(kUnloadDialogText) + "'; };";
49     }
50 
51     page += "</script><body>Page</body></html>";
52     AddResource(kLifeSpanUrl, page, "text/html");
53 
54     // Create the browser.
55     CreateBrowser(kLifeSpanUrl);
56 
57     // Intentionally don't call SetTestTimeout() for these tests.
58   }
59 
OnAfterCreated(CefRefPtr<CefBrowser> browser)60   void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
61     got_after_created_.yes();
62     RoutingTestHandler::OnAfterCreated(browser);
63   }
64 
DoClose(CefRefPtr<CefBrowser> browser)65   bool DoClose(CefRefPtr<CefBrowser> browser) override {
66     if (executing_delay_close_)
67       return false;
68 
69     EXPECT_TRUE(browser->IsSame(GetBrowser()));
70 
71     got_do_close_.yes();
72 
73     if (!settings_.allow_do_close) {
74       // The close will be canceled.
75       ScheduleDelayClose();
76     }
77 
78     return !settings_.allow_do_close;
79   }
80 
OnBeforeClose(CefRefPtr<CefBrowser> browser)81   void OnBeforeClose(CefRefPtr<CefBrowser> browser) override {
82     if (!executing_delay_close_) {
83       got_before_close_.yes();
84       EXPECT_TRUE(browser->IsSame(GetBrowser()));
85     }
86 
87     RoutingTestHandler::OnBeforeClose(browser);
88   }
89 
OnBeforeUnloadDialog(CefRefPtr<CefBrowser> browser,const CefString & message_text,bool is_reload,CefRefPtr<CefJSDialogCallback> callback)90   bool OnBeforeUnloadDialog(CefRefPtr<CefBrowser> browser,
91                             const CefString& message_text,
92                             bool is_reload,
93                             CefRefPtr<CefJSDialogCallback> callback) override {
94     if (executing_delay_close_) {
95       callback->Continue(true, CefString());
96       return true;
97     }
98 
99     EXPECT_TRUE(browser->IsSame(GetBrowser()));
100 
101     // The message is no longer configurable via JavaScript.
102     // See http://crbug.com/587940.
103     EXPECT_STREQ("Is it OK to leave/reload this page?",
104                  message_text.ToString().c_str());
105 
106     EXPECT_FALSE(is_reload);
107     EXPECT_TRUE(callback.get());
108 
109     if (!settings_.accept_before_unload_dialog) {
110       // The close will be canceled.
111       ScheduleDelayClose();
112     }
113 
114     got_before_unload_dialog_.yes();
115     callback->Continue(settings_.accept_before_unload_dialog, CefString());
116     return true;
117   }
118 
OnLoadEnd(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int httpStatusCode)119   void OnLoadEnd(CefRefPtr<CefBrowser> browser,
120                  CefRefPtr<CefFrame> frame,
121                  int httpStatusCode) override {
122     got_load_end_.yes();
123     EXPECT_TRUE(browser->IsSame(GetBrowser()));
124 
125     if (settings_.add_onunload_handler) {
126       // Send the page a user gesture to enable firing of the onbefureunload
127       // handler. See https://crbug.com/707007.
128       CefExecuteJavaScriptWithUserGestureForTests(frame, CefString());
129     }
130 
131     // Attempt to close the browser.
132     CloseBrowser(browser, settings_.force_close);
133   }
134 
OnQuery(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int64 query_id,const CefString & request,bool persistent,CefRefPtr<Callback> callback)135   bool OnQuery(CefRefPtr<CefBrowser> browser,
136                CefRefPtr<CefFrame> frame,
137                int64 query_id,
138                const CefString& request,
139                bool persistent,
140                CefRefPtr<Callback> callback) override {
141     if (request.ToString() == kUnloadMsg) {
142       if (!executing_delay_close_)
143         got_unload_message_.yes();
144     }
145     callback->Success("");
146     return true;
147   }
148 
149   TrackCallback got_after_created_;
150   TrackCallback got_do_close_;
151   TrackCallback got_before_close_;
152   TrackCallback got_before_unload_dialog_;
153   TrackCallback got_unload_message_;
154   TrackCallback got_load_end_;
155   TrackCallback got_delay_close_;
156 
157  private:
158   // Wait a bit to make sure no additional events are received and then close
159   // the window.
ScheduleDelayClose()160   void ScheduleDelayClose() {
161     // This test will call DestroyTest().
162     SetDestroyTestExpected(true);
163 
164     CefPostDelayedTask(
165         TID_UI, base::BindOnce(&LifeSpanTestHandler::DelayClose, this), 100);
166   }
167 
DelayClose()168   void DelayClose() {
169     got_delay_close_.yes();
170     executing_delay_close_ = true;
171     DestroyTest();
172   }
173 
174   Settings settings_;
175 
176   // Forces the window to close (bypasses test conditions).
177   bool executing_delay_close_;
178 
179   IMPLEMENT_REFCOUNTING(LifeSpanTestHandler);
180 };
181 
182 }  // namespace
183 
TEST(LifeSpanTest,DoCloseAllow)184 TEST(LifeSpanTest, DoCloseAllow) {
185   LifeSpanTestHandler::Settings settings;
186   settings.allow_do_close = true;
187   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
188   handler->ExecuteTest();
189 
190   EXPECT_TRUE(handler->got_after_created_);
191   EXPECT_TRUE(handler->got_do_close_);
192   EXPECT_TRUE(handler->got_before_close_);
193   EXPECT_FALSE(handler->got_before_unload_dialog_);
194   EXPECT_TRUE(handler->got_unload_message_);
195   EXPECT_TRUE(handler->got_load_end_);
196   EXPECT_FALSE(handler->got_delay_close_);
197 
198   ReleaseAndWaitForDestructor(handler);
199 }
200 
TEST(LifeSpanTest,DoCloseAllowForce)201 TEST(LifeSpanTest, DoCloseAllowForce) {
202   LifeSpanTestHandler::Settings settings;
203   settings.allow_do_close = true;
204   settings.force_close = true;
205   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
206   handler->ExecuteTest();
207 
208   EXPECT_TRUE(handler->got_after_created_);
209   EXPECT_TRUE(handler->got_do_close_);
210   EXPECT_TRUE(handler->got_before_close_);
211   EXPECT_FALSE(handler->got_before_unload_dialog_);
212   EXPECT_TRUE(handler->got_unload_message_);
213   EXPECT_TRUE(handler->got_load_end_);
214   EXPECT_FALSE(handler->got_delay_close_);
215 
216   ReleaseAndWaitForDestructor(handler);
217 }
218 
TEST(LifeSpanTest,DoCloseDisallow)219 TEST(LifeSpanTest, DoCloseDisallow) {
220   LifeSpanTestHandler::Settings settings;
221   settings.allow_do_close = false;
222   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
223   handler->ExecuteTest();
224 
225   EXPECT_TRUE(handler->got_after_created_);
226   EXPECT_TRUE(handler->got_do_close_);
227   EXPECT_FALSE(handler->got_before_close_);
228   EXPECT_FALSE(handler->got_before_unload_dialog_);
229   EXPECT_TRUE(handler->got_unload_message_);
230   EXPECT_TRUE(handler->got_load_end_);
231   EXPECT_TRUE(handler->got_delay_close_);
232 
233   ReleaseAndWaitForDestructor(handler);
234 }
235 
TEST(LifeSpanTest,DoCloseDisallowForce)236 TEST(LifeSpanTest, DoCloseDisallowForce) {
237   LifeSpanTestHandler::Settings settings;
238   settings.allow_do_close = false;
239   settings.force_close = true;
240   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
241   handler->ExecuteTest();
242 
243   EXPECT_TRUE(handler->got_after_created_);
244   EXPECT_TRUE(handler->got_do_close_);
245   EXPECT_FALSE(handler->got_before_close_);
246   EXPECT_FALSE(handler->got_before_unload_dialog_);
247   EXPECT_TRUE(handler->got_unload_message_);
248   EXPECT_TRUE(handler->got_load_end_);
249   EXPECT_TRUE(handler->got_delay_close_);
250 
251   ReleaseAndWaitForDestructor(handler);
252 }
253 
TEST(LifeSpanTest,DoCloseDisallowWithOnUnloadAllow)254 TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadAllow) {
255   LifeSpanTestHandler::Settings settings;
256   settings.allow_do_close = false;
257   settings.add_onunload_handler = true;
258   settings.accept_before_unload_dialog = true;
259   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
260   handler->ExecuteTest();
261 
262   EXPECT_TRUE(handler->got_after_created_);
263   EXPECT_TRUE(handler->got_do_close_);
264   EXPECT_FALSE(handler->got_before_close_);
265   EXPECT_TRUE(handler->got_before_unload_dialog_);
266   EXPECT_TRUE(handler->got_unload_message_);
267   EXPECT_TRUE(handler->got_load_end_);
268   EXPECT_TRUE(handler->got_delay_close_);
269 
270   ReleaseAndWaitForDestructor(handler);
271 }
272 
TEST(LifeSpanTest,DoCloseAllowWithOnUnloadForce)273 TEST(LifeSpanTest, DoCloseAllowWithOnUnloadForce) {
274   LifeSpanTestHandler::Settings settings;
275   settings.allow_do_close = true;
276   settings.add_onunload_handler = true;
277   settings.force_close = true;
278   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
279   handler->ExecuteTest();
280 
281   EXPECT_TRUE(handler->got_after_created_);
282   EXPECT_TRUE(handler->got_do_close_);
283   EXPECT_TRUE(handler->got_before_close_);
284   EXPECT_FALSE(handler->got_before_unload_dialog_);
285   EXPECT_TRUE(handler->got_unload_message_);
286   EXPECT_TRUE(handler->got_load_end_);
287   EXPECT_FALSE(handler->got_delay_close_);
288 
289   ReleaseAndWaitForDestructor(handler);
290 }
291 
TEST(LifeSpanTest,DoCloseDisallowWithOnUnloadForce)292 TEST(LifeSpanTest, DoCloseDisallowWithOnUnloadForce) {
293   LifeSpanTestHandler::Settings settings;
294   settings.allow_do_close = false;
295   settings.add_onunload_handler = true;
296   settings.force_close = true;
297   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
298   handler->ExecuteTest();
299 
300   EXPECT_TRUE(handler->got_after_created_);
301   EXPECT_TRUE(handler->got_do_close_);
302   EXPECT_FALSE(handler->got_before_close_);
303   EXPECT_FALSE(handler->got_before_unload_dialog_);
304   EXPECT_TRUE(handler->got_unload_message_);
305   EXPECT_TRUE(handler->got_load_end_);
306   EXPECT_TRUE(handler->got_delay_close_);
307 
308   ReleaseAndWaitForDestructor(handler);
309 }
310 
TEST(LifeSpanTest,OnUnloadAllow)311 TEST(LifeSpanTest, OnUnloadAllow) {
312   LifeSpanTestHandler::Settings settings;
313   settings.add_onunload_handler = true;
314   settings.accept_before_unload_dialog = true;
315   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
316   handler->ExecuteTest();
317 
318   EXPECT_TRUE(handler->got_after_created_);
319   EXPECT_TRUE(handler->got_do_close_);
320   EXPECT_TRUE(handler->got_before_close_);
321   EXPECT_TRUE(handler->got_before_unload_dialog_);
322   EXPECT_TRUE(handler->got_unload_message_);
323   EXPECT_TRUE(handler->got_load_end_);
324   EXPECT_FALSE(handler->got_delay_close_);
325 
326   ReleaseAndWaitForDestructor(handler);
327 }
328 
TEST(LifeSpanTest,OnUnloadDisallow)329 TEST(LifeSpanTest, OnUnloadDisallow) {
330   LifeSpanTestHandler::Settings settings;
331   settings.add_onunload_handler = true;
332   settings.accept_before_unload_dialog = false;
333   CefRefPtr<LifeSpanTestHandler> handler = new LifeSpanTestHandler(settings);
334   handler->ExecuteTest();
335 
336   EXPECT_TRUE(handler->got_after_created_);
337   EXPECT_FALSE(handler->got_do_close_);
338   EXPECT_FALSE(handler->got_before_close_);
339   EXPECT_TRUE(handler->got_before_unload_dialog_);
340   EXPECT_FALSE(handler->got_unload_message_);
341   EXPECT_TRUE(handler->got_load_end_);
342   EXPECT_TRUE(handler->got_delay_close_);
343 
344   ReleaseAndWaitForDestructor(handler);
345 }
346