Index: ios/chrome/browser/context_menu/context_menu_egtest.mm |
diff --git a/ios/chrome/browser/context_menu/context_menu_egtest.mm b/ios/chrome/browser/context_menu/context_menu_egtest.mm |
new file mode 100644 |
index 0000000000000000000000000000000000000000..21b5311a671bec36ca59f9ce040289597c19207f |
--- /dev/null |
+++ b/ios/chrome/browser/context_menu/context_menu_egtest.mm |
@@ -0,0 +1,240 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#import <EarlGrey/EarlGrey.h> |
+#import <UIKit/UIKit.h> |
+#import <XCTest/XCTest.h> |
+ |
+#include "base/strings/sys_string_conversions.h" |
+#include "ios/chrome/browser/ui/ui_util.h" |
+#include "ios/chrome/grit/ios_strings.h" |
+#import "ios/chrome/test/app/chrome_test_util.h" |
+#import "ios/chrome/test/app/settings_test_util.h" |
+#import "ios/chrome/test/app/tab_test_util.h" |
+#include "ios/chrome/test/app/web_view_interaction_test_util.h" |
+#import "ios/chrome/test/earl_grey/chrome_actions.h" |
+#import "ios/chrome/test/earl_grey/chrome_assertions.h" |
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" |
+#import "ios/chrome/test/earl_grey/chrome_matchers.h" |
+#import "ios/chrome/test/earl_grey/chrome_test_case.h" |
+#include "ios/chrome/test/earl_grey/chrome_util.h" |
+#import "ios/testing/wait_util.h" |
+#import "ios/web/public/test/earl_grey/web_view_matchers.h" |
+#import "ios/web/public/test/http_server.h" |
+#import "ios/web/public/test/http_server_util.h" |
+#include "url/gurl.h" |
+ |
+using chrome_test_util::buttonWithAccessibilityLabelId; |
+ |
+namespace { |
+const char kUrlChromiumLogoPage[] = |
+ "http://ios/testing/data/http_server_files/chromium_logo_page.html"; |
+const char kUrlChromiumLogoImg[] = |
+ "http://ios/testing/data/http_server_files/chromium_logo.png"; |
+const char kUrlInitialPage[] = "http://scenarioContextMenuOpenInNewTab"; |
+const char kUrlDestinationPage[] = "http://destination"; |
+const char kChromiumImageID[] = "chromium_image"; |
+const char kDestinationLinkID[] = "link"; |
+ |
+// HTML content of the destination page that sets the page title. |
+const char kDestinationHtml[] = |
+ "<script>document.title='new doc'</script>You made it!"; |
+ |
+// Matcher for the open image button in the context menu. |
+id<GREYMatcher> openImageButton() { |
+ return buttonWithAccessibilityLabelId(IDS_IOS_CONTENT_CONTEXT_OPENIMAGE); |
+} |
+ |
+// Matcher for the open image in new tab button in the context menu. |
+id<GREYMatcher> openImageInNewTabButton() { |
+ return buttonWithAccessibilityLabelId( |
+ IDS_IOS_CONTENT_CONTEXT_OPENIMAGENEWTAB); |
+} |
+ |
+// Matcher for the open link in new tab button in the context menu. |
+id<GREYMatcher> openLinkInNewTabButton() { |
+ return buttonWithAccessibilityLabelId(IDS_IOS_CONTENT_CONTEXT_OPENLINKNEWTAB); |
+} |
+ |
+// Long press on |elementId| to trigger context menu and then tap on |
+// |contextMenuItemButton| item. |
+void LongPressElementAndTapOnButton(const char* elementId, |
+ id<GREYMatcher> contextMenuItemButton) { |
+ [[EarlGrey selectElementWithMatcher:chrome_test_util:: |
+ webViewBelongingToWebController()] |
+ performAction:chrome_test_util::longPressElementForContextMenu(elementId, |
+ true)]; |
+ |
+ [[EarlGrey selectElementWithMatcher:contextMenuItemButton] |
+ assertWithMatcher:grey_notNil()]; |
+ [[EarlGrey selectElementWithMatcher:contextMenuItemButton] |
+ performAction:grey_tap()]; |
+ [[EarlGrey selectElementWithMatcher:contextMenuItemButton] |
+ assertWithMatcher:grey_nil()]; |
+} |
+ |
+// A simple wrapper that sleeps for 1s to wait for the animation, triggered from |
+// opening a new tab through context menu, to finish before selecting tab. |
+// TODO(crbug.com/643792): Remove this function when the bug is fixed. |
+void SelectTabAtIndexInCurrentMode(NSUInteger index) { |
+ // Delay for 1 second. |
+ GREYCondition* myCondition = [GREYCondition conditionWithName:@"delay" |
+ block:^BOOL { |
+ return NO; |
+ }]; |
+ [myCondition waitWithTimeout:1U]; |
+ |
+ chrome_test_util::SelectTabAtIndexInCurrentMode(index); |
+} |
+ |
+} // namespace |
+ |
+// Context menu tests for Chrome. |
+@interface ContextMenuTestCase : ChromeTestCase |
+@end |
+ |
+@implementation ContextMenuTestCase |
+ |
++ (void)setUp { |
+ [super setUp]; |
+ chrome_test_util::SetContentSettingsBlockPopups(CONTENT_SETTING_ALLOW); |
+} |
+ |
++ (void)tearDown { |
+ chrome_test_util::SetContentSettingsBlockPopups(CONTENT_SETTING_DEFAULT); |
+ [super tearDown]; |
+} |
+ |
+// Tests that selecting "Open Image" from the context menu properly opens the |
+// image in the current tab. |
+- (void)testOpenImageInCurrentTabFromContextMenu { |
+ GURL pageURL = web::test::HttpServer::MakeUrl(kUrlChromiumLogoPage); |
+ GURL imageURL = web::test::HttpServer::MakeUrl(kUrlChromiumLogoImg); |
+ web::test::SetUpFileBasedHttpServer(); |
+ [ChromeEarlGrey loadURL:pageURL]; |
+ chrome_test_util::AssertMainTabCount(1U); |
+ |
+ LongPressElementAndTapOnButton(kChromiumImageID, openImageButton()); |
+ |
+ // Verify url and tab count. |
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText( |
+ imageURL.GetContent())] |
+ assertWithMatcher:grey_notNil()]; |
+ chrome_test_util::AssertMainTabCount(1U); |
+} |
+ |
+// Tests that selecting "Open Image in New Tab" from the context menu properly |
+// opens the image in a new background tab. |
+- (void)testOpenImageInNewTabFromContextMenu { |
+ GURL pageURL = web::test::HttpServer::MakeUrl(kUrlChromiumLogoPage); |
+ GURL imageURL = web::test::HttpServer::MakeUrl(kUrlChromiumLogoImg); |
+ web::test::SetUpFileBasedHttpServer(); |
+ [ChromeEarlGrey loadURL:pageURL]; |
+ chrome_test_util::AssertMainTabCount(1U); |
+ |
+ LongPressElementAndTapOnButton(kChromiumImageID, openImageInNewTabButton()); |
+ |
+ SelectTabAtIndexInCurrentMode(1U); |
+ |
+ // Verify url and tab count. |
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText( |
+ imageURL.GetContent())] |
+ assertWithMatcher:grey_notNil()]; |
+ chrome_test_util::AssertMainTabCount(2U); |
+} |
+ |
+// Tests "Open in New Tab" on context menu. |
+- (void)testContextMenuOpenInNewTab { |
+ // Set up test simple http server. |
+ std::map<GURL, std::string> responses; |
+ GURL initialURL = web::test::HttpServer::MakeUrl(kUrlInitialPage); |
+ GURL destinationURL = web::test::HttpServer::MakeUrl(kUrlDestinationPage); |
+ |
+ // The initial page contains a link to the destination page. |
+ responses[initialURL] = "<a style='margin-left:50px' href='" + |
+ destinationURL.spec() + "' id='link'>link</a>"; |
+ responses[destinationURL] = kDestinationHtml; |
+ |
+ web::test::SetUpSimpleHttpServer(responses); |
+ [ChromeEarlGrey loadURL:initialURL]; |
+ chrome_test_util::AssertMainTabCount(1U); |
+ |
+ LongPressElementAndTapOnButton(kDestinationLinkID, openLinkInNewTabButton()); |
+ |
+ SelectTabAtIndexInCurrentMode(1U); |
+ |
+ // Verify url and tab count. |
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText( |
+ destinationURL.GetContent())] |
+ assertWithMatcher:grey_notNil()]; |
+ chrome_test_util::AssertMainTabCount(2U); |
+} |
+ |
+// Tests "Open in New Tab" on context menu on a link that requires scrolling |
+// on the page to verify that context menu can be properly triggered in the |
+// current screen view. |
+- (void)testContextMenuOpenInNewTabFromTallPage { |
+ // Set up test simple http server. |
+ std::map<GURL, std::string> responses; |
+ GURL initialURL = |
+ web::test::HttpServer::MakeUrl("http://scenarioContextMenuOpenInNewTab"); |
+ GURL destinationURL = web::test::HttpServer::MakeUrl("http://destination"); |
+ |
+ // The initial page contains a link to the destination page that is below a |
+ // really tall div so that scrolling is required. |
+ responses[initialURL] = |
+ "<div style='height:4000px'></div>" |
+ "<a style='margin-left:50px' href='" + |
+ destinationURL.spec() + "' id='link'>link</a>"; |
+ responses[destinationURL] = kDestinationHtml; |
+ |
+ web::test::SetUpSimpleHttpServer(responses); |
+ [ChromeEarlGrey loadURL:initialURL]; |
+ chrome_test_util::AssertMainTabCount(1U); |
+ |
+ // Scroll down on the web view to make the link visible. |
+ [[EarlGrey |
+ selectElementWithMatcher:webViewScrollView( |
+ chrome_test_util::GetCurrentWebState())] |
+ performAction:grey_swipeFastInDirection(kGREYDirectionUp)]; |
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::webViewContainingText( |
+ kDestinationLinkID)] |
+ assertWithMatcher:grey_notNil()]; |
+ |
+ LongPressElementAndTapOnButton(kDestinationLinkID, openLinkInNewTabButton()); |
+ |
+ // Earl Grey cannot preperly synchronize some animations, so adding a |
+ // WaitUntilCondition to wait for the new tab opening animation to finish |
+ // and the scroll view to become interactable. |
+ ConditionBlock condition = ^{ |
+ NSError* error = nil; |
+ [[EarlGrey |
+ selectElementWithMatcher:webViewScrollView( |
+ chrome_test_util::GetCurrentWebState())] |
+ assertWithMatcher:grey_interactable() |
+ error:&error]; |
+ return !error; |
+ }; |
+ GREYAssert(testing::WaitUntilConditionOrTimeout( |
+ testing::kWaitForUIElementTimeout, condition), |
+ @"Web view did not become interactable"); |
+ |
+ // Make the toolbar visible by scrolling up on the web view to select the |
+ // newly opened tab. |
+ [[EarlGrey |
+ selectElementWithMatcher:webViewScrollView( |
+ chrome_test_util::GetCurrentWebState())] |
+ performAction:grey_swipeFastInDirection(kGREYDirectionDown)]; |
+ chrome_test_util::AssertToolbarVisible(); |
+ |
+ SelectTabAtIndexInCurrentMode(1U); |
+ |
+ // Verify url and tab count. |
+ [[EarlGrey selectElementWithMatcher:chrome_test_util::omniboxText( |
+ destinationURL.GetContent())] |
+ assertWithMatcher:grey_notNil()]; |
+ chrome_test_util::AssertMainTabCount(2U); |
+} |
+ |
+@end |