Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 77 additions & 1 deletion testing/scenario_app/bin/run_android_tests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ void main(List<String> args) async {
ndkStack: options.ndkStack,
forceSurfaceProducerSurfaceTexture: options.forceSurfaceProducerSurfaceTexture,
prefixLogsPerRun: options.prefixLogsPerRun,
recordScreen: options.recordScreen,
);
onSigint.cancel();
exit(0);
Expand Down Expand Up @@ -135,6 +136,7 @@ Future<void> _run({
required String ndkStack,
required bool forceSurfaceProducerSurfaceTexture,
required bool prefixLogsPerRun,
required bool recordScreen,
}) async {
const ProcessManager pm = LocalProcessManager();
final String scenarioAppPath = join(outDir.path, 'scenario_app');
Expand Down Expand Up @@ -230,6 +232,7 @@ Future<void> _run({
late Process logcatProcess;
late Future<int> logcatProcessExitCode;
_ImpellerBackend? actualImpellerBackend;
Process? screenRecordProcess;

final IOSink logcat = File(logcatPath).openWrite();
try {
Expand Down Expand Up @@ -361,14 +364,44 @@ Future<void> _run({
}
});

if (recordScreen) {
await step('Recording screen...', () async {
// Create a /tmp directory on the device to store the screen recording.
final int exitCode = await pm.runAndForward(<String>[
adb.path,
'shell',
'mkdir',
'-p',
join(_emulatorStoragePath, 'tmp'),
]);
if (exitCode != 0) {
panic(<String>['could not create /tmp directory on device']);
}
final String screenRecordingPath = join(
_emulatorStoragePath,
'tmp',
'screen.mp4',
);
screenRecordProcess = await pm.start(<String>[
adb.path,
'shell',
'screenrecord',
'--time-limit=0',
'--bugreport',
screenRecordingPath,
]);
log('writing screen recording to $screenRecordingPath');
});
}

await step('Running instrumented tests...', () async {
final (int exitCode, StringBuffer out) = await pm.runAndCapture(<String>[
adb.path,
'shell',
'am',
'instrument',
'-w',
'--no-window-animation',
'--no-window-animation',
if (smokeTestFullPath != null)
'-e class $smokeTestFullPath',
if (enableImpeller)
Expand Down Expand Up @@ -447,6 +480,47 @@ Future<void> _run({
}
});

if (screenRecordProcess != null) {
await step('Killing screen recording process...', () async {
// Kill the screen recording process.
screenRecordProcess!.kill(ProcessSignal.sigkill);
await screenRecordProcess!.exitCode;

// Pull the screen recording from the device.
final String screenRecordingPath = join(
_emulatorStoragePath,
'tmp',
'screen.mp4',
);
final String screenRecordingLocalPath = join(
logsDir.path,
'screen.mp4',
);
final int exitCode = await pm.runAndForward(<String>[
adb.path,
'pull',
screenRecordingPath,
screenRecordingLocalPath,
]);
if (exitCode != 0) {
logError('could not pull screen recording from device');
}

log('wrote screen recording to $screenRecordingLocalPath');

// Remove the screen recording from the device.
final int removeExitCode = await pm.runAndForward(<String>[
adb.path,
'shell',
'rm',
screenRecordingPath,
]);
if (removeExitCode != 0) {
logError('could not remove screen recording from device');
}
});
}

await step('Killing logcat process...', () async {
final bool delivered = logcatProcess.kill(ProcessSignal.sigkill);
assert(delivered);
Expand Down Expand Up @@ -536,6 +610,8 @@ Future<void> _run({
}
}

const String _emulatorStoragePath = '/storage/emulated/0/Download';

void _withTemporaryCwd(String path, void Function() callback) {
final String originalCwd = Directory.current.path;
Directory.current = Directory(path).path;
Expand Down
8 changes: 8 additions & 0 deletions testing/scenario_app/bin/utils/options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ extension type const Options._(ArgResults _args) {
defaultsTo: environment.isCi,
hide: hideUnusualOptions,
)
..addFlag(
'record-screen',
help: 'Whether to record the screen during the test run.',
defaultsTo: environment.isCi,
)
..addOption(
'impeller-backend',
help: 'The graphics backend to use when --enable-impeller is true. '
Expand Down Expand Up @@ -286,6 +291,9 @@ extension type const Options._(ArgResults _args) {
/// Whether to enable Impeller as the graphics backend.
bool get enableImpeller => _args['enable-impeller'] as bool;

/// Whether to record the screen during the test run.
bool get recordScreen => _args['record-screen'] as bool;

/// The graphics backend to use when --enable-impeller is true.
String get impellerBackend => _args['impeller-backend'] as String;

Expand Down