-
Notifications
You must be signed in to change notification settings - Fork 0
Add gauge-appium (Java, Gauge + Appium) App Automate sample — android/ #1
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
Open
AakashHotchandani
wants to merge
7
commits into
main
Choose a base branch
from
sdk-sample
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
6c11f50
Add gauge-appium (Java, Gauge + Appium) App Automate sample — android/
AakashHotchandani 1a0f2a1
Restore scaffold files dropped by import (Semgrep CI workflow, CODEOW…
AakashHotchandani 88bb785
Add BrowserStack SDK sample-test GitHub Actions workflow (workflow_di…
AakashHotchandani 638d253
Add least-privilege permissions to sample-test workflow (CodeQL: limi…
AakashHotchandani 7dafc98
Commit public sample app(s) + reference by relative path (drop accoun…
AakashHotchandani 5968976
Framework-led source token (gauge) to match published sibling convent…
AakashHotchandani d921e9f
Fix README cd path to the full repo directory name
AakashHotchandani File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| # Runs the BrowserStack SDK sample against a given commit and reports a status check. | ||
| # Trigger: Actions tab -> "Gauge Appium App Automate SDK sample test" -> Run workflow -> paste the PR's full commit SHA. | ||
| # Requires repo secrets: BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY. | ||
| # NOTE (App Automate): the app under test is referenced via `app: bs://...` in browserstack.yml; | ||
| # ensure that uploaded app exists on the account whose secrets are used (re-upload + update if expired). | ||
| name: Gauge Appium App Automate SDK sample test | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| inputs: | ||
| commit_sha: | ||
| description: 'The full commit id to build' | ||
| required: true | ||
|
|
||
| permissions: | ||
| contents: read # checkout | ||
| checks: write # github-script creates the status check | ||
|
|
||
| jobs: | ||
| sdk-sample: | ||
| runs-on: ${{ matrix.os }} | ||
| strategy: | ||
| fail-fast: false | ||
| max-parallel: 3 | ||
| matrix: | ||
| os: [ubuntu-latest] | ||
| java: ['11', '17'] | ||
| name: gauge-appium JDK ${{ matrix.java }} sample | ||
| env: | ||
| BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} | ||
| BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} | ||
| defaults: | ||
| run: | ||
| working-directory: android | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| ref: ${{ github.event.inputs.commit_sha }} | ||
| - name: Mark status check in_progress | ||
| uses: actions/github-script@v7 | ||
| env: | ||
| job_name: gauge-appium JDK ${{ matrix.java }} sample | ||
| commit_sha: ${{ github.event.inputs.commit_sha }} | ||
| with: | ||
| github-token: ${{ github.token }} | ||
| script: | | ||
| await github.rest.checks.create({ | ||
| owner: context.repo.owner, repo: context.repo.repo, | ||
| name: process.env.job_name, head_sha: process.env.commit_sha, | ||
| status: 'in_progress' | ||
| }).catch(e => console.log('check create failed:', e.status)); | ||
| - uses: actions/setup-java@v4 | ||
| with: | ||
| distribution: 'temurin' | ||
| java-version: ${{ matrix.java }} | ||
| - name: Install Gauge | ||
| run: | | ||
| npm install -g @getgauge/cli | ||
| gauge install java | ||
| - name: Run sample test | ||
| run: | | ||
| mvn compile | ||
| mvn test | ||
| - name: Mark status check completed | ||
| if: always() | ||
| uses: actions/github-script@v7 | ||
| env: | ||
| conclusion: ${{ job.status }} | ||
| job_name: gauge-appium JDK ${{ matrix.java }} sample | ||
| commit_sha: ${{ github.event.inputs.commit_sha }} | ||
| with: | ||
| github-token: ${{ github.token }} | ||
| script: | | ||
| await github.rest.checks.create({ | ||
| owner: context.repo.owner, repo: context.repo.repo, | ||
| name: process.env.job_name, head_sha: process.env.commit_sha, | ||
| status: 'completed', conclusion: process.env.conclusion | ||
| }).catch(e => console.log('check create failed:', e.status)); | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Gradle | ||
| .gradle/ | ||
| **/build/ | ||
| gradle-app.setting | ||
|
|
||
| # Gauge | ||
| **/logs/ | ||
| **/log/ | ||
| **/reports/ | ||
| **/.gauge/ | ||
| local.log | ||
|
|
||
| # BrowserStack SDK run artifacts | ||
| **/browserstack.err | ||
| **/bstack_build_*/ | ||
| **/gradle-m-config.json | ||
| **/dependency-tree.log | ||
|
|
||
| # IDE | ||
| .idea/ | ||
| *.iml | ||
| .vscode/ | ||
| .settings/ | ||
| .project | ||
| .classpath | ||
|
|
||
| # OS | ||
| .DS_Store | ||
|
|
||
| # Credentials — never commit | ||
| *.env |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,117 @@ | ||
| # gauge-appium-app-browserstack | ||
| We require the following new public repositories under the browserstack GitHub organization to host customer-facing sample projects for the BrowserStack SDK. | ||
| # Gauge + Appium with BrowserStack App Automate | ||
|
|
||
| Run [Gauge](https://gauge.org/) + [Appium](https://appium.io/) (Java) mobile tests on real devices | ||
| in the [BrowserStack App Automate](https://app-automate.browserstack.com/) cloud, instrumented by the | ||
| [BrowserStack Java SDK](https://www.browserstack.com/docs/app-automate/appium/getting-started/java). | ||
|
|
||
| The SDK reads `browserstack.yml`, uploads/points at the app under test, provisions the device, and reports | ||
| each scenario's name and status to App Automate and Test Observability — no per-test capability code. | ||
|
|
||
| This sample currently ships the **`android/`** platform directory (Android, Samsung Galaxy S22 Ultra). | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - A [BrowserStack](https://www.browserstack.com/) account (username + access key). | ||
| - **JDK 11+** (`java -version`). | ||
| - **Gradle 7+** (a wrapper can be generated with `gradle wrapper`). | ||
| - **Gauge CLI** with the Java plugin: | ||
| ```bash | ||
| brew install gauge # macOS (or see https://docs.gauge.org/getting_started/installing-gauge.html) | ||
| gauge install java | ||
| gauge install html-report | ||
| gauge install screenshot | ||
| ``` | ||
|
|
||
| ## Setup | ||
|
|
||
| ```bash | ||
| git clone <this-repo> | ||
| cd gauge-appium-app-browserstack/android | ||
| ``` | ||
|
|
||
| Configure credentials — set them as environment variables (recommended) or edit `android/browserstack.yml`: | ||
|
|
||
| ```bash | ||
| export BROWSERSTACK_USERNAME="YOUR_USERNAME" | ||
| export BROWSERSTACK_ACCESS_KEY="YOUR_ACCESS_KEY" | ||
| ``` | ||
|
|
||
| Resolve dependencies and stage the BrowserStack Java SDK agent: | ||
|
|
||
| ```bash | ||
| gradle clean build copyBrowserStackAgent | ||
| ``` | ||
|
|
||
| `copyBrowserStackAgent` stages the resolved `browserstack-java-sdk` jar at `build/agent/browserstack-java-sdk.jar`. | ||
| The `-javaagent` is attached to the **Gauge Java runner JVM** via `env/default/java.properties` | ||
| (`gauge_jvm_args`) — Gauge spawns its own runner JVM, so the agent must be wired there (not on the Gradle | ||
| build JVM) for the Appium driver to be instrumented. | ||
|
|
||
| ### App under test | ||
|
|
||
| `android/browserstack.yml` points at a pre-uploaded `WikipediaSample.apk` | ||
| (`app: bs://92d48b416632f2b1734259565ceab61b05ad0b24`). To use your own build, upload it and replace the value: | ||
|
|
||
| ```bash | ||
| curl -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \ | ||
| -X POST "https://api-cloud.browserstack.com/app-automate/upload" \ | ||
| -F "file=@/path/to/WikipediaSample.apk" | ||
| # -> use the returned "app_url" (bs://...) as the `app:` value | ||
| ``` | ||
|
|
||
| ## Run Sample Test | ||
|
|
||
| Searches the Wikipedia sample app for "BrowserStack" and asserts results are listed. | ||
|
|
||
| ```bash | ||
| cd android | ||
| gradle runSampleTest | ||
| # or run the whole suite: gradle gauge | ||
| # or via the Gauge CLI: gauge run specs/bstack-specs/bstack-sample.spec | ||
| ``` | ||
|
|
||
| ## Run Local Test | ||
|
|
||
| Verifies the [BrowserStack Local](https://www.browserstack.com/local-testing/app-automate) tunnel is | ||
| connected. The SDK starts the tunnel automatically because `browserstackLocal: true` is set in | ||
| `browserstack.yml`. | ||
|
|
||
| ```bash | ||
| cd android | ||
| gradle runLocalTest | ||
| # or via the Gauge CLI: gauge run specs/bstack-specs/local-test.spec | ||
| ``` | ||
|
|
||
| ## Notes / Dashboard | ||
|
|
||
| - View runs, video, device logs, and network logs at **https://app-automate.browserstack.com/**. | ||
| - With `testObservability: true`, builds also appear at **https://observability.browserstack.com/**. | ||
| - The `framework: gauge` token in `browserstack.yml` lets the Java SDK report each scenario's name and | ||
| status to BrowserStack. | ||
| - The BrowserStack Gradle SDK plugin (`com.browserstack.gradle-sdk`) is declared per the BrowserStack | ||
| SDK convention; the actual Appium-driver instrumentation for this Gauge/Java flow is performed by the | ||
| `browserstack-java-sdk` `-javaagent` on the Gauge runner JVM (see Setup). | ||
|
|
||
| ### Known issue (BrowserStack Java SDK + Gauge App Automate) | ||
|
|
||
| With the **published** `browserstack-java-sdk:1.59.7`, `framework: gauge` disables the SDK's normal | ||
| in-process flow and instead drives the run through the **Gradle Tooling API** (it re-invokes the | ||
| `gauge` task per device platform). On this version the SDK mis-resolves the Gradle installation to | ||
| `GRADLE_USER_HOME` (`~/.gradle`) and the Tooling-API connection fails: | ||
|
|
||
| ``` | ||
| GradleTaskExecutor - Using Gradle Installation /Users/<you>/.gradle | ||
| GradleTaskExecutor - Gradle connection failed for Platform Index: 0 | ||
| [SDK-TRA-006] ... could not find relevant classes from gauge on your class path | ||
| ``` | ||
|
|
||
| The SDK then ends its run inside the `-javaagent` premain and the Gauge runner JVM exits before any | ||
| test (and therefore any Appium driver / device session) is created. Only the Observability/TestHub | ||
| build is created; no App Automate device session starts. | ||
|
|
||
| This reproduces with both `gauge run` and `gradle gauge`, with `gauge-java` 0.12.0 and 1.0.1, and with | ||
| or without the `framework` token. The known-working internal reference for this combo used **unpublished | ||
| local dev builds** (`browserstack-java-sdk-1.32.12` + `gradle-sdk` plugin `99.86.49`). Track the fix / | ||
| a published known-good SDK version with the BrowserStack Java SDK team before relying on this sample for | ||
| a live device run. The repo itself is complete and compiles; the blocker is in the SDK's Gauge App | ||
| Automate execution path, not in the test code. |
Binary file not shown.
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| # ============================= | ||
| # Set BrowserStack Credentials | ||
| # ============================= | ||
| # Add your BrowserStack userName and accessKey here or set BROWSERSTACK_USERNAME and | ||
| # BROWSERSTACK_ACCESS_KEY as env variables. | ||
| userName: YOUR_USERNAME | ||
| accessKey: YOUR_ACCESS_KEY | ||
|
|
||
| # ====================== | ||
| # BrowserStack Reporting | ||
| # ====================== | ||
| projectName: BrowserStack Samples | ||
| buildName: appauto-gauge-appium | ||
| buildIdentifier: '#${BUILD_NUMBER}' | ||
| # `framework` lets the BrowserStack Java SDK (javaagent) instrument the Gauge runner and report each | ||
| # scenario's name and status to BrowserStack. The SDK's gauge instrumentation is validated against the | ||
| # Gauge `java` runner plugin + gauge-java library 0.12.0 (see build.gradle); keep those aligned. | ||
| framework: gauge | ||
|
|
||
| # ====================================== | ||
| # Public sample app committed in this repo (relative path); the SDK uploads it at run time. | ||
| # ====================================== | ||
| # WikipediaSample.apk, already uploaded to BrowserStack App Automate. | ||
| # To upload your own build, run: | ||
| # curl -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \ | ||
| # -X POST "https://api-cloud.browserstack.com/app-automate/upload" \ | ||
| # -F "file=@/path/to/WikipediaSample.apk" | ||
| # Public sample app committed in this repo (relative path); the SDK uploads it at run time. | ||
| app: ./WikipediaSample.apk | ||
|
|
||
| # ======================================= | ||
| # Platforms (real devices to test on) | ||
| # ======================================= | ||
| platforms: | ||
| - deviceName: Samsung Galaxy S22 Ultra | ||
| osVersion: "12.0" | ||
| platformName: android | ||
|
|
||
| # ======================= | ||
| # Parallels per Platform | ||
| # ======================= | ||
| parallelsPerPlatform: 1 | ||
|
|
||
| # ========================================== | ||
| # BrowserStack Local (for the local test) | ||
| # ========================================== | ||
| browserstackLocal: true | ||
|
|
||
| source: gauge:appium-sample-sdk:v1.0 | ||
|
|
||
| # ====================== | ||
| # Test Observability | ||
| # ====================== | ||
| testObservability: true | ||
|
|
||
| # =================== | ||
| # Debugging features | ||
| # =================== | ||
| debug: true | ||
| networkLogs: true |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| plugins { | ||
| id 'java' | ||
| id 'org.gauge' version '1.8.2' | ||
| // BrowserStack Gradle SDK plugin (latest). Declared per the BrowserStack SDK convention. | ||
| id 'com.browserstack.gradle-sdk' version '3.1.6' | ||
| } | ||
|
|
||
| apply plugin: 'com.browserstack.gradle-sdk' | ||
|
|
||
| group 'com.browserstack' | ||
| version '1.0-SNAPSHOT' | ||
|
|
||
| java { | ||
| sourceCompatibility = JavaVersion.VERSION_11 | ||
| targetCompatibility = JavaVersion.VERSION_11 | ||
| } | ||
|
|
||
| repositories { | ||
| mavenCentral() | ||
| mavenLocal() | ||
| } | ||
|
|
||
| configurations.all { | ||
| resolutionStrategy { | ||
| eachDependency { details -> | ||
| if (details.requested.group == 'com.google.guava' && details.requested.name == 'guava') { | ||
| details.useVersion '32.1.2-jre' | ||
| details.because 'Align Guava across Selenium/Appium/Gauge for Java 11+' | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation 'com.google.guava:guava:32.1.2-jre' | ||
| // gauge-java MUST match the installed Gauge Java runner plugin version. The BrowserStack Java SDK's | ||
| // gauge instrumentation is validated against gauge-java 0.12.0 (the reference pin); pair it with the | ||
| // matching Gauge `java` runner plugin (0.12.0). A newer gauge-java (1.0.1) trips SDK error SDK-TRA-006. | ||
| implementation 'com.thoughtworks.gauge:gauge-java:0.12.0' | ||
| implementation 'org.seleniumhq.selenium:selenium-java:4.13.0' | ||
| implementation 'io.appium:java-client:8.6.0' | ||
| implementation 'com.browserstack:browserstack-local-java:1.0.6' | ||
| implementation 'commons-io:commons-io:2.11.0' | ||
| testImplementation 'org.assertj:assertj-core:3.20.2' | ||
|
|
||
| // BrowserStack Java SDK — provides the -javaagent that instruments the Appium driver and | ||
| // injects app + device capabilities from browserstack.yml. The agent is attached to the | ||
| // Gauge Java *runner* JVM via env/default/java.properties (gauge_jvm_args). Resolving LATEST | ||
| // from Maven Central also makes the jar available under ~/.m2 / the Gradle cache so the | ||
| // -javaagent path can point at it. See README.md. | ||
| // NOTE: Gradle does not understand Maven's "LATEST" keyword — use "latest.release". | ||
| implementation 'com.browserstack:browserstack-java-sdk:latest.release' | ||
| } | ||
|
|
||
| // Convenience: copy the resolved BrowserStack Java SDK jar into build/agent so env/default/java.properties | ||
| // can reference a stable, version-independent path (build/agent/browserstack-java-sdk.jar). | ||
| task copyBrowserStackAgent(type: Copy) { | ||
| description = 'Stage the BrowserStack Java SDK jar for the -javaagent on the Gauge runner JVM.' | ||
| from { | ||
| configurations.runtimeClasspath.find { it.name ==~ /browserstack-java-sdk-.*\.jar/ } | ||
| } | ||
| into "$projectDir/build/agent" | ||
| rename { 'browserstack-java-sdk.jar' } | ||
| } | ||
|
|
||
| // Helper: build a Gauge-CLI run task. | ||
| // We invoke the Gauge CLI directly (rather than the org.gauge GaugeTask, which subclasses Gradle's | ||
| // `Test` task and is skipped as NO-SOURCE because there are no JUnit/TestNG classes). The Gauge Java | ||
| // runner classpath is provided explicitly via the gauge_custom_classpath env var, sourced from the | ||
| // project's compiled test classes + full runtime dependencies. The -javaagent is wired separately on | ||
| // the Gauge runner JVM via env/default/java.properties (gauge_jvm_args). | ||
| def gaugeRunTask = { String taskName, String specPath, String desc -> | ||
| tasks.register(taskName, Exec) { | ||
| group = 'verification' | ||
| description = desc | ||
| dependsOn 'testClasses', 'copyBrowserStackAgent' | ||
| workingDir projectDir | ||
| doFirst { | ||
| def cp = sourceSets.test.runtimeClasspath.files | ||
| .collect { it.absolutePath }.join(File.pathSeparator) | ||
| environment 'gauge_custom_classpath', cp | ||
| commandLine 'gauge', 'run', '--verbose', specPath | ||
| } | ||
| } | ||
| } | ||
|
|
||
| gaugeRunTask('runSampleTest', 'specs/bstack-specs/bstack-sample.spec', | ||
| 'Run the WikipediaSample sample spec on BrowserStack App Automate.') | ||
| gaugeRunTask('runLocalTest', 'specs/bstack-specs/local-test.spec', | ||
| 'Run the LocalSample local-connection spec on BrowserStack App Automate.') | ||
| gaugeRunTask('runTests', 'specs/bstack-specs', | ||
| 'Run the full Gauge spec suite on BrowserStack App Automate.') | ||
|
|
||
| // Print the test runtime classpath (compiled test classes + all runtime deps) so the Gauge CLI can | ||
| // also be invoked manually: `export gauge_custom_classpath=$(cat build/gauge-classpath.txt); gauge run …` | ||
| task printGaugeClasspath { | ||
| dependsOn 'testClasses' | ||
| doLast { | ||
| def cp = sourceSets.test.runtimeClasspath.files.collect { it.absolutePath }.join(File.pathSeparator) | ||
| new File("$projectDir/build/gauge-classpath.txt").text = cp | ||
| println "WROTE_CLASSPATH" | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.