- Added search icon and search clear button in 1x and 2x. Screenshot: http://i.imgur...
[chromium-blink-merge.git] / chrome / browser / errorpage_browsertest.cc
blob98b9f16d8495183b88f557a9a2e6c4463e526213
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/bind.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/google/google_util.h"
8 #include "chrome/browser/net/url_request_mock_util.h"
9 #include "chrome/browser/ui/browser.h"
10 #include "chrome/browser/ui/browser_commands.h"
11 #include "chrome/browser/ui/tabs/tab_strip_model.h"
12 #include "chrome/test/base/in_process_browser_test.h"
13 #include "chrome/test/base/ui_test_utils.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/test/browser_test_utils.h"
16 #include "content/public/test/test_navigation_observer.h"
17 #include "content/test/net/url_request_failed_job.h"
18 #include "content/test/net/url_request_mock_http_job.h"
19 #include "net/base/net_errors.h"
20 #include "net/url_request/url_request_filter.h"
21 #include "net/url_request/url_request_job_factory.h"
23 using content::BrowserThread;
24 using content::NavigationController;
25 using content::URLRequestFailedJob;
27 namespace {
29 class ErrorPageTest : public InProcessBrowserTest {
30 public:
31 enum HistoryNavigationDirection {
32 HISTORY_NAVIGATE_BACK,
33 HISTORY_NAVIGATE_FORWARD,
36 // Navigates the active tab to a mock url created for the file at |file_path|.
37 void NavigateToFileURL(const base::FilePath::StringType& file_path) {
38 ui_test_utils::NavigateToURL(
39 browser(),
40 content::URLRequestMockHTTPJob::GetMockUrl(base::FilePath(file_path)));
43 // Navigates to the given URL and waits for |num_navigations| to occur, and
44 // the title to change to |expected_title|.
45 void NavigateToURLAndWaitForTitle(const GURL& url,
46 const std::string& expected_title,
47 int num_navigations) {
48 content::TitleWatcher title_watcher(
49 browser()->tab_strip_model()->GetActiveWebContents(),
50 ASCIIToUTF16(expected_title));
52 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
53 browser(), url, num_navigations);
55 EXPECT_EQ(ASCIIToUTF16(expected_title), title_watcher.WaitAndGetTitle());
58 // Navigates back in the history and waits for |num_navigations| to occur, and
59 // the title to change to |expected_title|.
60 void GoBackAndWaitForTitle(const std::string& expected_title,
61 int num_navigations) {
62 NavigateHistoryAndWaitForTitle(expected_title,
63 num_navigations,
64 HISTORY_NAVIGATE_BACK);
67 // Navigates forward in the history and waits for |num_navigations| to occur,
68 // and the title to change to |expected_title|.
69 void GoForwardAndWaitForTitle(const std::string& expected_title,
70 int num_navigations) {
71 NavigateHistoryAndWaitForTitle(expected_title,
72 num_navigations,
73 HISTORY_NAVIGATE_FORWARD);
76 protected:
77 virtual void SetUpOnMainThread() OVERRIDE {
78 BrowserThread::PostTask(
79 BrowserThread::IO, FROM_HERE,
80 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
83 // Returns a GURL that results in a DNS error.
84 GURL GetDnsErrorURL() const {
85 return URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED);
88 private:
89 // Navigates the browser the indicated direction in the history and waits for
90 // |num_navigations| to occur and the title to change to |expected_title|.
91 void NavigateHistoryAndWaitForTitle(const std::string& expected_title,
92 int num_navigations,
93 HistoryNavigationDirection direction) {
94 content::TitleWatcher title_watcher(
95 browser()->tab_strip_model()->GetActiveWebContents(),
96 ASCIIToUTF16(expected_title));
98 content::TestNavigationObserver test_navigation_observer(
99 browser()->tab_strip_model()->GetActiveWebContents(),
100 num_navigations);
101 if (direction == HISTORY_NAVIGATE_BACK) {
102 chrome::GoBack(browser(), CURRENT_TAB);
103 } else if (direction == HISTORY_NAVIGATE_FORWARD) {
104 chrome::GoForward(browser(), CURRENT_TAB);
105 } else {
106 FAIL();
108 test_navigation_observer.WaitForObservation(
109 base::Bind(&content::RunMessageLoop),
110 base::Bind(&base::MessageLoop::Quit,
111 base::Unretained(base::MessageLoopForUI::current())));
113 EXPECT_EQ(title_watcher.WaitAndGetTitle(), ASCIIToUTF16(expected_title));
117 // See crbug.com/109669
118 #if defined(USE_AURA) || defined(OS_WIN)
119 #define MAYBE_DNSError_Basic DISABLED_DNSError_Basic
120 #else
121 #define MAYBE_DNSError_Basic DNSError_Basic
122 #endif
123 // Test that a DNS error occuring in the main frame redirects to an error page.
124 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_DNSError_Basic) {
125 // The first navigation should fail, and the second one should be the error
126 // page.
127 NavigateToURLAndWaitForTitle(GetDnsErrorURL(), "Mock Link Doctor", 2);
130 // See crbug.com/109669
131 #if defined(USE_AURA)
132 #define MAYBE_DNSError_GoBack1 DISABLED_DNSError_GoBack1
133 #else
134 #define MAYBE_DNSError_GoBack1 DNSError_GoBack1
135 #endif
137 // Test that a DNS error occuring in the main frame does not result in an
138 // additional session history entry.
139 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_DNSError_GoBack1) {
140 NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
141 NavigateToURLAndWaitForTitle(GetDnsErrorURL(), "Mock Link Doctor", 2);
142 GoBackAndWaitForTitle("Title Of Awesomeness", 1);
145 // See crbug.com/109669
146 #if defined(USE_AURA)
147 #define MAYBE_DNSError_GoBack2 DISABLED_DNSError_GoBack2
148 #else
149 #define MAYBE_DNSError_GoBack2 DNSError_GoBack2
150 #endif
151 // Test that a DNS error occuring in the main frame does not result in an
152 // additional session history entry.
153 IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_GoBack2) {
154 NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
156 NavigateToURLAndWaitForTitle(GetDnsErrorURL(), "Mock Link Doctor", 2);
157 NavigateToFileURL(FILE_PATH_LITERAL("title3.html"));
159 GoBackAndWaitForTitle("Mock Link Doctor", 2);
160 GoBackAndWaitForTitle("Title Of Awesomeness", 1);
163 // See crbug.com/109669
164 #if defined(USE_AURA)
165 #define MAYBE_DNSError_GoBack2AndForward DISABLED_DNSError_GoBack2AndForward
166 #else
167 #define MAYBE_DNSError_GoBack2AndForward DNSError_GoBack2AndForward
168 #endif
169 // Test that a DNS error occuring in the main frame does not result in an
170 // additional session history entry.
171 IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_GoBack2AndForward) {
172 NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
174 NavigateToURLAndWaitForTitle(GetDnsErrorURL(), "Mock Link Doctor", 2);
175 NavigateToFileURL(FILE_PATH_LITERAL("title3.html"));
177 GoBackAndWaitForTitle("Mock Link Doctor", 2);
178 GoBackAndWaitForTitle("Title Of Awesomeness", 1);
180 GoForwardAndWaitForTitle("Mock Link Doctor", 2);
183 // See crbug.com/109669
184 #if defined(USE_AURA)
185 #define MAYBE_DNSError_GoBack2Forward2 DISABLED_DNSError_GoBack2Forward2
186 #else
187 #define MAYBE_DNSError_GoBack2Forward2 DNSError_GoBack2Forward2
188 #endif
189 // Test that a DNS error occuring in the main frame does not result in an
190 // additional session history entry.
191 IN_PROC_BROWSER_TEST_F(ErrorPageTest, DNSError_GoBack2Forward2) {
192 NavigateToFileURL(FILE_PATH_LITERAL("title3.html"));
194 NavigateToURLAndWaitForTitle(GetDnsErrorURL(), "Mock Link Doctor", 2);
195 NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
197 GoBackAndWaitForTitle("Mock Link Doctor", 2);
198 GoBackAndWaitForTitle("Title Of More Awesomeness", 1);
200 GoForwardAndWaitForTitle("Mock Link Doctor", 2);
201 GoForwardAndWaitForTitle("Title Of Awesomeness", 1);
204 // Test that a DNS error occuring in an iframe.
205 IN_PROC_BROWSER_TEST_F(ErrorPageTest, IFrameDNSError_Basic) {
206 NavigateToURLAndWaitForTitle(
207 content::URLRequestMockHTTPJob::GetMockUrl(
208 base::FilePath(FILE_PATH_LITERAL("iframe_dns_error.html"))),
209 "Blah",
213 // This test fails regularly on win_rel trybots. See crbug.com/121540
214 #if defined(OS_WIN)
215 #define MAYBE_IFrameDNSError_GoBack DISABLED_IFrameDNSError_GoBack
216 #else
217 #define MAYBE_IFrameDNSError_GoBack IFrameDNSError_GoBack
218 #endif
219 // Test that a DNS error occuring in an iframe does not result in an
220 // additional session history entry.
221 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_IFrameDNSError_GoBack) {
222 NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
223 NavigateToFileURL(FILE_PATH_LITERAL("iframe_dns_error.html"));
224 GoBackAndWaitForTitle("Title Of Awesomeness", 1);
227 // This test fails regularly on win_rel trybots. See crbug.com/121540
228 #if defined(OS_WIN)
229 #define MAYBE_IFrameDNSError_GoBackAndForward DISABLED_IFrameDNSError_GoBackAndForward
230 #else
231 #define MAYBE_IFrameDNSError_GoBackAndForward IFrameDNSError_GoBackAndForward
232 #endif
233 // Test that a DNS error occuring in an iframe does not result in an
234 // additional session history entry.
235 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_IFrameDNSError_GoBackAndForward) {
236 NavigateToFileURL(FILE_PATH_LITERAL("title2.html"));
237 NavigateToFileURL(FILE_PATH_LITERAL("iframe_dns_error.html"));
238 GoBackAndWaitForTitle("Title Of Awesomeness", 1);
239 GoForwardAndWaitForTitle("Blah", 1);
242 // Checks that the Link Doctor is not loaded when we receive an actual 404 page.
243 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) {
244 NavigateToURLAndWaitForTitle(
245 content::URLRequestMockHTTPJob::GetMockUrl(
246 base::FilePath(FILE_PATH_LITERAL("page404.html"))),
247 "SUCCESS",
251 // Protocol handler that fails all requests with net::ERR_ADDRESS_UNREACHABLE.
252 class AddressUnreachableProtocolHandler
253 : public net::URLRequestJobFactory::ProtocolHandler {
254 public:
255 AddressUnreachableProtocolHandler() {}
256 virtual ~AddressUnreachableProtocolHandler() {}
258 // net::URLRequestJobFactory::ProtocolHandler:
259 virtual net::URLRequestJob* MaybeCreateJob(
260 net::URLRequest* request,
261 net::NetworkDelegate* network_delegate) const OVERRIDE {
262 return new URLRequestFailedJob(request,
263 network_delegate,
264 net::ERR_ADDRESS_UNREACHABLE);
267 private:
268 DISALLOW_COPY_AND_ASSIGN(AddressUnreachableProtocolHandler);
271 // A test fixture that returns ERR_ADDRESS_UNREACHABLE for all Link Doctor
272 // requests. ERR_NAME_NOT_RESOLVED is more typical, but need to use a different
273 // error for the Link Doctor and the original page to validate the right page
274 // is being displayed.
275 class ErrorPageLinkDoctorFailTest : public InProcessBrowserTest {
276 public:
277 // InProcessBrowserTest:
278 virtual void SetUpOnMainThread() OVERRIDE {
279 BrowserThread::PostTask(
280 BrowserThread::IO, FROM_HERE,
281 base::Bind(&ErrorPageLinkDoctorFailTest::AddFilters));
284 virtual void CleanUpOnMainThread() OVERRIDE {
285 BrowserThread::PostTask(
286 BrowserThread::IO, FROM_HERE,
287 base::Bind(&ErrorPageLinkDoctorFailTest::RemoveFilters));
290 private:
291 // Adds a filter that causes all requests for the Link Doctor's scheme and
292 // host to fail with ERR_ADDRESS_UNREACHABLE. Since the Link Doctor adds
293 // query strings, it's not enough to just fail exact matches.
295 // Also adds the content::URLRequestFailedJob filter.
296 static void AddFilters() {
297 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
298 content::URLRequestFailedJob::AddUrlHandler();
300 net::URLRequestFilter::GetInstance()->AddHostnameProtocolHandler(
301 google_util::LinkDoctorBaseURL().scheme(),
302 google_util::LinkDoctorBaseURL().host(),
303 scoped_ptr<net::URLRequestJobFactory::ProtocolHandler>(
304 new AddressUnreachableProtocolHandler()));
307 static void RemoveFilters() {
308 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
309 net::URLRequestFilter::GetInstance()->ClearHandlers();
313 // Make sure that when the Link Doctor fails to load, the network error page is
314 // successfully loaded.
315 IN_PROC_BROWSER_TEST_F(ErrorPageLinkDoctorFailTest, LinkDoctorFail) {
316 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
317 browser(),
318 URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED),
321 // Verify that the expected error page is being displayed. Do this by making
322 // sure the original error code (ERR_NAME_NOT_RESOLVED) is displayed.
323 bool result = false;
324 EXPECT_TRUE(content::ExecuteScriptAndExtractBool(
325 browser()->tab_strip_model()->GetActiveWebContents(),
326 "var textContent = document.body.textContent;"
327 "var hasError = textContent.indexOf('ERR_NAME_NOT_RESOLVED') >= 0;"
328 "domAutomationController.send(hasError);",
329 &result));
330 EXPECT_TRUE(result);
333 } // namespace