Skip to content

Commit fd29a09

Browse files
committed
Sample solution for Cucumber
1 parent 6207131 commit fd29a09

File tree

11 files changed

+219
-26
lines changed

11 files changed

+219
-26
lines changed

.idea/compiler.xml

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pom.xml

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<maven.compiler.source>17</maven.compiler.source>
1313
<maven.compiler.target>17</maven.compiler.target>
1414
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15-
<allure.version>2.25.0</allure.version>
15+
<allure.version>2.29.0</allure.version>
1616
<aspectj.version>1.9.21</aspectj.version>
1717
</properties>
1818

@@ -38,7 +38,28 @@
3838
<dependency>
3939
<groupId>org.junit.jupiter</groupId>
4040
<artifactId>junit-jupiter</artifactId>
41-
<version>5.11.1</version>
41+
<version>5.11.3</version>
42+
<scope>test</scope>
43+
</dependency>
44+
<dependency>
45+
<groupId>io.cucumber</groupId>
46+
<artifactId>cucumber-java</artifactId>
47+
<version>7.20.1</version>
48+
</dependency>
49+
<dependency>
50+
<groupId>io.cucumber</groupId>
51+
<artifactId>cucumber-junit</artifactId>
52+
<version>7.20.1</version>
53+
</dependency>
54+
<dependency>
55+
<groupId>io.cucumber</groupId>
56+
<artifactId>cucumber-junit-platform-engine</artifactId>
57+
<version>7.20.1</version>
58+
</dependency>
59+
<dependency>
60+
<groupId>org.junit.platform</groupId>
61+
<artifactId>junit-platform-suite</artifactId>
62+
<version>1.11.3</version>
4263
<scope>test</scope>
4364
</dependency>
4465
<dependency>
@@ -56,9 +77,29 @@
5677
<artifactId>allure-junit5</artifactId>
5778
<scope>test</scope>
5879
</dependency>
80+
<dependency>
81+
<groupId>io.qameta.allure</groupId>
82+
<artifactId>allure-cucumber7-jvm</artifactId>
83+
<scope>test</scope>
84+
</dependency>
85+
<dependency>
86+
<groupId>io.qameta.allure</groupId>
87+
<artifactId>allure-junit-platform</artifactId>
88+
<scope>test</scope>
89+
</dependency>
5990
</dependencies>
6091
<build>
6192
<plugins>
93+
<plugin>
94+
<groupId>org.apache.maven.plugins</groupId>
95+
<artifactId>maven-compiler-plugin</artifactId>
96+
<version>3.8.1</version>
97+
<configuration>
98+
<compilerArgs>
99+
<arg>-parameters</arg>
100+
</compilerArgs>
101+
</configuration>
102+
</plugin>
62103
<plugin>
63104
<groupId>org.apache.maven.plugins</groupId>
64105
<artifactId>maven-surefire-plugin</artifactId>

src/test/java/com/serenitydojo/playwright/toolshop/catalog/AddToCartTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.serenitydojo.playwright.toolshop.catalog.pageobjects.*;
44
import com.serenitydojo.playwright.toolshop.fixtures.PlaywrightTestCase;
5+
import io.qameta.allure.Feature;
6+
import io.qameta.allure.Story;
57
import org.assertj.core.api.Assertions;
68
import org.junit.jupiter.api.BeforeEach;
79
import org.junit.jupiter.api.DisplayName;
@@ -10,6 +12,7 @@
1012
import java.util.List;
1113

1214
@DisplayName("Shopping Cart")
15+
@Feature("Shopping Cart")
1316
public class AddToCartTest extends PlaywrightTestCase {
1417

1518
SearchComponent searchComponent;
@@ -33,6 +36,7 @@ void setUp() {
3336
}
3437

3538
@Test
39+
@Story("Check out")
3640
@DisplayName("Checking out a single item")
3741
void whenCheckingOutASingleItem() {
3842
searchComponent.searchBy("pliers");
@@ -56,6 +60,7 @@ void whenCheckingOutASingleItem() {
5660
}
5761

5862
@Test
63+
@Story("Check out")
5964
@DisplayName("Checking out multiple items")
6065
void whenCheckingOutMultipleItems() {
6166
navBar.openHomePage();

src/test/java/com/serenitydojo/playwright/toolshop/catalog/SearchForProductsTest.java

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import com.serenitydojo.playwright.toolshop.catalog.pageobjects.ProductList;
44
import com.serenitydojo.playwright.toolshop.catalog.pageobjects.SearchComponent;
55
import com.serenitydojo.playwright.toolshop.fixtures.PlaywrightTestCase;
6+
import io.qameta.allure.Feature;
7+
import io.qameta.allure.Story;
68
import org.assertj.core.api.Assertions;
79
import org.junit.jupiter.api.BeforeEach;
810
import org.junit.jupiter.api.DisplayName;
911
import org.junit.jupiter.api.Nested;
1012
import org.junit.jupiter.api.Test;
1113

1214
@DisplayName("Searching for products")
15+
@Feature("Searching for products")
1316
public class SearchForProductsTest extends PlaywrightTestCase {
1417

1518
@BeforeEach
@@ -19,6 +22,7 @@ void openHomePage() {
1922

2023
@Nested
2124
@DisplayName("Searching by keyword")
25+
@Story("Searching by keyword")
2226
class SearchingByKeyword {
2327

2428
@Test
@@ -46,21 +50,22 @@ void whenThereIsNoMatchingProduct() {
4650
Assertions.assertThat(matchingProducts).isEmpty();
4751
Assertions.assertThat(productList.getSearchCompletedMessage()).contains("There are no products found.");
4852
}
53+
}
4954

50-
@Test
51-
@DisplayName("When the user clears a previous search results")
52-
void clearingTheSearchResults() {
53-
SearchComponent searchComponent = new SearchComponent(page);
54-
ProductList productList = new ProductList(page);
55-
searchComponent.searchBy("saw");
55+
@Test
56+
@Story("Clearing the previous search results")
57+
@DisplayName("When the user clears a previous search results")
58+
void clearingTheSearchResults() {
59+
SearchComponent searchComponent = new SearchComponent(page);
60+
ProductList productList = new ProductList(page);
61+
searchComponent.searchBy("saw");
5662

57-
var matchingFilteredProducts = productList.getProductNames();
58-
Assertions.assertThat(matchingFilteredProducts).hasSize(2);
63+
var matchingFilteredProducts = productList.getProductNames();
64+
Assertions.assertThat(matchingFilteredProducts).hasSize(2);
5965

60-
searchComponent.clearSearch();
66+
searchComponent.clearSearch();
6167

62-
var matchingProducts = productList.getProductNames();
63-
Assertions.assertThat(matchingProducts).hasSize(9);
64-
}
68+
var matchingProducts = productList.getProductNames();
69+
Assertions.assertThat(matchingProducts).hasSize(9);
6570
}
6671
}

src/test/java/com/serenitydojo/playwright/toolshop/contact/ContactFormTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.serenitydojo.playwright.toolshop.catalog.pageobjects.NavBar;
55
import com.serenitydojo.playwright.toolshop.fixtures.PlaywrightTestCase;
66
import io.qameta.allure.Allure;
7+
import io.qameta.allure.Feature;
8+
import io.qameta.allure.Story;
79
import org.assertj.core.api.Assertions;
810
import org.junit.jupiter.api.BeforeEach;
911
import org.junit.jupiter.api.DisplayName;
@@ -18,19 +20,20 @@
1820
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
1921

2022
@DisplayName("Contact form")
23+
@Feature("Contact form")
2124
public class ContactFormTest extends PlaywrightTestCase {
2225

2326
ContactForm contactForm;
2427
NavBar navigate;
2528

26-
@DisplayName("When submitting a request")
2729
@BeforeEach
2830
void openContactPage() {
2931
contactForm = new ContactForm(page);
3032
navigate = new NavBar(page);
3133
navigate.toTheContactPage();
3234
}
3335

36+
@Story("Submitting a request")
3437
@DisplayName("Customers can use the contact form to contact us")
3538
@Test
3639
void completeForm() throws URISyntaxException {
@@ -49,12 +52,11 @@ void completeForm() throws URISyntaxException {
4952
.contains("Thanks for your message! We will contact you shortly.");
5053
}
5154

55+
@Story("Submitting a request")
5256
@DisplayName("First name, last name, email and message are mandatory")
53-
@ParameterizedTest
57+
@ParameterizedTest(name = "{arguments} is a mandatory field")
5458
@ValueSource(strings = {"First name", "Last name", "Email", "Message"})
5559
void mandatoryFields(String fieldName) {
56-
Allure.parameter("fieldName", fieldName);
57-
5860
// Fill in the field values
5961
contactForm.setFirstName("Sarah-Jane");
6062
contactForm.setLastName("Smith");
@@ -73,6 +75,7 @@ void mandatoryFields(String fieldName) {
7375
assertThat(errorMessage).isVisible();
7476
}
7577

78+
@Story("Submitting a request")
7679
@DisplayName("The message must be at least 50 characters long")
7780
@Test
7881
void messageTooShort() {
@@ -88,12 +91,11 @@ void messageTooShort() {
8891
assertThat(page.getByRole(AriaRole.ALERT)).hasText("Message must be minimal 50 characters");
8992
}
9093

94+
@Story("Submitting a request")
9195
@DisplayName("The email address must be correctly formatted")
92-
@ParameterizedTest
96+
@ParameterizedTest(name = "'{arguments}' should be rejected")
9397
@ValueSource(strings = {"not-an-email", "not-an.email.com", "notanemail"})
9498
void invalidEmailField(String invalidEmail) {
95-
Allure.parameter("invalidEmail", invalidEmail);
96-
9799
contactForm.setFirstName("Sarah-Jane");
98100
contactForm.setLastName("Smith");
99101
contactForm.setEmail(invalidEmail);
@@ -104,6 +106,4 @@ void invalidEmailField(String invalidEmail) {
104106

105107
assertThat(page.getByRole(AriaRole.ALERT)).hasText("Email format is invalid");
106108
}
107-
108-
109109
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.serenitydojo.playwright.toolshop.cucumber;
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+
@Suite
9+
@IncludeEngines("cucumber")
10+
@ConfigurationParameter(key="cucumber.plugin",
11+
value = "io.qameta.allure.cucumber7jvm.AllureCucumber7Jvm, " +
12+
"pretty, " +
13+
"html:target/cucumber-reports/cucumber.html, " +
14+
"json:target/cucumber-reports/cucumber.json")
15+
@SelectClasspathResource("/features")
16+
public class AcceptanceTestSuite {
17+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package com.serenitydojo.playwright.toolshop.cucumber;
2+
3+
import com.microsoft.playwright.*;
4+
import io.cucumber.java.After;
5+
import io.cucumber.java.AfterAll;
6+
import io.cucumber.java.Before;
7+
import io.cucumber.java.BeforeAll;
8+
9+
import java.util.Arrays;
10+
11+
public class PlaywrightHooks {
12+
13+
static Playwright playwright;
14+
static Browser browser;
15+
16+
static ThreadLocal<BrowserContext> contextHolder = new ThreadLocal<>();
17+
static ThreadLocal<Page> pageHolder = new ThreadLocal<>();
18+
19+
@BeforeAll
20+
public static void beforeAll() {
21+
playwright = Playwright.create();
22+
playwright.selectors().setTestIdAttribute("data-test");
23+
browser = playwright.chromium().launch(
24+
new BrowserType.LaunchOptions()
25+
.setHeadless(true)
26+
.setArgs(Arrays.asList("--no-sandbox", "--disable-extensions", "--disable-gpu"))
27+
);
28+
}
29+
30+
@Before(order = 100)
31+
public void beforeEach() {
32+
contextHolder.set(browser.newContext());
33+
pageHolder.set(browser.newPage());
34+
}
35+
36+
@After
37+
public void shutdownContext() {
38+
if (contextHolder.get() != null) {
39+
contextHolder.get().close();
40+
contextHolder.remove();
41+
}
42+
}
43+
44+
@AfterAll
45+
public static void afterAll() {
46+
if (playwright != null) {
47+
playwright.close();
48+
}
49+
}
50+
51+
public static Page getPage() {
52+
return pageHolder.get();
53+
}
54+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.serenitydojo.playwright.toolshop.cucumber;
2+
3+
import com.serenitydojo.playwright.toolshop.catalog.pageobjects.NavBar;
4+
import com.serenitydojo.playwright.toolshop.catalog.pageobjects.ProductList;
5+
import com.serenitydojo.playwright.toolshop.catalog.pageobjects.SearchComponent;
6+
import io.cucumber.java.Before;
7+
import io.cucumber.java.en.Given;
8+
import io.cucumber.java.en.Then;
9+
import io.cucumber.java.en.When;
10+
11+
import java.util.List;
12+
13+
import static org.assertj.core.api.Assertions.assertThat;
14+
15+
public class SearchStepDefinitions {
16+
17+
NavBar navBar;
18+
ProductList productList;
19+
SearchComponent searchComponent;
20+
21+
@Before
22+
public void setUp() {
23+
navBar = new NavBar(PlaywrightHooks.getPage());
24+
searchComponent = new SearchComponent(PlaywrightHooks.getPage());
25+
productList = new ProductList(PlaywrightHooks.getPage());
26+
}
27+
28+
@Given("Sharon is on the home page")
29+
public void sharon_is_on_the_home_page() {
30+
navBar.openHomePage();
31+
}
32+
33+
@When("she searches for {string}")
34+
public void she_searches_for(String searchTerm) {
35+
searchComponent.searchBy(searchTerm);
36+
37+
}
38+
39+
@Then("she should be presented with the following products:")
40+
public void she_should_be_presented_with_the_following_products(List<String> expectedProducts) {
41+
42+
var matchingProducts = productList.getProductNames();
43+
44+
assertThat(matchingProducts).containsExactlyElementsOf(expectedProducts);
45+
}
46+
47+
@Then("she should not see any products")
48+
public void she_should_not_see_any_products() {
49+
var matchingProducts = productList.getProductNames();
50+
assertThat(matchingProducts).isEmpty();
51+
}
52+
53+
}

src/test/java/com/serenitydojo/playwright/toolshop/fixtures/PlaywrightTestCase.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ public abstract class PlaywrightTestCase {
1919

2020
protected static ThreadLocal<Browser> browser = ThreadLocal.withInitial(() ->
2121
playwright.get().chromium().launch(
22-
new BrowserType.LaunchOptions().setHeadless(true)
22+
new BrowserType.LaunchOptions()
23+
.setHeadless(true)
2324
.setArgs(Arrays.asList("--no-sandbox", "--disable-extensions", "--disable-gpu"))
2425
)
2526
);

0 commit comments

Comments
 (0)