Skip to content

Commit acbe6ed

Browse files
authored
Merge pull request #34 from 07souravkunda/sdk
Add sdk to main
2 parents 156a929 + 7c7eabc commit acbe6ed

File tree

13 files changed

+1566
-429
lines changed

13 files changed

+1566
-429
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
node_modules
22
local.log
33
screenshots
4+
log/
5+
browserstack.err
6+
**/.DS_Store
7+
.vscode/
8+
.env

README.md

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,58 @@
11
# cucumber-js-browserstack
22

3-
[Cucumber-JS](https://github.com/cucumber/cucumber-js) Integration with BrowserStack.
4-
5-
Master branch contains **Selenium 3** samples, for **Selenium 4 - W3C protocol** please checkout [selenium-4](https://github.com/browserstack/cucumber-js-browserstack/tree/selenium-4) branch
3+
[Cucumber-JS](https://github.com/cucumber/cucumber-js) Integration with BrowserStack for E2E functional testing of UI using Selenium and [browserstack-node-sdk](https://www.npmjs.com/package/browserstack-node-sdk).
64

75
![BrowserStack Logo](https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780)
86

97
<img src = "https://cucumber.io/images/cucumber-logo.svg" height = "100">
108

119

12-
## Setup
13-
* Clone the repo
14-
* Install dependencies `npm install`
15-
* Update `*.conf.js` files inside the `conf/` directory with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings)
10+
## Run sample build
1611

17-
## Running your tests
18-
* To run a single test, run `npm run single`
19-
* To run local tests, run `npm run local`
20-
* To run parallel tests, run `npm run parallel`
12+
---
13+
- Clone the repo
14+
- Install dependencies `npm install`
15+
- Set your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings) in [browserstack.yml](browserstack.yml) `npx setup --username userName --key accessKey`
16+
- To run sample test, run `npm run sample-test` or `yarn run sample-test`
17+
- To run tests on private websites,
18+
- set browserstackLocal: true at [browserstack.yml](browserstack.yml)
19+
- run `npm run sample-local-test` or `yarn run sample-local-test`
2120

2221
Understand how many parallel sessions you need by using our [Parallel Test Calculator](https://www.browserstack.com/automate/parallel-calculator?ref=github)
2322

24-
## Notes
25-
* You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate)
26-
* To test on a different set of browsers, check out our [platform configurator](https://www.browserstack.com/automate/node#setting-os-and-browser)
27-
* You can export the environment variables for the Username and Access Key of your BrowserStack account
28-
23+
## Integrate your test suite
24+
25+
---
26+
1. Install browserstack-node-sdk as a dev-dependency
27+
```
28+
npm i -D browserstack-node-sdk
29+
or
30+
yarn add --dev browserstack-node-sdk
31+
```
32+
2. Setup
33+
```
34+
npx setup --username userName --key accessKey
35+
```
36+
* Adds a browserstack.yml file at root of your mocha project with your [BrowserStack Username and Access Key](https://www.browserstack.com/accounts/settings).
37+
* Adds a new command for running tests on browserstack in scripts tag of package.json,
2938
```
30-
export BROWSERSTACK_USERNAME=<browserstack-username> &&
31-
export BROWSERSTACK_ACCESS_KEY=<browserstack-access-key>
39+
"scripts": {
40+
"test": "cucumber-js [args]",
41+
"browserstack-test": "browserstack-node-sdk cucumber-js [args]"
42+
},
3243
```
33-
44+
45+
46+
## Notes
47+
48+
---
49+
- You can view your test results on the [BrowserStack Automate dashboard](https://www.browserstack.com/automate)
50+
- To test on a different set of browsers, check out our [platform configurator](https://www.browserstack.com/automate/node#setting-os-and-browser)
51+
3452
## Additional Resources
35-
* [Documentation for writing Automate test scripts in Node](https://www.browserstack.com/automate/node)
36-
* [Customizing your tests on BrowserStack](https://www.browserstack.com/automate/capabilities)
37-
* [Browsers & mobile devices for selenium testing on BrowserStack](https://www.browserstack.com/list-of-browsers-and-platforms?product=automate)
38-
* [Using REST API to access information about your tests via the command-line interface](https://www.browserstack.com/automate/rest-api)
53+
54+
---
55+
- [Documentation for writing Automate test scripts in Node](https://www.browserstack.com/automate/node)
56+
- [Customizing your tests on BrowserStack](https://www.browserstack.com/automate/capabilities)
57+
- [Browsers & mobile devices for selenium testing on BrowserStack](https://www.browserstack.com/list-of-browsers-and-platforms?product=automate)
58+
- [Using REST API to access information about your tests via the command-line interface](https://www.browserstack.com/automate/rest-api)

browserstack.yml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# =============================
2+
# Set BrowserStack Credentials
3+
# =============================
4+
# Add your BrowserStack userName and acccessKey here or set BROWSERSTACK_USERNAME and
5+
# BROWSERSTACK_ACCESS_KEY as env variables
6+
userName: YOUR_USERNAME
7+
accessKey: YOUR_ACCESS_KEY
8+
# ======================
9+
# Organizing your tests
10+
# ======================
11+
# Use `projectName`, `buildName`, `name` capabilities to organise your tests
12+
# `name` is the name of your test sessions and is automatically picked from your
13+
# test name and doesn't need to be set manually when using BrowserStack SDK
14+
# `buildName` is used to name your CI/CD job or the execution of your test suite.
15+
# Ensure you add a dynamic identifier, like an incremental build number from your
16+
# CI/CD or timestamp at the end of every build; otherwise tests from different
17+
# executions will be grouped together on BrowserStack
18+
buildName: browserstack-build-1
19+
# Use `projectName` to set the name of your project. Example, Marketing Website
20+
projectName: BrowserStack Samples
21+
# =======================================
22+
# Platforms (Browsers / Devices to test)
23+
# =======================================
24+
# Platforms object contains all the browser / device combinations you want to test on.
25+
# Entire list available here -> (https://www.browserstack.com/list-of-browsers-and-platforms/automate)
26+
platforms:
27+
- os: OS X
28+
osVersion: Big Sur
29+
browser: Chrome
30+
browserVersion: latest
31+
- os: Windows
32+
osVersion: 10
33+
browser: Edge
34+
browserVersion: latest
35+
- device: iPhone 13
36+
browserName: Safari
37+
osVersion: 15
38+
- device: Samsung Galaxy S22 Ultra
39+
browserName: chrome # Try 'samsung' for Samsung browser
40+
osVersion: 12.0
41+
# =======================
42+
# Parallels per Platform
43+
# =======================
44+
# The number of parallel threads to be used for each platform set.
45+
# BrowserStack's SDK runner will select the best strategy based on the configured value
46+
#
47+
# 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
48+
#
49+
# 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
50+
parallelsPerPlatform: 1
51+
# ==========================================
52+
# BrowserStack Local
53+
# (For localhost, staging/private websites)
54+
# ==========================================
55+
# Set browserStackLocal to true if your website under test is not accessible publicly over the internet
56+
# Learn more about how BrowserStack Local works here -> https://www.browserstack.com/docs/automate/selenium/local-testing-introduction
57+
browserstackLocal: true # <boolean> (Default false)
58+
# browserStackLocalOptions:
59+
# Options to be passed to BrowserStack local in-case of advanced configurations
60+
# localIdentifier: # <string> (Default: null) Needed if you need to run multiple instances of local.
61+
# forceLocal: true # <boolean> (Default: false) Set to true if you need to resolve all your traffic via BrowserStack Local tunnel.
62+
# Entire list of arguments availabe here -> https://www.browserstack.com/docs/automate/selenium/manage-incoming-connections
63+
# ===================
64+
# Debugging features
65+
# ===================
66+
debug: false # <boolean> # Set to true if you need screenshots for every selenium command ran
67+
networkLogs: false # <boolean> Set to true to enable HAR logs capturing
68+
consoleLogs: errors # <string> Remote browser's console debug levels to be printed (Default: errors)
69+
# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors)

conf/local.conf.js

Lines changed: 0 additions & 21 deletions
This file was deleted.

conf/parallel.conf.js

Lines changed: 0 additions & 29 deletions
This file was deleted.

conf/single.conf.js

Lines changed: 0 additions & 20 deletions
This file was deleted.
Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,32 @@
11
'use strict';
22

3-
var assert = require('cucumber-assert');
3+
var assert = require('assert');
4+
const { Given, When, Then } = require("@cucumber/cucumber");
5+
const { By, until } = require("selenium-webdriver");
46

5-
module.exports = function() {
6-
var productText = "";
7-
this.Given(/^I visit bstackdemo website/, function (next) {
8-
this.driver.get('https://bstackdemo.com/').then(next);
9-
});
7+
var productText = "";
8+
Given(/^I visit bstackdemo website/, async function () {
9+
await this.driver.get('https://bstackdemo.com/');
10+
});
1011

11-
this.When(/^I add a product to the cart/, function (next) {
12-
const productOnScreen = this.driver.findElement({xpath: '//*[@id="1"]/p'})
13-
productOnScreen.getText().then(function (text) {
14-
productText = text;
15-
});
16-
this.driver.findElement({xpath: '//*[@id="1"]/div[4]'}).click().then(next);
17-
});
12+
When(/^I add a product to the cart/, async function () {
13+
await this.driver.wait(until.elementLocated(By.xpath('//*[@id="1"]/p')));
14+
productText = await this.driver.findElement(By.xpath('//*[@id="1"]/p')).getText();
15+
await this.driver.findElement({xpath: '//*[@id="1"]/div[4]'}).click();
16+
});
1817

19-
this.Then(/^I should see the same product in the cart section/, function (next) {
20-
this.driver.findElement({xpath: "//*[@id=\'__next\']/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]"})
21-
.getText()
22-
.then(function (text) {
23-
assert.equal(text, productText, next, 'Expected product to be ' + productText)
24-
})
25-
});
26-
};
18+
Then(/^I should see the same product in the cart section/, async function () {
19+
await this.driver.wait(until.elementLocated(By.className("float-cart__content")));
20+
await this.driver.findElement(By.className("float-cart__content"));
21+
22+
await this.driver.wait(until.elementLocated(By.xpath('//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]')));
23+
let productCartText = await this.driver
24+
.findElement(
25+
By.xpath(
26+
'//*[@id="__next"]/div/div/div[2]/div[2]/div[2]/div/div[3]/p[1]'
27+
)
28+
)
29+
.getText();
30+
31+
assert.equal(productCartText, productText, 'Expected product to be ' + productText)
32+
});
Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
'use strict';
22

3-
var assert = require('cucumber-assert');
4-
var webdriver = require('selenium-webdriver');
3+
var assert = require('assert');
4+
const { When, Then } = require("@cucumber/cucumber");
55

6-
module.exports = function() {
6+
When(/^I open health check$/, async function () {
7+
await this.driver.get('http://bs-local.com:45691/check');
8+
});
79

8-
this.When(/^I open health check$/, function (next) {
9-
this.driver.get('http://bs-local.com:45691/check');
10-
next();
11-
});
12-
13-
this.Then(/^I should see "([^"]*)"$/, function (sourceMatch, next) {
14-
this.driver.getPageSource()
15-
.then(function(source) {
16-
assert.equal(source.indexOf(sourceMatch) > -1, true, next, 'Expected source to contain ' + sourceMatch);
17-
});
18-
});
19-
};
10+
Then(/^I should see "([^"]*)"$/, async function (sourceMatch) {
11+
let source = await this.driver.getPageSource();
12+
assert.equal(source.indexOf(sourceMatch) > -1, true, 'Expected source to contain ' + sourceMatch);
13+
});

features/support/env.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
'use strict';
22

3-
var configure = function () {
4-
this.setDefaultTimeout(60 * 1000);
5-
};
3+
const { setDefaultTimeout } = require("@cucumber/cucumber");
64

7-
module.exports = configure;
5+
setDefaultTimeout(60 * 1000);

features/support/hooks.js

Lines changed: 15 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,23 @@
11
'use strict';
22

3-
var webdriver = require('selenium-webdriver');
4-
var browserstack = require('browserstack-local');
3+
const { Builder, Capabilities } = require("selenium-webdriver");
4+
const { Before, After } = require("@cucumber/cucumber");
55

6-
var config_file = '../../conf/' + (process.env.CONFIG_FILE || 'single') + '.conf.js';
7-
var config = require(config_file).config;
8-
9-
var username = process.env.BROWSERSTACK_USERNAME || config.user;
10-
var accessKey = process.env.BROWSERSTACK_ACCESS_KEY || config.key;
11-
12-
var createBrowserStackSession = function (config, caps) {
13-
return new webdriver.Builder().
14-
usingServer(`https://${username}:${accessKey}@${config.server}/wd/hub`).
15-
withCapabilities(caps).
6+
var createBrowserStackSession = function(){
7+
return new Builder().
8+
usingServer('http://localhost:4444/wd/hub').
9+
withCapabilities(Capabilities.chrome()).
1610
build();
1711
}
1812

19-
var myHooks = function () {
20-
var bs_local = null;
21-
22-
this.Before(function (scenario, callback) {
23-
var world = this;
24-
var task_id = parseInt(process.env.TASK_ID || 0);
25-
var caps = config.capabilities[task_id];
26-
27-
if (caps["bstack:options"] && caps["bstack:options"]['local']) {
28-
// Code to start browserstack local before start of test and stop browserstack local after end of test
29-
bs_local = new browserstack.Local();
30-
bs_local.start({ key: accessKey }, function (error) {
31-
if (error) return console.log(error.red);
13+
Before(function (scenario, callback) {
14+
var world = this;
15+
world.driver = createBrowserStackSession();
16+
callback();
17+
});
3218

33-
world.driver = createBrowserStackSession(config, caps);
34-
callback();
35-
});
36-
}
37-
else {
38-
world.driver = createBrowserStackSession(config, caps);
39-
callback();
40-
}
19+
After(function(scenario, callback){
20+
this.driver.quit().then(function(){
21+
callback();
4122
});
42-
43-
this.After(function (scenario, callback) {
44-
this.driver.quit().then(function () {
45-
if (bs_local) {
46-
bs_local.stop(callback);
47-
}
48-
else callback();
49-
});
50-
});
51-
};
52-
53-
module.exports = myHooks;
23+
});

0 commit comments

Comments
 (0)