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 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
114 } else { | 121 } else { |
115 FAIL(); | 122 FAIL(); |
116 } | 123 } |
117 test_navigation_observer.Wait(); | 124 test_navigation_observer.Wait(); |
118 | 125 |
119 EXPECT_EQ(title_watcher.WaitAndGetTitle(), | 126 EXPECT_EQ(title_watcher.WaitAndGetTitle(), |
120 base::ASCIIToUTF16(expected_title)); | 127 base::ASCIIToUTF16(expected_title)); |
121 } | 128 } |
122 }; | 129 }; |
123 | 130 |
124 | |
125 class TestFailProvisionalLoadObserver : public content::WebContentsObserver { | 131 class TestFailProvisionalLoadObserver : public content::WebContentsObserver { |
126 public: | 132 public: |
127 explicit TestFailProvisionalLoadObserver(content::WebContents* contents) | 133 explicit TestFailProvisionalLoadObserver(content::WebContents* contents) |
128 : content::WebContentsObserver(contents) {} | 134 : content::WebContentsObserver(contents) {} |
129 virtual ~TestFailProvisionalLoadObserver() {} | 135 virtual ~TestFailProvisionalLoadObserver() {} |
130 | 136 |
131 // This method is invoked when the provisional load failed. | 137 // This method is invoked when the provisional load failed. |
132 virtual void DidFailProvisionalLoad( | 138 virtual void DidFailProvisionalLoad( |
133 int64 frame_id, | 139 int64 frame_id, |
134 const base::string16& frame_unique_name, | 140 const base::string16& frame_unique_name, |
135 bool is_main_frame, | 141 bool is_main_frame, |
136 const GURL& validated_url, | 142 const GURL& validated_url, |
137 int error_code, | 143 int error_code, |
138 const base::string16& error_description, | 144 const base::string16& error_description, |
139 content::RenderViewHost* render_view_host) OVERRIDE { | 145 content::RenderViewHost* render_view_host) OVERRIDE { |
140 fail_url_ = validated_url; | 146 fail_url_ = validated_url; |
141 } | 147 } |
142 | 148 |
143 const GURL& fail_url() const { return fail_url_; } | 149 const GURL& fail_url() const { return fail_url_; } |
144 | 150 |
145 private: | 151 private: |
146 GURL fail_url_; | 152 GURL fail_url_; |
147 | 153 |
148 DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver); | 154 DISALLOW_COPY_AND_ASSIGN(TestFailProvisionalLoadObserver); |
149 }; | 155 }; |
150 | 156 |
157 void InterceptNetworkTransactions(net::URLRequestContextGetter* getter, | |
158 net::Error error) { | |
159 DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
160 net::HttpCache* cache( | |
161 getter->GetURLRequestContext()->http_transaction_factory()->GetCache()); | |
162 DCHECK(cache); | |
163 scoped_ptr<net::FailingHttpTransactionFactory> factory( | |
mmenke
2014/01/28 17:27:23
nit: Can just make this a HttpTransactionFactory,
Randy Smith (Not in Mondays)
2014/01/28 22:52:59
Done.
| |
164 new net::FailingHttpTransactionFactory(cache->GetSession(), error)); | |
165 // Throw away old version; since we're a browser test, we don't | |
166 // need to restore the old state. | |
mmenke
2014/01/28 17:27:23
nit: Don't use "we" in comments.
Randy Smith (Not in Mondays)
2014/01/28 22:52:59
Done.
| |
167 cache->SetHttpNetworkTransactionFactoryForTesting( | |
168 factory.PassAs<net::HttpTransactionFactory>()); | |
169 } | |
170 | |
151 // See crbug.com/109669 | 171 // See crbug.com/109669 |
152 #if defined(USE_AURA) || defined(OS_WIN) | 172 #if defined(USE_AURA) || defined(OS_WIN) |
153 #define MAYBE_DNSError_Basic DISABLED_DNSError_Basic | 173 #define MAYBE_DNSError_Basic DISABLED_DNSError_Basic |
154 #else | 174 #else |
155 #define MAYBE_DNSError_Basic DNSError_Basic | 175 #define MAYBE_DNSError_Basic DNSError_Basic |
156 #endif | 176 #endif |
157 // Test that a DNS error occuring in the main frame redirects to an error page. | 177 // 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) { | 178 IN_PROC_BROWSER_TEST_F(ErrorPageTest, MAYBE_DNSError_Basic) { |
159 // The first navigation should fail, and the second one should be the error | 179 // The first navigation should fail, and the second one should be the error |
160 // page. | 180 // page. |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
349 | 369 |
350 // Checks that the Link Doctor is not loaded when we receive an actual 404 page. | 370 // Checks that the Link Doctor is not loaded when we receive an actual 404 page. |
351 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) { | 371 IN_PROC_BROWSER_TEST_F(ErrorPageTest, Page404) { |
352 NavigateToURLAndWaitForTitle( | 372 NavigateToURLAndWaitForTitle( |
353 content::URLRequestMockHTTPJob::GetMockUrl( | 373 content::URLRequestMockHTTPJob::GetMockUrl( |
354 base::FilePath(FILE_PATH_LITERAL("page404.html"))), | 374 base::FilePath(FILE_PATH_LITERAL("page404.html"))), |
355 "SUCCESS", | 375 "SUCCESS", |
356 1); | 376 1); |
357 } | 377 } |
358 | 378 |
379 // Checks that when an error occurs, the stale cache status of the page | |
380 // is correctly transferred. | |
381 IN_PROC_BROWSER_TEST_F(ErrorPageTest, StaleCacheStatus) { | |
382 ASSERT_TRUE(test_server()->Start()); | |
383 // Load cache with entry with "nocache" set, to create stale | |
384 // cache. | |
385 GURL test_url(test_server()->GetURL("files/nocache.html")); | |
386 NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1); | |
387 | |
388 // Reload same URL after forcing an error from the the network layer; | |
389 // confirm that the error page is told the cached copy exists. | |
390 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = | |
391 browser()->profile()->GetRequestContext(); | |
392 BrowserThread::PostTask( | |
393 BrowserThread::IO, FROM_HERE, | |
394 base::Bind(&InterceptNetworkTransactions, url_request_context_getter, | |
395 // Note that we can't use an error that'll invoke the link | |
396 // doctor. In normal network error conditions that would | |
397 // work (because the link doctor fetch would also fail, | |
398 // putting us back in the main offline path), but | |
399 // SetUrlRequestMocksEnabled() has also specfied a link | |
400 // doctor mock, which will be accessible because it | |
401 // won't go through the network cache. | |
402 net::ERR_FAILED)); | |
403 | |
404 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( | |
405 // With no link doctor load, there's only one navigation. | |
406 browser(), test_url, 1); | |
407 | |
408 content::WebContents* wc = | |
409 browser()->tab_strip_model()->GetActiveWebContents(); | |
410 const char* js_cache_probe = | |
411 "(function () {\n" | |
412 "if ('staleCopyInCache' in templateData) {\n" | |
413 "return templateData.staleCopyInCache;\n" | |
414 "} else {\n" | |
415 "return 'Undefined';\n" | |
416 "}\n" | |
417 "})();"; | |
418 | |
419 scoped_ptr<base::Value> value = | |
420 content::ExecuteScriptAndGetValue( | |
421 wc->GetRenderViewHost(), js_cache_probe); | |
422 ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN)) << "Type is " | |
423 << value->GetType(); | |
424 bool result = false; | |
425 EXPECT_TRUE(value->GetAsBoolean(&result)); | |
426 EXPECT_TRUE(result); | |
mmenke
2014/01/28 17:27:23
optional: It's simpler to do:
ASSERT_TRUE(conten
Randy Smith (Not in Mondays)
2014/01/28 22:52:59
So it turns out that ExecuteScriptAndGetValue() an
mmenke
2014/01/28 23:10:22
My general feeling on this is that ExecuteScriptAn
Randy Smith (Not in Mondays)
2014/01/29 21:14:10
This makes sense. Done. (I used ExecuteScriptAnd
| |
427 | |
428 // Clear the cache and reload the same URL; confirm the error page is told | |
429 // that there is no cached copy. | |
430 BrowsingDataRemover* remover = | |
431 BrowsingDataRemover::CreateForUnboundedRange(browser()->profile()); | |
432 remover->Remove(BrowsingDataRemover::REMOVE_CACHE, | |
433 BrowsingDataHelper::UNPROTECTED_WEB); | |
434 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( | |
435 browser(), test_url, 1); | |
436 value = content::ExecuteScriptAndGetValue( | |
437 wc->GetRenderViewHost(), js_cache_probe); | |
438 ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN)); | |
439 EXPECT_TRUE(value->GetAsBoolean(&result)); | |
440 EXPECT_FALSE(result); | |
mmenke
2014/01/28 17:27:23
Suggest making this into a function. 4 copies see
Randy Smith (Not in Mondays)
2014/01/28 22:52:59
Done.
| |
441 } | |
442 | |
359 // Returns Javascript code that executes plain text search for the page. | 443 // Returns Javascript code that executes plain text search for the page. |
360 // Pass into content::ExecuteScriptAndExtractBool as |script| parameter. | 444 // Pass into content::ExecuteScriptAndExtractBool as |script| parameter. |
361 std::string GetTextContentContainsStringScript( | 445 std::string GetTextContentContainsStringScript( |
362 const std::string& value_to_search) { | 446 const std::string& value_to_search) { |
363 return base::StringPrintf( | 447 return base::StringPrintf( |
364 "var textContent = document.body.textContent;" | 448 "var textContent = document.body.textContent;" |
365 "var hasError = textContent.indexOf('%s') >= 0;" | 449 "var hasError = textContent.indexOf('%s') >= 0;" |
366 "domAutomationController.send(hasError);", | 450 "domAutomationController.send(hasError);", |
367 value_to_search.c_str()); | 451 value_to_search.c_str()); |
368 } | 452 } |
(...skipping 15 matching lines...) Expand all Loading... | |
384 } | 468 } |
385 | 469 |
386 private: | 470 private: |
387 DISALLOW_COPY_AND_ASSIGN(AddressUnreachableProtocolHandler); | 471 DISALLOW_COPY_AND_ASSIGN(AddressUnreachableProtocolHandler); |
388 }; | 472 }; |
389 | 473 |
390 // A test fixture that returns ERR_ADDRESS_UNREACHABLE for all Link Doctor | 474 // 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 | 475 // 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 | 476 // error for the Link Doctor and the original page to validate the right page |
393 // is being displayed. | 477 // is being displayed. |
394 class ErrorPageLinkDoctorFailTest : public InProcessBrowserTest { | 478 class ErrorPageLinkDoctorFailTest : public ErrorPageTest { |
395 public: | 479 public: |
396 // InProcessBrowserTest: | 480 // InProcessBrowserTest: |
397 virtual void SetUpOnMainThread() OVERRIDE { | 481 virtual void SetUpOnMainThread() OVERRIDE { |
398 BrowserThread::PostTask( | 482 BrowserThread::PostTask( |
399 BrowserThread::IO, FROM_HERE, | 483 BrowserThread::IO, FROM_HERE, |
400 base::Bind(&ErrorPageLinkDoctorFailTest::AddFilters)); | 484 base::Bind(&ErrorPageLinkDoctorFailTest::AddFilters)); |
401 } | 485 } |
402 | 486 |
403 virtual void CleanUpOnMainThread() OVERRIDE { | 487 virtual void CleanUpOnMainThread() OVERRIDE { |
404 BrowserThread::PostTask( | 488 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 | 524 // 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. | 525 // sure the original error code (ERR_NAME_NOT_RESOLVED) is displayed. |
442 bool result = false; | 526 bool result = false; |
443 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | 527 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
444 browser()->tab_strip_model()->GetActiveWebContents(), | 528 browser()->tab_strip_model()->GetActiveWebContents(), |
445 GetTextContentContainsStringScript("ERR_NAME_NOT_RESOLVED"), | 529 GetTextContentContainsStringScript("ERR_NAME_NOT_RESOLVED"), |
446 &result)); | 530 &result)); |
447 EXPECT_TRUE(result); | 531 EXPECT_TRUE(result); |
448 } | 532 } |
449 | 533 |
534 // Checks that when an error occurs and a link doctor load fails, the stale | |
535 // cache status of the page is correctly transferred. Most logic copied | |
536 // from StaleCacheStatus above. | |
537 IN_PROC_BROWSER_TEST_F(ErrorPageLinkDoctorFailTest, | |
538 StaleCacheStatusFailedLinkDoctor) { | |
539 ASSERT_TRUE(test_server()->Start()); | |
540 // Load cache with entry with "nocache" set, to create stale | |
541 // cache. | |
542 GURL test_url(test_server()->GetURL("files/nocache.html")); | |
543 NavigateToURLAndWaitForTitle(test_url, "Nocache Test Page", 1); | |
544 | |
545 // Reload same URL after forcing an error from the the network layer; | |
546 // confirm that the error page is told the cached copy exists. | |
547 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter = | |
548 browser()->profile()->GetRequestContext(); | |
549 BrowserThread::PostTask( | |
550 BrowserThread::IO, FROM_HERE, | |
551 base::Bind(&InterceptNetworkTransactions, url_request_context_getter, | |
552 net::ERR_CONNECTION_FAILED)); | |
553 | |
554 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( | |
555 // With no link doctor load, there's only one navigation. | |
556 browser(), test_url, 1); | |
mmenke
2014/01/28 17:27:23
If Link Doctor is failing properly, this should be
Randy Smith (Not in Mondays)
2014/01/28 22:52:59
Done.
| |
557 | |
558 content::WebContents* wc = | |
559 browser()->tab_strip_model()->GetActiveWebContents(); | |
560 const char* js_cache_probe = | |
561 "(function () {\n" | |
562 "if ('staleCopyInCache' in templateData) {\n" | |
563 "return templateData.staleCopyInCache;\n" | |
564 "} else {\n" | |
565 "return 'Undefined';\n" | |
566 "}\n" | |
567 "})();"; | |
568 | |
569 scoped_ptr<base::Value> value = | |
570 content::ExecuteScriptAndGetValue( | |
571 wc->GetRenderViewHost(), js_cache_probe); | |
572 ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN)) << "Type is " | |
573 << value->GetType(); | |
574 bool result = false; | |
575 EXPECT_TRUE(value->GetAsBoolean(&result)); | |
576 EXPECT_TRUE(result); | |
577 | |
578 // Clear the cache and reload the same URL; confirm the error page is told | |
579 // that there is no cached copy. | |
580 BrowsingDataRemover* remover = | |
581 BrowsingDataRemover::CreateForUnboundedRange(browser()->profile()); | |
582 remover->Remove(BrowsingDataRemover::REMOVE_CACHE, | |
583 BrowsingDataHelper::UNPROTECTED_WEB); | |
584 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete( | |
585 browser(), test_url, 1); | |
586 value = content::ExecuteScriptAndGetValue( | |
587 wc->GetRenderViewHost(), js_cache_probe); | |
588 ASSERT_TRUE(value->IsType(base::Value::TYPE_BOOLEAN)); | |
589 EXPECT_TRUE(value->GetAsBoolean(&result)); | |
590 EXPECT_FALSE(result); | |
591 } | |
592 | |
450 // A test fixture that simulates failing requests for an IDN domain name. | 593 // A test fixture that simulates failing requests for an IDN domain name. |
451 class ErrorPageForIDNTest : public InProcessBrowserTest { | 594 class ErrorPageForIDNTest : public InProcessBrowserTest { |
452 public: | 595 public: |
453 // Target hostname in different forms. | 596 // Target hostname in different forms. |
454 static const char kHostname[]; | 597 static const char kHostname[]; |
455 static const char kHostnameJSUnicode[]; | 598 static const char kHostnameJSUnicode[]; |
456 | 599 |
457 // InProcessBrowserTest: | 600 // InProcessBrowserTest: |
458 virtual void SetUpOnMainThread() OVERRIDE { | 601 virtual void SetUpOnMainThread() OVERRIDE { |
459 // Clear AcceptLanguages to force punycode decoding. | 602 // Clear AcceptLanguages to force punycode decoding. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
499 | 642 |
500 bool result = false; | 643 bool result = false; |
501 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( | 644 EXPECT_TRUE(content::ExecuteScriptAndExtractBool( |
502 browser()->tab_strip_model()->GetActiveWebContents(), | 645 browser()->tab_strip_model()->GetActiveWebContents(), |
503 GetTextContentContainsStringScript(kHostnameJSUnicode), | 646 GetTextContentContainsStringScript(kHostnameJSUnicode), |
504 &result)); | 647 &result)); |
505 EXPECT_TRUE(result); | 648 EXPECT_TRUE(result); |
506 } | 649 } |
507 | 650 |
508 } // namespace | 651 } // namespace |
OLD | NEW |