diff --git a/page-object/pom.xml b/page-object/pom.xml
index 62a8214cb..ae239725d 100644
--- a/page-object/pom.xml
+++ b/page-object/pom.xml
@@ -32,20 +32,9 @@
+ * Due to this reason, it has become very popular within the test automation community. + * In particular, it is very common in that the page object is used to represent the html pages of a + * web application that is under test. This web application is referred to as AUT (Application Under Test). + * A web browser automation tool/framework like Selenium for instance, is then used to drive the automating + * of the browser navigation and user actions journeys through this web application. Your test class would + * therefore only be responsible for particular test cases and page object would be used by the test class + * for UI manipulation required for the tests. + * + *
+ * In this implementation rather than using Selenium, the HtmlUnit library is used as a replacement to + * represent the specific html elements and to drive the browser. The purpose of this example is just to + * provide a simple version that showcase the intentions of this pattern and how this pattern is used + * in order to understand it. + */ +public final class App { + + private static final Logger LOGGER = LoggerFactory.getLogger(App.class); + private App() { + } + + /** + * Application entry point + * + *
+ * The application under development is a web application. Normally you would probably have a + * backend that is probably implemented in an object-oriented language (e.g. Java) that serves + * the frontend which comprises of a series of HTML, CSS, JS etc... + * + *
+ * For illustrations purposes only, a very simple static html app is used here. This main method + * just fires up this simple web app in a default browser. + * + * @param args arguments + */ + public static void main(String[] args) { + + try { + File applicationFile = new File(App.class.getClassLoader().getResource("sample-ui/login.html").getPath()); + + // should work for unix like OS (mac, unix etc...) + if (Desktop.isDesktopSupported()) { + Desktop.getDesktop().open(applicationFile); + + } else { + // java Desktop not supported - above unlikely to work for Windows so try following instead... + Runtime.getRuntime().exec("cmd.exe start " + applicationFile); + } + + } catch (IOException ex) { + LOGGER.error("An error occured.", ex); + } + + } +} diff --git a/page-object/sample-application/src/main/resources/sample-ui/album-list.html b/page-object/sample-application/src/main/resources/sample-ui/album-list.html new file mode 100644 index 000000000..7e674c60a --- /dev/null +++ b/page-object/sample-application/src/main/resources/sample-ui/album-list.html @@ -0,0 +1,60 @@ + + + +
+ +Album Title | +Album Year | +Album Rating | +Number of Songs | +Artist | +
---|---|---|---|---|
21 | +2011 | +A | +11 | +Adele | +
+ * 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.
+ */
+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
+ * 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.
+ */
+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;
+ }
+
+}
diff --git a/page-object/test-automation/src/main/java/com/iluwatar/pageobject/LoginPage.java b/page-object/test-automation/src/main/java/com/iluwatar/pageobject/LoginPage.java
new file mode 100644
index 000000000..942bd6f61
--- /dev/null
+++ b/page-object/test-automation/src/main/java/com/iluwatar/pageobject/LoginPage.java
@@ -0,0 +1,120 @@
+/**
+ * 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.
+ */
+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);
+ }
+
+}
diff --git a/page-object/test-automation/src/main/java/com/iluwatar/pageobject/Page.java b/page-object/test-automation/src/main/java/com/iluwatar/pageobject/Page.java
new file mode 100644
index 000000000..f6765b8ce
--- /dev/null
+++ b/page-object/test-automation/src/main/java/com/iluwatar/pageobject/Page.java
@@ -0,0 +1,57 @@
+/**
+ * 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.
+ */
+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();
+
+
+}
diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java
new file mode 100644
index 000000000..16e008b8f
--- /dev/null
+++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumListPageTest.java
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ */
+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());
+ }
+
+}
diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java
new file mode 100644
index 000000000..ca48fff88
--- /dev/null
+++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/AlbumPageTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.
+ */
+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());
+ }
+
+}
diff --git a/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java
new file mode 100644
index 000000000..b471db3cb
--- /dev/null
+++ b/page-object/test-automation/src/test/java/com/iluwatar/pageobject/LoginPageTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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.
+ */
+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());
+ }
+
+}
diff --git a/pom.xml b/pom.xml
index 69af36c57..84cf41535 100644
--- a/pom.xml
+++ b/pom.xml
@@ -289,7 +289,6 @@