| OLD | NEW |
| (Empty) |
| 1 // Copyright 2016 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. | |
| 4 | |
| 5 #import <EarlGrey/EarlGrey.h> | |
| 6 | |
| 7 #include "components/strings/grit/components_strings.h" | |
| 8 #import "ios/chrome/test/app/chrome_test_util.h" | |
| 9 #include "ios/chrome/test/app/web_view_interaction_test_util.h" | |
| 10 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" | |
| 11 #import "ios/chrome/test/earl_grey/chrome_matchers.h" | |
| 12 #import "ios/chrome/test/earl_grey/chrome_test_case.h" | |
| 13 #import "ios/web/public/test/http_server.h" | |
| 14 #import "ios/web/public/test/earl_grey/web_view_matchers.h" | |
| 15 #include "ios/web/public/test/http_server_util.h" | |
| 16 #include "ios/web/public/test/response_providers/data_response_provider.h" | |
| 17 #include "ios/web/public/test/response_providers/error_page_response_provider.h" | |
| 18 #include "ui/base/l10n/l10n_util.h" | |
| 19 #include "ui/base/l10n/l10n_util_mac.h" | |
| 20 | |
| 21 #if !defined(__has_feature) || !__has_feature(objc_arc) | |
| 22 #error "This file requires ARC support." | |
| 23 #endif | |
| 24 | |
| 25 using chrome_test_util::OmniboxText; | |
| 26 using chrome_test_util::TapWebViewElementWithId; | |
| 27 using chrome_test_util::WebViewContainingText; | |
| 28 using chrome_test_util::WebViewNotContainingText; | |
| 29 | |
| 30 using web::test::HttpServer; | |
| 31 | |
| 32 // Tests display of error pages for bad URLs. | |
| 33 @interface ErrorPageTestCase : ChromeTestCase | |
| 34 | |
| 35 // Checks that the DNS error page is not visible. | |
| 36 - (void)checkErrorPageIsNotVisible; | |
| 37 | |
| 38 @end | |
| 39 | |
| 40 @implementation ErrorPageTestCase | |
| 41 | |
| 42 #pragma mark - utilities | |
| 43 | |
| 44 - (void)checkErrorPageIsNotVisible { | |
| 45 // Check that the webview belongs to the web controller, and that the error | |
| 46 // text doesn't appear in the webview. | |
| 47 id<GREYMatcher> webViewMatcher = | |
| 48 web::WebViewInWebState(chrome_test_util::GetCurrentWebState()); | |
| 49 [[EarlGrey selectElementWithMatcher:webViewMatcher] | |
| 50 assertWithMatcher:grey_notNil()]; | |
| 51 const std::string kError = | |
| 52 l10n_util::GetStringUTF8(IDS_ERRORPAGES_HEADING_NOT_AVAILABLE); | |
| 53 [[EarlGrey selectElementWithMatcher:WebViewNotContainingText(kError)] | |
| 54 assertWithMatcher:grey_notNil()]; | |
| 55 } | |
| 56 | |
| 57 #pragma mark - tests | |
| 58 | |
| 59 // Tests whether the error page is displayed for a bad URL. | |
| 60 - (void)testErrorPage { | |
| 61 // TODO(crbug.com/694662): This test relies on external URL because of the bug. | |
| 62 // Re-enable this test on device once the bug is fixed. | |
| 63 #if !TARGET_IPHONE_SIMULATOR | |
| 64 EARL_GREY_TEST_DISABLED(@"Test disabled on device."); | |
| 65 #endif | |
| 66 | |
| 67 std::unique_ptr<web::DataResponseProvider> provider( | |
| 68 new ErrorPageResponseProvider()); | |
| 69 web::test::SetUpHttpServer(std::move(provider)); | |
| 70 | |
| 71 [ChromeEarlGrey loadURL:ErrorPageResponseProvider::GetDnsFailureUrl()]; | |
| 72 | |
| 73 [ChromeEarlGrey waitForErrorPage]; | |
| 74 } | |
| 75 | |
| 76 // Tests whether the error page is displayed if it is behind a redirect. | |
| 77 - (void)testErrorPageRedirect { | |
| 78 // TODO(crbug.com/694662): This test relies on external URL because of the bug. | |
| 79 // Re-enable this test on device once the bug is fixed. | |
| 80 #if !TARGET_IPHONE_SIMULATOR | |
| 81 EARL_GREY_TEST_DISABLED(@"Test disabled on device."); | |
| 82 #endif | |
| 83 | |
| 84 std::unique_ptr<web::DataResponseProvider> provider( | |
| 85 new ErrorPageResponseProvider()); | |
| 86 web::test::SetUpHttpServer(std::move(provider)); | |
| 87 | |
| 88 // Load a URL that redirects to the DNS-failing URL. | |
| 89 [ChromeEarlGrey | |
| 90 loadURL:ErrorPageResponseProvider::GetRedirectToDnsFailureUrl()]; | |
| 91 | |
| 92 // Verify that the redirect occurred before checking for the DNS error. | |
| 93 const std::string& redirectedURL = | |
| 94 ErrorPageResponseProvider::GetDnsFailureUrl().GetContent(); | |
| 95 [[EarlGrey selectElementWithMatcher:OmniboxText(redirectedURL)] | |
| 96 assertWithMatcher:grey_notNil()]; | |
| 97 | |
| 98 [ChromeEarlGrey waitForErrorPage]; | |
| 99 } | |
| 100 | |
| 101 // Tests that the error page is not displayed if the bad URL is in a <iframe> | |
| 102 // tag. | |
| 103 - (void)testErrorPageInIFrame { | |
| 104 std::map<GURL, std::string> responses; | |
| 105 const GURL URL = HttpServer::MakeUrl("http://browsingErrorPageInIFrame"); | |
| 106 // This page contains an iframe to a bad URL. | |
| 107 responses[URL] = std::string("This page contains an iframe.<iframe src='") + | |
| 108 ErrorPageResponseProvider::GetDnsFailureUrl().spec() + | |
| 109 "'>whatever</iframe>"; | |
| 110 std::unique_ptr<web::DataResponseProvider> provider( | |
| 111 new ErrorPageResponseProvider(responses)); | |
| 112 web::test::SetUpHttpServer(std::move(provider)); | |
| 113 | |
| 114 [ChromeEarlGrey loadURL:URL]; | |
| 115 | |
| 116 [self checkErrorPageIsNotVisible]; | |
| 117 } | |
| 118 | |
| 119 // Tests that the error page is not displayed if the bad URL is in a <iframe> | |
| 120 // tag that is loaded after the initial page load completes. | |
| 121 - (void)testErrorPageInIFrameAfterDelay { | |
| 122 // Create map of canned responses and set up the test HTML server. | |
| 123 std::map<GURL, std::string> responses; | |
| 124 const GURL URL = | |
| 125 HttpServer::MakeUrl("http://browsingErrorPageInIFrameAfterDelay"); | |
| 126 // This page adds an iframe to a bad URL one second after loading. When the | |
| 127 // timer completes, some text is also added to the page so EarlGrey can detect | |
| 128 // that the timer has completed. | |
| 129 const std::string kTimerCompleted = "Timer completed"; | |
| 130 responses[URL] = | |
| 131 std::string("This page will have an iframe appended after page load.") + | |
| 132 "<script>setTimeout(" + "function() { document.body.innerHTML+='<p>" + | |
| 133 kTimerCompleted + "</p>" + "<iframe src=\"" + | |
| 134 ErrorPageResponseProvider::GetDnsFailureUrl().spec() + | |
| 135 "\"></iframe>'}, 1000);" + "</script>"; | |
| 136 std::unique_ptr<web::DataResponseProvider> provider( | |
| 137 new ErrorPageResponseProvider(responses)); | |
| 138 web::test::SetUpHttpServer(std::move(provider)); | |
| 139 | |
| 140 [ChromeEarlGrey loadURL:URL]; | |
| 141 // Check that the timer has completed. | |
| 142 [[EarlGrey selectElementWithMatcher:WebViewContainingText(kTimerCompleted)] | |
| 143 assertWithMatcher:grey_notNil()]; | |
| 144 // DNS error page should still not appear. | |
| 145 [self checkErrorPageIsNotVisible]; | |
| 146 } | |
| 147 | |
| 148 // Tests that the error page is not displayed if the navigation was not | |
| 149 // user-initiated. | |
| 150 - (void)testErrorPageNoUserInteraction { | |
| 151 // Create map of canned responses and set up the test HTML server. | |
| 152 std::map<GURL, std::string> responses; | |
| 153 const GURL URL = | |
| 154 HttpServer::MakeUrl("http://browsingErrorPageNoUserInteraction"); | |
| 155 // This page contains a button that starts a timer that appends an iframe to a | |
| 156 // bad URL. To create a non-user-initiated navigation, the timer takes longer | |
| 157 // than the CRWWebController's kMaximumDelayForUserInteractionInSeconds | |
| 158 // constant. When the timer completes, some text is also added to the page so | |
| 159 // the test can detect that the timer has completed. | |
| 160 const std::string kTimerCompleted = "Timer completed"; | |
| 161 const std::string kButtonId = "aButton"; | |
| 162 // Timeout used for the setTimeout() call the button invokes. This value must | |
| 163 // be greater than CRWWebController's kMaximumDelayForUserInteractionInSeconds | |
| 164 // and less than testing::kWaitForUIElementTimeout | |
| 165 const std::string kTimeoutMs = "3000"; | |
| 166 responses[URL] = std::string("<form><input type='button' id='") + kButtonId + | |
| 167 "' value='button' onClick='setTimeout(function() { " + | |
| 168 "document.body.innerHTML+=\"<p>" + kTimerCompleted + | |
| 169 "</p><iframe src=" + | |
| 170 ErrorPageResponseProvider::GetDnsFailureUrl().spec() + | |
| 171 ">\"}, " + kTimeoutMs + ");'></form>"; | |
| 172 std::unique_ptr<web::DataResponseProvider> provider( | |
| 173 new ErrorPageResponseProvider(responses)); | |
| 174 web::test::SetUpHttpServer(std::move(provider)); | |
| 175 | |
| 176 [ChromeEarlGrey loadURL:URL]; | |
| 177 TapWebViewElementWithId(kButtonId); | |
| 178 // Check that the timer has completed. | |
| 179 [[EarlGrey selectElementWithMatcher:WebViewContainingText(kTimerCompleted)] | |
| 180 assertWithMatcher:grey_notNil()]; | |
| 181 // DNS error page should still not appear. | |
| 182 [self checkErrorPageIsNotVisible]; | |
| 183 } | |
| 184 | |
| 185 @end | |
| OLD | NEW |