blob: 614379c5a7d0ccd699a4ea2fec1981bdf9e01c41 [file] [log] [blame]
// 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 <XCTest/XCTest.h>
#include "base/mac/foundation_util.h"
#include "base/metrics/field_trial.h"
#include "base/strings/sys_string_conversions.h"
#include "components/strings/grit/components_strings.h"
#include "components/version_info/version_info.h"
#include "ios/chrome/browser/chrome_url_constants.h"
#include "ios/chrome/browser/experimental_flags.h"
#import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
#include "ios/chrome/test/app/navigation_test_util.h"
#include "ios/chrome/test/app/web_view_interaction_test_util.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"
#import "ios/testing/wait_util.h"
#import "ios/web/public/web_client.h"
#include "ui/base/device_form_factor.h"
#include "ui/base/l10n/l10n_util.h"
#include "url/scheme_host_port.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
using chrome_test_util::BackButton;
using chrome_test_util::ForwardButton;
using chrome_test_util::StaticHtmlViewContainingText;
using chrome_test_util::TapWebViewElementWithId;
using chrome_test_util::WebViewContainingText;
namespace {
// Loads WebUI page with given |host|.
void LoadWebUIUrl(const std::string& host) {
GURL web_ui_url(url::SchemeHostPort(kChromeUIScheme, host, 0).Serialize());
[ChromeEarlGrey loadURL:web_ui_url];
}
// Adds wait for omnibox text matcher so that omnibox text can be updated.
// TODO(crbug.com/642207): This method has to be unified with the omniboxText
// matcher or resides in the same location with the omniboxText matcher.
id<GREYMatcher> WaitForOmniboxText(std::string text) {
MatchesBlock matches = ^BOOL(UIView* view) {
if (![view isKindOfClass:[OmniboxTextFieldIOS class]]) {
return NO;
}
OmniboxTextFieldIOS* omnibox =
base::mac::ObjCCast<OmniboxTextFieldIOS>(view);
GREYAssert(testing::WaitUntilConditionOrTimeout(
testing::kWaitForUIElementTimeout,
^{
return base::SysNSStringToUTF8(omnibox.text) == text;
}),
@"Omnibox did not contain %@", base::SysUTF8ToNSString(text));
return YES;
};
DescribeToBlock describe = ^(id<GREYDescription> description) {
[description appendText:@"omnibox text "];
[description appendText:base::SysUTF8ToNSString(text)];
};
return grey_allOf(
chrome_test_util::Omnibox(),
[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
descriptionBlock:describe],
nil);
}
} // namespace
// Test case for chrome://* WebUI pages.
@interface WebUITestCase : ChromeTestCase
@end
@implementation WebUITestCase
// Tests that chrome://version renders and contains correct version number and
// user agent string.
- (void)testVersion {
LoadWebUIUrl(kChromeUIVersionHost);
// Verify that app version is present on the page.
const std::string version = version_info::GetVersionNumber();
[[EarlGrey selectElementWithMatcher:WebViewContainingText(version)]
assertWithMatcher:grey_notNil()];
// Verify that mobile User Agent string is present on the page.
const bool isDesktopUA = false;
const std::string userAgent = web::GetWebClient()->GetUserAgent(isDesktopUA);
[[EarlGrey selectElementWithMatcher:WebViewContainingText(userAgent)]
assertWithMatcher:grey_notNil()];
}
// Tests that chrome://physical-web renders and the page title is present.
- (void)testPhysicalWeb {
// Enable the Physical Web via Chrome variation.
base::FieldTrialList::CreateFieldTrial("PhysicalWebEnabled", "Enabled");
LoadWebUIUrl(kChromeUIPhysicalWebHost);
// Verify that the title string is present on the page.
std::string pageTitle = l10n_util::GetStringUTF8(IDS_PHYSICAL_WEB_UI_TITLE);
[[EarlGrey selectElementWithMatcher:WebViewContainingText(pageTitle)]
assertWithMatcher:grey_notNil()];
}
// Tests that clicking on a link for a native page from chrome://chrome-urls
// navigates to that page.
- (void)testChromeURLNavigateToNativePage {
LoadWebUIUrl(kChromeUIChromeURLsHost);
// Tap on chrome://terms link on the page.
chrome_test_util::TapWebViewElementWithId(kChromeUITermsHost);
// Verify that the resulting page is chrome://terms.
[[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://terms")]
assertWithMatcher:grey_sufficientlyVisible()];
NSString* kTermsText = @"Google Chrome Terms of Service";
[[EarlGrey selectElementWithMatcher:StaticHtmlViewContainingText(kTermsText)]
assertWithMatcher:grey_notNil()];
}
// Tests that back navigation functions properly after navigation via anchor
// click.
- (void)testChromeURLBackNavigationFromAnchorClick {
LoadWebUIUrl(kChromeUIChromeURLsHost);
// Tap on chrome://version link on the page.
chrome_test_util::TapWebViewElementWithId(kChromeUIVersionHost);
// Verify that the resulting page is chrome://version.
[[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://version")]
assertWithMatcher:grey_sufficientlyVisible()];
const std::string kAuthorsText = "The Chromium Authors";
[[EarlGrey selectElementWithMatcher:WebViewContainingText(kAuthorsText)]
assertWithMatcher:grey_notNil()];
// Tap the back button in the toolbar and verify that the resulting page is
// the previously visited page chrome://chrome-urls.
[[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
[[EarlGrey
selectElementWithMatcher:WaitForOmniboxText("chrome://chrome-urls")]
assertWithMatcher:grey_sufficientlyVisible()];
const std::string kChromeURLsText = "List of Chrome URLs";
[[EarlGrey selectElementWithMatcher:WebViewContainingText(kChromeURLsText)]
assertWithMatcher:grey_notNil()];
}
// Tests that back and forward navigation between chrome URLs functions
// properly.
- (void)testChromeURLBackAndForwardNavigation {
// Navigate to the first URL chrome://version.
LoadWebUIUrl(kChromeUIVersionHost);
// Navigate to the second URL chrome://flags.
LoadWebUIUrl(kChromeUIFlagsHost);
// Tap the back button in the toolbar and verify that the resulting page's URL
// corresponds to the first URL chrome://version that was loaded.
[[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://version")]
assertWithMatcher:grey_sufficientlyVisible()];
// Tap the forward button in the toolbar and verify that the resulting page's
// URL corresponds the second URL chrome://flags that was loaded.
[[EarlGrey selectElementWithMatcher:ForwardButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://flags")]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that all URLs on chrome://chrome-urls page load without error.
- (void)testChromeURLsLoadWithoutError {
// Load WebUI pages and verify they load without any error.
for (size_t i = 0; i < kNumberOfChromeHostURLs; ++i) {
const char* host = kChromeHostURLs[i];
// Exclude non-WebUI pages, as they do not go through a "loading" phase as
// expected in LoadWebUIUrl.
if (host == kChromeUIBookmarksHost || host == kChromeUINewTabHost ||
host == kChromeUITermsHost) {
continue;
}
if (host == kChromeUIPhysicalWebHost &&
!experimental_flags::IsPhysicalWebEnabled()) {
continue;
}
LoadWebUIUrl(host);
const std::string chrome_url_path =
url::SchemeHostPort(kChromeUIScheme, kChromeHostURLs[i], 0).Serialize();
[[EarlGrey selectElementWithMatcher:WaitForOmniboxText(chrome_url_path)]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Load chrome://terms differently since it is a Native page and is never in
// the "loading" phase.
chrome_test_util::LoadUrl(GURL(kChromeUITermsURL));
[[EarlGrey selectElementWithMatcher:WaitForOmniboxText("chrome://terms")]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that loading an invalid Chrome URL results in an error page.
- (void)testChromeURLInvalid {
// Navigate to the native error page chrome://invalidchromeurl.
const std::string kChromeInvalidURL = "chrome://invalidchromeurl";
chrome_test_util::LoadUrl(GURL(kChromeInvalidURL));
// Verify that the resulting page is an error page.
[[EarlGrey selectElementWithMatcher:WaitForOmniboxText(kChromeInvalidURL)]
assertWithMatcher:grey_sufficientlyVisible()];
NSString* kError =
l10n_util::GetNSString(IDS_ERRORPAGES_HEADING_NOT_AVAILABLE);
id<GREYMatcher> messageMatcher = [GREYMatchers matcherForText:kError];
[[EarlGrey selectElementWithMatcher:messageMatcher]
assertWithMatcher:grey_notNil()];
}
@end