简体   繁体   中英

How to separate page objects from code logic in Selenium- java

I am learning and trying to separate locators from actual code in selenium. I have already separated them but I need guidance on more optimization, how can I optimize the code more? Is the Page Object design model used to store only locators? Or can we store their methods too. Can someone please explain with reference to below code?

Link: https://www.goibibo.com/

Actual code with Logic(TC_01Test.java) and Base.java class initializes driver


public class TC_01Test extends Base {

    WebDriver driver;

    @BeforeTest
    public void initialize() throws IOException {

        driver = initializeDriver();
    }

    // Sign In functionality
    @Test
    public void SignIn() throws InterruptedException {

        TC_01 tc02 = new TC_01(driver);
        tc02.siginLink().click();
        System.out.println(driver.getWindowHandle());
        driver.switchTo().frame("authiframe");
        System.out.println(driver.getWindowHandle());
        tc02.mobileNumber().sendKeys(prop.getProperty("phoneNumber"));
        System.out.println("number entered");
        tc02.submitButton().click();
        System.out.println("button clicked");
        driver.switchTo().defaultContent();
        System.out.println(driver.getWindowHandle());
        tc02.closePopup().click();

    }

    // SignUp functionality
    @Test
    public void SignOut() {
        TC_01 tc01 = new TC_01(driver);
        tc01.sigupLink().click();
        driver.switchTo().frame("authiframe");
        tc01.mobileNumber().sendKeys(prop.getProperty("phoneNumber"));
        tc01.submitButton().click();
        driver.switchTo().defaultContent();
        tc01.closePopup().click();

    }

    @AfterTest
    public void closeBrowser() {
        driver = tearDown();
    }

}

Below is the code for Page Object(TC_01.java) created for above test case.

public class TC_01 {

    WebDriver driver;

    public TC_01(WebDriver driver) {
        this.driver = driver;
    }

    // driver.findElement(By.xpath("//a[@id='get_sign_in']"))

    // mobileNumber= driver.findElement(By.xpath("//input[@id='authMobile']")

    // driver.findElement(By.id("mobileSubmitBtn"))

    // driver.findElement(By.xpath("//div[@class='popContent']/a"))

    By signinLink = By.xpath("//a[@id='get_sign_in']");
    By signupLink = By.xpath("//a[@id='get_sign_up']");
    By mobileNumber = By.xpath("//input[@id='authMobile']");
    By submitButton = By.id("mobileSubmitBtn");
    By closePopup = By.xpath("//div[@class='popContent']/a");

    public WebElement siginLink() {

        return driver.findElement(signinLink);
    }

    public WebElement sigupLink() {

        return driver.findElement(signupLink);
    }

    public WebElement mobileNumber() {

        return driver.findElement(mobileNumber);
    }

    public WebElement submitButton() {

        return driver.findElement(submitButton);
    }

    public WebElement closePopup() {

        return driver.findElement(closePopup);
    }
}

Answering on your question - yes, you can store methods in PO classes as well. Furthermore, it's a good practice. Regarding your code optimization - it's better to express business behavior instead of granular technical actions. Also, instead of returning WebElement methods and then perform actions (click, sendKeys etc) in the Test class you can simply perform such actions in PO class. Check the code below.

    public void enterFirstName() {

        driver.findElement(firstName).sendKeys("abc");
    }

    public void enterLastName() {

        driver.findElement(lastName).sendKeys("qwerty");
    }

    public void pressSubmitButton() {

        driver.findElement(submitButton).click();
    }
// instead of invocation all of these methods above in test class you can simply do this:

    public void loginWithValidCredentials(String firstNameValue, String lastNameValue) {
        driver.findElement(firstName).sendKeys(firstNameValue);
        driver.findElement(lastName).sendKeys(lastNameValue);
        driver.findElement(submitButton).click();
    }

// Thus your test will look like:

@Test
public void loginTest() {
    POclass po = new POclass();
    po.loginWithValidCredentials("yourName", "yourNameABC");
    // some assert() methods...
}

This is much simplier. BTW, it's useful to know and use PageFactory concept - https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html

PS - read about "Chain of responsibilities" pattern, but in case you are strong in Java, because this is a quite advanced topic.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM