Search code examples
seleniumtestingautomated-testspageobjectspage-factory

Using different sets of page objects with the same selenium tests


[This is cross-posted with SQA - https://sqa.stackexchange.com/questions/35081/using-different-sets-of-page-objects-with-the-same-selenium-tests]

I'm working on a selenium test suite for a set of similar websites. The test suite would be execute separately for each site and the tests in the suite are applicable to all websites.

These websites are built on the same underlying platform, however have different theme/scheme and therefore page objects for these sites need to be different. This is not a case of one or two selectors being different, but majority of selectors different - yet the rest of the structure is the same.

I can easily create two (or three, or whatever) sets of page objects, however I can't figure out how to tell the test executor (Cucumber cli in my case) which page objects to use.

The closest I can come up with is use different package names with common base classes and then individual pages extending from the common base classes. Another possibility is to extract all the selectors into property files and load one or another based on an input parameter, however this would preclude me from using PageFactory. I can also, probably, create separate sets of page objects in different source sets and then compile one or the other based on my need - but, again, I can think of the theory, yet not the execution.

So, what's the right approach and how to achieve this? If it matters, the project is built using gradle.


Solution

  • The solution turned out to be a custom ElementLocator and ElementLocatorFactory with a corresponding custom annotation. It's a bit more work, but it's a very clear solution. I published it on github. In short, the implementation allows to do this:

    public class MyPage {
        @SearchWith(page="MyPage", name="myElement", locatorsFile="{locators}")
        WebElement someElement
    
        ...
    }
    

    Then run the whole test with -Dlocators=site1.json or -Dlocators=site2.json - and corresponding locators will be loaded from one or the other. It even allows to specify -Dlocators=[site3.json] and load locators from site3.json resource (as obtained using this.getClass().getResourceAsStream(locatorsFile))