Showing posts with label architecture. Show all posts
Showing posts with label architecture. Show all posts

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);
}

}

Monday, 11 July 2016

WebDriver Architecture

All implementations of WebDriver that communicate with the browser, or a RemoteWebDriver server use a common wire protocol. This wire protocol defines a RESTful web service using JSON over HTTP.

So each WebDriver command is mapped to an HTTP method via the WebDriver service, and then passed on to the HTTP Command Processor to communicate with the browser. The Command responses are returned as HTTP/1.1 response messages via the WebDriver service.
Different drivers, such as the Firefox Driver and the IE Driver, have different implementations to accomplish the above.

The Selenium WebDriver architecture document linked below goes into further details on how these are implemented and how WebDrvier commands flow through to the browser and back. Read section 16.6 for details on the Firefox Driver.

Execution Flow:

Step 1. Automation Script is written using Client binding for different languages

Step 2. Once Test execution is started

Step 3. Browser driver is created

Step 3. Respective Driver.exe file starts “HTTP server” and starts listening for HTTP requests.

Step 4. A new HTTP request Creates, as each Selenium Method contains is mapped to respected webDriver API

Step 5. HTTP request is sent to the HTTP server

Step 6. HTTP server determines the steps needed for implementing the Selenium command

Step 7. The implementation steps are sent to the browser

Step 8. The HTTP server send the execution status back to the test script


Tuesday, 5 July 2016

Understanding Selenium IDE & Architecture




Selenium IDE, is an extension for Firefox that allows users to record and playback tests.

A table-based syntax was placed over the raw Javascript and this allowed tests to be written by people with limited programming experience using a keyword-driven approach in HTML files.  

Command        –               Element             –            Text
type                                 name=q                       Selenium WebDriver

Selenium IDE is developed using Javascript, as all the browsers being tested supported Javascript. 

Do you want to see? How Selenium IDE code looks like?

      a. Download latest selenium IDE add-on file from here. (Ex: http://release.seleniumhq.org/selenium-ide/2.9.0/ )  selenium-ide-2.9.0.xpi  749 KB

      b.   Extract xpi file using a software, which you can download here. http://b1.org/

      c.    You would notice multiple xpi files under selenium-ide-2.9.0.xpi file, but we are mainly looking at selenium-ide.xpi file

      d.    Extract selenium-ide.xpi file

      e.     Browse below folder once you extract xpi file C:\Users\USER_ACCOUNT\Downloads\selenium-ide-     2.9.0\selenium-ide\chrome\content\selenium-core\scripts

      f.     All Java script files!! This is the selenium Core.

Selenium Core is the heart of the original Selenium implementation, and is a set of Javascript scripts that control the browser. This is sometimes referred to as "Selenium" and sometimes as "Core".

How selenium IDE works?

Test Runner will do the job.


or

C:\Users\ USER_ACCOUNT \Downloads\selenium-ide-2.9.0\selenium-ide\chrome\content\selenium-core/ TestRunner.html

Below are the the referenced javascript files to execute our scripts.

Lib/prototype.js, lib/sizzle.js, lib/snapsie.js, scripts/atoms.js, scripts/htmlutils.js, scripts/ui-element.js, lib/scriptaculous/scriptaculous.js, scripts/selenium-browserdetect.js, scripts/selenium-browserbot.js, scripts/find_matching_child.js, scripts/selenium-api.js, scripts/selenium-commandhandlers.js, scripts/selenium-executionloop.js, scripts/selenium-testrunner.js, scripts/selenium-logging.js, scripts/selenium-version.js, xpath/util.js, xpath/xmltoken.js, xpath/dom.js, xpath/xpath.js, xpath/javascript-xpath-0.1.12.js, scripts/user-extensions.js

Above all javascript libraries are heart of selenium IDE, which are very important to run selenium commands.

So, Do you want to add your own / custom functionality? Here is the way.
Because Selenium's core is developed in JavaScript, creating an extension follows the standard rules for prototypal languages. To create an extension, we create a function in the following design pattern.
Ex: C:\Users\ USER_ACCOUNT \Downloads\selenium-ide-2.9.0\selenium-ide\chrome\content\selenium-core/script/user-extensions.js.sample

Selenium.prototype.assertValueRepeated = function(locator, text) {
    // All locator-strategies are automatically handled by "findElement"
    var element = this.page().findElement(locator);
    // Create the text to verify
    var expectedValue = text + text;
    // Get the actual element value
    var actualValue = element.value;
    // Make sure the actual value matches the expected
    Assert.matches(expectedValue, actualValue);
};
Save the above code as 'user-extensions.js"

By default, Selenium looks for a file called "user-extensions.js", and loads and javascript  code found in that file.  user-extensions.js provides a convenient location for adding extensions to Selenium, like  new actions, checks and locator-strategies.


By default, this file does not exist. Users can create this file and place their extension code  in this common location.
How to use newly created core extension?
1.     Go to Selenium IDE - Click on Options -> Options…
2.     In General section select the location of the newly created Selenium Core Extension
3.     Click OK and restart Selenium IDE

You will find the extension in the command list






Architecture:

Advantages:
  • Selenium IDE is very easy to use.
  • It has the capability to convert the test to different programming languages such as html, java etc
  • Programming language experience is not required for Selenium IDE
  • Selenium IDE provides Logging capabilities using file login plug-in.
  • In Selenium IDE, user can debug and set breakpoints
  • Selenium IDE is flexible for the users.
  • Auto complete for all common Selenium commands
  • Debug and set breakpoints
  • Option to automatically assert the title of every page
  • Support for Selenium user-extensions.js file
Disadvantage:
  • Selenium IDE is Firefox plugin, thus its support is limited to Firefox only
  • It will not support iteration and conditional statement
  • Selenium IDE doesn't support Exception and Error handling
  • Doesn't support test script grouping
  • No Reporting
  • No Test Fixtures and data-driven tests
  • No Test Dependencies
  • No way to take screen shots
  • Selenium IDE do not support Database testing
  • It is not playing multiple windows when we record it ( switching between windows).
  • limitations to open/ identifying the child windows,clicking on the pop ups, etc.,


Clue to Selenium Remote Controller:


Why not use Selenium IDE alone? For one thing, it works only with FireFox, version 1.5 or later. If we run the tests on the server, we can test our application using any browser.