[web] running ios unit tests from felt … (#18856)

* running ios unit tests from felt by booting/shutingdown simulators. create simulator with felt

* changing the readme file for ios,mac,xcode spellings

* addressing reviewer comments

* fix analyse error

* fixing cleanup issue. solution: adding and await and using for loop instead of foreach
This commit is contained in:
nturgut 2020-06-10 09:33:17 -07:00 committed by GitHub
parent 5c69b8beb5
commit eaa2f7f90f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 188 additions and 23 deletions

View File

@ -83,12 +83,34 @@ For Chrome and Firefox, the tests run on a version locked on the [browser_lock.y
felt test --browser=firefox --firefox-version=70.0.1
```
To run tests on Safari use the following command. It works on MacOS devices and it uses the Safari installed on the OS. Currently there is no option for using another Safari version.
To run tests on Safari use the following command. It works on macOS devices and it uses the Safari installed on the OS. Currently there is no option for using another Safari version.
```
felt test --browser=safari
```
One can also use Safari running in iOS Simulator for running unit tests. There are few prerequisite steps:
1. Please make sure that you installed Xcode.
2. The default version used in the tests are in browser_lock.yaml file. Install the ios version to use for simulators: Xcode > Preferences > Components
3. run `xcrun simctl list devices`. If the simulator you want is not installed use step 4.
4. Use felt to create a simulator:
```
felt create_simulator --type='iOS' --version='13.1' --device='iPhone.11.Pro'
```
To run tests on ios-safari use the one of the following commands:
```
felt test --browser=ios-safari
felt test --browser=ios-safari --version='13.1' --device='iPhone.11.Pro'
felt test --browser=ios-safari test/alarm_clock_test.dart
```
To run tests on Windows Edge use the following command. It works on Windows devices and it uses the Edge installed on the OS.
```

View File

@ -10,3 +10,7 @@ firefox:
version: '72.0'
edge:
launcher_version: '1.2.0.0'
ios-safari:
majorVersion: 13
minorVersion: 5
device: 'iPhone 11'

View File

@ -0,0 +1,57 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.6
import 'dart:async';
import 'package:args/command_runner.dart';
import 'package:simulators/simulator_manager.dart';
import 'safari_installation.dart';
import 'utils.dart';
class CreateSimulatorCommand extends Command<bool> with ArgUtils {
CreateSimulatorCommand() {
IosSafariArgParser.instance.populateOptions(argParser);
argParser
..addOption(
'type',
defaultsTo: _defaultType,
help: 'Type of the mobile simulator. Currently the only iOS '
'Simulators are supported. Android will be added soon. This option '
'is not case sensitive, ios, iOS, IOS are all valid.',
);
}
/// Currently the only iOS Simulators are supported.
static final String _defaultType = 'iOS';
@override
String get name => 'create_simulator';
@override
String get description => 'Creates mobile simulators.';
@override
FutureOr<bool> run() async {
IosSafariArgParser.instance.parseOptions(argResults);
final String simulatorType = argResults['type'] as String;
if (simulatorType.toUpperCase() != 'IOS') {
throw Exception('Currently the only iOS Simulators are supported');
}
final IosSimulatorManager iosSimulatorManager = IosSimulatorManager();
try {
final IosSimulator simulator = await iosSimulatorManager.createSimulator(
IosSafariArgParser.instance.iosMajorVersion,
IosSafariArgParser.instance.iosMinorVersion,
IosSafariArgParser.instance.iosDevice);
print('INFO: Simulator created ${simulator.toString()}');
} catch (e) {
throw Exception('Error creating requested simulator. You can use Xcode '
'to install more versions: XCode > Preferences > Components.'
' Exception: $e');
}
return true;
}
}

View File

@ -9,6 +9,7 @@ import 'package:args/command_runner.dart';
import 'build.dart';
import 'clean.dart';
import 'create_simulator.dart';
import 'licenses.dart';
import 'exceptions.dart';
import 'test_runner.dart';
@ -19,6 +20,7 @@ CommandRunner runner = CommandRunner<bool>(
'Command-line utility for building and testing Flutter web engine.',
)
..addCommand(CleanCommand())
..addCommand(CreateSimulatorCommand())
..addCommand(LicensesCommand())
..addCommand(TestCommand())
..addCommand(BuildCommand());

View File

@ -7,6 +7,7 @@ import 'dart:async';
import 'dart:io' as io;
import 'package:args/args.dart';
import 'package:yaml/yaml.dart';
import 'common.dart';
@ -31,6 +32,9 @@ class SafariArgParser extends BrowserArgParser {
'Soon we will add support for using different versions using the '
'tech previews.',
);
// Populate options for Ios Safari.
IosSafariArgParser.instance.populateOptions(argParser);
}
@override
@ -45,10 +49,73 @@ class SafariArgParser extends BrowserArgParser {
String get version => _version;
bool _isMobileBrowser;
bool get isMobileBrowser => _isMobileBrowser;
}
class IosSafariArgParser extends BrowserArgParser {
static final IosSafariArgParser _singletonInstance = IosSafariArgParser._();
/// The [IosSafariArgParser] singleton.
static IosSafariArgParser get instance => _singletonInstance;
String get version => 'iOS ${iosMajorVersion}.${iosMinorVersion}';
int _pinnedIosMajorVersion;
int _iosMajorVersion;
int get iosMajorVersion => _iosMajorVersion ?? _pinnedIosMajorVersion;
int _pinnedIosMinorVersion;
int _iosMinorVersion;
int get iosMinorVersion => _iosMinorVersion ?? _pinnedIosMinorVersion;
String _pinnedIosDevice;
String _iosDevice;
String get iosDevice => _iosDevice ?? _pinnedIosDevice;
IosSafariArgParser._();
@override
void populateOptions(ArgParser argParser) {
final YamlMap browserLock = BrowserLock.instance.configuration;
_pinnedIosMajorVersion = browserLock['ios-safari']['majorVersion'] as int;
_pinnedIosMinorVersion = browserLock['ios-safari']['minorVersion'] as int;
final pinnedIosVersion =
'${_pinnedIosMajorVersion}.${_pinnedIosMinorVersion}';
_pinnedIosDevice = browserLock['ios-safari']['device'] as String;
argParser
..addOption('version',
defaultsTo: '$pinnedIosVersion',
help: 'The version for the iOS operating system the iOS Simulator '
'will use for tests. For example for testing with iOS 13.2, '
'use `13.2`. Use command: '
'`xcrun simctl list runtimes` to list available versions. Use '
'XCode to install more versions: Xcode > Preferences > Components'
'If this value is not filled version locked in the '
'browser_lock.yaml file will be user.')
..addOption('device',
defaultsTo: '$_pinnedIosDevice',
help: 'The device to be used for the iOS Simulator during the tests. '
'Use `.` instead of space for seperating the words. '
'Common examples: iPhone.8, iPhone.8.Plus, iPhone.11, '
'iPhone 11 Pro. Use command: '
'`xcrun simctl list devices` for listing the available '
'devices. If this value is not filled device locked in the '
'browser_lock.yaml file will be user.');
}
@override
void parseOptions(ArgResults argResults) {
final String iosVersion = argResults['version'] as String;
// The version will contain major and minor version seperated by a comma,
// for example: 13.1, 12.2
assert(iosVersion.split('.').length == 2,
'The version should be in format 13.5');
_iosMajorVersion = int.parse(iosVersion.split('.')[0]);
_iosMinorVersion = int.parse(iosVersion.split('.')[1]);
_iosDevice = (argResults['device'] as String).replaceAll('.', ' ');
}
}
/// Returns the installation of Safari.
///
/// Currently uses the Safari version installed on the operating system.
@ -62,7 +129,6 @@ Future<BrowserInstallation> getOrInstallSafari(
String requestedVersion, {
StringSink infoLog,
}) async {
// These tests are aimed to run only on macOS machines local or on LUCI.
if (!io.Platform.isMacOS) {
throw UnimplementedError('Safari on ${io.Platform.operatingSystem} is'

View File

@ -14,10 +14,12 @@ import 'package:test_core/src/runner/hack_register_platform.dart'
import 'package:test_api/src/backend/runtime.dart'; // ignore: implementation_imports
import 'package:test_core/src/executable.dart'
as test; // ignore: implementation_imports
import 'package:simulators/simulator_manager.dart';
import 'environment.dart';
import 'exceptions.dart';
import 'integration_tests_manager.dart';
import 'safari_installation.dart';
import 'supported_browsers.dart';
import 'test_platform.dart';
import 'utils.dart';
@ -159,23 +161,30 @@ class TestCommand extends Command<bool> with ArgUtils {
await _runPubGet();
}
// Many tabs will be left open after Safari runs, quit Safari during
// cleanup.
if (browser == 'safari') {
cleanupCallbacks.add(() async {
// Only close Safari if felt is running in CI environments. Do not close
// Safari for the local testing.
if (io.Platform.environment['LUCI_CONTEXT'] != null || isCirrus) {
print('INFO: Safari tests ran. Quit Safari.');
await runProcess(
'sudo',
['pkill', '-lf', 'Safari'],
workingDirectory: environment.webUiRootDir.path,
);
} else {
print('INFO: Safari tests ran. Please quit Safari tabs.');
}
});
// In order to run iOS Safari unit tests we need to make sure iOS Simulator
// is booted.
if (browser == 'ios-safari') {
final IosSimulatorManager iosSimulatorManager = IosSimulatorManager();
IosSimulator iosSimulator;
try {
iosSimulator = await iosSimulatorManager.getSimulator(
IosSafariArgParser.instance.iosMajorVersion,
IosSafariArgParser.instance.iosMinorVersion,
IosSafariArgParser.instance.iosDevice);
} catch (e) {
throw Exception('Error getting requested simulator. Try running '
'`felt create` command first before running the tests. exception: '
'$e');
}
if (!iosSimulator.booted) {
await iosSimulator.boot();
print('INFO: Simulator ${iosSimulator.id} booted.');
cleanupCallbacks.add(() async {
await iosSimulator.shutdown();
print('INFO: Simulator ${iosSimulator.id} shutdown.');
});
}
}
await _buildTargets();

View File

@ -219,7 +219,7 @@ void cleanup() async {
}
}
cleanupCallbacks.forEach((element) {
element.call();
});
for (final AsyncCallback callback in cleanupCallbacks) {
await callback();
}
}

View File

@ -23,6 +23,11 @@ dev_dependencies:
watcher: 0.9.7+12
web_engine_tester:
path: ../../web_sdk/web_engine_tester
simulators:
git:
url: git://github.com/flutter/web_installers.git
path: packages/simulators/
ref: 9ede7e3c069180b28322bb3f0d0307c824071fb5
web_driver_installer:
git:
url: git://github.com/flutter/web_installers.git