| Index: ios/chrome/test/earl_grey/chrome_matchers.mm
|
| diff --git a/ios/chrome/test/earl_grey/chrome_matchers.mm b/ios/chrome/test/earl_grey/chrome_matchers.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..eea05e7b07b7a2292a36a1718646f73d614c269a
|
| --- /dev/null
|
| +++ b/ios/chrome/test/earl_grey/chrome_matchers.mm
|
| @@ -0,0 +1,218 @@
|
| +// 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 "ios/chrome/test/earl_grey/chrome_matchers.h"
|
| +
|
| +#import <OCHamcrest/OCHamcrest.h>
|
| +
|
| +#import <WebKit/WebKit.h>
|
| +
|
| +#include "base/mac/foundation_util.h"
|
| +#include "base/strings/sys_string_conversions.h"
|
| +#include "base/test/ios/wait_util.h"
|
| +#include "components/strings/grit/components_strings.h"
|
| +#import "ios/chrome/browser/ui/collection_view/cells/collection_view_switch_item.h"
|
| +#import "ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.h"
|
| +#import "ios/chrome/browser/ui/static_content/static_html_view_controller.h"
|
| +#import "ios/chrome/browser/ui/toolbar/toolbar_controller.h"
|
| +#include "ios/chrome/grit/ios_strings.h"
|
| +#import "ios/chrome/test/app/chrome_test_util.h"
|
| +#import "ios/testing/wait_util.h"
|
| +#import "ios/web/public/block_types.h"
|
| +#import "ios/web/public/test/earl_grey/web_view_matchers.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +
|
| +namespace {
|
| +
|
| +// Script that returns document.body as a string.
|
| +NSString* const kGetDocumentBodyJavaScript =
|
| + @"document.body ? document.body.textContent : null";
|
| +
|
| +// Synchronously returns the result of executed JavaScript.
|
| +id ExecuteScriptInStaticController(
|
| + StaticHtmlViewController* html_view_controller,
|
| + NSString* script) {
|
| + __block id result = nil;
|
| + __block bool did_finish = false;
|
| + web::JavaScriptResultBlock completion_handler =
|
| + ^(id script_result, NSError* error) {
|
| + result = [script_result copy];
|
| + did_finish = true;
|
| + };
|
| + [html_view_controller executeJavaScript:script
|
| + completionHandler:completion_handler];
|
| +
|
| + GREYAssert(
|
| + testing::WaitUntilConditionOrTimeout(testing::kWaitForJSCompletionTimeout,
|
| + ^{
|
| + return did_finish;
|
| + }),
|
| + @"JavaScript did not complete");
|
| +
|
| + return [result autorelease];
|
| +}
|
| +
|
| +id<GREYMatcher> webViewWithNavDelegateOfClass(Class cls) {
|
| + MatchesBlock matches = ^BOOL(UIView* view) {
|
| + return [view isKindOfClass:[WKWebView class]] &&
|
| + [base::mac::ObjCCast<WKWebView>(view).navigationDelegate
|
| + isKindOfClass:cls];
|
| + };
|
| +
|
| + DescribeToBlock describe = ^(id<GREYDescription> description) {
|
| + [description appendText:@"web view with "];
|
| + [description appendText:NSStringFromClass(cls)];
|
| + [description appendText:@"navigation delegate"];
|
| + };
|
| +
|
| + return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
|
| + descriptionBlock:describe]
|
| + autorelease];
|
| +}
|
| +
|
| +id<GREYMatcher> collectionViewSwitchIsOn(BOOL isOn) {
|
| + MatchesBlock matches = ^BOOL(id element) {
|
| + CollectionViewSwitchCell* switchCell =
|
| + base::mac::ObjCCastStrict<CollectionViewSwitchCell>(element);
|
| + UISwitch* switchView = switchCell.switchView;
|
| + return (switchView.on && isOn) || (!switchView.on && !isOn);
|
| + };
|
| + DescribeToBlock describe = ^void(id<GREYDescription> description) {
|
| + NSString* name =
|
| + [NSString stringWithFormat:@"collectionViewSwitchInState(%@)",
|
| + isOn ? @"ON" : @"OFF"];
|
| + [description appendText:name];
|
| + };
|
| + return [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
|
| + descriptionBlock:describe]
|
| + autorelease];
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace chrome_test_util {
|
| +
|
| +id<GREYMatcher> buttonWithAccessibilityLabel(NSString* label) {
|
| + return grey_allOf(grey_accessibilityLabel(label),
|
| + grey_accessibilityTrait(UIAccessibilityTraitButton), nil);
|
| +}
|
| +
|
| +id<GREYMatcher> buttonWithAccessibilityLabelId(int message_id) {
|
| + return buttonWithAccessibilityLabel(
|
| + l10n_util::GetNSStringWithFixup(message_id));
|
| +}
|
| +
|
| +id<GREYMatcher> staticTextWithAccessibilityLabel(NSString* label) {
|
| + return grey_allOf(grey_accessibilityLabel(label),
|
| + grey_accessibilityTrait(UIAccessibilityTraitStaticText),
|
| + nil);
|
| +}
|
| +
|
| +id<GREYMatcher> staticTextWithAccessibilityLabelId(int message_id) {
|
| + return staticTextWithAccessibilityLabel(
|
| + l10n_util::GetNSStringWithFixup(message_id));
|
| +}
|
| +
|
| +id<GREYMatcher> webViewBelongingToWebController() {
|
| + return webViewWithNavDelegateOfClass(NSClassFromString(@"CRWWebController"));
|
| +}
|
| +
|
| +id<GREYMatcher> webViewContainingText(std::string text) {
|
| + return web::webViewContainingText(std::move(text), GetCurrentWebState());
|
| +}
|
| +
|
| +id<GREYMatcher> webViewNotContainingText(std::string text) {
|
| + return web::webViewNotContainingText(std::move(text), GetCurrentWebState());
|
| +}
|
| +
|
| +id<GREYMatcher> webViewContainingBlockedImage(std::string image_id) {
|
| + return web::webViewContainingBlockedImage(std::move(image_id),
|
| + GetCurrentWebState());
|
| +}
|
| +
|
| +id<GREYMatcher> staticHtmlViewContainingText(NSString* text) {
|
| + // The WKWebView in a static HTML view isn't part of a webState, but it
|
| + // does have the StaticHtmlViewController as its navigation delegate.
|
| + MatchesBlock matches = ^BOOL(WKWebView* webView) {
|
| + StaticHtmlViewController* html_view_controller =
|
| + base::mac::ObjCCast<StaticHtmlViewController>(
|
| + webView.navigationDelegate);
|
| +
|
| + __block BOOL did_succeed = NO;
|
| + NSDate* deadline =
|
| + [NSDate dateWithTimeIntervalSinceNow:testing::kWaitForUIElementTimeout];
|
| + while (([[NSDate date] compare:deadline] != NSOrderedDescending) &&
|
| + !did_succeed) {
|
| + id result = ExecuteScriptInStaticController(html_view_controller,
|
| + kGetDocumentBodyJavaScript);
|
| + if ([result isKindOfClass:[NSString class]]) {
|
| + NSString* body = base::mac::ObjCCast<NSString>(result);
|
| + did_succeed = [body containsString:text];
|
| + }
|
| + base::test::ios::SpinRunLoopWithMaxDelay(
|
| + base::TimeDelta::FromSecondsD(testing::kSpinDelaySeconds));
|
| + }
|
| + return did_succeed;
|
| + };
|
| +
|
| + DescribeToBlock describe = ^(id<GREYDescription> description) {
|
| + [description appendText:@"static HTML web view containing "];
|
| + [description appendText:text];
|
| + };
|
| +
|
| + return grey_allOf(
|
| + webViewWithNavDelegateOfClass([StaticHtmlViewController class]),
|
| + [[[GREYElementMatcherBlock alloc] initWithMatchesBlock:matches
|
| + descriptionBlock:describe]
|
| + autorelease],
|
| + nil);
|
| +}
|
| +
|
| +id<GREYMatcher> forwardButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_ACCNAME_FORWARD);
|
| +}
|
| +
|
| +id<GREYMatcher> backButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_ACCNAME_BACK);
|
| +}
|
| +
|
| +id<GREYMatcher> reloadButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_ACCNAME_RELOAD);
|
| +}
|
| +
|
| +id<GREYMatcher> stopButton() {
|
| + return buttonWithAccessibilityLabelId(IDS_IOS_ACCNAME_STOP);
|
| +}
|
| +
|
| +id<GREYMatcher> omnibox() {
|
| + return grey_kindOfClass([OmniboxTextFieldIOS class]);
|
| +}
|
| +
|
| +id<GREYMatcher> pageSecurityInfoButton() {
|
| + return grey_accessibilityLabel(@"Page Security Info");
|
| +}
|
| +
|
| +id<GREYMatcher> omniboxText(std::string text) {
|
| + return grey_allOf(omnibox(),
|
| + hasProperty(@"text", base::SysUTF8ToNSString(text)), nil);
|
| +}
|
| +
|
| +id<GREYMatcher> toolsMenuButton() {
|
| + return grey_allOf(grey_accessibilityID(kToolbarToolsMenuButtonIdentifier),
|
| + grey_sufficientlyVisible(), nil);
|
| +}
|
| +
|
| +id<GREYMatcher> showTabsButton() {
|
| + return grey_allOf(grey_accessibilityID(kToolbarStackButtonIdentifier),
|
| + grey_sufficientlyVisible(), nil);
|
| +}
|
| +
|
| +id<GREYMatcher> collectionViewSwitchCell(NSString* accessibilityIdentifier,
|
| + BOOL isOn) {
|
| + return grey_allOf(grey_accessibilityID(accessibilityIdentifier),
|
| + collectionViewSwitchIsOn(isOn), grey_sufficientlyVisible(),
|
| + nil);
|
| +}
|
| +
|
| +} // namespace chrome_test_util
|
|
|