| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 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 #import <XCTest/XCTest.h> | 5 #import <XCTest/XCTest.h> |
| 6 #include <map> | 6 #include <map> |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/ios/ios_util.h" | 10 #include "base/ios/ios_util.h" |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 @implementation BrowsingTestCase | 124 @implementation BrowsingTestCase |
| 125 | 125 |
| 126 // Matcher for the title of the current tab (on tablet only). | 126 // Matcher for the title of the current tab (on tablet only). |
| 127 id<GREYMatcher> TabWithTitle(const std::string& tab_title) { | 127 id<GREYMatcher> TabWithTitle(const std::string& tab_title) { |
| 128 id<GREYMatcher> notPartOfOmnibox = | 128 id<GREYMatcher> notPartOfOmnibox = |
| 129 grey_not(grey_ancestor(chrome_test_util::Omnibox())); | 129 grey_not(grey_ancestor(chrome_test_util::Omnibox())); |
| 130 return grey_allOf(grey_accessibilityLabel(base::SysUTF8ToNSString(tab_title)), | 130 return grey_allOf(grey_accessibilityLabel(base::SysUTF8ToNSString(tab_title)), |
| 131 notPartOfOmnibox, nil); | 131 notPartOfOmnibox, nil); |
| 132 } | 132 } |
| 133 | 133 |
| 134 // Matcher for a Go button that is interactable. | |
| 135 id<GREYMatcher> GoButtonMatcher() { | |
| 136 return grey_allOf(grey_accessibilityID(@"Go"), grey_interactable(), nil); | |
| 137 } | |
| 138 | |
| 139 // Tests that page successfully reloads. | 134 // Tests that page successfully reloads. |
| 140 - (void)testReload { | 135 - (void)testReload { |
| 141 // Set up test HTTP server responses. | 136 // Set up test HTTP server responses. |
| 142 std::unique_ptr<web::DataResponseProvider> provider( | 137 std::unique_ptr<web::DataResponseProvider> provider( |
| 143 new ReloadResponseProvider()); | 138 new ReloadResponseProvider()); |
| 144 web::test::SetUpHttpServer(std::move(provider)); | 139 web::test::SetUpHttpServer(std::move(provider)); |
| 145 | 140 |
| 146 GURL URL = ReloadResponseProvider::GetReloadTestUrl(); | 141 GURL URL = ReloadResponseProvider::GetReloadTestUrl(); |
| 147 [ChromeEarlGrey loadURL:URL]; | 142 [ChromeEarlGrey loadURL:URL]; |
| 148 std::string expectedBodyBeforeReload( | 143 std::string expectedBodyBeforeReload( |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 // Page with some text. | 362 // Page with some text. |
| 368 responses[destURL] = "You've arrived!"; | 363 responses[destURL] = "You've arrived!"; |
| 369 web::test::SetUpSimpleHttpServer(responses); | 364 web::test::SetUpSimpleHttpServer(responses); |
| 370 | 365 |
| 371 [ChromeEarlGrey loadURL:URL]; | 366 [ChromeEarlGrey loadURL:URL]; |
| 372 chrome_test_util::TapWebViewElementWithId("link"); | 367 chrome_test_util::TapWebViewElementWithId("link"); |
| 373 | 368 |
| 374 [[EarlGrey selectElementWithMatcher:OmniboxText(destURL.GetContent())] | 369 [[EarlGrey selectElementWithMatcher:OmniboxText(destURL.GetContent())] |
| 375 assertWithMatcher:grey_notNil()]; | 370 assertWithMatcher:grey_notNil()]; |
| 376 | 371 |
| 377 [self goBack]; | 372 [ChromeEarlGrey goBack]; |
| 378 [[EarlGrey selectElementWithMatcher:OmniboxText(URL.GetContent())] | 373 [[EarlGrey selectElementWithMatcher:OmniboxText(URL.GetContent())] |
| 379 assertWithMatcher:grey_notNil()]; | 374 assertWithMatcher:grey_notNil()]; |
| 380 } | 375 } |
| 381 | 376 |
| 382 // TODO(crbug.com/638674): Evaluate if this can move to shared code | |
| 383 // Navigates back to the previous webpage. | |
| 384 - (void)goBack { | |
| 385 GenericChromeCommand* backCommand = | |
| 386 [[GenericChromeCommand alloc] initWithTag:IDC_BACK]; | |
| 387 chrome_test_util::RunCommandWithActiveViewController(backCommand); | |
| 388 | |
| 389 [ChromeEarlGrey waitForPageToFinishLoading]; | |
| 390 } | |
| 391 | |
| 392 // Navigates forward to a previous webpage. | |
| 393 // TODO(crbug.com/638674): Evaluate if this can move to shared code | |
| 394 - (void)goForward { | |
| 395 GenericChromeCommand* forwardCommand = | |
| 396 [[GenericChromeCommand alloc] initWithTag:IDC_FORWARD]; | |
| 397 chrome_test_util::RunCommandWithActiveViewController(forwardCommand); | |
| 398 | |
| 399 [ChromeEarlGrey waitForPageToFinishLoading]; | |
| 400 } | |
| 401 | |
| 402 // Tests that a link with WebUI URL does not trigger a load. WebUI pages may | 377 // Tests that a link with WebUI URL does not trigger a load. WebUI pages may |
| 403 // have increased power and using the same web process (which may potentially | 378 // have increased power and using the same web process (which may potentially |
| 404 // be controlled by an attacker) is dangerous. | 379 // be controlled by an attacker) is dangerous. |
| 405 - (void)testTapLinkWithWebUIURL { | 380 - (void)testTapLinkWithWebUIURL { |
| 406 // Create map of canned responses and set up the test HTML server. | 381 // Create map of canned responses and set up the test HTML server. |
| 407 std::map<GURL, std::string> responses; | 382 std::map<GURL, std::string> responses; |
| 408 const GURL URL(web::test::HttpServer::MakeUrl("http://pageWithWebUILink")); | 383 const GURL URL(web::test::HttpServer::MakeUrl("http://pageWithWebUILink")); |
| 409 const char kPageHTML[] = | 384 const char kPageHTML[] = |
| 410 "<script>" | 385 "<script>" |
| 411 " function printMsg() {" | 386 " function printMsg() {" |
| (...skipping 16 matching lines...) Expand all Loading... |
| 428 // Verify that page did not change by checking its URL and message printed by | 403 // Verify that page did not change by checking its URL and message printed by |
| 429 // onclick event. | 404 // onclick event. |
| 430 [[EarlGrey selectElementWithMatcher:OmniboxText("chrome://version")] | 405 [[EarlGrey selectElementWithMatcher:OmniboxText("chrome://version")] |
| 431 assertWithMatcher:grey_nil()]; | 406 assertWithMatcher:grey_nil()]; |
| 432 [ChromeEarlGrey waitForWebViewContainingText:"Hello world!"]; | 407 [ChromeEarlGrey waitForWebViewContainingText:"Hello world!"]; |
| 433 | 408 |
| 434 // Verify that no new tabs were open which could load chrome://version. | 409 // Verify that no new tabs were open which could load chrome://version. |
| 435 chrome_test_util::AssertMainTabCount(1U); | 410 chrome_test_util::AssertMainTabCount(1U); |
| 436 } | 411 } |
| 437 | 412 |
| 438 // Tests that pressing the button on a POST-based form with same-page action | |
| 439 // does not change the page and that the back button works as expected | |
| 440 // afterwards. | |
| 441 - (void)testBrowsingPostToSamePage { | |
| 442 // TODO(crbug.com/714303): Re-enable this test on devices. | |
| 443 #if !TARGET_IPHONE_SIMULATOR | |
| 444 EARL_GREY_TEST_DISABLED(@"Test disabled on device."); | |
| 445 #endif | |
| 446 | |
| 447 // Create map of canned responses and set up the test HTML server. | |
| 448 std::map<GURL, std::string> responses; | |
| 449 const GURL firstURL = web::test::HttpServer::MakeUrl("http://first"); | |
| 450 const GURL formURL = web::test::HttpServer::MakeUrl("http://form"); | |
| 451 // This is just a page with some text. | |
| 452 responses[firstURL] = "foo"; | |
| 453 // This is a page with at button that posts to the current URL. | |
| 454 responses[formURL] = | |
| 455 "<form method='post'>" | |
| 456 "<input value='button' type='submit' id='button'></form>"; | |
| 457 web::test::SetUpSimpleHttpServer(responses); | |
| 458 | |
| 459 // Open the first URL so it's in history. | |
| 460 [ChromeEarlGrey loadURL:firstURL]; | |
| 461 | |
| 462 // Open the second URL, tap the button, and verify the browser navigates to | |
| 463 // the expected URL. | |
| 464 [ChromeEarlGrey loadURL:formURL]; | |
| 465 chrome_test_util::TapWebViewElementWithId("button"); | |
| 466 [[EarlGrey selectElementWithMatcher:OmniboxText(formURL.GetContent())] | |
| 467 assertWithMatcher:grey_notNil()]; | |
| 468 | |
| 469 // Go back once and verify the browser navigates to the form URL. | |
| 470 [self goBack]; | |
| 471 [[EarlGrey selectElementWithMatcher:OmniboxText(formURL.GetContent())] | |
| 472 assertWithMatcher:grey_notNil()]; | |
| 473 | |
| 474 // Go back a second time and verify the browser navigates to the first URL. | |
| 475 [self goBack]; | |
| 476 [[EarlGrey selectElementWithMatcher:OmniboxText(firstURL.GetContent())] | |
| 477 assertWithMatcher:grey_notNil()]; | |
| 478 } | |
| 479 | |
| 480 // Tests that evaluating user JavaScript that causes navigation correctly | 413 // Tests that evaluating user JavaScript that causes navigation correctly |
| 481 // modifies history. | 414 // modifies history. |
| 482 - (void)testBrowsingUserJavaScriptNavigation { | 415 - (void)testBrowsingUserJavaScriptNavigation { |
| 483 // TODO(crbug.com/640220): Keyboard entry inside the omnibox fails only on | 416 // TODO(crbug.com/640220): Keyboard entry inside the omnibox fails only on |
| 484 // iPad running iOS 10. | 417 // iPad running iOS 10. |
| 485 if (IsIPadIdiom() && base::ios::IsRunningOnIOS10OrLater()) | 418 if (IsIPadIdiom() && base::ios::IsRunningOnIOS10OrLater()) |
| 486 return; | 419 return; |
| 487 | 420 |
| 488 // Create map of canned responses and set up the test HTML server. | 421 // Create map of canned responses and set up the test HTML server. |
| 489 std::map<GURL, std::string> responses; | 422 std::map<GURL, std::string> responses; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 502 targetURL.spec().c_str()]; | 435 targetURL.spec().c_str()]; |
| 503 [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] | 436 [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] |
| 504 performAction:grey_typeText(script)]; | 437 performAction:grey_typeText(script)]; |
| 505 [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")] | 438 [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")] |
| 506 performAction:grey_tap()]; | 439 performAction:grey_tap()]; |
| 507 [ChromeEarlGrey waitForPageToFinishLoading]; | 440 [ChromeEarlGrey waitForPageToFinishLoading]; |
| 508 | 441 |
| 509 [[EarlGrey selectElementWithMatcher:OmniboxText(targetURL.GetContent())] | 442 [[EarlGrey selectElementWithMatcher:OmniboxText(targetURL.GetContent())] |
| 510 assertWithMatcher:grey_notNil()]; | 443 assertWithMatcher:grey_notNil()]; |
| 511 | 444 |
| 512 [self goBack]; | 445 [ChromeEarlGrey goBack]; |
| 513 [[EarlGrey selectElementWithMatcher:OmniboxText(startURL.GetContent())] | 446 [[EarlGrey selectElementWithMatcher:OmniboxText(startURL.GetContent())] |
| 514 assertWithMatcher:grey_notNil()]; | 447 assertWithMatcher:grey_notNil()]; |
| 515 } | 448 } |
| 516 | 449 |
| 517 // Tests that evaluating non-navigation user JavaScript doesn't affect history. | 450 // Tests that evaluating non-navigation user JavaScript doesn't affect history. |
| 518 - (void)testBrowsingUserJavaScriptWithoutNavigation { | 451 - (void)testBrowsingUserJavaScriptWithoutNavigation { |
| 519 // TODO(crbug.com/640220): Keyboard entry inside the omnibox fails only on | 452 // TODO(crbug.com/640220): Keyboard entry inside the omnibox fails only on |
| 520 // iPad running iOS 10. | 453 // iPad running iOS 10. |
| 521 if (IsIPadIdiom() && base::ios::IsRunningOnIOS10OrLater()) | 454 if (IsIPadIdiom() && base::ios::IsRunningOnIOS10OrLater()) |
| 522 return; | 455 return; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 537 // Execute some JavaScript in the omnibox. | 470 // Execute some JavaScript in the omnibox. |
| 538 [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] | 471 [[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()] |
| 539 performAction:grey_typeText(@"javascript:document.write('foo')")]; | 472 performAction:grey_typeText(@"javascript:document.write('foo')")]; |
| 540 [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")] | 473 [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")] |
| 541 performAction:grey_tap()]; | 474 performAction:grey_tap()]; |
| 542 | 475 |
| 543 [ChromeEarlGrey waitForWebViewContainingText:"foo"]; | 476 [ChromeEarlGrey waitForWebViewContainingText:"foo"]; |
| 544 | 477 |
| 545 // Verify that the JavaScript did not affect history by going back and then | 478 // Verify that the JavaScript did not affect history by going back and then |
| 546 // forward again. | 479 // forward again. |
| 547 [self goBack]; | 480 [ChromeEarlGrey goBack]; |
| 548 [[EarlGrey selectElementWithMatcher:OmniboxText(firstURL.GetContent())] | 481 [[EarlGrey selectElementWithMatcher:OmniboxText(firstURL.GetContent())] |
| 549 assertWithMatcher:grey_notNil()]; | 482 assertWithMatcher:grey_notNil()]; |
| 550 [self goForward]; | 483 [ChromeEarlGrey goForward]; |
| 551 [[EarlGrey selectElementWithMatcher:OmniboxText(secondURL.GetContent())] | 484 [[EarlGrey selectElementWithMatcher:OmniboxText(secondURL.GetContent())] |
| 552 assertWithMatcher:grey_notNil()]; | 485 assertWithMatcher:grey_notNil()]; |
| 553 } | 486 } |
| 554 | 487 |
| 555 // Tap the text field indicated by |ID| to open the keyboard, and then | |
| 556 // press the keyboard's "Go" button to submit the form. | |
| 557 - (void)submitFormUsingKeyboardGoButtonWithInputID:(const std::string&)ID { | |
| 558 // Disable EarlGrey's synchronization since it is blocked by opening the | |
| 559 // keyboard from a web view. | |
| 560 [[GREYConfiguration sharedInstance] | |
| 561 setValue:@NO | |
| 562 forConfigKey:kGREYConfigKeySynchronizationEnabled]; | |
| 563 | |
| 564 // Wait for web view to be interactable before tapping. | |
| 565 GREYCondition* interactableCondition = [GREYCondition | |
| 566 conditionWithName:@"Wait for web view to be interactable." | |
| 567 block:^BOOL { | |
| 568 NSError* error = nil; | |
| 569 id<GREYMatcher> webViewMatcher = WebViewInWebState( | |
| 570 chrome_test_util::GetCurrentWebState()); | |
| 571 [[EarlGrey selectElementWithMatcher:webViewMatcher] | |
| 572 assertWithMatcher:grey_interactable() | |
| 573 error:&error]; | |
| 574 return !error; | |
| 575 }]; | |
| 576 GREYAssert( | |
| 577 [interactableCondition waitWithTimeout:testing::kWaitForUIElementTimeout], | |
| 578 @"Web view did not become interactable."); | |
| 579 | |
| 580 web::WebState* currentWebState = chrome_test_util::GetCurrentWebState(); | |
| 581 [[EarlGrey selectElementWithMatcher:web::WebViewInWebState(currentWebState)] | |
| 582 performAction:web::WebViewTapElement(currentWebState, ID)]; | |
| 583 | |
| 584 // Wait until the keyboard shows up before tapping. | |
| 585 GREYCondition* condition = [GREYCondition | |
| 586 conditionWithName:@"Wait for the keyboard to show up." | |
| 587 block:^BOOL { | |
| 588 NSError* error = nil; | |
| 589 [[EarlGrey selectElementWithMatcher:GoButtonMatcher()] | |
| 590 assertWithMatcher:grey_notNil() | |
| 591 error:&error]; | |
| 592 return (error == nil); | |
| 593 }]; | |
| 594 GREYAssert([condition waitWithTimeout:10], | |
| 595 @"No keyboard with 'Go' button showed up."); | |
| 596 | |
| 597 [[EarlGrey selectElementWithMatcher:grey_accessibilityID(@"Go")] | |
| 598 performAction:grey_tap()]; | |
| 599 | |
| 600 // Reenable synchronization now that the keyboard has been closed. | |
| 601 [[GREYConfiguration sharedInstance] | |
| 602 setValue:@YES | |
| 603 forConfigKey:kGREYConfigKeySynchronizationEnabled]; | |
| 604 } | |
| 605 | |
| 606 // Tests that submitting a POST-based form by tapping the 'Go' button on the | |
| 607 // keyboard navigates to the correct URL and the back button works as expected | |
| 608 // afterwards. | |
| 609 // TODO(crbug.com/711108): Move test to forms_egtest.mm. | |
| 610 - (void)testBrowsingPostEntryWithKeyboard { | |
| 611 // TODO(crbug.com/704618): Re-enable this test on devices. | |
| 612 #if !TARGET_IPHONE_SIMULATOR | |
| 613 EARL_GREY_TEST_DISABLED(@"Test disabled on device."); | |
| 614 #endif | |
| 615 | |
| 616 // Create map of canned responses and set up the test HTML server. | |
| 617 std::map<GURL, std::string> responses; | |
| 618 const GURL URL = | |
| 619 web::test::HttpServer::MakeUrl("http://postEntryWithKeyboard"); | |
| 620 const GURL destinationURL = web::test::HttpServer::MakeUrl("http://foo"); | |
| 621 // This is a page this an input text field and a button that posts to the | |
| 622 // destination. | |
| 623 responses[URL] = base::StringPrintf( | |
| 624 "hello!" | |
| 625 "<form action='%s' method='post'>" | |
| 626 "<input value='textfield' id='textfield' type='text'></label>" | |
| 627 "<input type='submit'></form>", | |
| 628 destinationURL.spec().c_str()); | |
| 629 // This is the page that should be showing at the end of the test. | |
| 630 responses[destinationURL] = "baz!"; | |
| 631 web::test::SetUpSimpleHttpServer(responses); | |
| 632 | |
| 633 // Open the URL, focus the textfield,and submit via keyboard. | |
| 634 [ChromeEarlGrey loadURL:URL]; | |
| 635 [ChromeEarlGrey waitForWebViewContainingText:"hello!"]; | |
| 636 | |
| 637 [self submitFormUsingKeyboardGoButtonWithInputID:"textfield"]; | |
| 638 | |
| 639 // Verify that the browser navigates to the expected URL. | |
| 640 [ChromeEarlGrey waitForWebViewContainingText:"baz!"]; | |
| 641 [[EarlGrey selectElementWithMatcher:OmniboxText(destinationURL.GetContent())] | |
| 642 assertWithMatcher:grey_notNil()]; | |
| 643 | |
| 644 // Go back and verify that the browser navigates to the original URL. | |
| 645 [self goBack]; | |
| 646 [ChromeEarlGrey waitForWebViewContainingText:"hello!"]; | |
| 647 [[EarlGrey selectElementWithMatcher:OmniboxText(URL.GetContent())] | |
| 648 assertWithMatcher:grey_notNil()]; | |
| 649 } | |
| 650 | |
| 651 @end | 488 @end |
| OLD | NEW |