// Copyright (c) 2013 The Chromium Embedded Framework Authors. All rights // reserved. Use of this source code is governed by a BSD-style license that // can be found in the LICENSE file. #include #include "include/base/cef_callback.h" #include "include/wrapper/cef_closure_task.h" #include "tests/ceftests/routing_test_handler.h" #include "tests/ceftests/test_handler.h" #include "tests/gtest/include/gtest/gtest.h" namespace { // How it works: // 1. Load kTitleUrl1 (title should be kTitleStr1) // 2. Load kTitleUrl2 (title should be kTitleStr2) // 3. History back to kTitleUrl1 (title should be kTitleStr1) // 4. History forward to kTitleUrl2 (title should be kTitleStr2) // 5. Set title via JavaScript (title should be kTitleStr3) const char kTitleUrl1[] = "https://tests-title/nav1.html"; const char kTitleUrl2[] = "https://tests-title/nav2.html"; const char kTitleStr1[] = "Title 1"; const char kTitleStr2[] = "Title 2"; const char kTitleStr3[] = "Title 3"; // Browser side. class TitleTestHandler : public TestHandler { public: TitleTestHandler() : step_(0), got_title_change_(false), got_loading_state_change_(false) {} void RunTest() override { // Add the resources that we will navigate to/from. AddResource(kTitleUrl1, "" + std::string(kTitleStr1) + "Nav1", "text/html"); AddResource(kTitleUrl2, "" + std::string(kTitleStr2) + "Nav2" + "" + "", "text/html"); // Create the browser. CreateBrowser(kTitleUrl1); // Time out the test after a reasonable period of time. SetTestTimeout(); } void OnTitleChange(CefRefPtr browser, const CefString& title) override { // Ignore the 2nd OnTitleChange call which arrives after navigation // completion. if (got_title_change_) { return; } std::string title_str = title; if (step_ == 0 || step_ == 2) { EXPECT_STREQ(kTitleStr1, title_str.c_str()); } else if (step_ == 1 || step_ == 3) { EXPECT_STREQ(kTitleStr2, title_str.c_str()); } else if (step_ == 4) { EXPECT_STREQ(kTitleStr3, title_str.c_str()); } got_title_[step_].yes(); if (step_ == 4) { DestroyTest(); } else { got_title_change_ = true; NextIfReady(browser); } } void OnLoadingStateChange(CefRefPtr browser, bool isLoading, bool canGoBack, bool canGoForward) override { if (isLoading) { return; } // Call NextIfReady asynchronously because an additional call to // OnTitleChange will be triggered later in the current call stack due to // navigation completion and we want that call to arrive before execution of // NextIfReady. got_loading_state_change_ = true; CefPostTask(TID_UI, base::BindOnce(&TitleTestHandler::NextIfReady, this, browser)); } private: void NextIfReady(CefRefPtr browser) { if (!got_title_change_ || !got_loading_state_change_) { return; } got_title_change_ = false; got_loading_state_change_ = false; switch (step_++) { case 0: browser->GetMainFrame()->LoadURL(kTitleUrl2); break; case 1: browser->GoBack(); break; case 2: browser->GoForward(); break; case 3: browser->GetMainFrame()->ExecuteJavaScript("setTitle()", kTitleUrl2, 0); break; default: EXPECT_TRUE(false); // Not reached. } } void DestroyTest() override { for (int i = 0; i < 5; ++i) { EXPECT_TRUE(got_title_[i]) << "step " << i; } TestHandler::DestroyTest(); } int step_; bool got_title_change_; bool got_loading_state_change_; TrackCallback got_title_[5]; IMPLEMENT_REFCOUNTING(TitleTestHandler); }; } // namespace // Test title notifications. TEST(DisplayTest, Title) { CefRefPtr handler = new TitleTestHandler(); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } namespace { const char kAutoResizeUrl[] = "https://tests-display/auto-resize.html"; class AutoResizeTestHandler : public RoutingTestHandler { public: AutoResizeTestHandler() {} void RunTest() override { // Add the resources that we will navigate to/from. AddResource(kAutoResizeUrl, "
Content
", "text/html"); // Create the browser. CreateBrowser(kAutoResizeUrl); // Time out the test after a reasonable period of time. SetTestTimeout(); } void OnAfterCreated(CefRefPtr browser) override { RoutingTestHandler::OnAfterCreated(browser); browser->GetHost()->SetAutoResizeEnabled(true, CefSize(10, 10), CefSize(500, 500)); } bool OnAutoResize(CefRefPtr browser, const CefSize& new_size) override { if (new_size.width == 1064 && new_size.height == 576) { // Ignore this initial resize that may or may not occur. } else if (!got_auto_resize1_) { got_auto_resize1_.yes(); EXPECT_EQ(50, new_size.width); EXPECT_EQ(18, new_size.height); // Trigger a resize. browser->GetMainFrame()->ExecuteJavaScript( "document.getElementById('a').innerText='New Content';", kAutoResizeUrl, 0); } else if (!got_auto_resize2_) { got_auto_resize2_.yes(); EXPECT_EQ(50, new_size.width); EXPECT_EQ(37, new_size.height); // Disable resize notifications. browser->GetHost()->SetAutoResizeEnabled(false, CefSize(), CefSize()); // There should be no more resize notifications. End the test after a // short delay. browser->GetMainFrame()->ExecuteJavaScript( "document.getElementById('a').innerText='New Content Again';" "var interval = setInterval(function() {" "window.testQuery({request:'done'});clearInterval(interval);}, 50);", kAutoResizeUrl, 0); } else { EXPECT_TRUE(false); // Not reached. } return true; } bool OnQuery(CefRefPtr browser, CefRefPtr frame, int64_t query_id, const CefString& request, bool persistent, CefRefPtr callback) override { EXPECT_STREQ("done", request.ToString().c_str()); EXPECT_FALSE(got_done_message_); got_done_message_.yes(); DestroyTest(); return true; } void DestroyTest() override { EXPECT_TRUE(got_auto_resize1_); EXPECT_TRUE(got_auto_resize2_); EXPECT_TRUE(got_done_message_); TestHandler::DestroyTest(); } private: TrackCallback got_auto_resize1_; TrackCallback got_auto_resize2_; TrackCallback got_done_message_; IMPLEMENT_REFCOUNTING(AutoResizeTestHandler); }; } // namespace // Test OnAutoResize notification. TEST(DisplayTest, AutoResize) { CefRefPtr handler = new AutoResizeTestHandler(); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } namespace { // Browser side. class ConsoleTestHandler : public TestHandler { public: struct TestConfig { // Use something other than 1 as |line| for testing. explicit TestConfig(cef_log_severity_t message_level) : level(message_level), message("'Test Message'"), expected_message("Test Message"), source("https://tests-console-message/level.html"), line(42) {} cef_log_severity_t level; std::string message; std::string expected_message; std::string source; int line; std::string function; }; ConsoleTestHandler(const TestConfig& config) : config_(config) {} void RunTest() override { // Add the resources that will be used to print to console. AddResource( config_.source, CreateResourceContent(config_.message, config_.function, config_.line), "text/html"); // Create the browser. CreateBrowser(config_.source); // Time out the test after a reasonable period of time. SetTestTimeout(); } void OnLoadingStateChange(CefRefPtr browser, bool isLoading, bool canGoBack, bool canGoForward) override { if (isLoading) { return; } // Print console message after loading. browser->GetMainFrame()->ExecuteJavaScript("printMessage()", config_.source, 0); } bool OnConsoleMessage(CefRefPtr browser, cef_log_severity_t level, const CefString& message, const CefString& source, int line) override { EXPECT_EQ(config_.level, level); EXPECT_EQ(config_.expected_message, message.ToString()); EXPECT_EQ(config_.source, source.ToString()); EXPECT_EQ(config_.line, line); TestHandler::DestroyTest(); return false; } private: std::string CreateResourceContent(const CefString& message, const CefString& function, int line) { std::string content = ""; return content; } TestConfig config_; IMPLEMENT_REFCOUNTING(ConsoleTestHandler); }; } // namespace TEST(DisplayTest, OnConsoleMessageDebug) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_DEBUG); config.function = "debug"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageCount) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_DEBUG); config.function = "count"; config.expected_message = "Test Message: 1"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageTimeEnd) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_WARNING); config.function = "timeEnd"; config.expected_message = "Timer 'Test Message' does not exist"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageInfo) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO); config.function = "info"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageLog) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO); config.function = "log"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageGroup) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO); config.function = "group"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageGroupCollapsed) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO); config.function = "groupCollapsed"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageGroupEnd) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO); config.function = "groupEnd"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageTable) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO); config.function = "table"; config.message = "[1, 2, 3]"; config.expected_message = "1,2,3"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageTrace) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_INFO); config.function = "trace"; config.message = ""; config.expected_message = "console.trace"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageWarn) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_WARNING); config.function = "warn"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageError) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_ERROR); config.function = "error"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } TEST(DisplayTest, OnConsoleMessageAssert) { ConsoleTestHandler::TestConfig config(LOGSEVERITY_ERROR); config.function = "assert"; config.message = "false"; config.expected_message = "console.assert"; CefRefPtr handler = new ConsoleTestHandler(config); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); } namespace { const char kLoadinProgressUrl[] = "https://tests-display/loading-progress.html"; // Browser side. class LoadingProgressTestHandler : public TestHandler { public: LoadingProgressTestHandler() {} void RunTest() override { // Add the resources that we will navigate to/from. AddResource(kLoadinProgressUrl, "
Content
", "text/html"); // Create the browser. CreateBrowser(kLoadinProgressUrl); // Time out the test after a reasonable period of time. SetTestTimeout(); } void OnLoadingStateChange(CefRefPtr browser, bool isLoading, bool canGoBack, bool canGoForward) override { if (isLoading) { return; } DestroyTest(); } void OnLoadingProgressChange(CefRefPtr browser, double progress) override { if (!got_loading_progress_change0_) { got_loading_progress_change0_.yes(); EXPECT_GE(progress, 0.0); } else if (!got_loading_progress_change1_) { got_loading_progress_change1_.yes(); EXPECT_LE(progress, 1.0); } } void DestroyTest() override { EXPECT_TRUE(got_loading_progress_change0_); EXPECT_TRUE(got_loading_progress_change1_); TestHandler::DestroyTest(); } private: TrackCallback got_loading_progress_change0_; TrackCallback got_loading_progress_change1_; IMPLEMENT_REFCOUNTING(LoadingProgressTestHandler); }; } // namespace // Test OnLoadingProgressChange notification. TEST(DisplayTest, LoadingProgress) { CefRefPtr handler = new LoadingProgressTestHandler(); handler->ExecuteTest(); ReleaseAndWaitForDestructor(handler); }