From fd9e6244b78cba6a1b1ed215070d5eaa4635940e Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Fri, 7 Oct 2022 14:56:57 +0530 Subject: [PATCH 1/4] update: add SDk changes, remove extra files --- browserstack.yml | 70 ++++++++++++++++++++++++++++++++++ config/Config.py | 36 ++++------------- config/KeywordsFile.robot | 33 +--------------- config/manage-local-testing.py | 19 --------- config/mark-test-status.py | 9 ----- requirements.txt | 3 +- tests/LocalTest.robot | 24 ++++-------- tests/parallel/Suite01.robot | 9 +---- tests/parallel/Suite02.robot | 9 +---- tests/parallel/Suite03.robot | 9 +---- tests/testcases.robot | 8 ---- 11 files changed, 95 insertions(+), 134 deletions(-) create mode 100644 browserstack.yml delete mode 100644 config/manage-local-testing.py delete mode 100644 config/mark-test-status.py diff --git a/browserstack.yml b/browserstack.yml new file mode 100644 index 0000000..aa837fd --- /dev/null +++ b/browserstack.yml @@ -0,0 +1,70 @@ +# ============================= +# Set BrowserStack Credentials +# ============================= +# Add your BrowserStack userName and acccessKey here or set BROWSERSTACK_USERNAME and +# BROWSERSTACK_ACCESS_KEY as env variables +userName: YOUR_USERNAME +accessKey: YOUR_ACCESS_KEY + +# ====================== +# Organizing your tests +# ====================== +# Use `projectName`, `buildName`, `name` capabilities to organise your tests +# `name` is the name of your test sessions and is automatically picked from your +# test name and doesn't need to be set manually when using BrowserStack SDK +# `buildName` is used to name your CI/CD job or the execution of your test suite. +# Ensure you add a dynamic identifier, like an incremental build number from your +# CI/CD or timestamp at the end of every build; otherwise tests from different +# executions will be grouped together on BrowserStack +buildName: browserstack-build-1 +# Use `projectName` to set the name of your project. Example, Marketing Website +projectName: BrowserStack Samples + +# ======================================= +# 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 + browser: Chrome + browserVersion: latest + - os: Windows + osVersion: 10 + browser: Edge + browserVersion: latest + - device: 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 availabe 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 (Available levels: `disable`, `errors`, `warnings`, `info`, `verbose`, Default: errors) diff --git a/config/Config.py b/config/Config.py index 1f243f3..f09cc12 100644 --- a/config/Config.py +++ b/config/Config.py @@ -1,37 +1,15 @@ import os -common_caps = { - "browserstack.user" : "BROWSERSTACK_USERNAME", - "browserstack.key" : "BROWSERSTACK_ACCESS_KEY", - "build" : "browserstack-build-1", - "browserstack.debug" : "true" -} - envs = [{ - "os" : "Windows", - "os_version" : "10", - "browser" : "Chrome", - "browser_version" : "latest" + "browser": "Chrome", }, -{ - "os" : "OS X", - "os_version" : "Big Sur", - "browser" : "Safari", - "browser_version" : "latest" + { + "browser": "Safari", }, -{ - "device" : "Samsung Galaxy S22", - "os_version" : "12" + { + "browser": "Firefox", }] -def combine_caps(i): - - username = os.environ.get("BROWSERSTACK_USERNAME") - accesskey = os.environ.get("BROWSERSTACK_ACCESS_KEY") - if username != None and accesskey != None: - common_caps["browserstack.user"] = username - common_caps["browserstack.key"] = accesskey - x = int(i) - envs[x].update(common_caps) - return envs[x] +def get_test_caps(i): + return envs[int(i)] diff --git a/config/KeywordsFile.robot b/config/KeywordsFile.robot index ded1323..bcd3b2a 100644 --- a/config/KeywordsFile.robot +++ b/config/KeywordsFile.robot @@ -1,9 +1,8 @@ *** Settings *** Library SeleniumLibrary -Library mark-test-status.py *** Variables *** -${remote_url}= https://hub.browserstack.com/wd/hub +${remote_url}= http://localhost:4444/wd/hub *** Keywords *** Open Session @@ -16,37 +15,11 @@ Close Session Add Implicit Wait set selenium implicit wait 5 -Mark Test Status - [Arguments] ${status} ${reason} - TEST STATUS ${status} ${reason} - Get the page title get title -Click on Sign In - click element id=signin - -Enter Credentials - [Arguments] ${username} ${password} - input text css=#username input ${username} - click element css= .css-1n7v3ny-option - input text css=#password input ${password} - click element css= .css-1n7v3ny-option - -Click on Login - click element id=login-btn - -Verify username - [Arguments] ${assert_username} - ${retrived_username}= get text css=.username - run keyword if "${retrived_username}" == "${assert_username}" mark test status passed Username validated! - run keyword if "${retrived_username}" != "${assert_username}" mark test status failed Username validation failed! - element should contain css=.username ${assert_username} - Verify site content ${site_content}= get text css=body - run keyword if "${site_content}" == "Up and running" mark test status passed Site Content validated! - run keyword if "${site_content}" != "Up and running" mark test status failed Site Content validation failed! element should contain css=body Up and running Add first product to cart @@ -54,7 +27,5 @@ Add first product to cart Verify product is added to cart ${product_name} get text xpath=//*[@id="1"]/p - ${product_incart} get text css=p.title - run keyword if "${product_name}" == "${product_incart}" mark test status passed Correct product added! - run keyword if "${product_name}" != "${product_incart}" mark test status failed Something went wrong! + ${product_incart} get text css=p.title element should contain css=p.title ${product_name} diff --git a/config/manage-local-testing.py b/config/manage-local-testing.py deleted file mode 100644 index 95f6cc6..0000000 --- a/config/manage-local-testing.py +++ /dev/null @@ -1,19 +0,0 @@ -import os -from robot.libraries.BuiltIn import BuiltIn -from robot.libraries.BuiltIn import _Misc -import robot.api.logger as logger -from robot.api.deco import keyword -from browserstack.local import Local - -access_key = os.getenv("BROWSERSTACK_ACCESS_KEY") -bs_local = Local() - -@keyword("START LOCAL") -def startLocal(): - bs_local_args = {"key": access_key} - bs_local.start(**bs_local_args) - print(bs_local.isRunning()) - -@keyword("STOP LOCAL") -def stopLocal(): - bs_local.stop() diff --git a/config/mark-test-status.py b/config/mark-test-status.py deleted file mode 100644 index 34469c6..0000000 --- a/config/mark-test-status.py +++ /dev/null @@ -1,9 +0,0 @@ -from robot.libraries.BuiltIn import BuiltIn -from robot.libraries.BuiltIn import _Misc -import robot.api.logger as logger -from robot.api.deco import keyword - -@keyword("TEST STATUS") -def testStatus(status, reason): - driver = BuiltIn().get_library_instance('SeleniumLibrary').driver - driver.execute_script('browserstack_executor: {"action": "setSessionStatus", "arguments": {"status":"'+status+'", "reason": "'+reason+'"}}') diff --git a/requirements.txt b/requirements.txt index bf195a4..789a91d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,5 @@ robotframework robotframework-seleniumlibrary==5.1.3 robotframework-pabot browserstack-local -selenium==3.141.0 +selenium +browserstack-sdk diff --git a/tests/LocalTest.robot b/tests/LocalTest.robot index 1f8427b..e1c95aa 100644 --- a/tests/LocalTest.robot +++ b/tests/LocalTest.robot @@ -1,25 +1,17 @@ *** Settings *** -Library SeleniumLibrary -Library Collections -Library ../config/manage-local-testing.py +Library SeleniumLibrary Library ../config/Config.py -Resource ../config/KeywordsFile.robot -Test Setup Setup for local test -Test Teardown Teardown for local test +Resource ../config/KeywordsFile.robot +Test Setup Execute local test +Test Teardown Close Session *** Variables *** -${local_url}= http://bs-local.com:45691/check +${local_website_url}= http://bs-local.com:45691/check *** Keywords *** -Setup for local test - START LOCAL - ${final_caps}= combine caps 0 - Set to Dictionary ${final_caps} name=BStack Demo - ${TEST NAME} browserstack.local=true - Open Session ${final_caps} ${local_url} - -Teardown for local test - Close Session - STOP LOCAL +Execute local test + ${test_caps}= get test caps 0 + Open Session ${test_caps} ${local_website_url} *** Test Cases *** Local Test diff --git a/tests/parallel/Suite01.robot b/tests/parallel/Suite01.robot index 8137bef..6b5167d 100644 --- a/tests/parallel/Suite01.robot +++ b/tests/parallel/Suite01.robot @@ -1,6 +1,5 @@ *** Settings *** Library SeleniumLibrary -Library Collections Library ../../config/Config.py Resource ../../config/KeywordsFile.robot Resource ../testcases.robot @@ -12,14 +11,10 @@ ${website_url}= https://bstackdemo.com *** Keywords *** Execute test - ${final_caps}= combine caps 0 - Set to Dictionary ${final_caps} name=BStack Demo - ${TEST NAME} - Open Session ${final_caps} ${website_url} + ${test_caps}= get test caps 0 + Open Session ${test_caps} ${website_url} *** Test Cases *** -Login Test - Login - Add to Cart Test Add to Cart diff --git a/tests/parallel/Suite02.robot b/tests/parallel/Suite02.robot index ed3d211..e3d344f 100644 --- a/tests/parallel/Suite02.robot +++ b/tests/parallel/Suite02.robot @@ -1,6 +1,5 @@ *** Settings *** Library SeleniumLibrary -Library Collections Library ../../config/Config.py Resource ../../config/KeywordsFile.robot Resource ../testcases.robot @@ -12,14 +11,10 @@ ${website_url}= https://bstackdemo.com *** Keywords *** Execute test - ${final_caps}= combine caps 1 - Set to Dictionary ${final_caps} name=BStack Demo - ${TEST NAME} - Open Session ${final_caps} ${website_url} + ${test_caps}= get test caps 1 + Open Session ${test_caps} ${website_url} *** Test Cases *** -Login Test - Login - Add to Cart Test Add to Cart diff --git a/tests/parallel/Suite03.robot b/tests/parallel/Suite03.robot index c730ffb..4a4dc1f 100644 --- a/tests/parallel/Suite03.robot +++ b/tests/parallel/Suite03.robot @@ -1,6 +1,5 @@ *** Settings *** Library SeleniumLibrary -Library Collections Library ../../config/Config.py Resource ../../config/KeywordsFile.robot Resource ../testcases.robot @@ -12,14 +11,10 @@ ${website_url}= https://bstackdemo.com *** Keywords *** Execute test - ${final_caps}= combine caps 2 - Set to Dictionary ${final_caps} name=BStack Demo - ${TEST NAME} - Open Session ${final_caps} ${website_url} + ${test_caps}= get test caps 2 + Open Session ${test_caps} ${website_url} *** Test Cases *** -Login Test - Login - Add to Cart Test Add to Cart diff --git a/tests/testcases.robot b/tests/testcases.robot index 9d966ed..65c7fcc 100644 --- a/tests/testcases.robot +++ b/tests/testcases.robot @@ -3,14 +3,6 @@ Library SeleniumLibrary Resource ../config/KeywordsFile.robot *** Keywords *** -Login - Add Implicit Wait - Get the page title - Click on Sign In - Enter Credentials demouser testingisfun99 - Click on Login - Verify username demouser - Add to Cart Add Implicit Wait Get the page title From f31e2e7a6b47aa58a94bdfb4c647e62cf82468c1 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Fri, 7 Oct 2022 15:12:11 +0530 Subject: [PATCH 2/4] update: README with sdk --- README.md | 65 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 32bd691..96b15a2 100644 --- a/README.md +++ b/README.md @@ -2,46 +2,51 @@ ![BrowserStack Logo](https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780) -## Setup -* Clone the repo -* Install dependencies `pip install -r requirements.txt` - -## Set BrowserStack Credentials -* Export the BrowserStack username and access key as environment variables +## Prerequisite +``` +python3 should be installed +``` -#### For Linux/MacOS - ``` - export BROWSERSTACK_USERNAME= - export BROWSERSTACK_ACCESS_KEY= +## Setup +* Clone the repo ``` -#### For Windows + git clone -b sdk https://github.com/browserstack/robot-browserstack.git ``` - setx BROWSERSTACK_USERNAME= - setx BROWSERSTACK_ACCESS_KEY= +* Install dependencies ``` + pip install -r requirements.txt + ``` + +## Set BrowserStack Credentials +* Add your BrowserStack username and access key in the `browserstack.yml` config fle. +* You can also export them as environment variables, `BROWSERSTACK_USERNAME` and `BROWSERSTACK_ACCESS_KEY`: + + #### For Linux/MacOS + ``` + export BROWSERSTACK_USERNAME= + export BROWSERSTACK_ACCESS_KEY= + ``` + #### For Windows + ``` + setx BROWSERSTACK_USERNAME= + setx BROWSERSTACK_ACCESS_KEY= + ``` ## Running tests -* To run local test, run `robot tests/LocalTest.robot` -* To run parallel tests we will be using the [Pabot](https://pabot.org/) library: - 1. To run test suites in parallel (Testcases within respective test suites will be sequential) - * Run - `pabot --processes tests/parallel/*.robot` - * Alternate method: `pabot --processes ` -
Eg: `pabot --processes 2 tests/parallel/Suite01.robot tests/parallel/Suite02.robot` - 2. To run all test cases within a test suite in parallel - * Run - `pabot --testlevelsplit ` -
Eg: `pabot --testlevelsplit tests/parallel/Suite01.robot` - 3. Run all testcases across all Test Suites in parallel - * Run - `pabot --testlevelsplit --processes tests/parallel/*.robot` -
**Note: If the process count exceeds the parallel threads available on BrowserStack, the sessions will automatically get queued.** +* To run sample tests: + - To run the sample tests in parallel across the platforms defined in the `browserstack.yml` file, run: + ``` + browserstack-sdk pabot ./tests/parallel/*.robot + ``` +* To run tests on locally hosted websites: + - To run the local test in parallel across the platforms defined in the `browserstack.yml` file, run: + ``` + browserstack-sdk pabot ./tests/LocalTest.robot + ``` Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github) -## Notes -* This repository only works for Selenium 3 as of now. Desired Capabilities do not get honoured for Selenium 4. The open issue on SeleniumLibrary can be found [here](https://github.com/robotframework/SeleniumLibrary/issues/1774). -* You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate) -* To test on a different set of browsers, check out our [platform configurator](https://www.browserstack.com/automate/capabilities) - ## Additional Resources * [Documentation for writing Automate test scripts in Python](https://www.browserstack.com/automate/python) * [Customizing your tests on BrowserStack](https://www.browserstack.com/automate/capabilities) From 61aa0ac0bbb9ae27cc406b45f9532e4854816f10 Mon Sep 17 00:00:00 2001 From: Ankit Singh <51696887+Ankit098@users.noreply.github.com> Date: Thu, 20 Oct 2022 23:15:50 +0530 Subject: [PATCH 3/4] chore: set command for adding env variables --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 96b15a2..4694335 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,9 @@ python3 should be installed ``` #### For Windows ``` + set BROWSERSTACK_USERNAME= + set BROWSERSTACK_ACCESS_KEY= + setx BROWSERSTACK_USERNAME= setx BROWSERSTACK_ACCESS_KEY= ``` From 041ce48e89bd6c7bcf9fbcc70c6d36200f4c2848 Mon Sep 17 00:00:00 2001 From: Ankit Singh <2501.ankit@gmail.com> Date: Wed, 16 Nov 2022 20:16:18 +0530 Subject: [PATCH 4/4] update: local tests with localIdentifier --- config/KeywordsFile.robot | 5 ++--- tests/LocalTest.robot | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/config/KeywordsFile.robot b/config/KeywordsFile.robot index bcd3b2a..bc059f6 100644 --- a/config/KeywordsFile.robot +++ b/config/KeywordsFile.robot @@ -18,9 +18,8 @@ Add Implicit Wait Get the page title get title -Verify site content - ${site_content}= get text css=body - element should contain css=body Up and running +Verify Local Page + Title Should be BrowserStack Local Add first product to cart click element xpath=//*[@id="1"]/div[4] diff --git a/tests/LocalTest.robot b/tests/LocalTest.robot index e1c95aa..dd8ecd8 100644 --- a/tests/LocalTest.robot +++ b/tests/LocalTest.robot @@ -6,7 +6,7 @@ Test Setup Execute local test Test Teardown Close Session *** Variables *** -${local_website_url}= http://bs-local.com:45691/check +${local_website_url}= http://bs-local.com:45454 *** Keywords *** Execute local test @@ -16,4 +16,4 @@ Execute local test *** Test Cases *** Local Test Add Implicit Wait - Verify site content + Verify Local Page