From a0fa6667b3625547e24a6a0a26557ca1a8c752fe Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Wed, 16 Aug 2023 15:29:55 +0530 Subject: [PATCH 01/28] added java sdk --- browserstack.yml | 75 ++++++++++++++++++++++++++++++++++++++++++++++++ pom.xml | 28 +++++++++++++----- 2 files changed, 96 insertions(+), 7 deletions(-) create mode 100644 browserstack.yml diff --git a/browserstack.yml b/browserstack.yml new file mode 100644 index 0000000..577087d --- /dev/null +++ b/browserstack.yml @@ -0,0 +1,75 @@ +# ============================= +# 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 +# ====================== +# The following capabilities are used to set up reporting on BrowserStack: +# Set 'projectName' to the name of your project. Example, Marketing Website +projectName: BrowserStack Sample +# Set `buildName` as the name of the job / testsuite being run +buildName: browserstack build +# `buildIdentifier` is a unique id to differentiate every execution that gets appended to +# buildName. Choose your buildIdentifier format from the available expressions: +# ${BUILD_NUMBER} (Default): Generates an incremental counter with every execution +# ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30 +# Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests +buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression} + +# ======================================= +# Platforms (Browsers / Devices to test) +# ======================================= +# Platforms object contains all the browser / device combinations you want to test on. +# Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate) +platforms: + - os: OS X + osVersion: Big Sur + browserName: Chrome + browserVersion: latest + - os: Windows + osVersion: 10 + browserName: Edge + browserVersion: latest + - deviceName: Samsung Galaxy S22 Ultra + browserName: chrome # Try 'samsung' for Samsung browser + osVersion: 12.0 + +# ======================= +# Parallels per Platform +# ======================= +# The number of parallel threads to be used for each platform set. +# BrowserStack's SDK runner will select the best strategy based on the configured value +# +# Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack +# +# Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack +parallelsPerPlatform: 1 + +source: java:intellij:v1.1.2 +staticWebDriver: true +# ========================================== +# BrowserStack Local +# (For localhost, staging/private websites) +# ========================================== +# Set browserStackLocal to true if your website under test is not accessible publicly over the internet +# Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction +browserstackLocal: false # (Default false) + +# Options to be passed to BrowserStack local in-case of advanced configurations +# browserStackLocalOptions: + # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. + # forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. + # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections + +# =================== +# Debugging features +# =================== +debug: false # # Set to true if you need screenshots for every selenium command ran +networkLogs: false # Set to true to enable HAR logs capturing +consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors) +# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors) diff --git a/pom.xml b/pom.xml index edddd83..30b7fec 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,4 @@ - - + 4.0.0 org.BrowserStack @@ -13,10 +10,9 @@ UTF-8 1.8 1.8 + 3.0.0-M5 7.4.0 3.0.0-M5 - - https://bstackdemo.com/ @@ -79,6 +75,12 @@ okhttp 5.0.0-alpha.10 + + com.browserstack + browserstack-java-sdk + LATEST + compile + @@ -90,13 +92,25 @@ ${suiteXmlFile} - + -javaagent:"${com.browserstack:browserstack-java-sdk:jar}" ${browser-type} ${Application_url} + + maven-dependency-plugin + 3.3.0 + + + getClasspathFilenames + + properties + + + + From 3e1be76348e3768eff48c683268b6e23c1505199 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Fri, 18 Aug 2023 19:57:19 +0530 Subject: [PATCH 02/28] refactor the xml --- .../Run_Local_Parallel/local.parallel.json | 48 ------------------- .../localParallel.testng.xml | 32 ------------- .../conf/Run_Local_Test/local.conf.json | 26 ---------- .../conf/Run_Local_Test/local.testng.xml | 14 ------ .../conf/Run_Parallel_Test/parallel.conf.json | 22 --------- .../Run_Parallel_Test/parallel.testng.xml | 18 ------- 6 files changed, 160 deletions(-) delete mode 100644 src/test/resources/browserstack/conf/Run_Local_Parallel/local.parallel.json delete mode 100644 src/test/resources/browserstack/conf/Run_Local_Parallel/localParallel.testng.xml delete mode 100644 src/test/resources/browserstack/conf/Run_Local_Test/local.conf.json delete mode 100644 src/test/resources/browserstack/conf/Run_Local_Test/local.testng.xml diff --git a/src/test/resources/browserstack/conf/Run_Local_Parallel/local.parallel.json b/src/test/resources/browserstack/conf/Run_Local_Parallel/local.parallel.json deleted file mode 100644 index 801495b..0000000 --- a/src/test/resources/browserstack/conf/Run_Local_Parallel/local.parallel.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "server": "hub-cloud.browserstack.com", - "user": "", - "key": "", - - "capabilities": { - "projectName": "Local BDD", - "buildName": "BDD-Local-Parallel-7", - "sessionName": "BS Suite", - "local": "true", - "debug": "true", - "networkLogs": "true", - "consoleLogs": "errors" - }, - - "environments": { - "env1": { - "browser": "Safari", - "browser_version": "15.3", - "envOptions": { - "os": "OS X", - "osVersion": "Monterey" - } - }, - "env2":{ - "browser": "Edge", - "browser_version": "latest", - "envOptions": { - "os": "Windows", - "osVersion": "11" - } - },"env3":{ - "envOptions": { - "osVersion": "15", - "deviceName": "iPhone 13 Pro Max", - "realMobile": "true" - } - }, - "env4":{ - "envOptions": { - "osVersion": "12.0", - "browserName": "samsung", - "deviceName": "Samsung Galaxy S22 Ultra", - "realMobile": "true" - } - } - } -} \ No newline at end of file diff --git a/src/test/resources/browserstack/conf/Run_Local_Parallel/localParallel.testng.xml b/src/test/resources/browserstack/conf/Run_Local_Parallel/localParallel.testng.xml deleted file mode 100644 index fcb49a1..0000000 --- a/src/test/resources/browserstack/conf/Run_Local_Parallel/localParallel.testng.xml +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/browserstack/conf/Run_Local_Test/local.conf.json b/src/test/resources/browserstack/conf/Run_Local_Test/local.conf.json deleted file mode 100644 index 34f464a..0000000 --- a/src/test/resources/browserstack/conf/Run_Local_Test/local.conf.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "server": "hub-cloud.browserstack.com", - "user": "", - "key": "", - - "capabilities": { - "projectName": "Local BDD", - "buildName": "Local_BS_BDD_2", - "sessionName": "Local_Test", - "debug": "true", - "networkLogs": "true", - "local": true , - "consoleLogs":"errors" - }, - - "environments": { - "env": { - "browserName": "Chrome", - "browserVersion": "latest", - "envOptions": { - "os": "Windows", - "osVersion": "11" - } - } - } -} \ No newline at end of file diff --git a/src/test/resources/browserstack/conf/Run_Local_Test/local.testng.xml b/src/test/resources/browserstack/conf/Run_Local_Test/local.testng.xml deleted file mode 100644 index 4d85002..0000000 --- a/src/test/resources/browserstack/conf/Run_Local_Test/local.testng.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json index a1fc52e..0fdf3d3 100644 --- a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json +++ b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json @@ -21,28 +21,6 @@ "os": "Windows", "osVersion": "11" } - }, - "env2":{ - "browser": "Safari", - "browser_version": "15.3", - "envOptions": { - "os": "OS X", - "osVersion": "Monterey" - } - },"env3":{ - "envOptions": { - "osVersion": "15", - "deviceName": "iPhone 13 Pro Max", - "realMobile": "true" - } - }, - "env4":{ - "envOptions": { - "osVersion": "12.0", - "browserName": "chrome", - "deviceName": "Samsung Galaxy S22 Ultra", - "realMobile": "true" - } } } } \ No newline at end of file diff --git a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml index 2931e53..b21f994 100644 --- a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml +++ b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml @@ -11,22 +11,4 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file From e0a50e73f2c78a7ef5750b73e012d0ad22c60f3c Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Fri, 18 Aug 2023 20:02:25 +0530 Subject: [PATCH 03/28] Changes to config --- browserstack.yml | 12 ++++++--- pom.xml | 27 +++++-------------- src/test/java/Runner/CucumberTest.java | 3 ++- .../conf/Run_Parallel_Test/parallel.conf.json | 20 +++++++++----- .../Run_Parallel_Test/parallel.testng.xml | 2 +- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index 577087d..c954063 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -38,6 +38,8 @@ platforms: - deviceName: Samsung Galaxy S22 Ultra browserName: chrome # Try 'samsung' for Samsung browser osVersion: 12.0 + - deviceName: iPhone 13 Pro Max + osVersion: 15 # ======================= # Parallels per Platform @@ -49,8 +51,8 @@ platforms: # # Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack parallelsPerPlatform: 1 - -source: java:intellij:v1.1.2 +framework: cucumber-testng #junit,testng,java,cucumber-testng,serenity,cucumber-junit +source: cucumber-testng:intellij:v1.1.2 staticWebDriver: true # ========================================== # BrowserStack Local @@ -58,7 +60,7 @@ staticWebDriver: true # ========================================== # Set browserStackLocal to true if your website under test is not accessible publicly over the internet # Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction -browserstackLocal: false # (Default false) +browserstackLocal: true # (Default false) # Options to be passed to BrowserStack local in-case of advanced configurations # browserStackLocalOptions: @@ -73,3 +75,7 @@ debug: false # # Set to true if you need screenshots for every seleniu networkLogs: false # Set to true to enable HAR logs capturing consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors) # Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors) + +# Test Observability is an intelligent test reporting & debugging product. It collects data using the SDK. Read more about what data is collected at https://www.browserstack.com/docs/test-observability/references/terms-and-conditions +# Visit observability.browserstack.com to see your test reports and insights. To disable test observability, specify `testObservability: false` in the key below. +testObservability: true diff --git a/pom.xml b/pom.xml index 30b7fec..91c9cbe 100644 --- a/pom.xml +++ b/pom.xml @@ -76,11 +76,11 @@ 5.0.0-alpha.10 - com.browserstack - browserstack-java-sdk - LATEST - compile - + com.browserstack + browserstack-java-sdk + LATEST + compile + @@ -129,27 +129,12 @@ src/test/resources/browserstack/conf/Run_Single_Test/single.testng.xml - - suite-cross-bs - - remote - src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml - - local-bs remote http://localhost:3000/ - src/test/resources/browserstack/conf/Run_Local_Test/local.testng.xml - - - - local-cross-bs - - remote - http://localhost:3000/ - src/test/resources/browserstack/conf/Run_Local_Parallel/localParallel.testng.xml + src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml diff --git a/src/test/java/Runner/CucumberTest.java b/src/test/java/Runner/CucumberTest.java index fa7602b..2c56452 100644 --- a/src/test/java/Runner/CucumberTest.java +++ b/src/test/java/Runner/CucumberTest.java @@ -120,7 +120,8 @@ public Object[][] scenarios(){ @AfterClass(alwaysRun = true) public void tearDownClass() { - testNGCucumberRunner.finish(); + //testNGCucumberRunner.finish(); //Conflict with the SDK Runner.CucumberTest.tearDownClass + // NoSuchMethod org.yaml.snakeyaml.constructor.Constructor. } @AfterSuite public void shutLocal() throws Exception { diff --git a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json index 0fdf3d3..9f3c6f9 100644 --- a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json +++ b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json @@ -15,12 +15,20 @@ "environments": { "env1": { - "browser": "Edge", - "browser_version": "latest", - "envOptions": { - "os": "Windows", - "osVersion": "11" - } + "browser": "Edge", + "browser_version": "latest", + "envOptions": { + "os": "Windows", + "osVersion": "11" + } + }, + "env2":{ + "browser": "Safari", + "browser_version": "15.3", + "envOptions": { + "os": "OS X", + "osVersion": "Monterey" + } } } } \ No newline at end of file diff --git a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml index b21f994..28058f2 100644 --- a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml +++ b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.testng.xml @@ -1,6 +1,6 @@ - + From 679d751c67fc29dfb286fcd62aed42ba9286934a Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Mon, 21 Aug 2023 12:30:18 +0530 Subject: [PATCH 04/28] Update README.md --- README.md | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 6d84572..084f399 100644 --- a/README.md +++ b/README.md @@ -67,18 +67,16 @@ This repository contains the following Cucumber Scenario tests: - [BrowserStack](#browserstack) --- -## Configuring the maximum parallel test threads for this repository +## Configuring the maximum parallel test threads for this repository[SDK] -For all the parallel run configuration profiles, tests will run with max parallels in your BrowserStack account, or you can configure the parallel test threads from the terminal +For all the parallel run configuration profiles, tests will run with max parallels in your BrowserStack account, or you can configure the parallel test threads from the browserstack.yml file - "-DthreadCount=xx" + parallelsPerPlatform |BrowserStack| onPrem | |--|--| | browserstack/conf/Run_Single_Test/single.testng.xml|testng.xml -browserstack/conf/Run_Parallel_Test/parallel.testng.xml | | -|browserstack/conf/Run_Local_Test/local.testng.xml| -|browserstack/conf/Run_Parallel_Test/parallel.testng.xml +browserstack/conf/Run_Parallel_Test/parallel.testng.xml | @@ -142,11 +140,8 @@ This infrastructure points to running the tests on your own machine using any br set BROWSERSTACK_ACCESS_KEY= ``` - Alternatively, you can also hardcode username and access_key objects in the respective json files: - - [single.conf.json](src/test/resources/browserstack/conf/Run_Single_Test/single.conf.json) file - - [parallel.conf.json](src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json) file - - [local.conf.json](src/test/resources/browserstack/conf/Run_Local_Test/local.conf.json) file - - [local.parallel.json](src/test/resources/browserstack/conf/Run_Local_Parallel/local.parallel.json) file + Alternatively, you can also hardcode username and access_key objects in the respective file: + - [browserstack.yml](browserstack.yml) file Note: @@ -158,7 +153,7 @@ Note: ### Run a specific test/entire test suite in parallel on a single BrowserStack browser -In this section, we will run the tests in parallel on a single browser on Browserstack. Refer to [single.conf.json](src/test/resources/browserstack/conf/Run_Single_Test/single.conf.json) file to change test capabilities for this configuration. +In this section, we will run the tests in parallel on a single browser on Browserstack. Refer to [browserstack.yml](browserstack.yml) file to change test capabilities for this configuration. - How to run the test? @@ -178,13 +173,13 @@ In this section, we will run the tests in parallel on a single browser on Browse - Note: By default, this execution would run maximum test threads based on the parallel quota on your BrowserStack Account. Thread count can be configured as below based on your requirements. ```sh - mvn test -P scenario-bs "-Dcucumber.filter.tags=@regresssion" "-DthreadCount=3" + mvn test -P scenario-bs "-Dcucumber.filter.tags=@regresssion" ``` ### Run the entire test suite in parallel on multiple BrowserStack browsers -In this section, we will run the tests in parallel on multiple browsers on Browserstack. Refer to the [parallel.conf.json](src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json) file to change test capabilities for this configuration. +In this section, we will run the tests in parallel on multiple browsers on Browserstack. Refer to the [browserstack.yml](browserstack.yml) file to change test capabilities for this configuration. - How to run the test? @@ -192,7 +187,7 @@ In this section, we will run the tests in parallel on multiple browsers on Brows Maven: ```sh - mvn test -P suite-cross-bs + mvn test -P scenario-bs ``` You can mention any scenario from the feature files using the `-Dcucumber.filter.tags`, tags defined at Feature level Eg. `@users` will run all the scenarios in the [Users Feature](src/test/resources/Features/Users.feature) file in parallel. Likewise `@regression` will run all the scenarios from all the Feature files in parallel across multiple browsers/devices. @@ -206,7 +201,7 @@ In this section, we will run the tests in parallel on multiple browsers on Brows git clone https://github.com/browserstack/browserstack-demo-app ``` - Please follow the README.md on the BrowserStack demo application repository to install and start the dev server on localhost. -- In this section, we will run a single test case to test the BrowserStack Demo app hosted on your local machine i.e. localhost. Refer to the [local.conf.json](src/test/resources/browserstack/conf/Run_Local_Test/local.conf.json) file to change test capabilities for this configuration. +- In this section, we will run a single test case to test the BrowserStack Demo app hosted on your local machine i.e. localhost. Refer to the [browserstack.yml](browserstack.yml) file to change test capabilities for this configuration. - Note: You may need to provide additional BrowserStackLocal arguments to successfully connect your localhost environment with BrowserStack infrastructure. (e.g if you are behind firewalls, proxy or VPN). - Further details for successfully creating a BrowserStackLocal connection can be found here: @@ -234,7 +229,7 @@ You can mention any scenario from the feature files using the `-Dcucumber.filter ### [Web application hosted on internal environment] Run the entire test suite in parallel on multiple BrowserStack browser using BrowserStackLocal -In this section, we will run the test cases to test the internally hosted website in parallel on multiple browsers/devices on Browserstack. Refer to the [local.parallel.json](src/test/resources/browserstack/conf/Run_Local_Parallel/local.parallel.json) file to change test capabilities for this configuration. +In this section, we will run the test cases to test the internally hosted website in parallel on multiple browsers/devices on Browserstack. Refer to the [browserstack.yml](browserstack.yml) file to change test capabilities for this configuration. - How to run the test? @@ -242,7 +237,7 @@ In this section, we will run the test cases to test the internally hosted websit Maven: ```sh - mvn test -P local-cross-bs + mvn test -P local-bs ``` - Output @@ -251,7 +246,7 @@ In this section, we will run the test cases to test the internally hosted websit - Note: By default, this execution would run maximum test threads based on the parallel quota on your BrowserStack Account. Thread count can be configured as below based on your requirements. ```sh - mvn test -P local-cross-bs "-Dcucumber.filter.tags=@e2e" "-DthreadCount=3" + mvn test -P local-bs "-Dcucumber.filter.tags=@e2e" ``` From 2e9bb91c22bfb25b8702a5d324a773c1f61a1a58 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Thu, 5 Oct 2023 14:37:14 +0530 Subject: [PATCH 05/28] e Please enter the commit message for your changes. Lines starting :wq Removed listeners and js executors duplicates :wq --- browserstack.yml | 4 ++-- src/test/java/Runner/CucumberTest.java | 4 ++-- src/test/java/StepDefinitions/ApplicationHooks.java | 8 -------- .../java/com/qa/util/BrowserstackTestStatusListener.java | 2 +- 4 files changed, 5 insertions(+), 13 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index c954063..8c8cd84 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -63,9 +63,9 @@ staticWebDriver: true browserstackLocal: true # (Default false) # Options to be passed to BrowserStack local in-case of advanced configurations -# browserStackLocalOptions: +browserStackLocalOptions: # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. - # forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. + forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections # =================== diff --git a/src/test/java/Runner/CucumberTest.java b/src/test/java/Runner/CucumberTest.java index 2c56452..84f5e57 100644 --- a/src/test/java/Runner/CucumberTest.java +++ b/src/test/java/Runner/CucumberTest.java @@ -109,8 +109,8 @@ public static synchronized WebDriver getDriver(){ @Test(dataProvider = "scenarios") public void scenario(PickleWrapper pickleWrapper, FeatureWrapper featureWrapper) throws MalformedURLException { JavascriptExecutor jse = (JavascriptExecutor)getDriver(); - if(System.getProperty("browser-type").equalsIgnoreCase("remote")) - jse.executeScript("browserstack_executor: {\"action\": \"setSessionName\", \"arguments\": {\"name\":\" "+ pickleWrapper.getPickle().getName() +" \" }}"); + //if(System.getProperty("browser-type").equalsIgnoreCase("remote")) + //jse.executeScript("browserstack_executor: {\"action\": \"setSessionName\", \"arguments\": {\"name\":\" "+ pickleWrapper.getPickle().getName() +" \" }}"); testNGCucumberRunner.runScenario(pickleWrapper.getPickle()); } @DataProvider(parallel = true) diff --git a/src/test/java/StepDefinitions/ApplicationHooks.java b/src/test/java/StepDefinitions/ApplicationHooks.java index 153b056..99f5eb1 100644 --- a/src/test/java/StepDefinitions/ApplicationHooks.java +++ b/src/test/java/StepDefinitions/ApplicationHooks.java @@ -17,12 +17,4 @@ public void screenshot(Scenario sc){ sc.attach(sourcePath,"image/png",screenshotName); } - private void markTestStatus(String status, String reason, WebDriver driver) { - try { - JavascriptExecutor jse = (JavascriptExecutor) driver; - jse.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); - } catch (Exception e) { - System.out.print("Error executing javascript" + e); - } - } } diff --git a/src/test/java/com/qa/util/BrowserstackTestStatusListener.java b/src/test/java/com/qa/util/BrowserstackTestStatusListener.java index 77ed674..79b324a 100644 --- a/src/test/java/com/qa/util/BrowserstackTestStatusListener.java +++ b/src/test/java/com/qa/util/BrowserstackTestStatusListener.java @@ -11,7 +11,7 @@ public class BrowserstackTestStatusListener implements ITestListener { private void markTestStatus(String status, String reason, WebDriver driver) { try { JavascriptExecutor jse = (JavascriptExecutor) driver; - jse.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); + //jse.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); } catch (Exception e) { System.out.print("Error executing javascript" + e); } From f9915f03cedcde23eda446a2e8dbfabfe3c3c8dc Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Mon, 29 Jul 2024 13:29:03 +0530 Subject: [PATCH 06/28] a11y o11y --- browserstack.yml | 30 +++++++++++++++++++------- pom.xml | 11 +++++----- src/test/java/Runner/CucumberTest.java | 5 +++-- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index 8c8cd84..e532ead 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -11,7 +11,7 @@ accessKey: YOUR_ACCESS_KEY # ====================== # The following capabilities are used to set up reporting on BrowserStack: # Set 'projectName' to the name of your project. Example, Marketing Website -projectName: BrowserStack Sample +projectName: check QG on #BrowserStack Sample # Automate - Map SDK # Set `buildName` as the name of the job / testsuite being run buildName: browserstack build # `buildIdentifier` is a unique id to differentiate every execution that gets appended to @@ -20,7 +20,8 @@ buildName: browserstack build # ${DATE_TIME}: Generates a Timestamp with every execution. Eg. 05-Nov-19:30 # Read more about buildIdentifiers here -> https://www.browserstack.com/docs/automate/selenium/organize-tests buildIdentifier: '#${BUILD_NUMBER}' # Supports strings along with either/both ${expression} - +buildTag: "regresson" +selfHeal: true # ======================================= # Platforms (Browsers / Devices to test) # ======================================= @@ -31,16 +32,19 @@ platforms: osVersion: Big Sur browserName: Chrome browserVersion: latest + accessibility: true - os: Windows osVersion: 10 browserName: Edge browserVersion: latest + accessibility: false - deviceName: Samsung Galaxy S22 Ultra browserName: chrome # Try 'samsung' for Samsung browser osVersion: 12.0 + accessibility: false - deviceName: iPhone 13 Pro Max osVersion: 15 - + accessibility: false # ======================= # Parallels per Platform # ======================= @@ -50,32 +54,42 @@ platforms: # Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack # # Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack -parallelsPerPlatform: 1 +parallelsPerPlatform: 3 framework: cucumber-testng #junit,testng,java,cucumber-testng,serenity,cucumber-junit source: cucumber-testng:intellij:v1.1.2 staticWebDriver: true +browserstackAutomation: true # ========================================== # BrowserStack Local # (For localhost, staging/private websites) # ========================================== # Set browserStackLocal to true if your website under test is not accessible publicly over the internet # Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction -browserstackLocal: true # (Default false) +browserstackLocal: false # (Default false) # Options to be passed to BrowserStack local in-case of advanced configurations browserStackLocalOptions: # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. - forceLocal: true # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. + forceLocal: false # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections # =================== # Debugging features # =================== -debug: false # # Set to true if you need screenshots for every selenium command ran -networkLogs: false # Set to true to enable HAR logs capturing +debug: true # # Set to true if you need screenshots for every selenium command ran +networkLogs: true # Set to true to enable HAR logs capturing consoleLogs: errors # Remote browser's console debug levels to be printed (Default: errors) # Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors) # Test Observability is an intelligent test reporting & debugging product. It collects data using the SDK. Read more about what data is collected at https://www.browserstack.com/docs/test-observability/references/terms-and-conditions # Visit observability.browserstack.com to see your test reports and insights. To disable test observability, specify `testObservability: false` in the key below. testObservability: true + +accessibilityOptions: + wcagVersion: wcag21aaa # Default: wcag21aa + includeIssueType: + bestPractice: true # Default: false + needsReview: true # Default: true + experimental: true # Default: true + #includeTagsInTestingScope: [ '@users' ] # Tags for test cases to include + #excludeTagsInTestingScope: [ 'old', 'deprecated' ] # Tags for test cases to exclude \ No newline at end of file diff --git a/pom.xml b/pom.xml index 91c9cbe..70dc3b2 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ 1.0-SNAPSHOT - 7.2.2 + 7.3.0 UTF-8 1.8 1.8 @@ -43,17 +43,18 @@ org.seleniumhq.selenium selenium-java - 4.1.0 + 4.22.0 io.github.bonigarcia webdrivermanager - 5.0.3 + LATEST + test commons-io commons-io - 2.11.0 + LATEST tech.grasshopper @@ -118,7 +119,7 @@ scenario-onprem - chrome + firefox testng.xml diff --git a/src/test/java/Runner/CucumberTest.java b/src/test/java/Runner/CucumberTest.java index 84f5e57..5f0ae7e 100644 --- a/src/test/java/Runner/CucumberTest.java +++ b/src/test/java/Runner/CucumberTest.java @@ -28,8 +28,9 @@ import java.util.Map; @CucumberOptions(features = "src/test/resources/Features", glue = {"StepDefinitions"}, - plugin = {"pretty", - "com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:"}, + plugin = {"pretty","json:target/cucumber-reports/Cucumber.json" + //"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:" + }, monochrome = true ) @Listeners(BrowserstackTestStatusListener.class) From 2ef6a9e4c1217f1927a70074f03ebbd685584d8a Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Tue, 10 Sep 2024 12:31:25 +0530 Subject: [PATCH 07/28] lighthouse and percy --- browserstack.yml | 17 ++++++++++------- src/test/java/StepDefinitions/E2ESteps.java | 5 +++++ .../qa/util/BrowserstackTestStatusListener.java | 2 +- src/test/resources/Features/E2E.feature | 2 +- src/test/resources/Features/Users.feature | 6 +++--- .../conf/Run_Parallel_Test/parallel.conf.json | 1 - .../conf/Run_Single_Test/single.conf.json | 1 - 7 files changed, 20 insertions(+), 14 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index e532ead..7c6bc90 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -11,7 +11,7 @@ accessKey: YOUR_ACCESS_KEY # ====================== # The following capabilities are used to set up reporting on BrowserStack: # Set 'projectName' to the name of your project. Example, Marketing Website -projectName: check QG on #BrowserStack Sample # Automate - Map SDK +projectName: BrowserStack Sample # Automate - Map SDK # Set `buildName` as the name of the job / testsuite being run buildName: browserstack build # `buildIdentifier` is a unique id to differentiate every execution that gets appended to @@ -54,7 +54,7 @@ platforms: # Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack # # Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack -parallelsPerPlatform: 3 +parallelsPerPlatform: 2 framework: cucumber-testng #junit,testng,java,cucumber-testng,serenity,cucumber-junit source: cucumber-testng:intellij:v1.1.2 staticWebDriver: true @@ -70,9 +70,9 @@ browserstackLocal: false # (Default false) # Options to be passed to BrowserStack local in-case of advanced configurations browserStackLocalOptions: # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. - forceLocal: false # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. + # forceLocal: false # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections - + # =================== # Debugging features # =================== @@ -84,12 +84,15 @@ consoleLogs: errors # Remote browser's console debug levels to be print # Test Observability is an intelligent test reporting & debugging product. It collects data using the SDK. Read more about what data is collected at https://www.browserstack.com/docs/test-observability/references/terms-and-conditions # Visit observability.browserstack.com to see your test reports and insights. To disable test observability, specify `testObservability: false` in the key below. testObservability: true - accessibilityOptions: wcagVersion: wcag21aaa # Default: wcag21aa includeIssueType: bestPractice: true # Default: false needsReview: true # Default: true experimental: true # Default: true - #includeTagsInTestingScope: [ '@users' ] # Tags for test cases to include - #excludeTagsInTestingScope: [ 'old', 'deprecated' ] # Tags for test cases to exclude \ No newline at end of file + #includeTagsInTestingScope: [ '@users' ] # Tags for test cases to include + #excludeTagsInTestingScope: [ 'old', 'deprecated' ] # Tags for test cases to exclude + +performance: assert +percy: true +percyCaptureMode: auto \ No newline at end of file diff --git a/src/test/java/StepDefinitions/E2ESteps.java b/src/test/java/StepDefinitions/E2ESteps.java index 6295f58..15515a0 100644 --- a/src/test/java/StepDefinitions/E2ESteps.java +++ b/src/test/java/StepDefinitions/E2ESteps.java @@ -48,6 +48,11 @@ public void user_is_on_home_page() { hooks.driver.get(System.getProperties().getProperty("Application_url").replaceAll("localhost","bs-local.com")); else hooks.driver.get(System.getProperties().getProperty("Application_url")); + + jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\""+hooks.driver.getCurrentUrl()+"\",\"executorOutput\":\"json\"}}"); + + jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\""+hooks.driver.getCurrentUrl()+"\",\"assertResult\":{\"categories\":{\"performance\":40,\"best-practices\":50},\"metrics\":{\"first-contentful-paint\":{\"moreThan\":50,\"metricUnit\":\"score\"},\"largest-contentful-paint\":{\"lessThan\":4000,\"metricUnit\":\"numeric\"},\"total-blocking-time\":{\"lessThan\":600,\"metricUnit\":\"numeric\"},\"cumulative-layout-shift\":{\"moreThan\":50,\"metricUnit\":\"score\"}}}}}"); + } @When("User clicks on sign in link") public void user_clicks_on_sign_in_link() { diff --git a/src/test/java/com/qa/util/BrowserstackTestStatusListener.java b/src/test/java/com/qa/util/BrowserstackTestStatusListener.java index 79b324a..77ed674 100644 --- a/src/test/java/com/qa/util/BrowserstackTestStatusListener.java +++ b/src/test/java/com/qa/util/BrowserstackTestStatusListener.java @@ -11,7 +11,7 @@ public class BrowserstackTestStatusListener implements ITestListener { private void markTestStatus(String status, String reason, WebDriver driver) { try { JavascriptExecutor jse = (JavascriptExecutor) driver; - //jse.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); + jse.executeScript("browserstack_executor: {\"action\": \"setSessionStatus\", \"arguments\": {\"status\": \"" + status + "\", \"reason\": \"" + reason + "\"}}"); } catch (Exception e) { System.out.print("Error executing javascript" + e); } diff --git a/src/test/resources/Features/E2E.feature b/src/test/resources/Features/E2E.feature index 52d509c..f18735d 100644 --- a/src/test/resources/Features/E2E.feature +++ b/src/test/resources/Features/E2E.feature @@ -3,7 +3,7 @@ #Description: Demonstrate Cucumber Java framework with BS Automate product @e2e @regression Feature: E2E Flow - Scenario Outline: Signed in User makes a Purchase for a product with Price and Vendor filters + Scenario Outline: TC-1480 Signed in User makes a Purchase for a product with Price and Vendor filters Given User is on home page When User clicks on sign in link And User enters and and clicks on sign in diff --git a/src/test/resources/Features/Users.feature b/src/test/resources/Features/Users.feature index dc3aec0..7bf8cbe 100644 --- a/src/test/resources/Features/Users.feature +++ b/src/test/resources/Features/Users.feature @@ -8,7 +8,7 @@ Feature: Different Users use cases in BStackDemo When User clicks on sign in link @noimage @fail - Scenario Outline: Login as User with no image loaded + Scenario Outline: TC-1665 Login as User with no image loaded When User enters and and clicks on sign in And is signed in to the App Then Product images are not loaded for the @@ -17,7 +17,7 @@ Feature: Different Users use cases in BStackDemo |"image_not_loading_user"|"testingisfun99"| @orders - Scenario Outline: Login as existing user to verify orders + Scenario Outline: TC-1666 Login as existing user to verify orders When User enters and and clicks on sign in And is signed in to the App And User clicks on Orders @@ -27,7 +27,7 @@ Feature: Different Users use cases in BStackDemo |"existing_orders_user"|"testingisfun99"| @locked - Scenario Outline: Login as a locked User + Scenario Outline: TC-1667 Login as a locked User When User enters and and clicks on sign in Then gets Your account has been locked. Examples: diff --git a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json index 9f3c6f9..ae18182 100644 --- a/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json +++ b/src/test/resources/browserstack/conf/Run_Parallel_Test/parallel.conf.json @@ -9,7 +9,6 @@ "sessionName": "BS Suite", "debug": "true", "networkLogs": "true", - "seleniumVersion": "4.0.0", "consoleLogs": "errors" }, diff --git a/src/test/resources/browserstack/conf/Run_Single_Test/single.conf.json b/src/test/resources/browserstack/conf/Run_Single_Test/single.conf.json index 21be2da..590f319 100644 --- a/src/test/resources/browserstack/conf/Run_Single_Test/single.conf.json +++ b/src/test/resources/browserstack/conf/Run_Single_Test/single.conf.json @@ -9,7 +9,6 @@ "sessionName": "BS Suite", "debug": "true", "networkLogs": "true", - "seleniumVersion": "4.0.0", "consoleLogs": "errors" }, From 46552c859a0b1e73c5b4145eb79164650ae84d7c Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Mon, 16 Sep 2024 13:27:28 +0530 Subject: [PATCH 08/28] lighthouse and percy --- browserstack.yml | 14 ++++++++------ pom.xml | 1 - src/test/java/Runner/CucumberTest.java | 11 +++++++++-- src/test/java/StepDefinitions/E2ESteps.java | 7 ++++--- .../qa/util/BrowserstackTestStatusListener.java | 4 ++-- src/test/resources/Features/E2E.feature | 2 +- 6 files changed, 24 insertions(+), 15 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index 7c6bc90..5ee46a1 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -38,12 +38,13 @@ platforms: browserName: Edge browserVersion: latest accessibility: false - - deviceName: Samsung Galaxy S22 Ultra + - deviceName: Samsung Galaxy S2* browserName: chrome # Try 'samsung' for Samsung browser - osVersion: 12.0 + osVersion: [12131415] accessibility: false - - deviceName: iPhone 13 Pro Max - osVersion: 15 + - deviceName: iPhone 1* + browserName: safari + osVersion: [15161718] accessibility: false # ======================= # Parallels per Platform @@ -68,7 +69,7 @@ browserstackAutomation: true browserstackLocal: false # (Default false) # Options to be passed to BrowserStack local in-case of advanced configurations -browserStackLocalOptions: +#browserStackLocalOptions: # localIdentifier: # (Default: null) Needed if you need to run multiple instances of local. # forceLocal: false # (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel. # Entire list of arguments available here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections @@ -95,4 +96,5 @@ accessibilityOptions: performance: assert percy: true -percyCaptureMode: auto \ No newline at end of file +percyCaptureMode: auto +#logLevel: debug \ No newline at end of file diff --git a/pom.xml b/pom.xml index 70dc3b2..8667b3e 100644 --- a/pom.xml +++ b/pom.xml @@ -80,7 +80,6 @@ com.browserstack browserstack-java-sdk LATEST - compile diff --git a/src/test/java/Runner/CucumberTest.java b/src/test/java/Runner/CucumberTest.java index 5f0ae7e..4efc161 100644 --- a/src/test/java/Runner/CucumberTest.java +++ b/src/test/java/Runner/CucumberTest.java @@ -31,7 +31,7 @@ plugin = {"pretty","json:target/cucumber-reports/Cucumber.json" //"com.aventstack.extentreports.cucumber.adapter.ExtentCucumberAdapter:" }, - monochrome = true + monochrome = true,publish = true ) @Listeners(BrowserstackTestStatusListener.class) public class CucumberTest { @@ -99,8 +99,15 @@ public void setUpHooks(String config_file, String environment) throws Exception new URL("https://" + username + ":" + accessKey + "@" + config.get("server") + "/wd/hub"), capabilities)); }else throw new AssertionError("Invalid input for browser"); - if(!capabilities.toString().contains("realMobile")) + Map deviceInfo = new HashMap<>(); + JavascriptExecutor jse = (JavascriptExecutor) getDriver(); + try{ + deviceInfo = (Map) jse.executeScript("mobile:deviceInfo"); + }catch(Exception e){ + } + if(deviceInfo.isEmpty()) getDriver().manage().window().maximize(); + } public static synchronized WebDriver getDriver(){ diff --git a/src/test/java/StepDefinitions/E2ESteps.java b/src/test/java/StepDefinitions/E2ESteps.java index 15515a0..55d379d 100644 --- a/src/test/java/StepDefinitions/E2ESteps.java +++ b/src/test/java/StepDefinitions/E2ESteps.java @@ -49,10 +49,11 @@ public void user_is_on_home_page() { else hooks.driver.get(System.getProperties().getProperty("Application_url")); - jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\""+hooks.driver.getCurrentUrl()+"\",\"executorOutput\":\"json\"}}"); - - jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\""+hooks.driver.getCurrentUrl()+"\",\"assertResult\":{\"categories\":{\"performance\":40,\"best-practices\":50},\"metrics\":{\"first-contentful-paint\":{\"moreThan\":50,\"metricUnit\":\"score\"},\"largest-contentful-paint\":{\"lessThan\":4000,\"metricUnit\":\"numeric\"},\"total-blocking-time\":{\"lessThan\":600,\"metricUnit\":\"numeric\"},\"cumulative-layout-shift\":{\"moreThan\":50,\"metricUnit\":\"score\"}}}}}"); + if(System.getenv("BROWSERSTACK_AUTOMATION").equalsIgnoreCase("true")) { + jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\"" + hooks.driver.getCurrentUrl() + "\",\"executorOutput\":\"json\"}}"); + jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\"" + hooks.driver.getCurrentUrl() + "\",\"assertResult\":{\"categories\":{\"performance\":40,\"best-practices\":50},\"metrics\":{\"first-contentful-paint\":{\"moreThan\":50,\"metricUnit\":\"score\"},\"largest-contentful-paint\":{\"lessThan\":4000,\"metricUnit\":\"numeric\"},\"total-blocking-time\":{\"lessThan\":600,\"metricUnit\":\"numeric\"},\"cumulative-layout-shift\":{\"moreThan\":50,\"metricUnit\":\"score\"}}}}}"); + } } @When("User clicks on sign in link") public void user_clicks_on_sign_in_link() { diff --git a/src/test/java/com/qa/util/BrowserstackTestStatusListener.java b/src/test/java/com/qa/util/BrowserstackTestStatusListener.java index 77ed674..194ac8b 100644 --- a/src/test/java/com/qa/util/BrowserstackTestStatusListener.java +++ b/src/test/java/com/qa/util/BrowserstackTestStatusListener.java @@ -21,7 +21,7 @@ private void markTestStatus(String status, String reason, WebDriver driver) { public void onTestSuccess(ITestResult result) { Object currentClass = result.getInstance(); WebDriver driver = ((CucumberTest) currentClass).getDriver(); - markTestStatus("passed", "", driver); + //markTestStatus("passed", "", driver); driver.quit(); } @@ -31,7 +31,7 @@ public void onTestFailure(ITestResult result) { WebDriver driver = ((CucumberTest) currentClass).getDriver(); String message = result.getThrowable().getMessage(); String reason = (message != null && message.length() > 254) ? message.substring(0, 254) : message; - markTestStatus("failed", reason.replaceAll("[^a-zA-Z0-9._-]", " "), driver); + //markTestStatus("failed", reason.replaceAll("[^a-zA-Z0-9._-]", " "), driver); driver.quit(); } diff --git a/src/test/resources/Features/E2E.feature b/src/test/resources/Features/E2E.feature index f18735d..f14fd22 100644 --- a/src/test/resources/Features/E2E.feature +++ b/src/test/resources/Features/E2E.feature @@ -3,7 +3,7 @@ #Description: Demonstrate Cucumber Java framework with BS Automate product @e2e @regression Feature: E2E Flow - Scenario Outline: TC-1480 Signed in User makes a Purchase for a product with Price and Vendor filters + Scenario Outline: TC-1856 Signed in User makes a Purchase for a product with Price and Vendor filters Given User is on home page When User clicks on sign in link And User enters and and clicks on sign in From c76995b811735947ae8d061708442952236aa4aa Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Thu, 10 Oct 2024 17:04:58 +0530 Subject: [PATCH 09/28] platform a11y --- browserstack.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index 5ee46a1..25bde8e 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -32,20 +32,16 @@ platforms: osVersion: Big Sur browserName: Chrome browserVersion: latest - accessibility: true - os: Windows osVersion: 10 browserName: Edge browserVersion: latest - accessibility: false - deviceName: Samsung Galaxy S2* browserName: chrome # Try 'samsung' for Samsung browser osVersion: [12131415] - accessibility: false - deviceName: iPhone 1* browserName: safari osVersion: [15161718] - accessibility: false # ======================= # Parallels per Platform # ======================= @@ -85,6 +81,7 @@ consoleLogs: errors # Remote browser's console debug levels to be print # Test Observability is an intelligent test reporting & debugging product. It collects data using the SDK. Read more about what data is collected at https://www.browserstack.com/docs/test-observability/references/terms-and-conditions # Visit observability.browserstack.com to see your test reports and insights. To disable test observability, specify `testObservability: false` in the key below. testObservability: true +accessibility: true accessibilityOptions: wcagVersion: wcag21aaa # Default: wcag21aa includeIssueType: From 41299d1933d0b904588a0e6515cd8448266ccb05 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Wed, 16 Oct 2024 14:24:52 +0530 Subject: [PATCH 10/28] yaml reader --- src/test/java/StepDefinitions/E2ESteps.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/test/java/StepDefinitions/E2ESteps.java b/src/test/java/StepDefinitions/E2ESteps.java index 55d379d..9a84208 100644 --- a/src/test/java/StepDefinitions/E2ESteps.java +++ b/src/test/java/StepDefinitions/E2ESteps.java @@ -12,7 +12,11 @@ import io.cucumber.java.en.When; import org.openqa.selenium.JavascriptExecutor; import org.testng.Assert; +import org.yaml.snakeyaml.Yaml; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; import java.util.HashMap; import java.util.Map; @@ -36,7 +40,7 @@ public void getScenario(Scenario scenario){ this.sc = scenario; } @Given("User is on home page") - public void user_is_on_home_page() { + public void user_is_on_home_page() throws FileNotFoundException { JavascriptExecutor jse = (JavascriptExecutor) hooks.driver; Map deviceInfo = new HashMap<>(); try{ @@ -48,8 +52,10 @@ public void user_is_on_home_page() { hooks.driver.get(System.getProperties().getProperty("Application_url").replaceAll("localhost","bs-local.com")); else hooks.driver.get(System.getProperties().getProperty("Application_url")); - - if(System.getenv("BROWSERSTACK_AUTOMATION").equalsIgnoreCase("true")) { + Yaml yaml = new Yaml(); + InputStream inputStream = new FileInputStream("browserstack.yml"); + HashMap yamlMap = yaml.load(inputStream); + if(yamlMap.get("browserstackAutomation").toString().equalsIgnoreCase("true")) { jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\"" + hooks.driver.getCurrentUrl() + "\",\"executorOutput\":\"json\"}}"); jse.executeScript("browserstack_executor: {\"action\":\"lighthouseAudit\",\"arguments\":{\"url\":\"" + hooks.driver.getCurrentUrl() + "\",\"assertResult\":{\"categories\":{\"performance\":40,\"best-practices\":50},\"metrics\":{\"first-contentful-paint\":{\"moreThan\":50,\"metricUnit\":\"score\"},\"largest-contentful-paint\":{\"lessThan\":4000,\"metricUnit\":\"numeric\"},\"total-blocking-time\":{\"lessThan\":600,\"metricUnit\":\"numeric\"},\"cumulative-layout-shift\":{\"moreThan\":50,\"metricUnit\":\"score\"}}}}}"); From c08023e756305f367c1ebfebc7386bab7b1ce252 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Fri, 24 Jan 2025 23:05:21 +0530 Subject: [PATCH 11/28] Update E2E.feature TC mapping --- src/test/resources/Features/E2E.feature | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/resources/Features/E2E.feature b/src/test/resources/Features/E2E.feature index f14fd22..90055d7 100644 --- a/src/test/resources/Features/E2E.feature +++ b/src/test/resources/Features/E2E.feature @@ -3,7 +3,7 @@ #Description: Demonstrate Cucumber Java framework with BS Automate product @e2e @regression Feature: E2E Flow - Scenario Outline: TC-1856 Signed in User makes a Purchase for a product with Price and Vendor filters + Scenario Outline: TC-3294 Signed in User makes a Purchase for a product with Price and Vendor filters Given User is on home page When User clicks on sign in link And User enters and and clicks on sign in @@ -16,4 +16,4 @@ Feature: E2E Flow Then User can see the order id for the product Examples: |username|password|first|last|address|state|postal| - |"demouser"|"testingisfun99"|"first"|"last"|"test"|"test state"|1234| \ No newline at end of file + |"demouser"|"testingisfun99"|"first"|"last"|"test"|"test state"|1234| From e238f7261cd01a7664e929a667f3896a14f4bd53 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 5 Feb 2025 18:51:41 +0530 Subject: [PATCH 12/28] Web AI Sef Heal --- browserstack.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index 25bde8e..7139724 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -31,11 +31,11 @@ platforms: - os: OS X osVersion: Big Sur browserName: Chrome - browserVersion: latest + browserVersion: 131.0 - os: Windows osVersion: 10 browserName: Edge - browserVersion: latest + browserVersion: 131.0 - deviceName: Samsung Galaxy S2* browserName: chrome # Try 'samsung' for Samsung browser osVersion: [12131415] @@ -94,4 +94,4 @@ accessibilityOptions: performance: assert percy: true percyCaptureMode: auto -#logLevel: debug \ No newline at end of file +#logLevel: debug From f4546da5dee7eada6f5b4c1bb641033f91bc6851 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Wed, 12 Mar 2025 16:49:42 +0530 Subject: [PATCH 13/28] jdk update --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8667b3e..c69281d 100644 --- a/pom.xml +++ b/pom.xml @@ -8,8 +8,8 @@ 7.3.0 UTF-8 - 1.8 - 1.8 + 11 + 11 3.0.0-M5 7.4.0 3.0.0-M5 From 6b46a183c58c7de14eaad354e99b79de019f54bf Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Wed, 28 May 2025 20:43:41 +0530 Subject: [PATCH 14/28] change in proj caps for a11y --- browserstack.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/browserstack.yml b/browserstack.yml index 25bde8e..585e259 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -11,7 +11,7 @@ accessKey: YOUR_ACCESS_KEY # ====================== # The following capabilities are used to set up reporting on BrowserStack: # Set 'projectName' to the name of your project. Example, Marketing Website -projectName: BrowserStack Sample # Automate - Map SDK +projectName: BrowserStack Cucumber TestNG # Automate - Map SDK # Set `buildName` as the name of the job / testsuite being run buildName: browserstack build # `buildIdentifier` is a unique id to differentiate every execution that gets appended to @@ -32,6 +32,7 @@ platforms: osVersion: Big Sur browserName: Chrome browserVersion: latest + accessibility: true - os: Windows osVersion: 10 browserName: Edge @@ -39,7 +40,7 @@ platforms: - deviceName: Samsung Galaxy S2* browserName: chrome # Try 'samsung' for Samsung browser osVersion: [12131415] - - deviceName: iPhone 1* + - deviceName: iPhone 1* browserName: safari osVersion: [15161718] # ======================= From 0a02c60e3604f4dc3e317c214d00d453c8161470 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 13:13:15 +0530 Subject: [PATCH 15/28] Create check-quality-gate.sh TRA Quality Gates --- check-quality-gate.sh | 75 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 check-quality-gate.sh diff --git a/check-quality-gate.sh b/check-quality-gate.sh new file mode 100644 index 0000000..ee3d94f --- /dev/null +++ b/check-quality-gate.sh @@ -0,0 +1,75 @@ +#!/bin/bash +# Update values here +project_name="BrowserStack Cucumber TestNG" # Replace with your project name +build_name="$BROWSERSTACK_BUILD_NAME" # Replace with your build name use $BROWSERSTACK_BUILD_NAME if you use the BrowserStack Jenkins Plugin + +# Read secrets from environment variables +username="$BROWSERSTACK_USERNAME" +access_key="$BROWSERSTACK_ACCESS_KEY" + +max_attempts=20 # Replace with your max retry attempt +build_tags="{Insert Value Here}" # Optional - Replace with custom build tags if any +# Script Functions - REFRAIN FROM MODIFYING THE SCRIPT BELOW +# Function to sanitize project and build names +sanitize_name() { +local name="$1" +sanitized_name=$(echo "$name" | sed 's/ /%20/g') +echo "$sanitized_name" +} +# Function to get the UUID of the latest build +get_latest_build_uuid() { +local sanitized_project_name=$(sanitize_name "$project_name") +local sanitized_build_name=$(sanitize_name "$build_name") +local sanitized_build_tags=$(sanitize_name "$build_tags") +# Fetch and sanitize the JSON response +if [ -n "$sanitized_build_tags" ]; then + response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name&user_name=$username&build_tags=$sanitized_build_tags") +else + response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name&user_name=$username") +fi +response=$(echo "$response" | perl -pe 's/([[:cntrl:]])/sprintf("\\x{%02X}", ord($1))/eg') +local build_uuid=$(echo "$response" | jq -r '.build_id') +echo "$build_uuid" +} +# Function to hit Quality Gates API and get the result +get_quality_gate_result() { +quality_gate_result=$(curl -s -H --retry 3 --connect-timeout 10 -u "$username:$access_key" https://api-automation.browserstack.com/ext/v1/quality-gates/$build_uuid) +echo "$quality_gate_result" +} +# Function to poll the API until the results of the Quality Gate are received +poll_quality_gate_api() { +local attempt=0 +local max_time=600 +local total_time=0 +while [[ $attempt -lt $max_attempts ]] && [[ $total_time -lt max_time ]]; do +quality_gate_result=$(get_quality_gate_result "$1" "$2" "$build_uuid") +local result=$(echo "$quality_gate_result" | jq -r '.status') +if [ "$result" != "running" ]; then +echo "$quality_gate_result" +exit 0 +fi +sleep 30 # Poll every 30 seconds +((attempt++)) +total_time=$((attempt * 30)) # Total elapsed time in seconds +done +echo "Timed out waiting for Quality Gate results" +exit 1 +} +# Function to assert the API response and throw pass/fail exit code +assert_quality_gate_result() { +local result=$(echo "$quality_gate_result" | jq -r '.status') +# Replace the condition below with the actual condition to determine pass/fail +if [ "$result" == "passed" ]; then +echo "Quality Gate passed" +exit 0 +else +echo "Quality Gate failed" +exit 1 +fi +} +# Quality Gates API Poll +build_uuid=\$(get_latest_build_uuid) +sleep 20 +quality_gate_result=\$(poll_quality_gate_api) +echo "Quality Gate Result: \$quality_gate_result" +assert_quality_gate_result From 2ab7e1d259ee86a595df8df999681a738f8f8b80 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:01:20 +0530 Subject: [PATCH 16/28] Update check-quality-gate.sh --- check-quality-gate.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index ee3d94f..65037a6 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -70,6 +70,6 @@ fi # Quality Gates API Poll build_uuid=\$(get_latest_build_uuid) sleep 20 -quality_gate_result=\$(poll_quality_gate_api) -echo "Quality Gate Result: \$quality_gate_result" +quality_gate_result=$(poll_quality_gate_api) +echo "Quality Gate Result: $quality_gate_result" assert_quality_gate_result From 6948bc73340f34903752cceee2440488b0a4f21f Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 14:09:42 +0530 Subject: [PATCH 17/28] Update check-quality-gate.sh --- check-quality-gate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index 65037a6..6482576 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -68,7 +68,7 @@ exit 1 fi } # Quality Gates API Poll -build_uuid=\$(get_latest_build_uuid) +build_uuid=$(get_latest_build_uuid) sleep 20 quality_gate_result=$(poll_quality_gate_api) echo "Quality Gate Result: $quality_gate_result" From ae0dcf6b8ff546f5fd35bc1c72d0667a75560177 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 17:18:01 +0530 Subject: [PATCH 18/28] debug check-quality-gate.sh --- check-quality-gate.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index 6482576..2e3441e 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -1,14 +1,14 @@ #!/bin/bash # Update values here project_name="BrowserStack Cucumber TestNG" # Replace with your project name -build_name="$BROWSERSTACK_BUILD_NAME" # Replace with your build name use $BROWSERSTACK_BUILD_NAME if you use the BrowserStack Jenkins Plugin +build_name="azure-BrowserStack_Platform_SDK-CI-355" # "$BROWSERSTACK_BUILD_NAME" # Replace with your build name use $BROWSERSTACK_BUILD_NAME if you use the BrowserStack Jenkins Plugin # Read secrets from environment variables username="$BROWSERSTACK_USERNAME" access_key="$BROWSERSTACK_ACCESS_KEY" max_attempts=20 # Replace with your max retry attempt -build_tags="{Insert Value Here}" # Optional - Replace with custom build tags if any +build_tags="" # Optional - Replace with custom build tags if any # Script Functions - REFRAIN FROM MODIFYING THE SCRIPT BELOW # Function to sanitize project and build names sanitize_name() { @@ -27,8 +27,10 @@ if [ -n "$sanitized_build_tags" ]; then else response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name&user_name=$username") fi -response=$(echo "$response" | perl -pe 's/([[:cntrl:]])/sprintf("\\x{%02X}", ord($1))/eg') -local build_uuid=$(echo "$response" | jq -r '.build_id') +# Use perl to strip ALL non-printable control characters that can break jq. +# This is a more robust fix than just replacing \n and \t. +local sanitized_response=$(echo "$response" | perl -pe 's/[^[:print:]]//g') +local build_uuid=$(echo "$sanitized_response" | jq -r '.build_id') echo "$build_uuid" } # Function to hit Quality Gates API and get the result From ebe09aa09fbc98062d8ca2cae7fde5c31d455f95 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 17:47:37 +0530 Subject: [PATCH 19/28] Debug check-quality-gate.sh --- check-quality-gate.sh | 141 ++++++++++++++++++++++++++---------------- 1 file changed, 88 insertions(+), 53 deletions(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index 2e3441e..5a1528d 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -1,77 +1,112 @@ #!/bin/bash # Update values here -project_name="BrowserStack Cucumber TestNG" # Replace with your project name -build_name="azure-BrowserStack_Platform_SDK-CI-355" # "$BROWSERSTACK_BUILD_NAME" # Replace with your build name use $BROWSERSTACK_BUILD_NAME if you use the BrowserStack Jenkins Plugin +project_name="BrowserStack Cucumber TestNG" +build_name="azure-BrowserStack_Platform_SDK-CI-355" # Read secrets from environment variables -username="$BROWSERSTACK_USERNAME" -access_key="$BROWSERSTACK_ACCESS_KEY" +username="$BROWSERSTACK_USERNAME" +access_key="$BROWSERSTACK_ACCESS_KEY" -max_attempts=20 # Replace with your max retry attempt -build_tags="" # Optional - Replace with custom build tags if any -# Script Functions - REFRAIN FROM MODIFYING THE SCRIPT BELOW +max_attempts=20 +build_tags="" # Optional + +echo "[DEBUG] --- Initial Configuration ---" +echo "[DEBUG] Project Name: $project_name" +echo "[DEBUG] Build Name (from env): $build_name" +echo "[DEBUG] Username: $username" +echo "[DEBUG] Build Tags: $build_tags" +echo "[DEBUG] ---------------------------" + +# Script Functions # Function to sanitize project and build names sanitize_name() { -local name="$1" -sanitized_name=$(echo "$name" | sed 's/ /%20/g') -echo "$sanitized_name" + local name="$1" + sanitized_name=$(echo "$name" | sed 's/ /%20/g') + echo "$sanitized_name" } + # Function to get the UUID of the latest build get_latest_build_uuid() { -local sanitized_project_name=$(sanitize_name "$project_name") -local sanitized_build_name=$(sanitize_name "$build_name") -local sanitized_build_tags=$(sanitize_name "$build_tags") -# Fetch and sanitize the JSON response -if [ -n "$sanitized_build_tags" ]; then - response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name&user_name=$username&build_tags=$sanitized_build_tags") -else - response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name&user_name=$username") -fi -# Use perl to strip ALL non-printable control characters that can break jq. -# This is a more robust fix than just replacing \n and \t. -local sanitized_response=$(echo "$response" | perl -pe 's/[^[:print:]]//g') -local build_uuid=$(echo "$sanitized_response" | jq -r '.build_id') -echo "$build_uuid" + local sanitized_project_name=$(sanitize_name "$project_name") + local sanitized_build_name=$(sanitize_name "$build_name") + local sanitized_build_tags=$(sanitize_name "$build_tags") + + echo "[DEBUG] Sanitized Project Name: $sanitized_project_name" + echo "[DEBUG] Sanitized Build Name: $sanitized_build_name" + + local url="https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name&user_name=$username" + if [ -n "$sanitized_build_tags" ]; then + url="$url&build_tags=$sanitized_build_tags" + fi + + echo "[DEBUG] Querying URL: $url" + + # Fetch the JSON response + response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "$url") + + echo "[DEBUG] Raw API Response for Build UUID: $response" + + # Use perl to strip ALL non-printable control characters that can break jq. + local sanitized_response=$(echo "$response" | perl -pe 's/[^[:print:]]//g') + + # Use the corrected "sanitized_response" variable + local build_uuid=$(echo "$sanitized_response" | jq -r '.build_id') + echo "[DEBUG] Extracted Build UUID: $build_uuid" + echo "$build_uuid" } + # Function to hit Quality Gates API and get the result get_quality_gate_result() { -quality_gate_result=$(curl -s -H --retry 3 --connect-timeout 10 -u "$username:$access_key" https://api-automation.browserstack.com/ext/v1/quality-gates/$build_uuid) -echo "$quality_gate_result" + echo "[DEBUG] Checking Quality Gate for Build UUID: $build_uuid" + local qg_url="https://api-automation.browserstack.com/ext/v1/quality-gates/$build_uuid" + echo "[DEBUG] Querying Quality Gate URL: $qg_url" + quality_gate_result=$(curl -s -H --retry 3 --connect-timeout 10 -u "$username:$access_key" "$qg_url") + echo "[DEBUG] Raw Quality Gate Response: $quality_gate_result" + echo "$quality_gate_result" } + # Function to poll the API until the results of the Quality Gate are received poll_quality_gate_api() { -local attempt=0 -local max_time=600 -local total_time=0 -while [[ $attempt -lt $max_attempts ]] && [[ $total_time -lt max_time ]]; do -quality_gate_result=$(get_quality_gate_result "$1" "$2" "$build_uuid") -local result=$(echo "$quality_gate_result" | jq -r '.status') -if [ "$result" != "running" ]; then -echo "$quality_gate_result" -exit 0 -fi -sleep 30 # Poll every 30 seconds -((attempt++)) -total_time=$((attempt * 30)) # Total elapsed time in seconds -done -echo "Timed out waiting for Quality Gate results" -exit 1 + local attempt=0 + local max_time=600 + local total_time=0 + while [[ $attempt -lt $max_attempts ]] && [[ $total_time -lt max_time ]]; do + echo "[DEBUG] Polling attempt #$((attempt + 1))..." + quality_gate_result=$(get_quality_gate_result "$1" "$2" "$build_uuid") + local result=$(echo "$quality_gate_result" | jq -r '.status') + echo "[DEBUG] Current status is: '$result'" + if [ "$result" != "running" ]; then + echo "$quality_gate_result" + exit 0 + fi + sleep 30 + ((attempt++)) + total_time=$((attempt * 30)) + done + echo "Timed out waiting for Quality Gate results" + exit 1 } + # Function to assert the API response and throw pass/fail exit code assert_quality_gate_result() { -local result=$(echo "$quality_gate_result" | jq -r '.status') -# Replace the condition below with the actual condition to determine pass/fail -if [ "$result" == "passed" ]; then -echo "Quality Gate passed" -exit 0 -else -echo "Quality Gate failed" -exit 1 -fi + local result=$(echo "$quality_gate_result" | jq -r '.status') + if [ "$result" == "passed" ]; then + echo "Quality Gate passed" + exit 0 + else + echo "Quality Gate failed" + exit 1 + fi } -# Quality Gates API Poll + +# --- Main Script Execution --- build_uuid=$(get_latest_build_uuid) +if [ "$build_uuid" == "null" ] || [ -z "$build_uuid" ]; then + echo "[ERROR] Failed to retrieve a valid Build UUID. Please check the project and build names in the logs above." + exit 1 +fi + sleep 20 quality_gate_result=$(poll_quality_gate_api) -echo "Quality Gate Result: $quality_gate_result" +echo "Final Quality Gate Result: $quality_gate_result" assert_quality_gate_result From 39caf325ed14f5542ac2aabe0e39f175f3b7cf89 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:03:11 +0530 Subject: [PATCH 20/28] Debug check-quality-gate.sh --- check-quality-gate.sh | 104 ++++++++++++++++++------------------------ 1 file changed, 45 insertions(+), 59 deletions(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index 5a1528d..dd7a1c2 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -10,6 +10,10 @@ access_key="$BROWSERSTACK_ACCESS_KEY" max_attempts=20 build_tags="" # Optional +# --- Redirect debug logs to stderr to avoid corrupting JSON variables --- +exec 3>&1 # Save original stdout +exec 1>&2 # Redirect stdout to stderr for debug logs + echo "[DEBUG] --- Initial Configuration ---" echo "[DEBUG] Project Name: $project_name" echo "[DEBUG] Build Name (from env): $build_name" @@ -18,95 +22,77 @@ echo "[DEBUG] Build Tags: $build_tags" echo "[DEBUG] ---------------------------" # Script Functions -# Function to sanitize project and build names sanitize_name() { local name="$1" sanitized_name=$(echo "$name" | sed 's/ /%20/g') echo "$sanitized_name" } -# Function to get the UUID of the latest build get_latest_build_uuid() { local sanitized_project_name=$(sanitize_name "$project_name") local sanitized_build_name=$(sanitize_name "$build_name") - local sanitized_build_tags=$(sanitize_name "$build_tags") echo "[DEBUG] Sanitized Project Name: $sanitized_project_name" echo "[DEBUG] Sanitized Build Name: $sanitized_build_name" - local url="https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name&user_name=$username" - if [ -n "$sanitized_build_tags" ]; then - url="$url&build_tags=$sanitized_build_tags" - fi + # REMOVED user_name parameter for a more reliable query + local url="https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name" echo "[DEBUG] Querying URL: $url" - # Fetch the JSON response + # Fetch the JSON response and send it to the original stdout response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "$url") - - echo "[DEBUG] Raw API Response for Build UUID: $response" - - # Use perl to strip ALL non-printable control characters that can break jq. - local sanitized_response=$(echo "$response" | perl -pe 's/[^[:print:]]//g') - - # Use the corrected "sanitized_response" variable - local build_uuid=$(echo "$sanitized_response" | jq -r '.build_id') - echo "[DEBUG] Extracted Build UUID: $build_uuid" - echo "$build_uuid" + echo "$response" >&3 } -# Function to hit Quality Gates API and get the result get_quality_gate_result() { echo "[DEBUG] Checking Quality Gate for Build UUID: $build_uuid" local qg_url="https://api-automation.browserstack.com/ext/v1/quality-gates/$build_uuid" echo "[DEBUG] Querying Quality Gate URL: $qg_url" + + # Fetch the JSON response and send it to the original stdout quality_gate_result=$(curl -s -H --retry 3 --connect-timeout 10 -u "$username:$access_key" "$qg_url") - echo "[DEBUG] Raw Quality Gate Response: $quality_gate_result" - echo "$quality_gate_result" + echo "$quality_gate_result" >&3 } -# Function to poll the API until the results of the Quality Gate are received -poll_quality_gate_api() { - local attempt=0 - local max_time=600 - local total_time=0 - while [[ $attempt -lt $max_attempts ]] && [[ $total_time -lt max_time ]]; do - echo "[DEBUG] Polling attempt #$((attempt + 1))..." - quality_gate_result=$(get_quality_gate_result "$1" "$2" "$build_uuid") - local result=$(echo "$quality_gate_result" | jq -r '.status') - echo "[DEBUG] Current status is: '$result'" - if [ "$result" != "running" ]; then - echo "$quality_gate_result" - exit 0 - fi - sleep 30 - ((attempt++)) - total_time=$((attempt * 30)) - done - echo "Timed out waiting for Quality Gate results" - exit 1 -} +# --- Main Script Execution --- -# Function to assert the API response and throw pass/fail exit code -assert_quality_gate_result() { - local result=$(echo "$quality_gate_result" | jq -r '.status') - if [ "$result" == "passed" ]; then - echo "Quality Gate passed" - exit 0 - else - echo "Quality Gate failed" - exit 1 - fi -} +# Restore stdout for the main logic +exec 1>&3 + +build_uuid_json=$(get_latest_build_uuid) +echo "[DEBUG] Raw API Response for Build UUID: $build_uuid_json" +sanitized_response=$(echo "$build_uuid_json" | perl -pe 's/[^[:print:]]//g') +build_uuid=$(echo "$sanitized_response" | jq -r '.build_id') +echo "[DEBUG] Extracted Build UUID: $build_uuid" -# --- Main Script Execution --- -build_uuid=$(get_latest_build_uuid) if [ "$build_uuid" == "null" ] || [ -z "$build_uuid" ]; then - echo "[ERROR] Failed to retrieve a valid Build UUID. Please check the project and build names in the logs above." + echo "[ERROR] Failed to retrieve a valid Build UUID. Please check the project and build names in the logs above." >&2 exit 1 fi sleep 20 -quality_gate_result=$(poll_quality_gate_api) -echo "Final Quality Gate Result: $quality_gate_result" -assert_quality_gate_result + +# Polling loop +attempt=0 +while [[ $attempt -lt $max_attempts ]]; do + echo "[DEBUG] Polling attempt #$((attempt + 1))..." >&2 + quality_gate_result_json=$(get_quality_gate_result) + result=$(echo "$quality_gate_result_json" | jq -r '.status') + echo "[DEBUG] Current status is: '$result'" >&2 + if [ "$result" != "running" ]; then + break + fi + sleep 30 + ((attempt++)) +done + +if [ "$result" != "passed" ]; then + echo "Final Quality Gate Result: $quality_gate_result_json" + echo "Quality Gate failed" >&2 + exit 1 +else + echo "Final Quality Gate Result: $quality_gate_result_json" + echo "Quality Gate passed" >&2 + exit 0 +fi From 14bda668b6170c4ab315c3379c2b798e4fe4c6bf Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:15:36 +0530 Subject: [PATCH 21/28] Update check-quality-gate.sh --- check-quality-gate.sh | 75 ++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 41 deletions(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index dd7a1c2..75beaaf 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -1,73 +1,63 @@ #!/bin/bash # Update values here project_name="BrowserStack Cucumber TestNG" -build_name="azure-BrowserStack_Platform_SDK-CI-355" +build_name="$BROWSERSTACK_BUILD_NAME" # Read secrets from environment variables username="$BROWSERSTACK_USERNAME" access_key="$BROWSERSTACK_ACCESS_KEY" max_attempts=20 -build_tags="" # Optional +build_tags="" -# --- Redirect debug logs to stderr to avoid corrupting JSON variables --- -exec 3>&1 # Save original stdout -exec 1>&2 # Redirect stdout to stderr for debug logs - -echo "[DEBUG] --- Initial Configuration ---" -echo "[DEBUG] Project Name: $project_name" -echo "[DEBUG] Build Name (from env): $build_name" -echo "[DEBUG] Username: $username" -echo "[DEBUG] Build Tags: $build_tags" -echo "[DEBUG] ---------------------------" +# --- Print initial config to stderr --- +echo "[DEBUG] --- Initial Configuration ---" >&2 +echo "[DEBUG] Project Name: $project_name" >&2 +echo "[DEBUG] Build Name (from env): $build_name" >&2 +echo "[DEBUG] Username: $username" >&2 +echo "[DEBUG] Build Tags: $build_tags" >&2 +echo "[DEBUG] ---------------------------" >&2 # Script Functions sanitize_name() { local name="$1" - sanitized_name=$(echo "$name" | sed 's/ /%20/g') - echo "$sanitized_name" + echo "$name" | sed 's/ /%20/g' } get_latest_build_uuid() { local sanitized_project_name=$(sanitize_name "$project_name") local sanitized_build_name=$(sanitize_name "$build_name") - echo "[DEBUG] Sanitized Project Name: $sanitized_project_name" - echo "[DEBUG] Sanitized Build Name: $sanitized_build_name" + echo "[DEBUG] Sanitized Project Name: $sanitized_project_name" >&2 + echo "[DEBUG] Sanitized Build Name: $sanitized_build_name" >&2 # REMOVED user_name parameter for a more reliable query local url="https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name" - - echo "[DEBUG] Querying URL: $url" + echo "[DEBUG] Querying URL: $url" >&2 - # Fetch the JSON response and send it to the original stdout - response=$(curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "$url") - echo "$response" >&3 + # Fetch the JSON response. This goes to stdout. + curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "$url" } get_quality_gate_result() { - echo "[DEBUG] Checking Quality Gate for Build UUID: $build_uuid" + echo "[DEBUG] Checking Quality Gate for Build UUID: $build_uuid" >&2 local qg_url="https://api-automation.browserstack.com/ext/v1/quality-gates/$build_uuid" - echo "[DEBUG] Querying Quality Gate URL: $qg_url" - - # Fetch the JSON response and send it to the original stdout - quality_gate_result=$(curl -s -H --retry 3 --connect-timeout 10 -u "$username:$access_key" "$qg_url") - echo "$quality_gate_result" >&3 + echo "[DEBUG] Querying Quality Gate URL: $qg_url" >&2 + + # Fetch the JSON response. This goes to stdout. + curl -s -H --retry 3 --connect-timeout 10 -u "$username:$access_key" "$qg_url" } # --- Main Script Execution --- - -# Restore stdout for the main logic -exec 1>&3 - build_uuid_json=$(get_latest_build_uuid) -echo "[DEBUG] Raw API Response for Build UUID: $build_uuid_json" -sanitized_response=$(echo "$build_uuid_json" | perl -pe 's/[^[:print:]]//g') +echo "[DEBUG] Raw API Response for Build UUID: $build_uuid_json" >&2 + +sanitized_response=$(echo "$build_uuid_json" | perl -pe 's/[^[:print:]\n]//g') build_uuid=$(echo "$sanitized_response" | jq -r '.build_id') -echo "[DEBUG] Extracted Build UUID: $build_uuid" +echo "[DEBUG] Extracted Build UUID: $build_uuid" >&2 if [ "$build_uuid" == "null" ] || [ -z "$build_uuid" ]; then - echo "[ERROR] Failed to retrieve a valid Build UUID. Please check the project and build names in the logs above." >&2 + echo "[ERROR] Failed to retrieve a valid Build UUID. Check API response above." >&2 exit 1 fi @@ -78,8 +68,11 @@ attempt=0 while [[ $attempt -lt $max_attempts ]]; do echo "[DEBUG] Polling attempt #$((attempt + 1))..." >&2 quality_gate_result_json=$(get_quality_gate_result) + echo "[DEBUG] Raw Quality Gate Response: $quality_gate_result_json" >&2 + result=$(echo "$quality_gate_result_json" | jq -r '.status') echo "[DEBUG] Current status is: '$result'" >&2 + if [ "$result" != "running" ]; then break fi @@ -87,12 +80,12 @@ while [[ $attempt -lt $max_attempts ]]; do ((attempt++)) done -if [ "$result" != "passed" ]; then - echo "Final Quality Gate Result: $quality_gate_result_json" - echo "Quality Gate failed" >&2 - exit 1 -else - echo "Final Quality Gate Result: $quality_gate_result_json" +echo "Final Quality Gate Result: $quality_gate_result_json" + +if [ "$result" == "passed" ]; then echo "Quality Gate passed" >&2 exit 0 +else + echo "Quality Gate failed" >&2 + exit 1 fi From 06fd387f2068b0a11561cba3ce450513e454bd49 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:17:35 +0530 Subject: [PATCH 22/28] Update check-quality-gate.sh --- check-quality-gate.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index 75beaaf..07ee2ad 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -1,7 +1,7 @@ #!/bin/bash # Update values here project_name="BrowserStack Cucumber TestNG" -build_name="$BROWSERSTACK_BUILD_NAME" +build_name="azure-BrowserStack_Platform_SDK-CI-355" # Read secrets from environment variables username="$BROWSERSTACK_USERNAME" From 2cfb5b9575f168ac907b1d1759fb7a785b912d27 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 17 Sep 2025 18:33:22 +0530 Subject: [PATCH 23/28] Update check-quality-gate.sh --- check-quality-gate.sh | 104 +++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 48 deletions(-) diff --git a/check-quality-gate.sh b/check-quality-gate.sh index 07ee2ad..553cc83 100644 --- a/check-quality-gate.sh +++ b/check-quality-gate.sh @@ -1,91 +1,99 @@ #!/bin/bash -# Update values here -project_name="BrowserStack Cucumber TestNG" -build_name="azure-BrowserStack_Platform_SDK-CI-355" +set -e # Exit immediately if a command exits with a non-zero status. -# Read secrets from environment variables +# --- Configuration --- +# These values are read from Azure DevOps Pipeline variables. +project_name="BrowserStack Cucumber TestNG" +build_name="$BROWSERSTACK_BUILD_NAME" username="$BROWSERSTACK_USERNAME" access_key="$BROWSERSTACK_ACCESS_KEY" -max_attempts=20 -build_tags="" +# --- Script Parameters --- +max_attempts=20 # Max number of times to poll the API (20 attempts * 30s = 10 minutes) +build_tags="" # Optional: Set build tags if needed -# --- Print initial config to stderr --- -echo "[DEBUG] --- Initial Configuration ---" >&2 -echo "[DEBUG] Project Name: $project_name" >&2 -echo "[DEBUG] Build Name (from env): $build_name" >&2 -echo "[DEBUG] Username: $username" >&2 -echo "[DEBUG] Build Tags: $build_tags" >&2 -echo "[DEBUG] ---------------------------" >&2 +# --- Script Functions --- -# Script Functions +# Function to URL-encode a string sanitize_name() { local name="$1" echo "$name" | sed 's/ /%20/g' } +# Function to get the UUID of the latest build get_latest_build_uuid() { - local sanitized_project_name=$(sanitize_name "$project_name") - local sanitized_build_name=$(sanitize_name "$build_name") - - echo "[DEBUG] Sanitized Project Name: $sanitized_project_name" >&2 - echo "[DEBUG] Sanitized Build Name: $sanitized_build_name" >&2 + local sanitized_project_name + local sanitized_build_name + sanitized_project_name=$(sanitize_name "$project_name") + sanitized_build_name=$(sanitize_name "$build_name") - # REMOVED user_name parameter for a more reliable query + # API call relies on project and build name, which is most reliable in CI. local url="https://api-automation.browserstack.com/ext/v1/builds/latest?project_name=$sanitized_project_name&build_name=$sanitized_build_name" - echo "[DEBUG] Querying URL: $url" >&2 - # Fetch the JSON response. This goes to stdout. + # Add optional build tags to the query if they are set + if [ -n "$build_tags" ]; then + local sanitized_build_tags + sanitized_build_tags=$(sanitize_name "$build_tags") + url="$url&build_tags=$sanitized_build_tags" + fi + + echo "Querying for build..." >&2 + + # Fetch the JSON response. This goes to standard output. curl -s --retry 3 --connect-timeout 10 -u "$username:$access_key" "$url" } +# Function to get the status of the Quality Gate for a given build UUID get_quality_gate_result() { - echo "[DEBUG] Checking Quality Gate for Build UUID: $build_uuid" >&2 + local build_uuid="$1" local qg_url="https://api-automation.browserstack.com/ext/v1/quality-gates/$build_uuid" - echo "[DEBUG] Querying Quality Gate URL: $qg_url" >&2 - # Fetch the JSON response. This goes to stdout. + # Fetch the JSON response. This goes to standard output. curl -s -H --retry 3 --connect-timeout 10 -u "$username:$access_key" "$qg_url" } # --- Main Script Execution --- -build_uuid_json=$(get_latest_build_uuid) -echo "[DEBUG] Raw API Response for Build UUID: $build_uuid_json" >&2 -sanitized_response=$(echo "$build_uuid_json" | perl -pe 's/[^[:print:]\n]//g') -build_uuid=$(echo "$sanitized_response" | jq -r '.build_id') -echo "[DEBUG] Extracted Build UUID: $build_uuid" >&2 +echo "--- BrowserStack Quality Gate Check ---" >&2 + +build_info_json=$(get_latest_build_uuid) +build_uuid=$(echo "$build_info_json" | jq -r '.build_id') if [ "$build_uuid" == "null" ] || [ -z "$build_uuid" ]; then - echo "[ERROR] Failed to retrieve a valid Build UUID. Check API response above." >&2 + echo "Error: Failed to retrieve a valid Build UUID from the API." >&2 + echo "API Response: $build_info_json" >&2 exit 1 fi +echo "Successfully found Build UUID: $build_uuid" >&2 +echo "Waiting 20 seconds before polling Quality Gate..." >&2 sleep 20 # Polling loop attempt=0 while [[ $attempt -lt $max_attempts ]]; do - echo "[DEBUG] Polling attempt #$((attempt + 1))..." >&2 - quality_gate_result_json=$(get_quality_gate_result) - echo "[DEBUG] Raw Quality Gate Response: $quality_gate_result_json" >&2 + attempt=$((attempt + 1)) + echo "Polling attempt #$attempt..." >&2 + + quality_gate_json=$(get_quality_gate_result "$build_uuid") + status=$(echo "$quality_gate_json" | jq -r '.status') - result=$(echo "$quality_gate_result_json" | jq -r '.status') - echo "[DEBUG] Current status is: '$result'" >&2 + echo "Current status is: '$status'" >&2 - if [ "$result" != "running" ]; then - break + if [ "$status" != "running" ]; then + echo "Final Quality Gate Result: $quality_gate_json" + + if [ "$status" == "passed" ]; then + echo "✅ Quality Gate Passed" >&2 + exit 0 + else + echo "❌ Quality Gate Failed" >&2 + exit 1 + fi fi + sleep 30 - ((attempt++)) done -echo "Final Quality Gate Result: $quality_gate_result_json" - -if [ "$result" == "passed" ]; then - echo "Quality Gate passed" >&2 - exit 0 -else - echo "Quality Gate failed" >&2 - exit 1 -fi +echo "Error: Timed out waiting for Quality Gate results after $max_attempts attempts." >&2 +exit 1 From 74daff1945e887ab235cb3017aaebefd030b0e78 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Tue, 4 Nov 2025 17:29:23 +0530 Subject: [PATCH 24/28] Add browser profiling and test orchestration options --- browserstack.yml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/browserstack.yml b/browserstack.yml index 7ca1a9d..09eb28c 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -94,4 +94,14 @@ accessibilityOptions: performance: assert percy: true percyCaptureMode: auto -#logLevel: debug \ No newline at end of file +#logLevel: debug +browserProfiling: true + +testOrchestrationOptions: + retryTestsOnFailure: + enabled: true + maxRetries: 2 + runSmartSelection: + enabled: true + mode: relevantFirst + runPreviouslyFailedFirst: true From 3f6a470e3d7fd96252122fd7b706396f663822c3 Mon Sep 17 00:00:00 2001 From: abdul-qadir92 Date: Wed, 26 Nov 2025 19:57:01 +0530 Subject: [PATCH 25/28] Add accessibility assertions and GitHub Action workflow --- .../workflows/browserstack-accessibility.yml | 28 ++++++++++++ browserstack.yml | 6 +-- src/test/java/StepDefinitions/UsersSteps.java | 43 +++++++++++++++++++ 3 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/browserstack-accessibility.yml diff --git a/.github/workflows/browserstack-accessibility.yml b/.github/workflows/browserstack-accessibility.yml new file mode 100644 index 0000000..12cb032 --- /dev/null +++ b/.github/workflows/browserstack-accessibility.yml @@ -0,0 +1,28 @@ +name: BrowserStack Accessibility Tests (On-Prem) + +on: + # Manual trigger only + workflow_dispatch: + +jobs: + test: + runs-on: ubuntu-latest + + # Ensure this only runs for the sdk branch + if: github.ref == 'refs/heads/sdk' + + steps: + - name: Checkout sdk branch + uses: actions/checkout@v4 + with: + ref: sdk + + - name: Set up JDK 11 + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '11' + cache: maven + + - name: Run Accessibility tests + run: mvn test -P scenario-onprem -B \ No newline at end of file diff --git a/browserstack.yml b/browserstack.yml index 09eb28c..c9d8746 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -38,10 +38,10 @@ platforms: browserVersion: 131.0 - deviceName: Samsung Galaxy S2* browserName: chrome # Try 'samsung' for Samsung browser - osVersion: [12131415] + osVersion: "[12131415]" - deviceName: iPhone 1* browserName: safari - osVersion: [15161718] + osVersion: "[15161718]" # ======================= # Parallels per Platform # ======================= @@ -51,7 +51,7 @@ platforms: # Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack # # Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack -parallelsPerPlatform: 2 +parallelsPerPlatform: 4 framework: cucumber-testng #junit,testng,java,cucumber-testng,serenity,cucumber-junit source: cucumber-testng:intellij:v1.1.2 staticWebDriver: true diff --git a/src/test/java/StepDefinitions/UsersSteps.java b/src/test/java/StepDefinitions/UsersSteps.java index 234ddbf..55e1dd3 100644 --- a/src/test/java/StepDefinitions/UsersSteps.java +++ b/src/test/java/StepDefinitions/UsersSteps.java @@ -8,8 +8,14 @@ import io.cucumber.java.en.Then; import io.cucumber.java.en.When; +import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; + +import org.testng.Assert; + +import com.browserstack.accessibility.AccessibilityUtils; public class UsersSteps { @@ -68,6 +74,43 @@ public void gets_your_account_has_been_locked(String user) throws InterruptedExc }else throw new AssertionError("Locked user "+user+" logged in!"); + // Accessibility assertion using BrowserStack Accessibility results summary + // Documentation reference: + // https://www.browserstack.com/docs/accessibility/automated-tests/add-accessibility-assertions + Map summary = AccessibilityUtils.getResultsSummary(hooks.driver); + + // Debug logging to understand NPE / null values + System.out.println("Accessibility summary: " + summary); + sc.log("Accessibility summary: " + String.valueOf(summary)); + + if (summary == null) { + sc.log("Accessibility summary is null, skipping accessibility assertions."); + return; + } + + Object severityMapObj = summary.get("issueCountBySeverity"); + if (!(severityMapObj instanceof Map)) { + sc.log("issueCountBySeverity is missing or not a Map in accessibility summary, skipping assertions."); + return; + } + + Map severityMap = (Map) severityMapObj; + Object criticalObj = severityMap.get("critical"); + sc.log("Critical issue count (raw): " + String.valueOf(criticalObj)); + + if (criticalObj == null) { + sc.log("Critical issue count is null in accessibility summary, skipping assertions."); + return; + } + + // Fetch and log detailed accessibility results as well + ArrayList> results = AccessibilityUtils.getResults(hooks.driver); + System.out.println("Accessibility detailed results: " + results); + sc.log("Accessibility detailed results: " + String.valueOf(results)); + + int criticalIssueCount = Integer.parseInt(String.valueOf(criticalObj)); + Assert.assertTrue(criticalIssueCount < 1, "Critical issue count breached the threshold!"); + } } From f1bf5a1258320afb04bd8acc2a386e0431d8fadc Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 26 Nov 2025 20:13:33 +0530 Subject: [PATCH 26/28] Update BrowserStack accessibility workflow Removed conditional check for sdk branch in workflow. --- .github/workflows/browserstack-accessibility.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/browserstack-accessibility.yml b/.github/workflows/browserstack-accessibility.yml index 12cb032..7425362 100644 --- a/.github/workflows/browserstack-accessibility.yml +++ b/.github/workflows/browserstack-accessibility.yml @@ -1,16 +1,12 @@ name: BrowserStack Accessibility Tests (On-Prem) on: - # Manual trigger only workflow_dispatch: jobs: test: runs-on: ubuntu-latest - # Ensure this only runs for the sdk branch - if: github.ref == 'refs/heads/sdk' - steps: - name: Checkout sdk branch uses: actions/checkout@v4 @@ -25,4 +21,4 @@ jobs: cache: maven - name: Run Accessibility tests - run: mvn test -P scenario-onprem -B \ No newline at end of file + run: mvn test -P scenario-onprem -B From a15c817f3d0b559aac8c280d61f7eb8798011fbd Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Wed, 26 Nov 2025 20:18:43 +0530 Subject: [PATCH 27/28] Change parallelsPerPlatform from 4 to 2 --- browserstack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browserstack.yml b/browserstack.yml index c9d8746..4dced8c 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -51,7 +51,7 @@ platforms: # Example 1 - If you have configured 3 platforms and set `parallelsPerPlatform` as 2, a total of 6 (2 * 3) parallel threads will be used on BrowserStack # # Example 2 - If you have configured 1 platform and set `parallelsPerPlatform` as 5, a total of 5 (1 * 5) parallel threads will be used on BrowserStack -parallelsPerPlatform: 4 +parallelsPerPlatform: 2 framework: cucumber-testng #junit,testng,java,cucumber-testng,serenity,cucumber-junit source: cucumber-testng:intellij:v1.1.2 staticWebDriver: true From be987a4aaa53bd8db7d71dcf1b78295af380d1db Mon Sep 17 00:00:00 2001 From: abdul-qadir92 <92802404+abdul-qadir92@users.noreply.github.com> Date: Tue, 9 Dec 2025 13:08:31 +0530 Subject: [PATCH 28/28] Update scenario outlines for user login tests --- src/test/resources/Features/Users.feature | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/resources/Features/Users.feature b/src/test/resources/Features/Users.feature index 7bf8cbe..22b3911 100644 --- a/src/test/resources/Features/Users.feature +++ b/src/test/resources/Features/Users.feature @@ -8,7 +8,7 @@ Feature: Different Users use cases in BStackDemo When User clicks on sign in link @noimage @fail - Scenario Outline: TC-1665 Login as User with no image loaded + Scenario Outline: TC-5883 Login as User with no image loaded When User enters and and clicks on sign in And is signed in to the App Then Product images are not loaded for the @@ -17,7 +17,7 @@ Feature: Different Users use cases in BStackDemo |"image_not_loading_user"|"testingisfun99"| @orders - Scenario Outline: TC-1666 Login as existing user to verify orders + Scenario Outline: TC-5884 Login as existing user to verify orders When User enters and and clicks on sign in And is signed in to the App And User clicks on Orders @@ -27,7 +27,7 @@ Feature: Different Users use cases in BStackDemo |"existing_orders_user"|"testingisfun99"| @locked - Scenario Outline: TC-1667 Login as a locked User + Scenario Outline: TC-5885 Login as a locked User When User enters and and clicks on sign in Then gets Your account has been locked. Examples: