From a78503f883dbff6872230e4b97c645e444170138 Mon Sep 17 00:00:00 2001 From: Kamalpreet Kaur Date: Fri, 7 Jul 2023 12:10:55 +0530 Subject: [PATCH 1/3] init: cucumber-junit5 repo --- README.md | 41 +------------ browserstack.yml | 2 +- build.gradle | 57 ------------------- pom.xml | 54 +++++++++++------- .../RunWebDriverCucumberTests.java | 26 +++++---- .../RunWebDriverCucumberTestsLocal.java | 17 ++++++ src/test/resources/allure.properties | 1 - .../features/localtest/Local.feature | 2 +- .../resources/features/test/StackDemo.feature | 2 +- src/test/resources/testng.xml | 9 --- 10 files changed, 70 insertions(+), 141 deletions(-) delete mode 100644 build.gradle create mode 100644 src/test/java/com/browserstack/RunWebDriverCucumberTestsLocal.java delete mode 100644 src/test/resources/allure.properties delete mode 100644 src/test/resources/testng.xml diff --git a/README.md b/README.md index 86c6a84..d5f3ffc 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Cucumber Java Browserstack +# Cucumber-JUnit5 Java Browserstack ![BrowserStack Logo](https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780) [Cucumber JVM](https://cucumber.io/docs/reference/jvm) Integration with BrowserStack. @@ -12,7 +12,6 @@ - Install dependencies `mvn compile` - To run the test suite having cross-platform with parallelization, run `mvn test -P sample-test` - To run local tests, run `mvn test -P sample-local-test` -- To view Allure Reports, run `allure serve target/allure-results` Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github) @@ -57,43 +56,5 @@ Understand how many parallel sessions you need by using our [Parallel Test Calcu ``` -### Migrate from Vanilla Cucumber to use Testng Runner -* If you are using Vanilla Cucumber CLI, you can migrate to use TestNG Runner with BrowserStack using the below command : -``` -mvn archetype:generate -DarchetypeGroupId=com.browserstack -DarchetypeArtifactId=cucumber-testng-archetype -DarchetypeVersion=1.0 -DgroupId=com.browserstack -DartifactId=cucumber-testng-archetype -Dversion=1.0 -DinteractiveMode=false -``` -* Run your tests using `mvn test` -* To use specific `@CucumberOptions` in generated class `BrowserStackCucumberTestNgRunner`, refer - https://javadoc.io/static/io.cucumber/cucumber-testng/5.0.0-RC2/io/cucumber/testng/CucumberOptions.html - -## Using Gradle - -### Run sample build - -- Clone the repository -- Install dependencies `gradle build` -- To run the test suite having cross-platform with parallelization, run `gradle sampleTest` -- To run local tests, run `gradle sampleLocalTest` - -Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github) - -### Integrate your test suite - -* Install dependencies `gradle build` -* Following are the changes required in `gradle.build` - - * Add `compileOnly 'com.browserstack:browserstack-java-sdk:latest.release'` in dependencies - * Fetch Artifact Information and add `jvmArgs` property in tasks *SampleTest* and *SampleLocalTest* : - ``` - def browserstackSDKArtifact = configurations.compileClasspath.resolvedConfiguration.resolvedArtifacts.find { it.name == 'browserstack-java-sdk' } - - task sampleTest(type: Test) { - useTestNG() { - dependsOn cleanTest - useDefaultListeners = true - suites "config/sample-test.testng.xml" - jvmArgs "-javaagent:${browserstackSDKArtifact.file}" - } - } - ``` - ## Notes * You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate) diff --git a/browserstack.yml b/browserstack.yml index 99bde03..b86bae5 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -22,7 +22,7 @@ buildName: browserstack build buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression} # Set `framework` of your test suite. Example, `testng`, `cucumber`, `cucumber-testng` # This property is needed to send test context to BrowserStack (test name, status) -framework: cucumber-testng +framework: cucumber-junit5 # ======================================= # Platforms (Browsers / Devices to test) diff --git a/build.gradle b/build.gradle deleted file mode 100644 index 31d6830..0000000 --- a/build.gradle +++ /dev/null @@ -1,57 +0,0 @@ -plugins { - id 'java' -} - -repositories { - mavenCentral() -} - -dependencies { - implementation 'org.seleniumhq.selenium:selenium-java:4.1.4' - testImplementation 'io.cucumber:cucumber-java:7.3.4' - testImplementation 'io.cucumber:cucumber-testng:7.3.4' - testImplementation 'io.cucumber:cucumber-core:7.3.4' - compileOnly 'com.browserstack:browserstack-java-sdk:latest.release' -} - -group = 'com.browserstack' -version = '1.0-SNAPSHOT' -description = 'cucumber-java-browserstack' -sourceCompatibility = '1.8' -targetCompatibility = '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 -} - -task sampleTest(type: Test) { - systemProperty "cucumber.publish.quiet", "true" - systemProperty "cucumber.features", "src/test/resources/features/test" - systemProperties System.getProperties() - useTestNG() { - dependsOn clean - useDefaultListeners = true - suites "src/test/resources/testng.xml" - jvmArgs "-javaagent:${browserstackSDKArtifact.file}" - } - scanForTestClasses = false -} - -task sampleLocalTest(type: Test) { - systemProperty "cucumber.publish.quiet", "true" - systemProperty "cucumber.features", "src/test/resources/features/localtest" - systemProperties System.getProperties() - useTestNG() { - dependsOn clean - useDefaultListeners = true - suites "src/test/resources/testng.xml" - jvmArgs "-javaagent:${browserstackSDKArtifact.file}" - } - scanForTestClasses = false -} diff --git a/pom.xml b/pom.xml index fdb9d51..c50ffcf 100644 --- a/pom.xml +++ b/pom.xml @@ -15,20 +15,31 @@ 1.8 1.8 7.4.1 - 7.4.0 4.1.4 - 1.0.6 1.1.1 LATEST + 5.9.1 + 1.9.3 - org.testng - testng - ${testng.version} + org.junit.jupiter + junit-jupiter-api + ${junit-jupiter.version} test + + org.junit.platform + junit-platform-suite + ${junit-platform-suite.version} + test + + + org.junit.jupiter + junit-jupiter-engine + ${junit-jupiter.version} + io.cucumber cucumber-java @@ -37,7 +48,7 @@ io.cucumber - cucumber-testng + cucumber-junit-platform-engine ${cucumber.version} test @@ -88,15 +99,15 @@ maven-surefire-plugin 3.0.0-M5 - - src/test/resources/testng.xml - -javaagent:${com.browserstack:browserstack-java-sdk:jar} true + + **/RunWebDriverCucumberTests.java + @@ -111,16 +122,16 @@ maven-surefire-plugin 3.0.0-M5 - - src/test/resources/testng.xml - -javaagent:${com.browserstack:browserstack-java-sdk:jar} - + + + **/RunWebDriverCucumberTests.java + @@ -135,16 +146,21 @@ maven-surefire-plugin 3.0.0-M5 - - src/test/resources/testng.xml - -javaagent:${com.browserstack:browserstack-java-sdk:jar} - + + + + **/RunWebDriverCucumberTestsLocal.java + diff --git a/src/test/java/com/browserstack/RunWebDriverCucumberTests.java b/src/test/java/com/browserstack/RunWebDriverCucumberTests.java index 3be242f..bb6bfb4 100644 --- a/src/test/java/com/browserstack/RunWebDriverCucumberTests.java +++ b/src/test/java/com/browserstack/RunWebDriverCucumberTests.java @@ -1,15 +1,17 @@ package com.browserstack; -import io.cucumber.testng.*; +import org.junit.platform.suite.api.IncludeEngines; +import org.junit.platform.suite.api.SelectClasspathResource; +import org.junit.platform.suite.api.ConfigurationParameter; +import org.junit.platform.suite.api.Suite; -@CucumberOptions( - glue = "com.browserstack.stepdefs", - features = "src/test/resources/features/test", - plugin = { - "pretty", - "html:reports/tests/cucumber/cucumber-pretty.html", - "testng:reports/tests/cucumber/testng/cucumber.xml", - "json:reports/tests/cucumber/json/cucumberTestReport.json" - } -) -public class RunWebDriverCucumberTests extends AbstractTestNGCucumberTests {} +import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; +import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME; + +@Suite +@IncludeEngines("cucumber") +@SelectClasspathResource("features/test") +@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.browserstack.stepdefs") +@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty, json:reports/tests/cucumber/json/cucumberTestReport.json") +public class RunWebDriverCucumberTests { +} diff --git a/src/test/java/com/browserstack/RunWebDriverCucumberTestsLocal.java b/src/test/java/com/browserstack/RunWebDriverCucumberTestsLocal.java new file mode 100644 index 0000000..8a565c1 --- /dev/null +++ b/src/test/java/com/browserstack/RunWebDriverCucumberTestsLocal.java @@ -0,0 +1,17 @@ +package com.browserstack; + +import org.junit.platform.suite.api.IncludeEngines; +import org.junit.platform.suite.api.SelectClasspathResource; +import org.junit.platform.suite.api.ConfigurationParameter; +import org.junit.platform.suite.api.Suite; + +import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME; +import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME; + +@Suite +@IncludeEngines("cucumber") +@SelectClasspathResource("features/localtest") +@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.browserstack.stepdefs") +@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty, json:reports/tests/cucumber/json/cucumberTestReport.json") +public class RunWebDriverCucumberTestsLocal { +} diff --git a/src/test/resources/allure.properties b/src/test/resources/allure.properties deleted file mode 100644 index 80b02dd..0000000 --- a/src/test/resources/allure.properties +++ /dev/null @@ -1 +0,0 @@ -allure.results.directory=target/allure-results diff --git a/src/test/resources/features/localtest/Local.feature b/src/test/resources/features/localtest/Local.feature index bf5edbf..ee12509 100644 --- a/src/test/resources/features/localtest/Local.feature +++ b/src/test/resources/features/localtest/Local.feature @@ -1,5 +1,5 @@ Feature: Verify Local test - Scenario: Navigate to Local App page + Scenario: BStack Local Test - Navigate to Local App page Given I am on the website 'http://bs-local.com:45454/' Then the page title should contain 'BrowserStack Local' diff --git a/src/test/resources/features/test/StackDemo.feature b/src/test/resources/features/test/StackDemo.feature index 9e3a2e5..f0df316 100644 --- a/src/test/resources/features/test/StackDemo.feature +++ b/src/test/resources/features/test/StackDemo.feature @@ -1,6 +1,6 @@ Feature: BrowserStack Demo - Scenario: Add product to cart + Scenario: BStack Sample Test - Add product to cart Given I am on the website 'https://www.bstackdemo.com' When I select a product and click on 'Add to cart' button Then the product should be added to cart diff --git a/src/test/resources/testng.xml b/src/test/resources/testng.xml deleted file mode 100644 index 28c168b..0000000 --- a/src/test/resources/testng.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - From 3fdd52bb93b5236d713548a9329dbc87c02e6e83 Mon Sep 17 00:00:00 2001 From: Kamalpreet Kaur Date: Mon, 10 Jul 2023 17:36:41 +0530 Subject: [PATCH 2/3] add: sample for cucumber-junit5 --- .github/workflows/maven-workflow-run.yml | 91 ------------------- pom.xml | 21 ++--- ...va => RunWebDriverCucumberLocalTests.java} | 2 +- ...a => RunWebDriverCucumberSampleTests.java} | 2 +- 4 files changed, 9 insertions(+), 107 deletions(-) delete mode 100644 .github/workflows/maven-workflow-run.yml rename src/test/java/com/browserstack/{RunWebDriverCucumberTestsLocal.java => RunWebDriverCucumberLocalTests.java} (93%) rename src/test/java/com/browserstack/{RunWebDriverCucumberTests.java => RunWebDriverCucumberSampleTests.java} (93%) diff --git a/.github/workflows/maven-workflow-run.yml b/.github/workflows/maven-workflow-run.yml deleted file mode 100644 index e93bb3f..0000000 --- a/.github/workflows/maven-workflow-run.yml +++ /dev/null @@ -1,91 +0,0 @@ -# This job is to test different maven profiles in sdk branch again Pull Request raised -# This workflow targets Java with Maven execution - -name: Java SDK Test workflow for Maven on workflow_dispatch - -on: - workflow_dispatch: - inputs: - pull_request_number: - description: 'The pull request number 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: Cucumber 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: refs/pull/${{ github.event.inputs.pull_request_number }}/head - - name: Fetch Commit SHA - run: | - git log -1 --format='%H' - echo "commit_sha=$(git log -1 --format='%H')" >> $GITHUB_ENV - echo "commit_sha=$(git log -1 --format='%H')" >> $env:GITHUB_ENV - - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 - id: status-check-in-progress - env: - job_name: Cucumber Repo ${{ matrix.Java }} - ${{ matrix.os }} Sample - 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 - run: | - mvn compile - mvn test - - name: Run mvn profile sample-local-test - run: | - mvn compile - mvn test -P sample-local-test - - name: Run mvn profile sample-test - run: | - mvn compile - mvn test -P sample-test - - if: always() - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 - id: status-check-completed - env: - conclusion: ${{ job.status }} - job_name: Cucumber Repo ${{ matrix.Java }} - ${{ matrix.os }} Sample - 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/pom.xml b/pom.xml index c50ffcf..fd426bc 100644 --- a/pom.xml +++ b/pom.xml @@ -106,7 +106,7 @@ true - **/RunWebDriverCucumberTests.java + **/RunWebDriverCucumberSampleTests.java @@ -125,12 +125,11 @@ -javaagent:${com.browserstack:browserstack-java-sdk:jar} - + - **/RunWebDriverCucumberTests.java + **/RunWebDriverCucumberSampleTests.java @@ -149,17 +148,11 @@ -javaagent:${com.browserstack:browserstack-java-sdk:jar} - - + - **/RunWebDriverCucumberTestsLocal.java + **/RunWebDriverCucumberLocalTests.java diff --git a/src/test/java/com/browserstack/RunWebDriverCucumberTestsLocal.java b/src/test/java/com/browserstack/RunWebDriverCucumberLocalTests.java similarity index 93% rename from src/test/java/com/browserstack/RunWebDriverCucumberTestsLocal.java rename to src/test/java/com/browserstack/RunWebDriverCucumberLocalTests.java index 8a565c1..298655b 100644 --- a/src/test/java/com/browserstack/RunWebDriverCucumberTestsLocal.java +++ b/src/test/java/com/browserstack/RunWebDriverCucumberLocalTests.java @@ -13,5 +13,5 @@ @SelectClasspathResource("features/localtest") @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.browserstack.stepdefs") @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty, json:reports/tests/cucumber/json/cucumberTestReport.json") -public class RunWebDriverCucumberTestsLocal { +public class RunWebDriverCucumberLocalTests { } diff --git a/src/test/java/com/browserstack/RunWebDriverCucumberTests.java b/src/test/java/com/browserstack/RunWebDriverCucumberSampleTests.java similarity index 93% rename from src/test/java/com/browserstack/RunWebDriverCucumberTests.java rename to src/test/java/com/browserstack/RunWebDriverCucumberSampleTests.java index bb6bfb4..37cb875 100644 --- a/src/test/java/com/browserstack/RunWebDriverCucumberTests.java +++ b/src/test/java/com/browserstack/RunWebDriverCucumberSampleTests.java @@ -13,5 +13,5 @@ @SelectClasspathResource("features/test") @ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.browserstack.stepdefs") @ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty, json:reports/tests/cucumber/json/cucumberTestReport.json") -public class RunWebDriverCucumberTests { +public class RunWebDriverCucumberSampleTests { } From 605361b5ab95349ceadfb23a5cbb35b3fbff1668 Mon Sep 17 00:00:00 2001 From: Kamalpreet Kaur Date: Thu, 13 Jul 2023 15:42:40 +0530 Subject: [PATCH 3/3] update: get userName and accessKey from browserstack.yml to run it w/o SDK --- .../browserstack/stepdefs/StackDemoSteps.java | 37 +++++++++++++++++-- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/browserstack/stepdefs/StackDemoSteps.java b/src/test/java/com/browserstack/stepdefs/StackDemoSteps.java index 42f2f4c..e88801a 100644 --- a/src/test/java/com/browserstack/stepdefs/StackDemoSteps.java +++ b/src/test/java/com/browserstack/stepdefs/StackDemoSteps.java @@ -10,10 +10,14 @@ import org.openqa.selenium.MutableCapabilities; import org.openqa.selenium.WebDriver; import org.openqa.selenium.remote.RemoteWebDriver; +import org.yaml.snakeyaml.Yaml; import java.net.MalformedURLException; import java.net.URL; -import java.util.HashMap; +import java.io.File; +import java.io.InputStream; +import java.nio.file.Files; +import java.util.*; import org.testng.Assert; @@ -21,14 +25,25 @@ public class StackDemoSteps { private WebDriver driver; private HomePage homePage; + public static String userName, accessKey; + public static Map browserStackYamlMap; + public static final String USER_DIR = "user.dir"; + + public StackDemoSteps() { + File file = new File(getUserDir() + "/browserstack.yml"); + this.browserStackYamlMap = convertYamlFileToMap(file, new HashMap<>()); + } + @Before public void setUp() throws MalformedURLException { MutableCapabilities capabilities = new MutableCapabilities(); HashMap bstackOptions = new HashMap<>(); - bstackOptions.putIfAbsent("source", "cucumber-java:sample-master:v1.2"); + userName = System.getenv("BROWSERSTACK_USERNAME") != null ? System.getenv("BROWSERSTACK_USERNAME") : (String) browserStackYamlMap.get("userName"); + accessKey = System.getenv("BROWSERSTACK_ACCESS_KEY") != null ? System.getenv("BROWSERSTACK_ACCESS_KEY") : (String) browserStackYamlMap.get("accessKey"); + bstackOptions.putIfAbsent("source", "cucumber-java:sample-cucumber-junit5:v1.0"); capabilities.setCapability("bstack:options", bstackOptions); driver = new RemoteWebDriver( - new URL("https://hub.browserstack.com/wd/hub"), capabilities); + new URL(String.format("https://%s:%s@hub.browserstack.com/wd/hub", userName , accessKey)), capabilities); homePage = new HomePage(driver); } @@ -61,4 +76,20 @@ public void teardown(Scenario scenario) throws Exception { Thread.sleep(2000); driver.quit(); } + + private String getUserDir() { + return System.getProperty(USER_DIR); + } + + private Map convertYamlFileToMap(File yamlFile, Map map) { + try { + InputStream inputStream = Files.newInputStream(yamlFile.toPath()); + Yaml yaml = new Yaml(); + Map config = yaml.load(inputStream); + map.putAll(config); + } catch (Exception e) { + throw new RuntimeException(String.format("Malformed browserstack.yml file - %s.", e)); + } + return map; + } }