Jacobvu84 / serenity-pageobject-junit-webdriver

4 stars 1 forks source link

How is a base class helpful in the Selenium WebDriver framework? #86

Open Jacobvu84 opened 3 years ago

Jacobvu84 commented 3 years ago

enjoys writing about Selenium test automation and labradors

I confess!

I am guilty too of using utility base classes!

For a while, I used base pages in my automation projects for storing common methods such as

getting the page title and url finding elements with explicit waits and expected conditions clearing-and-typing keywords in textboxes switching to iframes switching to windows taking screenshots anything else that I needed in page object classes selecting options from listboxes etc My utility class was a mess with methods that were doing everything except getting my groceries from the store.

Why did I do this?

Why did I think that it is a good idea?

Because I did not know better.

I thought that I was writing Java code.

Instead, I was practicing Visual Basic in Java.

For a while, I was content with how much simpler my automation code was when using a base class.

But it did not take long before thinking that something is not right.

All development books that I was reading (among them Elegant Objects, Clean Code) said that

I should use composition instead of inheritance utility classes are a bad practice program to an interface It is easy to understand why utility classes are bad.

If you have a Results Page class that inherits from a Utility class, that means in programming terms that the Results Page is a type of a Utility.

Which is obviously not the case.

The second argument took longer to understand.

Since I dont want to bore you with long discussions, lets just say that in Java inheritance should be used sparingly.

Because a class can only have a parent.

If the parent is a utility class, you cannot have another parent.

Also, inheritance, especially when the child class is not related to the parent class by a IS-A relationship (example: labrador is a dog, tomato is a vegetable, checking is an account, etc) leads to code that is not exactly object oriented.

So, I started paying more attention to the topic of the base classes.

Do I really need them?

I don’t.

But, Alex, where are you putting all those common methods?

Easy to say that utility classes are bad but what is the solution?

Let’s see:

you can create a custom driver class that implements the WebDriver interface, override all WebDriver methods with your own implementations and add more methods applicable to what a driver does You can create classes for each type of html element; these classes implement the WebElement interface, override all WebElement methods with your own implementations; you can also add more methods applicable to html elements Does this mean that base pages should never be used?

I dont know.

I still use them in 1 case.

I really like using the LoadableComponent class of Selenium WebDriver in my code since it streamlines my tests.

The tests start with the page to be tested instead of home page.

But that’s about it.

…………………………………………………………………………………

In summary,

If you want to become a good test automation engineer,

Stay away from utility base classes!

public class WelcomePage extends LoadableComponent<WelcomePage> { 
    private BrowserDriver driver; 
    private final LoadableComponent<?> parent; 

    public WelcomePage(BrowserDriver driver, LoadableComponent<?> parent) { 
        this.driver = driver;            
        this.parent = parent;            
    } 
    @Override 
    protected void load() { 
        parent.get(); 
        ((LoginPage)parent).signIn(); 
    } 
    @Override 
    protected void isLoaded() throws Error {         
        try { 
            if (this.driver.getCurrentUrl().equalsIgnoreCase("data:,")) 
                throw new Error("Welcome Page is not loaded!"); 

            new WebDriverWait(driver(), 30).until(titleIs(TITLE)); 
        } 
        catch (Exception ex) { 
            assertTrue(false); 
        } 

    }