Skip to content

Commit

Permalink
sync develop with master
Browse files Browse the repository at this point in the history
  • Loading branch information
bartekpacia committed Sep 15, 2023
1 parent 3950c72 commit a42a17e
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 26 deletions.
7 changes: 6 additions & 1 deletion packages/patrol/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@

This version requires version 2.2.0-dev.1 of `patrol_cli` package.

## 2.2.5

- Fix `grantPermissionOnlyThisTime()` crashing on Android <11 (#1698)

## 2.2.4

- Remove deprecation of `nativeAutomation` and add message about migration to `patrol_finders` (#1670)
- Remove deprecation of `nativeAutomation` and add message about migration to
`patrol_finders` (#1670)

## 2.2.3

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -392,9 +392,9 @@ class Automator private constructor() {

fun allowPermissionWhileUsingApp() {
val identifiers = arrayOf(
"com.android.packageinstaller:id/permission_allow_button",
"com.android.permissioncontroller:id/permission_allow_button",
"com.android.permissioncontroller:id/permission_allow_foreground_only_button"
"com.android.packageinstaller:id/permission_allow_button", // API <= 28
"com.android.permissioncontroller:id/permission_allow_button", // API 29
"com.android.permissioncontroller:id/permission_allow_foreground_only_button" // API >= 30 + API 29 (only for location permission)
)

val uiObject = waitForUiObjectByResourceId(*identifiers, timeout = timeoutMillis)
Expand All @@ -404,10 +404,15 @@ class Automator private constructor() {
}

fun allowPermissionOnce() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
// One-time permissions are available only on API 30 (R) and above.
// See: https://developer.android.com/training/permissions/requesting#one-time
allowPermissionWhileUsingApp()
return
}

val identifiers = arrayOf(
"com.android.packageinstaller:id/permission_allow_button",
"com.android.permissioncontroller:id/permission_allow_button",
"com.android.permissioncontroller:id/permission_allow_one_time_button"
"com.android.permissioncontroller:id/permission_allow_one_time_button" // API >= 30
)

val uiObject = waitForUiObjectByResourceId(*identifiers, timeout = timeoutMillis)
Expand All @@ -418,8 +423,8 @@ class Automator private constructor() {

fun denyPermission() {
val identifiers = arrayOf(
"com.android.packageinstaller:id/permission_deny_button",
"com.android.permissioncontroller:id/permission_deny_button"
"com.android.packageinstaller:id/permission_deny_button", // API <= 28
"com.android.permissioncontroller:id/permission_deny_button" // API >= 29
)

val uiObject = waitForUiObjectByResourceId(*identifiers, timeout = timeoutMillis)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ void main() {
await $.native.selectFineLocation();
await $.native.selectCoarseLocation();
await $.native.selectFineLocation();
await $.native.grantPermissionWhenInUse();
await $.native.grantPermissionOnlyThisTime();
}
await $.pump();

Expand Down
4 changes: 4 additions & 0 deletions packages/patrol/lib/src/native/native_automator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -694,6 +694,10 @@ class NativeAutomator {
/// On iOS, this is the same as [grantPermissionWhenInUse] except for the
/// location permission.
///
/// On Android versions older than 11 (R, API level 30), the concept of
/// "one-time permissions" doesn't exist. In this case, this method is the
/// same as [grantPermissionWhenInUse].
///
/// See also:
///
/// * [grantPermissionWhenInUse] and [denyPermission]
Expand Down
4 changes: 4 additions & 0 deletions packages/patrol_cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

This version requires version 2.3.0-dev.1 of `patrol` package.

## 2.1.4

- Uninstall RunnerUITests app on iOS when flavor is present (#1694)

## 2.1.3

- Add migration message due to release of `patrol_finders`
Expand Down
22 changes: 15 additions & 7 deletions packages/patrol_cli/lib/src/commands/develop.dart
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,11 @@ class DevelopCommand extends PatrolCommand {
case TargetPlatform.iOS:
final bundleId = iosOpts.bundleId;
if (bundleId != null) {
action = () => _iosTestBackend.uninstall(bundleId, device);
action = () => _iosTestBackend.uninstall(
appId: bundleId,
flavor: iosOpts.flutter.flavor,
device: device,
);
}
break;
}
Expand All @@ -238,7 +242,7 @@ class DevelopCommand extends PatrolCommand {
Future<void> _execute(
FlutterAppOptions flutterOpts,
AndroidAppOptions android,
IOSAppOptions ios, {
IOSAppOptions iosOpts, {
required bool uninstall,
required Device device,
}) async {
Expand All @@ -257,12 +261,16 @@ class DevelopCommand extends PatrolCommand {
}
break;
case TargetPlatform.iOS:
appId = ios.bundleId;
appId = iosOpts.bundleId;
action = () async =>
_iosTestBackend.execute(ios, device, interruptible: true);
final bundle = ios.bundleId;
if (bundle != null && uninstall) {
finalizer = () => _iosTestBackend.uninstall(bundle, device);
_iosTestBackend.execute(iosOpts, device, interruptible: true);
final bundleId = iosOpts.bundleId;
if (bundleId != null && uninstall) {
finalizer = () => _iosTestBackend.uninstall(
appId: bundleId,
flavor: iosOpts.flutter.flavor,
device: device,
);
}
}

Expand Down
20 changes: 14 additions & 6 deletions packages/patrol_cli/lib/src/commands/test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,11 @@ See https://github.com/leancodepl/patrol/issues/1316 to learn more.
case TargetPlatform.iOS:
final bundleId = iosOpts.bundleId;
if (bundleId != null) {
action = () => _iosTestBackend.uninstall(bundleId, device);
action = () => _iosTestBackend.uninstall(
appId: bundleId,
flavor: iosOpts.flutter.flavor,
device: device,
);
}
break;
}
Expand Down Expand Up @@ -240,7 +244,7 @@ See https://github.com/leancodepl/patrol/issues/1316 to learn more.
Future<bool> _execute(
FlutterAppOptions flutterOpts,
AndroidAppOptions android,
IOSAppOptions ios, {
IOSAppOptions iosOpts, {
required bool uninstall,
required Device device,
}) async {
Expand All @@ -256,10 +260,14 @@ See https://github.com/leancodepl/patrol/issues/1316 to learn more.
}
break;
case TargetPlatform.iOS:
action = () async => _iosTestBackend.execute(ios, device);
final bundle = ios.bundleId;
if (bundle != null && uninstall) {
finalizer = () => _iosTestBackend.uninstall(bundle, device);
action = () async => _iosTestBackend.execute(iosOpts, device);
final bundleId = iosOpts.bundleId;
if (bundleId != null && uninstall) {
finalizer = () => _iosTestBackend.uninstall(
appId: bundleId,
flavor: iosOpts.flutter.flavor,
device: device,
);
}
break;
}
Expand Down
34 changes: 31 additions & 3 deletions packages/patrol_cli/lib/src/ios/ios_test_backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:io' show Process;
import 'package:dispose_scope/dispose_scope.dart';
import 'package:file/file.dart';
import 'package:glob/glob.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' show join;
import 'package:patrol_cli/src/base/exceptions.dart';
import 'package:patrol_cli/src/base/logger.dart';
Expand Down Expand Up @@ -189,7 +190,14 @@ class IOSTestBackend {
});
}

Future<void> uninstall(String appId, Device device) async {
/// Uninstalls the app under test and the test runner from [device].
///
/// [flavor] is required to infer the test runner bundle ID.
Future<void> uninstall({
required String appId,
required String? flavor,
required Device device,
}) async {
if (device.real) {
// uninstall from iOS device
await _processManager.run(
Expand All @@ -208,8 +216,10 @@ class IOSTestBackend {
);
}

// TODO: Not being removed https://github.com/leancodepl/patrol/issues/1094
final testApp = '$appId.RunnerUITests.xctrunner';
// See rationale: https://github.com/leancodepl/patrol/issues/1094
final appIdWithoutFlavor = stripFlavorFromAppId(appId, flavor);
final testApp = '$appIdWithoutFlavor.RunnerUITests.xctrunner';

if (device.real) {
// uninstall from iOS device
await _processManager.run(
Expand All @@ -229,6 +239,24 @@ class IOSTestBackend {
}
}

/// Removes [flavor] from the end of [appId].
///
/// Assumes that [appId] and [flavor] are separated by a dot.
@visibleForTesting
String stripFlavorFromAppId(String appId, String? flavor) {
if (flavor == null) {
return appId;
}

final idx = appId.indexOf('.$flavor');

if (idx == -1) {
return appId;
}

return appId.substring(0, idx);
}

Future<String> xcTestRunPath({
required bool real,
required String scheme,
Expand Down
32 changes: 32 additions & 0 deletions packages/patrol_cli/test/ios/ios_test_backend_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,38 @@ void main() {
testPlan: 'SomeTestPlan',
);
});

group('stripFlavorFromAppId', () {
test('simply returns appId when flavor is null', () {
const appId = 'com.company.app';
const String? flavor = null;

expect(
iosTestBackend.stripFlavorFromAppId(appId, flavor),
'com.company.app',
);
});

test('works when appId contains flavor', () {
const appId = 'com.company.app.dev';
const flavor = 'dev';

expect(
iosTestBackend.stripFlavorFromAppId(appId, flavor),
'com.company.app',
);
});

test('ignores when appId contains flavor not preceded by a dot', () {
const appId = 'com.company.app_dev';
const flavor = 'dev';

expect(
iosTestBackend.stripFlavorFromAppId(appId, flavor),
'com.company.app_dev',
);
});
});
});
}

Expand Down

0 comments on commit a42a17e

Please sign in to comment.