samedi 7 août 2021

Testing framework with POM and PageObjectFactory: error using java reflection

I am building an automation framework and using the Page Object pattern.

There's only three pages and it's very simple. Initially I was doing the framework code in the src/main/java plus the pages code. I had a test runner class in the src/test/java as well as the step definitions. However, I wanted to try to put the framework code in a different module from the test code (because re-usability and because I like to make life harder apparently) which created some problems.

I had one class which was the PageObjectFactory and its goal was to create a Page when one didn't exist. Since I only had three pages, I put this for the three

public Homepage getHomePage() {
  return (homePage == null) ? homePage = new 
      Homepage(driver) : homePage;
 }

But now, since the PageObjectFactory is not part of the test module, it's in the other module I had to come up with a generic method. I can't put a dependency for the test module in the framework module becuase I already have a dependency for the framework module in the test module and it would generate a cyclic dependency.

So I came up which this:

public PageObjectsManager getInstance() {
    LOG.info("PageObjectsManager getInstance()");
    if (instance == null) {
        instance = new PageObjectsManager();
    }
    return instance;
}

public <E extends BasePage> E getPageObject(Class<E> clazz) {
    LOG.info("PageObjectsManager getPageObject()");
    if (!pageObjectsList.containsKey(clazz)) {
        E newPageObject = 
             createPageObjectInstance(clazz);
        pageObjectsList.put(clazz, newPageObject);
        LOG.info("Clazz " + clazz);
        LOG.info(" " + newPageObject);
    }
    return clazz.cast(pageObjectsList.get(clazz));
}

private <E extends BasePage> E 
       createPageObjectInstance(Class<E> clazz) {
    LOG.info("PageObjectsManager 
              createPageObjectInstance()");
     E e = null;
     try {
             Constructor<E> pageConstructor = 
    clazz.getConstructor();
             e = (E) pageConstructor.newInstance();

     } catch(InstantiationException | IllegalAccessException | 
   InvocationTargetException | NoSuchMethodException e1) {
         LOG.info("Exception " + e1.getMessage());
     }

    LOG.info("e " + e);
    return e;

Which would is logic, makes sense, but doesn't work :x It prints this exception instead of creating the page: Exception pageobjects.Homepage.<init>()

Should I just give up? :( I think this is getting too complicated and I have limited time to finish this project so maybe I'll just go with the primitive approach of putting everything in the same module.

EDIT: I had to create a BasePage class which basically just has a constructor:

public BasePage(WebDriver _driver) {
    this.driver = _driver;
    PageFactory.initElements(driver, this);
    wait = new WebDriverWait(driver, 50);
}

And then all the pages extend this.





Aucun commentaire:

Enregistrer un commentaire