From b680dd65faf7c1f684e421db4018ac27fb366c25 Mon Sep 17 00:00:00 2001 From: Rakesh Dasi Date: Mon, 5 Jun 2023 01:36:42 +0530 Subject: [PATCH 1/7] Added Test for Playwright Cucumber JS --- README.md | 76 +++++++++++- playwright-cucumber-js/.gitignore | 111 ++++++++++++++++++ .../features/config/config.js | 3 + .../features/page-objects/checkout-page.js | 42 +++++++ .../features/page-objects/home-page.js | 35 ++++++ .../features/page-objects/login-page.js | 42 +++++++ .../features/steps/assertions.js | 4 + .../features/steps/setup.js | 51 ++++++++ .../features/steps/viewBrowserstack.js | 44 +++++++ .../features/view-browserstack.feature | 10 ++ playwright-cucumber-js/package.json | 19 +++ 11 files changed, 435 insertions(+), 2 deletions(-) create mode 100644 playwright-cucumber-js/.gitignore create mode 100644 playwright-cucumber-js/features/config/config.js create mode 100644 playwright-cucumber-js/features/page-objects/checkout-page.js create mode 100644 playwright-cucumber-js/features/page-objects/home-page.js create mode 100644 playwright-cucumber-js/features/page-objects/login-page.js create mode 100644 playwright-cucumber-js/features/steps/assertions.js create mode 100644 playwright-cucumber-js/features/steps/setup.js create mode 100644 playwright-cucumber-js/features/steps/viewBrowserstack.js create mode 100644 playwright-cucumber-js/features/view-browserstack.feature create mode 100644 playwright-cucumber-js/package.json diff --git a/README.md b/README.md index 5830aae..485f65f 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,74 @@ -# cucumber-js-playwright-browserstack -Creating a sample repo for different Playwright languages and runners +# Running Playwright Tests with Cucumber.js on BrowserStack + +Cucumber.js is a JavaScript-based open-source framework for web automation testing. It runs on Node.js and latest web browsers. Cucumber.js allows you to write and execute tests in Gherkin - a non-technical and human-readable language. + +This repository provides an example setup for running Playwright tests with Cucumber.js on the BrowserStack cloud platform. + +## Prerequisites + +Before getting started, make sure you have the following prerequisites installed: + +- [Node.js](https://nodejs.org) - The JavaScript runtime environment +- [npm](https://www.npmjs.com/) - The Node.js package manager +- [Playwright](https://playwright.dev/) - A Node.js library for browser automation + +## Setup + +1. Clone this repository to your local machine: + +```bash +git clone https://github.com/browserstack/cucumber-js-playwright-browserstack.git +``` + +2. Install the dependencies by navigating to the project directory and running: + +Navigate to the `playwright-cucumber-js` directory: + +```bash +cd playwright-cucumber-js +``` + +```bash +npm install +``` + +3. Set up your BrowserStack Environment variables + +```plaintext +BROWSERSTACK_USERNAME= +BROWSERSTACK_ACCESS_KEY= +``` + +Replace `` and `` with your BrowserStack username and access key, which you can obtain from the BrowserStack dashboard. + +## Running the Tests + +To run the Playwright tests with Cucumber.js on BrowserStack, follow these steps: + +1. Update the `setup.js` file to configure the desired browsers, OS, and other capabilities for your test execution. +2. Run the tests using the following command: + +```bash +npm run test +``` + +The command will execute the test suite defined in the `features` directory using the configurations specified in `browserstack.conf.js`. The test results will be displayed in the console output. + +## Reporting + +By default, Cucumber.js generates HTML reports in the `reports` directory after the test execution. You can open the HTML report in your browser to view the test results and detailed information. + +## Conclusion + +This repository provides a basic setup for running Playwright tests with Cucumber.js on the BrowserStack cloud platform. Feel free to modify and expand it based on your project requirements. + +For more information on Playwright and Cucumber.js, refer to their respective documentation: + +- [Playwright Documentation](https://playwright.dev/docs/intro) +- [Cucumber.js Documentation](https://github.com/cucumber/cucumber-js) + +For additional details on configuring and using BrowserStack with Playwright, consult the BrowserStack documentation: + +- [BrowserStack Documentation](https://www.browserstack.com/docs) + +Happy testing! \ No newline at end of file diff --git a/playwright-cucumber-js/.gitignore b/playwright-cucumber-js/.gitignore new file mode 100644 index 0000000..581af78 --- /dev/null +++ b/playwright-cucumber-js/.gitignore @@ -0,0 +1,111 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock +package-lock.json + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env +.env.test + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# Next.js build output +.next + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and *not* Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# IDE files +.idea/ + +**/target/ +**/.DS_Store diff --git a/playwright-cucumber-js/features/config/config.js b/playwright-cucumber-js/features/config/config.js new file mode 100644 index 0000000..641238a --- /dev/null +++ b/playwright-cucumber-js/features/config/config.js @@ -0,0 +1,3 @@ +Object.assign(global, { + BASE_URL: 'https://bstackdemo.com/' +}); \ No newline at end of file diff --git a/playwright-cucumber-js/features/page-objects/checkout-page.js b/playwright-cucumber-js/features/page-objects/checkout-page.js new file mode 100644 index 0000000..ef6a21c --- /dev/null +++ b/playwright-cucumber-js/features/page-objects/checkout-page.js @@ -0,0 +1,42 @@ +locators = { + "submit_button": "#checkout-shipping-continue", + "confirmation_message": "#confirmation-message" +} + +class CheckoutPage { + + async setUserDetails(firstName, lastName, address, state, pincode) { + await page.locator("//input[@id='firstNameInput']").fill(firstName); + await page.locator("//input[@id='lastNameInput']").fill(lastName); + await page.locator("//input[@id='addressLine1Input']").fill(address); + await page.locator("//input[@id='provinceInput']").fill(state); + await page.locator("//input[@id='postCodeInput']").fill(pincode); + + } + + async verifyHomePageIsDisplayed() { + return expect(await page.title()).to.equal('StackDemo'); + } + + async clickSubmit() { + await page.locator("//button[@id='checkout-shipping-continue']").dblclick(); + + } + + async clickProduct() { + await page.locator("(//div[text()='Add to cart'])[1]").click(); + } + + async verifyAfterLoginPage() { + await page.waitForSelector(locators.username_text); + const visible = await page.isVisible(locators.username_text); + return expect(visible).to.equal(true); + } + + async verifyConfirmationMessage() { + const visible = await page.locator("//legend[@id='confirmation-message']").isVisible(); + return expect(visible).to.equal(true); + } +} + +module.exports = { CheckoutPage }; \ No newline at end of file diff --git a/playwright-cucumber-js/features/page-objects/home-page.js b/playwright-cucumber-js/features/page-objects/home-page.js new file mode 100644 index 0000000..7d5592f --- /dev/null +++ b/playwright-cucumber-js/features/page-objects/home-page.js @@ -0,0 +1,35 @@ +locators = { + "sign_in": "#signin", + "username_input": "#user-name", + "password_input": "#password", + "login_button": "#login-button", + "username_text": "//span[text()='fav_user']", + } + + class HomePage { + + async navigateToAutomate() { + return await page.goto(global.BASE_URL); + } + + async verifyHomePageIsDisplayed() { + return expect(await page.title()).to.equal('StackDemo'); + } + + async clickSignIn() { + const element = await page.waitForSelector(locators.sign_in); + await page.click(locators.sign_in); + } + + async clickProduct() { + await page.locator("(//div[text()='Add to cart'])[1]").click(); + } + + async verifyAfterLoginPage() { + await page.waitForSelector(locators.username_text); + const visible = await page.isVisible(locators.username_text); + return expect(visible).to.equal(true); + } + } + + module.exports = { HomePage }; \ No newline at end of file diff --git a/playwright-cucumber-js/features/page-objects/login-page.js b/playwright-cucumber-js/features/page-objects/login-page.js new file mode 100644 index 0000000..ea09e4c --- /dev/null +++ b/playwright-cucumber-js/features/page-objects/login-page.js @@ -0,0 +1,42 @@ +locators = { + "sign_in": "#signin", + "username_field": "#username", + "username_input": "//input[@id='react-select-2-input']", + "password_field": "#password", + "password_input": "//input[@id='react-select-3-input']", + "login_button": "#login-btn", + "username_text": "//span[text()='fav_user']" +} + +class LoginPage { + + async navigateToAutomate() { + return await page.goto(global.BASE_URL); + } + + async verifyHomePageIsDisplayed() { + return expect(await page.title()).to.equal('StackDemo'); + } + + async clickSignIn() { + const element = await page.waitForSelector(locators.sign_in); + await page.click(locators.sign_in); + } + + async submitLoginForm(username, password) { + const element = await page.waitForSelector(locators.username_field); + // Click Username field + await page.click(locators.username_field); + // Enter Username + await page.fill(locators.username_input, username); + await page.keyboard.press('Enter'); + // Click Password field + await page.click(locators.password_field); + await page.fill(locators.password_input, password); + await page.keyboard.press('Enter'); + // Click Login Button + await page.click(locators.login_button); + } +} + +module.exports = { LoginPage }; \ No newline at end of file diff --git a/playwright-cucumber-js/features/steps/assertions.js b/playwright-cucumber-js/features/steps/assertions.js new file mode 100644 index 0000000..0cdc387 --- /dev/null +++ b/playwright-cucumber-js/features/steps/assertions.js @@ -0,0 +1,4 @@ +const chai = require('chai'); +global.expect = chai.expect; +global.assert = chai.assert; +global.should = chai.should; \ No newline at end of file diff --git a/playwright-cucumber-js/features/steps/setup.js b/playwright-cucumber-js/features/steps/setup.js new file mode 100644 index 0000000..d45925c --- /dev/null +++ b/playwright-cucumber-js/features/steps/setup.js @@ -0,0 +1,51 @@ +const { setWorldConstructor, World, Before, After, Status, setDefaultTimeout } = require("@cucumber/cucumber"); +const { chromium, devices } = require('playwright') +const cp = require('child_process'); +const playwrightClientVersion = cp.execSync('npx playwright --version').toString().trim().split(' ')[1]; +setDefaultTimeout(120 * 1000) + +Before(async (scenario) => { + + const caps = { + 'os': 'os x', + 'os_version': 'big sur', + 'browser': 'chrome', // You can choose `chrome`, `edge` or `firefox` in this capability + 'browser_version': 'latest', // We support v83 and above. You can choose `latest`, `latest-beta`, `latest-1`, `latest-2` and so on, in this capability + // 'browser': 'playwright-webkit', // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit` + // 'name': 'Test on Playwright emulated iPhone 11 Pro', + 'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME', + 'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY', + 'project': 'PLAYWRIGHT-CUCUMBER-JS', + 'build': 'playwright-cucumber-build-1', + 'name': scenario.pickle.name, // The name of your test and build. See browserstack.com/docs/automate/playwright/organize tests for more details + 'buildTag': 'Regression', + // 'resolution': '1280x1024', + // 'browserstack.local': 'true', + // 'browserstack.localIdentifier': 'local_connection_name', + // 'browserstack.playwrightVersion': '1.latest', + // 'client.playwrightVersion': '1.latest' + }; + + + // Create page and browser globals to be used in the scenarios + global.browser = await chromium.connect({ + wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}`, + }) + + //const context = await global.browser.newContext({...devices['iPhone 11 Pro']}); + const context = await global.browser.newContext(); + global.page = await context.newPage(); +}) + +After(async () => { + await global.browser.close() +}) + +After(async (scenario) => { + if (scenario.result.status === Status.PASSED) { + await page.evaluate(_ => { }, `browserstack_executor: ${JSON.stringify({ action: 'setSessionStatus', arguments: { status: 'passed', reason: 'Test Passed' } })}`); + } + else if (scenario.result.status === Status.FAILED) { + await page.evaluate(_ => { }, `browserstack_executor: ${JSON.stringify({ action: 'setSessionStatus', arguments: { status: 'failed', reason: 'Test Failed' } })}`); + } +}); diff --git a/playwright-cucumber-js/features/steps/viewBrowserstack.js b/playwright-cucumber-js/features/steps/viewBrowserstack.js new file mode 100644 index 0000000..4b55257 --- /dev/null +++ b/playwright-cucumber-js/features/steps/viewBrowserstack.js @@ -0,0 +1,44 @@ +const { Given, When, Then } = require("@cucumber/cucumber"); +const { HomePage } = require('../page-objects/home-page') +const { LoginPage } = require('../page-objects/login-page') +const { CheckoutPage } = require('../page-objects/checkout-page') +const homePage = new HomePage(); +const loginPage = new LoginPage(); +const checkoutPage = new CheckoutPage(); + +Given("Open BrowserStack Demo website", { timeout: 60 * 1000 }, async function () { + await homePage.navigateToAutomate(); + await homePage.verifyHomePageIsDisplayed(); +}); + +Given('I SignIn as {string} with {string} password', async function (username, password) { + await homePage.clickSignIn(); + await loginPage.submitLoginForm(username, password); + await homePage.verifyAfterLoginPage(); +}); + +When("I add iPhone 12 to cart", async function () { + await homePage.clickProduct(); + // Click Checkout + await page.click("text=Checkout"); +}); + +When("I add the shipping address and submit the details", async function (dataTable) { + const userPromises = dataTable.hashes().map(async (element) => { + await checkoutPage.setUserDetails(element.FirstName, element.LastName, element.Address, element.State, element.PostalCode); + }); + + await Promise.all(userPromises); +}); + +Then("I should see product has been placed successfully", async function () { + await checkoutPage.clickSubmit(); + await wait(3000); + await checkoutPage.verifyConfirmationMessage(); +}); + +function wait(timeout) { + return new Promise((resolve) => { + setTimeout(resolve, timeout); + }); +} \ No newline at end of file diff --git a/playwright-cucumber-js/features/view-browserstack.feature b/playwright-cucumber-js/features/view-browserstack.feature new file mode 100644 index 0000000..4858542 --- /dev/null +++ b/playwright-cucumber-js/features/view-browserstack.feature @@ -0,0 +1,10 @@ +Feature: View BrowserStack Demo Site + + Scenario: Verify if User is able to place the Order + Given Open BrowserStack Demo website + And I SignIn as "fav_user" with "testingisfun99" password + When I add iPhone 12 to cart + And I add the shipping address and submit the details + | FirstName | LastName | Address | State | PostalCode | + | Demo | User | H.no 123 | Telangana | 500019 | + Then I should see product has been placed successfully \ No newline at end of file diff --git a/playwright-cucumber-js/package.json b/playwright-cucumber-js/package.json new file mode 100644 index 0000000..58c879c --- /dev/null +++ b/playwright-cucumber-js/package.json @@ -0,0 +1,19 @@ +{ + "name": "playwright-cucumber-js", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "./node_modules/.bin/cucumber-js --exit" + }, + "author": "", + "license": "ISC", + "dependencies": { + "@cucumber/cucumber": "^7.3.2", + "assert": "^2.0.0", + "playwright": "1.29.2" + }, + "devDependencies": { + "chai": "^4.3.7" + } +} From d79de418e87fed796c0c79f988afa10d2030ceca Mon Sep 17 00:00:00 2001 From: Rakesh Dasi Date: Tue, 6 Jun 2023 18:10:21 +0530 Subject: [PATCH 2/7] Restructured the Folders --- playwright-cucumber-js/.gitignore => .gitignore | 2 +- README.md | 7 ++----- .../features => features}/config/config.js | 0 .../features => features}/steps/assertions.js | 0 .../features => features}/steps/setup.js | 0 .../features => features}/steps/viewBrowserstack.js | 6 +++--- .../features => features}/view-browserstack.feature | 0 playwright-cucumber-js/package.json => package.json | 0 .../page-objects => page-objects}/checkout-page.js | 0 .../features/page-objects => page-objects}/home-page.js | 7 ++++--- .../features/page-objects => page-objects}/login-page.js | 4 ++-- 11 files changed, 12 insertions(+), 14 deletions(-) rename playwright-cucumber-js/.gitignore => .gitignore (99%) rename {playwright-cucumber-js/features => features}/config/config.js (100%) rename {playwright-cucumber-js/features => features}/steps/assertions.js (100%) rename {playwright-cucumber-js/features => features}/steps/setup.js (100%) rename {playwright-cucumber-js/features => features}/steps/viewBrowserstack.js (87%) rename {playwright-cucumber-js/features => features}/view-browserstack.feature (100%) rename playwright-cucumber-js/package.json => package.json (100%) rename {playwright-cucumber-js/features/page-objects => page-objects}/checkout-page.js (100%) rename {playwright-cucumber-js/features/page-objects => page-objects}/home-page.js (82%) rename {playwright-cucumber-js/features/page-objects => page-objects}/login-page.js (94%) diff --git a/playwright-cucumber-js/.gitignore b/.gitignore similarity index 99% rename from playwright-cucumber-js/.gitignore rename to .gitignore index 581af78..3679719 100644 --- a/playwright-cucumber-js/.gitignore +++ b/.gitignore @@ -108,4 +108,4 @@ dist .idea/ **/target/ -**/.DS_Store +**/.DS_Store \ No newline at end of file diff --git a/README.md b/README.md index 485f65f..79610be 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ Cucumber.js is a JavaScript-based open-source framework for web automation testing. It runs on Node.js and latest web browsers. Cucumber.js allows you to write and execute tests in Gherkin - a non-technical and human-readable language. +By default, Cucumber JS will automatically search for Step Definitions in the same folder as the feature files. + This repository provides an example setup for running Playwright tests with Cucumber.js on the BrowserStack cloud platform. ## Prerequisites @@ -22,11 +24,6 @@ git clone https://github.com/browserstack/cucumber-js-playwright-browserstack.gi 2. Install the dependencies by navigating to the project directory and running: -Navigate to the `playwright-cucumber-js` directory: - -```bash -cd playwright-cucumber-js -``` ```bash npm install diff --git a/playwright-cucumber-js/features/config/config.js b/features/config/config.js similarity index 100% rename from playwright-cucumber-js/features/config/config.js rename to features/config/config.js diff --git a/playwright-cucumber-js/features/steps/assertions.js b/features/steps/assertions.js similarity index 100% rename from playwright-cucumber-js/features/steps/assertions.js rename to features/steps/assertions.js diff --git a/playwright-cucumber-js/features/steps/setup.js b/features/steps/setup.js similarity index 100% rename from playwright-cucumber-js/features/steps/setup.js rename to features/steps/setup.js diff --git a/playwright-cucumber-js/features/steps/viewBrowserstack.js b/features/steps/viewBrowserstack.js similarity index 87% rename from playwright-cucumber-js/features/steps/viewBrowserstack.js rename to features/steps/viewBrowserstack.js index 4b55257..d299d6c 100644 --- a/playwright-cucumber-js/features/steps/viewBrowserstack.js +++ b/features/steps/viewBrowserstack.js @@ -1,7 +1,7 @@ const { Given, When, Then } = require("@cucumber/cucumber"); -const { HomePage } = require('../page-objects/home-page') -const { LoginPage } = require('../page-objects/login-page') -const { CheckoutPage } = require('../page-objects/checkout-page') +const { HomePage } = require('../../page-objects/home-page') +const { LoginPage } = require('../../page-objects/login-page') +const { CheckoutPage } = require('../../page-objects/checkout-page') const homePage = new HomePage(); const loginPage = new LoginPage(); const checkoutPage = new CheckoutPage(); diff --git a/playwright-cucumber-js/features/view-browserstack.feature b/features/view-browserstack.feature similarity index 100% rename from playwright-cucumber-js/features/view-browserstack.feature rename to features/view-browserstack.feature diff --git a/playwright-cucumber-js/package.json b/package.json similarity index 100% rename from playwright-cucumber-js/package.json rename to package.json diff --git a/playwright-cucumber-js/features/page-objects/checkout-page.js b/page-objects/checkout-page.js similarity index 100% rename from playwright-cucumber-js/features/page-objects/checkout-page.js rename to page-objects/checkout-page.js diff --git a/playwright-cucumber-js/features/page-objects/home-page.js b/page-objects/home-page.js similarity index 82% rename from playwright-cucumber-js/features/page-objects/home-page.js rename to page-objects/home-page.js index 7d5592f..8b87f81 100644 --- a/playwright-cucumber-js/features/page-objects/home-page.js +++ b/page-objects/home-page.js @@ -1,4 +1,4 @@ -locators = { +const locators = { "sign_in": "#signin", "username_input": "#user-name", "password_input": "#password", @@ -17,8 +17,9 @@ locators = { } async clickSignIn() { - const element = await page.waitForSelector(locators.sign_in); - await page.click(locators.sign_in); + const signInLocator = locators.sign_in; + const element = await page.waitForSelector(signInLocator); + await page.click(signInLocator); } async clickProduct() { diff --git a/playwright-cucumber-js/features/page-objects/login-page.js b/page-objects/login-page.js similarity index 94% rename from playwright-cucumber-js/features/page-objects/login-page.js rename to page-objects/login-page.js index ea09e4c..5f782f7 100644 --- a/playwright-cucumber-js/features/page-objects/login-page.js +++ b/page-objects/login-page.js @@ -1,4 +1,4 @@ -locators = { +const locators = { "sign_in": "#signin", "username_field": "#username", "username_input": "//input[@id='react-select-2-input']", @@ -23,7 +23,7 @@ class LoginPage { await page.click(locators.sign_in); } - async submitLoginForm(username, password) { + async submitLoginForm(username, password) { const element = await page.waitForSelector(locators.username_field); // Click Username field await page.click(locators.username_field); From 4027171d3e53fe82df015039d3e81bf9e24cd25a Mon Sep 17 00:00:00 2001 From: Rakesh Dasi Date: Fri, 30 Jun 2023 02:23:29 +0530 Subject: [PATCH 3/7] Updated Code to Execute Test in Parallel and to Enable Local Testing --- README.md | 19 ++--- features/config/config.js | 3 +- features/steps/setup.js | 92 +++++++++++++++++------- features/steps/viewBrowserstack.js | 4 ++ features/view-browserstack-local.feature | 6 ++ features/view-browserstack.feature | 12 ++++ package.json | 13 +++- page-objects/home-page.js | 52 +++++++------- 8 files changed, 141 insertions(+), 60 deletions(-) create mode 100644 features/view-browserstack-local.feature diff --git a/README.md b/README.md index 79610be..a7b8f34 100644 --- a/README.md +++ b/README.md @@ -38,18 +38,21 @@ BROWSERSTACK_ACCESS_KEY= Replace `` and `` with your BrowserStack username and access key, which you can obtain from the BrowserStack dashboard. -## Running the Tests - -To run the Playwright tests with Cucumber.js on BrowserStack, follow these steps: - -1. Update the `setup.js` file to configure the desired browsers, OS, and other capabilities for your test execution. -2. Run the tests using the following command: +## Execution +To run the tests in parallel with different browser configurations, use the following command: ```bash -npm run test +npm run test:parallel ``` +This command will execute the Cucumber.js tests in parallel on Chrome and Firefox browsers based on the configurations specified in the features/steps/viewBrowserstack.js file. -The command will execute the test suite defined in the `features` directory using the configurations specified in `browserstack.conf.js`. The test results will be displayed in the console output. +## Other Available Commands +```bash +npm run sample-local-test: Run a sample test using BrowserStack Local testing. +npm run sample-test: Run a sample test without BrowserStack Local testing. +npm run test:chrome: Run the tests only on Chrome. +npm run test:firefox: Run the tests only on Firefox. +``` ## Reporting diff --git a/features/config/config.js b/features/config/config.js index 641238a..f0f636c 100644 --- a/features/config/config.js +++ b/features/config/config.js @@ -1,3 +1,4 @@ Object.assign(global, { - BASE_URL: 'https://bstackdemo.com/' + BASE_URL: 'https://bstackdemo.com/', + LOCAL_URL: 'https://www.example.com/' }); \ No newline at end of file diff --git a/features/steps/setup.js b/features/steps/setup.js index d45925c..684350b 100644 --- a/features/steps/setup.js +++ b/features/steps/setup.js @@ -1,51 +1,93 @@ -const { setWorldConstructor, World, Before, After, Status, setDefaultTimeout } = require("@cucumber/cucumber"); -const { chromium, devices } = require('playwright') +const { setWorldConstructor, World, Before, After, Status, setDefaultTimeout } = require("@cucumber/cucumber"); +const { chromium, devices } = require('playwright'); const cp = require('child_process'); +const BrowserStackLocal = require('browserstack-local'); const playwrightClientVersion = cp.execSync('npx playwright --version').toString().trim().split(' ')[1]; -setDefaultTimeout(120 * 1000) +setDefaultTimeout(120 * 1000); + +const enableLocalTesting = true; // Set this flag to true to enable BrowserStack Local testing + +const browserConfigs = [ + { + browserName: 'chrome', + browserVersion: 'latest', + os: 'osx', + osVersion: 'big sur', + resolution: '1280x1024', + }, + { + browserName: 'playwright-firefox', + browserVersion: 'latest', + os: 'osx', + osVersion: 'big sur', + resolution: '1280x1024', + }, +]; + +const browserConnections = []; Before(async (scenario) => { + const browserConfig = browserConfigs[scenario.pickle.tags.indexOf('@browser')]; const caps = { - 'os': 'os x', - 'os_version': 'big sur', - 'browser': 'chrome', // You can choose `chrome`, `edge` or `firefox` in this capability - 'browser_version': 'latest', // We support v83 and above. You can choose `latest`, `latest-beta`, `latest-1`, `latest-2` and so on, in this capability - // 'browser': 'playwright-webkit', // allowed browsers are `chrome`, `edge`, `playwright-chromium`, `playwright-firefox` and `playwright-webkit` - // 'name': 'Test on Playwright emulated iPhone 11 Pro', + ...browserConfig, 'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME', - 'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY', + 'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY', 'project': 'PLAYWRIGHT-CUCUMBER-JS', 'build': 'playwright-cucumber-build-1', - 'name': scenario.pickle.name, // The name of your test and build. See browserstack.com/docs/automate/playwright/organize tests for more details + 'name': scenario.pickle.name, 'buildTag': 'Regression', - // 'resolution': '1280x1024', - // 'browserstack.local': 'true', - // 'browserstack.localIdentifier': 'local_connection_name', - // 'browserstack.playwrightVersion': '1.latest', - // 'client.playwrightVersion': '1.latest' + 'browserstack.playwrightVersion': '1.latest', + 'client.playwrightVersion': '1.latest' }; + if (enableLocalTesting && browserConnections.length === 0) { + const bsLocal = new BrowserStackLocal.Local(); + const bsLocalArgs = { + key: process.env.BROWSERSTACK_ACCESS_KEY, // Replace with your BrowserStack access key + localIdentifier: 'local_connection_name' // Replace with your desired local connection name + }; + + await new Promise((resolve, reject) => { + bsLocal.start(bsLocalArgs, (error) => { + if (error) { + console.error('Failed to start BrowserStack Local:', error); + reject(error); + } else { + console.log('BrowserStack Local started successfully'); + resolve(); + } + }); + }); + } // Create page and browser globals to be used in the scenarios - global.browser = await chromium.connect({ + const browser = await chromium.connect({ wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}`, - }) + }); - //const context = await global.browser.newContext({...devices['iPhone 11 Pro']}); - const context = await global.browser.newContext(); + const context = await browser.newContext(); global.page = await context.newPage(); -}) + + browserConnections.push(browser); +}); After(async () => { - await global.browser.close() -}) + await Promise.all(browserConnections.map(browser => browser.close())); +}); After(async (scenario) => { if (scenario.result.status === Status.PASSED) { await page.evaluate(_ => { }, `browserstack_executor: ${JSON.stringify({ action: 'setSessionStatus', arguments: { status: 'passed', reason: 'Test Passed' } })}`); - } - else if (scenario.result.status === Status.FAILED) { + } else if (scenario.result.status === Status.FAILED) { await page.evaluate(_ => { }, `browserstack_executor: ${JSON.stringify({ action: 'setSessionStatus', arguments: { status: 'failed', reason: 'Test Failed' } })}`); } }); + +setWorldConstructor(function () { + this.testCaseRetry = 2; // Set the number of retries for each test case +}); + +module.exports = { + parallel: 2, // Set the number of parallel test workers to the number of browsers +}; diff --git a/features/steps/viewBrowserstack.js b/features/steps/viewBrowserstack.js index d299d6c..6a130d4 100644 --- a/features/steps/viewBrowserstack.js +++ b/features/steps/viewBrowserstack.js @@ -11,6 +11,10 @@ Given("Open BrowserStack Demo website", { timeout: 60 * 1000 }, async function ( await homePage.verifyHomePageIsDisplayed(); }); +Given("Open local hosted website", { timeout: 60 * 1000 }, async function () { + await homePage.navigateToLocalWebsite(); +}); + Given('I SignIn as {string} with {string} password', async function (username, password) { await homePage.clickSignIn(); await loginPage.submitLoginForm(username, password); diff --git a/features/view-browserstack-local.feature b/features/view-browserstack-local.feature new file mode 100644 index 0000000..e62e174 --- /dev/null +++ b/features/view-browserstack-local.feature @@ -0,0 +1,6 @@ +Feature: Execute the Test in Local Environment + + @browser:1 + Scenario: Verify if User is able run on the local server + Given Open local hosted website + \ No newline at end of file diff --git a/features/view-browserstack.feature b/features/view-browserstack.feature index 4858542..b4e8cf8 100644 --- a/features/view-browserstack.feature +++ b/features/view-browserstack.feature @@ -1,6 +1,18 @@ Feature: View BrowserStack Demo Site + + Scenario: Verify if User is able to place the Order + Given Open BrowserStack Demo website + And I SignIn as "fav_user" with "testingisfun99" password + When I add iPhone 12 to cart + And I add the shipping address and submit the details + | FirstName | LastName | Address | State | PostalCode | + | Demo | User | H.no 123 | Telangana | 500019 | + Then I should see product has been placed successfully + + @browser:1 + Scenario: Verify if User is able to place the Order on Firefox Given Open BrowserStack Demo website And I SignIn as "fav_user" with "testingisfun99" password When I add iPhone 12 to cart diff --git a/package.json b/package.json index 58c879c..22616bc 100644 --- a/package.json +++ b/package.json @@ -4,16 +4,25 @@ "description": "", "main": "index.js", "scripts": { - "test": "./node_modules/.bin/cucumber-js --exit" + "test": "./node_modules/.bin/cucumber-js", + "sample-local-test": "npx cucumber-js ./features/view-browserstack-local.feature", + "sample-test": "npx cucumber-js ./features/view-browserstack.feature", + "test:parallel": "npm-run-all -p test:chrome test:firefox", + "parallel-test": "npx cucumber-parallel --features ./features/*.feature --require ./features/steps/viewBrowserstack.js", + "test:chrome": "cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 0}\"", + "test:firefox": "cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 1}\"" }, "author": "", "license": "ISC", "dependencies": { "@cucumber/cucumber": "^7.3.2", "assert": "^2.0.0", + "browserstack-local": "^1.5.3", + "cucumber": "^6.0.7", "playwright": "1.29.2" }, "devDependencies": { - "chai": "^4.3.7" + "chai": "^4.3.7", + "npm-run-all": "^4.1.5" } } diff --git a/page-objects/home-page.js b/page-objects/home-page.js index 8b87f81..4569ca5 100644 --- a/page-objects/home-page.js +++ b/page-objects/home-page.js @@ -1,36 +1,40 @@ const locators = { - "sign_in": "#signin", - "username_input": "#user-name", - "password_input": "#password", - "login_button": "#login-button", - "username_text": "//span[text()='fav_user']", - } - - class HomePage { - - async navigateToAutomate() { + "sign_in": "#signin", + "username_input": "#user-name", + "password_input": "#password", + "login_button": "#login-button", + "username_text": "//span[text()='fav_user']", +} + +class HomePage { + + async navigateToAutomate() { return await page.goto(global.BASE_URL); - } - - async verifyHomePageIsDisplayed() { + } + + async navigateToLocalWebsite() { + return await page.goto(global.LOCAL_URL); + } + + async verifyHomePageIsDisplayed() { return expect(await page.title()).to.equal('StackDemo'); - } - - async clickSignIn() { + } + + async clickSignIn() { const signInLocator = locators.sign_in; - const element = await page.waitForSelector(signInLocator); - await page.click(signInLocator); - } + const element = await page.waitForSelector(signInLocator); + await page.click(signInLocator); + } - async clickProduct() { + async clickProduct() { await page.locator("(//div[text()='Add to cart'])[1]").click(); } - async verifyAfterLoginPage() { + async verifyAfterLoginPage() { await page.waitForSelector(locators.username_text); const visible = await page.isVisible(locators.username_text); return expect(visible).to.equal(true); } - } - - module.exports = { HomePage }; \ No newline at end of file +} + +module.exports = { HomePage }; \ No newline at end of file From 8f9d07c011744fa0360ec665de909eb5e551bd6e Mon Sep 17 00:00:00 2001 From: Rakesh Dasi Date: Fri, 30 Jun 2023 02:38:42 +0530 Subject: [PATCH 4/7] Line spacing --- features/view-browserstack.feature | 2 -- 1 file changed, 2 deletions(-) diff --git a/features/view-browserstack.feature b/features/view-browserstack.feature index b4e8cf8..9d0b0b1 100644 --- a/features/view-browserstack.feature +++ b/features/view-browserstack.feature @@ -1,7 +1,5 @@ Feature: View BrowserStack Demo Site - - Scenario: Verify if User is able to place the Order Given Open BrowserStack Demo website And I SignIn as "fav_user" with "testingisfun99" password From b8c1402c028d26911387171c95c4acd18749958a Mon Sep 17 00:00:00 2001 From: Rakesh Dasi Date: Sun, 8 Oct 2023 02:06:29 +0530 Subject: [PATCH 5/7] Added YML --- browserstack.yml | 77 ++++++++++++++++++++++++++++++ features/steps/setup.js | 12 ++--- features/view-browserstack.feature | 3 +- package.json | 13 ++++- playwright.config.js | 10 ++++ 5 files changed, 106 insertions(+), 9 deletions(-) create mode 100644 browserstack.yml create mode 100644 playwright.config.js diff --git a/browserstack.yml b/browserstack.yml new file mode 100644 index 0000000..ea18d1f --- /dev/null +++ b/browserstack.yml @@ -0,0 +1,77 @@ +# ============================= +# Set BrowserStack Credentials +# ============================= +# Add your BrowserStack userName and accessKey here or set BROWSERSTACK_USERNAME and +# BROWSERSTACK_ACCESS_KEY as env variables +userName: rakeshdasi_bLnYJW +accessKey: cYRj9XTqzxqdBozK9DFf + +# ====================== +# 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 Samples +# 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 + +# ========================================== +# 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) +# browserStackLocalOptions: +# Options to be passed to BrowserStack local in-case of advanced configurations + # 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) +# CUSTOM_TAG_: # (Default: parent folder name of the test file) Custom tag for your test suite + +# 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/features/steps/setup.js b/features/steps/setup.js index 684350b..4c8e81d 100644 --- a/features/steps/setup.js +++ b/features/steps/setup.js @@ -11,15 +11,15 @@ const browserConfigs = [ { browserName: 'chrome', browserVersion: 'latest', - os: 'osx', - osVersion: 'big sur', + os: 'Windows', + osVersion: '10', resolution: '1280x1024', }, { - browserName: 'playwright-firefox', + browserName: 'chrome', browserVersion: 'latest', - os: 'osx', - osVersion: 'big sur', + os: 'Windows', + osVersion: '11', resolution: '1280x1024', }, ]; @@ -90,4 +90,4 @@ setWorldConstructor(function () { module.exports = { parallel: 2, // Set the number of parallel test workers to the number of browsers -}; +}; \ No newline at end of file diff --git a/features/view-browserstack.feature b/features/view-browserstack.feature index 9d0b0b1..d66e50d 100644 --- a/features/view-browserstack.feature +++ b/features/view-browserstack.feature @@ -1,5 +1,6 @@ Feature: View BrowserStack Demo Site + @chrome Scenario: Verify if User is able to place the Order Given Open BrowserStack Demo website And I SignIn as "fav_user" with "testingisfun99" password @@ -9,7 +10,7 @@ Feature: View BrowserStack Demo Site | Demo | User | H.no 123 | Telangana | 500019 | Then I should see product has been placed successfully - @browser:1 + @playwright-firefox Scenario: Verify if User is able to place the Order on Firefox Given Open BrowserStack Demo website And I SignIn as "fav_user" with "testingisfun99" password diff --git a/package.json b/package.json index 22616bc..a2ca6a9 100644 --- a/package.json +++ b/package.json @@ -6,11 +6,17 @@ "scripts": { "test": "./node_modules/.bin/cucumber-js", "sample-local-test": "npx cucumber-js ./features/view-browserstack-local.feature", - "sample-test": "npx cucumber-js ./features/view-browserstack.feature", + "sample-test": "concurrently \"npx cucumber-js ./features/view-browserstack.feature --tags '@chrome'\" \"npx cucumber-js ./features/view-browserstack.feature --tags '@playwright-firefox'\"", "test:parallel": "npm-run-all -p test:chrome test:firefox", "parallel-test": "npx cucumber-parallel --features ./features/*.feature --require ./features/steps/viewBrowserstack.js", "test:chrome": "cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 0}\"", - "test:firefox": "cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 1}\"" + "test:firefox": "cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 1}\"", + "postinstall": "npm update browserstack-node-sdk", + "test-browserstack": "browserstack-node-sdk ./node_modules/.bin/cucumber-js", + "sample-local-test-browserstack": "npx browserstack-node-sdk cucumber-js ./features/view-browserstack-local.feature", + "sample-test-browserstack": "npx browserstack-node-sdk cucumber-js ./features/view-browserstack.feature", + "test:chrome-browserstack": "browserstack-node-sdk cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 0}\"", + "test:firefox-browserstack": "browserstack-node-sdk cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 1}\"" }, "author": "", "license": "ISC", @@ -19,10 +25,13 @@ "assert": "^2.0.0", "browserstack-local": "^1.5.3", "cucumber": "^6.0.7", + "cucumber-parallel": "^2.0.3", "playwright": "1.29.2" }, "devDependencies": { + "browserstack-node-sdk": "^1.28.0", "chai": "^4.3.7", + "concurrently": "^8.2.1", "npm-run-all": "^4.1.5" } } diff --git a/playwright.config.js b/playwright.config.js new file mode 100644 index 0000000..cac63ad --- /dev/null +++ b/playwright.config.js @@ -0,0 +1,10 @@ +const { devices } = require('@playwright/test'); + +module.exports = { + projects: [ + { + name: 'desktop', + use: { ...devices['Desktop 1920x1080'], channel: 'chrome' }, + }, + ], +}; From 89f8d6e10f0c1b6daa0db1af39bbaff3d7da7520 Mon Sep 17 00:00:00 2001 From: Rakesh Dasi Date: Tue, 17 Oct 2023 22:19:45 +0530 Subject: [PATCH 6/7] Updated the Setup FIle Updated the Setup FIle --- features/steps/setup.js | 99 +++++++++++++++++------------- features/view-browserstack.feature | 4 +- package.json | 2 +- 3 files changed, 60 insertions(+), 45 deletions(-) diff --git a/features/steps/setup.js b/features/steps/setup.js index 4c8e81d..9dd8eb4 100644 --- a/features/steps/setup.js +++ b/features/steps/setup.js @@ -5,71 +5,86 @@ const BrowserStackLocal = require('browserstack-local'); const playwrightClientVersion = cp.execSync('npx playwright --version').toString().trim().split(' ')[1]; setDefaultTimeout(120 * 1000); -const enableLocalTesting = true; // Set this flag to true to enable BrowserStack Local testing +const enableLocalTesting = false; // Set this flag to true to enable BrowserStack Local testing const browserConfigs = [ + { browserName: 'chrome', + browserTagName: '@chrome', browserVersion: 'latest', - os: 'Windows', - osVersion: '10', + os: 'OS X', + osVersion: 'Monterey', resolution: '1280x1024', }, { - browserName: 'chrome', + browserName: 'playwright-firefox', + browserTagName: '@playwright-firefox', browserVersion: 'latest', os: 'Windows', osVersion: '11', resolution: '1280x1024', }, + { + browserName: 'edge', + browserTagName: '@edge', + browserVersion: 'latest', + os: 'OS X', + osVersion: 'Ventura', + resolution: '1280x1024', + }, ]; const browserConnections = []; Before(async (scenario) => { - const browserConfig = browserConfigs[scenario.pickle.tags.indexOf('@browser')]; + const tagName = scenario.pickle.tags[0].name; + const filteredBrowserConfigs = browserConfigs.filter(config => config.browserTagName === tagName); - const caps = { - ...browserConfig, - 'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME', - 'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY', - 'project': 'PLAYWRIGHT-CUCUMBER-JS', - 'build': 'playwright-cucumber-build-1', - 'name': scenario.pickle.name, - 'buildTag': 'Regression', - 'browserstack.playwrightVersion': '1.latest', - 'client.playwrightVersion': '1.latest' - }; - - if (enableLocalTesting && browserConnections.length === 0) { - const bsLocal = new BrowserStackLocal.Local(); - const bsLocalArgs = { - key: process.env.BROWSERSTACK_ACCESS_KEY, // Replace with your BrowserStack access key - localIdentifier: 'local_connection_name' // Replace with your desired local connection name + for (const browserConfig of filteredBrowserConfigs) { + const caps = { + ...browserConfig, + 'browserstack.username': process.env.BROWSERSTACK_USERNAME || 'YOUR_USERNAME', + 'browserstack.accessKey': process.env.BROWSERSTACK_ACCESS_KEY || 'YOUR_ACCESS_KEY', + 'project': 'PLAYWRIGHT-CUCUMBER-JS', + 'build': 'playwright-cucumber-build-1', + 'name': scenario.pickle.name, + 'buildTag': 'Regression', + 'browserstack.playwrightVersion': '1.latest', + 'client.playwrightVersion': '1.latest' }; - - await new Promise((resolve, reject) => { - bsLocal.start(bsLocalArgs, (error) => { - if (error) { - console.error('Failed to start BrowserStack Local:', error); - reject(error); - } else { - console.log('BrowserStack Local started successfully'); - resolve(); - } + + console.log('enableLocalTesting', enableLocalTesting); + if (enableLocalTesting && browserConnections.length === 0) { + const bsLocal = new BrowserStackLocal.Local(); + const bsLocalArgs = { + key: process.env.BROWSERSTACK_ACCESS_KEY, // Replace with your BrowserStack access key + localIdentifier: 'local_connection_name' // Replace with your desired local connection name + }; + + await new Promise((resolve, reject) => { + bsLocal.start(bsLocalArgs, (error) => { + if (error) { + console.error('Failed to start BrowserStack Local:', error); + reject(error); + } else { + console.log('BrowserStack Local started successfully'); + resolve(); + } + }); }); + } + + // Create page and browser globals to be used in the scenarios + const browser = await chromium.connect({ + wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}`, }); + + const context = await browser.newContext(); + global.page = await context.newPage(); + + browserConnections.push(browser); } - - // Create page and browser globals to be used in the scenarios - const browser = await chromium.connect({ - wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify(caps))}`, - }); - - const context = await browser.newContext(); - global.page = await context.newPage(); - - browserConnections.push(browser); }); After(async () => { diff --git a/features/view-browserstack.feature b/features/view-browserstack.feature index d66e50d..16a0c46 100644 --- a/features/view-browserstack.feature +++ b/features/view-browserstack.feature @@ -10,8 +10,8 @@ Feature: View BrowserStack Demo Site | Demo | User | H.no 123 | Telangana | 500019 | Then I should see product has been placed successfully - @playwright-firefox - Scenario: Verify if User is able to place the Order on Firefox + @edge + Scenario: Verify if User is able to place the Order on Edge Given Open BrowserStack Demo website And I SignIn as "fav_user" with "testingisfun99" password When I add iPhone 12 to cart diff --git a/package.json b/package.json index a2ca6a9..3da8281 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "test": "./node_modules/.bin/cucumber-js", "sample-local-test": "npx cucumber-js ./features/view-browserstack-local.feature", - "sample-test": "concurrently \"npx cucumber-js ./features/view-browserstack.feature --tags '@chrome'\" \"npx cucumber-js ./features/view-browserstack.feature --tags '@playwright-firefox'\"", + "sample-test": "npx cucumber-js ./features/view-browserstack.feature", "test:parallel": "npm-run-all -p test:chrome test:firefox", "parallel-test": "npx cucumber-parallel --features ./features/*.feature --require ./features/steps/viewBrowserstack.js", "test:chrome": "cucumber-js --world-parameters \"{\\\"browserConfigIndex\\\": 0}\"", From 922263e5c4aaf3f429e6cc1a515deca1d842dd71 Mon Sep 17 00:00:00 2001 From: Rakesh Dasi Date: Thu, 19 Oct 2023 14:40:44 +0530 Subject: [PATCH 7/7] Updated the ReadMe File --- README.md | 18 +++++++---- browserstack.yml | 77 -------------------------------------------- playwright.config.js | 10 ------ 3 files changed, 11 insertions(+), 94 deletions(-) delete mode 100644 browserstack.yml delete mode 100644 playwright.config.js diff --git a/README.md b/README.md index a7b8f34..42e7b54 100644 --- a/README.md +++ b/README.md @@ -38,20 +38,24 @@ BROWSERSTACK_ACCESS_KEY= Replace `` and `` with your BrowserStack username and access key, which you can obtain from the BrowserStack dashboard. +## Browserstack Configuration +To view and update the Browser-OS combinations, please refer to the "features/steps/setup.js" file. + ## Execution To run the tests in parallel with different browser configurations, use the following command: +## Running your Tests: +To run a sample Test, run + ```bash -npm run test:parallel +npm run sample-test ``` -This command will execute the Cucumber.js tests in parallel on Chrome and Firefox browsers based on the configurations specified in the features/steps/viewBrowserstack.js file. +This command will execute the Cucumber.js tests in parallel on Chrome and Edge browsers based on the configurations specified in the "features/steps/setup.js" file.` + +## Run Test on Locally hosted Websites -## Other Available Commands ```bash -npm run sample-local-test: Run a sample test using BrowserStack Local testing. -npm run sample-test: Run a sample test without BrowserStack Local testing. -npm run test:chrome: Run the tests only on Chrome. -npm run test:firefox: Run the tests only on Firefox. +npm sample-local-test ``` ## Reporting diff --git a/browserstack.yml b/browserstack.yml deleted file mode 100644 index ea18d1f..0000000 --- a/browserstack.yml +++ /dev/null @@ -1,77 +0,0 @@ -# ============================= -# Set BrowserStack Credentials -# ============================= -# Add your BrowserStack userName and accessKey here or set BROWSERSTACK_USERNAME and -# BROWSERSTACK_ACCESS_KEY as env variables -userName: rakeshdasi_bLnYJW -accessKey: cYRj9XTqzxqdBozK9DFf - -# ====================== -# 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 Samples -# 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 - -# ========================================== -# 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) -# browserStackLocalOptions: -# Options to be passed to BrowserStack local in-case of advanced configurations - # 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) -# CUSTOM_TAG_: # (Default: parent folder name of the test file) Custom tag for your test suite - -# 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/playwright.config.js b/playwright.config.js deleted file mode 100644 index cac63ad..0000000 --- a/playwright.config.js +++ /dev/null @@ -1,10 +0,0 @@ -const { devices } = require('@playwright/test'); - -module.exports = { - projects: [ - { - name: 'desktop', - use: { ...devices['Desktop 1920x1080'], channel: 'chrome' }, - }, - ], -};