Commit b9ad0e78 authored by Gauthier Ambard's avatar Gauthier Ambard Committed by Commit Bot

Add EG test to check the toolbar visibility

This CL adds an Earl Grey test to ensure that the toolbar buttons and
the toolbar visibility is correctly updated when the size class changes.

Bug: 804726
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: Iee3937485ddf379695fabe420ce3311ddea4aba3
Reviewed-on: https://chromium-review.googlesource.com/919061Reviewed-by: default avatarSylvain Defresne <sdefresne@chromium.org>
Reviewed-by: default avatarOlivier Robin <olivierrobin@chromium.org>
Reviewed-by: default avataredchin <edchin@chromium.org>
Commit-Queue: Gauthier Ambard <gambard@chromium.org>
Cr-Commit-Position: refs/heads/master@{#537775}
parent fed9b413
...@@ -2069,7 +2069,7 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint { ...@@ -2069,7 +2069,7 @@ applicationCommandEndpoint:(id<ApplicationCommands>)applicationCommandEndpoint {
// The height of the secondary toolbar with the bottom safe area inset included. // The height of the secondary toolbar with the bottom safe area inset included.
// Returns 0 if the toolbar should be hidden. // Returns 0 if the toolbar should be hidden.
- (CGFloat)secondaryToolbarHeightWithInset { - (CGFloat)secondaryToolbarHeightWithInset {
if (!IsSplitToolbarMode()) if (!IsSplitToolbarMode(self))
return 0; return 0;
UIView* secondaryToolbar = UIView* secondaryToolbar =
......
...@@ -85,11 +85,13 @@ source_set("eg_tests") { ...@@ -85,11 +85,13 @@ source_set("eg_tests") {
] ]
deps = [ deps = [
":adaptive_ui",
"//base", "//base",
"//components/strings", "//components/strings",
"//ios/chrome/app/strings", "//ios/chrome/app/strings",
"//ios/chrome/browser/ui:ui_util", "//ios/chrome/browser/ui:ui_util",
"//ios/chrome/browser/ui/toolbar/public", "//ios/chrome/browser/ui/toolbar/public",
"//ios/chrome/browser/ui/util",
"//ios/chrome/test/app:test_support", "//ios/chrome/test/app:test_support",
"//ios/chrome/test/earl_grey:test_support", "//ios/chrome/test/earl_grey:test_support",
"//ios/testing/earl_grey:earl_grey_support", "//ios/testing/earl_grey:earl_grey_support",
......
...@@ -6,9 +6,12 @@ ...@@ -6,9 +6,12 @@
#import <XCTest/XCTest.h> #import <XCTest/XCTest.h>
#include "components/strings/grit/components_strings.h" #include "components/strings/grit/components_strings.h"
#import "ios/chrome/browser/ui/toolbar/adaptive/primary_toolbar_view.h"
#import "ios/chrome/browser/ui/toolbar/adaptive/secondary_toolbar_view.h"
#import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_constants.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_controller_constants.h"
#include "ios/chrome/browser/ui/ui_util.h" #include "ios/chrome/browser/ui/ui_util.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h" #import "ios/chrome/browser/ui/uikit_ui_util.h"
#import "ios/chrome/browser/ui/util/top_view_controller.h"
#include "ios/chrome/grit/ios_strings.h" #include "ios/chrome/grit/ios_strings.h"
#include "ios/chrome/test/app/bookmarks_test_util.h" #include "ios/chrome/test/app/bookmarks_test_util.h"
#import "ios/chrome/test/app/chrome_test_util.h" #import "ios/chrome/test/app/chrome_test_util.h"
...@@ -45,15 +48,18 @@ std::unique_ptr<net::test_server::HttpResponse> StandardResponse( ...@@ -45,15 +48,18 @@ std::unique_ptr<net::test_server::HttpResponse> StandardResponse(
return std::move(http_response); return std::move(http_response);
} }
// Returns a matcher for the bookmark button.
id<GREYMatcher> BookmarkButton() { id<GREYMatcher> BookmarkButton() {
return chrome_test_util::ButtonWithAccessibilityLabelId(IDS_TOOLTIP_STAR); return chrome_test_util::ButtonWithAccessibilityLabelId(IDS_TOOLTIP_STAR);
} }
// Returns a matcher for the visible share button.
id<GREYMatcher> ShareButton() { id<GREYMatcher> ShareButton() {
return grey_allOf(grey_accessibilityID(kToolbarShareButtonIdentifier), return grey_allOf(grey_accessibilityID(kToolbarShareButtonIdentifier),
grey_sufficientlyVisible(), nil); grey_sufficientlyVisible(), nil);
} }
// Returns a matcher for a UIResponder object being first responder.
id<GREYMatcher> firstResponder() { id<GREYMatcher> firstResponder() {
MatchesBlock matches = ^BOOL(UIResponder* responder) { MatchesBlock matches = ^BOOL(UIResponder* responder) {
return [responder isFirstResponder]; return [responder isFirstResponder];
...@@ -67,6 +73,92 @@ id<GREYMatcher> firstResponder() { ...@@ -67,6 +73,92 @@ id<GREYMatcher> firstResponder() {
descriptionBlock:describe], descriptionBlock:describe],
nil); nil);
} }
// Returns a matcher for elements being subviews of the PrimaryToolbarView and
// sufficientlyVisible.
id<GREYMatcher> VisibleInPrimaryToolbar() {
return grey_allOf(grey_ancestor(grey_kindOfClass([PrimaryToolbarView class])),
grey_sufficientlyVisible(), nil);
}
// Returns a matcher for elements being subviews of the SecondaryToolbarView and
// sufficientlyVisible.
id<GREYMatcher> VisibleInSecondaryToolbar() {
return grey_allOf(
grey_ancestor(grey_kindOfClass([SecondaryToolbarView class])),
grey_sufficientlyVisible(), nil);
}
// Check that the button displayed are the ones which should be displayed in the
// environment described by |traitCollection|.
void CheckToolbarButtonVisibility(UITraitCollection* traitCollection) {
if (traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact &&
traitCollection.verticalSizeClass != UIUserInterfaceSizeClassCompact) {
// Split toolbar.
// Test the visibility of the primary toolbar buttons.
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
assertWithMatcher:VisibleInPrimaryToolbar()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()]
assertWithMatcher:VisibleInPrimaryToolbar()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
assertWithMatcher:VisibleInPrimaryToolbar()];
// Test the visibility of the secondary toolbar buttons.
[[EarlGrey selectElementWithMatcher:chrome_test_util::
ButtonWithAccessibilityLabelId(
IDS_IOS_TOOLBAR_SHOW_TABS)]
assertWithMatcher:VisibleInSecondaryToolbar()];
[[EarlGrey selectElementWithMatcher:ShareButton()]
assertWithMatcher:VisibleInSecondaryToolbar()];
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kToolbarOmniboxButtonIdentifier)]
assertWithMatcher:VisibleInSecondaryToolbar()];
[[EarlGrey selectElementWithMatcher:BookmarkButton()]
assertWithMatcher:VisibleInSecondaryToolbar()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::
ButtonWithAccessibilityLabelId(
IDS_IOS_TOOLBAR_SETTINGS)]
assertWithMatcher:VisibleInSecondaryToolbar()];
} else {
// Unsplit toolbar.
// Test the visibility of the primary toolbar buttons.
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
assertWithMatcher:VisibleInPrimaryToolbar()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::ForwardButton()]
assertWithMatcher:VisibleInPrimaryToolbar()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::Omnibox()]
assertWithMatcher:VisibleInPrimaryToolbar()];
[[EarlGrey selectElementWithMatcher:ShareButton()]
assertWithMatcher:VisibleInPrimaryToolbar()];
[[EarlGrey selectElementWithMatcher:BookmarkButton()]
assertWithMatcher:VisibleInPrimaryToolbar()];
[[EarlGrey selectElementWithMatcher:chrome_test_util::
ButtonWithAccessibilityLabelId(
IDS_IOS_TOOLBAR_SETTINGS)]
assertWithMatcher:VisibleInPrimaryToolbar()];
// The secondary toolbar is not visible.
[[EarlGrey
selectElementWithMatcher:grey_kindOfClass([SecondaryToolbarView class])]
assertWithMatcher:grey_not(grey_sufficientlyVisible())];
if (traitCollection.verticalSizeClass == UIUserInterfaceSizeClassCompact) {
// Unsplit in compact height, the stack view button is visible.
[[EarlGrey selectElementWithMatcher:chrome_test_util::
ButtonWithAccessibilityLabelId(
IDS_IOS_TOOLBAR_SHOW_TABS)]
assertWithMatcher:VisibleInPrimaryToolbar()];
} else {
// Unsplit in Regular x Regular, the reload/stop button is visible.
[[EarlGrey selectElementWithMatcher:chrome_test_util::
ButtonWithAccessibilityLabelId(
IDS_IOS_ACCNAME_RELOAD)]
assertWithMatcher:VisibleInPrimaryToolbar()];
}
}
}
} }
#pragma mark - TestCase #pragma mark - TestCase
...@@ -233,21 +325,54 @@ id<GREYMatcher> firstResponder() { ...@@ -233,21 +325,54 @@ id<GREYMatcher> firstResponder() {
// Verifies the existence and state of toolbar UI elements. // Verifies the existence and state of toolbar UI elements.
- (void)testToolbarUI { - (void)testToolbarUI {
id<GREYMatcher> bookmarkButton = // Load a page to have the toolbar visible (hidden on NTP).
chrome_test_util::ButtonWithAccessibilityLabelId(IDS_TOOLTIP_STAR);
// Navigate to a page and verify the back button is enabled.
[ChromeEarlGrey loadURL:GURL("chrome://version")]; [ChromeEarlGrey loadURL:GURL("chrome://version")];
[[EarlGrey selectElementWithMatcher:chrome_test_util::BackButton()]
assertWithMatcher:grey_interactable()];
// Check that the bookmark button is visible on compact width. // Get the original trait collection.
if (IsCompactWidth()) { UIViewController* topViewController =
[[EarlGrey selectElementWithMatcher:bookmarkButton] top_view_controller::TopPresentedViewController();
assertWithMatcher:grey_sufficientlyVisible()]; UITraitCollection* originalTraitCollection =
topViewController.traitCollection;
// Check the button visibility.
CheckToolbarButtonVisibility(originalTraitCollection);
UITraitCollection* secondTraitCollection = nil;
if (IsIPadIdiom()) {
// Simulate a multitasking by overriding the trait collections of the view
// controllers. The rotation doesn't work on iPad.
UITraitCollection* horizontalCompact = [UITraitCollection
traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassCompact];
secondTraitCollection =
[UITraitCollection traitCollectionWithTraitsFromCollections:@[
originalTraitCollection, horizontalCompact
]];
for (UIViewController* child in topViewController.childViewControllers) {
[topViewController setOverrideTraitCollection:secondTraitCollection
forChildViewController:child];
}
} else {
// On iPhone rotate to test the the landscape orientation.
[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeLeft
errorOrNil:nil];
secondTraitCollection = topViewController.traitCollection;
} }
// TODO(crbug.com/801145): Test more pieces of UI. // Check the visiblity after a size class change.
CheckToolbarButtonVisibility(secondTraitCollection);
if (IsIPadIdiom()) {
// Remove the override.
for (UIViewController* child in topViewController.childViewControllers) {
[topViewController setOverrideTraitCollection:originalTraitCollection
forChildViewController:child];
}
} else {
// Cancel the rotation.
[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationPortrait
errorOrNil:nil];
}
} }
@end @end
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#import "ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator_delegate.h" #import "ios/chrome/browser/ui/toolbar/clean/toolbar_coordinator_delegate.h"
#import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h" #import "ios/chrome/browser/ui/toolbar/public/web_toolbar_controller_constants.h"
#include "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h" #include "ios/chrome/browser/ui/toolbar/toolbar_model_ios.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h"
#import "ios/chrome/browser/ui/url_loader.h" #import "ios/chrome/browser/ui/url_loader.h"
#import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_list.h"
#include "ios/web/public/referrer.h" #include "ios/web/public/referrer.h"
......
...@@ -48,10 +48,6 @@ bool IsTabSwitcherTabGridEnabled(); ...@@ -48,10 +48,6 @@ bool IsTabSwitcherTabGridEnabled();
// Returns the height of the status bar, accounting for orientation. // Returns the height of the status bar, accounting for orientation.
CGFloat StatusBarHeight(); CGFloat StatusBarHeight();
// Returns whether the toolbar is split between top and bottom toolbar or if it
// is displayed as only one toolbar.
bool IsSplitToolbarMode();
// Returns the closest pixel-aligned value less than |value|, taking the scale // Returns the closest pixel-aligned value less than |value|, taking the scale
// factor into account. At a scale of 1, equivalent to floor(). // factor into account. At a scale of 1, equivalent to floor().
CGFloat AlignValueToPixel(CGFloat value); CGFloat AlignValueToPixel(CGFloat value);
......
...@@ -89,10 +89,6 @@ CGFloat StatusBarHeight() { ...@@ -89,10 +89,6 @@ CGFloat StatusBarHeight() {
return isCompactHeight ? 0 : 20; return isCompactHeight ? 0 : 20;
} }
bool IsSplitToolbarMode() {
return IsCompactWidth() && !IsCompactHeight();
}
CGFloat AlignValueToPixel(CGFloat value) { CGFloat AlignValueToPixel(CGFloat value) {
static CGFloat scale = [[UIScreen mainScreen] scale]; static CGFloat scale = [[UIScreen mainScreen] scale];
return floor(value * scale) / scale; return floor(value * scale) / scale;
......
...@@ -202,6 +202,17 @@ bool IsCompactTablet(); ...@@ -202,6 +202,17 @@ bool IsCompactTablet();
// vertical size class. // vertical size class.
bool IsCompactHeight(); bool IsCompactHeight();
// Whether the |environment| has a compact vertical size class.
bool IsCompactHeight(id<UITraitEnvironment> environment);
// Returns whether the toolbar is split between top and bottom toolbar or if it
// is displayed as only one toolbar.
bool IsSplitToolbarMode();
// Returns whether the |environment|'s toolbar is split between top and bottom
// toolbar or if it is displayed as only one toolbar.
bool IsSplitToolbarMode(id<UITraitEnvironment> environment);
// Returns the current first responder. // Returns the current first responder.
UIResponder* GetFirstResponder(); UIResponder* GetFirstResponder();
......
...@@ -546,11 +546,22 @@ bool IsCompactTablet() { ...@@ -546,11 +546,22 @@ bool IsCompactTablet() {
} }
bool IsCompactHeight() { bool IsCompactHeight() {
return [UIApplication sharedApplication] return IsCompactHeight([UIApplication sharedApplication].keyWindow);
.keyWindow.traitCollection.verticalSizeClass == }
bool IsCompactHeight(id<UITraitEnvironment> environment) {
return environment.traitCollection.verticalSizeClass ==
UIUserInterfaceSizeClassCompact; UIUserInterfaceSizeClassCompact;
} }
bool IsSplitToolbarMode() {
return IsCompactWidth() && !IsCompactHeight();
}
bool IsSplitToolbarMode(id<UITraitEnvironment> environment) {
return IsCompactWidth(environment) && !IsCompactHeight(environment);
}
// Returns the current first responder. // Returns the current first responder.
UIResponder* GetFirstResponder() { UIResponder* GetFirstResponder() {
DCHECK_CURRENTLY_ON(web::WebThread::UI); DCHECK_CURRENTLY_ON(web::WebThread::UI);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment