Showing posts with label POM. Show all posts
Showing posts with label POM. Show all posts

Thursday, 9 May 2019

Interview | @CacheLookup - in Page Object Model | Page Factory


@CacheLookup, as the name suggests helps us control when to cache a WebElement and when not to.

This annotation when applied over a WebElement instructs Selenium to keep a cache of the WebElement instead of searching for the WebElement every time from the WebPage. This helps us save a lot of time.

Syntax:
 @FindBy(how = How.NAME, using = "firstname")
 @CacheLookup
 public WebElement firsNameCached;

Wednesday, 16 May 2018

Interview question | Page Factory | Lazy loading

Here is the interview question:

As per "Page Factory", all the elements will be initialized at the time of page load.
But in dynamic applications how page factory works?
Ex: Assure a drop down content ( options)  loads on click of the respected select box, how can you implement page factory for this?, as page factory initializes elements at the time of page load only.

Answer:
Lazy load concept.

AjaxElementLocatorFactory is a lazy load concept in Page Factory pattern to identify WebElements only when they are used in any operation
i.e. a timeOut for a WebElement can be assigned to the Object page class with the help of AjaxElementLocatorFactory.

Syntax : ( similer to plain "Page Factory init elemnts"  method )

PageFactory.initElements(new c(driver, 30), this);

If element not found in 30 secs, NoSuchElemementException throws.

happy coding.

Thursday, 2 February 2017

page factory framework for selenium web automation

Here is my way of implementing selenium page factory framework.
yes, this framework can be modified to suite, pom , data driven, keyword driven framework.

Here is my Framework structure:



BaseDriver.java ( Here Driver creation happens)

package com.companyName.automation_one.web.pom.driver;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;

import com.companyName.automation_one.utils.PropertiesReaderUtility;

public class BaseDriver {

public static WebDriver driver;

public static void startSession() {
String browser, remote, baseUrl;
URL hub_url = null;
String user_dir = System.getProperty("user.dir");

PropertiesReaderUtility prop = new PropertiesReaderUtility(user_dir + "/selenium.properties");
browser = System.getProperty("browser", prop.getProperty("browser"));
remote = System.getProperty("remote.webdriver", prop.getProperty("remote.webdriver"));
baseUrl = System.getProperty("baseurl.dev", prop.getProperty("baseurl.dev"));
try {
hub_url = new URL(System.getProperty("hub.url", prop.getProperty("hub.url")));
} catch (MalformedURLException e) {
e.printStackTrace();
}
if (driver == null) {
if (remote.equalsIgnoreCase("false"))

switch (browser) {
case "firefox":
System.setProperty("webdriver.firefox.driver",
user_dir + "\\src\\ExternalJars\\geckodriver\\geckodriver.exe");
driver = new FirefoxDriver();
break;
case "chrome":
System.setProperty("webdriver.chrome.driver",
user_dir + "\\src\\ExternalJars\\chromeDriver\\chromedriver.exe");
driver = new ChromeDriver();
break;
case "ie":
System.setProperty("webdriver.ie.driver",
user_dir + "\\src\\ExternalJars\\IEDriverServer_x64_2.25.3\\IEDriverServer.exe");

DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
ieCapabilities.setCapability(
InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
driver = new InternetExplorerDriver(ieCapabilities);
break;
}
else
switch (browser) {
case "firefox":
System.setProperty("webdriver.firefox.driver",
user_dir + "\\src\\ExternalJars\\geckodriver\\geckodriver.exe");
FirefoxProfile fp = new FirefoxProfile();
DesiredCapabilities dc_ff = DesiredCapabilities.firefox();
dc_ff.setCapability(FirefoxDriver.PROFILE, fp);
driver = new RemoteWebDriver(hub_url, dc_ff);

break;
case "chrome":
System.setProperty("webdriver.chrome.driver",
user_dir + "\\src\\ExternalJars\\chromeDriver\\chromedriver.exe");
ChromeOptions chr_options = new ChromeOptions();
DesiredCapabilities dc_chr = DesiredCapabilities.chrome();
dc_chr.setCapability(ChromeOptions.CAPABILITY, chr_options);
driver = new RemoteWebDriver(hub_url, dc_chr);

break;
case "ie":
System.setProperty("webdriver.ie.driver",
user_dir + "\\src\\ExternalJars\\IEDriverServer_x64_2.25.3\\IEDriverServer.exe");
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
ieCapabilities.setCapability(
InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
driver = new RemoteWebDriver(hub_url, ieCapabilities);
break;
}
}
driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);
driver.get(baseUrl);
driver.manage().window().maximize();
}

public static void stopSession() {
driver.quit();
driver = null;
}
}



LoginPage.java ( Here, we keep locators and methods related to one page  )

package com.companyName.automation_one.web.pom.pages.login;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;

import com.companyName.automation_one.web.pom.driver.BaseDriver;

public class LoginPage {
WebDriver driver;

@FindBy(how = How.ID, using = "userName")
WebElement userName;
@FindBy(how = How.ID, using = "password")
WebElement password;
@FindBy(how = How.ID, using = "submit")
WebElement submit;
public LoginPage() throws Exception {
this.driver = BaseDriver.driver;
PageFactory.initElements(driver, LoginPage.class);
}

public void login(String uname, String pwd) {
userName.sendKeys(uname);
password.sendKeys(pwd);
submit.click();
}

}


BaseTest,java ( which is a parent class for each testClass )

package com.companyName.automation_one.web.pom.tests.login;

import org.junit.AfterClass;
import org.junit.BeforeClass;

import com.companyName.automation_one.web.pom.driver.BaseDriver;

public class BaseTest {
@BeforeClass
public void setup() {
BaseDriver.startSession();

@AfterClass
public void cleanup() {
BaseDriver.stopSession();
}
}

LoginTest.java ( this is one test class)

package com.companyName.automation_one.web.pom.tests.login;

import org.testng.Assert;
import org.testng.annotations.Test;

import com.companyName.automation_one.web.pom.pages.login.LoginPage;

public class LoginTest extends BaseTest {

@Test
public void Method1() throws Exception {
LoginPage lp=new LoginPage();
lp.login("test", "test");
Assert.assertTrue(true);
}

}

Wednesday, 11 May 2016

How PageFactory DP is different from Page Object Model

Assume you are already aware of Page Object Design pattern.

Quick Recap:
 Each web page in the application there should be corresponding page class.
- Object Repository is independent of test cases.
- Flows in the UI should be separated from verification.

Advantages:
- Easy to Maintain
- Easy Readability of scripts
- Reduce or Eliminate duplicacy
- Re-usability of code

- Reliability


Page Factory :

- Extension to Page Object Model , but Page Factory is much enhanced model.


"Factory class can be used to make using Page Objects simpler and easier".

- We use Page Factory pattern to initialize web elements which are defined in Page Objects.
  Once we call initElements() method, all elements will get initialized.
- It is used to initialize elements of a Page class without having to use ‘FindElement’ or ‘FindElements’. Annotations can be used to supply descriptive names of target objects to improve code readability.

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.How;
import org.openqa.selenium.support.PageFactory;

import com.abof.selenium_pagefactory.pom.utils.WebElementWait;

public class HeaderPage {
WebDriver driver;

@FindBy(how = How.LINK_TEXT, using = "Track my order")
private WebElement linkTrackMyOrder;

@FindBy(how = How.ID, using = "Header_GlobalLogin_signInQuickLink")
private WebElement linkSignIn;

@FindBy(how = How.ID, using = "Header_GlobalLogin_signOutQuickLinkUser")
private WebElement linkSignOut;

@FindBy(how = How.ID, using = "Header_GlobalLogin_loggedInDropdown_SignOut")
private WebElement btnSignOut;

public HeaderPage(WebDriver driver) throws Exception {
this.driver = driver;
PageFactory.initElements(driver, this);
}

public void navigateToSignInPage() {
linkSignIn.click();
}

public void signOut() {
linkSignOut.click();
btnSignOut.click();
}

public void navigateToTrackingOrderPage() {
linkTrackMyOrder.click();
}

public String getMeLoggedInPersonFirstName() {
WebElementWait.elementIsDisplayedFluentlyPredicate(linkSignOut, 5, 500);
return linkSignOut.getText();
}


}


PageFactory Instantiates all the elements of the web page at the start when we Initialized any page class objects. But think of the elements which will display on the web page after some action, say Ajax action. In PageFactory, every time when we call a method on the WebElement, the driver will go and find it on the current page once again.

In an AJAX-heavy application this is what we would like to happen, but in the case of regular application where elements are stable and when we know that the element is always going to be there and won’t change.  It would be handy if we could ‘cache’ the element once we’d looked it up and save some time of execution by commanding PageFactory to not search the WebElements on the page again.

Advantages of PageFactory
- less code using @FindBy
- Initialize all elements at a time
- using cache feature, we can save execution time
AjaxElementLocatorFactory feature

Friday, 22 April 2016

Selenium POM ( Page object model) Project


-          Create a Maven project as explained here. http://kranthikasthuri.blogspot.com/2016/04/how-to-create-maven-project-in-eclipse.html




-          Lets add Selenium and TestNg Maven dependencies in pom.xml

<dependencies>
    <dependency>
       <groupId>org.seleniumhq.selenium</groupId>
       <artifactId>selenium-java</artifactId>
       <version>2.53.0</version>
    </dependency>
  
       <dependency>
         <groupId>org.testng</groupId>
         <artifactId>testng</artifactId>
         <version>6.8</version>
         <scope>test</scope>
       </dependency>
</dependencies>


-          The moment you add above code in pom.xml, IDE starts to download the said jars
-          Now maven dependencies looks like this.





Java coding part:

-          Now create packages for Page object model as shown below.

-          Driver object creation
o   I have used singleton design patterns to create. Here you can find it. http://kranthikasthuri.blogspot.com/2016/04/design-patterns-singleton-single-object.html
o   MyDriver.java contains only Driver object related stuff

-          Now, Lets work on POM
o   What is POM : Segregating Locators , pages and Tests related to each page for better maintenance.
o   This is how I segregated http://theyachtclub.in/  Home Page Locators, Pages and Tests.

-              HomePageLocators
-              HomePage
-              HomePageTests

o   Locators:
§  This this the palace where all your Specific page level locators exists.
o   Pages:
§  This is the places where all your specific page level locators exists

o   Tests:
§  This is the places where all your specific page level Test cases exists


Do you want to see the code?
Here is it.
https://github.com/kasthurikranthikumar/selenium-pom-sample 



-          For Running the project:
o   Right click on POM.xml and select maven test
-          If you are facing any issues please check below points
o   Make sure you had an entry in pom.xml which is related to testing dependency
o   You test class file must end with Test
o   M2_Maven variable must be added