diff --git a/pom.xml b/pom.xml index cdd6c4522..4cca338b3 100644 --- a/pom.xml +++ b/pom.xml @@ -119,6 +119,49 @@ spring-boot-devtools true + + + + io.cucumber + cucumber-java + 6.10.3 + test + + + io.cucumber + cucumber-junit + 6.10.3 + test + + + io.cucumber + cucumber-spring + 6.10.3 + test + + + org.seleniumhq.selenium + selenium-java + 3.141.59 + + + org.junit.vintage + junit-vintage-engine + ${junit-jupiter.version} + test + + + io.github.bonigarcia + webdrivermanager + 4.4.0 + test + + + org.assertj + assertj-core + 3.19.0 + test + diff --git a/src/test/java/org/springframework/samples/petclinic/integration/Browser.java b/src/test/java/org/springframework/samples/petclinic/integration/Browser.java new file mode 100644 index 000000000..54882b0f1 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/integration/Browser.java @@ -0,0 +1,43 @@ +package org.springframework.samples.petclinic.integration; + +import java.util.concurrent.TimeUnit; + +import org.openqa.selenium.Dimension; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.chrome.ChromeDriver; +import org.openqa.selenium.chrome.ChromeDriverService; +import org.openqa.selenium.chrome.ChromeOptions; + +import io.github.bonigarcia.wdm.WebDriverManager; + +public class Browser { + public final static WebDriver webDriver = createDriver(); + + private static WebDriver createDriver() { + setupDriver(); + ChromeDriver chromeDriver = new ChromeDriver( + new ChromeDriverService.Builder().withSilent(true).build(), + chromeOptions() + ); + chromeDriver.manage().window().setSize(new Dimension(1024, 768)); + chromeDriver.manage().timeouts().implicitlyWait(0L, TimeUnit.SECONDS); + return chromeDriver; + } + + private static void setupDriver() { + WebDriverManager + .chromedriver() + .timeout(60) + .setup(); + } + + private static ChromeOptions chromeOptions() { + final ChromeOptions chromeOptions = new ChromeOptions(); + chromeOptions.addArguments("enable-automation"); + chromeOptions.addArguments("--no-sandbox"); + chromeOptions.addArguments("--disable-infobars"); + chromeOptions.addArguments("--disable-dev-shm-usage"); + chromeOptions.addArguments("--disable-browser-side-navigation"); + return chromeOptions; + } +} diff --git a/src/test/java/org/springframework/samples/petclinic/integration/CucumberRunner.java b/src/test/java/org/springframework/samples/petclinic/integration/CucumberRunner.java new file mode 100644 index 000000000..6b28fc7db --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/integration/CucumberRunner.java @@ -0,0 +1,16 @@ +package org.springframework.samples.petclinic.integration; + +import org.junit.runner.RunWith; + +import io.cucumber.junit.Cucumber; +import io.cucumber.junit.CucumberOptions; + + +@RunWith(Cucumber.class) +@CucumberOptions( + plugin = { "pretty", "html:target/cucumber-html-report" }, + glue = { "org.springframework.samples.petclinic.integration" }, + features = "classpath:scenarios" +) +public class CucumberRunner { +} diff --git a/src/test/java/org/springframework/samples/petclinic/integration/SpringIntegrationTest.java b/src/test/java/org/springframework/samples/petclinic/integration/SpringIntegrationTest.java new file mode 100644 index 000000000..a59c16b26 --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/integration/SpringIntegrationTest.java @@ -0,0 +1,10 @@ +package org.springframework.samples.petclinic.integration; + +import org.springframework.boot.test.context.SpringBootTest; + +import io.cucumber.spring.CucumberContextConfiguration; + +@CucumberContextConfiguration +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT) +public class SpringIntegrationTest { +} diff --git a/src/test/java/org/springframework/samples/petclinic/integration/StepDefinition.java b/src/test/java/org/springframework/samples/petclinic/integration/StepDefinition.java new file mode 100644 index 000000000..db06aaefd --- /dev/null +++ b/src/test/java/org/springframework/samples/petclinic/integration/StepDefinition.java @@ -0,0 +1,51 @@ +package org.springframework.samples.petclinic.integration; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import org.openqa.selenium.By; +import org.openqa.selenium.WebDriver; +import org.openqa.selenium.WebElement; +import org.openqa.selenium.support.ui.WebDriverWait; + +import io.cucumber.java.en.Given; +import io.cucumber.java.en.Then; +import io.cucumber.java.en.When; + +public class StepDefinition extends SpringIntegrationTest { + private final WebDriver webDriver = Browser.webDriver; + + @Given("^I go to the main page$") + public void mainPage() { + webDriver.navigate().to("http://localhost:8080"); + } + + @When("^I click on the link with title \"([^\"]*)\"$") + public void clickOnLinkWithTitle(String linkTitle) { + By elementSelector = By.xpath(String.format("//*[@title='%s']", linkTitle)); + new WebDriverWait(webDriver, 60L).until(driver -> driver.findElement(elementSelector).isDisplayed()); + WebElement webElement = webDriver.findElement(elementSelector); + webElement.click(); + } + + @Then("^I should see the \"([^\"]*)\" page$") + public void shouldSeeThePage(String pageTitle) { + By elementSelector = By.tagName("h2"); + new WebDriverWait(webDriver, 60L).until(driver -> driver.findElement(elementSelector).isDisplayed()); + WebElement webElement = webDriver.findElement(elementSelector); + assertThat(webElement.getText()).isEqualTo(pageTitle); + } + + @When("^I fill the field named \"([^\"]*)\" with value \"([^\"]*)\"$") + public void fillInputBoxWithValue(String name, String value) { + By elementSelector = By.name(name); + WebElement webElement = webDriver.findElement(elementSelector); + webElement.sendKeys(value); + } + + @When("^I submit the form \"([^\"]*)\"$") + public void submitForm(String id) { + By elementSelector = By.id(id); + WebElement webElement = webDriver.findElement(elementSelector); + webElement.submit(); + } +} diff --git a/src/test/resources/scenarios/AddOwners.feature b/src/test/resources/scenarios/AddOwners.feature new file mode 100644 index 000000000..e69f35b0a --- /dev/null +++ b/src/test/resources/scenarios/AddOwners.feature @@ -0,0 +1,3 @@ +Feature: Add owners + + # Add scenarios covering all cases. diff --git a/src/test/resources/scenarios/FindOwners.feature b/src/test/resources/scenarios/FindOwners.feature new file mode 100644 index 000000000..1ca6624b6 --- /dev/null +++ b/src/test/resources/scenarios/FindOwners.feature @@ -0,0 +1,14 @@ +Feature: Find owners + + Scenario: Find owners page + When I click on the link with title "find owners" + Then I should see the "Find Owners" page + + Scenario: Should find an owner + When I fill the field named "lastName" with value "Franklin" + Then I should see the "Owner Information" page + + Scenario: Should find multiple owners + When I fill the field named "lastName" with value "Davis" + Then I should see the "Owners" page + # Add additional checks here. diff --git a/src/test/resources/scenarios/MainPage.feature b/src/test/resources/scenarios/MainPage.feature new file mode 100644 index 000000000..eebeae133 --- /dev/null +++ b/src/test/resources/scenarios/MainPage.feature @@ -0,0 +1,5 @@ +Feature: Main page + + Scenario: Main page + When I go to the main page + Then I should see the "Welcome" page