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

feat(detox): Add optional Test Butler setup #147

Open
wants to merge 1 commit into
base: main
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
2 changes: 2 additions & 0 deletions packages/detox/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ The plugin provides props for extra customization. Every time you change the pro

- `skipProguard` (_boolean_): Disable adding proguard minification to the `app/build.gradle`. Defaults to `false`.
- `subdomains` (_string[] | '\*'_): Hostnames to add to the network security config. Pass `'*'` to allow all domains. Defaults to `['10.0.2.2', 'localhost']`.
- `includeTestButler` (_boolean_): Enable [Test Butler](https://github.com/linkedin/test-butler) library injection in `app/build.grade` and modifications to JUnit test runner. Defaults to `false`

`app.config.js`

Expand All @@ -73,6 +74,7 @@ export default {
{
skipProguard: false,
subdomains: ["10.0.2.2", "localhost"],
includeTestButler: false
},
],
],
Expand Down
6 changes: 6 additions & 0 deletions packages/detox/build/withDetox.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions packages/detox/build/withDetox.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions packages/detox/build/withDetoxTestAppGradle.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 39 additions & 14 deletions packages/detox/build/withDetoxTestAppGradle.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/detox/build/withDetoxTestClass.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

37 changes: 21 additions & 16 deletions packages/detox/build/withDetoxTestClass.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 14 additions & 4 deletions packages/detox/src/withDetox.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import {

import withDetoxProjectGradle from "./withDetoxProjectGradle";
import withDetoxTestAppGradle from "./withDetoxTestAppGradle";
import { withDetoxTestClass } from "./withDetoxTestClass";
import withDetoxTestClass from "./withDetoxTestClass";
import withJUnitRunnerClass from "./withJUnitRunnerClass";
import withKotlinGradle from "./withKotlinGradle";
import {
withNetworkSecurityConfigManifest,
SubdomainsType,
} from "./withNetworkSecurityConfig";
import withProguardGradle from "./withProguardGradle";
import withTestButlerProbe from "./withTestButlerProbe";

const withDetox: ConfigPlugin<
{
Expand All @@ -30,27 +32,35 @@ const withDetox: ConfigPlugin<
* @default ['10.0.2.2', 'localhost'] // (Google emulators)
*/
subdomains?: SubdomainsType;
/**
* Enable Test Butler library injection in `app/build.grade` and modifications to JUnit test runner
*
* @default false
*/
includeTestButler?: boolean;
} | void
> = (config, { skipProguard, subdomains } = {}) => {
> = (config, { skipProguard, subdomains, includeTestButler } = {}) => {
return withPlugins(
config,
[
// 3.
withDetoxProjectGradle,
// 3.
withDetoxTestAppGradle,
withDetoxTestAppGradle(includeTestButler),
// 4.
[
withKotlinGradle,
// Minimum version of Kotlin required to work with expo packages in SDK 45
"1.6.10",
],
// 5.
withDetoxTestClass,
withDetoxTestClass(includeTestButler),
// 6.
[withNetworkSecurityConfigManifest, { subdomains }],
// 7.
!skipProguard && withProguardGradle,
includeTestButler && withTestButlerProbe,
includeTestButler && withJUnitRunnerClass,
].filter(Boolean) as ([ConfigPlugin, any] | ConfigPlugin)[]
);
};
Expand Down
75 changes: 57 additions & 18 deletions packages/detox/src/withDetoxTestAppGradle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ConfigPlugin, withAppBuildGradle } from "@expo/config-plugins";
import assert from "node:assert";

/**
* [Step 3](https://github.com/wix/Detox/blob/master/docs/Introduction.Android.md#3-add-the-native-detox-dependency). Add the Native Detox dependency.
Expand All @@ -7,22 +8,42 @@ import { ConfigPlugin, withAppBuildGradle } from "@expo/config-plugins";
* 2. Add `testInstrumentationRunner` to the app/build.gradle
* @param config
*/
const withDetoxTestAppGradle: ConfigPlugin = (config) => {
return withAppBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = setGradleAndroidTestImplementation(
config.modResults.contents
);
config.modResults.contents = addDetoxDefaultConfigBlock(
config.modResults.contents
);
} else {
throw new Error(
"Cannot add Detox maven gradle because the project build.gradle is not groovy"
);
}
return config;
});
const withDetoxTestAppGradle: (includeTestButler?: boolean) => ConfigPlugin = (
includeTestButler
) => {
return (config) => {
const packageName = config.android?.package;
assert(packageName, "android.package must be defined");

const testRunnerClass = includeTestButler
? `${packageName}.DetoxTestAppJUnitRunner`
: "androidx.test.runner.AndroidJUnitRunner";
console.log(includeTestButler, testRunnerClass)

return withAppBuildGradle(config, (config) => {
if (config.modResults.language === "groovy") {
config.modResults.contents = setGradleAndroidTestImplementation(
config.modResults.contents
);
config.modResults.contents = addDetoxDefaultConfigBlock(
config.modResults.contents,
testRunnerClass
);

if (includeTestButler) {
config.modResults.contents =
setGradleAndroidTestImplementationForTestButler(
config.modResults.contents
);
}
} else {
throw new Error(
"Cannot add Detox maven gradle because the project build.gradle is not groovy"
);
}
return config;
});
};
};

export function setGradleAndroidTestImplementation(
Expand All @@ -39,7 +60,25 @@ export function setGradleAndroidTestImplementation(
);
}

export function addDetoxDefaultConfigBlock(buildGradle: string): string {
export function setGradleAndroidTestImplementationForTestButler(
buildGradle: string
): string {
const pattern =
/androidTestImplementation 'com\.linkedin\.testbutler:test-butler-library:2\.2\.1'/g;
if (buildGradle.match(pattern)) {
return buildGradle;
}
return buildGradle.replace(
/dependencies\s?{/,
`dependencies {
androidTestImplementation 'com.linkedin.testbutler:test-butler-library:2.2.1'`
);
}

export function addDetoxDefaultConfigBlock(
buildGradle: string,
testRunnerClass: string
): string {
const pattern = /detox-plugin-default-config/g;
if (buildGradle.match(pattern)) {
return buildGradle;
Expand All @@ -50,7 +89,7 @@ export function addDetoxDefaultConfigBlock(buildGradle: string): string {
`defaultConfig {
// detox-plugin-default-config
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'`
testInstrumentationRunner '${testRunnerClass}'`
);
}

Expand Down
Loading