Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
local.log
screenshots
log/
browserstack.err
**/.DS_Store
.vscode/
.env
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,68 @@
# cucumber-js-appium-app-browserstack

This repository demonstrates how to run Appium Cucumber JS tests on BrowserStack App Automate.

## Setup

### Requirements

1. Node.js

- If not installed, install Node.js from [here](https://nodejs.org/en/download/)

- Ensure you have node & npm installed by running `node -v` & `npm -v`

### Install the dependencies

For Android tests, run the following command in project's base directory :

```
cd android
npm install
```
Or,

For dependencies for iOS tests, run following command in project's base directory :
```
cd ios
npm install
```
## Getting Started

Getting Started with Appium tests in NodeJS mocha on BrowserStack couldn't be easier!

### Run your first test :

Open `Android` or in `ios` folder

- If you have uploaded your app then add the app id to the `browserstack.yml` config file, or you can directly specify the path to your app in the `browserstack.yml` file.

- Run `npm run sample-test`

- You can access the test execution results, and debugging information such as video recording, network logs on [App Automate dashboard](https://app-automate.browserstack.com/dashboard)

---

### **Use Local testing for apps that access resources hosted in development or testing environments :**

Open `Android` or in `ios` folder

- Ensure that `browserstackLocal` capability is set to `true` in the `browserstack.yml` file.

- If you have uploaded your app then add the app id to the `browserstack.yml` config file, or you can directly specify the path to your app in the `browserstack.yml` file.

- Run `npm run sample-local-test`

- You can access the test execution results, and debugging information such as video recording, network logs on [App Automate dashboard](https://app-automate.browserstack.com/dashboard)

## Integration with other NodeJS frameworks

For other NodeJS frameworks samples, refer to following repositories :

- [WebdriverIO](https://github.com/browserstack/webdriverio-appium-app-browserstack)

Note: For other test frameworks supported by App-Automate refer our [Developer documentation](https://www.browserstack.com/docs/)

## Getting Help

If you are running into any issues or have any queries, please check [Browserstack Support page](https://www.browserstack.com/support/app-automate) or [get in touch with us](https://www.browserstack.com/contact?ref=help).
Binary file added android/LocalSample.apk
Binary file not shown.
Binary file added android/WikipediaSample.apk
Binary file not shown.
67 changes: 67 additions & 0 deletions android/browserstack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# =============================
# Set BrowserStack Credentials
# =============================
# Add your BrowserStack userName and acccessKey here or set BROWSERSTACK_USERNAME and
# BROWSERSTACK_ACCESS_KEY as env variables
userName: BROWSERSTACK_USERNAME
accessKey: BROWSERSTACK_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}

source: cucumber-js:appium-sample-master:v1.0

# Set `app` to define the app that is to be used for testing.
# It can either take the id of any uploaded app or the path of the app directly.
app: ./WikipediaSample.apk
# app: ./LocalSample.apk #For running local tests

# =======================================
# 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:
- deviceName: Samsung Galaxy S22 Ultra
osVersion: 12.0
platformName: android
- deviceName: OnePlus 11R
osVersion: 13.0
platformName: android
- deviceName: Google Pixel 6 Pro
osVersion: 12.0
platformName: android

# ==========================================
# 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 # <boolean> (Default false)
#browserStackLocalOptions:
#Options to be passed to BrowserStack local in-case of advanced configurations
# localIdentifier: # <string> (Default: null) Needed if you need to run multiple instances of local.
# forceLocal: true # <boolean> (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 # <boolean> # Set to true if you need screenshots for every selenium command ran
networkLogs: false # <boolean> Set to true to enable HAR logs capturing
consoleLogs: errors # <string> Remote browser's console debug levels to be printed (Default: errors)
# Available options are `disable`, `errors`, `warnings`, `info`, `verbose` (Default: errors)
5 changes: 5 additions & 0 deletions android/features/local.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Feature: BrowserStack Local Testing

Scenario: BStack Local Test - Can check tunnel working
When I start test on the Local Sample App
Then I should see "Up and running"
6 changes: 6 additions & 0 deletions android/features/single.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Feature: Browserstack test

Scenario: BStack Sample Test - Search BrowserStack
Given I try to search using Wikipedia App
Then I search with keyword BrowserStack
Then The search results should be listed
41 changes: 41 additions & 0 deletions android/features/step_definitions/bstack-steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

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

Given(/^I try to search using Wikipedia App/, async function () {
await this.driver
.wait(
until.elementLocated(
By.xpath(
"/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout/android.view.ViewGroup/android.support.v4.view.ViewPager/android.view.ViewGroup/android.widget.FrameLayout/android.support.v7.widget.RecyclerView/android.widget.FrameLayout[1]/android.widget.LinearLayout/android.widget.TextView"
)
),
30000
)
.click();
});

When(/^I search with keyword BrowserStack/, async function () {
var insertTextSelector = await this.driver.wait(
until.elementLocated(
By.xpath(
"/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout[1]/android.widget.FrameLayout[1]/android.view.ViewGroup/android.widget.LinearLayout/android.support.v7.widget.LinearLayoutCompat/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.LinearLayout/android.widget.AutoCompleteTextView"
),
30000
)
);
await insertTextSelector.sendKeys("BrowserStack");
await this.driver.sleep(5000);
});

Then(/^The search results should be listed/, async function () {
var allProductsName = await this.driver.findElements(
By.xpath(
"/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.FrameLayout/android.widget.LinearLayout[1]/android.widget.FrameLayout[2]/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.ListView/android.widget.LinearLayout"
)
);

assert(allProductsName.length > 0);
});
28 changes: 28 additions & 0 deletions android/features/step_definitions/local-steps.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict';

var assert = require('assert');
const { When, Then } = require("@cucumber/cucumber");
const { By, until } = require("selenium-webdriver");

When(/^I start test on the Local Sample App$/, async function () {
await this.driver.wait(
until.elementLocated(
By.xpath(
'/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.view.ViewGroup/android.widget.Button'
)
), 30000
).click();
});

Then(/^I should see "([^"]*)"$/, async function (sourceMatch) {
var textElement = await this.driver.wait(
until.elementLocated(
By.xpath(
'/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.view.ViewGroup/android.widget.FrameLayout[2]/android.view.ViewGroup/android.widget.TextView'
), 30000
)
).getText();

assert(textElement.includes('The active connection is wifi'));
assert(textElement.includes('Up and running'));
});
5 changes: 5 additions & 0 deletions android/features/support/env.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
'use strict';

const { setDefaultTimeout } = require("@cucumber/cucumber");

setDefaultTimeout(60 * 1000);
22 changes: 22 additions & 0 deletions android/features/support/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

const { Builder, Capabilities } = require("selenium-webdriver");
const { Before, After } = require("@cucumber/cucumber");

var createBrowserStackSession = function(){
return new Builder().
usingServer('http://localhost:4444/wd/hub').
build();
}

Before(function (scenario, callback) {
var world = this;
world.driver = createBrowserStackSession();
callback();
});

After(function(scenario, callback){
this.driver.quit().then(function(){
callback();
});
});
Loading