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 #import <UIKit/UIKit.h> |
| 7 #import <XCTest/XCTest.h> |
| 8 |
| 9 #include "base/ios/ios_util.h" |
| 10 #include "base/mac/bind_objc_block.h" |
| 11 #include "base/strings/stringprintf.h" |
| 12 #include "base/strings/sys_string_conversions.h" |
| 13 #include "base/strings/utf_string_conversions.h" |
| 14 #import "ios/chrome/browser/ui/toolbar/toolbar_controller.h" |
| 15 #import "ios/chrome/test/app/chrome_test_util.h" |
| 16 #import "ios/chrome/test/app/settings_test_util.h" |
| 17 #import "ios/chrome/test/app/web_view_interaction_test_util.h" |
| 18 #include "ios/chrome/test/earl_grey/chrome_assertions.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/chrome/test/earl_grey/chrome_util.h" |
| 23 #import "ios/testing/wait_util.h" |
| 24 #import "ios/web/public/test/earl_grey/web_view_matchers.h" |
| 25 #import "ios/web/public/test/http_server.h" |
| 26 #import "ios/web/public/test/http_server_util.h" |
| 27 #import "ios/web/public/test/response_providers/error_page_response_provider.h" |
| 28 #import "ios/web/public/test/web_view_interaction_test_util.h" |
| 29 #include "url/gurl.h" |
| 30 |
| 31 namespace { |
| 32 |
| 33 // TODO(crbug.com/638674): Move this to a shared location as it is a duplicate |
| 34 // of ios/web/shell/test/page_state_egtest.mm. |
| 35 // Returns a matcher for asserting that element's content offset matches the |
| 36 // given |offset|. |
| 37 id<GREYMatcher> contentOffset(CGPoint offset) { |
| 38 MatchesBlock matches = ^BOOL(UIScrollView* element) { |
| 39 return CGPointEqualToPoint([element contentOffset], offset); |
| 40 }; |
| 41 DescribeToBlock describe = ^(id<GREYDescription> description) { |
| 42 [description appendText:@"contentOffset"]; |
| 43 }; |
| 44 return grey_allOf( |
| 45 grey_kindOfClass([UIScrollView class]), |
| 46 [[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches |
| 47 descriptionBlock:describe], |
| 48 nil); |
| 49 } |
| 50 |
| 51 // Hides the toolbar by scrolling down. |
| 52 void HideToolbarUsingUI() { |
| 53 [[EarlGrey |
| 54 selectElementWithMatcher:webViewScrollView( |
| 55 chrome_test_util::GetCurrentWebState())] |
| 56 performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; |
| 57 } |
| 58 |
| 59 // Asserts that the current URL is the |expectedURL| one. |
| 60 void AssertURLIs(const GURL& expectedURL) { |
| 61 NSString* description = [NSString |
| 62 stringWithFormat:@"Timeout waiting for the url to be %@", |
| 63 base::SysUTF8ToNSString(expectedURL.GetContent())]; |
| 64 |
| 65 ConditionBlock condition = ^{ |
| 66 NSError* error = nil; |
| 67 [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText( |
| 68 expectedURL.GetContent())] |
| 69 assertWithMatcher:grey_notNil() |
| 70 error:&error]; |
| 71 return (error == nil); |
| 72 }; |
| 73 GREYAssert(testing::WaitUntilConditionOrTimeout(1.0, condition), description); |
| 74 } |
| 75 |
| 76 // Asserts that the current web view containers contains |text|. |
| 77 void AssertStringIsPresentOnPage(const std::string& text) { |
| 78 id<GREYMatcher> response_matcher = |
| 79 chrome_test_util::webViewContainingText(text); |
| 80 [[EarlGrey selectElementWithMatcher:response_matcher] |
| 81 assertWithMatcher:grey_notNil()]; |
| 82 } |
| 83 |
| 84 } // namespace |
| 85 |
| 86 #pragma mark - Tests |
| 87 |
| 88 // Fullscreens tests for Chrome. |
| 89 @interface FullscreenTestCase : ChromeTestCase |
| 90 |
| 91 @end |
| 92 |
| 93 @implementation FullscreenTestCase |
| 94 |
| 95 // Verifies that the content offset of the web view is set up at the correct |
| 96 // initial value when initially displaying a PDF. |
| 97 - (void)testLongPDFInitialState { |
| 98 web::test::SetUpFileBasedHttpServer(); |
| 99 GURL URL = web::test::HttpServer::MakeUrl( |
| 100 "http://ios/testing/data/http_server_files/two_pages.pdf"); |
| 101 [ChromeEarlGrey loadURL:URL]; |
| 102 |
| 103 chrome_test_util::AssertToolbarVisible(); |
| 104 // Initial y scroll position is -56 on iPhone and -95 on iPad, to make room |
| 105 // for the toolbar. |
| 106 // TODO(crbug.com/618887) Replace use of specific values when API which |
| 107 // generates these values is exposed. |
| 108 CGFloat yOffset = IsIPadIdiom() ? -95.0 : -56.0; |
| 109 [[EarlGrey |
| 110 selectElementWithMatcher:web::webViewScrollView( |
| 111 chrome_test_util::GetCurrentWebState())] |
| 112 assertWithMatcher:contentOffset(CGPointMake(0, yOffset))]; |
| 113 } |
| 114 |
| 115 // Verifies that the toolbar properly appears/disappears when scrolling up/down |
| 116 // on a PDF that is short in length and wide in width. |
| 117 - (void)testSmallWidePDFScroll { |
| 118 web::test::SetUpFileBasedHttpServer(); |
| 119 GURL URL = web::test::HttpServer::MakeUrl( |
| 120 "http://ios/testing/data/http_server_files/single_page_wide.pdf"); |
| 121 [ChromeEarlGrey loadURL:URL]; |
| 122 |
| 123 // Test that the toolbar is still visible after a user swipes down. |
| 124 [[EarlGrey |
| 125 selectElementWithMatcher:webViewScrollView( |
| 126 chrome_test_util::GetCurrentWebState())] |
| 127 performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; |
| 128 chrome_test_util::AssertToolbarVisible(); |
| 129 |
| 130 // Test that the toolbar is no longer visible after a user swipes up. |
| 131 HideToolbarUsingUI(); |
| 132 chrome_test_util::AssertToolbarNotVisible(); |
| 133 } |
| 134 |
| 135 // Verifies that the toolbar properly appears/disappears when scrolling up/down |
| 136 // on a PDF that is long in length and wide in width. |
| 137 - (void)testLongPDFScroll { |
| 138 web::test::SetUpFileBasedHttpServer(); |
| 139 GURL URL = web::test::HttpServer::MakeUrl( |
| 140 "http://ios/testing/data/http_server_files/two_pages.pdf"); |
| 141 [ChromeEarlGrey loadURL:URL]; |
| 142 |
| 143 // Test that the toolbar is hidden after a user swipes up. |
| 144 HideToolbarUsingUI(); |
| 145 chrome_test_util::AssertToolbarNotVisible(); |
| 146 |
| 147 // Test that the toolbar is visible after a user swipes down. |
| 148 [[EarlGrey |
| 149 selectElementWithMatcher:webViewScrollView( |
| 150 chrome_test_util::GetCurrentWebState())] |
| 151 performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; |
| 152 chrome_test_util::AssertToolbarVisible(); |
| 153 |
| 154 // Test that the toolbar is hidden after a user swipes up. |
| 155 HideToolbarUsingUI(); |
| 156 chrome_test_util::AssertToolbarNotVisible(); |
| 157 } |
| 158 |
| 159 // Tests that link clicks from a chrome:// to chrome:// link result in the |
| 160 // header being shown even if was not previously shown. |
| 161 - (void)testChromeToChromeURLKeepsHeaderOnScreen { |
| 162 const GURL kChromeAboutURL("chrome://chrome-urls"); |
| 163 [ChromeEarlGrey loadURL:kChromeAboutURL]; |
| 164 |
| 165 AssertStringIsPresentOnPage("chrome://version"); |
| 166 |
| 167 // Hide the toolbar. The page is not long enough to dismiss the toolbar using |
| 168 // the UI so we have to zoom in. |
| 169 const char script[] = |
| 170 "(function(){" |
| 171 "var metas = document.getElementsByTagName('meta');" |
| 172 "for (var i=0; i<metas.length; i++) {" |
| 173 " if (metas[i].getAttribute('name') == 'viewport') {" |
| 174 " metas[i].setAttribute('content', 'width=10');" |
| 175 " return;" |
| 176 " }" |
| 177 "}" |
| 178 "document.body.innerHTML += \"<meta name='viewport' content='width=10'>\"" |
| 179 "})()"; |
| 180 |
| 181 __block bool finished = false; |
| 182 chrome_test_util::GetCurrentWebState()->ExecuteJavaScript( |
| 183 base::UTF8ToUTF16(script), base::BindBlock(^(const base::Value*) { |
| 184 finished = true; |
| 185 })); |
| 186 |
| 187 GREYAssert(testing::WaitUntilConditionOrTimeout(1.0, |
| 188 ^{ |
| 189 return finished; |
| 190 }), |
| 191 @"JavaScript to hide the toolbar did not complete"); |
| 192 |
| 193 // Scroll to hide the UI. |
| 194 HideToolbarUsingUI(); |
| 195 chrome_test_util::AssertToolbarNotVisible(); |
| 196 |
| 197 // Test that the toolbar is visible when moving from one chrome:// link to |
| 198 // another chrome:// link. |
| 199 chrome_test_util::TapWebViewElementWithId("version"); |
| 200 chrome_test_util::AssertToolbarVisible(); |
| 201 } |
| 202 |
| 203 // Tests hiding and showing of the header with a user scroll on a long page. |
| 204 - (void)testHideHeaderUserScrollLongPage { |
| 205 std::map<GURL, std::string> responses; |
| 206 const GURL URL = web::test::HttpServer::MakeUrl("http://tallpage"); |
| 207 |
| 208 // A page long enough to ensure that the toolbar goes away on scrolling. |
| 209 responses[URL] = "<p style='height:200em'>a</p><p>b</p>"; |
| 210 web::test::SetUpSimpleHttpServer(responses); |
| 211 |
| 212 [ChromeEarlGrey loadURL:URL]; |
| 213 chrome_test_util::AssertToolbarVisible(); |
| 214 // Simulate a user scroll down. |
| 215 HideToolbarUsingUI(); |
| 216 chrome_test_util::AssertToolbarNotVisible(); |
| 217 // Simulate a user scroll up. |
| 218 [[EarlGrey |
| 219 selectElementWithMatcher:webViewScrollView( |
| 220 chrome_test_util::GetCurrentWebState())] |
| 221 performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; |
| 222 chrome_test_util::AssertToolbarVisible(); |
| 223 } |
| 224 |
| 225 // Tests that reloading of a page shows the header even if it was not shown |
| 226 // previously. |
| 227 - (void)testShowHeaderOnReload { |
| 228 std::map<GURL, std::string> responses; |
| 229 const GURL URL = web::test::HttpServer::MakeUrl("http://origin"); |
| 230 // This is a tall page -- necessary to make sure scrolling can hide away the |
| 231 // toolbar safely-- and with a link to reload itself. |
| 232 responses[URL] = |
| 233 "<p style='height:200em'>Tall page</p>" |
| 234 "<a onclick='window.location.reload();' id='link'>link</a>"; |
| 235 web::test::SetUpSimpleHttpServer(responses); |
| 236 |
| 237 [ChromeEarlGrey loadURL:URL]; |
| 238 AssertStringIsPresentOnPage("Tall page"); |
| 239 |
| 240 // Hide the toolbar. |
| 241 HideToolbarUsingUI(); |
| 242 chrome_test_util::AssertToolbarNotVisible(); |
| 243 |
| 244 chrome_test_util::TapWebViewElementWithId("link"); |
| 245 |
| 246 // Main test is here: Make sure the header is still visible! |
| 247 chrome_test_util::AssertToolbarVisible(); |
| 248 } |
| 249 |
| 250 // Test to make sure the header is shown when a Tab opened by the current Tab is |
| 251 // closed even if the toolbar was not present previously. |
| 252 - (void)testShowHeaderWhenChildTabCloses { |
| 253 std::map<GURL, std::string> responses; |
| 254 const GURL URL = web::test::HttpServer::MakeUrl("http://origin"); |
| 255 const GURL destinationURL = |
| 256 web::test::HttpServer::MakeUrl("http://destination"); |
| 257 // JavaScript to open a window using window.open. |
| 258 std::string javaScript = |
| 259 base::StringPrintf("window.open(\"%s\");", destinationURL.spec().c_str()); |
| 260 |
| 261 // A long page with a link to execute JavaScript. |
| 262 responses[URL] = base::StringPrintf( |
| 263 "<p style='height:200em'>whatever</p>" |
| 264 "<a onclick='%s' id='link1'>link1</a>", |
| 265 javaScript.c_str()); |
| 266 // A long page with some simple text and link to close itself using |
| 267 // window.close. |
| 268 javaScript = "window.close()"; |
| 269 responses[destinationURL] = base::StringPrintf( |
| 270 "<p style='height:200em'>whatever</p><a onclick='%s' " |
| 271 "id='link2'>link2</a>", |
| 272 javaScript.c_str()); |
| 273 |
| 274 web::test::SetUpSimpleHttpServer(responses); |
| 275 chrome_test_util::SetContentSettingsBlockPopups(CONTENT_SETTING_ALLOW); |
| 276 |
| 277 [ChromeEarlGrey loadURL:URL]; |
| 278 AssertStringIsPresentOnPage("link1"); |
| 279 chrome_test_util::AssertMainTabCount(1); |
| 280 |
| 281 // Hide the toolbar. |
| 282 HideToolbarUsingUI(); |
| 283 chrome_test_util::AssertToolbarNotVisible(); |
| 284 |
| 285 // Open new window. |
| 286 chrome_test_util::TapWebViewElementWithId("link1"); |
| 287 |
| 288 // Check that a new Tab was created. |
| 289 AssertStringIsPresentOnPage("link2"); |
| 290 chrome_test_util::AssertMainTabCount(2); |
| 291 |
| 292 AssertURLIs(destinationURL); |
| 293 |
| 294 // Hide the toolbar. |
| 295 HideToolbarUsingUI(); |
| 296 chrome_test_util::AssertToolbarNotVisible(); |
| 297 |
| 298 // Close the tab. |
| 299 chrome_test_util::TapWebViewElementWithId("link2"); |
| 300 AssertStringIsPresentOnPage("link1"); |
| 301 |
| 302 // Make sure the toolbar is on the screen. |
| 303 chrome_test_util::AssertMainTabCount(1); |
| 304 chrome_test_util::AssertToolbarVisible(); |
| 305 } |
| 306 |
| 307 // Tests that the header is shown when a regular page (non-native page) is |
| 308 // loaded from a page where the header was not see before. |
| 309 // Also tests that auto-hide works correctly on new page loads. |
| 310 - (void)testShowHeaderOnRegularPageLoad { |
| 311 std::map<GURL, std::string> responses; |
| 312 const GURL originURL = web::test::HttpServer::MakeUrl("http://origin"); |
| 313 const GURL destinationURL = |
| 314 web::test::HttpServer::MakeUrl("http://destination"); |
| 315 |
| 316 const std::string manyLines = |
| 317 "<p style='height:100em'>a</p><p>End of lines</p>"; |
| 318 |
| 319 // A long page representing many lines and a link to the destination URL page. |
| 320 responses[originURL] = manyLines + "<a href='" + destinationURL.spec() + |
| 321 "' id='link1'>link1</a>"; |
| 322 // A long page representing many lines and a link to go back. |
| 323 responses[destinationURL] = manyLines + |
| 324 "<a href='javascript:void(0)' " |
| 325 "onclick='window.history.back()' " |
| 326 "id='link2'>link2</a>"; |
| 327 web::test::SetUpSimpleHttpServer(responses); |
| 328 |
| 329 [ChromeEarlGrey loadURL:originURL]; |
| 330 |
| 331 AssertStringIsPresentOnPage("link1"); |
| 332 // Dismiss the toolbar. |
| 333 HideToolbarUsingUI(); |
| 334 chrome_test_util::AssertToolbarNotVisible(); |
| 335 |
| 336 // Navigate to the other page. |
| 337 chrome_test_util::TapWebViewElementWithId("link1"); |
| 338 AssertStringIsPresentOnPage("link2"); |
| 339 |
| 340 // Make sure toolbar is shown since a new load has started. |
| 341 chrome_test_util::AssertToolbarVisible(); |
| 342 |
| 343 // Dismiss the toolbar. |
| 344 HideToolbarUsingUI(); |
| 345 chrome_test_util::AssertToolbarNotVisible(); |
| 346 |
| 347 // Go back. |
| 348 chrome_test_util::TapWebViewElementWithId("link2"); |
| 349 |
| 350 // Make sure the toolbar has loaded now that a new page has loaded. |
| 351 chrome_test_util::AssertToolbarVisible(); |
| 352 } |
| 353 |
| 354 // Tests that the header is shown when a native page is loaded from a page where |
| 355 // the header was not seen before. |
| 356 - (void)testShowHeaderOnNativePageLoad { |
| 357 std::map<GURL, std::string> responses; |
| 358 const GURL URL = web::test::HttpServer::MakeUrl("http://origin"); |
| 359 |
| 360 // A long page representing many lines and a link to go back. |
| 361 std::string manyLines = |
| 362 "<p style='height:100em'>a</p>" |
| 363 "<a onclick='window.history.back()' id='link'>link</a>"; |
| 364 responses[URL] = manyLines; |
| 365 web::test::SetUpSimpleHttpServer(responses); |
| 366 |
| 367 [ChromeEarlGrey loadURL:URL]; |
| 368 AssertStringIsPresentOnPage("link"); |
| 369 |
| 370 // Dismiss the toolbar. |
| 371 HideToolbarUsingUI(); |
| 372 chrome_test_util::AssertToolbarNotVisible(); |
| 373 |
| 374 // Go back to NTP, which is a native view. |
| 375 chrome_test_util::TapWebViewElementWithId("link"); |
| 376 |
| 377 // Make sure the toolbar is visible now that a new page has loaded. |
| 378 chrome_test_util::AssertToolbarVisible(); |
| 379 } |
| 380 |
| 381 // Tests that the header is shown when loading an error page in a native view |
| 382 // even if fullscreen was enabled previously. |
| 383 - (void)testShowHeaderOnErrorPage { |
| 384 std::map<GURL, std::string> responses; |
| 385 const GURL URL = web::test::HttpServer::MakeUrl("http://origin"); |
| 386 // A long page with some simple text -- a long page is necessary so that |
| 387 // enough content is present to ensure that the toolbar can be hidden safely. |
| 388 responses[URL] = base::StringPrintf( |
| 389 "<p style='height:100em'>a</p>" |
| 390 "<a href=\"%s\" id=\"link\">bad link</a>", |
| 391 ErrorPageResponseProvider::GetDnsFailureUrl().spec().c_str()); |
| 392 std::unique_ptr<web::DataResponseProvider> provider( |
| 393 new ErrorPageResponseProvider(responses)); |
| 394 web::test::SetUpHttpServer(std::move(provider)); |
| 395 |
| 396 [ChromeEarlGrey loadURL:URL]; |
| 397 HideToolbarUsingUI(); |
| 398 chrome_test_util::AssertToolbarNotVisible(); |
| 399 |
| 400 chrome_test_util::TapWebViewElementWithId("link"); |
| 401 AssertURLIs(ErrorPageResponseProvider::GetDnsFailureUrl()); |
| 402 chrome_test_util::AssertToolbarVisible(); |
| 403 } |
| 404 |
| 405 @end |
OLD | NEW |