Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix problem with flavor and applicationIdSuffix on android #108

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ Configuration information is passed to _Sylph_ using a configuration file. The d
# sylph config
tmp_dir: /tmp/sylph
artifacts_dir: /tmp/sylph_artifacts
# The folder in which screenshots are created during the tests.
# The folder will be copied to DEVICEFARM_SCREENSHOT_PATH so that AWD displays screenshots
screenhost_dir: ./screenshots
# local timeout per device farm run
sylph_timeout: 720 # seconds approx
# run on ios and android pools concurrently (for faster results)
Expand Down
10 changes: 5 additions & 5 deletions lib/resources/script/local_utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ build_debug_ipa() {
local app_name="Runner"
local scheme
if [[ -z "$flavor" ]]; then
echo "Running flutter build ios -t test_driver/main.dart --debug..."
flutter build ios -t test_driver/main.dart --debug
echo "Running flutter build ios -t test_driver/main.dart --debug --no-codesign..."
flutter build ios -t test_driver/main.dart --debug --no-codesign
scheme="$app_name"
build_config="Debug"
else
echo "Running flutter build ios -t test_driver/main.dart --debug --flavor $flavor..."
flutter build ios -t test_driver/main.dart --debug --flavor $flavor
echo "Running flutter build ios -t test_driver/main.dart --debug --no-codesign --flavor $flavor..."
flutter build ios -t test_driver/main.dart --debug --flavor $flavor --no-codesign
scheme="$flavor"
build_config="Debug $flavor"
fi
Expand All @@ -105,7 +105,7 @@ build_debug_ipa() {
remove_archive_disabler

local default_debug_ipa_name='Debug_Runner.ipa'
local ios_build_dir="$PWD/build/ios/Debug-iphoneos"
local ios_build_dir="$PWD/build/ios/$build_config-iphoneos"
local archive_path="$ios_build_dir/$app_name.xcarchive"

echo "Generating debug archive..."
Expand Down
12 changes: 6 additions & 6 deletions lib/resources/script/test_android.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ main() {
--run-tests)
if [[ -z $2 ]]; then show_help; fi
# run_tests "$2" "$4" "$6"
run_tests "$2"
run_tests "$2" "$3"
;;
--run-driver)
if [[ -z $2 ]]; then show_help; fi
Expand Down Expand Up @@ -60,11 +60,11 @@ where:

run_tests() {
local test_paths=$1 # comma-delimited list of test paths
local flavor=$2

while IFS=',' read -ra tests; do # parse comma-delimited list into real list of [tests]
for test in "${tests[@]}"; do
# custom_test_runner "$test" "$2" "$3"
custom_test_runner "$test"
custom_test_runner "$test" "$flavor"
done
done <<< "$test_paths"
}
Expand All @@ -74,10 +74,9 @@ run_tests() {
# (see https://github.com/flutter/flutter/issues/34909)
custom_test_runner() {
local test_path=$1
local app_id=$2
local forwarded_port=4723 # re-use appium server port if on device farm host

local app_id
app_id=$(grep applicationId android/app/build.gradle | awk '{print $2}' | tr -d '"')
# local package
# package=app_id

Expand Down Expand Up @@ -110,7 +109,8 @@ custom_test_runner() {
adb logcat -c

# start app on device
adb shell am start -a android.intent.action.RUN -f 0x20000000 --ez enable-background-compilation true --ez enable-dart-profiling true --ez enable-checked-mode true --ez verify-entry-points true --ez start-paused true "$app_id/.MainActivity"
activity=$(adb shell cmd package resolve-activity -c android.intent.category.LAUNCHER $app_id | sed -n '/name=/s/^.*name=//p')
adb shell am start -a android.intent.action.RUN -f 0x20000000 --ez enable-background-compilation true --ez enable-dart-profiling true --ez enable-checked-mode true --ez verify-entry-points true --ez start-paused true $app_id/$activity

# wait for observatory startup on device and get port number
obs_str=$( (adb logcat -v time &) | grep -m 1 "Observatory listening on")
Expand Down
10 changes: 8 additions & 2 deletions lib/resources/test_spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,11 @@ phases:
- rm -f .packages # todo: remove from bundle
- MAIN=test_driver/main.dart
- TESTS='test_driver/main_test.dart'
- APP_ID=''
- >-
if [ $DEVICEFARM_DEVICE_PLATFORM_NAME = "Android" ];
then
./script/test_android.sh --run-tests "$TESTS"
./script/test_android.sh --run-tests "$TESTS" "$APP_ID"
track_test_phase_status
fi

Expand Down Expand Up @@ -128,7 +129,12 @@ phases:

# The post test phase includes are commands that are run after your tests are executed.
post_test:
commands:
commands:
- SCREENSHOTS_PATH=''
- >-
if [ -d "$SCREENSHOTS_PATH" ]; then
cp -r $SCREENSHOTS_PATH $DEVICEFARM_SCREENSHOT_PATH
fi

# The artifacts phase lets you specify the location where your tests logs, device logs will be stored.
# And also let you specify the location of your test logs and artifacts which you want to be collected by Device Farm.
Expand Down
4 changes: 4 additions & 0 deletions lib/src/base/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,7 @@ String formatArns(List arns) {

/// tests for empty [string].
bool isEmpty(String string) => !(string != null && string.isNotEmpty);

String capitalize(String str) {
return "${str[0].toUpperCase()}${str.substring(1)}";
}
2 changes: 2 additions & 0 deletions lib/src/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ class Config {
String get tmpDir => _configInfo['tmp_dir'];
bool get concurrentRuns => _configInfo['concurrent_runs'];
String get artifactsDir => _configInfo['artifacts_dir'];
String get screenhostDir => _configInfo['screenhost_dir'];
String get flavor => _configInfo['flavor'];
String get appIdentifier => _configInfo['app_identifier'];

List<SylphDevice> getPoolDevices(String poolName) =>
_getSylphDevices(_getPoolInfo(poolName));
Expand Down
9 changes: 6 additions & 3 deletions lib/src/resources.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const kAppIdentifier = 'APP_IDENTIFIER';
/// Unpacks resources found in package into [tmpDir].
/// Appium template is used to deliver tests.
/// Scripts are used to initialize device and run tests.
Future<void> unpackResources(String tmpDir, bool isIosPoolTypeActive,
Future<void> unpackResources(String tmpDir, String appIdentifier, bool isIosPoolTypeActive,
{String appDir = '.'}) async {
printStatus('Unpacking sylph resources to $tmpDir');
clearDirectory(tmpDir);
Expand All @@ -50,8 +50,11 @@ Future<void> unpackResources(String tmpDir, bool isIosPoolTypeActive,

// unpack build to os map file
await unpackFile(kBuildToOsMapFileName, tmpDir);

final nameVals = {kAppIdentifier: getIosAppIdentifier(appDir)};

final nameVals = {kAppIdentifier:
appIdentifier?.isEmpty ?? true
? getIosAppIdentifier(appDir)
: appIdentifier};

// unpack export options
if (isIosPoolTypeActive) {
Expand Down
30 changes: 26 additions & 4 deletions lib/src/sylph_run.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import 'base/devices.dart';
import 'base/utils.dart';

const kDebugApkPath = 'build/app/outputs/apk/debug/app-debug.apk';
const kDebugIpaPath = 'build/ios/Debug-iphoneos/Debug_Runner.ipa';

/// Processes config file (subject to change).
/// For each device pool:
Expand Down Expand Up @@ -53,7 +52,7 @@ Future<bool> sylphRun(String configFilePath, String sylphRunName,
final projectArn = setupProject(config.projectName, config.defaultJobTimeout);

// Unpack resources used for building debug .ipa and to bundle tests
await unpackResources(config.tmpDir, isIosPoolTypeActive);
await unpackResources(config.tmpDir, config.appIdentifier, isIosPoolTypeActive);

// Bundle tests
bundleFlutterTests(config);
Expand Down Expand Up @@ -149,6 +148,11 @@ Future<bool> runSylphJob(
tmpDir,
config.flavor,
);
final appId = await _getAppId(
devicePool.deviceType,
config.flavor
);
printStatus('Aplication id: $appId');

// Upload test suite (in 2 parts)

Expand All @@ -161,7 +165,7 @@ Future<bool> runSylphJob(
// 2. Upload custom test spec yaml
final testSpecPath = '$tmpDir/$kAppiumTestSpecName';
// Substitute MAIN and TESTS for actual debug main and tests from test suite.
setTestSpecEnv(testSuite, testSpecPath);
setTestSpecEnv(testSuite, testSpecPath, appId, config.screenhostDir);
printStatus('Uploading test specification: $testSpecPath ...');
String testSpecArn =
await uploadFile(projectArn, testSpecPath, 'APPIUM_PYTHON_TEST_SPEC');
Expand Down Expand Up @@ -216,12 +220,21 @@ Future<String> _buildUploadApp(String projectArn, DeviceType poolType,
addFlavor(flavor);
await streamCmd(command);
// Upload ipa
final kDebugIpaPath = flavor.isNotEmpty ? 'build/ios/Debug ${flavor}-iphoneos/Debug_Runner.ipa' : 'build/ios/Debug-iphoneos/Debug_Runner.ipa';
printStatus('Uploading debug iOS app: $kDebugIpaPath ...');
appArn = await uploadFile(projectArn, kDebugIpaPath, 'IOS_APP');
}
return appArn;
}

String _getAppId(DeviceType poolType, String flavor) {
if (poolType == DeviceType.android) {
final applicationIdPath = 'build/app/intermediates/metadata_application_id/${flavor}Debug/write${capitalize(flavor)}DebugApplicationId/application-id.txt';
return fs.file(applicationIdPath).readAsStringSync();
}
return '';
}

/// Runs the test suite on each device in device pool and downloads artifacts.
/// Returns [bool] on pass/fail.
Future<bool> _runTests(
Expand Down Expand Up @@ -272,18 +285,27 @@ DateTime sylphTimestamp() {
}

/// Set MAIN and TESTS env vars in test spec.
void setTestSpecEnv(TestSuite test_suite, String testSpecPath) {
void setTestSpecEnv(TestSuite test_suite, String testSpecPath, String appId, String screenhostDir) {
const kMainEnvName = 'MAIN=';
const kTestsEnvName = 'TESTS=';
const kAppIdEnvName = 'APP_ID=';
const kScreenhostPathEnvName = 'SCREENSHOTS_PATH=';
final mainEnvVal = test_suite.main;
final testsEnvVal = test_suite.tests.join(",");
final appIdEnvVal = appId;
final mainRegExp = RegExp('$kMainEnvName.*');
final testsRegExp = RegExp('$kTestsEnvName.*');
final appIdRegExp = RegExp('$kAppIdEnvName.*');
final screenhostPathRegExp = RegExp('$kScreenhostPathEnvName.*');
String testSpecStr = fs.file(testSpecPath).readAsStringSync();
testSpecStr =
testSpecStr.replaceFirst(mainRegExp, '$kMainEnvName$mainEnvVal');
testSpecStr =
testSpecStr.replaceAll(testsRegExp, '$kTestsEnvName\'$testsEnvVal\'');
testSpecStr =
testSpecStr.replaceAll(appIdRegExp, '$kAppIdEnvName\'$appIdEnvVal\'');
testSpecStr =
testSpecStr.replaceAll(screenhostPathRegExp, '$kScreenhostPathEnvName\'$screenhostDir\'');
fs.file(testSpecPath).writeAsStringSync(testSpecStr);
}

Expand Down