-
Notifications
You must be signed in to change notification settings - Fork 0
Add vanilla-java-appium App Automate sample (Appium, 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
1ab3c82
Add vanilla-java-appium App Automate sample (Appium, Android)
AakashHotchandani 8fced6f
Restore scaffold files dropped by import (Semgrep CI workflow, CODEOW…
AakashHotchandani 8111745
Add BrowserStack SDK sample-test GitHub Actions workflow (workflow_di…
AakashHotchandani 583aad1
Add least-privilege permissions to sample-test workflow (CodeQL: limi…
AakashHotchandani 43d086f
Commit public sample app(s) + reference by relative path (drop accoun…
AakashHotchandani 12765cf
Framework-led source token (java) to match published sibling conventi…
AakashHotchandani dfe063d
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,74 @@ | ||
| # Runs the BrowserStack SDK sample against a given commit and reports a status check. | ||
| # Trigger: Actions tab -> "Vanilla Java 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: Vanilla Java 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: vanilla-java-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: vanilla-java-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: 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: vanilla-java-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 |
|---|---|---|
| @@ -1,2 +1,82 @@ | ||
| # vanilla-java-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. | ||
| # Vanilla Java Appium with BrowserStack App Automate | ||
|
|
||
| Run a vanilla Java Appium (Android) test on real devices via | ||
| [BrowserStack App Automate](https://app-automate.browserstack.com/) using the | ||
| [BrowserStack Java SDK](https://www.browserstack.com/docs/app-automate/appium/getting-started/java). | ||
|
|
||
| The SDK is attached as a `-javaagent`, reads `browserstack.yml`, selects the | ||
| pre-uploaded app, starts the Appium session on the chosen device, and reports | ||
| results back to BrowserStack — your test code stays plain `io.appium:java-client` | ||
| driving JUnit 5. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - A [BrowserStack](https://www.browserstack.com/) account (username + access key). | ||
| - JDK 8+ and Maven 3.6+. | ||
|
|
||
| ## Setup | ||
|
|
||
| ```bash | ||
| git clone <this-repo> | ||
| cd vanilla-java-appium-app-browserstack/android | ||
| mvn -DskipTests compile | ||
| ``` | ||
|
|
||
| Configure credentials either in `browserstack.yml` (`userName` / `accessKey`) | ||
| or as environment variables: | ||
|
|
||
| ```bash | ||
| export BROWSERSTACK_USERNAME="YOUR_USERNAME" | ||
| export BROWSERSTACK_ACCESS_KEY="YOUR_ACCESS_KEY" | ||
| ``` | ||
|
|
||
| The sample app is already referenced in `android/browserstack.yml` as a | ||
| pre-uploaded `bs://` app id (WikipediaSample.apk). To use your own build, set | ||
| `app:` to a local `.apk` path and the SDK will upload it for you. | ||
|
|
||
| ## Run Sample Test | ||
|
|
||
| ```bash | ||
| cd android | ||
| mvn test -Dtest=BStackSampleTest | ||
| ``` | ||
|
|
||
| The `-javaagent` is wired into the Maven Surefire plugin's `argLine` (the jar | ||
| path resolves from `~/.m2` via the `maven-dependency-plugin` `properties` goal), | ||
| so a plain `mvn test` attaches the SDK automatically. The sample test: | ||
|
|
||
| 1. taps **Search Wikipedia** (accessibility id), | ||
| 2. types `BrowserStack` into the search field, and | ||
| 3. asserts the results list rendered at least one entry. | ||
|
|
||
| ## Run Local Test | ||
|
|
||
| `BStackLocalTest` drives `LocalSample.apk` (pkg | ||
| `com.example.android.basicnetworking`) and asserts the in-app network check | ||
| reports **Up and running**, proving the BrowserStack Local tunnel is connected. | ||
| It is `@Disabled` by default because this `android/` dir ships wired to the | ||
| Wikipedia sample app. To run it: | ||
|
|
||
| 1. point `browserstack.yml` `app:` at `LocalSample.apk`, | ||
| 2. set `browserstackLocal: true`, | ||
| 3. remove the `@Disabled` annotation, then: | ||
|
|
||
| ```bash | ||
| cd android | ||
| mvn test -Dtest=BStackLocalTest | ||
| ``` | ||
|
|
||
| ## Notes / Dashboard | ||
|
|
||
| - Watch sessions live and review video/logs at | ||
| [app-automate.browserstack.com](https://app-automate.browserstack.com/). | ||
| - `testObservability: true` also surfaces this build in | ||
| [BrowserStack Test Observability](https://observability.browserstack.com/). | ||
| - The SDK dependency `com.browserstack:browserstack-java-sdk` uses `LATEST`, | ||
| matching the published-sample convention (resolved to `1.59.7` at validation | ||
| time). | ||
| - `io.appium:java-client` is pinned to `8.2.1` with `selenium-java` `4.5.0`. | ||
| Newer java-client (8.6.0) trips the SDK 1.59.7 javaagent on an empty/injected | ||
| capability set (`IllegalArgumentException: Capabilities must be set`, session | ||
| never starts); the 8.2.1 + Selenium 4.5.0 combo is the known-good pairing and | ||
| passes a live device session. |
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,7 @@ | ||
| target/ | ||
| .idea/ | ||
| *.iml | ||
| log/ | ||
| local.log | ||
| *.log | ||
| .DS_Store |
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,50 @@ | ||
| # ============================= | ||
| # 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-vanilla-java-appium | ||
| buildIdentifier: '#${BUILD_NUMBER}' | ||
| # `framework` lets the Java SDK instrument the JUnit 5 runner so it can report | ||
| # per-test context (name, status) to BrowserStack. Unlike the Node App Automate | ||
| # samples (where `framework` is injected into bstack:options and the Appium hub | ||
| # rejects it), the Java SDK reports test context out-of-band via the -javaagent | ||
| # and does NOT push `framework` into the W3C session caps, so it is safe here. | ||
| framework: junit5 | ||
|
|
||
| # Public sample app committed in this repo (relative path); the SDK uploads it at run time. | ||
| app: ./WikipediaSample.apk | ||
|
|
||
| # ======================================= | ||
| # Platforms (Devices to test) | ||
| # ======================================= | ||
| platforms: | ||
| - deviceName: Samsung Galaxy S22 Ultra | ||
| osVersion: "12.0" | ||
| platformName: android | ||
|
|
||
| # ======================= | ||
| # Parallels per Platform | ||
| # ======================= | ||
| parallelsPerPlatform: 1 | ||
|
|
||
| source: java:appium-sample-sdk:v1.0 | ||
|
|
||
| # ====================== | ||
| # Test Observability | ||
| # ====================== | ||
| testObservability: true | ||
|
|
||
| # =================== | ||
| # Debugging features | ||
| # =================== | ||
| debug: true | ||
| networkLogs: true | ||
| consoleLogs: errors |
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,95 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <groupId>com.browserstack</groupId> | ||
| <artifactId>vanilla-java-appium</artifactId> | ||
| <version>1.0-SNAPSHOT</version> | ||
| <packaging>jar</packaging> | ||
|
|
||
| <name>vanilla-java-appium</name> | ||
| <url>https://www.github.com/browserstack/vanilla-java-appium-app-browserstack</url> | ||
|
|
||
| <properties> | ||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||
| <maven.compiler.source>1.8</maven.compiler.source> | ||
| <maven.compiler.target>1.8</maven.compiler.target> | ||
| <junit.jupiter.version>5.10.2</junit.jupiter.version> | ||
| </properties> | ||
|
|
||
| <dependencies> | ||
| <!-- Selenium 4.5.0 — the version Appium java-client 8.2.1 was built | ||
| against (still ships org.openqa.selenium.Rotatable, which the | ||
| Appium AndroidDriver references). --> | ||
| <dependency> | ||
| <groupId>org.seleniumhq.selenium</groupId> | ||
| <artifactId>selenium-java</artifactId> | ||
| <version>4.5.0</version> | ||
| </dependency> | ||
|
|
||
| <!-- Appium Java client (drives the Android session on the BrowserStack hub) --> | ||
| <dependency> | ||
| <groupId>io.appium</groupId> | ||
| <artifactId>java-client</artifactId> | ||
| <version>8.2.1</version> | ||
| </dependency> | ||
|
|
||
| <!-- JUnit 5 (Jupiter) — the test runner the SDK instruments. --> | ||
| <dependency> | ||
| <groupId>org.junit.jupiter</groupId> | ||
| <artifactId>junit-jupiter</artifactId> | ||
| <version>${junit.jupiter.version}</version> | ||
| <scope>test</scope> | ||
| </dependency> | ||
|
|
||
| <!-- BrowserStack Java SDK: instruments the Appium driver + JUnit 5 runner | ||
| via the -javaagent (wired into surefire's argLine below). --> | ||
| <dependency> | ||
| <groupId>com.browserstack</groupId> | ||
| <artifactId>browserstack-java-sdk</artifactId> | ||
| <version>LATEST</version> | ||
| <scope>compile</scope> | ||
| </dependency> | ||
| </dependencies> | ||
|
|
||
| <build> | ||
| <plugins> | ||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-compiler-plugin</artifactId> | ||
| <version>3.8.1</version> | ||
| <configuration> | ||
| <source>${maven.compiler.source}</source> | ||
| <target>${maven.compiler.target}</target> | ||
| </configuration> | ||
| </plugin> | ||
|
|
||
| <!-- Exposes ${com.browserstack:browserstack-java-sdk:jar} = the absolute | ||
| path to the SDK jar resolved into ~/.m2, used by the -javaagent below. --> | ||
| <plugin> | ||
| <artifactId>maven-dependency-plugin</artifactId> | ||
| <executions> | ||
| <execution> | ||
| <id>getClasspathFilenames</id> | ||
| <goals> | ||
| <goal>properties</goal> | ||
| </goals> | ||
| </execution> | ||
| </executions> | ||
| </plugin> | ||
|
|
||
| <plugin> | ||
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-surefire-plugin</artifactId> | ||
| <version>3.2.5</version> | ||
| <configuration> | ||
| <!-- Attach the BrowserStack Java SDK as a -javaagent so it can | ||
| instrument the Appium driver and report test results. --> | ||
| <argLine>-javaagent:${com.browserstack:browserstack-java-sdk:jar}</argLine> | ||
| </configuration> | ||
| </plugin> | ||
| </plugins> | ||
| </build> | ||
| </project> |
82 changes: 82 additions & 0 deletions
82
android/src/test/java/com/browserstack/BStackLocalTest.java
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,82 @@ | ||
| package com.browserstack; | ||
|
|
||
| import io.appium.java_client.AppiumBy; | ||
| import io.appium.java_client.android.AndroidDriver; | ||
| import org.junit.jupiter.api.AfterEach; | ||
| import org.junit.jupiter.api.BeforeEach; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.api.Disabled; | ||
| import org.openqa.selenium.WebElement; | ||
| import org.openqa.selenium.remote.DesiredCapabilities; | ||
| import org.openqa.selenium.support.ui.ExpectedConditions; | ||
| import org.openqa.selenium.support.ui.WebDriverWait; | ||
|
|
||
| import java.net.URL; | ||
| import java.time.Duration; | ||
| import java.util.List; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
|
||
| /** | ||
| * Local App Automate test against the LocalSample.apk app | ||
| * (pkg com.example.android.basicnetworking). | ||
| * | ||
| * Proves the BrowserStack Local tunnel is connected: triggers the in-app network | ||
| * test action and asserts the app reports it is "Up and running". | ||
| * | ||
| * Requires browserstackLocal: true and the LocalSample.apk app in browserstack.yml. | ||
| * Disabled by default because this android/ dir is wired to the Wikipedia sample | ||
| * app + a single platform; enable it once you point browserstack.yml at | ||
| * LocalSample.apk and set browserstackLocal: true. | ||
| */ | ||
| @Disabled("Enable after configuring browserstack.yml with LocalSample.apk + browserstackLocal: true") | ||
| public class BStackLocalTest { | ||
|
|
||
| private AndroidDriver driver; | ||
|
|
||
| @BeforeEach | ||
| public void setUp() throws Exception { | ||
| String userName = System.getenv("BROWSERSTACK_USERNAME"); | ||
| String accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY"); | ||
|
|
||
| // Minimal capabilities — the SDK injects the app + device caps from | ||
| // browserstack.yml on top. platformName satisfies the Appium java-client | ||
| // 8.x W3C validation (it rejects a fully-empty capability set). | ||
| DesiredCapabilities capabilities = new DesiredCapabilities(); | ||
| capabilities.setCapability("platformName", "android"); | ||
|
|
||
| driver = new AndroidDriver( | ||
| new URL("http://" + userName + ":" + accessKey + "@hub.browserstack.com/wd/hub"), | ||
| capabilities); | ||
| } | ||
|
|
||
| @Test | ||
| public void localTunnelUpAndRunning() { | ||
| WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); | ||
|
|
||
| // Trigger the in-app network test action. | ||
| wait.until(ExpectedConditions.elementToBeClickable( | ||
| AppiumBy.id("com.example.android.basicnetworking:id/test_action"))).click(); | ||
|
|
||
| wait.until(ExpectedConditions.presenceOfElementLocated( | ||
| AppiumBy.className("android.widget.TextView"))); | ||
|
|
||
| // Assert a TextView reports the tunnel is up. | ||
| List<WebElement> textViews = driver.findElements( | ||
| AppiumBy.className("android.widget.TextView")); | ||
|
|
||
| boolean upAndRunning = textViews.stream() | ||
| .map(WebElement::getText) | ||
| .filter(t -> t != null) | ||
| .anyMatch(t -> t.contains("Up and running")); | ||
|
|
||
| assertTrue(upAndRunning, "Expected 'Up and running' text confirming the Local tunnel"); | ||
| } | ||
|
|
||
| @AfterEach | ||
| public void tearDown() { | ||
| if (driver != null) { | ||
| driver.quit(); | ||
| } | ||
| } | ||
| } |
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.