| // Copyright 2016 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #import <XCTest/XCTest.h> |
| |
| #import "base/apple/foundation_util.h" |
| #import "base/metrics/field_trial.h" |
| #import "base/strings/sys_string_conversions.h" |
| #import "base/test/ios/wait_util.h" |
| #import "components/strings/grit/components_strings.h" |
| #import "components/version_info/version_info.h" |
| #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h" |
| #import "ios/chrome/browser/ui/webui/web_ui_test_utils.h" |
| #import "ios/chrome/common/channel_info.h" |
| #import "ios/chrome/grit/ios_chromium_strings.h" |
| #import "ios/chrome/test/earl_grey/chrome_earl_grey.h" |
| #import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" |
| #import "ios/chrome/test/earl_grey/chrome_matchers.h" |
| #import "ios/chrome/test/earl_grey/chrome_test_case.h" |
| #import "ios/components/webui/web_ui_url_constants.h" |
| #import "ios/testing/earl_grey/earl_grey_test.h" |
| #import "net/test/embedded_test_server/embedded_test_server.h" |
| #import "ui/base/device_form_factor.h" |
| #import "ui/base/l10n/l10n_util.h" |
| |
| using chrome_test_util::BackButton; |
| using chrome_test_util::ForwardButton; |
| |
| // Test case for chrome://* WebUI pages. |
| @interface WebUITestCase : ChromeTestCase |
| @end |
| |
| @implementation WebUITestCase |
| |
| // Tests that the WebUI pages (chrome://version) have the correct User Agent. |
| - (void)testUserAgent { |
| [ChromeEarlGrey loadURL:WebUIPageUrlWithHost(kChromeUIVersionHost)]; |
| |
| NSString* userAgent = [ChromeEarlGrey mobileUserAgentString]; |
| // Verify that JavaScript navigator.userAgent returns the mobile User Agent. |
| base::Value result = |
| [ChromeEarlGrey evaluateJavaScript:@"navigator.userAgent"]; |
| GREYAssertTrue(result.is_string(), @"Result is not a string."); |
| NSString* navigatorUserAgent = base::SysUTF8ToNSString(result.GetString()); |
| GREYAssertEqualObjects(userAgent, navigatorUserAgent, |
| @"User-Agent strings did not match"); |
| } |
| |
| // Tests that chrome://version renders and contains correct version number and |
| // user agent string. |
| - (void)testVersion { |
| [ChromeEarlGrey loadURL:WebUIPageUrlWithHost(kChromeUIVersionHost)]; |
| |
| // Verify that app version is present on the page. |
| const std::string version(version_info::GetVersionNumber()); |
| [ChromeEarlGrey waitForWebStateContainingText:version]; |
| |
| NSString* userAgent = [ChromeEarlGrey mobileUserAgentString]; |
| std::string userAgentString = base::SysNSStringToUTF8(userAgent); |
| |
| // Verify that mobile User Agent string is present on the page. Testing for |
| // only a portion of the string is sufficient to ensure the value has been |
| // populated in the UI and it is not blank. However, the exact string value is |
| // not validated as this test does not have access to get the full User Agent |
| // string from the WebClient. |
| [ChromeEarlGrey waitForWebStateContainingText:userAgentString]; |
| } |
| |
| // Tests that clicking on a chrome://terms link from chrome://chrome-urls |
| // navigates to terms page. |
| - (void)testChromeURLNavigateToTerms { |
| [ChromeEarlGrey loadURL:WebUIPageUrlWithHost(kChromeUIChromeURLsHost)]; |
| |
| // Tap on chrome://terms link on the page. |
| [ChromeEarlGrey |
| tapWebStateElementWithID:[NSString |
| stringWithUTF8String:kChromeUITermsHost]]; |
| |
| // Verify that the resulting page is chrome://terms. |
| GREYAssert(WaitForOmniboxURLString(kChromeUITermsURL), |
| @"Omnibox does not contain URL."); |
| const std::string kTermsText = "Terms of Service"; |
| [ChromeEarlGrey waitForWebStateContainingText:kTermsText]; |
| } |
| |
| // Tests that back navigation functions properly after navigation via anchor |
| // click. |
| - (void)testChromeURLBackNavigationFromAnchorClick { |
| [ChromeEarlGrey loadURL:GURL(kChromeUIChromeURLsURL)]; |
| |
| // Tap on chrome://version link on the page. |
| [ChromeEarlGrey |
| tapWebStateElementWithID:[NSString |
| stringWithUTF8String:kChromeUIVersionHost]]; |
| |
| // Verify that the resulting page is chrome://version. |
| GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), |
| @"Omnibox did not contain URL."); |
| [ChromeEarlGrey |
| waitForWebStateContainingText:l10n_util::GetStringUTF8( |
| IDS_IOS_ABOUT_VERSION_COMPANY_NAME)]; |
| |
| // 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()]; |
| GREYAssert(WaitForOmniboxURLString(kChromeUIChromeURLsURL), |
| @"Omnibox did not contain URL."); |
| [ChromeEarlGrey waitForWebStateContainingText:"List of Chrome URLs"]; |
| } |
| |
| // Tests that back and forward navigation between chrome URLs functions |
| // properly. |
| - (void)testChromeURLBackAndForwardAndReloadNavigation { |
| // Navigate to the first URL chrome://version. |
| [ChromeEarlGrey loadURL:GURL(kChromeUIVersionURL)]; |
| |
| // Navigate to the second URL chrome://chrome-urls. |
| [ChromeEarlGrey loadURL:GURL(kChromeUIChromeURLsURL)]; |
| |
| // 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()]; |
| GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), |
| @"Omnibox did not contain URL."); |
| |
| // Tap the forward button in the toolbar and verify that the resulting page's |
| // URL corresponds the second URL chrome://chrome-urls that was loaded. |
| [[EarlGrey selectElementWithMatcher:ForwardButton()] |
| performAction:grey_tap()]; |
| GREYAssert(WaitForOmniboxURLString(kChromeUIChromeURLsURL), |
| @"Omnibox did not contain URL."); |
| |
| // Tap the back button in the toolbar then reload, and verify that the |
| // resulting page corresponds to the first URL. |
| [[EarlGrey selectElementWithMatcher:BackButton()] performAction:grey_tap()]; |
| [ChromeEarlGrey waitForPageToFinishLoading]; |
| [ChromeEarlGrey reload]; |
| GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), |
| @"Omnibox did not contain URL."); |
| |
| // Make sure forward navigation is still possible. |
| [[EarlGrey selectElementWithMatcher:ForwardButton()] |
| performAction:grey_tap()]; |
| GREYAssert(WaitForOmniboxURLString(kChromeUIChromeURLsURL), |
| @"Omnibox did not contain URL."); |
| } |
| |
| // 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. |
| if (host == kChromeUINewTabHost) { |
| continue; |
| } |
| GURL URL = WebUIPageUrlWithHost(host); |
| [ChromeEarlGrey loadURL:URL]; |
| |
| GREYAssert(WaitForOmniboxURLString(URL.spec()), |
| @"Omnibox did not contain URL."); |
| } |
| } |
| |
| // 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"; |
| [ChromeEarlGrey loadURL:GURL(kChromeInvalidURL)]; |
| |
| // Verify that the resulting page is an error page. |
| GREYAssert(WaitForOmniboxURLString(kChromeInvalidURL), |
| @"Omnibox did not contain URL."); |
| std::string errorMessage = net::ErrorToShortString(net::ERR_INVALID_URL); |
| [ChromeEarlGrey waitForWebStateContainingText:errorMessage]; |
| } |
| |
| // Tests that repeated back/forward navigation from web URL is allowed. |
| - (void)testBackForwardFromWebURL { |
| GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); |
| |
| std::string chromeVersionWebText = |
| l10n_util::GetStringUTF8(IDS_IOS_ABOUT_VERSION_COMPANY_NAME); |
| const char kWebPageText[] = "pony"; |
| |
| [ChromeEarlGrey loadURL:GURL(kChromeUIVersionURL)]; |
| |
| GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), |
| @"Omnibox did not contain URL."); |
| [ChromeEarlGrey waitForWebStateContainingText:chromeVersionWebText]; |
| |
| GURL webURL = self.testServer->GetURL("/pony.html"); |
| [ChromeEarlGrey loadURL:webURL]; |
| [ChromeEarlGrey waitForWebStateContainingText:kWebPageText]; |
| |
| [ChromeEarlGrey goBack]; |
| GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), |
| @"Omnibox did not contain URL."); |
| [ChromeEarlGrey waitForWebStateContainingText:chromeVersionWebText]; |
| |
| [ChromeEarlGrey goForward]; |
| [ChromeEarlGrey waitForWebStateContainingText:kWebPageText]; |
| |
| [ChromeEarlGrey goBack]; |
| GREYAssert(WaitForOmniboxURLString(kChromeUIVersionURL), |
| @"Omnibox did not contain URL."); |
| [ChromeEarlGrey waitForWebStateContainingText:chromeVersionWebText]; |
| } |
| |
| - (void)testChromeFlagsOnNTP { |
| // Start with NTP and load chrome://flags. |
| [ChromeEarlGrey loadURL:GURL(kChromeUIFlagsURL)]; |
| |
| GREYAssert(WaitForOmniboxURLString(kChromeUIFlagsURL), |
| @"Omnibox did not contain URL."); |
| |
| // Validates that some of the expected text on the page exists. |
| [ChromeEarlGrey waitForWebStateContainingText:"Experiments"]; |
| [ChromeEarlGrey waitForWebStateContainingText:"Available"]; |
| |
| // Validates that the experimental flags container is visible. |
| NSString* flags_page_warning = |
| l10n_util::GetNSString(IDS_FLAGS_UI_PAGE_WARNING); |
| [ChromeEarlGrey waitForWebStateContainingText:base::SysNSStringToUTF8( |
| flags_page_warning)]; |
| } |
| |
| - (void)testChromeFlagsOnWebsite { |
| // Starts with loading a website. |
| GREYAssertTrue(self.testServer->Start(), @"Test server failed to start."); |
| |
| const char kWebPageText[] = "pony"; |
| GURL webURL = self.testServer->GetURL("/pony.html"); |
| [ChromeEarlGrey loadURL:webURL]; |
| [ChromeEarlGrey waitForWebStateContainingText:kWebPageText]; |
| |
| // Then load chrome://flags in the same tab that has loaded a website. |
| [ChromeEarlGrey loadURL:WebUIPageUrlWithHost(kChromeUIFlagsHost)]; |
| |
| GREYAssert(WaitForOmniboxURLString(kChromeUIFlagsURL), |
| @"Omnibox did not contain URL."); |
| |
| // Validates that some of the expected text on the page exists. |
| [ChromeEarlGrey waitForWebStateContainingText:"Experiments"]; |
| [ChromeEarlGrey waitForWebStateContainingText:"Available"]; |
| |
| NSString* flags_page_warning = |
| l10n_util::GetNSString(IDS_FLAGS_UI_PAGE_WARNING); |
| [ChromeEarlGrey waitForWebStateContainingText:base::SysNSStringToUTF8( |
| flags_page_warning)]; |
| } |
| |
| - (void)testChromePasswordManagerInternalsSite { |
| GURL URL = WebUIPageUrlWithHost(kChromeUIPasswordManagerInternalsHost); |
| [ChromeEarlGrey loadURL:URL]; |
| |
| GREYAssert(WaitForOmniboxURLString(URL.spec()), |
| @"Omnibox did not contain URL."); |
| |
| // Validates that some of the expected text on the page exists. |
| [ChromeEarlGrey waitForWebStateContainingText:"Variations"]; |
| [ChromeEarlGrey waitForWebStateContainingText:"Password Manager Internals"]; |
| } |
| |
| - (void)testChromeAutofillInternalsSite { |
| GURL URL = WebUIPageUrlWithHost(kChromeUIAutofillInternalsHost); |
| [ChromeEarlGrey loadURL:URL]; |
| |
| // Autofill-Internals stores the log filter configuration in the URL's |
| // fragment identifier (after the hash). |
| GREYAssert(WaitForOmniboxURLString(URL.spec(), false), |
| @"Omnibox did not contain URL."); |
| |
| // Validates that some of the expected text on the page exists. |
| [ChromeEarlGrey waitForWebStateContainingText:"Variations"]; |
| [ChromeEarlGrey waitForWebStateContainingText:"Autofill Internals"]; |
| } |
| |
| // Test chrome://userdefaults-internals page. |
| - (void)testChromeUserdefaultsInternalSite { |
| if (GetChannel() == version_info::Channel::STABLE) { |
| // This page is not supported on STABLE build. |
| return; |
| } |
| |
| // Start with NTP and load chrome://userdefaults-internals. |
| GURL URL = WebUIPageUrlWithHost(kChromeUIUserDefaultsInternalsHost); |
| [ChromeEarlGrey loadURL:URL]; |
| |
| // Autofill-Internals stores the log filter configuration in the URL's |
| // fragment identifier (after the hash). |
| GREYAssert(WaitForOmniboxURLString(URL.spec()), |
| @"Omnibox did not contain URL"); |
| |
| // Validates that some of the expected text on the page exists. |
| [ChromeEarlGrey waitForWebStateContainingText:"List of user defaults:"]; |
| } |
| |
| // Test chrome://userdefaults-internals page in incognito. |
| - (void)testChromeUserdefaultsInternalIncognitoSite { |
| if (GetChannel() == version_info::Channel::STABLE) { |
| // This page is not supported on STABLE build. |
| return; |
| } |
| |
| // Start with incognito NTP and load chrome://userdefaults-internals. |
| GURL URL = WebUIPageUrlWithHost(kChromeUIUserDefaultsInternalsHost); |
| [ChromeEarlGrey openNewIncognitoTab]; |
| [ChromeEarlGrey loadURL:URL]; |
| |
| // Autofill-Internals stores the log filter configuration in the URL's |
| // fragment identifier (after the hash). |
| GREYAssert(WaitForOmniboxURLString(URL.spec()), |
| @"Omnibox did not contain URL"); |
| |
| // Validates that some of the expected text on the page exists. |
| [ChromeEarlGrey waitForWebStateContainingText: |
| "This page is not available in incognito mode."]; |
| } |
| |
| @end |