Skip to content

Commit db307da

Browse files
authored
Merge branch 'main' into add-jest-sample
2 parents d7dc97e + a3658e3 commit db307da

6 files changed

Lines changed: 383 additions & 0 deletions

File tree

serenity-cucumber/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# browserstack-selenium-load-testing-sample
2+
3+
![BrowserStack Logo](https://d98b8t1nnulk5.cloudfront.net/production/images/layout/logo-header.png?1469004780)
4+
5+
## Getting Started
6+
7+
### Run Sample Build
8+
9+
1. **Clone the repository**
10+
11+
```sh
12+
git clone https://github.com/browserstack/browserstack-selenium-load-testing-sample.git
13+
cd browserstack-selenium-load-testing-sample
14+
cd serenity-cucumber
15+
```
16+
17+
2. **Install Maven dependencies**
18+
19+
```sh
20+
mvn compile
21+
```
22+
23+
3. **Install BrowserStack CLI**
24+
25+
Download the appropriate BrowserStack CLI binary based on your operating system:
26+
27+
- **macOS x86**
28+
[browserstack-cli-macOS-x86](https://load-api.browserstack.com/api/v1/binary?os=macos&arch=x64)
29+
30+
- **macOS ARM**
31+
[browserstack-cli-macOS-arm](https://load-api.browserstack.com/api/v1/binary?os=macos&arch=arm64)
32+
33+
- **Windows x86**
34+
[browserstack-cli-windows](https://load-api.browserstack.com/api/v1/binary?os=win&arch=x64)
35+
36+
- **Linux x86**
37+
[browserstack-cli-linux-x86](https://load-api.browserstack.com/api/v1/binary?os=linux&arch=arm64)
38+
39+
- **Linux ARM**
40+
[browserstack-cli-linux-arm](https://load-api.browserstack.com/api/v1/binary?os=linux&arch=x64)
41+
42+
> Place the downloaded `browserstack-cli` binary in the root of your project.
43+
44+
4. **Run tests using BrowserStack CLI**
45+
46+
```sh
47+
./browserstack-cli load run
48+
```
49+
50+
5. **View Test Results**
51+
52+
Visit the [BrowserStack Load-Testing Dashboard](https://load.browserstack.com/projects) to monitor and analyze your test runs.
53+
54+
---
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# =============================
2+
# Set BrowserStack Credentials
3+
# =============================
4+
# Add your BrowserStack userName and accessKey here or set BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY as env variables.
5+
userName: BROWSERSTACK_USERNAME
6+
accessKey: BROWSERSTACK_ACCESS_KEY
7+
8+
# ======================
9+
# BrowserStack Reporting
10+
# ======================
11+
# The following parameters are used to set up reporting on BrowserStack Load Testing:
12+
# Set 'projectName' to the name of your project. Example: 'Product ABC'. Tests under the same projectName will be grouped together.
13+
projectName: Default Project
14+
15+
# Set 'testName' to the name of your test. Example: 'First Load Test'. Test runs with the same testName will be grouped together.
16+
testName: Default Test
17+
18+
# ======================
19+
# Set Load Configuration
20+
# ======================
21+
# The following parameters are used to set load configuration for your test:
22+
# Set 'testType' to the type of load test that you want to execute. Example:'Playwright', 'Selenium'. This is a required parameter.
23+
testType: Selenium
24+
25+
# Set 'vus' to the maximum number of virtual users to simulate during the test.
26+
vus: 1
27+
28+
# Set multiple regions from which you would want to generate the load (percent should total 100 across all loadzones).
29+
regions:
30+
- loadzone: us-east-1
31+
percent: 100
32+
33+
# Set language to the programming language used in your project. Example: 'java', 'nodejs'.
34+
language: java
35+
36+
# Set framework to the test framework used in your Selenium project.
37+
framework: serenity-cucumber
38+
39+
# Add list of file paths under 'dependencies' to help set up the test environment by installing required packages. Example: path to 'pom.xml' for Java projects using Maven, path to 'package.json' for Node.js projects.
40+
# Add list of file paths under 'testConfigs' to define which configuration files should be used to run tests. Example: path to 'playwright.config.ts' for Playwright (Node.js), path to 'testng.xml' for Selenium (TestNG).
41+
files:
42+
dependencies:
43+
- ./pom.xml
44+
testConfigs: []

serenity-cucumber/pom.xml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<groupId>com.example</groupId>
7+
<artifactId>selenium-serenity-cucumber-example</artifactId>
8+
<version>1.0-SNAPSHOT</version>
9+
<packaging>jar</packaging>
10+
11+
<properties>
12+
<maven.compiler.source>17</maven.compiler.source>
13+
<maven.compiler.target>17</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
<selenium.version>4.15.0</selenium.version>
16+
<serenity.version>4.2.16</serenity.version>
17+
<cucumber.version>7.20.1</cucumber.version>
18+
<junit.jupiter.version>5.10.1</junit.jupiter.version>
19+
<junit.platform.version>1.10.1</junit.platform.version>
20+
</properties>
21+
22+
<dependencies>
23+
<!-- Selenium WebDriver -->
24+
<dependency>
25+
<groupId>org.seleniumhq.selenium</groupId>
26+
<artifactId>selenium-java</artifactId>
27+
<version>${selenium.version}</version>
28+
</dependency>
29+
30+
<!-- Serenity BDD core -->
31+
<dependency>
32+
<groupId>net.serenity-bdd</groupId>
33+
<artifactId>serenity-core</artifactId>
34+
<version>${serenity.version}</version>
35+
</dependency>
36+
37+
<!-- Serenity Cucumber integration -->
38+
<dependency>
39+
<groupId>net.serenity-bdd</groupId>
40+
<artifactId>serenity-cucumber</artifactId>
41+
<version>${serenity.version}</version>
42+
</dependency>
43+
44+
<!-- Serenity JUnit 5 integration -->
45+
<dependency>
46+
<groupId>net.serenity-bdd</groupId>
47+
<artifactId>serenity-junit5</artifactId>
48+
<version>${serenity.version}</version>
49+
</dependency>
50+
51+
<!-- Cucumber JVM runtime -->
52+
<dependency>
53+
<groupId>io.cucumber</groupId>
54+
<artifactId>cucumber-java</artifactId>
55+
<version>${cucumber.version}</version>
56+
</dependency>
57+
58+
<!-- Cucumber JUnit 5 platform engine -->
59+
<dependency>
60+
<groupId>io.cucumber</groupId>
61+
<artifactId>cucumber-junit-platform-engine</artifactId>
62+
<version>${cucumber.version}</version>
63+
</dependency>
64+
65+
<!-- JUnit Jupiter API & Engine -->
66+
<dependency>
67+
<groupId>org.junit.jupiter</groupId>
68+
<artifactId>junit-jupiter</artifactId>
69+
<version>${junit.jupiter.version}</version>
70+
<scope>test</scope>
71+
</dependency>
72+
73+
<!-- JUnit 5 Platform Suite (used by the Cucumber runner class) -->
74+
<dependency>
75+
<groupId>org.junit.platform</groupId>
76+
<artifactId>junit-platform-suite</artifactId>
77+
<version>${junit.platform.version}</version>
78+
<scope>test</scope>
79+
</dependency>
80+
</dependencies>
81+
82+
<build>
83+
<plugins>
84+
<plugin>
85+
<groupId>org.apache.maven.plugins</groupId>
86+
<artifactId>maven-compiler-plugin</artifactId>
87+
<version>3.11.0</version>
88+
<configuration>
89+
<source>${maven.compiler.source}</source>
90+
<target>${maven.compiler.target}</target>
91+
</configuration>
92+
</plugin>
93+
<plugin>
94+
<groupId>org.apache.maven.plugins</groupId>
95+
<artifactId>maven-surefire-plugin</artifactId>
96+
<version>3.1.2</version>
97+
<configuration>
98+
<!-- Cucumber JUnit5 Suite runners commonly use either the
99+
*Test.java or *Runner.java naming convention. Surefire's
100+
default include pattern only catches Test*/Tests/TestCase
101+
names, so a runner renamed to e.g. CucumberTestRunner.java
102+
would be skipped — combined with failIfNoTests=true that
103+
surfaces to the LT pod as errorType=initialization with
104+
no log artifacts. Listing both conventions makes the
105+
build robust to runner-class renames. -->
106+
<includes>
107+
<include>**/*Runner.java</include>
108+
<include>**/*Test.java</include>
109+
<include>**/*Tests.java</include>
110+
<include>**/*TestCase.java</include>
111+
</includes>
112+
<useModulePath>false</useModulePath>
113+
<!-- Fail the build if zero scenarios execute (e.g., when every Cucumber scenario
114+
is tagged @ignore). Without this, Maven exits 0 with no work done and the
115+
load test reports a false success. -->
116+
<failIfNoTests>true</failIfNoTests>
117+
</configuration>
118+
</plugin>
119+
</plugins>
120+
</build>
121+
</project>
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.example;
2+
3+
import org.junit.platform.suite.api.ConfigurationParameter;
4+
import org.junit.platform.suite.api.IncludeEngines;
5+
import org.junit.platform.suite.api.SelectClasspathResource;
6+
import org.junit.platform.suite.api.Suite;
7+
8+
import static io.cucumber.core.options.Constants.GLUE_PROPERTY_NAME;
9+
import static io.cucumber.core.options.Constants.PLUGIN_PROPERTY_NAME;
10+
11+
/**
12+
* JUnit 5 Platform Suite that runs all Cucumber feature files.
13+
* Maven Surefire picks this class up via mvn test and executes the scenarios.
14+
*/
15+
@Suite
16+
@IncludeEngines("cucumber")
17+
@SelectClasspathResource("features")
18+
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "com.example")
19+
@ConfigurationParameter(
20+
key = PLUGIN_PROPERTY_NAME,
21+
value = "pretty, summary"
22+
)
23+
public class RunCucumberTest {
24+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package com.example;
2+
3+
import io.cucumber.java.After;
4+
import io.cucumber.java.Before;
5+
import io.cucumber.java.en.And;
6+
import io.cucumber.java.en.Given;
7+
import io.cucumber.java.en.Then;
8+
import io.cucumber.java.en.When;
9+
import org.openqa.selenium.By;
10+
import org.openqa.selenium.WebDriver;
11+
import org.openqa.selenium.WebElement;
12+
import org.openqa.selenium.chrome.ChromeOptions;
13+
import org.openqa.selenium.remote.RemoteWebDriver;
14+
import org.openqa.selenium.support.ui.WebDriverWait;
15+
16+
import java.net.URL;
17+
import java.time.Duration;
18+
19+
import static org.junit.jupiter.api.Assertions.assertEquals;
20+
21+
public class StepDefs {
22+
23+
private WebDriver driver;
24+
private String addedProductName;
25+
private static final String HUB_URL = "http://localhost:4444/wd/hub";
26+
27+
@Before
28+
public void setUp() throws Exception {
29+
ChromeOptions chromeOptions = new ChromeOptions();
30+
chromeOptions.addArguments(
31+
"--headless",
32+
"--no-first-run",
33+
"--no-default-browser-check",
34+
"--disable-extensions",
35+
"--disable-default-apps",
36+
"--disable-gpu",
37+
"--disable-dev-shm-usage",
38+
"--disable-software-rasterizer",
39+
"--no-sandbox",
40+
"--disable-background-timer-throttling",
41+
"--disable-backgrounding-occluded-windows",
42+
"--disable-renderer-backgrounding",
43+
"--disable-features=TranslateUI",
44+
"--disable-ipc-flooding-protection",
45+
"--disable-web-security",
46+
"--disable-features=VizDisplayCompositor",
47+
"--disable-logging",
48+
"--silent"
49+
);
50+
51+
driver = new RemoteWebDriver(new URL(HUB_URL), chromeOptions);
52+
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
53+
driver.manage().window().maximize();
54+
}
55+
56+
@After
57+
public void tearDown() {
58+
if (driver != null) {
59+
driver.quit();
60+
}
61+
}
62+
63+
@Given("I open the BrowserStack demo store")
64+
public void iOpenTheBrowserStackDemoStore() {
65+
driver.get("https://bstackdemo.com/");
66+
}
67+
68+
@And("I sign in to BrowserStack demo")
69+
public void iSignInToBrowserStackDemo() throws InterruptedException {
70+
driver.findElement(By.id("signin")).click();
71+
driver.findElement(By.cssSelector("#username svg")).click();
72+
driver.findElement(By.id("react-select-2-option-0-0")).click();
73+
driver.findElement(By.cssSelector("#password svg")).click();
74+
driver.findElement(By.id("react-select-3-option-0-0")).click();
75+
driver.findElement(By.id("login-btn")).click();
76+
Thread.sleep(500);
77+
}
78+
79+
@When("I add the product at index {string} to my cart")
80+
public void iAddTheProductAtIndexToMyCart(String index) {
81+
WebElement productNameElem = driver.findElement(By.cssSelector("#\\3" + index + " > p"));
82+
addedProductName = productNameElem.getText();
83+
WebElement addToCartBtn = driver.findElement(By.cssSelector("#\\3" + index + " > .shelf-item__buy-btn"));
84+
addToCartBtn.click();
85+
}
86+
87+
@Then("the same product should appear in my cart")
88+
public void theSameProductShouldAppearInMyCart() {
89+
By cartProductTitle = By.cssSelector(
90+
"#__next > div > div > div.float-cart.float-cart--open > div.float-cart__content > div.float-cart__shelf-container > div > div.shelf-item__details > p.title"
91+
);
92+
// The cart panel slides in async after the buy click; wait for its text to populate
93+
// before asserting, otherwise getText() can return an empty string.
94+
new WebDriverWait(driver, Duration.ofSeconds(10))
95+
.until(d -> !d.findElement(cartProductTitle).getText().isEmpty());
96+
assertEquals(addedProductName, driver.findElement(cartProductTitle).getText());
97+
}
98+
99+
@And("I close the cart panel")
100+
public void iCloseTheCartPanel() {
101+
driver.findElement(By.cssSelector("div.float-cart__close-btn")).click();
102+
}
103+
104+
@And("I proceed to checkout")
105+
public void iProceedToCheckout() {
106+
driver.findElement(By.cssSelector(".buy-btn")).click();
107+
}
108+
109+
@And("I fill in the shipping address")
110+
public void iFillInTheShippingAddress() {
111+
driver.findElement(By.id("firstNameInput")).sendKeys("first");
112+
driver.findElement(By.id("lastNameInput")).sendKeys("last");
113+
driver.findElement(By.id("addressLine1Input")).sendKeys("address");
114+
driver.findElement(By.id("provinceInput")).sendKeys("province");
115+
driver.findElement(By.id("postCodeInput")).sendKeys("pincode");
116+
driver.findElement(By.id("checkout-shipping-continue")).click();
117+
}
118+
119+
@Then("I should see the confirmation message {string}")
120+
public void iShouldSeeTheConfirmationMessage(String expected) {
121+
String message = driver.findElement(By.id("confirmation-message")).getText();
122+
assertEquals(expected, message);
123+
}
124+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Feature: BrowserStack Demo cart and checkout
2+
3+
Scenario: Add a product to the cart
4+
Given I open the BrowserStack demo store
5+
When I add the product at index "3" to my cart
6+
Then the same product should appear in my cart
7+
8+
Scenario: Complete a checkout
9+
Given I open the BrowserStack demo store
10+
And I sign in to BrowserStack demo
11+
When I add the product at index "1" to my cart
12+
And I close the cart panel
13+
And I add the product at index "2" to my cart
14+
And I proceed to checkout
15+
And I fill in the shipping address
16+
Then I should see the confirmation message "Your Order has been successfully placed."

0 commit comments

Comments
 (0)