1

This might be a very strange question, but I am not even sure how to title this question. I am quite new to C# and Selenium. I have done some coding on it and I'm quite comfortable creating a (very messy) test that runs how I want to. I would like to organize my tests a bit better.

I will use this as an example to what I want to achieve:

On a login page lets say I have a button "Log In" and that button opens a page that let's me put my credentials "Username" and "Password".

Lets say i would like to program it like this: have the landing page with the login with all the elements of that page, and one only for the elements of the login page.

And the test would be something like this:

LandingPage.Login.Click();
LandingPage.Login.Username("username");
LandingPage.Login.Password("password";
LandingPage.Login.LoginBtn.Click();

I have seen this type of coding being used. I'm starting to create a "page object model" for my test and would like to separate it so then i can use the way I showed above. The "LandinPage.cs" would have the login link as well as other elements and the "Login.cs" would have the username field and the password and the login button, along side other elements not relevant now.

My question is, is there a name for this kind of formatting? I am struggling to find such so I can start my studying there.

2
  • Welcome. Yes, this is the right place to ask. What you are describing is called the Page Object Model. This is a well known, well documented design pattern famously used with Selenium.
    – Lee Jensen
    Commented May 4, 2021 at 14:30
  • Hey Lee, thank you for your reply. The issue I am facing is, using the page object model i am identifying each element independently. So it would be: Login.Click(); Username("username"); I can't write a "flow" like on the example above. Does it make sense? i can i for example put the Login() inside the LandingPage(), and then the loginBtn() (for example) inside the Login()?
    – DjNewma
    Commented May 4, 2021 at 14:36

1 Answer 1

1

As @Lee Jensen mentioned, this is called Page Object Model.

The basic idea is for your tests to have only application actions, whereas low-level HTML manipulation is hidden deep in structure objects that reassemble the areas of your page.

If you want a Coding Kata that exercises a typical login form, you can check out this blog post I wrote.

For example, you can have a LoginPage that holds a LoginForm object:

class LoginPage(driver: WebDriver): Page(driver) {

    private var loginForm: LoginForm

    init {
        driver.get("https://the-internet.herokuapp.com/login")
        initPage()
        loginForm = LoginForm()
    }

    fun login(userCredentials: UserCredentials): SecureAreaPage {
        loginForm.login(userCredentials)
        return SecureAreaPage(driver)
    }
}

And the LoginForm will have all the details on how to fill the fields and perform the login itself:

class LoginForm(baseLocator: WebElement) {
    private var baseLocator = baseLocator.findElement(By.id("login"))

    private val usernameField: WebElement
        get() = baseLocator.findElement(By.id("username"))

    private val passwordField: WebElement
        get() = baseLocator.findElement(By.id("password"))

    private val loginButton: WebElement
        get() = baseLocator.findElement(By.tagName("button"))

    fun login(userCredentials: UserCredentials) {
        fillFields(userCredentials)
        performLogin()
    }

    private fun fillFields(userCredentials: UserCredentials) {
        fillUsernameField(userCredentials.username)
        fillPasswordField(userCredentials.password)
    }

    private fun fillUsernameField(username: String) {
        usernameField.sendKeys(username)
    }

    private fun fillPasswordField(password: String) {
        passwordField.sendKeys(password)
    }

    private fun performLogin() {
        loginButton.click()
    }
}

Your tests then can be very simple:

@Test
fun performLoginTest() {
    val loginPage = LoginPage(driver)

    val secureAreaPage = loginPage.login(username = "tomsmith", password = "SuperSecretPassword!")

    verifyLoggedPageElements(
        secureAreaPage = secureAreaPage,
        title = "Secure Area",
        subtitle = "Welcome to the Secure Area. When you are done click logout below."
    )
}

...

}

About: LandingPage.Login.Username("username");

The general rule of thumb is that if your tests are using attributes of your Page Objects, you are creating a brittle test. Object-oriented programming is about sending messages. If you want to perform an action on a page, create a method for that - send the message to the method and let your object figure out how to implement the action.

You can read about Page Object Model in more detail on Martin Fowler's blog. enter image description here

1
  • 1
    Thank you João. This answer was the clarification i was looking for. I will follow this example, i will also have a look at your blog as i'm sure it will help me a lot! Obrigado amigo!
    – DjNewma
    Commented May 4, 2021 at 14:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.