From abb7f645930aeb5e92efe643e82080897ac16448 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Thu, 22 Dec 2022 19:39:38 +0530 Subject: [PATCH 01/23] add: sdk flow for pytest sample repo --- .browserstack | 3 -- .gitignore | 1 + README.md | 28 +++++++++-------- browserstack.yml | 75 ++++++++++++++++++++++++++++++++++++++++++++ config/local.json | 24 -------------- config/sample.json | 38 ---------------------- conftest.py | 41 ------------------------ pavement.py | 37 ---------------------- requirements.txt | 4 +-- tests/test_local.py | 10 ++---- tests/test_sample.py | 9 ++---- 11 files changed, 97 insertions(+), 173 deletions(-) delete mode 100644 .browserstack create mode 100644 browserstack.yml delete mode 100644 config/local.json delete mode 100644 config/sample.json delete mode 100644 conftest.py delete mode 100644 pavement.py diff --git a/.browserstack b/.browserstack deleted file mode 100644 index 2eb6b4b..0000000 --- a/.browserstack +++ /dev/null @@ -1,3 +0,0 @@ -[credentials] -username = BROWSERSTACK_USERNAME -key = BROWSERSTACK_ACCESS_KEY diff --git a/.gitignore b/.gitignore index 59d19f7..c723d19 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ __pycache__ .pytest_cache local.log +env diff --git a/README.md b/README.md index 59795ee..8b078e9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PyTest with Browserstack -PyTest Integration with BrowserStack. +PyTest Integration with BrowserStack using SDK. ![BrowserStack Logo](https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780) ## Prerequisite @@ -8,19 +8,21 @@ PyTest Integration with BrowserStack. ## Setup -* Clone the repo +* Clone the repo with `git clone -b sdk https://github.com/browserstack/pytest-browserstack.git` * Install dependencies `pip install -r requirements.txt` -* To run your automated tests using BrowserStack, you must provide a valid username and access key. This can be done either by using a .browserstack configuration file in the working directory or your home directory, by setting the BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY environment variables, or by adding user & key to config file. - - -## Run tests on locally hosted websites -* To run a local test, (if you have not set the BROWSERSTACK_ACCESS_KEY environment variable) first go to config/local.json then edit key on line 3 -* Run `paver run local` - -## Run sample tests -* To run parallel tests, run `paver run sample` - - Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github) +* To run your automated tests using BrowserStack, you must provide a valid username and access key. This can be done either by providing your username and access key in the `browserstack.yml` configuration file, or by setting the `BROWSERSTACK_USERNAME` and `BROWSERSTACK_ACCESS_KEY` environment variables. + +## Run sample test in parallel: +* To run the sample test across platforms defined in the configuration file run: +``` + browserstack-sdk pytest -s tests/test_sample.py +``` + +## Run a sample local test: +* To run the sample local test across platforms defined in the configuration file, you just need to set `browserstackLocal` key as true in the `browserstack.yml` file and run: +``` + browserstack-sdk pytest -s tests/test_local.py +``` ## Notes * You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate) diff --git a/browserstack.yml b/browserstack.yml new file mode 100644 index 0000000..18d9510 --- /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 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} +# Set `framework` of your test suite. Example, `testng`, `cucumber`, `cucumber-testng` +# This property is needed to send test context to BrowserStack (test name, status) +framework: pytest + +# ======================================= +# 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) diff --git a/config/local.json b/config/local.json deleted file mode 100644 index e490cb8..0000000 --- a/config/local.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "user": "BROWSERSTACK_USERNAME", - "key": "BROWSERSTACK_ACCESS_KEY", - "capabilities": { - "bstack:options": { - "projectName": "Pytest Browserstack", - "buildName": "browserstack-build-1", - "sessionName": "BStack local pytest", - "local": true, - "debug": "true", - "networkLogs": "true" - } - }, - "environments": [ - { - "bstack:options": { - "os": "Windows", - "osVersion": "11" - }, - "browserName": "chrome", - "browserVersion": "latest" - } - ] -} diff --git a/config/sample.json b/config/sample.json deleted file mode 100644 index 2bfb4ab..0000000 --- a/config/sample.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "user": "BROWSERSTACK_USERNAME", - "key": "BROWSERSTACK_ACCESS_KEY", - "capabilities": { - "bstack:options": { - "projectName": "Pytest Browserstack", - "buildName": "browserstack-build-1", - "sessionName": "BStack sample pytest", - "local": false, - "debug": "true", - "networkLogs": "true" - } - }, - "environments": [ - { - "bstack:options": { - "os": "Windows", - "osVersion": "11" - }, - "browserName": "chrome", - "browserVersion": "latest" - }, - { - "bstack:options": { - "os": "OS X", - "osVersion": "Monterey" - }, - "browserName": "firefox", - "browserVersion": "latest" - }, - { - "bstack:options": { - "osVersion": "10.0", - "deviceName": "Samsung Galaxy S20" - } - } - ] -} diff --git a/conftest.py b/conftest.py deleted file mode 100644 index 821e950..0000000 --- a/conftest.py +++ /dev/null @@ -1,41 +0,0 @@ -import pytest -from browserstack.local import Local -import os, json -from jsonmerge import merge -CONFIG_FILE = os.environ['CONFIG_FILE'] if 'CONFIG_FILE' in os.environ else 'config/single.json' -TASK_ID = int(os.environ['TASK_ID']) if 'TASK_ID' in os.environ else 0 - -with open(CONFIG_FILE) as data_file: - CONFIG = json.load(data_file) - -bs_local = None - -BROWSERSTACK_USERNAME = os.environ['BROWSERSTACK_USERNAME'] if 'BROWSERSTACK_USERNAME' in os.environ else CONFIG["user"] -BROWSERSTACK_ACCESS_KEY = os.environ['BROWSERSTACK_ACCESS_KEY'] if 'BROWSERSTACK_ACCESS_KEY' in os.environ else CONFIG["key"] - -def start_local(): - """Code to start browserstack local before start of test.""" - global bs_local - bs_local = Local() - bs_local_args = { "key": BROWSERSTACK_ACCESS_KEY or "access_key", "forcelocal": "true" } - bs_local.start(**bs_local_args) - -def stop_local(): - """Code to stop browserstack local after end of test.""" - global bs_local - if bs_local is not None: - bs_local.stop() - -@pytest.fixture(scope='session') -def session_capabilities(): - capabilities = merge(CONFIG['environments'][TASK_ID],CONFIG["capabilities"]) - capabilities['bstack:options']['userName'] = BROWSERSTACK_USERNAME - capabilities['bstack:options']['accessKey'] = BROWSERSTACK_ACCESS_KEY - capabilities['bstack:options']['source'] = 'pytest:sample-main:v1.0' - if "local" in capabilities['bstack:options'] and capabilities['bstack:options']['local']: - start_local() - return capabilities - - -def pytest_sessionfinish(session, exitstatus): - stop_local() diff --git a/pavement.py b/pavement.py deleted file mode 100644 index 3accb7c..0000000 --- a/pavement.py +++ /dev/null @@ -1,37 +0,0 @@ -from paver.easy import * -from paver.setuputils import setup -from multiprocess import Process -import platform -import json - -setup( - name = "pytest-browserstack", - version = "0.1.0", - author = "BrowserStack", - author_email = "support@browserstack.com", - description = ("PyTest Integration with BrowserStack"), - license = "MIT", - keywords = "example selenium browserstack", - url = "https://github.com/browserstack/pytest-browserstack", - packages=['tests'] -) - -def run_py_test(config, task_id=0): - if platform.system() == "Windows": - sh('cmd /C "set CONFIG_FILE=config/%s.json && set TASK_ID=%s && pytest -s tests/test_%s.py --driver Browserstack"' % (config, task_id, config)) - else: - sh('CONFIG_FILE=config/%s.json TASK_ID=%s pytest -s tests/test_%s.py --driver Browserstack' % (config, task_id, config)) - -@task -@consume_nargs(1) -def run(args): - """Run single, local and parallel test using different config.""" - jobs = [] - config_file = 'config/%s.json' % (args[0]) - with open(config_file) as data_file: - CONFIG = json.load(data_file) - environments = CONFIG['environments'] - for i in range(len(environments)): - p = Process(target=run_py_test, args=(args[0], i)) - jobs.append(p) - p.start() diff --git a/requirements.txt b/requirements.txt index 8acdc13..e0085e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,8 @@ browserstack-local jsonmerge -multiprocess -paver selenium==4.* psutil pytest pytest-variables pytest-selenium -pytest-xdist +browserstack-sdk diff --git a/tests/test_local.py b/tests/test_local.py index 5d4d72f..2e76538 100644 --- a/tests/test_local.py +++ b/tests/test_local.py @@ -1,10 +1,6 @@ import pytest -from selenium.webdriver.common.by import By def test_local(selenium): - selenium.get('http://bs-local.com:45691/check') - - if selenium.find_element(By.CSS_SELECTOR, 'body').text == 'Up and running': - selenium.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"passed","reason": "Local is Running"}}') - else: - selenium.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"failed","reason": "Local is Not Running"}}') + selenium.get('http://bs-local.com:45454') + local_page_title = selenium.title + assert local_page_title == 'BrowserStack Local' diff --git a/tests/test_sample.py b/tests/test_sample.py index 7ba9692..3a21d93 100644 --- a/tests/test_sample.py +++ b/tests/test_sample.py @@ -1,5 +1,3 @@ -from browserstack.local import Local -from selenium import webdriver import pytest from selenium.webdriver.common.by import By @@ -18,8 +16,5 @@ def test_example(selenium): # locating product in cart and getting name of the product in cart productCartText = selenium.find_element(By.XPATH, '//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]').text - # checking whether product has been added to cart by comparing product name and marking test pass or fail - if productText == productCartText: - selenium.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"passed","reason": "Test Passed Successfully"}}') - else: - selenium.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"failed","reason": "Product added to the cart not same as selected"}}') + # checking whether product has been added to cart by comparing product name + assert productCartText == productText From bfbaa0a5eb55dd5ca10c3f00fdb91fe9370debbe Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Wed, 28 Dec 2022 14:46:34 +0530 Subject: [PATCH 02/23] chore: restructure files --- tests/{test_local.py => local-test.py} | 0 tests/{test_sample.py => test.py} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/{test_local.py => local-test.py} (100%) rename tests/{test_sample.py => test.py} (100%) diff --git a/tests/test_local.py b/tests/local-test.py similarity index 100% rename from tests/test_local.py rename to tests/local-test.py diff --git a/tests/test_sample.py b/tests/test.py similarity index 100% rename from tests/test_sample.py rename to tests/test.py From c30436ff39c0e10d4c8be043f13b16c376acc992 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Wed, 28 Dec 2022 14:48:29 +0530 Subject: [PATCH 03/23] update: readme run commands --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8b078e9..efd7dbc 100644 --- a/README.md +++ b/README.md @@ -9,19 +9,25 @@ PyTest Integration with BrowserStack using SDK. ## Setup * Clone the repo with `git clone -b sdk https://github.com/browserstack/pytest-browserstack.git` +* It is recommended to use a virtual environment to install dependencies. To create a virtual environment: + ``` + python3 -m venv env + source env/bin/activate # on Mac + env\Scripts\activate # on Windows + ``` * Install dependencies `pip install -r requirements.txt` * To run your automated tests using BrowserStack, you must provide a valid username and access key. This can be done either by providing your username and access key in the `browserstack.yml` configuration file, or by setting the `BROWSERSTACK_USERNAME` and `BROWSERSTACK_ACCESS_KEY` environment variables. ## Run sample test in parallel: * To run the sample test across platforms defined in the configuration file run: ``` - browserstack-sdk pytest -s tests/test_sample.py + browserstack-sdk pytest -s tests/test.py ``` ## Run a sample local test: * To run the sample local test across platforms defined in the configuration file, you just need to set `browserstackLocal` key as true in the `browserstack.yml` file and run: ``` - browserstack-sdk pytest -s tests/test_local.py + browserstack-sdk pytest -s tests/local-test.py ``` ## Notes From 48df04d8d6eaea64da97d553c1ddbd04c80556f2 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Mon, 9 Jan 2023 13:53:04 +0530 Subject: [PATCH 04/23] chore: add source --- browserstack.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/browserstack.yml b/browserstack.yml index 18d9510..4e9667f 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -66,6 +66,8 @@ browserstackLocal: true # (Default false) # 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 +source: pytest-browserstack:sample-sdk:v1.0 + # =================== # Debugging features # =================== From 2349b8629c49d9e301d0934e92d126fc8ec24d2f Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Mon, 10 Apr 2023 18:20:32 +0530 Subject: [PATCH 05/23] Added github action --- .github/CODEOWNERS | 1 + .github/workflows/reviewing_changes.yml | 88 +++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/workflows/reviewing_changes.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..8f0fab7 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +.github/workflows/*.yml @browserstack/asi-devs diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml new file mode 100644 index 0000000..6f46d3f --- /dev/null +++ b/.github/workflows/reviewing_changes.yml @@ -0,0 +1,88 @@ +# This job is to test different profiles in sdk branch against Pull Requests raised +# This workflow targets pytest + +name: Pytest Test workflow for Python from workflow_dispatch + +on: + workflow_dispatch: + inputs: + pull_request_number: + description: 'The pull request number to build' + required: true + +jobs: + comment-run: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + max-parallel: 3 + matrix: + python: ['3.7', '3.10', '3.11'] + os: [ macos-latest, windows-latest, ubuntu-latest ] + name: Pytest Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + env: + BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} + BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} + + steps: + - uses: actions/checkout@v3 + with: + ref: refs/pull/${{ github.event.inputs.pull_request_number }}/head + - name: Fetch Commit SHA + run: | + git log -1 --format='%H' + echo "commit_sha=$(git log -1 --format='%H')" >> $GITHUB_ENV + echo "commit_sha=$(git log -1 --format='%H')" >> $env:GITHUB_ENV + - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 + id: status-check-in-progress + env: + job_name: Pytest Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + with: + github-token: ${{ github.token }} + script: | + const result = await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: process.env.job_name, + head_sha: process.env.commit_sha, + status: 'in_progress' + }).catch((err) => ({status: err.status, response: err.response})); + console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) + if (result.status !== 201) { + console.log('Failed to create check run') + } + - name: Setup python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python }} + + - name: Install dependencies + run: python -m pip install -r requirements.txt + + - name: run tests in parallel + run: browserstack-sdk pytest -s tests/test.py + + - name: run local tests in parallel + run: browserstack-sdk pytest -s tests/local-test.py + + - if: always() + uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 + id: status-check-completed + env: + conclusion: ${{ job.status }} + job_name: Pytest Repo ${{ matrix.python }} - ${{ matrix.os }} Sample + with: + github-token: ${{ github.token }} + script: | + const result = await github.rest.checks.create({ + owner: context.repo.owner, + repo: context.repo.repo, + name: process.env.job_name, + head_sha: process.env.commit_sha, + status: 'completed', + conclusion: process.env.conclusion + }).catch((err) => ({status: err.status, response: err.response})); + console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) + if (result.status !== 201) { + console.log('Failed to create check run') + } From f3f1a8fe63681460c9005bb0f836a937d247bb17 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Tue, 11 Apr 2023 10:59:19 +0530 Subject: [PATCH 06/23] fix codeowners --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8f0fab7..7e1f1b4 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -.github/workflows/*.yml @browserstack/asi-devs +.github/* @browserstack/asi-devs From 70eee2111a82f1d5eb737dd415ffa12904c88cb4 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Tue, 11 Apr 2023 12:58:25 +0530 Subject: [PATCH 07/23] fix name in workflow file --- .github/workflows/reviewing_changes.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml index 6f46d3f..8f96a40 100644 --- a/.github/workflows/reviewing_changes.yml +++ b/.github/workflows/reviewing_changes.yml @@ -1,7 +1,7 @@ # This job is to test different profiles in sdk branch against Pull Requests raised # This workflow targets pytest -name: Pytest Test workflow for Python from workflow_dispatch +name: Python SDK Test workflow on workflow_dispatch on: workflow_dispatch: From b49db5b47d6133730919197c498fc9ac8dce759c Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Thu, 13 Apr 2023 13:43:56 +0530 Subject: [PATCH 08/23] Test --- browserstack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browserstack.yml b/browserstack.yml index 4e9667f..d3b0199 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -13,7 +13,7 @@ accessKey: YOUR_ACCESS_KEY # 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 +buildName: test pytest # `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 From 0029786fbafdc555353a7498d19bd9d3e16110b5 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Mon, 19 Jun 2023 12:57:01 +0530 Subject: [PATCH 09/23] Added bstack to file names --- README.md | 4 ++-- tests/local-test.py | 6 ------ tests/test.py | 20 -------------------- 3 files changed, 2 insertions(+), 28 deletions(-) delete mode 100644 tests/local-test.py delete mode 100644 tests/test.py diff --git a/README.md b/README.md index efd7dbc..a016396 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,13 @@ PyTest Integration with BrowserStack using SDK. ## Run sample test in parallel: * To run the sample test across platforms defined in the configuration file run: ``` - browserstack-sdk pytest -s tests/test.py + browserstack-sdk pytest -s tests/bstack-sample-test.py ``` ## Run a sample local test: * To run the sample local test across platforms defined in the configuration file, you just need to set `browserstackLocal` key as true in the `browserstack.yml` file and run: ``` - browserstack-sdk pytest -s tests/local-test.py + browserstack-sdk pytest -s tests/bstack-local-test.py ``` ## Notes diff --git a/tests/local-test.py b/tests/local-test.py deleted file mode 100644 index 2e76538..0000000 --- a/tests/local-test.py +++ /dev/null @@ -1,6 +0,0 @@ -import pytest - -def test_local(selenium): - selenium.get('http://bs-local.com:45454') - local_page_title = selenium.title - assert local_page_title == 'BrowserStack Local' diff --git a/tests/test.py b/tests/test.py deleted file mode 100644 index 3a21d93..0000000 --- a/tests/test.py +++ /dev/null @@ -1,20 +0,0 @@ -import pytest -from selenium.webdriver.common.by import By - -def test_example(selenium): - selenium.get('https://bstackdemo.com/') - - # locating product on webpage and getting name of the product - productText = selenium.find_element(By.XPATH, '//*[@id="1"]/p').text - - # clicking the 'Add to cart' button - selenium.find_element(By.XPATH, '//*[@id="1"]/div[4]').click() - - # waiting until the Cart pane has been displayed on the webpage - selenium.find_element(By.CLASS_NAME, 'float-cart__content') - - # locating product in cart and getting name of the product in cart - productCartText = selenium.find_element(By.XPATH, '//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]').text - - # checking whether product has been added to cart by comparing product name - assert productCartText == productText From 9fef37def0b1197c3c6e4d1643f0f77aad24ffba Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Mon, 19 Jun 2023 12:57:38 +0530 Subject: [PATCH 10/23] Added bstack to file names --- tests/bstack-local-test.py | 6 ++++++ tests/bstack-sample-test.py | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 tests/bstack-local-test.py create mode 100644 tests/bstack-sample-test.py diff --git a/tests/bstack-local-test.py b/tests/bstack-local-test.py new file mode 100644 index 0000000..2e76538 --- /dev/null +++ b/tests/bstack-local-test.py @@ -0,0 +1,6 @@ +import pytest + +def test_local(selenium): + selenium.get('http://bs-local.com:45454') + local_page_title = selenium.title + assert local_page_title == 'BrowserStack Local' diff --git a/tests/bstack-sample-test.py b/tests/bstack-sample-test.py new file mode 100644 index 0000000..3a21d93 --- /dev/null +++ b/tests/bstack-sample-test.py @@ -0,0 +1,20 @@ +import pytest +from selenium.webdriver.common.by import By + +def test_example(selenium): + selenium.get('https://bstackdemo.com/') + + # locating product on webpage and getting name of the product + productText = selenium.find_element(By.XPATH, '//*[@id="1"]/p').text + + # clicking the 'Add to cart' button + selenium.find_element(By.XPATH, '//*[@id="1"]/div[4]').click() + + # waiting until the Cart pane has been displayed on the webpage + selenium.find_element(By.CLASS_NAME, 'float-cart__content') + + # locating product in cart and getting name of the product in cart + productCartText = selenium.find_element(By.XPATH, '//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]').text + + # checking whether product has been added to cart by comparing product name + assert productCartText == productText From 0d72120787c82d3f00f3cc8a6d3c7b6591549ac6 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Tue, 20 Jun 2023 11:57:59 +0530 Subject: [PATCH 11/23] Small fix --- browserstack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/browserstack.yml b/browserstack.yml index d3b0199..fa0c5b6 100644 --- a/browserstack.yml +++ b/browserstack.yml @@ -13,7 +13,7 @@ accessKey: YOUR_ACCESS_KEY # 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: test pytest +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 From 152c8b1603b45a55fb8ab29abc6e3e74b8cebe00 Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Wed, 5 Jul 2023 12:59:49 +0530 Subject: [PATCH 12/23] fixed workflow file --- .github/workflows/reviewing_changes.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml index 8f96a40..ef7e50f 100644 --- a/.github/workflows/reviewing_changes.yml +++ b/.github/workflows/reviewing_changes.yml @@ -60,10 +60,10 @@ jobs: run: python -m pip install -r requirements.txt - name: run tests in parallel - run: browserstack-sdk pytest -s tests/test.py + run: browserstack-sdk pytest -s tests/bstack-sample-test.py - name: run local tests in parallel - run: browserstack-sdk pytest -s tests/local-test.py + run: browserstack-sdk pytest -s tests/bstack-local-test.py - if: always() uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 From ce9dc69508d0b7a242d61ae4b3e237d86f628aca Mon Sep 17 00:00:00 2001 From: Neha Agarwal Date: Mon, 10 Jul 2023 13:24:29 +0530 Subject: [PATCH 13/23] delete sdk workflow --- .github/workflows/reviewing_changes.yml | 88 ------------------------- 1 file changed, 88 deletions(-) delete mode 100644 .github/workflows/reviewing_changes.yml diff --git a/.github/workflows/reviewing_changes.yml b/.github/workflows/reviewing_changes.yml deleted file mode 100644 index ef7e50f..0000000 --- a/.github/workflows/reviewing_changes.yml +++ /dev/null @@ -1,88 +0,0 @@ -# This job is to test different profiles in sdk branch against Pull Requests raised -# This workflow targets pytest - -name: Python SDK Test workflow on workflow_dispatch - -on: - workflow_dispatch: - inputs: - pull_request_number: - description: 'The pull request number to build' - required: true - -jobs: - comment-run: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - max-parallel: 3 - matrix: - python: ['3.7', '3.10', '3.11'] - os: [ macos-latest, windows-latest, ubuntu-latest ] - name: Pytest Repo ${{ matrix.python }} - ${{ matrix.os }} Sample - env: - BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }} - BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }} - - steps: - - uses: actions/checkout@v3 - with: - ref: refs/pull/${{ github.event.inputs.pull_request_number }}/head - - name: Fetch Commit SHA - run: | - git log -1 --format='%H' - echo "commit_sha=$(git log -1 --format='%H')" >> $GITHUB_ENV - echo "commit_sha=$(git log -1 --format='%H')" >> $env:GITHUB_ENV - - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 - id: status-check-in-progress - env: - job_name: Pytest Repo ${{ matrix.python }} - ${{ matrix.os }} Sample - with: - github-token: ${{ github.token }} - script: | - const result = await github.rest.checks.create({ - owner: context.repo.owner, - repo: context.repo.repo, - name: process.env.job_name, - head_sha: process.env.commit_sha, - status: 'in_progress' - }).catch((err) => ({status: err.status, response: err.response})); - console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) - if (result.status !== 201) { - console.log('Failed to create check run') - } - - name: Setup python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python }} - - - name: Install dependencies - run: python -m pip install -r requirements.txt - - - name: run tests in parallel - run: browserstack-sdk pytest -s tests/bstack-sample-test.py - - - name: run local tests in parallel - run: browserstack-sdk pytest -s tests/bstack-local-test.py - - - if: always() - uses: actions/github-script@98814c53be79b1d30f795b907e553d8679345975 - id: status-check-completed - env: - conclusion: ${{ job.status }} - job_name: Pytest Repo ${{ matrix.python }} - ${{ matrix.os }} Sample - with: - github-token: ${{ github.token }} - script: | - const result = await github.rest.checks.create({ - owner: context.repo.owner, - repo: context.repo.repo, - name: process.env.job_name, - head_sha: process.env.commit_sha, - status: 'completed', - conclusion: process.env.conclusion - }).catch((err) => ({status: err.status, response: err.response})); - console.log(`The status-check response : ${result.status} Response : ${JSON.stringify(result.response)}`) - if (result.status !== 201) { - console.log('Failed to create check run') - } From ccfa08ed83a39f1654b38d8cf8b14365a4fdf516 Mon Sep 17 00:00:00 2001 From: Karan Shah <64479353+karanshah-browserstack@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:48:11 +0530 Subject: [PATCH 14/23] 1.15.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index e0085e4..162f9bb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ psutil pytest pytest-variables pytest-selenium -browserstack-sdk +browserstack-sdk==1.15.1 From 437d925d31f629672e19e78ba2f3854f197586ec Mon Sep 17 00:00:00 2001 From: Karan Shah <64479353+karanshah-browserstack@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:53:19 +0530 Subject: [PATCH 15/23] Pin to 1.15.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 162f9bb..997dffd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,4 +5,4 @@ psutil pytest pytest-variables pytest-selenium -browserstack-sdk==1.15.1 +browserstack-sdk==1.15.0 From f375871f79e3be769bc4120a3cafc5213b4e1c91 Mon Sep 17 00:00:00 2001 From: Karan Shah <64479353+karanshah-browserstack@users.noreply.github.com> Date: Mon, 4 Sep 2023 14:59:00 +0530 Subject: [PATCH 16/23] Fix selenium --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 997dffd..3ca71e3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,6 @@ browserstack-local jsonmerge -selenium==4.* +selenium==4.11.2 psutil pytest pytest-variables From 16d493b36159c4310b5356de6e2513c98383c40a Mon Sep 17 00:00:00 2001 From: Karan Shah <64479353+karanshah-browserstack@users.noreply.github.com> Date: Mon, 4 Sep 2023 15:00:46 +0530 Subject: [PATCH 17/23] Fix pytest version --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 3ca71e3..e2d0016 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,7 +2,7 @@ browserstack-local jsonmerge selenium==4.11.2 psutil -pytest +pytest==7.4.0 pytest-variables pytest-selenium browserstack-sdk==1.15.0 From 14fccd18bf228ad470b9c669f2046a9d7fef7a23 Mon Sep 17 00:00:00 2001 From: Karan Shah <64479353+karanshah-browserstack@users.noreply.github.com> Date: Mon, 4 Sep 2023 15:05:15 +0530 Subject: [PATCH 18/23] Add pytest-html --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index e2d0016..578b7e9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ pytest==7.4.0 pytest-variables pytest-selenium browserstack-sdk==1.15.0 +pytest-html==3.2.0 \ No newline at end of file From 8221bb61cb2e02e75bee8dd4493f6f39289b2165 Mon Sep 17 00:00:00 2001 From: Karan Shah <64479353+karanshah-browserstack@users.noreply.github.com> Date: Mon, 4 Sep 2023 15:11:33 +0530 Subject: [PATCH 19/23] Fix pytest html --- requirements.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 578b7e9..8319375 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,9 @@ browserstack-local jsonmerge -selenium==4.11.2 +selenium==4.* psutil -pytest==7.4.0 +pytest pytest-variables pytest-selenium -browserstack-sdk==1.15.0 +browserstack-sdk pytest-html==3.2.0 \ No newline at end of file From f78c152b5241782a58be690aab1c092666954584 Mon Sep 17 00:00:00 2001 From: Karan Shah <64479353+karanshah-browserstack@users.noreply.github.com> Date: Thu, 28 Mar 2024 22:41:09 +0530 Subject: [PATCH 20/23] Update requirements.txt --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8319375..eecbf6a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,8 +2,8 @@ browserstack-local jsonmerge selenium==4.* psutil -pytest +pytest==7.4.4 pytest-variables pytest-selenium browserstack-sdk -pytest-html==3.2.0 \ No newline at end of file +pytest-html==3.2.0 From 69cef2d21ef19840ea4095c5dc9e2e44e9b64b01 Mon Sep 17 00:00:00 2001 From: Hrithik Katiyar Date: Mon, 1 Jul 2024 15:27:11 +0530 Subject: [PATCH 21/23] Fixed linting issue --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c723d19..ac13aa0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .vscode __pycache__ .pytest_cache -local.log env +local.log From 4087c06d2ca7a14cce3af68e10402f7e6e464a97 Mon Sep 17 00:00:00 2001 From: Rahul Dandona Bstack Date: Thu, 20 Nov 2025 18:48:53 +0530 Subject: [PATCH 22/23] chore: update requirements.txt --- requirements.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index eecbf6a..f9f7e9a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,4 @@ -browserstack-local -jsonmerge -selenium==4.* -psutil +selenium>=3.14 pytest==7.4.4 -pytest-variables pytest-selenium browserstack-sdk -pytest-html==3.2.0 From 35a33896fa254a21d5b2a4009c9a667ab6784743 Mon Sep 17 00:00:00 2001 From: Rahul Dandona Bstack Date: Fri, 21 Nov 2025 16:09:35 +0530 Subject: [PATCH 23/23] chore: update requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index f9f7e9a..0bf126d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +browserstack-local selenium>=3.14 pytest==7.4.4 pytest-selenium