This short article is a small case study with two main points:
The usefulness of interface with Generics and the consequences of the decision made in planning automation.
The issue
Lately, I was dealing with some problem
I was automating actions on the website in technology that similarly to angular – it has a form of page loading that makes it challenging to test.
I won’t go into details here, Enough to say those tried and true ways of waiting for the page to load didn’t work.
So I had to make my method – „WaitForPageLoad” – and since we are using Page Object Pattern, we had to put this method in each page.

Why is this an issue?
You are probably thinking:
„Wait! This sound like something that should go to parent Class! Not to children! DRY for goodness sake!”
This is a consequence of previous decisions:
What shouldn’t be a surprise. We used the Page Object Pattern as the way of managing our classes for representing pages.
Next, we decided to use Method Chaining for readability.
Another decision that is important to us is how we designed page classes. We went with only methods that simulate user action can be public.
The consequence
Of course, like with every decision, there are some cases that we had to address.
First is returning information to the test. Should we break the chain or use outs? – I am in favour of breaking chain in that situation
But this test has a little different role to play. So I am in a fortunate position in saying – this problem does not apply. We won’t need to return any info to the test.
The second problem is the way we handle waiting.
My original plan was to hide the wait for page load inside the action that requires the wait.
So, for example, if users click on the go to the next page. – The action should wait for it to load. But after some thinking and discussing it with my rubber duck (Which is a wool dragon in reality).
I concluded that the wait is a user action. Ergo user decides if he wants to wait or instead cancel action/go to other pages)
So, in that case, I can’t hide the wait in BaseClass
Cause in each class I have to have. The same method with a different signature.
public class HomePage: PageBase { public HomePage WaitForPageToLoad() { //some code // return this; } }
Still we can do dry!
Of course, we can do some optimization:
public class HomePage: PageBase { public HomePage WaitForPageToLoad() { WaitForPageToLoad(Locator); return this; } } public abstract class PageBase { protected void WaitForPageToLoad(By Locator) { //the code moved here } }
So know wait code hidden in the base class and children call it with their signature.
Problem is I don’t like this solution.
- Now everybody has to remember to add the method.
- It’s a hack. You will need to explain it with comment.
Alternatively, we could put it in the helper class. But then you would also need to pass the driver there.
Interface for the rescue
So I had an idea for a solution, but I couldn’t fully visualize it – My rubber duck has failed me.
Fortunately, consultation with my friend reminded me of the fact that you can make generic interfaces.
so you can do this:
public class HomePage: PageBase, IWaitable<HomePage> { public HomePage WaitForPageToLoad() { WaitForPageToLoad(Locator); return this; } } public abstract class PageBase { protected void WaitForPageToLoad(By Locator) { //the code moved here } } public interface IWaitable <T> { T WaitForPageToLoad(); }
Thanks to the generic interface you can have to add the method alway, and it will always be returning the proper type!

problem is it means you always have to remember to add this interface.
I think it is easier to remember the interface then about the whole method.
Unofrunetly this is the place where I had to finish.
There are other solutions that one could try, but I decided that this solution is good enough.
Like every solution, it has some issues – one you have to use the interface and understand what type to set. Plus we are using interface to enforce behaviour. While it is a way to use them, their main function is to enable polymorphism which one could argue my solution is breaking it.
Interface is fine but can we do that with the abstract class?
So after I finish I had some time to think about this problem, could I do it in a different way? Is there some better solution?
I wanted to try to put it into the parent class.
So my first attempt ended in Stack overflow exception. Let’s just say the code created infinite recursion. Unfortunately I don’t have a snippet to show you.
But this works!
public class MainPage: PageBase<MainPage> { public override MainPage WaitForPageToLoad() { InternalWaitForPageToLoad(); return this; } } public abstract class PageBase<T> { protected void InternalWaitForPageToLoad() { //somecode } public abstract T WaitForPageToLoad(); }
I am still not entirely sure of this solution, but if I will have to do it once more. This is the way I would go about it.
Conclusion.
When we write code, we need to be consistent. If we set up some rules, we have to follow them.
Why? Because as easy as it seems to ignore them, it leads to messy, unpredictable code.
That people who come after us will have a problem to understand.
When we have some rules that follow all that you have to do is pass those rules to them.
This makes it easier for them to understand your creation.
Of course, when creating those rules, you have to be aware of their consequences.
I will tell you already – you won’t be able to foresee all the consequence – I was ready for some.
But while making the plan, I wasn’t considering the wait method.
Every good software architect will tell you that you can’t foresee all situation so what you have to do is prepare a solution that is good enough and flexible enough not to hinder you when problems occur. And this is not easy!
This is my little retro on this specific problem. But in the near future, I have to do a bigger one for my current approach for test automation.
This is my second conclusion their retro/lesson learned from the past are much more critical then I originally was giving them credit.
That all this week if you would like to read more about my tricks while writing code, you can check here.
Huge Thank you to Zigi for help!
EDIT: Sorry for the formatting 🙁
You should be able to avoid overriding of the method in each child class. I didn’t try the code though.
public class MainPage : PageBase { }
public abstract class PageBase where T : PageBase
{
public T WaitForPageLoad()
{
// Do whatever you want to wait for page load.
return (T)this;
}
}
The real question is whether this is good idea at all.
Well, as I can see it also removed generic parameters, so here it is correctly rendered: https://gist.github.com/radekpetruska/48a4663db8b506c531d3820fe423e926
I briefly tested it on non-realworld scenario and it worked for me.