Tuesday, February 18, 2020

Selenium WebDriver – Singleton DriverFactory Design Pattern Using Java 8

WebApplication Singleton driver Factory Design Pattern :


Mobile Singleton driver Factory Design Pattern :
  • AppiumServerJava : is used to customize the url and desirecapabilities 
  • CreateDriver     : is to create LocalThread instance 


Package Runner;

import java.io.IOException;

import java.net.MalformedURLException;

import java.net.URL;

import org.apache.log4j.Logger;

import org.apache.log4j.xml.DOMConfigurator;

import org.apache.commons.cli.CommandLine;

import org.apache.log4j.Logger;

import org.openqa.selenium.WebDriver;

import org.openqa.selenium.remote.DesiredCapabilities;

import org.openqa.selenium.remote.RemoteWebDriver;

import org.testng.annotations.BeforeClass;

import org.testng.annotations.BeforeSuite;

 

import io.appium.java_client.android.AndroidDriver;

import io.appium.java_client.remote.AndroidMobileCapabilityType;

import io.appium.java_client.remote.MobileCapabilityType;

import io.appium.java_client.remote.MobilePlatform;

import io.appium.java_client.service.local.AppiumDriverLocalService;

import io.appium.java_client.service.local.AppiumServiceBuilder;



public class AppiumServerJava {

       private static DesiredCapabilities cap;

       public static AndroidDriver driver;

       public static AppiumServiceBuilder builder = null;

       static AppiumDriverLocalService service = null;

         private static Logger Log = Logger.getLogger(AppiumServerJava.class);

 

//     @BeforeSuite

       public static DesiredCapabilities AppiumServerCapabilities() {

              DOMConfigurator.configure(System.getProperty("user.dir") + File.separator + "log4j.xml");

              Log.debug("This is debug message ");

              Log.info("desire capabilities initized");

              File appDir = new File(System.getProperty("user.dir") + "/src/test/java/appStore/");

              File app = new File(appDir, "Flipkart Online Shopping App_v6.17_apkpure.com.apk");

              Log.info(app + "_____");

              cap = new DesiredCapabilities(); // Cabaliliesties for server

              cap.setCapability("noReset", "false");

//            cap.setCapability(MobileCapabilityType.BROWSER_NAME, "Android");

              cap.setCapability(MobileCapabilityType.UDID, "4200cab8de3b747f"); // Give Device ID of your mobile phone

              cap.setCapability(MobileCapabilityType.APP, app.getAbsolutePath());

              cap.setCapability(MobileCapabilityType.DEVICE_NAME, "Galaxy On Max");

              cap.setCapability(MobileCapabilityType.PLATFORM_NAME, MobilePlatform.ANDROID);

              cap.setCapability(AndroidMobileCapabilityType.APP_PACKAGE, "com.flipkart.android");

              cap.setCapability("appActivity", "com.flipkart.android.SplashActivity");

              builder = new AppiumServiceBuilder().withCapabilities(cap);

              DesiredCapabilities capClient = new DesiredCapabilities(); // Capabilities for client

              return cap;

       }


       public static String getURL() {

              AppiumServerCapabilities();

              service = builder.build();

              Log.info("appium service started ");

              service.start();

              Log.error(service.getUrl().toString());

              return service.getUrl().toString();

       }


    }

public class CreateDriver extends AppiumServerJava{

private static Logger Log = Logger.getLogger(CreateDriver.class);




       private static final ThreadLocal<AndroidDriver> mobileDriver = new ThreadLocal<AndroidDriver>();

       private URL serverUrl = null;



/*

        * Method to create local driver

        * @param capabilities

        * @param testBedConfig

        */

      

       public void createLocalDriver(){

//            AndroidDriver driver = null;

              try {

                      serverUrl = new URL(AppiumServerJava.getURL());

                      Log.info("createLocalDriver ::: serverUrl:::"+serverUrl);

              } catch (MalformedURLException e) {

                      e.printStackTrace();

              }

              try{

                      driver = new AndroidDriver(serverUrl, AppiumServerJava.AppiumServerCapabilities());

                     driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

                      setDriver(driver);

              }catch(Exception ex){

                      Log.error("Error while createLocalDriver:::"+ex.getMessage());

                      ex.printStackTrace();

              }

       }

      

       /**

        * Method to get driver

        * @param capabilities

        * @param testBedConfig

        * @return

        */

       @BeforeSuite

       public AndroidDriver getDriverAndroid(){

//            AndroidDriver driver = null;

              if(mobileDriver.get()==null){

                      createLocalDriver();

              }

              return mobileDriver.get();

       }

      

       /**

        * Method to set driver

        * @param localDriver

        */

       public void setDriver(AndroidDriver localDriver){

              mobileDriver.set(localDriver);

       }

      

       /**

        * Method to get driver

        * @return

        */

       public static AndroidDriver getDriver(){

              return driver =mobileDriver.get();

       }

}




2 .  Singleton driver Factory Design Pattern :

//chrome driver supplier
Supplier<WebDriver> chromeDriverSupplier = () -> {
    System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
    return new ChromeDriver();
};
 
//firefox driver supplier
Supplier<WebDriver> firefoxDriverSupplier = () -> {
    System.setProperty("webdriver.gecko.driver", "/Users/username/Downloads/geckodriver");
    return new FirefoxDriver();
};
Copy
You might want to add additional suppliers like Safari, IE etc depends on your requirement.
public enum DriverType {
    CHROME,
    FIREFOX,
    SAFARI,
    IE;
}
Copy
To avoid if-else / switch statements, I create a map as shown here. Once I have all my suppliers, then I add the suppliers into the map.
public class DriverFactory {
 
    private static final Map<DriverType, Supplier<WebDriver>> driverMap = new HashMap<>();
 
    //chrome driver supplier
    private static final Supplier<WebDriver> chromeDriverSupplier = () -> {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        return new ChromeDriver();
    };
 
    //firefox driver supplier
    private static final Supplier<WebDriver> firefoxDriverSupplier = () -> {
        System.setProperty("webdriver.gecko.driver", "/Users/username/Downloads/geckodriver");
        return new FirefoxDriver();
    };
 
    //add more suppliers here
 
    //add all the drivers into a map
    static{
        driverMap.put(DriverType.CHROME, chromeDriverSupplier);
        driverMap.put(DriverType.FIREFOX, firefoxDriverSupplier);
    }
 
    //return a new driver from the map
    public static final WebDriver getDriver(DriverType type){
        return driverMap.get(type).get();
    }
 
}
Copy
Now your test should be simply written as shown here to get a new WebDriver.
public class SampleBrowserTest {
 
    private WebDriver driver;
 
    @BeforeTest
    public void setup(){
        driver = DriverFactory.getDriver(DriverType.CHROME);
    }
 
    @Test
    public void test1(){
        driver.get("https://www.google.com");
        //your test using webdriver
    }
 
    @AfterTest
    public void teardown(){
        driver.close();
    }
 
}


3.   Driver Factory using Maven  dependency



 <dependency>
    <groupId>ru.stqa.selenium</groupId>
    <artifactId>webdriver-factory</artifactId>
    <version>4.4</version>
</dependency>
<dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
</dependency>
 


The library provides three ways to manage instances:
  • SingleWebDriverPool allows a single managed instance of WebDriver to exist at any given moment,
  • ThreadLocalSingleWebDriverPool allows a single managed instance of WebDriver to exist for each thread,
  • LooseWebDriverPool does not impose any restrictions, it creates a new managed instance on each request.
You can use as many separate pools as you like, but there is also WebDriverPool.DEFAULT that is an instance of ThreadLocalSingleWebDriverPool.



import ru.stqa.selenium.factory.WebDriverPool;
 
 
// adding desirecapabilities;
@BeforeEach public void initDriver() throws Throwable { 
       driver = WebDriverPool.DEFAULT.getDriver(gridHubUrl, capabilities); 
}
 
// Start Browser :
@BeforeMethod public void startBrowser() { 
       driver = WebDriverPool.DEFAULT.getDriver(DesiredCapabilities.firefox());
 }
 
 
@Test
public void testSomething() {
  WebDriver driver = WebDriverPool.DEFAULT.getDriver(new FirefoxOptions());
  // do something with the driver
  driver.get("http://seleniumhq.org/");
}
 
@Test
public void testSomethingElse() {
  WebDriver driver = WebDriverPool.DEFAULT.getDriver(new ChromeOptions());
  // do something with the driver
  driver.get("http://seleniumhq.org/");
}
 
@AfterSuite
public void stopAllDrivers() {
  WebDriverPool.DEFAULT.dismissAll();
}







4.   




No comments:

Post a Comment