patternjavaMinor
Selenium Framework using a lot of statics
Viewed 0 times
staticsseleniumlotusingframework
Problem
I am writing a Selenium framework that should be really easy for a tester with relatively little Java knowledge to use and write tests for. In order to keep the framework as user friendly as possible, I've noticed that I am writing a lot of statics so that the tester doesn't have to instantiate the page objects and methods every time. This of course goes against the principles of OOP. Before I get in too deep with this I'd like to see if there are viable alternatives to my approach. I'm including below the login page class that instantiates a webdriver Singleton, has a username/password field, and a login button. There are 2 tests for this page that are run using TestNG. All code to follow:
LoginPage.java
```
public class LoginPage {
public static WebDriver driver;
private static String username_selector = "username";
private static String password_selector = "password";
private static String login_button_selector = "#loginbutton > input";
private static String fail_message_selector = "error";
public static void goTo(String environment_url){
driver = Driver.getDriver();
driver.get(environment_url);
}
public static void loginAs(String username, String password){
WebElement user = driver.findElement(By.name(username_selector));
user.clear();
user.sendKeys(username);
WebElement pass = driver.findElement(By.name(password_selector));
pass.clear();
pass.sendKeys(password);
WebElement loginBtn = driver.findElement(By.cssSelector(login_button_selector));
loginBtn.click();
}
public static boolean loginErrorDisplayed(){
WebElement failMessageContainer = driver.findElement(By.className(fail_message_selector));
if(failMessageContainer.isDisplayed()){
return true;
}
else return false;
}
public static String getLoginErrorMessage(){
WebElement failMessageContainer = driver.findElem
LoginPage.java
```
public class LoginPage {
public static WebDriver driver;
private static String username_selector = "username";
private static String password_selector = "password";
private static String login_button_selector = "#loginbutton > input";
private static String fail_message_selector = "error";
public static void goTo(String environment_url){
driver = Driver.getDriver();
driver.get(environment_url);
}
public static void loginAs(String username, String password){
WebElement user = driver.findElement(By.name(username_selector));
user.clear();
user.sendKeys(username);
WebElement pass = driver.findElement(By.name(password_selector));
pass.clear();
pass.sendKeys(password);
WebElement loginBtn = driver.findElement(By.cssSelector(login_button_selector));
loginBtn.click();
}
public static boolean loginErrorDisplayed(){
WebElement failMessageContainer = driver.findElement(By.className(fail_message_selector));
if(failMessageContainer.isDisplayed()){
return true;
}
else return false;
}
public static String getLoginErrorMessage(){
WebElement failMessageContainer = driver.findElem
Solution
if(failMessageContainer.isDisplayed()){
return true;
}
else return false;Why not simply
return failMessageContainer.isDisplayed()?@Test(priority = 0)
public void loginfail() {
LoginPage.goTo("http://127.0.0.1:8080/login");
LoginPage.loginAs("wrong username", "wrongpassword");
boolean didLoginFail = LoginPage.loginErrorDisplayed();
Assert.assertTrue(didLoginFail == true, "Bad login was successful");
if (didLoginFail){
LoginPage.getLoginErrorMessage();
}
}What about
Assert.assertTrue((((didLoginFail == true) == true) == true, ...). I mean, if writing a==true was better than a, then doing it more often must be even better.The following
if is superfluous, the getLoginErrorMessage doesn't get used.I've noticed that I am writing a lot of statics so that the tester doesn't have to instantiate the page objects and methods every time.
I'd start by dropping all the
static modifiers and making it fluent. With a proper API the tester will happily do the instantiation as it leads them to what they want to do.I don't find something like
public void loginfail() {
LoginPage loginPage = new LoginPage()
.goTo("http://127.0.0.1:8080/login")
.loginAs("wrong username", "wrongpassword");
Assert.assertTrue(loginPage.loginErrorDisplayed());
Assert.assertTrue(loginPage.getLoginErrorMessage().contains("WTF?"));
}harder to use than the static version. You could provide even more, but this is most probably not worth the effort (you'd sort of do the tester's job by providing fluent versions of all asserts they may need; this goes too far, but might be useful for the most commonly used assertions):
public void loginfail() {
LoginPage loginPage = new LoginPage()
.goTo("http://127.0.0.1:8080/login")
.loginAs("wrong username", "wrongpassword")
.assertThatLoginErrorDisplayed()
.assertThatLoginErrorMessageContains("WTF?");
}Code Snippets
if(failMessageContainer.isDisplayed()){
return true;
}
else return false;@Test(priority = 0)
public void loginfail() {
LoginPage.goTo("http://127.0.0.1:8080/login");
LoginPage.loginAs("wrong username", "wrongpassword");
boolean didLoginFail = LoginPage.loginErrorDisplayed();
Assert.assertTrue(didLoginFail == true, "Bad login was successful");
if (didLoginFail){
LoginPage.getLoginErrorMessage();
}
}public void loginfail() {
LoginPage loginPage = new LoginPage()
.goTo("http://127.0.0.1:8080/login")
.loginAs("wrong username", "wrongpassword");
Assert.assertTrue(loginPage.loginErrorDisplayed());
Assert.assertTrue(loginPage.getLoginErrorMessage().contains("WTF?"));
}public void loginfail() {
LoginPage loginPage = new LoginPage()
.goTo("http://127.0.0.1:8080/login")
.loginAs("wrong username", "wrongpassword")
.assertThatLoginErrorDisplayed()
.assertThatLoginErrorMessageContains("WTF?");
}Context
StackExchange Code Review Q#91629, answer score: 3
Revisions (0)
No revisions yet.