OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/prefs/pref_service.h" | 6 #include "base/prefs/pref_service.h" |
7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "chrome/browser/browsing_data/browsing_data_helper.h" |
| 10 #include "chrome/browser/browsing_data/browsing_data_remover.h" |
9 #include "chrome/browser/google/google_util.h" | 11 #include "chrome/browser/google/google_util.h" |
10 #include "chrome/browser/net/url_request_mock_util.h" | 12 #include "chrome/browser/net/url_request_mock_util.h" |
11 #include "chrome/browser/profiles/profile.h" | 13 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/browser/ui/browser.h" | 14 #include "chrome/browser/ui/browser.h" |
13 #include "chrome/browser/ui/browser_commands.h" | 15 #include "chrome/browser/ui/browser_commands.h" |
14 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 16 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
15 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" |
16 #include "chrome/test/base/in_process_browser_test.h" | 18 #include "chrome/test/base/in_process_browser_test.h" |
17 #include "chrome/test/base/ui_test_utils.h" | 19 #include "chrome/test/base/ui_test_utils.h" |
18 #include "content/public/browser/notification_service.h" | 20 #include "content/public/browser/notification_service.h" |
19 #include "content/public/browser/render_view_host.h" | 21 #include "content/public/browser/render_view_host.h" |
20 #include "content/public/browser/web_contents.h" | 22 #include "content/public/browser/web_contents.h" |
21 #include "content/public/browser/web_contents_observer.h" | 23 #include "content/public/browser/web_contents_observer.h" |
22 #include "content/public/test/browser_test_utils.h" | 24 #include "content/public/test/browser_test_utils.h" |
23 #include "content/public/test/test_navigation_observer.h" | 25 #include "content/public/test/test_navigation_observer.h" |
24 #include "content/test/net/url_request_failed_job.h" | 26 #include "content/test/net/url_request_failed_job.h" |
25 #include "content/test/net/url_request_mock_http_job.h" | 27 #include "content/test/net/url_request_mock_http_job.h" |
26 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
27 #include "net/base/net_util.h" | 29 #include "net/base/net_util.h" |
| 30 #include "net/http/failing_http_transaction_factory.h" |
| 31 #include "net/http/http_cache.h" |
| 32 #include "net/test/spawned_test_server/spawned_test_server.h" |
| 33 #include "net/url_request/url_request_context.h" |
| 34 #include "net/url_request/url_request_context_getter.h" |
28 #include "net/url_request/url_request_filter.h" | 35 #include "net/url_request/url_request_filter.h" |
29 #include "net/url_request/url_request_job_factory.h" | 36 #include "net/url_request/url_request_job_factory.h" |
30 | 37 |
31 using content::BrowserThread; | 38 using content::BrowserThread; |
32 using content::NavigationController; | 39 using content::NavigationController; |
33 using content::URLRequestFailedJob; | 40 using content::URLRequestFailedJob; |
34 | 41 |
35 namespace { | 42 namespace { |
36 | 43 |
37 class ErrorPageTest : public InProcessBrowserTest { | 44 class ErrorPageTest : public InProcessBrowserTest { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
75 | 82 |
76 // Navigates forward in the history and waits for |num_navigations| to occur, | 83 // Navigates forward in the history and waits for |num_navigations| to occur, |
77 // and the title to change to |expected_title|. | 84 // and the title to change to |expected_title|. |
78 void GoForwardAndWaitForTitle(const std::string& expected_title, | 85 void GoForwardAndWaitForTitle(const std::string& expected_title, |
79 int num_navigations) { | 86 int num_navigations) { |
80 NavigateHistoryAndWaitForTitle(expected_title, | 87 NavigateHistoryAndWaitForTitle(expected_title, |
81 num_navigations, | 88 num_navigations, |
82 HISTORY_NAVIGATE_FORWARD); | 89 HISTORY_NAVIGATE_FORWARD); |
83 } | 90 } |
84 | 91 |
| 92 // Confirms that the javascript variable indicating whether or not we have |
| 93 // a stale copy in the cache has been set to |expected|. |
| 94 bool ProbeStaleCopyValue(bool expected) { |
| 95 const char* js_cache_probe = |
| 96 "(function () {\n" |
| 97 " if ('staleCopyInCache' in templateData) {\n" |
| 98 " domAutomationController.send(\n" |
| 99 " templateData.staleCopyInCache ? 'yes' : 'no');\n" |
| 100 " } else {\n" |
| 101 " domAutomationController.send('absent');\n" |
| 102 " }\n" |
| 103 "})();"; |
| 104 |
| 105 std::string result; |
| 106 bool ret = |
| 107 content::ExecuteScriptAndExtractString( |
| 108 browser()->tab_strip_model()->GetActiveWebContents(), |
| 109 js_cache_probe, |
| 110 &result); |
| 111 EXPECT_TRUE(ret); |
| 112 if (!ret) |
| 113 return false; |
| 114 EXPECT_EQ(expected ? "yes" : "no", result); |
| 115 return ((expected ? "yes" : "no") == result); |
| 116 } |
| 117 |
85 protected: | 118 protected: |
86 virtual void SetUpOnMainThread() OVERRIDE { | 119 virtual void SetUpOnMainThread() OVERRIDE { |
87 BrowserThread::PostTask( | 120 BrowserThread::PostTask( |
88 BrowserThread::IO, FROM_HERE, | 121 BrowserThread::IO, FROM_HERE, |
89 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); | 122 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true)); |
90 } | 123 } |
91 | 124 |
92 // Returns a GURL that results in a DNS error. | 125 // Returns a GURL that results in a DNS error. |
93 GURL GetDnsErrorURL() const { | 126 GURL GetDnsErrorURL() const { |
94 return URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED); | 127 return URLRequestFailedJob::GetMockHttpUrl(net::ERR_NAME_NOT_RESOLVED); |
(...skipping 19 matching lines...) Expand all Loading... |
114 } else { | 147 } else { |
115 FAIL(); | 148 FAIL(); |
116 } | 149 } |
117 test_navigation_observer.Wait(); | 150 test_navigation_observer.Wait(); |
118 | 151 |
119 EXPECT_EQ(title_watcher.WaitAndGetTitle(), | 152 EXPECT_EQ(title_watcher.WaitAndGetTitle(), |
120 base::ASCIIToUTF16(expected_title)); | 153 base::ASCIIToUTF16(expected_title)); |
121 } | 154 } |
122 }; | 155 }; |
123 | 156 |
124 | |
125 class TestFailProvisionalLoadObserver : public content::WebContentsObserver { | 157 class TestFailProvisionalLoadObserver : public content::WebContentsObserver { |
126 public: | 158 public: |
127 explicit TestFailProvisionalLoadObserver(content::WebContents* contents) | 159 explicit TestFailProvisionalLoadObserver(content::WebContents* contents) |
128 : content::WebContentsObserver(contents) {} | 160 : content::WebContentsObserver(contents) {} |
129 virtual ~TestFailProvisionalLoadObserver() {} | 161 virtual ~TestFailProvisionalLoadObserver() {} |
130 | 162 |
131 // This method is invoked when the provisional load failed. | 163 // This method is invoked when the provisional load failed. |
132 virtual void DidFailProvisionalLoad( | 164 virtual void DidFailProvisionalLoad( |
133 int64 frame_id, | 165 int64 frame_id, |
134 const base::string16& frame_unique_name, | 166 const base::string16& frame_unique_name, |
135 bool is_main_frame, | 167 bool is_main_frame, |
136 const GURL& validated_url, | 168 const GURL& validated_url, |
137 int error_code, | 169 int error_code, |
138 const base::string16& error_description, | 170 const base::string16& error_description, |
139 content::RenderViewHost* render_view_host) OVERRIDE { | 171 content::RenderViewHost* render_view_host) OVERRIDE { |
140 fail_url_ = validated_url; | 172 fail_url_ = validated_url; |
141 } | 173 } |
142 | 174 |
143 const GURL& fail_url() const { return fail_url_; } | 175 const GURL& fail_url() const { return fail_url_; } |
144 | 176 |
145 private: | 177 private: |
146 GURL fail_url_; | 178 GURL fail_url_; |
147 | 179 |
148 DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver); | 180 DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver); |
149 }; | 181 }; |
150 | 182 |
| 183 void InterceptNetworkTransactions(net::URLRequestContextGetter* getter, |
| 184 net::Error error) { |
| 185 DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); |
| 186 net::HttpCache* cache( |
| 187 getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); |
| 188 DCHECK(cache); |
| 189 scoped_ptr<net::HttpTransactionFactory> factory( |
| 190 new net::FailingHttpTransactionFactory(cache->GetSession(), error)); |
| 191 // Throw away old version; since this is a a browser test, we don't |
| 192 // need to restore the old state. |
| 193 cache->SetHttpNetworkTransactionFactoryForTesting(factory.Pass()); |
| 194 } |
| 195 |
151 // See crbug.com/109669 | 196 // See crbug.com/109669 |
152 #if defined(USE_AURA) || defined(OS_WIN) | 197 #if defined(USE_AURA) || defined(OS_WIN) |
153 #define MAYBE_DNSError_Basic DISABLED_DNSError_Basic | 198 #define MAYBE_DNSError_Basic DISABLED_DNSError_Basic |
154 #else | 199 #else |
155 #define MAYBE_DNSError_Basic DNSError_Basic | 200 #define MAYBE_DNSError_Basic DNSError_Basic |
156 #endif | 201 #endif |
157 // Test that a DNS error occuring in the main frame redirects to an error page. | 202 // Test that a DNS error occuring in the main frame redirects to an error page. |
158 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_DNSError_Basic) { | 203 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_DNSError_Basic) { |
159 // The first navigation should fail, and the second one should be the error | 204 // The first navigation should fail, and the second one should be the error |
160 // page. | 205 // page. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 | 394 |
350 // Checks that the Link Doctor is not loaded when we receive an actual 404 page. | 395 // Checks that the Link Doctor is not loaded when we receive an actual 404 page. |
351 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) { | 396 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) { |
352 NavigateToURLAndWaitForTitle( | 397 NavigateToURLAndWaitForTitle( |
353 content::URLRequestMockHTTPJob::GetMockUrl( | 398 content::URLRequestMockHTTPJob::GetMockUrl( |
354 base::FilePath(FILE_PATH_LITERAL("page404.html"))), | 399 base::FilePath(FILE_PATH_LITERAL("page404.html"))), |
355 "SUCCESS", | 400 "SUCCESS", |
356 1); | 401 1); |
357 } | 402 } |
358 | 403 |
| 404 // Checks that when an error occurs, the stale cache status of the page |
| 405 // is correctly transferred. |
| 406 IN_PROC_BROWSER_TEST_F(ErrorPageTest, StaleCacheStatus) { |
| 407 ASSERT_TRUE(test_server()->Start()); |
| 408 // Load cache with entry with "nocache" set, to create stale |
| 409 // cache. |
| 410 GURL test_url(test_server()->GetURL("files/nocache.html")); |
| 411 NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1); |
| 412 |
| 413 // Reload same URL after forcing an error from the the network layer; |
| 414 // confirm that the error page is told the cached copy exists. |
| 415 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
| 416 browser()->profile()->GetRequestContext(); |
| 417 BrowserThread::PostTask( |
| 418 BrowserThread::IO, FROM_HERE, |
| 419 base::Bind(&InterceptNetworkTransactions, url_request_context_getter, |
| 420 // Note that we can't use an error that'll invoke the link |
| 421 // doctor. In normal network error conditions that would |
| 422 // work (because the link doctor fetch would also fail, |
| 423 // putting us back in the main offline path), but |
| 424 // SetUrlRequestMocksEnabled() has also specfied a link |
| 425 // doctor mock, which will be accessible because it |
| 426 // won't go through the network cache. |
| 427 net::ERR_FAILED)); |
| 428 |
| 429 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( |
| 430 // With no link doctor load, there's only one navigation. |
| 431 browser(), test_url, 1); |
| 432 EXPECT_TRUE(ProbeStaleCopyValue(true)); |
| 433 |
| 434 // Clear the cache and reload the same URL; confirm the error page is told |
| 435 // that there is no cached copy. |
| 436 BrowsingDataRemover* remover = |
| 437 BrowsingDataRemover::CreateForUnboundedRange(browser()->profile()); |
| 438 remover->Remove(BrowsingDataRemover::REMOVE_CACHE, |
| 439 BrowsingDataHelper::UNPROTECTED_WEB); |
| 440 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( |
| 441 browser(), test_url, 1); |
| 442 EXPECT_TRUE(ProbeStaleCopyValue(false)); |
| 443 } |
| 444 |
359 // Returns Javascript code that executes plain text search for the page. | 445 // Returns Javascript code that executes plain text search for the page. |
360 // Pass into content::ExecuteScriptAndExtractBool as |script| parameter. | 446 // Pass into content::ExecuteScriptAndExtractBool as |script| parameter. |
361 std::string GetTextContentContainsStringScript( | 447 std::string GetTextContentContainsStringScript( |
362 const std::string& value_to_search) { | 448 const std::string& value_to_search) { |
363 return base::StringPrintf( | 449 return base::StringPrintf( |
364 "var textContent = document.body.textContent;" | 450 "var textContent = document.body.textContent;" |
365 "var hasError = textContent.indexOf('%s') >= 0;" | 451 "var hasError = textContent.indexOf('%s') >= 0;" |
366 "domAutomationController.send(hasError);", | 452 "domAutomationController.send(hasError);", |
367 value_to_search.c_str()); | 453 value_to_search.c_str()); |
368 } | 454 } |
(...skipping 15 matching lines...) Expand all Loading... |
384 } | 470 } |
385 | 471 |
386 private: | 472 private: |
387 DISALLOW_COPY_AND_ASSIGN(AddressUnreachableProtocolHandler); | 473 DISALLOW_COPY_AND_ASSIGN(AddressUnreachableProtocolHandler); |
388 }; | 474 }; |
389 | 475 |
390 // A test fixture that returns ERR_ADDRESS_UNREACHABLE for all Link Doctor | 476 // A test fixture that returns ERR_ADDRESS_UNREACHABLE for all Link Doctor |
391 // requests. ERR_NAME_NOT_RESOLVED is more typical, but need to use a different | 477 // requests. ERR_NAME_NOT_RESOLVED is more typical, but need to use a different |
392 // error for the Link Doctor and the original page to validate the right page | 478 // error for the Link Doctor and the original page to validate the right page |
393 // is being displayed. | 479 // is being displayed. |
394 class ErrorPageLinkDoctorFailTest : public InProcessBrowserTest { | 480 class ErrorPageLinkDoctorFailTest : public ErrorPageTest { |
395 public: | 481 public: |
396 // InProcessBrowserTest: | 482 // InProcessBrowserTest: |
397 virtual void SetUpOnMainThread() OVERRIDE { | 483 virtual void SetUpOnMainThread() OVERRIDE { |
398 BrowserThread::PostTask( | 484 BrowserThread::PostTask( |
399 BrowserThread::IO, FROM_HERE, | 485 BrowserThread::IO, FROM_HERE, |
400 base::Bind(&ErrorPageLinkDoctorFailTest::AddFilters)); | 486 base::Bind(&ErrorPageLinkDoctorFailTest::AddFilters)); |
401 } | 487 } |
402 | 488 |
403 virtual void CleanUpOnMainThread() OVERRIDE { | 489 virtual void CleanUpOnMainThread() OVERRIDE { |
404 BrowserThread::PostTask( | 490 BrowserThread::PostTask( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 // Verify that the expected error page is being displayed. Do this by making | 526 // Verify that the expected error page is being displayed. Do this by making |
441 // sure the original error code (ERR_NAME_NOT_RESOLVED) is displayed. | 527 // sure the original error code (ERR_NAME_NOT_RESOLVED) is displayed. |
442 bool result = false; | 528 bool result = false; |
443 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | 529 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
444 browser()->tab_strip_model()->GetActiveWebContents(), | 530 browser()->tab_strip_model()->GetActiveWebContents(), |
445 GetTextContentContainsStringScript("ERR_NAME_NOT_RESOLVED"), | 531 GetTextContentContainsStringScript("ERR_NAME_NOT_RESOLVED"), |
446 &result)); | 532 &result)); |
447 EXPECT_TRUE(result); | 533 EXPECT_TRUE(result); |
448 } | 534 } |
449 | 535 |
| 536 // Checks that when an error occurs and a link doctor load fails, the stale |
| 537 // cache status of the page is correctly transferred. Most logic copied |
| 538 // from StaleCacheStatus above. |
| 539 IN_PROC_BROWSER_TEST_F(ErrorPageLinkDoctorFailTest, |
| 540 StaleCacheStatusFailedLinkDoctor) { |
| 541 ASSERT_TRUE(test_server()->Start()); |
| 542 // Load cache with entry with "nocache" set, to create stale |
| 543 // cache. |
| 544 GURL test_url(test_server()->GetURL("files/nocache.html")); |
| 545 NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1); |
| 546 |
| 547 // Reload same URL after forcing an error from the the network layer; |
| 548 // confirm that the error page is told the cached copy exists. |
| 549 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = |
| 550 browser()->profile()->GetRequestContext(); |
| 551 BrowserThread::PostTask( |
| 552 BrowserThread::IO, FROM_HERE, |
| 553 base::Bind(&InterceptNetworkTransactions, url_request_context_getter, |
| 554 net::ERR_CONNECTION_FAILED)); |
| 555 |
| 556 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( |
| 557 browser(), test_url, 2); |
| 558 ProbeStaleCopyValue(true); |
| 559 |
| 560 // Clear the cache and reload the same URL; confirm the error page is told |
| 561 // that there is no cached copy. |
| 562 BrowsingDataRemover* remover = |
| 563 BrowsingDataRemover::CreateForUnboundedRange(browser()->profile()); |
| 564 remover->Remove(BrowsingDataRemover::REMOVE_CACHE, |
| 565 BrowsingDataHelper::UNPROTECTED_WEB); |
| 566 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( |
| 567 browser(), test_url, 2); |
| 568 ProbeStaleCopyValue(false); |
| 569 } |
| 570 |
450 // A test fixture that simulates failing requests for an IDN domain name. | 571 // A test fixture that simulates failing requests for an IDN domain name. |
451 class ErrorPageForIDNTest : public InProcessBrowserTest { | 572 class ErrorPageForIDNTest : public InProcessBrowserTest { |
452 public: | 573 public: |
453 // Target hostname in different forms. | 574 // Target hostname in different forms. |
454 static const char kHostname[]; | 575 static const char kHostname[]; |
455 static const char kHostnameJSUnicode[]; | 576 static const char kHostnameJSUnicode[]; |
456 | 577 |
457 // InProcessBrowserTest: | 578 // InProcessBrowserTest: |
458 virtual void SetUpOnMainThread() OVERRIDE { | 579 virtual void SetUpOnMainThread() OVERRIDE { |
459 // Clear AcceptLanguages to force punycode decoding. | 580 // Clear AcceptLanguages to force punycode decoding. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
499 | 620 |
500 bool result = false; | 621 bool result = false; |
501 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | 622 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
502 browser()->tab_strip_model()->GetActiveWebContents(), | 623 browser()->tab_strip_model()->GetActiveWebContents(), |
503 GetTextContentContainsStringScript(kHostnameJSUnicode), | 624 GetTextContentContainsStringScript(kHostnameJSUnicode), |
504 &result)); | 625 &result)); |
505 EXPECT_TRUE(result); | 626 EXPECT_TRUE(result); |
506 } | 627 } |
507 | 628 |
508 } // namespace | 629 } // namespace |
OLD | NEW |