1 // Copyright 2016 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 <algorithm>
6 #include <memory>
7
8 #include "include/base/cef_callback.h"
9 #include "include/cef_callback.h"
10 #include "include/cef_parser.h"
11 #include "include/wrapper/cef_closure_task.h"
12 #include "tests/ceftests/test_handler.h"
13 #include "tests/gtest/include/gtest/gtest.h"
14
15 namespace {
16
17 typedef std::vector<std::string> UrlList;
18
19 class WebUITestHandler : public TestHandler {
20 public:
WebUITestHandler(const UrlList & url_list)21 explicit WebUITestHandler(const UrlList& url_list)
22 : url_list_(url_list), url_index_(0U), expected_error_code_(ERR_NONE) {
23 CHECK(!url_list_.empty());
24 }
25
set_expected_url(const std::string & expected_url)26 void set_expected_url(const std::string& expected_url) {
27 expected_url_ = expected_url;
28 }
29
set_expected_error_code(int error_code)30 void set_expected_error_code(int error_code) {
31 expected_error_code_ = error_code;
32 }
33
RunTest()34 void RunTest() override {
35 // Create the browser.
36 CreateBrowser(url_list_[0]);
37
38 // Time out the test after a reasonable period of time.
39 SetTestTimeout((int(url_list_.size() / 5U) + 1) * 5000);
40 }
41
NextNav()42 void NextNav() {
43 base::OnceClosure next_action;
44
45 if (++url_index_ < url_list_.size()) {
46 next_action = base::BindOnce(&WebUITestHandler::LoadURL, this,
47 url_list_[url_index_]);
48 } else {
49 next_action = base::BindOnce(&WebUITestHandler::DestroyTest, this);
50 }
51
52 // Wait a bit for the WebUI content to finish loading before performing the
53 // next action.
54 CefPostDelayedTask(TID_UI, std::move(next_action), 200);
55 }
56
LoadURL(const std::string & url)57 void LoadURL(const std::string& url) {
58 GetBrowser()->GetMainFrame()->LoadURL(url);
59 }
60
OnLoadingStateChange(CefRefPtr<CefBrowser> browser,bool isLoading,bool canGoBack,bool canGoForward)61 void OnLoadingStateChange(CefRefPtr<CefBrowser> browser,
62 bool isLoading,
63 bool canGoBack,
64 bool canGoForward) override {
65 if (!isLoading) {
66 got_loading_state_done_.yes();
67 NextNavIfDone(browser->GetMainFrame()->GetURL());
68 }
69 }
70
OnLoadError(CefRefPtr<CefBrowser> browser,CefRefPtr<CefFrame> frame,ErrorCode errorCode,const CefString & errorText,const CefString & failedUrl)71 void OnLoadError(CefRefPtr<CefBrowser> browser,
72 CefRefPtr<CefFrame> frame,
73 ErrorCode errorCode,
74 const CefString& errorText,
75 const CefString& failedUrl) override {
76 got_load_error_.yes();
77 EXPECT_EQ(expected_error_code_, errorCode)
78 << "failedUrl = " << failedUrl.ToString();
79 NextNavIfDone(failedUrl);
80 }
81
DestroyTest()82 void DestroyTest() override {
83 EXPECT_TRUE(got_loading_state_done_);
84 if (expected_error_code_ == ERR_NONE)
85 EXPECT_FALSE(got_load_error_);
86 else
87 EXPECT_TRUE(got_load_error_);
88
89 TestHandler::DestroyTest();
90 }
91
92 private:
NextNavIfDone(const std::string & url)93 void NextNavIfDone(const std::string& url) {
94 bool done = false;
95 if (expected_error_code_ == ERR_NONE) {
96 if (got_loading_state_done_)
97 done = true;
98 } else if (got_load_error_ && got_loading_state_done_) {
99 done = true;
100 }
101
102 if (done) {
103 // Verify that we navigated to the expected URL.
104 std::string expected_url = expected_url_;
105 if (expected_url.empty() && url_index_ < url_list_.size())
106 expected_url = url_list_[url_index_];
107 EXPECT_STREQ(expected_url.c_str(), url.c_str());
108
109 NextNav();
110 }
111 }
112
113 UrlList url_list_;
114 size_t url_index_;
115
116 std::string expected_url_;
117 int expected_error_code_;
118
119 TrackCallback got_loading_state_done_;
120 TrackCallback got_load_error_;
121
122 IMPLEMENT_REFCOUNTING(WebUITestHandler);
123 };
124
125 } // namespace
126
127 // Test hosts with special behaviors.
128
129 // about:* URIs should redirect to chrome://*.
TEST(WebUITest,about)130 TEST(WebUITest, about) {
131 UrlList url_list;
132 url_list.push_back("about:license");
133 CefRefPtr<WebUITestHandler> handler = new WebUITestHandler(url_list);
134 handler->set_expected_url("chrome://license/");
135 handler->ExecuteTest();
136 ReleaseAndWaitForDestructor(handler);
137 }
138
139 // chrome://network-error/X should generate network error X.
TEST(WebUITest,network_error)140 TEST(WebUITest, network_error) {
141 UrlList url_list;
142 // -310 is ERR_TOO_MANY_REDIRECTS
143 url_list.push_back("chrome://network-error/-310");
144 CefRefPtr<WebUITestHandler> handler = new WebUITestHandler(url_list);
145 handler->set_expected_error_code(ERR_TOO_MANY_REDIRECTS);
146 handler->ExecuteTest();
147 ReleaseAndWaitForDestructor(handler);
148 }
149
150 // Test hosts with a single URL.
151
152 namespace {
153
RunWebUITest(const UrlList & url_list)154 void RunWebUITest(const UrlList& url_list) {
155 CefRefPtr<WebUITestHandler> handler = new WebUITestHandler(url_list);
156 handler->ExecuteTest();
157 ReleaseAndWaitForDestructor(handler);
158 }
159
RunWebUITest(const std::string & url)160 void RunWebUITest(const std::string& url) {
161 UrlList url_list;
162 url_list.push_back(url);
163 RunWebUITest(url_list);
164 }
165
166 } // namespace
167
168 #define WEBUI_TEST(name) \
169 TEST(WebUITest, name) { \
170 std::string name_str = #name; \
171 std::replace(name_str.begin(), name_str.end(), '_', '-'); \
172 RunWebUITest("chrome://" + name_str + "/"); \
173 }
174
175 WEBUI_TEST(accessibility)
WEBUI_TEST(blob_internals)176 WEBUI_TEST(blob_internals)
177 WEBUI_TEST(extensions_support)
178 WEBUI_TEST(gpu)
179 WEBUI_TEST(histograms)
180 WEBUI_TEST(indexeddb_internals)
181 WEBUI_TEST(license)
182 WEBUI_TEST(media_internals)
183 WEBUI_TEST(net_export)
184 WEBUI_TEST(network_errors)
185 WEBUI_TEST(serviceworker_internals)
186 WEBUI_TEST(system)
187 WEBUI_TEST(tracing)
188 WEBUI_TEST(version)
189 WEBUI_TEST(webrtc_internals)
190 WEBUI_TEST(webui_hosts)
191
192 // Test hosts with multiple URLs.
193
194 TEST(WebUITest, net_internals) {
195 UrlList url_list;
196 url_list.push_back("chrome://net-internals/#events");
197 url_list.push_back("chrome://net-internals/#proxy");
198 url_list.push_back("chrome://net-internals/#dns");
199 url_list.push_back("chrome://net-internals/#sockets");
200 url_list.push_back("chrome://net-internals/#hsts");
201
202 RunWebUITest(url_list);
203 }
204