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 #import "base/mac/scoped_nsobject.h" |
| 8 #include "base/memory/ptr_util.h" |
| 9 #include "base/strings/stringprintf.h" |
| 10 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 11 #include "components/content_settings/core/common/content_settings.h" |
| 12 #include "ios/chrome/browser/content_settings/host_content_settings_map_factory.
h" |
| 13 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h" |
| 14 #include "ios/chrome/browser/ui/commands/ios_command_ids.h" |
| 15 #import "ios/chrome/test/app/chrome_test_util.h" |
| 16 #include "ios/chrome/test/app/history_test_util.h" |
| 17 #include "ios/chrome/test/app/navigation_test_util.h" |
| 18 #include "ios/chrome/test/app/web_view_interaction_test_util.h" |
| 19 #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" |
| 20 #import "ios/chrome/test/earl_grey/chrome_matchers.h" |
| 21 #import "ios/chrome/test/earl_grey/chrome_test_case.h" |
| 22 #import "ios/testing/wait_util.h" |
| 23 #import "ios/web/public/test/http_server.h" |
| 24 #include "ios/web/public/test/http_server_util.h" |
| 25 #include "ios/web/public/test/response_providers/html_response_provider.h" |
| 26 #include "url/gurl.h" |
| 27 |
| 28 using chrome_test_util::webViewContainingText; |
| 29 using web::test::HttpServer; |
| 30 |
| 31 namespace { |
| 32 |
| 33 // First page for cache testing. |
| 34 const char kCacheTestFirstPageURL[] = "http://cacheTestFirstPage"; |
| 35 |
| 36 // Second page for cache testing. |
| 37 const char kCacheTestSecondPageURL[] = "http://cacheTestSecondPage"; |
| 38 |
| 39 // Third page for cache testing. |
| 40 const char kCacheTestThirdPageURL[] = "http://cacheTestThirdPage"; |
| 41 |
| 42 // ID for HTML hyperlink element. |
| 43 const char kCacheTestLinkID[] = "cache-test-link-id"; |
| 44 |
| 45 // Response provider for cache testing that provides server hit count and |
| 46 // cache-control request header. |
| 47 class CacheTestResponseProvider : public web::DataResponseProvider { |
| 48 public: |
| 49 CacheTestResponseProvider() |
| 50 : first_page_url_(HttpServer::MakeUrl(kCacheTestFirstPageURL)), |
| 51 second_page_url_(HttpServer::MakeUrl(kCacheTestSecondPageURL)), |
| 52 third_page_url_(HttpServer::MakeUrl(kCacheTestThirdPageURL)) {} |
| 53 ~CacheTestResponseProvider() override {} |
| 54 |
| 55 // HtmlResponseProvider overrides: |
| 56 bool CanHandleRequest(const Request& request) override { |
| 57 return request.url == first_page_url_ || request.url == second_page_url_ || |
| 58 request.url == third_page_url_; |
| 59 } |
| 60 void GetResponseHeadersAndBody( |
| 61 const Request& request, |
| 62 scoped_refptr<net::HttpResponseHeaders>* headers, |
| 63 std::string* response_body) override { |
| 64 hit_counter_++; |
| 65 std::string cache_control_header; |
| 66 if (request.headers.HasHeader("Cache-Control")) { |
| 67 request.headers.GetHeader("Cache-Control", &cache_control_header); |
| 68 } |
| 69 *headers = web::ResponseProvider::GetDefaultResponseHeaders(); |
| 70 |
| 71 if (request.url == first_page_url_) { |
| 72 *response_body = base::StringPrintf( |
| 73 "<p>First Page</p>" |
| 74 "<p>serverHitCounter: %d</p>" |
| 75 "<p>cacheControl: %s</p>" |
| 76 "<a href='%s' id='%s'>link to second page</a>", |
| 77 hit_counter_, cache_control_header.c_str(), |
| 78 second_page_url_.spec().c_str(), kCacheTestLinkID); |
| 79 |
| 80 } else if (request.url == second_page_url_) { |
| 81 *response_body = base::StringPrintf( |
| 82 "<p>Second Page</p>" |
| 83 "<p>serverHitCounter: %d</p>" |
| 84 "<p>cacheControl: %s</p>", |
| 85 hit_counter_, cache_control_header.c_str()); |
| 86 } else if (request.url == third_page_url_) { |
| 87 *response_body = base::StringPrintf( |
| 88 "<p>Third Page</p>" |
| 89 "<p>serverHitCounter: %d</p>" |
| 90 "<p>cacheControl: %s</p>" |
| 91 "<a href='%s' id='%s' target='_blank'>" |
| 92 "link to first page in new tab</a>", |
| 93 hit_counter_, cache_control_header.c_str(), |
| 94 first_page_url_.spec().c_str(), kCacheTestLinkID); |
| 95 } else { |
| 96 NOTREACHED(); |
| 97 } |
| 98 } |
| 99 |
| 100 private: |
| 101 // A number that counts requests that have reached the server. |
| 102 int hit_counter_ = 0; |
| 103 |
| 104 // URLs for three test pages. |
| 105 GURL first_page_url_; |
| 106 GURL second_page_url_; |
| 107 GURL third_page_url_; |
| 108 }; |
| 109 |
| 110 // ScopedBlockPopupsPref modifies the block popups preference and resets the |
| 111 // preference to its original value when this object goes out of scope. |
| 112 // TODO(crbug.com/638674): Evaluate if this can move to shared code. |
| 113 class ScopedBlockPopupsPref { |
| 114 public: |
| 115 explicit ScopedBlockPopupsPref(ContentSetting setting) { |
| 116 original_setting_ = GetPrefValue(); |
| 117 SetPrefValue(setting); |
| 118 } |
| 119 ~ScopedBlockPopupsPref() { SetPrefValue(original_setting_); } |
| 120 |
| 121 private: |
| 122 // Gets the current value of the preference. |
| 123 ContentSetting GetPrefValue() { |
| 124 ContentSetting popupSetting = |
| 125 ios::HostContentSettingsMapFactory::GetForBrowserState( |
| 126 chrome_test_util::GetOriginalBrowserState()) |
| 127 ->GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_POPUPS, NULL); |
| 128 return popupSetting; |
| 129 } |
| 130 |
| 131 // Sets the preference to the given value. |
| 132 void SetPrefValue(ContentSetting setting) { |
| 133 DCHECK(setting == CONTENT_SETTING_BLOCK || |
| 134 setting == CONTENT_SETTING_ALLOW); |
| 135 ios::ChromeBrowserState* state = |
| 136 chrome_test_util::GetOriginalBrowserState(); |
| 137 ios::HostContentSettingsMapFactory::GetForBrowserState(state) |
| 138 ->SetDefaultContentSetting(CONTENT_SETTINGS_TYPE_POPUPS, setting); |
| 139 } |
| 140 |
| 141 // Saves the original pref setting so that it can be restored when the scoper |
| 142 // is destroyed. |
| 143 ContentSetting original_setting_; |
| 144 |
| 145 DISALLOW_COPY_AND_ASSIGN(ScopedBlockPopupsPref); |
| 146 }; |
| 147 |
| 148 } // namespace |
| 149 |
| 150 // Tests the browser cache behavior when navigating to cached pages. |
| 151 @interface CacheTestCase : ChromeTestCase |
| 152 @end |
| 153 |
| 154 @implementation CacheTestCase |
| 155 |
| 156 // Reloads the web view and waits for the loading to complete. |
| 157 // TODO(crbug.com/638674): Evaluate if this can move to shared code |
| 158 - (void)reloadPage { |
| 159 base::scoped_nsobject<GenericChromeCommand> reloadCommand( |
| 160 [[GenericChromeCommand alloc] initWithTag:IDC_RELOAD]); |
| 161 chrome_test_util::RunCommandWithActiveViewController(reloadCommand); |
| 162 |
| 163 [ChromeEarlGrey waitForPageToFinishLoading]; |
| 164 } |
| 165 |
| 166 // Navigates back to the previous webpage. |
| 167 // TODO(crbug.com/638674): Evaluate if this can move to shared code. |
| 168 - (void)goBack { |
| 169 base::scoped_nsobject<GenericChromeCommand> backCommand( |
| 170 [[GenericChromeCommand alloc] initWithTag:IDC_BACK]); |
| 171 chrome_test_util::RunCommandWithActiveViewController(backCommand); |
| 172 |
| 173 [ChromeEarlGrey waitForPageToFinishLoading]; |
| 174 } |
| 175 |
| 176 // Tests caching behavior on navigate back and page reload. Navigate back should |
| 177 // use the cached page. Page reload should use cache-control in the request |
| 178 // header and show updated page. |
| 179 - (void)testCachingBehaviorOnNavigateBackAndPageReload { |
| 180 web::test::SetUpHttpServer(base::MakeUnique<CacheTestResponseProvider>()); |
| 181 |
| 182 const GURL cacheTestFirstPageURL = |
| 183 HttpServer::MakeUrl(kCacheTestFirstPageURL); |
| 184 |
| 185 // 1st hit to server. Verify that the server has the correct hit count. |
| 186 [ChromeEarlGrey loadURL:cacheTestFirstPageURL]; |
| 187 [[EarlGrey |
| 188 selectElementWithMatcher:webViewContainingText("serverHitCounter: 1")] |
| 189 assertWithMatcher:grey_notNil()]; |
| 190 |
| 191 // Navigate to another page. 2nd hit to server. |
| 192 chrome_test_util::TapWebViewElementWithId(kCacheTestLinkID); |
| 193 [[EarlGrey |
| 194 selectElementWithMatcher:webViewContainingText("serverHitCounter: 2")] |
| 195 assertWithMatcher:grey_notNil()]; |
| 196 |
| 197 // Navigate back. This should not hit the server. Verify the page has been |
| 198 // loaded from cache. The serverHitCounter will remain the same. |
| 199 [self goBack]; |
| 200 [[EarlGrey |
| 201 selectElementWithMatcher:webViewContainingText("serverHitCounter: 1")] |
| 202 assertWithMatcher:grey_notNil()]; |
| 203 |
| 204 // Reload page. 3rd hit to server. Verify that page reload causes the |
| 205 // hitCounter to show updated value. |
| 206 [self reloadPage]; |
| 207 [[EarlGrey |
| 208 selectElementWithMatcher:webViewContainingText("serverHitCounter: 3")] |
| 209 assertWithMatcher:grey_notNil()]; |
| 210 |
| 211 // Verify that page reload causes Cache-Control value to be sent with request. |
| 212 [[EarlGrey |
| 213 selectElementWithMatcher:webViewContainingText("cacheControl: max-age=0")] |
| 214 assertWithMatcher:grey_notNil()]; |
| 215 } |
| 216 |
| 217 // Tests caching behavior when opening new tab. New tab should not use the |
| 218 // cached page. |
| 219 // TODO(crbug.com/644646): Monitor this test for flakiness. |
| 220 - (void)testCachingBehaviorOnOpenNewTab { |
| 221 web::test::SetUpHttpServer(base::MakeUnique<CacheTestResponseProvider>()); |
| 222 |
| 223 const GURL cacheTestFirstPageURL = |
| 224 HttpServer::MakeUrl(kCacheTestFirstPageURL); |
| 225 const GURL cacheTestThirdPageURL = |
| 226 HttpServer::MakeUrl(kCacheTestThirdPageURL); |
| 227 |
| 228 // 1st hit to server. Verify title and hitCount. |
| 229 [ChromeEarlGrey loadURL:cacheTestFirstPageURL]; |
| 230 [[EarlGrey selectElementWithMatcher:webViewContainingText("First Page")] |
| 231 assertWithMatcher:grey_notNil()]; |
| 232 [[EarlGrey |
| 233 selectElementWithMatcher:webViewContainingText("serverHitCounter: 1")] |
| 234 assertWithMatcher:grey_notNil()]; |
| 235 |
| 236 // 2nd hit to server. Verify hitCount. |
| 237 [ChromeEarlGrey loadURL:cacheTestThirdPageURL]; |
| 238 [[EarlGrey |
| 239 selectElementWithMatcher:webViewContainingText("serverHitCounter: 2")] |
| 240 assertWithMatcher:grey_notNil()]; |
| 241 |
| 242 // Open the first page in a new tab. Verify that cache was not used. Must |
| 243 // first allow popups. |
| 244 ScopedBlockPopupsPref prefSetter(CONTENT_SETTING_ALLOW); |
| 245 chrome_test_util::TapWebViewElementWithId(kCacheTestLinkID); |
| 246 [ChromeEarlGrey waitForPageToFinishLoading]; |
| 247 [[EarlGrey selectElementWithMatcher:webViewContainingText("First Page")] |
| 248 assertWithMatcher:grey_notNil()]; |
| 249 [[EarlGrey |
| 250 selectElementWithMatcher:webViewContainingText("serverHitCounter: 3")] |
| 251 assertWithMatcher:grey_notNil()]; |
| 252 } |
| 253 |
| 254 // Tests that cache is not used when selecting omnibox suggested website, even |
| 255 // though cache for that website exists. |
| 256 - (void)testCachingBehaviorOnSelectOmniboxSuggestion { |
| 257 web::test::SetUpHttpServer(base::MakeUnique<CacheTestResponseProvider>()); |
| 258 |
| 259 // Clear the history to ensure expected omnibox autocomplete results. |
| 260 chrome_test_util::ClearBrowsingHistory(); |
| 261 |
| 262 const GURL cacheTestFirstPageURL = |
| 263 HttpServer::MakeUrl(kCacheTestFirstPageURL); |
| 264 |
| 265 // 1st hit to server. Verify title and hitCount. |
| 266 [ChromeEarlGrey loadURL:cacheTestFirstPageURL]; |
| 267 [[EarlGrey selectElementWithMatcher:webViewContainingText("First Page")] |
| 268 assertWithMatcher:grey_notNil()]; |
| 269 [[EarlGrey |
| 270 selectElementWithMatcher:webViewContainingText("serverHitCounter: 1")] |
| 271 assertWithMatcher:grey_notNil()]; |
| 272 |
| 273 // Type a search into omnnibox and select the first suggestion (second row) |
| 274 [[EarlGrey selectElementWithMatcher:chrome_test_util::omnibox()] |
| 275 performAction:grey_typeText(@"cachetestfirstpage")]; |
| 276 [[EarlGrey |
| 277 selectElementWithMatcher:grey_accessibilityID(@"omnibox suggestion 1")] |
| 278 performAction:grey_tap()]; |
| 279 |
| 280 // Verify title and hitCount. Cache should not be used. |
| 281 [[EarlGrey selectElementWithMatcher:webViewContainingText("First Page")] |
| 282 assertWithMatcher:grey_notNil()]; |
| 283 [[EarlGrey |
| 284 selectElementWithMatcher:webViewContainingText("serverHitCounter: 2")] |
| 285 assertWithMatcher:grey_notNil()]; |
| 286 } |
| 287 |
| 288 @end |
OLD | NEW |