Verify Broken Links

By Published:
Verify Broken Links
Hi All,
Now we will learn how to validate broken links on page using WebDriver and java http methods. There are so many open source free tools available in market. Like Xenu we can validate the same but if we have to validate multiple web pages like >300 then it will be very tiresome task to enter each page URL.

Approach:

First we will open the webpage using web driver and get all the links having <A> tag. For finding the link URL, we will get the “href” property value of all the links present in webpage. In this way we will store the all the links URL present on webpage. We  have to exclude those links which having href property value like java script, hash(#) or mail to etc… because these links either referring to same page or refer to outlook mail like mail to link present in contact section.
Now we have the entire link’s URL, one way to open each URL using WebDriver but it is not advisable to use this approach because it will take too much time to perform. Instead of this we can use http method technique to test this. If my response code is 200 that means it is valid request else not. Note: Sometimes URL asks for certification acceptance, for handling this we are using SSL manager. For authentication URLs we can also use authentication methods

Below is the code where we getting the page URLs from excel sheet and validating the broken links. Results are saving in notepad.  Please do the modifications as per your need.

##################################################################

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class BrokenLinks {
 public static void main(String[] args) throws Exception {
  WebDriver driver = new FirefoxDriver();
  String urlxpath = "//a";
  List<WebElement> elements;
  Map<String, String> AllLinksURL = new HashMap<String, String>();
  Map<Integer, String> m = new HashMap<Integer, String>();
  try {
   // Open the Excel file
   FileInputStream fis = new FileInputStream(
     "D:\\url.xlsx");
   // Access the required test data sheet
   XSSFWorkbook wb = new XSSFWorkbook(fis);
   XSSFSheet sheet = wb.getSheet("url");
   // Loop through all rows in the sheet
   // Start at row 1 as row 0 is our header row
   File file = new File("Output.txt");
   // creates the file
   file.createNewFile();
   // creates a FileWriter Object
   FileWriter writer = new FileWriter(file);
   int i = 0;
   try {
    for (int count = 0; count <= sheet.getLastRowNum(); count++) {

     XSSFRow row = sheet.getRow(count);
     String page = row.getCell(0).toString();
     m.put(i, page);
     i++;
    }
   } catch (Exception e) {
    System.out.println(e);
   }
   fis.close();

   Collection<String> keyset = m.values();
   System.out.println(keyset);
   try {
    for (String page : keyset) {

     driver.get(page);
     Thread.sleep(5000);
     elements = driver.findElements(By.xpath(urlxpath));
     System.out.println(elements.size());
     // System.out.println(elements);
    
      for (WebElement ele : elements) {
       try {
        String temp = ele.getAttribute("href");
        // System.out.println(temp);

        if (temp != null) {
         if (!temp.contains("javascript")
           && (!temp.contains("tel://"))&& (!temp.contains("mailto:"))&& (!temp.equalsIgnoreCase("#")))
          
         AllLinksURL.put(temp, temp);

        }
       } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }
     
     

     
      for (String urlVal : AllLinksURL.keySet()) {
       try {
        String res = check(urlVal);
        // System.out.println(res);
        if (!res.equals("OK")) {

         // Writes the content to the file
         writer.write(page + "\t" + urlVal + "\t" + res
           + "\n");
         writer.flush();

        }
       } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }
      }
      AllLinksURL.clear();

    }
   } catch (Exception e) {
    System.out.println(e);
   }
   writer.close();
  } catch (IOException e) {
   System.out.println(e);
   System.out.println("Url file not found");
  }
 }

 public static String check(String urlString) throws Exception {
  String response = "";
  TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
   public java.security.cert.X509Certificate[] getAcceptedIssuers() {
    return null;
   }

   public void checkClientTrusted(X509Certificate[] certs,
     String authType) {
   }

   public void checkServerTrusted(X509Certificate[] certs,
     String authType) {
   }
  } };

  // Install the all-trusting trust manager
  SSLContext sc = SSLContext.getInstance("SSL");
  sc.init(null, trustAllCerts, new java.security.SecureRandom());
  HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

  // Create all-trusting host name verifier
  HostnameVerifier allHostsValid = new HostnameVerifier() {
   public boolean verify(String hostname, SSLSession session) {
    return true;
   }
  };

  // Install the all-trusting host verifier
  HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

  URL url = new URL(urlString);
  URLConnection con = url.openConnection();
  HttpURLConnection connection = (HttpURLConnection) con;
  connection.connect();

  response = connection.getResponseMessage();
  System.out.println("Response : " + response);
  connection.disconnect();
  return response;
 }
}


########################################################################
########################################################################

Webdriver | Implicit wait vs Explicit wait vs Fluentwait

By Published:
Implicit Wait:
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));

When to use: Not recommended

Explicit wait:
An explicit waits is code you define to wait for a certain condition to occur before proceeding further in the code. WebDriverWait by default calls the ExpectedCondition every 500 milliseconds until it returns successfully.

WebDriver driver = new FirefoxDriver();
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = (new WebDriverWait(driver, 10))
  .until(ExpectedConditions.presenceOfElementLocated(By.id("myDynamicElement")));
WebDriver Explicit Waits
Explicit Waits

When to use: If element takes a long time to load. Also, used to check property of an element (presence, clickability. etc).

FluentWait:
For each FluentWait instance, you can specify:

  1. Frequency with which FluentWait has to check the conditions defined.
  2. Ignore specific types of exception waiting such as NoSuchElementExceptions while searching for an element on the page.
  3. Maximum amount of time to wait for a condition

When to use FluentWait: When you try to test the presence of an element that may appear after every x seconds/minutes (Just an example, this is my guess of where such a thing can be used).

// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
    .withTimeout(30, SECONDS)
    .pollingEvery(5, SECONDS)
    .ignoring(NoSuchElementException.class);

WebElement foo = wait.until(new Function<WebDriver, WebElement>() 
{
  public WebElement apply(WebDriver driver) {
  return driver.findElement(By.id("foo"));
}
});

Difference Between Implicit, Explicit and Fluent Wait
Implicit Wait:
1.      During Implicit wait if the Web Driver cannot find it immediately because of its availability,
2.      The WebDriver will wait for mentioned time and it will not try to find the element again during the specified time period.
3.      Once the specified time is over, it will try to search the element once again the last time before throwing exception.
4.      The default setting is zero.
5.      Once we set a time, the Web Driver waits for the period of the WebDriver object instance.
Explicit Wait:
·         Suppose there is a scenario, when a particular element takes more than a minute to load.
·         In that case we would definitely not like to set a huge time to implicit wait, as if we do this, Browser will go to wait for the same time for every element.
In order to avoid such situation,
1.      Introduce a separate time on the required element only.
2.      By following this browser implicit wait time would be short for every element and it would be large for specific element.
Fluent Wait:
Scenario:  Suppose there is an element which takes some time to appear may be in just 1 second & some time it takes minutes to appear.
In that case it is better to use fluent wait,  1 .As this will try to find element again and again until it find it or until the final timer runs out.
Solutions: We always get confuse when it comes to using Wait commands, to better understand it we need to remember that there is a difference between several scenarios:
An element not being present at all in the DOM.
An element being present in the DOM but not visible.
An element being present in the DOM but not enabled. (i.e. clickable)
There are pages which get displayed with the JavaScript, the elements are already present in the browser DOM, but are not visible. The implicit wait only waits for an element to appear in the DOM, so it returns immediately, but when you try to interact with the element you get aNoSuchElementException. You could test this hypothesis by writing a helper method that explicit wait for an element to be visible or clickable.
public WebElement getWhenVisible(By locator, int timeout) {
WebElement element = null;
WebDriverWait wait = new WebDriverWait(driver, timeout);
element = wait.until(ExpectedConditions.visibilityOfElementLocated(locator));
return element;
}
public void clickWhenReady(By locator, int timeout) { WebElement element = null; WebDriverWait wait = new WebDriverWait(driver, timeout); element = wait.until(ExpectedConditions.elementToBeClickable(locator)); element.click(); }

Common Issues While Creating Performance Scripts

By Published:

Common Issues While Creating Performance Scripts

When you start load testing a web site (especially if this is the first load test in your life) you may see a lot of errors in the report. Possibly you will even have to stop the test before it completes, because at some point in time it becomes clear that something goes wrong. If the problem is not so obvious, it is still recommended to check the report for the errors related to each virtual user profile (i.e. to each different type of virtual users) before looking at any performance data.
Issue 1:  
Most probably the errors appear because you have not parameterized the HTTP requests in your profile. Note that initially all requests are recorded as is. If user use a recorded profile without any modifications. Performance tool will simply repeat all the same requests with the same values of all parameters. However some values should be unique for each session.
You can check the “Logs” folder for errors and find the first request that produced an error. The goal is to find dynamic session-specific values inside that request. You can do this by comparing different sessions. Usually such session-specific values are contained inside the request parameters, but they can also be passed inside the main part of the URL. When you find such value you also need to find a place (the body of one of the previous responses) from which you can extract it. You can use the “Edit | Find and Replace…” feature for that.
Issue 2:  
Let’s imagine that you have done good work on the parameterization and now when you verify your profile, it does not produce any errors, and each new session completes as expected. Now you try to execute a small test with several concurrent users, and you see that it fails for all users except the first one. The problem may be that your web site does not allow several concurrent sessions with the same user credentials. This means that you need to use a different user name and password for each virtual user.
After you make all necessary modifications to the profile you can enable the full logging to check that all user names and passwords are passed correctly. By default logging is enabled only for verification, but if you run test with just few users, you can switch to full logging without any significant performance overhead.
Issue 3:  
Even in case the user credentials are passed correctly, you may still see that almost all sessions complete with errors. This may be because some session-specific values still require parameterization, because they depend on the user account. Basically this is the same problem as the first one. I only wanted to note that you may face it again when you switch from one user to many users test.
For example, it may be that each user of your system has a special ID which is passed in some parameter of each request. If you use a different user name, you also need to change that ID. As usual the right value can be extracted from some response and assigned to a variable.
Issue 4:  
Your web application may require authentication. This is not exactly the same as entering the user name and password in some form on a web page and clicking the “Sign In” button. When you use a browser to access a site requiring authentication, it displays a separate dialog asking for credentials. Since this is done in a secure manner, it is not possible to record the credentials automatically
Issue 5:  
There is one very important rule that you should apply when creating a new virtual user profile: always start recording by entering the landing page URL into the address bar and always delete cookies and browser cache before recording. This is not just a good advice; this is the only correct practice.
If you start recording from the middle of a user session, your load testing tool will not be able to reproduce that session correctly. Even if you click a link on a page already open in your browser instead of manually entering the address, this can produce incorrect recording.
The same will happen if you do not delete cookies. Your web site may behave differently for new users and for returning ones. It may use cookies to restore the previous session. If you record such restored session, you will not be able to emulate a new one.
Finally, if you do not delete browser cache, all requests to cached elements will be skipped on recording. This is the least important problem, because any session-specific requests will be sent in any case, but to create a realistic load you will probably want to load page elements as well.
Important Note:
If you see errors in the report, you should definitely research the problem as described above. However even if you do not see any red lines in the log, this does not mean that everything works correctly. Your web site can produce errors in a “user friendly” manner or just redirect to a different page if it cannot provide valid content for a request containing incorrect parameters. This means that you need to read the actual response to see if it is correct. Again, you can use the “Compare with recorded” function and check all responses step by step.

How to use ADB (Android Debug Bridge) over WiFi | Android automation

By Published:
Whenever we work with Android mobile app automation we have to connect the device using USB cable. We can connect the device over Wi-Fi. To get rid of from the USB there is a super simple way! All you need is a USB cable (for the initial setup) and have both devices in the same network. This will work for non-rooted devices also.

Precondition: 
  • Your system and device must be in the same network.
  • Android mobile must have developer option set to true.
  • ADB (Android debug bridge) must be configure
  • Android SDK installed.
Step 1. Attach mobile via USB

Step 2. Open then command terminal type adb devices and press enter

It will confirm that your device is connected and able to recognize by android sdk.




Step 3:   type:
adb tcpip 5555
Step 4:To find the mobile ip type:
adb shell ip -f inet addr show wlan0
Step 5: The ip address will be shown in second line like this:
inet 192.168.1.233/24 brd 192.168.1.255 scope global wlan0
where 192.168.1.233 is the ip address of your mobile.
Step 6:Remove USB cable and type:
   adb connect <mobile-ip>:5555

 like:
adb connect <192.168.1.233>:5555 

Note: 
  1. Make sure: that you do not have Android studio running before executing the - 'restart adb in tcpip mode' command
  2. If you have IDE running then adb may have been already started and you may need to restart it in some cases: adb kill-server; adb start-server

How to know app package and activities information without having apk | android app | Appium

By Published:
How to know app package and activities information without having apk | android app | Appium

In Android app mobile automation,we need apk file of app but sometimes we have to perform action on inbuild app(pre installed) which come with device like call,sms etc.. for this we do not have apk file. Basically in android app automation we need app package information  and app activities. In case of apk it is easy to get above information with appium. But if we do not have apk and need the app package/activities information, we can use following command:

Precondition: 
1. Android mobile must have developer option set to true.
2. ADB (Android debug bridge) must be configure
3. Android SDK installed.

Step1. Open then command terminal type adb devices and press enter

It will confirm that your device is connected and able to recognize by android sdk.






Step2: Now in mobile, open the app of which you want to get app pkg info/activities. In your mobile, it should be current activated app with focus. Means current window of your mobile should be app like calling/msg/your app window. 

Step3: Now type adb shell and press enter to open the adb shell

Step4: type dumpsys window windows | grep -E 'mCurrentFocus|mFocusedApp'  and press enter







Above command will show the current activated app info of  your mobile. Now check the value of mCurrentFocus.

First highlighted text is pkg info



Second highlighted text is app activities info


Here you can see that we can use this:





 Thanks



WebDriver compare data/css between two pages

By Published:
Hi All,

In Web based project like implemented in CQ5 where we have to check same site for different country. For this we have to rollout/replicate some/all pages for different countries OR I can say downloaded/uploaded the production data in testing environment or vice versa.
After this we have to validate page static data (like text) with production site Data, page wise validation.
E.g.  One page of US site and replicate the same page for another country then verify page content or css
For this we have to check manually, we can automate the same. I assume both pages having same text content (English).
Logic to implement this:
• First we have to analyze page objects properties (what are the common page objects (elements) properties are being used) like class, id, type etc and create array of this.
• Then we have to get all elements from the base page(expected) using xpath(//*)
• For each element get all properties and value using java script and store only those element properties/value which are matching with common page objects (elements) properties stored in array.
• Create locators for those elements by generating xpath for them.
• Now same locator(xpath) should be exist in actual page
• open two driver instances driver1 for page1 , driver2 for another country page2
• Using WebDriver find element by xpath(locator) from base page and same for another page, match the text using gettext() method if  same element present in both pages
• We can use same for CSS attribute values check for two pages having same element with same type of properties(class, ID etc)

Here is the code to implement this.


public static List<String> getPageLocatorsxPath(WebDriver driverbase,String pageURL )
{
List<String> strLocatorxPath = new ArrayList<>();
/// Common attributes from base site pages
String[] attributes = { "class", "data-class", "data-class-name",
"data-tab", "id", "name", "data-countrycode" };

HashMap<String, String> mapWeblementAttributes = new HashMap<String, String>();

JavascriptExecutor js = (JavascriptExecutor) driverbase;

/// get all elements from page
List<WebElement> childElementsGSAM = driverbase.findElements(By
.xpath("//body//*"));
int counter=0;
for (WebElement webElement : childElementsGSAM) {

// check only those element which are visible and displayed
if (webElement.isDisplayed() & webElement.isEnabled()) {

mapWeblementAttributes.clear();
// get element tag name use for creating Xpath
String strTagName = webElement.getTagName();
String strAttributes = (String) js
.executeScript(
"var str = '', obj = arguments[0].attributes; for (var key in obj){if(obj.hasOwnProperty(key)){str = str + '~' + obj[key].name + '=' + obj[key].value;}}; return str;",
webElement);
// store element properties and value in map
String[] arrAttValues = strAttributes.split("~");

for (String attribute : attributes) {
for (int k = 0; k < arrAttValues.length; k++) {
String[] arrAttrValue = arrAttValues[k].split("=");
if (arrAttrValue.length == 2) {
String strAttr = arrAttValues[k].split("=")[0];
String strAttrValue = arrAttValues[k].split("=")[1];

// store only if element property match with defined properties
if (attribute.equals(strAttr)) {
mapWeblementAttributes.put(strAttr,
strAttrValue);

}
}
}
}
// create element locators only if attribute size >1 like class and id etc..

if (mapWeblementAttributes.size() > 1) {
Set<String> setUIKeys = mapWeblementAttributes.keySet();
String strLocatorStart = "//" + strTagName + "[";
String strLocator = "";
Boolean bAnd = false;
for (String key : setUIKeys) {
if (bAnd) {
strLocator = strLocator + "and@" + key + "='"
+ mapWeblementAttributes.get(key) + "'";
} else {
strLocator = strLocator + "@" + key + "='"
+ mapWeblementAttributes.get(key) + "'";
}
bAnd = true;
}
String finalxpath = strLocatorStart +strLocator + "]";
System.out.println(finalxpath);
strLocatorxPath.add(finalxpath);
counter++;
} else {
System.out.println("not able to create locator for "
+ strTagName
+ mapWeblementAttributes.values().toString());
}


///######################
//// only for class attribute if element has only one class attribute
if (mapWeblementAttributes.size() == 1) {
Set<String> setUIKeys = mapWeblementAttributes.keySet();
String strLocatorStart = "//" + strTagName + "[";
String strLocator = "";
Boolean bAnd = false;
for (String key : setUIKeys) {
if (key.equalsIgnoreCase("class"))
{
if (mapWeblementAttributes.get(key).matches(".*\\d.*"))
{
System.out.println("not able to create locator for "
+ strTagName
+ mapWeblementAttributes.values());


}else
{
if (bAnd) {
strLocator = strLocator + "and@" + key + "='"
+ mapWeblementAttributes.get(key) + "'";
} else {
strLocator = strLocator + "@" + key + "='"
+ mapWeblementAttributes.get(key) + "'";
}
bAnd = true;
String finalxpath = strLocatorStart + strLocator + "]";
System.out.println(finalxpath);
strLocatorxPath.add(finalxpath);
}
}

}

}
///#####################
}
}
        System.out.println("Total xpath locator created from base page " + strLocatorxPath.size());
return strLocatorxPath;
}

------------------------------------------------------#############---------------------

WebDriver driverbase = new FirefoxDriver(profile);
driverbase.manage().window().maximize();
WebDriver driverStatic = new FirefoxDriver(profile);
driverbase.manage().window().maximize();
String page1 = "http://www.google.com/";
String page2 = "http://www.google.com/";
driverbase.get(page2);
driverStatic.get(page1);

///######## Getting elements locator from base page ###################
List<String> strLocatorxPathofBasepage = getPageLocatorsxPath(driverbase, page1);
////##########################
        System.out.println("Total xpath locator created from base page " + strLocatorxPathofBasepage.size());
for (String xpathExpression : strLocatorxPathofBasepage) {
System.out.println("Checking for xpath " + xpathExpression);
        String strLocator = xpathExpression;
try {
                 boolean elementFoundinBasePage = (driverbase.findElements(By.xpath(xpathExpression))
.size() > 0);
                 boolean elementFoundinGivenPage = (driverStatic.findElements(By.xpath(xpathExpression))
.size() > 0);
               
if ((elementFoundinBasePage==true)
& (elementFoundinGivenPage==true)) {
strLocator = xpathExpression;
WebElement childElementGSAM = driverbase.findElement(By
.xpath(xpathExpression));
WebElement childElementStatic = driverStatic.findElement(By
.xpath(xpathExpression));
// call verify css method for css validation
verifyCSSAttributes(WebElement childElementGSAM,WebElement childElementStatic);

System.out.println(driverbase.findElement(
By.xpath(xpathExpression)).getText());
System.out.println(driverStatic.findElement(
By.xpath(xpathExpression)).getText());
/// call verify text method
verifyText(WebElement childElementGSAM,WebElement childElementStatic);
}
}}


##############################################


In this way we can check for multiple pages

Difference between action.build().perform() and action.perform()

By Published:

In Webdriver, handling keyboard events and mouse events (including actions such as Drag and Drop or clicking multiple elements With Control key) are done using the advanced user interactions API . It contains Actions and Action classes which are needed when performing these events. In order to perform action events, we need to use org.openqa.selenium.interactions.Actions class.

The build() method is used compile all the listed actions into a single step.
we have to use build() when we are performing sequence of operations and no need to use only if we are performing single action.

example where build() required
Actions builder = new Actions(driver);
builder.clickAndHold((WebElement)listItems.get(0)).clickAndHold((WebElement)listItems.get(3)).click().build().perform();


in the above code we are performing more than one operations so we have to use build() to compile all the actions into a single step

example where build is not required

WebElement draggable = driver.findElement(By.id("draggable")); 
WebElement droppable = driver.findElement(By.id("droppable")); 
new Actions(driver).dragAndDrop(draggable, droppable).perform();
in the above code we are performing just a single operations so no need to use build()