Run selenium testng tests from executable jar



How to run Selenium testng tests from Executable jar file.?


Have you ever thought of to run some set of tests and convert those test to executable jar and share that jar file to team members who are non -technical / business members so that with simple double clicks those test would run.? If yes, here is how to achieve the it.

pre-requisite:
 > Have a directory with all required libraries, say directory name as 'lib', then put the following jar files, 
a) chromedriver
b) jcommander-1.78.jar (latest version jar)
c) selenium-server-standalone
d) testng-6.8.8.jar (latest version compatible jar) 

1) A simple selenium testng test implemented in eclipse. (make sure test is running)
a) Create a java file with main method, for ex:
public class TestRunner {
static TestNG testng;
public static void main(String[] args) {
testng = new TestNG();
testng.setTestClasses(new Class[] {fayaz.google.searchtest.GoogleSearch.class});
testng.run();
}
}
b) From this java file, run the tests as java application to make sure tests are running
2) Right click on the project and click 'Export...'
3) Under 'Java' select 'Runnable JAR file'
4) Click Next, select the Launh file as, 'TestRunner' (java file name) and export to desktop
5) Open command prompt from the project directory ( NOT FROM desktop)
6) Now, double click the executable jar by providing the absolute path, with java -jar command, 
         for ex: D:\fayaz\workspace\TestRunnerDemo\> java -jar C:\Users\Fayaz\Desktop\testrunner.jar

Note: if the jar is running from the desktop directory then test doesn't run. 


=============================
Now, to make run the jar from any directory we need to have the chrome driver accessible.
To make chrome driver accessible, we need to set the driver path in environment variable, after which we need to restart the eclipse..  

Then set the chrome driver path as below..

String evn_var_chrome_driver_path = System.getenv("chrome_driver_path");
System.setProperty("webdriver.chrome.driver", evn_var_chrome_driver_path + "\\chromedriver");

Boommm.. now convert the project to executable java jar file and run it from any directory





Quick Reference - Selenium Interview Questions

* What is hard asserstion and soft assertion

* Handle alerts  -->  driver.switchTo().alert().accept();

* Select options

Select select = new Select(webElement); //select.getOptions();
select.selectByIndex(1);

* tesng.xml example
   <suite name="TestSuiteName" parallel="tests">
     <test name="TestName" preserve-order="true">
              <classes>
<class name="org.pacakge.name.TestClassName" />
     </classes>
     </test>
   </suite>

* how to disable web security in chrome
ChromeOptions options = new ChromeOptions();
options.addArguments("--disable-web-security");
DesiredCapabilities capabilities = DesiredCapabilities.chrome();
capabilities.setCapability(ChromeOptions.CAPABILITY, options);

* how to take screenshot
TakesScreenshoot screenshot = ((TakesScreenshot)driver)
File sourceFile = screenshot.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(sourceFile, "filename.jpg");

* Difference between navigate().to(URL) and driver.get(URL)

* Difference between implicitWait and explicitWait

* Wait for pageLoad
WebDriverWait wait = new WebDriverWait(driver, timeoutInSecs);
ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>(){
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript(
"return document.readyState").equals("Complete");
}
};
wait.until(pageLoadCondition);


* KeyboardActions
Ex: Actions action = new Actions(driver);
action.keyDown(Keys.CONTROL).sendKeys(Keys.F5).perform();

* Difference between testNG and JUnit

* assertions and types

* Run TestNG using cucumber
use following classes
MultiLoader()
RuntimeOptionsFactory()
PluginFactory()
ResourceLoaderClassFinder()

* ErrorCollector in JUnit

* Javascript in selenium

Ex: String MAX_BROWSER_WIN = "if (window.screen){window.moveTo(0,0); window.resizeTo(window.screen.availWidth, window.screen.availHeight);};";
((JavascriptExecutor)driver).executeScript(MAX_BROWSER_WIN);

Ex: ((JavascriptExecutor)driver).executeScript("scroll(250, 0)");

* configuration of testng in maven
<pluings>
<plugin>
-----
<configuration>
<suiteXmlFiles>
<suiteXmlFile>testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>

* configuration of reports in maven

* grouping from testng.xml

<suite>
<test name="testName">
<groups>
<define name="includeGroup">
<inlucde name="includeTestOne" />
<include name="includeTestTwo" />
</define>
<define name="exlcudeGroup">
<exclude name="excludeTestOne" />
<exclude name="excludeTestTwo" />
</define>
<run>
<include name="include-group" />
<exclude name="exclude-group" />
</run>
</groups>
</test>
</suite>

* customization of test execution reports
using XSLT reports using testng+ANT

* Design patterns in selenium
DomainDrivenDesign: Express your tests in the language of the end-user of the app.
PageObjects  : A simple abstraction of the UI of your web app.
LoadableComponent : Modeling PageObjects as components.
BotStyleTests  : Using a command-based approach to automating tests, rather than the object-based approach that PageObjects encourage
AcceptanceTests   : Use coarse-grained UI tests to help structure development work.
RegressionTests   : Collect the actions of multiple AcceptanceTests into one place for ease of maintenance.

Capture network calls and performance stats





Capturing Network calls:

To capture the network calls while loading a page, we need to use java script executor, ]the following example may helps:

    ChromeOptions options = new ChromeOptions();
    options.addArguments("disable-info");
    options.addArguments("start-maximized");
    DesiredCapabilities capabilities = DesiredCapabilities.chrome();
    capabilities.setCapability(ChromeOptions.CAPABILITY, options);
    driver = new ChromeDriver(capabilities);
    driver.get(url);
    //switch to Browser  Functions tab for code implementation
    String netData = ((JavascriptExecutor) driver).executeScript(scriptToExecute).toString();
    BrowserFunctions.waitUntilPageLoads(driver);
    String scriptToExecute = "var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {}; var network = performance.getEntries() || {};
return network;";
    System.out.println(netData);

Note: The out put in json format.



Capture Network performance:

DesiredCapabilities d = DesiredCapabilities.chrome();
LoggingPreferences logPrefs = new LoggingPreferences();
logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
d.setCapability(CapabilityType.LOGGING_PREFS, logPrefs);
WebDriver driver = new ChromeDriver(d);
driver.get("https://www.google.co.in/");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
LogEntries les = driver.manage().logs().get(LogType.PERFORMANCE);
for (LogEntry le : les) {
    System.out.println(le.getMessage());
}





How to import ssl certificate for secure connection


Sometimes it is necessary to import certificates to make secure connections (https://) when it broke. This is like, we download from the broken url (http://) and the we import the same into browser, so called self-signed certificates.

I am using chrome browser here to explain how to import self-signed certificates. After following the images , don't forget to restart the browse



Image - 1
r



Image -2




Note: Restart the browser

Read JSON object using java


import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Scanner;
import org.json.JSONArray;
import org.json.JSONObject;
import org.testng.Reporter;
public class ReadJsonObject {

private String URL;

public ReadJsonObject(String url) {
this.URL = url;
}

public void aptTesting() throws Exception {
try {
URL url = new URL(this.URL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");

if (conn.getResponseCode() != 200) {
throw new RuntimeException(" HTTP error code : "
+ conn.getResponseCode());
}

Scanner scan = new Scanner(url.openStream());
String entireResponse = new String();
while (scan.hasNext())
entireResponse += scan.nextLine();

System.out.println("Response : " + entireResponse);
scan.close();

JSONObject obj = new JSONObject(entireResponse);
String responseCode = obj.getString("status");
System.out.println("status : " + responseCode);

JSONArray arr = obj.getJSONArray("results");
for (int i = 0; i < arr.length(); i++) {
String placeid = arr.getJSONObject(i).getString("place_id");
System.out.println("Place id : " + placeid);
String formatAddress = arr.getJSONObject(i).getString("formatted_address");
System.out.println("Address : " + formatAddress);

//validating Address as per the requirement
if(formatAddress.equalsIgnoreCase("Chicago, IL, USA"))
{
System.out.println("Address is as Expected");
} else {
System.out.println("Address is not as Expected");
}
}
conn.disconnect();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

Reading HTTP server response using java


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

public class ReadServerResponse {

private static final String USER_AGENT = "Mozilla/5.0";
private String URL;

public ReadServerResponse(String url){
this.URL = url;
}

public static void main(String[] args) {
ReadServerResponse readServerResponse =
new ReadServerResponse("<Your UR>");
StringBuffer response = readServerResponse.getServerResponse();
System.out.println(response);
}

public StringBuffer getServerResponse() {
StringBuffer buffer = new StringBuffer();
try {
URL unifromResourceIdentifier = new URL(this.URL);
HttpURLConnection httpConnection = (HttpURLConnection) unifromResourceIdentifier.openConnection();
httpConnection.setRequestMethod("GET");
httpConnection.setRequestProperty("User-Agent", USER_AGENT);
int statusCode = httpConnection.getResponseCode();
if(statusCode == HttpURLConnection.HTTP_OK) {
InputStream is = httpConnection.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(is));

String inputLine;

while ((inputLine = in.readLine()) != null) {
               buffer.append(inputLine);
           }
           in.close();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}

return buffer;
}
}

EventFiringMouse in selenium webdriver

Mouse Actions in selenium web driver:


Fine, while I was verifying an image (progress bar like, graph chart like) I wanted to make two tests as per my requirement, 
    1) Verify expected image / widget is loaded properly
    2) If it is a progress / graph chart, some part of the image will get shaded region and we need to click on that region to view complete details

I am gonna writing this post to share how actually I achieved and what I experienced in this process.. 

1) Apparently, unlike other functional testing tools, we can't verify the expected image pixel by pixel using selenium web driver.. Instead, we can verify, whether an image is completely loaded or not, in other words, we can make sure, while loading page, expected image has not been broken

      To do this, I have written the following code, 
          import org.apache.http.HttpResponse;
          import org.apache.http.impl.client.DefaultHttpClient;
          import org.apache.http.client.methods.HttpGet;
/**
  * The following method verifying whether an expected image element is loaded properly or not,
  *  by reading image URL as an argument and returns true, if image loaded completely
  *
  *   @param imageURL
  **/
  public static boolean verifyImageStatus(String imageURL){
      try{
              HttpResponse  response = new DefaultHttpClient().execute(new HttpGet(imageURL));
              int statusCode = response.getStatusLine().getStatusCode();
              if(statusCode != 200) {
                           return false;
              }
      } catch(ClientProtocolException cpe) {
      } catch(IOException ioe) {
      }
       return true;
  }


2) To click on an web element, we can do it two ways as per my knowledge, using selenium webdriver 

 > Basic level:     Using simple 'Actions' class 

     Actions action = new Actions(webDriverReference);
     WebElement mainMenu = webDriverReference.findElement(By.linkText("mainMenuLink"));
     action.moveToElement(mainMenu);

     WebElement subMenu =  webDriverReference.fineElement(By.linkText("subMenuLink"));
     action.moveToElement(subMenu);
     action.click().build().perform();

     The entire thing can be also be done in a other way, 

     Actions action = new Actions(webDriverReference);
     WebElement mainMenu = webDriverReference.findElement(By.linkText("mainMenuLink"));
     action.moveToElement(mainMenu).moveToElement(webDriverReference.findElement(By.linkText("subMenuLink"))).click().build().perform();

>Advance level: Using EventFiringWebdriver and EventFiringMouse classes

       From selenium API, we can find that we have already provided with listeners so, what we need to do now is to simply implementing / extending those interface / classes respectively.

       For the time being, I will call a class, and say it is 'TestMouseEventListener' which extends 'AbstractWebDriverEventListener'. Notable thing here with API is, 'AbstractWebDriverEventListener' class is already have all implemented methods of 'WebDriverEventListener' interface, inorder to access these methods we need a reference, and since 'AbstractWebDriverEventListener' is an abstract class, we are creating our own class 'TestMouseEventListener' by extending it

        /**
          * Custom listener class
          */
           public class TestMouseEventListener extends AbstractWebDriverEventListener {
           }

        Now, inorder to click a web element, we need to register the event firing web driver and then use it, simple isn't it.. 

           /**
             *   part of implemented code
              **/
           TestMouseEventListener tmel = new TestMouseEventListener();
           EventFiringWebDriver efwd = new EventFiringWebDriver(webDriverReference);
           efwd.register(tmel);

           EventFiringMouse efm = new EventFiringMouse(webDriverReference, tmel);
         
           Locatable locator = (Locatable)webElement;
           Coordinates coordinates = locator.getCoordinates();
           //Move mouse to web element coordinates
           efm.mouseMove(coordinates);
           sleep(5.0);


  

Code snippet ready-made...

To get web element properties:


I am assuming you have already driver and element initialized in hand, then the following code is used to read the element properties 

/**
 * Return properties list of an element
 */
public static Object getElementProperties(WebElement element){
    Object object = ((JavascriptExecutor)driver).executeScript("var item{};  " + 
                                 " for (index = 0; index < argument[0].attributes.length(); ++index)  { " +
                                 " items[arguments[0].attributes[index].name = arguments[0].  " +                                                              " attributes[index]. value}; return items; ", element)
    return object;
}

Exception & Solutions

Exceptions & Solutions:

           Apparently, as a junior programmer, one can write the code but an experience programmer can easily debug whereas an expert can implement code to avoid run time exceptions., nevertheless we will face exceptions at some point of time.
          Objective of this page is to make familiar with some exceptions I dealt with the possible solutions I got. One more time, this is the possible solutions I found, perhaps your exception may differ in case to occur.
Sharing here may useful to some one or may be it will hold as a record for me to revise later point of time :D

However, see some of the exceptions here also.


Handling SSL Certificates


How to handle SSL Certificates ..??

This Exception may be common to all , but my fingers crossed when I see the next wizard, as shown in second image, 

Image 1:  This Connection is Untrusted
If we click 'Add Exception' button in the first page, then the next wizard comes up as shown below

Image 2: Add Security Exception

After a long search on some forums, I found that a small piece of code are not explained by most of the them or may be I come across most of such blogs. However, I thought of to put what I have discovered and handled this issue and where I was missing or may be you are missing the actual explanation in other blogs

Apparently, handling this ssl certificate can be achieved on firefox browser only, because it allows users to access the profile and where as other browsers doesn't have option for creating custom browser profile, if any one knows, please let me know in comments

Now, before explaining code, I want to explain how to create custom firefox profile then the code might be easily understands at its a very few in lines. 

How to create custom firefox profile?

1) Close all firefox browser windows and run the following command
firefox -ProfileManager -no-remote
2) Click "Create Profile"  and follow the instructions on the wizard
3) You can create with any name, as I created with "QAAutomation" as shown in below image

"firefox -ProfileManager -no-remote" to choose firefox profile

This is how we can create profiles in firefox browser, now we have to use this profile in our selenium webdirver code, as follows

#Java Program:

Method 1:
/**
 * Handle Untrusted HTTPs Connections With Selenium web driver. Also, handle an
 * additional wizards like, 'Add Security Exception' by Confirm Security
 * Exception
 * 
 * @author Fayaz
 * 
 */
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;


public class HandleWindows {

public static void main(String[] args){
ProfilesIni profile = new ProfilesIni();
FirefoxProfile ffProfile = profile.getProfile("QAAutomation"); // firefox profile **
ffProfile.setAcceptUntrustedCertificates(true);
ffProfile.setAssumeUntrustedCertificateIssuer(false);
WebDriver driver = new FirefoxDriver(ffProfile);
driver.get(URL);
}
}


** Most of the blogs are pasted code as it is, where some says, "HandleSSLCertificate" but they don't explain what is this "HandleSSLCertificate", whereas others explains simply as "firefox user profile name" (but they missed how to create profile, indeed)


Remember most of us use "default" as a profile name, by default. So please pass "default" as an parameter to getProfile() and try if you want, that is new ProfilesIni().getProfile("default");

Method 2:

/**
 * Handle Untrusted HTTPs Connections With Selenium web driver. Also, handle an
 * additional wizards like, 'Add Security Exception' by Confirm Security
 * Exception
 *
 * @author Fayaz
 *
 */
import java.io.File;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;
import org.openqa.selenium.firefox.internal.ProfilesIni;


public class HandleWindows {

 public static void main(String[] args){
 FirefoxProfile ffProfile = new FirefoxProfile(new File("C:\\Users\\Fayaz\\Desktop\\Selenium\\custom")); // firefox profile**
  ffProfile.setAcceptUntrustedCertificates(true);
  ffProfile.setAssumeUntrustedCertificateIssuer(false);
  WebDriver driver = new FirefoxDriver(ffProfile);
  driver.get(URL);

 }
}

** While creating a firefox profile I created a new folder with name 'custom'. That is though "QAAutomation" is actual firefox profile name, it is created under 'custom' directory. so custom is a my favorite directory on my machine where as QAAutomation is a firefox profile name


Finally, those who wants to execute test from command line interface aka CLI, then the command should be like, 
java -jar selenium-server.jar -firefoxProfileTemplate "C:\Users\Fayaz\Desktop\Selenium",
instead  of the giving the whole default path like, 
java -jar selenium-server.jar -firefoxProfileTemplate "C:\Documents and Settings\Fayaz\Application Data\Mozilla\Firefox\Profiles\io4kgk8d.default"
That's all we are done. For more info see Tips & Tricks page

Chrome :

Though by the time of writing this blog page, I didn't find the similar way, how we are handling dialog firefox browser. However, one way I used to handle this certificate dialog while using chrome is using Threads in java

Before, you read further, let me tell you what my issue was

When I request to an URL by calling our selenium WebDrivers, get(String URL) method and before the response gets back, certificate dialog is appearing and until I select the certificate the URL page isn't loading.
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Fayaz\\Desktop\\chromedriver.exe");
WebDriver driver = new ChromeDriver(); 
driver.get(URL); // this method execution is not finishing until I select a dialog in the //certificate dialog
driver.findElements(By.cssSelector("input#username")); //this code is not at all reaching

 So, inorder to handle this, what I did was, I was calling a Thread in which using Robot class, making enter key to press. That is, start a thread and make it to sleep for a while then do request to URL from driver.get() method, by the time certificate dialog appears our Thread process should finishes its sleep time and then start the thread to run, where in run() method, our Robot class hit the enter button

Here is the working code for me, how it works....        

#Java Program:

package selenium.project;

import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.remote.DesiredCapabilities;

/**
 * Handle Untrusted HTTPs Connections With Selenium web driver. Also, handle an
 * additional wizards like, 'Add Security Exception' by Confirm Security
 * Exception
 *
 * @author Fayaz
 *
 */
public class HandleWindows {

private static final String URL = "<your URL here> ";

public static void main(String[] args) {
WebDriver driver = null;
try {
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Fayaz\\Downloads\\chromedriver.exe");
driver = new ChromeDriver();
Thread certSelectionThread = null;
Runnable r = new Runnable() {

@Override
public void run() {
try {
Thread.sleep(1000 * 10);
Robot robot = new Robot();
robot.keyPress(KeyEvent.VK_ENTER);
} catch (AWTException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
certSelectionThread = new Thread(r);
certSelectionThread.start();
driver.get(URL);
if(certSelectionThread != null){
try {
certSelectionThread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} finally {
if(driver != null && !driver.toString().contains("null")){
driver.close();
driver.quit();
}
}
}
}



Sometime we need to handle certificate issues (SSL) with chrome as well especially for self-signed certificates. else we get exception, which says as follows

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:387)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:292)
at sun.security.validator.Validator.validate(Validator.java:260)
at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:324)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:229)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:124)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1351)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:156)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:925)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:860)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1043)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1343)
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:728)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123)
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:138)



when we run the following piece of code

public static boolean waitUntilRequestCompletes(String urlRequest) {
try {
URL url = new URL(urlRequest);
HttpURLConnection conn;
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");

if (conn.getResponseCode() != 200) {
throw new RuntimeException(" HTTP error code : "
+ conn.getResponseCode());
}

Scanner scan = new Scanner(url.openStream());
String entireResponse = new String();
while (scan.hasNext()) {
entireResponse += scan.nextLine();
System.out.println("Response : " + entireResponse);
}
scan.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}


To avoid such exception it is important to add signed certificate to JVM - security\cacerts.

How to do that.?

So from the insecure URL download the certificate, follow this page to know how to download certificate

Once the certificate in place, open command prompt in admin mode and run the following command

keytool -import -alias example_name -keystore "C:\Program Files\Java\jdk1.8.0_121\jre\lib\security\cacerts" -file "C:\Users\Fayaz\Desktop\ss_certificate\pd-123456789.cer"

That's it done. happy secure connection :)

Selenium Grid

Selenium Grid:

Well, I have experienced the following scenarios while setting up the grid environment for the first time. 

Here it is, I have two machine, say '10.19.137.247' (test machine) and 192.168.1.113 (test dev machine) so to start the hub on test machine I have run the following command:

On Test Machine:

    java -jar selenium-server-standalone.jar -role hub
The following message or information appeared on command line as a result
Mar 10, 2014 2:57:03 AM org.openqa.grid.selenium.GridLauncher main
INFO: Launching a selenium grid server
2014-03-10 02:57:26.332:INFO:osjs.Server:jetty-7.x.y-SANPSHOT
2014-03-10 02:57:26.395:INFO:osjsh.ContextHandler:started o.s.j.s.ServletContextHandler{/,null}
2014-03-10 02:57:26.410:INFO:osjs.AbstractConnector:Started SocketConnector@0.0.0.0:4444     

On Test Dev machine:

 java -jar selenium-server-standalone -Dwebdriver.chrome.driver=C:\Users\Fayaz\Downloads\chromedriver.exe -role webdriver -hub http://10.19.137.247/grid/register
The following message or information appeared on command line as a result
Mar 10,  2014 12:30:36 PM org.openqa.grid.selenium.GridLauncher main
INFO: Launching a selenium grid node
Mar 10, 2014 12:30:39 PM org.openqa.grid.internal.utils.SelfRegisteringRemote startRemoteServer
WARNING: error getting the parameters from the hub. The node may end up with wrong timeouts. Connection refused: connect
12:30:39.255 INFO - Java: Oracle Corportation 24.45-b08
12:30:39.263 INFO - OS:Windows 7 6.1 x86
12:30:39.295 INFO - v2.39.0, with Core v2.39.0. Built from revision ff23eac
12:30:39.565 INFO - Default driver org.openqa.selenium.iphone.IPhoneDriver registration is skipped: registration capabilities Capabilites [{platform=MAC, browserName=iPhone, version=}] does not match with current platform: VISTA
12:30:39:565 INFO - Default driver org.openqa.selenium.iphone.IPhoneDriver registration is skipped:
registration capabilities Capabilities [{platform=MAC, browserName=iPad, version=}] does not match with current platform: VISTA
12:30:39.648 INFO - RemoteWebDriver instances should connect to : http://127.0.0.1:5555/wd/hub
12:30:39.649 INFO - Version Jetty/5.1.x
12:30:39.650 INFO - Started HttpContext[/selenium-server/driver./selenium-server/driver]
12:30:39.651 INFO - Started HttpContext[/selenium-server,/selenium-server]
12:30:39:652 INFO - Started HttpContext[/,/]
12:30:39:654 INFO - Started org.openqa.jetty.jetty.servlet.ServletHandler@12132a6
12:30:39.654 INFO - Started HttpContext[/wd,/wd]
12:30:39.657 INFO - Started SocketListener on 0.0.0.0:5555
12:30:39.658 INFO - Started Started org.openqa.jetty.jetty.Server@a4b9da
12:30:39.661 INFO - using the json request : {"class":"org.openqa.grid.common.RegistrationRequest","capabilities":[{"platform":"VISTA","seleniumProtocol":"Selenium","browserName":"*firefox","maxInstances":5},{"platform":"VISTA","seleniumProtocol":"Selenium","browserName":"*googlechrome","maxInstances":5},{"platform":"VISTA","seleniumProtocol":"seleniumProtocol":"WebDriver","browserName":"chrome","maxInstances":1},{"platform":"VISTA","seleniumProtocol":"WebDriver","browserName":"internet explorer","maxInstances":1}],"configuration":{"port":5555,"register":true,"host":"192.168.1.113","proxy":"org.openqa.grid.selenium.proxy.DefaultRemoteProxy","maxSession":5,"role":"node","hubHost":"10.19.137.247","registerCycle":5000,"hub":"http://10.19.137.247/grid/register","hubPort":-1,"url":"http://192.168.1.113:5555","remoteHost":"http://192.168.1.113:5555"}}
12:30:39.664 INFO - Starting auto register thread. Will try to register every 5000 ms.
12:30:39.664 INFO - Registering the node to hub :http://10.19.137.247:-1/grid/register
12:30:41.466 INFO - couldn't register this node : Error sending the registration request.
12:30:48.264 INFO - couldn't register this node : Hub is down or not responding: Connection refused: connect
If we observer on the test machine to verify the status of the selenium web server whether the client / node is connected or not, in other words when no node connects to hub using selenium grid, it will looks like in the screen shot

When no nodes connects to a hub using selenium grid then the server details displayed


This error has been resolved after I corrected the command to connect the hub from my test dev machine, and the changed command is
java -jar selenium-server-standalone.jar -Dwebdriver.chrome.driver=C:\Users\Fayaz\Downloads\chromedriver.exe -role webdriver -hub http://10.19.137.247:4444/grid/register

The difference here is I am using port number ':4444' after test machine URL

After connecting to the server, we can verify the status of the selenium web server whether the client / node is connected or not, it will looks like in the screen shot


When a node connects to hub using selenium grid then the list of details displayed


The path in browser to see list of clients or nodes connected to a hub at server / hub side is,
 localhost:4444/grid/console
For a beginner most common and exception can occur as follows, part of exception pasted
Caused by: java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.chrome.driver system property;
For more info please find the source here

To handle ssl or certification errors on a remote browser, I have used the following code and it worked like a charm

For IE or Chrome:
  remoteWebdriver.navigate().to("javascript:document.getElementById('overridelink').click()");
//I assume you have already had a wed driver reference called 'remoteWebdriver'


Now, to take screen shot of the remote test script execution, you can find the code in this selenium webdriver cheat code or from here

Update :


From the latest release of selenium 3.x, if we use above command to register client to remote hub then we get the following exception

Exception in thread "main" com.beust.jcommander.ParameterException: Unknown option: -Dwebdriver.chrome.driver=C:\Users\Fayaz\Downloads\chromedriver.exe
        at com.beust.jcommander.JCommander.parseValues(JCommander.java:742)
        at com.beust.jcommander.JCommander.parse(JCommander.java:282)
        at com.beust.jcommander.JCommander.parse(JCommander.java:265)
        at com.beust.jcommander.JCommander.<init>(JCommander.java:210)
        at org.openqa.grid.selenium.GridLauncherV3$3.setConfiguration(GridLauncherV3.java:267)
        at org.openqa.grid.selenium.GridLauncherV3.buildLauncher(GridLauncherV3.java:155)
        at org.openqa.grid.selenium.GridLauncherV3.main(GridLauncherV3.java:75)




So the command to register a node / client is changed as follows:

                        java -jar selenium-server-standalone-3.3.1.jar -role node -hub http://<hub_ip>:4444/grid/register -port 4444

Browser Functions

Handling Browser Functionality

Scroll Down:

/**
 * Scroll to the bottom of a page and sleep for 10 seconds
 * 
 */
public static void scrollDown() {
((JavascriptExecutor) SeleniumAction.getDriver())
.executeScript("scroll(0, 250)");
sleep(10); // Customized sleep method
}

Scroll Up:

/**
 * Scroll to the top of a page and sleep for 10 seconds
 * 
 */
public static void scrollUp() {
((JavascriptExecutor) SeleniumAction.getDriver())
.executeScript("scroll(250, 0)");
sleep(10); // Customized sleep method
}


Scroll Upto an Element:

/**
 * Scroll to an web element to make it display on screen 
 *  
 * @param element
 */
public static void scrollToAnElement(WebElement element) {
if (isElementExists(element)) {
((Locatable) element).getCoordinates().inViewPort();
sleep(5); // Customized sleep method
}

}

Maximize a web browser:
/**
* Maximize a browser window
*/
public void maximizeBrowserWindow(){
       driver.manage().window().maximize();
}

Refresh a browser:
/**
* Refresh a browser window
*/
//Method #1:
public void refreshBrowserWindow(){
       driver.navigate().refresh();
}

//Method #2:
public void refreshBrowserWindow(){
       driver.get(driver.getCurrentUrl());
}

// Method #3:
public void refreshBrowserWindow(){
      driver.navigate().to(driver.getCurrentUrl());  
}

//Method #4:
public void refreshBrowserWindow(WebDriver driver){
      Actions refreshAction = new Actions(driver);
      refreshAction.keyDown(Keys.CONTROL).sendKeys(Keys.F5).perform();
}

Handling an alert:
/**
 * Handling an alert dialog 
 * 
 *@param discard
 */
public void handleAlert(boolean discard){
     Alert alertHandler =    driver.switchTo().alert();
     if(discard){
          alertHandler.dismiss();
     } else {
           alertHandler.accept();
     }
}

Take a screenshot:

/**
 * Takes a screen shot and save with the given file name
 *  
 * @param fileName
 * @throws IOException
 */

public static void takeScreenshot(String fileName) throws IOException {
File screenshot = ((TakesScreenshot) SeleniumAction.getDriver())
.getScreenshotAs(OutputType.FILE);
String dirPath = ScriptsExecuted.getRFTLogDirectory()
+ fileName
+ new SimpleDateFormat("MM-dd-yyy_HH:ss")
.format(new GregorianCalendar().getTime() + ".jpg");
FileUtils.moveFile(screenshot, new File(dirPath));
}

// For taking a screen shot on remote web driver, source

/**
  *  RemoteWebDriver does not implement the TakesScreenshot class
  *  if the driver does have the Capabilities to take a screenshot

  *  then Augmenter will add the TakesScreenshot methods to the instance
  */
public void myTest() throws Exception {
        WebDriver driver = new RemoteWebDriver(
                                new URL("http://localhost:4444/wd/hub"), 
                                DesiredCapabilities.firefox());
        
        driver.get("http://www.google.com");
        WebDriver augmentedDriver = new Augmenter().augment(driver);
        File screenshot = ((TakesScreenshot)augmentedDriver).
                            getScreenshotAs(OutputType.FILE);
}


Verification of an element existence:

/**
 * Method to verify whether desired web element is exists or not by handling
 * exceptions
 * 
 * @param element
 * @return
 */
public static boolean isElementExists(WebElement element) {
boolean result = false;
try {
if (element != null) {
result = element.isDisplayed();
}
} catch (NoSuchElementException noElementExecption) {
result = false;
} catch (StaleElementReferenceException staleElementException) {
return false;
}
return result;
}


Wait For page to load

void waitForLoad(WebDriver driver) {
    ExpectedCondition<Boolean> pageLoadCondition = new
        ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
            }
        };
    WebDriverWait wait = new WebDriverWait(driver, 30);
    wait.until(pageLoadCondition);

}


Validate Image Loaded properly

/**
  * Import statements, 
  */
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;

public void validateInvalidImages() {
try {
invalidImageCount = 0;
List<WebElement> imagesList = driver.findElements(By.tagName("img"));
System.out.println("Total no. of images are " + imagesList.size());
for (WebElement imgElement : imagesList) {
if (imgElement != null) {
verifyimageActive(imgElement);
}
}
System.out.println("Total no. of invalid images are " + invalidImageCount);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
}

public void verifyimageActive(WebElement imgElement) {
try {
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(imgElement.getAttribute("src"));
HttpResponse response = client.execute(request);
// verifying response code he HttpStatus should be 200 if not,
// increment as invalid images count
if (response.getStatusLine().getStatusCode() != 200)
invalidImageCount++;
} catch (Exception e) {
e.printStackTrace();
}

}