Search code examples
javamavenseleniumpageobjects

Error during converting Selenium Java project to Page Object Design Pattern


I created 4 classes also after I decided to convert my project into this design pattern. I moved my codes inside the related classes into the methods. While compiling I'm facing failures and I don't know why.

The main class

GidiyorTest.java

public class GidiyorTest {
  protected WebDriver driver;
  protected String baseUrl;
  private boolean acceptNextAlert = true;
  private StringBuffer verificationErrors = new StringBuffer();

  static GidiyorTest gittiGidiyor = new GidiyorTest();
  static String generatedMail = gittiGidiyor.generateString();
  static String generatedUsername = gittiGidiyor.generateString();  

  static RegisterPage  registerPage = new RegisterPage();
  static LoginPage loginPage = new LoginPage();
  static SearchPage searchPage = new SearchPage();
  static DiscountsPage discountsPage = new DiscountsPage();


  public String generateString(){
        char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
        StringBuilder sb = new StringBuilder();
        Random random = new Random();
        for (int i = 0; i < 7; i++) {
            char c = chars[random.nextInt(chars.length)];
            sb.append(c);
        }
        String output = sb.toString();
        return output;
    }


  @Before
  public void setUp() throws Exception {
    driver = new FirefoxDriver();
    baseUrl = "https://www.gittigidiyor.com/";
    driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
  }
  @Test
  public void testGidiyor() throws Exception {
    registerPage.Register();
    loginPage.Login();
    searchPage.Search();
    discountsPage.Discount();
}
@After
....

RegisterPage.java (One of the four new classes for instance sharing just one)

public class RegisterPage extends GidiyorTest {

    public void Register() throws InterruptedException {

        driver.get(baseUrl + "/kayit-ol");
        driver.findElement(By.name("name")).clear();
        driver.findElement(By.name("name")).sendKeys("murat");
        driver.findElement(By.name("surname")).clear();
        driver.findElement(By.name("surname")).sendKeys("yilmaz");
        Thread.sleep(300);
        driver.findElement(By.id("suggestion_email_input_verifier")).clear();
        driver.findElement(By.id("suggestion_email_input_verifier")).sendKeys(
                generatedMail + "@gmail.com");
        driver.findElement(By.id("nickname")).clear();
        driver.findElement(By.id("nickname")).sendKeys(generatedUsername);
        Thread.sleep(300);
        driver.findElement(By.name("passwd")).clear();
        driver.findElement(By.name("passwd")).sendKeys("123456abc");
        driver.findElement(By.name("passwd2")).clear();
        driver.findElement(By.name("passwd2")).sendKeys("123456abc");
        Thread.sleep(300);
        driver.findElement(By.id("cepgsm")).clear();
        driver.findElement(By.id("cepgsm")).sendKeys("531");
        driver.findElement(By.id("cep")).clear();
        driver.findElement(By.id("cep")).sendKeys("600 29 79");
        Thread.sleep(1000);
        driver.findElement(By.id("SubmitForm")).click();

    }
}

And the error is beginning at registerPage.Register(); line. One another is java.lang.NullPointerException.

Hope you can help.


Solution

  • The way you're creating your PageObject is not correct. You should not extend the test, one of the main points is that the PageObject should not know anything about the test, rather just expose the services offered by the page. On the other hand your test should hold the assertions and other test related logic.

    The second wrong thing is that you should use PageFactory to instantiate your page object, so that you can take advantage of the lazy binding mechanism. So change to something like this

    public class RegisterPage {
    
        private WebDriver driver;
    
        public RegisterPage(WebDriver driver) {
            this.driver = driver;
        }
    
       // The rest of your class
     }
    

    and instantiate inside the test using PageFactory

    PageFactory.initElements(driver, RegisterPage.class);
    

    also to ease up maintainence and benefit from lazy element binding you can think about adding your elements as fields, and mark them via annotation, so they get populated by PageFactory as well e.g.

    public class RegisterPage {
    
        private WebDriver driver;
    
        public RegisterPage(WebDriver driver) {
            this.driver = driver;
        }
    
        @FindBy(name = "name")
        private WebElement name;
    
        ...
    
    
        }
    }