0

I use Pagefactory design pattern for selenium java tests and things work just fine. I am wondering if it is possible to call a PageFactory instance only once for multiple actions instead of repeating the instance all the time in the same method. I have something like this:

private static BasePage basePage; //There is BasePage class somewhere that holds PageFactory elements
basePage = PageFactory.initElements(driver, BasePage.class); // PageFactory initialisation in the test class

public static void loginTest() throws InterruptedException {
     basePage.acceptButton.click();
     basePage.skipButton.click();
     basePage.loginButton.click();
}

I am repeating the basePage every time I perform an action. I am thinking if there is a way with java to call the basePage instance only once. I tried something like this:

basePage.acceptButton.click()
        .skipButton.click();
        .loginButton.click();

The code is unable to compile. Is there a workaround or is this beyond java?

The man
  • 129
  • 16
  • Possible duplicate of [how to achieve method chaining in java?](https://stackoverflow.com/questions/21180269/how-to-achieve-method-chaining-in-java) – JeffC Jan 28 '19 at 17:28
  • This doesn't have anything to do with page object model or PageFactory, it has to do with how you set up your methods. You are not following page object model standards, by the way... I'm not sure if you are intending to or not. You have exposed the individual page elements and are clicking them instead of creating an API through the page object to make certain actions available, e.g. logging in, etc. – JeffC Jan 28 '19 at 17:29
  • Also, PageFactory is not a design pattern... page object model is. PageFactory is just a support library to help make instantiation of page objects easier. See [PageFactory](https://github.com/SeleniumHQ/selenium/wiki/PageFactory) for more info. Also, Selenium contributors have stated that PageFactory should not be used. – JeffC Jan 28 '19 at 17:32

2 Answers2

2

what if use "chain of invocation"? in BasePage class every method has to be done in that way

public BasePage acceptButtonClick(){
   acceptButton.click();
   return this;
}

public BasePage skipButtonClick(){
   skiptButton.click();
   return this;
}
public BasePage loginButtonClick(){
   loginButton.click();
   return this;
}

Then you can call in in test like:

basepage.acceptButtonClick()
        .skipButtonClick()
        .loginButtonClick();
S.Manko
  • 151
  • 1
  • 2
  • 15
1

It depends entirely on how your test is designed, the page's contents, and your experienced results.

I do try to design my tests such that I can share a page object across multiple tests, and you just need to declare the page object variable at the class level to do that. The caveat is that your test steps need to run in expected order.

Generally speaking, it will work fine, even as the page itself changes, since each element is not accessed until you reference it. However, if you find yourself getting a stale element exception, it's a good idea to force re-initialization of the page object.

Update

I just re-read your ENTIRE question and realized I made a false assumption. You're looking to chain actions, not re-instantiate the page object. As far as I know, this is not possible with page objects, but I do not claim to be a java expert, so perhaps someone else can either confirm or deny that.

Bill Hileman
  • 2,798
  • 2
  • 17
  • 24
  • I share a page object across multiple tests and initiate the page object variable at the class level just once. What I am is call the respective elements individually but with just one basePage instance per method, instead of that basePage repetition in my code. Whether java can do it, I dont know – The man Jan 28 '19 at 15:28
  • Your updated assumption is correct. Chaining actions is the right phrase, well done! I am thinking maybe it's not possible also, but I may be wrong. – The man Jan 28 '19 at 15:34