Commit 662524b1 authored by Kristjan Kruus's avatar Kristjan Kruus

Merge pull request #34 in RIHA/riha-browser from...

Merge pull request #34 in RIHA/riha-browser from feature/RIHAKB-881-riha-haldajana-soovin-et-riha-funktsionaalsuse-manuaalsed-testid-oleks to develop

* commit 'dbaf1ed1':
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud;
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud;
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud; fixed jUnit version
  RIHAKB-860, RIHA haldajana soovin, et RIHA manuaalsed funktsionaalsuse testid oleks võimalikult suures ulatuses automatiseeritud; first test
parents fe279126 dbaf1ed1
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>autotest</artifactId>
<name>Autotest</name>
<description>Automated UI tests</description>
<parent>
<artifactId>browser</artifactId>
<groupId>ee.ria.riha</groupId>
<version>7.5.2</version>
</parent>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>3.141.59</version>
</dependency>
<dependency>
<groupId>io.github.bonigarcia</groupId>
<artifactId>webdrivermanager</artifactId>
<version>3.7.1</version>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>4.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>4.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.12.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package ee.ria.riha;
public final class Timeouts {
public static final int TABLE_SORT_TIMEOUT = 2000;
public static final int DISPLAY_ELEMENT_TIMEOUT = 15;
}
package ee.ria.riha.context;
import java.util.HashMap;
import java.util.Map;
public class ScenarioContext {
public static final String APP_URL_KEY = "appUrl";
public static final String SEARCH_TEXT_KEY = "searchText";
public static final String NAME_KEY = "name";
public static final String SHORT_NAME_KEY = "shortName";
public static final String HOMEPAGE_KEY = "homepage";
public static final String PURPOSE_KEY = "purpose";
public static final String LAST_INFOSYSTEM_NUMBER = "lastInfosystemNumber";
public static final String DEFAULT_APP_URL = "https://riha-browser-ik.ci.kit";
private final Map<String, String> context = new HashMap<>();
public ScenarioContext() {
String url = System.getProperty("url");
if (url == null) {
url = DEFAULT_APP_URL;
}
context.put(APP_URL_KEY, url);
}
public void saveToContext(String key, String value) {
context.put(key, value);
}
public String getFromContext(String key) {
return context.get(key);
}
public void clear() {
context.clear();
}
}
package ee.ria.riha.driver;
import ee.ria.riha.pages.PageFactory;
import io.cucumber.java.Before;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Setup {
public static WebDriver driver;
public static PageFactory pageFactory;
@Before
public void init() {
String browser = System.getProperty("browser");
if (browser == null) {
browser = "chrome";
}
switch (browser) {
case "chrome":
WebDriverManager.chromedriver().setup();
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.addArguments("start-maximized");
driver = new ChromeDriver(chromeOptions);
break;
case "firefox":
WebDriverManager.firefoxdriver().setup();
driver = new FirefoxDriver();
driver.manage().window().maximize();
break;
default:
throw new IllegalArgumentException("Browser \"" + browser + "\" isn't supported.");
}
pageFactory = new PageFactory();
}
}
package ee.ria.riha.driver;
import io.cucumber.core.api.Scenario;
import io.cucumber.java.After;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
public class TearDown {
private WebDriver driver;
public TearDown() {
this.driver = Setup.driver;
}
@After
public void quitDriver(Scenario scenario) {
if (scenario.isFailed()) {
saveScreenshotsForScenario(scenario);
}
this.driver.quit();
}
private void saveScreenshotsForScenario(final Scenario scenario) {
final byte[] screenshot = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.BYTES);
scenario.embed(screenshot, "image/png");
}
}
package ee.ria.riha.driver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.util.List;
public class Wait {
private WebDriver driver;
public Wait(WebDriver driver) {
this.driver = driver;
}
private void waitUntilCondition(ExpectedCondition condition, String timeoutMessage, int timeout) {
WebDriverWait wait = new WebDriverWait(driver, timeout);
wait.withMessage(timeoutMessage);
wait.until(condition);
}
public void forElementToBeDisplayed(int timeout, WebElement webElement, String webElementName) {
ExpectedCondition<WebElement> condition = ExpectedConditions.visibilityOf(webElement);
String timeoutMessage = webElementName + " wasn't displayed after " + Integer.toString(timeout) + " seconds.";
waitUntilCondition(condition, timeoutMessage, timeout);
}
public void forPresenceOfElements(int timeout, By elementLocator, String elementName) {
ExpectedCondition<List<WebElement>> condition = ExpectedConditions.presenceOfAllElementsLocatedBy(elementLocator);
String timeoutMessage = elementName + " elements were not displayed after " + Integer.toString(timeout) + " seconds.";
waitUntilCondition(condition, timeoutMessage, timeout);
}
public void sleep(int timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package ee.ria.riha.pages;
import ee.ria.riha.context.ScenarioContext;
import ee.ria.riha.driver.Setup;
import ee.ria.riha.driver.Wait;
import org.openqa.selenium.WebDriver;
public class BasePage {
protected WebDriver driver;
protected Wait wait;
protected ScenarioContext scenarioContext;
public BasePage(ScenarioContext scenarioContext) {
this.driver = Setup.driver;
this.wait = new Wait(driver);
this.scenarioContext = scenarioContext;
}
public String getCurrentUrl() {
return driver.getCurrentUrl();
}
public ScenarioContext getScenarioContext() {
return scenarioContext;
}
}
package ee.ria.riha.pages;
import ee.ria.riha.context.ScenarioContext;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import static ee.ria.riha.Timeouts.DISPLAY_ELEMENT_TIMEOUT;
public class HomePage extends BasePage {
@FindBy(xpath = "//img[@src='assets/images/base/RIHA.png']")
private WebElement logo;
@FindBy(css = ".btn > span:nth-child(1)")
private WebElement loginButton;
@FindBy(css = ".card:nth-child(2) .btn")
private WebElement goToMyInfosystemsPageButton;
@FindBy(css = ".nav-item:nth-child(2) > .nav-link")
private WebElement goToInfosystemsPageLink;
@FindBy(tagName = "ngb-modal-window")
private WebElement modalContainer;
public HomePage(ScenarioContext scenarioContext) {
super(scenarioContext);
PageFactory.initElements(driver, this);
}
public void goToPage(String path) {
String url = scenarioContext.getFromContext(ScenarioContext.APP_URL_KEY);
driver.get(url + path);
checkLogoDisplay();
}
public void checkLogoDisplay() {
wait.forElementToBeDisplayed(DISPLAY_ELEMENT_TIMEOUT, this.logo, "Logo");
}
public String getTitle() {
return driver.getTitle();
}
public String getLoggedInUsersName() {
return this.driver.findElement(By.cssSelector(".right a")).getText();
}
public void selectSecondOrganization() {
wait.forPresenceOfElements(25, By.tagName("ngb-modal-window"), "modal");
modalContainer.findElement(By.cssSelector("tr:nth-child(2) > td")).click();
}
public void selectOrganization(String organization) {
driver.findElement(By.cssSelector(".right a")).click();
wait.forPresenceOfElements(2, By.tagName("ngb-modal-window"), "modal");
modalContainer.findElement(By.xpath("//td[contains(.,'" + organization +"')]")).click();
}
public void goToLoginPage() {
loginButton.click();
}
public void goToMyInfosystemsPage() {
goToMyInfosystemsPageButton.click();
}
public void goToInfosystemsPage() {
goToInfosystemsPageLink.click();
}
}
\ No newline at end of file
This diff is collapsed.
package ee.ria.riha.pages;
import ee.ria.riha.context.ScenarioContext;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static ee.ria.riha.Timeouts.DISPLAY_ELEMENT_TIMEOUT;
import static ee.ria.riha.Timeouts.TABLE_SORT_TIMEOUT;
public class InfosystemsPage extends BasePage {
@FindBy(xpath = "//main[@id='content']/app-browser-list/section/div[2]/a")
private WebElement detailedSearchLink;
@FindBy(id = "owner-name-input")
private WebElement ownerInput;
@FindBy(id = "name-input")
private WebElement nameInput;
@FindBy(id = "topics-input")
private WebElement topicsInput;
@FindBy(id = "info-systems-table")
private WebElement infosystemsTable;
public InfosystemsPage(ScenarioContext scenarioContext) {
super(scenarioContext);
PageFactory.initElements(driver, this);
}
public List<String> getFoundInfosystemsTopics() {
waitForLoading();
List<String> topics = new ArrayList<>();
List<WebElement> tableRows = infosystemsTable.findElements(By.tagName("tr"));
tableRows.forEach(row -> {
if (row.findElements(By.className("topics")).size() > 0) {
topics.add(row.findElement(By.className("topics")).findElements(By.tagName("button")).stream().map(WebElement::getText).collect(Collectors.joining(",")));
}
});
return topics;
}
public List<String> getFoundInfosystemsShortName() {
waitForLoading();
List<String> sortNames = new ArrayList<>();
List<WebElement> tableRows = infosystemsTable.findElements(By.tagName("tr"));
tableRows.forEach(row -> {
sortNames.add(row.findElement(By.xpath("//td[2]")).findElement(By.tagName("a")).getText());
});
return sortNames;
}
public void openDetailedSearchForm() {
waitForLoading();
detailedSearchLink.click();
}
public String getTopicInputText() {
waitForLoading();
return topicsInput.getAttribute("value");
}
public String getOwnerInputText() {
return ownerInput.getAttribute("value");
}
public String getNameInputText() {
return nameInput.getAttribute("value");
}
public void searchByOwnerNameAndTopic(String owner, String name, String topic) {
ownerInput.sendKeys(owner);
nameInput.sendKeys(name);
topicsInput.sendKeys(topic);
topicsInput.sendKeys(Keys.RETURN);
waitForLoading();
}
private void waitForLoading() {
wait.forElementToBeDisplayed(DISPLAY_ELEMENT_TIMEOUT, infosystemsTable, "info-systems-table");
wait.sleep(TABLE_SORT_TIMEOUT);
}
}
package ee.ria.riha.pages;
import ee.ria.riha.context.ScenarioContext;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class LoginPage extends BasePage {
@FindBy(css = ".c-tab-login__nav-label > .icon-mobile-id")
private WebElement mobiilIdTab;
@FindBy(id = "mid-personal-code")
private WebElement isikukoodInput;
@FindBy(id = "mid-phone-number")
private WebElement telefoninumberInput;
@FindBy(css = "tr:nth-child(3) .c-btn")
private WebElement jatkanButton;
public LoginPage(ScenarioContext scenarioContext) {
super(scenarioContext);
PageFactory.initElements(driver, this);
}
public void selectMobiilIdTab() {
mobiilIdTab.click();
}
public void enterIsikukoodAndTelefoninumber(String personalCode, String phoneNumber) {
isikukoodInput.sendKeys(personalCode);
telefoninumberInput.sendKeys(phoneNumber);
jatkanButton.click();
}
}
package ee.ria.riha.pages;
import ee.ria.riha.context.ScenarioContext;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import static ee.ria.riha.Timeouts.DISPLAY_ELEMENT_TIMEOUT;
import static ee.ria.riha.Timeouts.TABLE_SORT_TIMEOUT;
import static ee.ria.riha.context.ScenarioContext.LAST_INFOSYSTEM_NUMBER;
import static ee.ria.riha.context.ScenarioContext.SEARCH_TEXT_KEY;
public class MyInfosystemsPage extends BasePage {
@FindBy(xpath = "//main[@id='content']/app-producer-list/section/div[2]/a[4]")
private WebElement detailedSearchLink;
@FindBy(id = "search-text-input")
private WebElement searchTextInput;
@FindBy(id = "topics-input")
private WebElement topicsInput;
@FindBy(id = "name-input")
private WebElement nameInput;
@FindBy(id = "short-name-input")
private WebElement shortNameInput;
@FindBy(id = "purpose-textarea")
private WebElement purposeInput;
@FindBy(css = ".table-responsive > .btn")
private WebElement createNewLink;
@FindBy(xpath = "//button[@type='submit']")
private WebElement submitButton;
@FindBy(id = "infosystems-table")
private WebElement infosystemsTable;
@FindBy(xpath = "//table[@id='infosystems-table']/thead/th/app-sort-button/button")
private WebElement sortByShortNameButton;
public MyInfosystemsPage(ScenarioContext scenarioContext) {
super(scenarioContext);
PageFactory.initElements(driver, this);
}
public void openDetailedSearchForm() {
detailedSearchLink.click();
}
public void searchByTopic(String topic) {
topicsInput.sendKeys(topic);
topicsInput.sendKeys(Keys.RETURN);
}
public List<String> getFoundInfosystemsTopics() {
waitForLoading();
List<String> topics = new ArrayList<>();
List<WebElement> tableRows = infosystemsTable.findElements(By.tagName("tr"));
tableRows.forEach(row -> {
topics.add(row.findElement(By.className("topics")).findElements(By.tagName("button")).stream().map(WebElement::getText).collect(Collectors.joining(",")));
});
return topics;
}
public void goToInfosystemPage(String infosystem) {
driver.findElement(By.linkText(infosystem)).click();
}
public void goToCreateNewInfosystemPage() {
wait.forElementToBeDisplayed(DISPLAY_ELEMENT_TIMEOUT, createNewLink, "createNewLink");
createNewLink.click();
}
public void enterNameShortNameAndPurpose(String namePrefix, String shortNamePrefix, String purpose) {
String lastCreatedInfosystemNumber = scenarioContext.getFromContext(LAST_INFOSYSTEM_NUMBER);
int i = Integer.parseInt(lastCreatedInfosystemNumber);
i++;
nameInput.sendKeys(namePrefix + " " + i);
shortNameInput.sendKeys(shortNamePrefix + "-" + i);
purposeInput.sendKeys(purpose);
submitButton.click();
}
public void enterSearchText(String text) {
waitForLoading();
scenarioContext.saveToContext(SEARCH_TEXT_KEY, text);
searchTextInput.sendKeys(text);
searchTextInput.sendKeys(Keys.RETURN);
waitForLoading();
}
public void sortByShortNameDesc() {
sortByShortNameButton.click(); //asc
waitForLoading();
sortByShortNameButton.click(); //desc
waitForLoading();
}
public void saveFirstFoundInfosystemShortNameToScenarioContext() {
WebElement firstRow = infosystemsTable.findElement(By.xpath("//tr[1]"));
String shortName = firstRow.findElement(By.xpath("//td[1]")).findElement(By.tagName("a")).getText();
scenarioContext.saveToContext(LAST_INFOSYSTEM_NUMBER, shortName.substring(scenarioContext.getFromContext(SEARCH_TEXT_KEY).length() + 1));
}
public void selectFirstFoundInfosystem() {
WebElement firstRow = infosystemsTable.findElement(By.xpath("//tr[1]"));
firstRow.findElement(By.xpath("//td[1]")).findElement(By.tagName("a")).click();
}
private void waitForLoading() {
wait.forElementToBeDisplayed(DISPLAY_ELEMENT_TIMEOUT, infosystemsTable, "infosystems-table");
wait.sleep(TABLE_SORT_TIMEOUT);
}
}
package ee.ria.riha.pages;
import ee.ria.riha.context.ScenarioContext;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class PageFactory {
private ScenarioContext scenarioContext;
private Map<Class, Object> pages;
public PageFactory() {
pages = new HashMap<>();
scenarioContext = new ScenarioContext();
}
public <T extends BasePage> T getPage(Class<T> pageClass) {
try {
T page = (T) pages.get(pageClass);
if (page == null) {
page = pageClass.getDeclaredConstructor(ScenarioContext.class).newInstance(scenarioContext);
pages.put(pageClass, page);
}
return page;
} catch (Exception e) {
log.error("Error creating page", e);
throw new RuntimeException("Error creating page");
}
}
}
package ee.ria.riha;
import ee.ria.riha.driver.Setup;
import ee.ria.riha.pages.HomePage;
import ee.ria.riha.pages.LoginPage;
import io.cucumber.java.en.Given;
public class BackgroundSteps {
private HomePage homePage;
private LoginPage loginPage;
public BackgroundSteps() {
loginPage = Setup.pageFactory.getPage(LoginPage.class);
homePage = Setup.pageFactory.getPage(HomePage.class);
}
@Given("User is logged in to {string} as {string} using tel. number {string}")
public void userIsLoggedInAsTestUser(String url, String personalCode, String phoneNumber) {
homePage.goToPage(url);
homePage.goToLoginPage();
loginPage.selectMobiilIdTab();
loginPage.enterIsikukoodAndTelefoninumber(personalCode, phoneNumber);
homePage.selectSecondOrganization();
}
}
package ee.ria.riha;
import io.cucumber.junit.Cucumber;
import io.cucumber.junit.CucumberOptions;
import org.junit.runner.RunWith;
@RunWith(Cucumber.class)
@CucumberOptions(features = {"src/test/resources/ee/ria/riha/SearchInfosystems.feature"},
strict = false, plugin = {"pretty",
"json:target/cucumber_json_reports/search-infosystems-page.json",
"html:target/search-infosystems-page-html"},
glue = {"ee.ria.riha"})
public class SearchInfosytemsTest {
}
package ee.ria.riha.homepage;
import ee.ria.riha.driver.Setup;
import ee.ria.riha.pages.HomePage;