diff --git a/.github/workflows/Semgrep.yml b/.github/workflows/Semgrep.yml new file mode 100644 index 0000000..0347afd --- /dev/null +++ b/.github/workflows/Semgrep.yml @@ -0,0 +1,48 @@ +# Name of this GitHub Actions workflow. +name: Semgrep + +on: + # Scan changed files in PRs (diff-aware scanning): + # The branches below must be a subset of the branches above + pull_request: + branches: ["master", "main"] + push: + branches: ["master", "main"] + schedule: + - cron: '0 6 * * *' + + +permissions: + contents: read + +jobs: + semgrep: + # User definable name of this GitHub Actions job. + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + name: semgrep/ci + # If you are self-hosting, change the following `runs-on` value: + runs-on: ubuntu-latest + + container: + # A Docker image with Semgrep installed. Do not change this. + image: returntocorp/semgrep + + # Skip any PR created by dependabot to avoid permission issues: + if: (github.actor != 'dependabot[bot]') + + steps: + # Fetch project source with GitHub Actions Checkout. + - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + # Run the "semgrep ci" command on the command line of the docker image. + - run: semgrep ci --sarif --output=semgrep.sarif + env: + # Add the rules that Semgrep uses by setting the SEMGREP_RULES environment variable. + SEMGREP_RULES: p/default # more at semgrep.dev/explore + + - name: Upload SARIF file for GitHub Advanced Security Dashboard + uses: github/codeql-action/upload-sarif@6c089f53dd51dc3fc7e599c3cb5356453a52ca9e # v2.20.0 + with: + sarif_file: semgrep.sarif + if: always() \ No newline at end of file diff --git a/.github/workflows/sanity-workflow.yml b/.github/workflows/sanity-workflow.yml new file mode 100644 index 0000000..a643564 --- /dev/null +++ b/.github/workflows/sanity-workflow.yml @@ -0,0 +1,148 @@ +# This job is to test different maven profiles in sdk branch against full commit-id provided +# This workflow targets Java with Maven execution + +name: Java SDK Test workflow for Maven on workflow_dispatch + +on: + workflow_dispatch: + inputs: + commit_sha: + description: 'The full commit id to build' + required: true + +jobs: + comment-run: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + max-parallel: 3 + matrix: + java: [ '8', '11', '17' ] + os: [ 'macos-latest', 'windows-latest', 'ubuntu-latest' ] + name: JUnit Appium Repo ${{ matrix.Java }} - ${{ matrix.os }} Sample + env: + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} + BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.inputs.commit_sha }} + - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 + id: status-check-in-progress + env: + job_name: JUnit Appium Repo ${{ matrix.Java }} - ${{ matrix.os }} Sample + commit_sha: ${{ github.event.inputs.commit_sha }} + with: + github-token: ${{ github.token }} + script: | + const result = 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((err) => ({status: err.status, response: err.response})); + console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) + if (result.status !== 201) { + console.log('Failed to create check run') + } + - name: Set up Java + uses: actions/setup-java@v3 + with: + distribution: 'temurin' + java-version: ${{ matrix.java }} + - name: Run mvn test for junit4 android + run: | + cd junit-4/android + mvn compile + mvn test -P sample-test + - name: Run mvn profile sample-local-test for junit4 android + run: | + cd junit-4/android + mvn compile + mvn test -P sample-local-test -D"browserstack.app"="./LocalSample.apk" + - name: Run mvn test for junit4 ios + run: | + cd junit-4/ios + mvn compile + mvn test -P sample-test + - name: Run mvn profile sample-local-test for junit4 ios + run: | + cd junit-4/ios + mvn compile + mvn test -P sample-local-test -D"browserstack.app"="./LocalSample.ipa" + - name: Run gradle test for junit4 android + run: | + cd junit-4/android + gradle clean sampleTest + - name: Run gradle sample-local-test for junit4 android + run: | + cd junit-4/android + gradle clean sampleLocalTest -D"browserstack.app"="./LocalSample.apk" + - name: Run gradle test for junit4 ios + run: | + cd junit-4/ios + gradle clean sampleTest + - name: Run gradle sample-local-test for junit4 ios + run: | + cd junit-4/ios + gradle clean sampleLocalTest -D"browserstack.app"="./LocalSample.ipa" + - name: Run mvn test for junit5 android + run: | + cd junit-5/android + mvn compile + mvn test -P sample-test + - name: Run mvn profile sample-local-test for junit5 android + run: | + cd junit-5/android + mvn compile + mvn test -P sample-local-test -D"browserstack.app"="./LocalSample.apk" + - name: Run mvn test for junit5 ios + run: | + cd junit-5/ios + mvn compile + mvn test -P sample-test + - name: Run mvn profile sample-local-test for junit5 ios + run: | + cd junit-5/ios + mvn compile + mvn test -P sample-local-test -D"browserstack.app"="./LocalSample.ipa" + - name: Run gradle test for junit5 android + run: | + cd junit-5/android + gradle clean sampleTest + - name: Run gradle sample-local-test for junit5 android + run: | + cd junit-5/android + gradle clean sampleLocalTest -D"browserstack.app"="./LocalSample.apk" + - name: Run gradle test for junit5 ios + run: | + cd junit-5/ios + gradle clean sampleTest + - name: Run gradle sample-local-test for junit5 ios + run: | + cd junit-5/ios + gradle clean sampleLocalTest -D"browserstack.app"="./LocalSample.ipa" + - if: always() + uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 + id: status-check-completed + env: + conclusion: ${{ job.status }} + job_name: JUnit Appium Repo ${{ matrix.Java }} - ${{ matrix.os }} Sample + commit_sha: ${{ github.event.inputs.commit_sha }} + with: + github-token: ${{ github.token }} + script: | + const result = 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((err) => ({status: err.status, response: err.response})); + console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) + if (result.status !== 201) { + console.log('Failed to create check run') + } diff --git a/.gitignore b/.gitignore index 04716af..a6c60e4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,11 @@ target/ local.log .idea -*.iml */*/logs +*.iml +bstack_* +gradlew* +gradle +.gradle +build +reports diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100644 index 0000000..ed09dd5 --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1 @@ +* @browserstack/app-automate-public-repos diff --git a/README.md b/README.md index dceeda1..8728e37 100644 --- a/README.md +++ b/README.md @@ -21,10 +21,16 @@ These code samples are currently based on: - For Windows, download latest java version from [here](https://java.com/en/download/) and run the installer executable - For Mac and Linux, run `java -version` to see what java version is pre-installed. If you want a different version download from [here](https://java.com/en/download/) -2. Maven +2. Maven (Only required if using Maven as the build tool) + - If Maven is not downloaded, download it from [here](https://maven.apache.org/download.cgi) - For installation, follow the instructions [here](https://maven.apache.org/install.html) +3. Gradle (Only required if using Gradle as the build tool) + + - If Gradle is not downloaded, download it from [here](https://gradle.org/releases/) + - For installation, follow the instructions [here](https://gradle.org/install/) + ### Install the dependencies To install the dependencies for JUnit4 tests, run : @@ -69,11 +75,25 @@ Getting Started with Appium tests in Junit4 and Junit5 on BrowserStack couldn't - Junit4 - Update `browserstack.yml` file at root level of [Android Junit4 examples](junit-4/android) or [iOS Junit4 examples](junit-4/ios) with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings) - - Run `mvn test -P sample-test` + - **For Maven:** Run the following command to execute tests in the Maven environment: + ```sh + mvn test -P sample-test + ``` + - **For Gradle:** Run the following command to execute tests in the Gradle environment: + ```sh + gradle clean sampleTest + ``` - Junit5 - Update `browserstack.yml` file at root level of [Android Junit5 examples](junit-5/android) or [iOS Junit5 examples](junit-5/ios) with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings) - - Run `mvn test -P sample-test` + - **For Maven:** Run the following command to execute tests in the Maven environment: + ```sh + mvn test -P sample-test + ``` + - **For Gradle:** Run the following command to execute tests in the Gradle environment: + ```sh + gradle clean sampleTest + ``` ### **Use Local testing for apps that access resources hosted in development or testing environments :** @@ -83,15 +103,29 @@ Getting Started with Appium tests in Junit4 and Junit5 on BrowserStack couldn't ``` browserstackLocal: true ``` - - Run `mvn test -P sample-local-test` + - **For Maven:** Run the following command to execute tests in the Maven environment: + ```sh + mvn test -P sample-local-test + ``` + - **For Gradle:** Run the following command to execute tests in the Gradle environment: + ```sh + gradle clean sampleLocalTest + ``` - - Junit5 - - Update `browserstack.yml` file at root level of Android Junit5 examples or iOS Junit5 examples with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings) - - Simply configure the browserstackLocal parameter in the browserstack.yml file accordingly in [Android Junit5 examples](junit-5/android) or [iOS Junit5 examples](junit-5/ios). +- Junit5 + - Update `browserstack.yml` file at root level of Android Junit5 examples or iOS Junit5 examples with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings) + - Simply configure the browserstackLocal parameter in the browserstack.yml file accordingly in [Android Junit5 examples](junit-5/android) or [iOS Junit5 examples](junit-5/ios). ``` browserstackLocal: true ``` - - Run `mvn test -P sample-local-test` + - **For Maven:** Run the following command to execute tests in the Maven environment: + ```sh + mvn test -P sample-local-test + ``` + - **For Gradle:** Run the following command to execute tests in the Gradle environment: + ```sh + gradle clean sampleLocalTest + ``` **Note**: If you are facing any issues, refer [Getting Help section](#Getting-Help) diff --git a/junit-4/android/build.gradle b/junit-4/android/build.gradle new file mode 100644 index 0000000..67ee4cd --- /dev/null +++ b/junit-4/android/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'java' + id 'com.browserstack.gradle-sdk' version "1.1.2" +} + +repositories { mavenCentral() } + +dependencies { + testImplementation 'junit:junit:4.13.2' + implementation 'commons-io:commons-io:2.11.0' + implementation 'org.seleniumhq.selenium:selenium-java:4.4.0' + implementation 'io.appium:java-client:8.1.1' + implementation 'com.googlecode.json-simple:json-simple:1.1.1' + implementation 'com.browserstack:browserstack-java-sdk:latest.release' +} + +group = 'com.browserstack' +version = '1.0-SNAPSHOT' +description = 'junit-browserstack' +sourceCompatibility = '1.8' + +def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' } + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +tasks.withType(Test) { + systemProperties = System.properties + jvmArgs += "-javaagent:${browserstackSDKArtifact.file}" +} + +task sampleTest(type: Test) { + dependsOn cleanTest + useJUnit() + + include 'com/browserstack/FirstTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} + + +task sampleLocalTest(type: Test) { + dependsOn cleanTest + useJUnit() + + include 'com/browserstack/LocalTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} diff --git a/junit-4/android/settings.gradle b/junit-4/android/settings.gradle new file mode 100644 index 0000000..3e5b662 --- /dev/null +++ b/junit-4/android/settings.gradle @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + mavenCentral() + mavenLocal() + gradlePluginPortal() + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.browserstack.gradle-sdk") { + useModule("com.browserstack:gradle-sdk:1.1.2") + } + } + } +} diff --git a/junit-4/ios/browserstack.yml b/junit-4/ios/browserstack.yml index 6dc64a4..5a22aa2 100644 --- a/junit-4/ios/browserstack.yml +++ b/junit-4/ios/browserstack.yml @@ -42,8 +42,8 @@ platforms: - deviceName: iPhone 13 Pro platformVersion: 15 platformName: ios - - deviceName: iPhone XS - platformVersion: 14 + - deviceName: iPhone 12 + platformVersion: 17 platformName: ios # ======================= diff --git a/junit-4/ios/build.gradle b/junit-4/ios/build.gradle new file mode 100644 index 0000000..67ee4cd --- /dev/null +++ b/junit-4/ios/build.gradle @@ -0,0 +1,50 @@ +plugins { + id 'java' + id 'com.browserstack.gradle-sdk' version "1.1.2" +} + +repositories { mavenCentral() } + +dependencies { + testImplementation 'junit:junit:4.13.2' + implementation 'commons-io:commons-io:2.11.0' + implementation 'org.seleniumhq.selenium:selenium-java:4.4.0' + implementation 'io.appium:java-client:8.1.1' + implementation 'com.googlecode.json-simple:json-simple:1.1.1' + implementation 'com.browserstack:browserstack-java-sdk:latest.release' +} + +group = 'com.browserstack' +version = '1.0-SNAPSHOT' +description = 'junit-browserstack' +sourceCompatibility = '1.8' + +def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' } + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +tasks.withType(Test) { + systemProperties = System.properties + jvmArgs += "-javaagent:${browserstackSDKArtifact.file}" +} + +task sampleTest(type: Test) { + dependsOn cleanTest + useJUnit() + + include 'com/browserstack/FirstTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} + + +task sampleLocalTest(type: Test) { + dependsOn cleanTest + useJUnit() + + include 'com/browserstack/LocalTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} diff --git a/junit-4/ios/settings.gradle b/junit-4/ios/settings.gradle new file mode 100644 index 0000000..3e5b662 --- /dev/null +++ b/junit-4/ios/settings.gradle @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + mavenCentral() + mavenLocal() + gradlePluginPortal() + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.browserstack.gradle-sdk") { + useModule("com.browserstack:gradle-sdk:1.1.2") + } + } + } +} diff --git a/junit-5/android/build.gradle b/junit-5/android/build.gradle new file mode 100644 index 0000000..1757ca2 --- /dev/null +++ b/junit-5/android/build.gradle @@ -0,0 +1,51 @@ +plugins { + id 'java' + id 'com.browserstack.gradle-sdk' version "1.1.2" +} + +repositories { mavenCentral() } + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' + implementation 'commons-io:commons-io:2.11.0' + implementation 'org.seleniumhq.selenium:selenium-java:4.4.0' + implementation 'io.appium:java-client:8.1.1' + implementation 'com.googlecode.json-simple:json-simple:1.1.1' + implementation 'com.browserstack:browserstack-java-sdk:latest.release' +} + +group = 'com.browserstack' +version = '1.0-SNAPSHOT' +description = 'junit-browserstack' +sourceCompatibility = '1.8' + +def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' } + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +tasks.withType(Test) { + systemProperties = System.properties + jvmArgs += "-javaagent:${browserstackSDKArtifact.file}" +} + +task sampleTest(type: Test) { + dependsOn cleanTest + useJUnitPlatform() + + include 'com/browserstack/FirstTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} + + +task sampleLocalTest(type: Test) { + dependsOn cleanTest + useJUnitPlatform() + + include 'com/browserstack/LocalTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} diff --git a/junit-5/android/settings.gradle b/junit-5/android/settings.gradle new file mode 100644 index 0000000..3e5b662 --- /dev/null +++ b/junit-5/android/settings.gradle @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + mavenCentral() + mavenLocal() + gradlePluginPortal() + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.browserstack.gradle-sdk") { + useModule("com.browserstack:gradle-sdk:1.1.2") + } + } + } +} diff --git a/junit-5/ios/browserstack.yml b/junit-5/ios/browserstack.yml index f0f47e0..13bc751 100644 --- a/junit-5/ios/browserstack.yml +++ b/junit-5/ios/browserstack.yml @@ -42,8 +42,8 @@ platforms: - deviceName: iPhone 13 Pro platformVersion: 15 platformName: ios - - deviceName: iPhone XS - platformVersion: 14 + - deviceName: iPhone 12 Pro + platformVersion: 17 platformName: ios # ======================= diff --git a/junit-5/ios/build.gradle b/junit-5/ios/build.gradle new file mode 100644 index 0000000..1757ca2 --- /dev/null +++ b/junit-5/ios/build.gradle @@ -0,0 +1,51 @@ +plugins { + id 'java' + id 'com.browserstack.gradle-sdk' version "1.1.2" +} + +repositories { mavenCentral() } + +dependencies { + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' + implementation 'commons-io:commons-io:2.11.0' + implementation 'org.seleniumhq.selenium:selenium-java:4.4.0' + implementation 'io.appium:java-client:8.1.1' + implementation 'com.googlecode.json-simple:json-simple:1.1.1' + implementation 'com.browserstack:browserstack-java-sdk:latest.release' +} + +group = 'com.browserstack' +version = '1.0-SNAPSHOT' +description = 'junit-browserstack' +sourceCompatibility = '1.8' + +def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' } + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +tasks.withType(Test) { + systemProperties = System.properties + jvmArgs += "-javaagent:${browserstackSDKArtifact.file}" +} + +task sampleTest(type: Test) { + dependsOn cleanTest + useJUnitPlatform() + + include 'com/browserstack/FirstTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} + + +task sampleLocalTest(type: Test) { + dependsOn cleanTest + useJUnitPlatform() + + include 'com/browserstack/LocalTest*' + + jvmArgs "-javaagent:${configurations.testRuntimeClasspath.find { it.name.contains('browserstack-java-sdk') }}" +} diff --git a/junit-5/ios/settings.gradle b/junit-5/ios/settings.gradle new file mode 100644 index 0000000..3e5b662 --- /dev/null +++ b/junit-5/ios/settings.gradle @@ -0,0 +1,15 @@ +pluginManagement { + repositories { + mavenCentral() + mavenLocal() + gradlePluginPortal() + } + + resolutionStrategy { + eachPlugin { + if (requested.id.id == "com.browserstack.gradle-sdk") { + useModule("com.browserstack:gradle-sdk:1.1.2") + } + } + } +}