• 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 <list>
6 
7 #include "include/base/cef_callback.h"
8 #include "include/wrapper/cef_closure_task.h"
9 #include "tests/ceftests/routing_test_handler.h"
10 #include "tests/ceftests/test_handler.h"
11 #include "tests/gtest/include/gtest/gtest.h"
12 
13 namespace {
14 
15 // How it works:
16 // 1. Load kTitleUrl1 (title should be kTitleStr1)
17 // 2. Load kTitleUrl2 (title should be kTitleStr2)
18 // 3. History back to kTitleUrl1 (title should be kTitleStr1)
19 // 4. History forward to kTitleUrl2 (title should be kTitleStr2)
20 // 5. Set title via JavaScript (title should be kTitleStr3)
21 
22 const char kTitleUrl1[] = "http://tests-title/nav1.html";
23 const char kTitleUrl2[] = "http://tests-title/nav2.html";
24 const char kTitleStr1[] = "Title 1";
25 const char kTitleStr2[] = "Title 2";
26 const char kTitleStr3[] = "Title 3";
27 
28 // Browser side.
29 class TitleTestHandler : public TestHandler {
30  public:
TitleTestHandler()31   TitleTestHandler()
32       : step_(0), got_title_change_(false), got_loading_state_change_(false) {}
33 
RunTest()34   void RunTest() override {
35     // Add the resources that we will navigate to/from.
36     AddResource(kTitleUrl1,
37                 "<html><head><title>" + std::string(kTitleStr1) +
38                     "</title></head>Nav1</html>",
39                 "text/html");
40     AddResource(kTitleUrl2,
41                 "<html><head><title>" + std::string(kTitleStr2) +
42                     "</title></head>Nav2" +
43                     "<script>function setTitle() { window.document.title = '" +
44                     std::string(kTitleStr3) + "'; }</script>" + "</html>",
45                 "text/html");
46 
47     // Create the browser.
48     CreateBrowser(kTitleUrl1);
49 
50     // Time out the test after a reasonable period of time.
51     SetTestTimeout();
52   }
53 
OnTitleChange(CefRefPtr<CefBrowser> browser,const CefString & title)54   void OnTitleChange(CefRefPtr<CefBrowser> browser,
55                      const CefString& title) override {
56     // Ignore the 2nd OnTitleChange call which arrives after navigation
57     // completion.
58     if (got_title_change_)
59       return;
60 
61     std::string title_str = title;
62     if (step_ == 0 || step_ == 2) {
63       EXPECT_STREQ(kTitleStr1, title_str.c_str());
64     } else if (step_ == 1 || step_ == 3) {
65       EXPECT_STREQ(kTitleStr2, title_str.c_str());
66     } else if (step_ == 4) {
67       EXPECT_STREQ(kTitleStr3, title_str.c_str());
68     }
69 
70     got_title_[step_].yes();
71 
72     if (step_ == 4) {
73       DestroyTest();
74     } else {
75       got_title_change_ = true;
76       NextIfReady(browser);
77     }
78   }
79 
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading,bool canGoBack,bool canGoForward)80   void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
81                             bool isLoading,
82                             bool canGoBack,
83                             bool canGoForward) override {
84     if (isLoading)
85       return;
86 
87     // Call NextIfReady asynchronously because an additional call to
88     // OnTitleChange will be triggered later in the current call stack due to
89     // navigation completion and we want that call to arrive before execution of
90     // NextIfReady.
91     got_loading_state_change_ = true;
92     CefPostTask(TID_UI,
93                 base::BindOnce(&TitleTestHandler::NextIfReady, this, browser));
94   }
95 
96  private:
NextIfReady(CefRefPtr<CefBrowser> browser)97   void NextIfReady(CefRefPtr<CefBrowser> browser) {
98     if (!got_title_change_ || !got_loading_state_change_)
99       return;
100 
101     got_title_change_ = false;
102     got_loading_state_change_ = false;
103 
104     switch (step_++) {
105       case 0:
106         browser->GetMainFrame()->LoadURL(kTitleUrl2);
107         break;
108       case 1:
109         browser->GoBack();
110         break;
111       case 2:
112         browser->GoForward();
113         break;
114       case 3:
115         browser->GetMainFrame()->ExecuteJavaScript("setTitle()", kTitleUrl2, 0);
116         break;
117       default:
118         EXPECT_TRUE(false);  // Not reached.
119     }
120   }
121 
DestroyTest()122   void DestroyTest() override {
123     for (int i = 0; i < 5; ++i)
124       EXPECT_TRUE(got_title_[i]) << "step " << i;
125 
126     TestHandler::DestroyTest();
127   }
128 
129   int step_;
130 
131   bool got_title_change_;
132   bool got_loading_state_change_;
133 
134   TrackCallback got_title_[5];
135 
136   IMPLEMENT_REFCOUNTING(TitleTestHandler);
137 };
138 
139 }  // namespace
140 
141 // Test title notifications.
TEST(DisplayTest,Title)142 TEST(DisplayTest, Title) {
143   CefRefPtr<TitleTestHandler> handler = new TitleTestHandler();
144   handler->ExecuteTest();
145   ReleaseAndWaitForDestructor(handler);
146 }
147 
148 namespace {
149 
150 const char kAutoResizeUrl[] = "http://tests-display/auto-resize.html";
151 
152 class AutoResizeTestHandler : public RoutingTestHandler {
153  public:
AutoResizeTestHandler()154   AutoResizeTestHandler() {}
155 
RunTest()156   void RunTest() override {
157     // Add the resources that we will navigate to/from.
158     AddResource(kAutoResizeUrl,
159                 "<html><head><style>"
160                 "body {overflow:hidden;margin:0px;padding:0px;}"
161                 "</style></head><body><div id=a>Content</div></body></html>",
162                 "text/html");
163 
164     // Create the browser.
165     CreateBrowser(kAutoResizeUrl);
166 
167     // Time out the test after a reasonable period of time.
168     SetTestTimeout();
169   }
170 
OnAfterCreated(CefRefPtr<CefBrowser> browser)171   void OnAfterCreated(CefRefPtr<CefBrowser> browser) override {
172     RoutingTestHandler::OnAfterCreated(browser);
173     browser->GetHost()->SetAutoResizeEnabled(true, CefSize(10, 10),
174                                              CefSize(500, 500));
175   }
176 
OnAutoResize(CefRefPtr<CefBrowser> browser,const CefSize & new_size)177   bool OnAutoResize(CefRefPtr<CefBrowser> browser,
178                     const CefSize& new_size) override {
179     if (new_size.width == 1064 && new_size.height == 576) {
180       // Ignore this initial resize that may or may not occur.
181     } else if (!got_auto_resize1_) {
182       got_auto_resize1_.yes();
183       EXPECT_EQ(50, new_size.width);
184       EXPECT_EQ(18, new_size.height);
185 
186       // Trigger a resize.
187       browser->GetMainFrame()->ExecuteJavaScript(
188           "document.getElementById('a').innerText='New Content';",
189           kAutoResizeUrl, 0);
190     } else if (!got_auto_resize2_) {
191       got_auto_resize2_.yes();
192       EXPECT_EQ(50, new_size.width);
193       EXPECT_EQ(36, new_size.height);
194 
195       // Disable resize notifications.
196       browser->GetHost()->SetAutoResizeEnabled(false, CefSize(), CefSize());
197 
198       // There should be no more resize notifications. End the test after a
199       // short delay.
200       browser->GetMainFrame()->ExecuteJavaScript(
201           "document.getElementById('a').innerText='New Content Again';"
202           "var interval = setInterval(function() {"
203           "window.testQuery({request:'done'});clearInterval(interval);}, 50);",
204           kAutoResizeUrl, 0);
205     } else {
206       EXPECT_TRUE(false);  // Not reached.
207     }
208     return true;
209   }
210 
OnQuery(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,int64 query_id,const CefString & request,bool persistent,CefRefPtr<Callback> callback)211   bool OnQuery(CefRefPtr<CefBrowser> browser,
212                CefRefPtr<CefFrame> frame,
213                int64 query_id,
214                const CefString& request,
215                bool persistent,
216                CefRefPtr<Callback> callback) override {
217     EXPECT_STREQ("done", request.ToString().c_str());
218     EXPECT_FALSE(got_done_message_);
219     got_done_message_.yes();
220     DestroyTest();
221     return true;
222   }
223 
DestroyTest()224   void DestroyTest() override {
225     EXPECT_TRUE(got_auto_resize1_);
226     EXPECT_TRUE(got_auto_resize2_);
227     EXPECT_TRUE(got_done_message_);
228     TestHandler::DestroyTest();
229   }
230 
231  private:
232   TrackCallback got_auto_resize1_;
233   TrackCallback got_auto_resize2_;
234   TrackCallback got_done_message_;
235 
236   IMPLEMENT_REFCOUNTING(AutoResizeTestHandler);
237 };
238 
239 }  // namespace
240 
241 // Test OnAutoResize notification.
TEST(DisplayTest,AutoResize)242 TEST(DisplayTest, AutoResize) {
243   CefRefPtr<AutoResizeTestHandler> handler = new AutoResizeTestHandler();
244   handler->ExecuteTest();
245   ReleaseAndWaitForDestructor(handler);
246 }
247 
248 namespace {
249 
250 // Browser side.
251 class ConsoleTestHandler : public TestHandler {
252  public:
253   struct TestConfig {
254     // Use something other than 1 as |line| for testing.
TestConfig__anonfadd5f3b0311::ConsoleTestHandler::TestConfig255     explicit TestConfig(cef_log_severity_t message_level)
256         : level(message_level),
257           message("'Test Message'"),
258           expected_message("Test Message"),
259           source("http://tests-console-message/level.html"),
260           line(42) {}
261 
262     cef_log_severity_t level;
263     std::string message;
264     std::string expected_message;
265     std::string source;
266     int line;
267     std::string function;
268   };
269 
ConsoleTestHandler(const TestConfig & config)270   ConsoleTestHandler(const TestConfig& config) : config_(config) {}
271 
RunTest()272   void RunTest() override {
273     // Add the resources that will be used to print to console.
274     AddResource(
275         config_.source,
276         CreateResourceContent(config_.message, config_.function, config_.line),
277         "text/html");
278 
279     // Create the browser.
280     CreateBrowser(config_.source);
281 
282     // Time out the test after a reasonable period of time.
283     SetTestTimeout();
284   }
285 
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading,bool canGoBack,bool canGoForward)286   void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
287                             bool isLoading,
288                             bool canGoBack,
289                             bool canGoForward) override {
290     if (isLoading)
291       return;
292 
293     // Print console message after loading.
294     browser->GetMainFrame()->ExecuteJavaScript("printMessage()", config_.source,
295                                                0);
296   }
297 
OnConsoleMessage(CefRefPtr<CefBrowser> browser,cef_log_severity_t level,const CefString & message,const CefString & source,int line)298   bool OnConsoleMessage(CefRefPtr<CefBrowser> browser,
299                         cef_log_severity_t level,
300                         const CefString& message,
301                         const CefString& source,
302                         int line) override {
303     EXPECT_EQ(config_.level, level);
304     EXPECT_EQ(config_.expected_message, message.ToString());
305     EXPECT_EQ(config_.source, source.ToString());
306     EXPECT_EQ(config_.line, line);
307 
308     TestHandler::DestroyTest();
309 
310     return false;
311   }
312 
313  private:
CreateResourceContent(const CefString & message,const CefString & function,int line)314   std::string CreateResourceContent(const CefString& message,
315                                     const CefString& function,
316                                     int line) {
317     std::string content = "<html><script>function printMessage() { ";
318     for (int i = 1; i < line; ++i) {
319       // Add additional lines to test the |line| argument in |OnConsoleMessage|.
320       content += ";\n";
321     }
322     content += "console." + function.ToString() + "(" + message.ToString() +
323                "); }</script></html>";
324 
325     return content;
326   }
327 
328   TestConfig config_;
329 
330   IMPLEMENT_REFCOUNTING(ConsoleTestHandler);
331 };
332 
333 }  // namespace
334 
TEST(DisplayTest,OnConsoleMessageDebug)335 TEST(DisplayTest, OnConsoleMessageDebug) {
336   ConsoleTestHandler::TestConfig config(LOGSEVERITY_DEBUG);
337   config.function = "debug";
338 
339   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
340   handler->ExecuteTest();
341   ReleaseAndWaitForDestructor(handler);
342 }
343 
TEST(DisplayTest,OnConsoleMessageCount)344 TEST(DisplayTest, OnConsoleMessageCount) {
345   ConsoleTestHandler::TestConfig config(LOGSEVERITY_DEBUG);
346   config.function = "count";
347   config.expected_message = "Test Message: 1";
348 
349   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
350   handler->ExecuteTest();
351   ReleaseAndWaitForDestructor(handler);
352 }
353 
TEST(DisplayTest,OnConsoleMessageTimeEnd)354 TEST(DisplayTest, OnConsoleMessageTimeEnd) {
355   ConsoleTestHandler::TestConfig config(LOGSEVERITY_WARNING);
356   config.function = "timeEnd";
357   config.expected_message = "Timer 'Test Message' does not exist";
358 
359   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
360   handler->ExecuteTest();
361   ReleaseAndWaitForDestructor(handler);
362 }
363 
TEST(DisplayTest,OnConsoleMessageInfo)364 TEST(DisplayTest, OnConsoleMessageInfo) {
365   ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO);
366   config.function = "info";
367 
368   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
369   handler->ExecuteTest();
370   ReleaseAndWaitForDestructor(handler);
371 }
372 
TEST(DisplayTest,OnConsoleMessageLog)373 TEST(DisplayTest, OnConsoleMessageLog) {
374   ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO);
375   config.function = "log";
376 
377   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
378   handler->ExecuteTest();
379   ReleaseAndWaitForDestructor(handler);
380 }
381 
TEST(DisplayTest,OnConsoleMessageGroup)382 TEST(DisplayTest, OnConsoleMessageGroup) {
383   ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO);
384   config.function = "group";
385 
386   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
387   handler->ExecuteTest();
388   ReleaseAndWaitForDestructor(handler);
389 }
390 
TEST(DisplayTest,OnConsoleMessageGroupCollapsed)391 TEST(DisplayTest, OnConsoleMessageGroupCollapsed) {
392   ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO);
393   config.function = "groupCollapsed";
394 
395   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
396   handler->ExecuteTest();
397   ReleaseAndWaitForDestructor(handler);
398 }
399 
TEST(DisplayTest,OnConsoleMessageGroupEnd)400 TEST(DisplayTest, OnConsoleMessageGroupEnd) {
401   ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO);
402   config.function = "groupEnd";
403 
404   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
405   handler->ExecuteTest();
406   ReleaseAndWaitForDestructor(handler);
407 }
408 
TEST(DisplayTest,OnConsoleMessageTable)409 TEST(DisplayTest, OnConsoleMessageTable) {
410   ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO);
411   config.function = "table";
412   config.message = "[1, 2, 3]";
413   config.expected_message = "1,2,3";
414 
415   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
416   handler->ExecuteTest();
417   ReleaseAndWaitForDestructor(handler);
418 }
419 
TEST(DisplayTest,OnConsoleMessageTrace)420 TEST(DisplayTest, OnConsoleMessageTrace) {
421   ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO);
422   config.function = "trace";
423   config.message = "";
424   config.expected_message = "console.trace";
425 
426   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
427   handler->ExecuteTest();
428   ReleaseAndWaitForDestructor(handler);
429 }
430 
TEST(DisplayTest,OnConsoleMessageWarn)431 TEST(DisplayTest, OnConsoleMessageWarn) {
432   ConsoleTestHandler::TestConfig config(LOGSEVERITY_WARNING);
433   config.function = "warn";
434 
435   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
436   handler->ExecuteTest();
437   ReleaseAndWaitForDestructor(handler);
438 }
439 
TEST(DisplayTest,OnConsoleMessageError)440 TEST(DisplayTest, OnConsoleMessageError) {
441   ConsoleTestHandler::TestConfig config(LOGSEVERITY_ERROR);
442   config.function = "error";
443 
444   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
445   handler->ExecuteTest();
446   ReleaseAndWaitForDestructor(handler);
447 }
448 
TEST(DisplayTest,OnConsoleMessageAssert)449 TEST(DisplayTest, OnConsoleMessageAssert) {
450   ConsoleTestHandler::TestConfig config(LOGSEVERITY_ERROR);
451   config.function = "assert";
452   config.message = "false";
453   config.expected_message = "console.assert";
454 
455   CefRefPtr<ConsoleTestHandler> handler = new ConsoleTestHandler(config);
456   handler->ExecuteTest();
457   ReleaseAndWaitForDestructor(handler);
458 }
459 
460 namespace {
461 
462 const char kLoadinProgressUrl[] = "http://tests-display/loading-progress.html";
463 
464 // Browser side.
465 class LoadingProgressTestHandler : public TestHandler {
466  public:
LoadingProgressTestHandler()467   LoadingProgressTestHandler() {}
468 
RunTest()469   void RunTest() override {
470     // Add the resources that we will navigate to/from.
471     AddResource(kLoadinProgressUrl,
472                 "<html><head><style>"
473                 "body {overflow:hidden;margin:0px;padding:0px;}"
474                 "</style></head><body><div id=a>Content</div></body></html>",
475                 "text/html");
476 
477     // Create the browser.
478     CreateBrowser(kLoadinProgressUrl);
479 
480     // Time out the test after a reasonable period of time.
481     SetTestTimeout();
482   }
483 
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading,bool canGoBack,bool canGoForward)484   void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
485                             bool isLoading,
486                             bool canGoBack,
487                             bool canGoForward) override {
488     if (isLoading)
489       return;
490 
491     DestroyTest();
492   }
493 
OnLoadingProgressChange(CefRefPtr<CefBrowser> browser,double progress)494   void OnLoadingProgressChange(CefRefPtr<CefBrowser> browser,
495                                double progress) override {
496     if (!got_loading_progress_change0_) {
497       got_loading_progress_change0_.yes();
498       EXPECT_GE(progress, 0.0);
499     } else if (!got_loading_progress_change1_) {
500       got_loading_progress_change1_.yes();
501       EXPECT_LE(progress, 1.0);
502     }
503   }
504 
DestroyTest()505   void DestroyTest() override {
506     EXPECT_TRUE(got_loading_progress_change0_);
507     EXPECT_TRUE(got_loading_progress_change1_);
508     TestHandler::DestroyTest();
509   }
510 
511  private:
512   TrackCallback got_loading_progress_change0_;
513   TrackCallback got_loading_progress_change1_;
514 
515   IMPLEMENT_REFCOUNTING(LoadingProgressTestHandler);
516 };
517 
518 }  // namespace
519 
520 // Test OnLoadingProgressChange notification.
TEST(DisplayTest,LoadingProgress)521 TEST(DisplayTest, LoadingProgress) {
522   CefRefPtr<LoadingProgressTestHandler> handler =
523       new LoadingProgressTestHandler();
524   handler->ExecuteTest();
525   ReleaseAndWaitForDestructor(handler);
526 }
527