blob: 3d1cd6e15740ba8857e674e2e2601afba0deeeec [file] [log] [blame]
// Copyright 2020 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 <UIKit/UIKit.h>
#import <XCTest/XCTest.h>
#include "components/strings/grit/components_chromium_strings.h"
#import "ios/chrome/browser/ui/page_info/page_info_constants.h"
#import "ios/chrome/browser/ui/permissions/permissions_app_interface.h"
#import "ios/chrome/browser/ui/permissions/permissions_constants.h"
#include "ios/chrome/grit/ios_chromium_strings.h"
#include "ios/chrome/grit/ios_strings.h"
#import "ios/chrome/test/earl_grey/chrome_actions.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/testing/earl_grey/earl_grey_test.h"
#include "ios/web/common/features.h"
#import "ios/web/public/permissions/permissions.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/base/l10n/l10n_util.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif
namespace {
// Matcher infobar modal camera permissions switch.
id<GREYMatcher> CameraPermissionsSwitch(BOOL isOn) {
return chrome_test_util::TableViewSwitchCell(
kPageInfoCameraSwitchAccessibilityIdentifier, isOn);
}
// Matcher infobar modal microphone permissions switch.
id<GREYMatcher> MicrophonePermissionsSwitch(BOOL isOn) {
return chrome_test_util::TableViewSwitchCell(
kPageInfoMicrophoneSwitchAccessibilityIdentifier, isOn);
}
} // namespace
@interface PageInfoTestCase : ChromeTestCase
@end
@implementation PageInfoTestCase
- (AppLaunchConfiguration)appConfigurationForTestCase {
AppLaunchConfiguration config;
if (@available(iOS 15.0, *)) {
config.features_enabled.push_back(web::features::kMediaPermissionsControl);
}
return config;
}
// Checks that if the alert for site permissions pops up, and allow it.
- (void)checkAndAllowPermissionAlerts {
XCUIApplication* app = [[XCUIApplication alloc] init];
// Allow system permission if shown.
NSError* systemAlertFoundError = nil;
[[EarlGrey selectElementWithMatcher:grey_systemAlertViewShown()]
assertWithMatcher:grey_nil()
error:&systemAlertFoundError];
if (systemAlertFoundError) {
NSError* acceptAlertError = nil;
[self grey_acceptSystemDialogWithError:&acceptAlertError];
GREYAssertNil(acceptAlertError, @"Error accepting system alert.\n%@",
acceptAlertError);
}
// Allow site permission.
XCUIElement* alert =
[[app descendantsMatchingType:XCUIElementTypeAlert] firstMatch];
XCUIElement* button = alert.buttons[@"Allow"];
GREYAssertNotNil(button, @"Cannot find \"Allow\" button in system alert.");
[button tap];
}
// Checks `expectedStatesForPermissions` matches the actual states for
// permissions of the active web state; checks will fail if there is no active
// web state.
- (void)checkStatesForPermissions:
(NSDictionary<NSNumber*, NSNumber*>*)expectedStatesForPermissions
API_AVAILABLE(ios(15.0)) {
NSDictionary<NSNumber*, NSNumber*>* actualStatesForPermissions =
[PermissionsAppInterface statesForAllPermissions];
GREYAssertEqualObjects(
expectedStatesForPermissions[@(web::PermissionCamera)],
actualStatesForPermissions[@(web::PermissionCamera)],
@"Camera state: %@ does not match expected: %@.",
actualStatesForPermissions[@(web::PermissionCamera)],
expectedStatesForPermissions[@(web::PermissionCamera)]);
GREYAssertEqualObjects(
expectedStatesForPermissions[@(web::PermissionMicrophone)],
actualStatesForPermissions[@(web::PermissionMicrophone)],
@"Microphone state: %@ does not match expected: %@.",
actualStatesForPermissions[@(web::PermissionMicrophone)],
expectedStatesForPermissions[@(web::PermissionMicrophone)]);
}
// Tests that rotating the device will don't dismiss the page info view.
- (void)testShowPageInfoRotation {
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
[ChromeEarlGrey loadURL:self.testServer->GetURL("/")];
[ChromeEarlGreyUI openPageInfo];
// Checks that the page info view has appeared.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kPageInfoViewAccessibilityIdentifier)]
assertWithMatcher:grey_sufficientlyVisible()];
// Rotates the device and checks that the page info view is still presented.
[EarlGrey rotateDeviceToOrientation:UIDeviceOrientationLandscapeRight
error:nil];
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kPageInfoViewAccessibilityIdentifier)]
assertWithMatcher:grey_sufficientlyVisible()];
// Closes the page info using the 'Done' button.
[[EarlGrey
selectElementWithMatcher:chrome_test_util::NavigationBarDoneButton()]
performAction:grey_tap()];
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kPageInfoViewAccessibilityIdentifier)]
assertWithMatcher:grey_nil()];
}
// Tests that opening the page info on a Chromium page displays the correct
// information.
- (void)testShowPageInfoChromePage {
[ChromeEarlGrey loadURL:GURL("chrome://version")];
[ChromeEarlGreyUI openPageInfo];
// Checks that the page info view has appeared.
[[EarlGrey selectElementWithMatcher:grey_accessibilityID(
kPageInfoViewAccessibilityIdentifier)]
assertWithMatcher:grey_sufficientlyVisible()];
// Checks that “You’re viewing a secure Chrome page.” is displayed.
[[EarlGrey selectElementWithMatcher:grey_text(l10n_util::GetNSString(
IDS_PAGE_INFO_INTERNAL_PAGE))]
assertWithMatcher:grey_sufficientlyVisible()];
}
// Tests that the Permissions section is not displayed, as there isn't any
// accessible permissions.
- (void)testShowPageInfoWithNoAccessiblePermission {
if (@available(iOS 15.0, *)) {
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
[ChromeEarlGrey loadURL:self.testServer->GetURL("/")];
[ChromeEarlGreyUI openPageInfo];
// Checks that permission header is not visible.
[[EarlGrey
selectElementWithMatcher:grey_text(l10n_util::GetNSString(
IDS_IOS_PAGE_INFO_PERMISSIONS_HEADER))]
assertWithMatcher:grey_notVisible()];
}
}
// Tests that single accessible permission is shown in Permissions section with
// toggle.
// TODO(crbug.com/1316705): Test fails on device due to asking for microphone
// permission.
#if !TARGET_IPHONE_SIMULATOR
#define MAYBE_testShowOneAccessiblePermissionInPageInfo \
DISABLED_testShowOneAccessiblePermissionInPageInfo
#else
#define MAYBE_testShowOneAccessiblePermissionInPageInfo \
testShowOneAccessiblePermissionInPageInfo
#endif
- (void)MAYBE_testShowOneAccessiblePermissionInPageInfo {
if (@available(iOS 15.0, *)) {
// Open a page that requests microphone permissions.
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
[ChromeEarlGrey
loadURL:self.testServer->GetURL("/permissions/microphone_only.html")];
[self checkAndAllowPermissionAlerts];
// Check that permission header is visible.
[ChromeEarlGreyUI openPageInfo];
[[EarlGrey
selectElementWithMatcher:grey_text(l10n_util::GetNSString(
IDS_IOS_PAGE_INFO_PERMISSIONS_HEADER))]
assertWithMatcher:grey_sufficientlyVisible()];
// Check that camera permission item is hidden, and in accordance with the
// web state permission states.
[self checkStatesForPermissions:@{
@(web::PermissionCamera) : @(web::PermissionStateNotAccessible),
@(web::PermissionMicrophone) : @(web::PermissionStateAllowed)
}];
[[EarlGrey
selectElementWithMatcher:grey_anyOf(CameraPermissionsSwitch(YES),
CameraPermissionsSwitch(NO), nil)]
assertWithMatcher:grey_notVisible()];
// Check that microphone permission item is visible, and turn it off.
[[EarlGrey selectElementWithMatcher:MicrophonePermissionsSwitch(YES)]
performAction:chrome_test_util::TurnTableViewSwitchOn(NO)];
[[EarlGrey // Dismiss view.
selectElementWithMatcher:grey_accessibilityID(
kPageInfoViewAccessibilityIdentifier)]
performAction:grey_swipeFastInDirection(kGREYDirectionDown)];
[self checkStatesForPermissions:@{
@(web::PermissionCamera) : @(web::PermissionStateNotAccessible),
@(web::PermissionMicrophone) : @(web::PermissionStateBlocked)
}];
}
}
// Tests that two accessible permissions are shown in Permissions section with
// toggle.
// TODO(crbug.com/1316705): Test fails on device due to asking for microphone
// permission.
#if !TARGET_IPHONE_SIMULATOR
#define MAYBE_testShowTwoAccessiblePermissionsInPageInfo \
DISABLED_testShowTwoAccessiblePermissionsInPageInfo
#else
#define MAYBE_testShowTwoAccessiblePermissionsInPageInfo \
testShowTwoAccessiblePermissionsInPageInfo
#endif
- (void)MAYBE_testShowTwoAccessiblePermissionsInPageInfo {
if (@available(iOS 15.0, *)) {
// Open a page that requests microphone permissions.
GREYAssertTrue(self.testServer->Start(), @"Test server failed to start.");
[ChromeEarlGrey loadURL:self.testServer->GetURL(
"/permissions/camera_and_microphone.html")];
[self checkAndAllowPermissionAlerts];
// Check that permission header is visible.
[ChromeEarlGreyUI openPageInfo];
[[EarlGrey
selectElementWithMatcher:grey_text(l10n_util::GetNSString(
IDS_IOS_PAGE_INFO_PERMISSIONS_HEADER))]
assertWithMatcher:grey_sufficientlyVisible()];
// Check that switchs for both permissions are visible.
[self checkStatesForPermissions:@{
@(web::PermissionCamera) : @(web::PermissionStateAllowed),
@(web::PermissionMicrophone) : @(web::PermissionStateAllowed)
}];
// Check that both permission item is visible, and turn off camera
// permission.
[[EarlGrey selectElementWithMatcher:MicrophonePermissionsSwitch(YES)]
assertWithMatcher:grey_sufficientlyVisible()];
[[EarlGrey selectElementWithMatcher:CameraPermissionsSwitch(YES)]
performAction:chrome_test_util::TurnTableViewSwitchOn(NO)];
[[EarlGrey // Dismiss view.
selectElementWithMatcher:grey_accessibilityID(
kPageInfoViewAccessibilityIdentifier)]
performAction:grey_swipeFastInDirection(kGREYDirectionDown)];
[self checkStatesForPermissions:@{
@(web::PermissionCamera) : @(web::PermissionStateBlocked),
@(web::PermissionMicrophone) : @(web::PermissionStateAllowed)
}];
}
}
@end