I'm learning Graphene and created to page objects for a login page and a welcome page.
Loginpage
@Location("myurl/login.xhtml")
public class LoginPage {
@Drone
private WebDriver driver;
@FindBy(id = "username")
private WebElement txtUserName;
@FindBy(id = "password")
private WebElement txtPassword;
@FindBy(id = "loginbutton")
private WebElement btnLogin;
public WebElement txtUserName() {
return txtUserName;
}
public WebElement getTxtPassword() {
return txtPassword;
}
public WebElement getBtnLogin() {
return btnLogin;
}
public void login(String username, String password) {
this.txtUserName().clear();
this.getTxtPassword().clear();
this.txtUserName().sendKeys(username);
this.getTxtPassword().sendKeys(password);
// Submit form and get redirect to welcome page
Graphene.guardHttp(this.getBtnLogin()).click();
}
}
Welcome Page:
@Location("myurl/")
public class WelcomePage {
@Drone
private WebDriver driver;
@FindBy(tagName = "nav")
NavigationFragment navigation;
@FindBy(id = "version")
WebElement labelVersion;
public WebElement getLabelVersion() {
return labelVersion;
}
public NavigationFragment getNavigation() {
return navigation;
}
}
As you can see my page objects using the @Location annotation. I then created two test classes, one for each page:
Test of login page. Try to login and check element of following (welcome) page.
public class LoginpageTest {
@Drone
protected WebDriver browser;
@ArquillianResource
protected URL baseUrl;
@Test
public void testLogin(@InitialPage LoginPage page) {
// Login into page
page.login("username", "password");
// Check version label is showing correct version
WebElement versionLabel = browser.findElement(By.id("version"));
Assert.assertEquals("Wrong version", "Version 0.2.4", versionLabel.getText());
}
}
Test welcome page.
public class WelcomepageTest {
@Drone
protected WebDriver browser;
@ArquillianResource
protected URL baseUrl;
@Page
private WelcomePage page;
@Test
public void testVersion(@InitialPage LoginPage loginpage) {
// Login into page
loginpage.login("username", "password");
// Check version label is showing correct version
Assert.assertEquals("Versionslabel falsch", "Version 0.2.4", page.getLabelVersion().getText());
}
@Test
public void testSomethingElse(@InitialPage LoginPage loginpage) {
// Login into page
loginpage.login("username", "password");
// Check something else
}
}
This works, but I would like to extract the redudant login from the testcase, so that I only got one place where it's needs to be maintained. All tutorials and wiki articles I read in the past few hours always do the login over and over again in each test method. As I would like to avoid that, I tried to extract it into a @Before method like this:
public class BeforeWelcomepageTest {
@Drone
protected WebDriver browser;
@ArquillianResource
protected URL baseUrl;
@Page
private WelcomePage page;
@Before
public void login(@InitialPage LoginPage loginpage) {
// Load loginpage via @InitialPage and do login
loginpage.login("username", "password");
}
@Test
public void testVersion() {
// Login should be done via @Before - method
// Check version label is showing correct version
Assert.assertEquals("Versionslabel falsch", "Version 0.2.4", page.getLabelVersion().getText());
}
}
But this gives me the following IllegalArgumentException exception:
java.lang.IllegalArgumentException: wrong number of arguments
So I think a method annotated with @Before must not contain any arguments.
I then tried to write a @Before-method to manually open the login page, similar to suggestions in several (older) selenium questions like this one. So I created the following class but struggled on opening the url of my login page, login and "land" on my welcome page.
public class SecondBeforeWelcomepageTest {
@Drone
protected WebDriver browser;
@ArquillianResource
protected URL baseUrl;
@Page
private LoginPage loginpage;
@Page
private WelcomePage page;
@Before
public void login() {
// Load loginpage via browser
browser.get(baseURL + "myurl/");
// Same with
// Graphene.goTo(LoginPage.class)
// do login
loginpage.login("username", "password");
}
@Test
public void testVersion() {
// Login should be done via @Before - method
// Check version label is showing correct version
Assert.assertEquals("Versionslabel falsch", "Version 0.2.4", page.getLabelVersion().getText());
}
}
But this brings two problems: First the URL of my page object is hard coded in the test (maybe [using reflection API like in this question] is a workaround. Second problem is: It does not work as the WelcomePage page is not opened and therefore the version label isn't found.
org.openqa.selenium.NoSuchElementException: Unable to locate element with ID: label
Does anyone knows a solution for extract the login into a non redunant method, executed before each @Test and provide valid objects?