Login Functionality with Page Object Model and Data-Driven Testing - Notes By ShariqSP

Login Functionality with Page Object Model and Data-Driven Testing

The Page Object Model (POM) design pattern helps improve code organization, maintainability, and reusability by separating page-specific elements and methods from test scripts. Combined with data-driven testing, it allows testers to efficiently manage test data and scenarios.

Project Structure

Here's the recommended structure for implementing POM with data-driven testing:

  • src/main/java/pages: Contains the page classes for different screens in the app.
  • src/test/java/tests: Contains the test scripts using the page objects.
  • src/test/java/utils: Contains utility classes, including data providers for test data.

Login Page Class


                    package pages;

                    import io.appium.java_client.android.AndroidDriver;
                    import org.openqa.selenium.WebElement;
                    import org.openqa.selenium.support.FindBy;
                    import org.openqa.selenium.support.PageFactory;
                    
                    public class LoginPage {
                        private AndroidDriver driver;
                    
                        // Constructor to initialize the driver and page elements
                        public LoginPage(AndroidDriver driver) {
                            this.driver = driver;
                            PageFactory.initElements(driver, this);
                        }
                    
                        // Locators using @FindBy
                        @FindBy(accessibility = "test-Username")
                        private WebElement usernameField;
                    
                        @FindBy(accessibility = "test-Password")
                        private WebElement passwordField;
                    
                        @FindBy(accessibility = "test-LOGIN")
                        private WebElement loginButton;
                    
                        // Methods to interact with elements
                        public void enterUsername(String username) {
                            usernameField.clear();
                            usernameField.sendKeys(username);
                        }
                    
                        public void enterPassword(String password) {
                            passwordField.clear();
                            passwordField.sendKeys(password);
                        }
                    
                        public void clickLogin() {
                            loginButton.click();
                        }
                    }
                    
                

Data Provider Class


                package utils;
              
                import org.testng.annotations.DataProvider;
              
                public class TestData {
                    @DataProvider(name = "loginData")
                    public Object[][] getLoginData() {
                        return new Object[][] {
                            {"standard_user", "secret_sauce", "valid"},
                            {"locked_out_user", "secret_sauce", "invalid"},
                            {"", "secret_sauce", "invalid"},
                            {"standard_user", "", "invalid"}
                        };
                    }
                }
                

Login Test Script


                package tests;
              
                import io.appium.java_client.android.AndroidDriver;
                import org.openqa.selenium.remote.DesiredCapabilities;
                import org.testng.annotations.AfterClass;
                import org.testng.annotations.BeforeClass;
                import org.testng.annotations.Test;
                import org.testng.annotations.DataProvider;
                import pages.LoginPage;
                import utils.TestData;
              
                import java.net.MalformedURLException;
                import java.net.URL;
                import java.time.Duration;
              
                public class LoginTest {
                    private AndroidDriver driver;
                    private LoginPage loginPage;
              
                    @BeforeClass
                    public void setUp() throws MalformedURLException {
                        DesiredCapabilities caps = new DesiredCapabilities();
                        caps.setCapability("platformName", "Android");
                        caps.setCapability("appium:platformVersion", "7.1.1");
                        caps.setCapability("appium:deviceName", "Mi Max 2");
                        caps.setCapability("appium:appPackage", "com.swaglabsmobileapp");
                        caps.setCapability("appium:appActivity", ".MainActivity");
                        caps.setCapability("appium:automationName", "UiAutomator2");
                        caps.setCapability("appium:noReset", true);
              
                        driver = new AndroidDriver(new URL("http://127.0.0.1:4723"), caps);
                        driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
              
                        loginPage = new LoginPage(driver); // Initialize the LoginPage object
                    }
              
                    @Test(dataProvider = "loginData", dataProviderClass = TestData.class)
                    public void testLogin(String username, String password, String expectedResult) {
                        loginPage.enterUsername(username);
                        loginPage.enterPassword(password);
                        loginPage.clickLogin();
              
                        // Validate login based on expectedResult
                        if ("valid".equals(expectedResult)) {
                            System.out.println("Login successful for: " + username);
                        } else {
                            System.out.println("Login failed for: " + username);
                        }
                    }
              
                    @AfterClass
                    public void tearDown() {
                        if (driver != null) {
                            driver.quit();
                        }
                    }
                }
                

Advantages of Using POM and Data-Driven Testing

  • Improves code organization by separating test logic from UI elements.
  • Makes the test scripts more readable and maintainable.
  • Facilitates reuse of page objects across multiple test cases.
  • Allows easy scalability when adding new test data or scenarios.
  • Reduces code duplication and simplifies updates when UI changes.

The combination of POM and data-driven testing provides a robust framework for mobile application testing. By organizing the code into reusable components and separating test data, you can streamline the testing process and ensure better maintainability.