3

I have a framework based on POM model. I am able to write test that only uses elements from 1 page but when I need to access elements from another page tests fail because I think it uses the wrong driver since I am creating 2 drivers in the test and looks like that's the problem.

Also any help or opinion on making the framework a little better to optimize Page Object Model and PageFactory would be greatly appreciated!

I have AbstractScreen.java that has a constructor which initializes elements using AppiumFieldDecorator:

public class AbstractScreen extends DriverFactory {

  protected AndroidDriver driver;

  public AbstractScreen(AndroidDriver driver) {
    this.driver = driver;
    PageFactory.initElements(new AppiumFieldDecorator(driver), this);
  }
}

I have DriverFactory.java that prepares the device:

public class DriverFactory {
  protected static AndroidDriver driver;

  @BeforeClass
  // Android device details
  public void configureSessionForDevice() throws MalformedURLException {
    DesiredCapabilities capabilities = new DesiredCapabilities();
    capabilities.setCapability("platformVersion", Device.platformVersion);
    capabilities.setCapability("deviceName", Device.deviceName);
    capabilities.setCapability("platformName", Device.platformName);
    capabilities.setCapability("udid", Device.udid);
    capabilities.setCapability("app", Device.appDir);
    capabilities.setCapability("appPackage", Device.appPackage);
    capabilities.setCapability("appActivity", Device.appActivity);
    capabilities.setCapability("automationName", "UiAutomator2");
    driver = new AndroidDriver(new URL(Device.URL), capabilities);
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  }

  @AfterClass
  public void killAppiumSession() {
    driver.quit();
  }
}

I have WelcomeScreen.java:

public class WelcomeScreen extends AbstractScreen {
  public WelcomeScreen(AndroidDriver driver) {
    super(driver);
  }

  @AndroidFindBy(id = "button1")
  AndroidElement loginToYourAccountButton;
  @AndroidFindBy(id = "button2")
  AndroidElement continuesAsGuestButton;
  @AndroidFindBy(id = "welcome_to_text")
  AndroidElement welcomeToTextView;
  @AndroidFindBy(id = "text")
  AndroidElement securelyMoveWelcomeTextView;
  @AndroidFindBy(id = "welcome_logo")
  AndroidElement WelcomeLogoImageView;

  public void clickLoginIBMButton() {
    loginToYourAccountButton.click();
  }

  public void clickGuestButton() {
    continuesAsGuestButton.click();
  }
}

I have AuthenticationScreen.java

public class AuthenticationScreen extends AbstractScreen {

  public AuthenticationScreen(AndroidDriver driver) {
    super(driver);
  }
  @AndroidFindBy(id = "button1")
  AndroidElement continueButton;
  @AndroidFindBy(id = "button2")
  AndroidElement findURLButton;
  @AndroidFindBy(id = "or_separator")
  AndroidElement orSeparator;
  @AndroidFindBy(id = "domain_text_view")
  AndroidElement ibmAspera;
  @AndroidFindBy(id = "domain_edit_text")
  AndroidElement organization;
  WebElement authenticationText = driver.findElement(By.xpath("//android.widget.TextView[@text='Authentication']"));

  public void enterOrganization(String org) {
    organization.setValue(org);
  }

  public void clickContinueButton() {
    continueButton.click();
  }
}

And the test I am trying to write to login. I need to use both page objects of welcomeScreen and authenticationScreen, but I don't think what I am doing is the correct strategy. Can you help me optimize it?

public class ClickLoginButton {
    private WelcomeScreen welcomeScreen;
    private AuthenticationScreen authenticationScreen;
    private String org = "testeng.qa";

    @BeforeClass
    public void setUpPage() {
        welcomeScreen = new WelcomeScreen(driver);
        authenticationScreen = new AuthenticationScreen(driver);
    }

    @Test
    public void ClickButton() throws Throwable {
        welcomeScreen.clickLoginIBMButton();
        authenticationScreen.enterOrganization(org);
    }
}

I tried to make ClickLoginButton test to extend AbstractScreen but it throws error that AbstractScreen doesn't have default constructor. Not even sure if that would help or not

0

It's been a long time since I worked with Java so my code suggestions are going to be more pseudo-code than full code.

That said, the way to handle this situation is to have your page object methods return the next page object you require. So your clickLoginIBMButton() method would become more like the following pseudo-code:

public AuthenticationScreen clickLoginIBMButton()
{
    loginToYourAccountButton.click();
    return new AuthenticationScreen(driver);
}

Then your test code would change to be more like the following:

public class ClickLoginButton {
    private WelcomeScreen welcomeScreen;
    private AuthenticationScreen authenticationScreen;
    private String org = "testeng.qa";

    @BeforeClass
    public void setUpPage() {
        welcomeScreen = new WelcomeScreen(driver);
    }

    @Test
    public void ClickButton() throws Throwable {
        authenticationScreen = welcomeScreen.clickLoginIBMButton();
        authenticationScreen.enterOrganization(org);

        /* Note that you could also code this in the fluent style -
           welcomeScreen.clickLoginIBMButton().enterOrganization(org);
           If enterOrganization() returns the next page in the sequence
           you can then use that page object for your assertion
        */
    }
}
  • Kate thanks for the help! I edited my code to return page object methods but i think it needs a little bit more correction. After editing my clickLoginIBMButton() method to what you said I get an error on this line: authenticationScreen = welcomeScreen.clickLoginIBMButton(); saying that "expected is AppPages.AuthenticationScreen but found void" I will edit my code little bit more thanks for the push towards right direction! Also thanks for formatting my code :) – user3085934 Nov 16 '18 at 18:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.