Refactor Page-object pattern (#812)

* Refactor : create 2 sub-modules for page-object pattern

* Replace e.printStrackTrace with logger
This commit is contained in:
staillebois
2018-10-24 22:17:46 +02:00
committed by Ilkka Seppälä
parent 2aa9e78ddd
commit 1f1fcae513
19 changed files with 1121 additions and 18 deletions

View File

@ -0,0 +1,51 @@
<?xml version="1.0"?>
<!--
The MIT License
Copyright (c) 2014-2016 Ilkka Seppälä
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>page-object</artifactId>
<groupId>com.iluwatar</groupId>
<version>1.21.0-SNAPSHOT</version>
</parent>
<artifactId>test-automation</artifactId>
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,100 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.pageobject;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlAnchor;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import java.io.IOException;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Page Object encapsulating the Album List page (album-list.html)
*/
public class AlbumListPage extends Page {
private static final Logger LOGGER = LoggerFactory.getLogger(AlbumListPage.class);
private static final String ALBUM_LIST_HTML_FILE = "album-list.html";
private static final String PAGE_URL = "file:" + AUT_PATH + ALBUM_LIST_HTML_FILE;
private HtmlPage page;
/**
* Constructor
*/
public AlbumListPage(WebClient webClient) {
super(webClient);
}
/**
* Navigates to the Album List Page
*
* @return {@link AlbumListPage}
*/
public AlbumListPage navigateToPage() {
try {
page = this.webClient.getPage(PAGE_URL);
} catch (IOException e) {
LOGGER.error("An error occured on navigateToPage.", e);
}
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAt() {
return "Album List".equals(page.getTitleText());
}
/**
* Selects an album by the given album title
*
* @param albumTitle the title of the album to click
* @return the album page
*/
public AlbumPage selectAlbum(String albumTitle) {
// uses XPath to find list of html anchor tags with the class album in it
List<HtmlAnchor> albumLinks = (List<HtmlAnchor>) page.getByXPath("//tr[@class='album']//a");
for (HtmlAnchor anchor : albumLinks) {
if (anchor.getTextContent().equals(albumTitle)) {
try {
anchor.click();
return new AlbumPage(webClient);
} catch (IOException e) {
LOGGER.error("An error occured on selectAlbum", e);
}
}
}
throw new IllegalArgumentException("No links with the album title: " + albumTitle);
}
}

View File

@ -0,0 +1,178 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.pageobject;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlNumberInput;
import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
/**
* Page Object encapsulating the Album Page (album-page.html)
*/
public class AlbumPage extends Page {
private static final Logger LOGGER = LoggerFactory.getLogger(AlbumPage.class);
private static final String ALBUM_PAGE_HTML_FILE = "album-page.html";
private static final String PAGE_URL = "file:" + AUT_PATH + ALBUM_PAGE_HTML_FILE;
private HtmlPage page;
/**
* Constructor
*/
public AlbumPage(WebClient webClient) {
super(webClient);
}
/**
* Navigates to the album page
*
* @return {@link AlbumPage}
*/
public AlbumPage navigateToPage() {
try {
page = this.webClient.getPage(PAGE_URL);
} catch (IOException e) {
LOGGER.error("An error occured on navigateToPage.", e);
}
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAt() {
return "Album Page".equals(page.getTitleText());
}
/**
* Sets the album title input text field
*
* @param albumTitle the new album title value to set
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumTitle(String albumTitle) {
HtmlTextInput albumTitleInputTextField = (HtmlTextInput) page.getElementById("albumTitle");
albumTitleInputTextField.setText(albumTitle);
return this;
}
/**
* Sets the artist input text field
*
* @param artist the new artist value to set
* @return {@link AlbumPage}
*/
public AlbumPage changeArtist(String artist) {
HtmlTextInput artistInputTextField = (HtmlTextInput) page.getElementById("albumArtist");
artistInputTextField.setText(artist);
return this;
}
/**
* Selects the select's option value based on the year value given
*
* @param year the new year value to set
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumYear(int year) {
HtmlSelect albumYearSelectOption = (HtmlSelect) page.getElementById("albumYear");
HtmlOption yearOption = albumYearSelectOption.getOptionByValue(Integer.toString(year));
albumYearSelectOption.setSelectedAttribute(yearOption, true);
return this;
}
/**
* Sets the album rating input text field
*
* @param albumRating the new album rating value to set
* @return {@link AlbumPage}
*/
public AlbumPage changeAlbumRating(String albumRating) {
HtmlTextInput albumRatingInputTextField = (HtmlTextInput) page.getElementById("albumRating");
albumRatingInputTextField.setText(albumRating);
return this;
}
/**
* Sets the number of songs number input field
*
* @param numberOfSongs the new number of songs value to be set
* @return {@link AlbumPage}
*/
public AlbumPage changeNumberOfSongs(int numberOfSongs) {
HtmlNumberInput numberOfSongsNumberField = (HtmlNumberInput) page.getElementById("numberOfSongs");
numberOfSongsNumberField.setText(Integer.toString(numberOfSongs));
return this;
}
/**
* Cancel changes made by clicking the cancel button
*
* @return {@link AlbumListPage}
*/
public AlbumListPage cancelChanges() {
HtmlSubmitInput cancelButton = (HtmlSubmitInput) page.getElementById("cancelButton");
try {
cancelButton.click();
} catch (IOException e) {
LOGGER.error("An error occured on cancelChanges.", e);
}
return new AlbumListPage(webClient);
}
/**
* Saves changes made by clicking the save button
*
* @return {@link AlbumPage}
*/
public AlbumPage saveChanges() {
HtmlSubmitInput saveButton = (HtmlSubmitInput) page.getElementById("saveButton");
try {
saveButton.click();
} catch (IOException e) {
LOGGER.error("An error occured on saveChanges.", e);
}
return this;
}
}

View File

@ -0,0 +1,120 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.pageobject;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlPasswordInput;
import com.gargoylesoftware.htmlunit.html.HtmlSubmitInput;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Page Object encapsulating the Login Page (login.html)
*/
public class LoginPage extends Page {
private static final Logger LOGGER = LoggerFactory.getLogger(LoginPage.class);
private static final String LOGIN_PAGE_HTML_FILE = "login.html";
private static final String PAGE_URL = "file:" + AUT_PATH + LOGIN_PAGE_HTML_FILE;
private HtmlPage page;
/**
* Constructor
*
* @param webClient {@link WebClient}
*/
public LoginPage(WebClient webClient) {
super(webClient);
}
/**
* Navigates to the Login page
*
* @return {@link LoginPage}
*/
public LoginPage navigateToPage() {
try {
page = this.webClient.getPage(PAGE_URL);
} catch (IOException e) {
LOGGER.error("An error occured on navigateToPage.", e);
}
return this;
}
/**
* {@inheritDoc}
*/
@Override
public boolean isAt() {
return "Login".equals(page.getTitleText());
}
/**
* Enters the username into the username input text field
*
* @param username the username to enter
* @return {@link LoginPage}
*/
public LoginPage enterUsername(String username) {
HtmlTextInput usernameInputTextField = (HtmlTextInput) page.getElementById("username");
usernameInputTextField.setText(username);
return this;
}
/**
* Enters the password into the password input password field
*
* @param password the password to enter
* @return {@link LoginPage}
*/
public LoginPage enterPassword(String password) {
HtmlPasswordInput passwordInputPasswordField = (HtmlPasswordInput) page.getElementById("password");
passwordInputPasswordField.setText(password);
return this;
}
/**
* Clicking on the login button to 'login'
*
* @return {@link AlbumListPage}
* - this is the page that user gets navigated to once successfully logged in
*/
public AlbumListPage login() {
HtmlSubmitInput loginButton = (HtmlSubmitInput) page.getElementById("loginButton");
try {
loginButton.click();
} catch (IOException e) {
LOGGER.error("An error occured on login.", e);
}
return new AlbumListPage(webClient);
}
}

View File

@ -0,0 +1,57 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.pageobject;
import com.gargoylesoftware.htmlunit.WebClient;
/**
* Encapsulation for a generic 'Page'
*/
public abstract class Page {
/**
* Application Under Test path
* This directory location is where html web pages are located
*/
public static final String AUT_PATH = "../sample-application/src/main/resources/sample-ui/";
protected final WebClient webClient;
/**
* Constructor
*
* @param webClient {@link WebClient}
*/
public Page(WebClient webClient) {
this.webClient = webClient;
}
/**
* Checks that the current page is actually the page this page object represents
*
* @return true if so, otherwise false
*/
public abstract boolean isAt();
}

View File

@ -0,0 +1,52 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.pageobject;
import com.gargoylesoftware.htmlunit.WebClient;
import com.iluwatar.pageobject.AlbumListPage;
import com.iluwatar.pageobject.AlbumPage;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test Album Selection and Album Listing
*/
public class AlbumListPageTest {
private AlbumListPage albumListPage = new AlbumListPage(new WebClient());
@BeforeEach
public void setUp() {
albumListPage.navigateToPage();
}
@Test
public void testSelectAlbum() {
AlbumPage albumPage = albumListPage.selectAlbum("21");
albumPage.navigateToPage();
assertTrue(albumPage.isAt());
}
}

View File

@ -0,0 +1,66 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.gargoylesoftware.htmlunit.WebClient;
/**
* Test Album Page Operations
*/
public class AlbumPageTest {
private AlbumPage albumPage = new AlbumPage(new WebClient());
@BeforeEach
public void setUp() {
albumPage.navigateToPage();
}
@Test
public void testSaveAlbum() {
AlbumPage albumPageAfterChanges = albumPage
.changeAlbumTitle("25")
.changeArtist("Adele Laurie Blue Adkins")
.changeAlbumYear(2015)
.changeAlbumRating("B")
.changeNumberOfSongs(20)
.saveChanges();
assertTrue(albumPageAfterChanges.isAt());
}
@Test
public void testCancelChanges() {
AlbumListPage albumListPage = albumPage.cancelChanges();
albumListPage.navigateToPage();
assertTrue(albumListPage.isAt());
}
}

View File

@ -0,0 +1,54 @@
/**
* The MIT License
* Copyright (c) 2014-2016 Ilkka Seppälä
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* <p>
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* <p>
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.iluwatar.pageobject;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import com.gargoylesoftware.htmlunit.WebClient;
/**
* Test Login Page Object
*/
public class LoginPageTest {
private LoginPage loginPage = new LoginPage(new WebClient());
@BeforeEach
public void setUp() {
loginPage.navigateToPage();
}
@Test
public void testLogin() {
AlbumListPage albumListPage = loginPage
.enterUsername("admin")
.enterPassword("password")
.login();
albumListPage.navigateToPage();
assertTrue(albumListPage.isAt());
}
}