How to use Exception Handling in Selenium Webdriver?

喜你入骨 提交于 2019-12-11 00:53:26

问题


The Scenario is as follows: When the code driver.get(url); runs, if the URL is not able to access (if server is not reachable) then it should throw an exception that server is not reachable and the code should stop executing the next line

driver.findElement(By.id("loginUsername")).sendKeys(username);

The following code I'm running in eclipse as follows:

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;


import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.Select;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class A {


    static Properties p= new Properties();
    String url=p.getProperty("url");
    private static Logger Log = Logger.getLogger(A.class.getName());

    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, InterruptedException {
        WebDriver driver = new FirefoxDriver();
        A a = new A();

        Actions actions = new Actions(driver);
        DOMConfigurator.configure("src/log4j.xml");
        String url = a.readXML("logindetails","url");
        String username = a.readXML("logindetails","username");
        String password = a.readXML("logindetails","password");

        //use username for webdriver specific actions
        Log.info("Sign in to the OneReports website");
        driver.manage().window().maximize();
        driver.get(url);// In this line after opens the browser it gets the URL from my **D://NewFile.xml* file and try to open in the browser. If the Server is not reachable then it should stop here. else it takes the username and password from the same file then it will open the page in browser.
        Thread.sleep(5000);
        Log.info("Enter Username");
        driver.findElement(By.id("loginUsername")).sendKeys(username);
        Log.info("Enter Password");
        driver.findElement(By.id("loginPassword")).sendKeys(password); 
        //submit
        Log.info("Submitting login details");
        waitforElement(driver,120 , "//*[@id='submit']");
        driver.findElement(By.id("submit")).submit();
        Thread.sleep(5000);


    }

    private static void waitforElement(WebDriver driver, int i, String string) {
        // TODO Auto-generated method stub

    }

    public String readXML(String searchelement,String tag) throws SAXException, IOException, ParserConfigurationException{
        String ele = null;
        File fXmlFile = new File("D://NewFile.xml");
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(fXmlFile);
        doc.getDocumentElement().normalize();
        NodeList nList = doc.getElementsByTagName(searchelement);
        Node nNode = nList.item(0);
        if (nNode.getNodeType() == Node.ELEMENT_NODE) {
            Element eElement = (Element) nNode;
            ele=eElement.getElementsByTagName(tag).item(0).getTextContent();
        }
        return ele;
    }

}

I tried this try block method as well. But it's not catching the exception just moving to the

driver.findElement(By.id("loginUsername")).sendKeys(username);

Error in code

line and I'm getting error as follows in the console:Unable to locate element: {"method":"id","selector":"loginUsername"} Command duration or timeout: 262 milliseconds

try
    {
        driver.get(url);
    }
    catch(Exception e)
    {
        Reporter.log("network server is slow..check internet connection");
        Log.info("Unable to open the website");
        throw new Error("network server is slow..check internet connection");
    }

回答1:


Basically, what you want to do is check the HTTP response code of the request that the browser is sending. If the code is 200, then you want the code to continue executing. If it is not then you want it to skip the code following it.

Well, selenium has not yet implemented a method for checking the response code yet. You can check this link to see details regarding this issue.

At the moment, all you can do is send a request to link by using HttpURLConnection and then check the response status code.

METHOD 1:

You can try something like this before calling driver.get() method:

public static boolean linkExists(String URLName){
    try {
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection conn = (HttpURLConnection) new URL(URLName).openConnection();
        conn.setRequestMethod("HEAD"); // Using HEAD since we wish to fetch only meta data
        return (conn.getResponseCode() == HttpURLConnection.HTTP_OK);
    } catch (Exception e) {
        return false;
    }
}

Then you can have:

if(linkExists(url)) {
    driver.get(url);
    // Continue ...
} else {
    // Do something else ...
}

EDIT:

METHOD 2: Otherwise you can try this. Create an Exception class named LinkDoesNotExistException like this:

LinkDoesNotExistException.java

public class LinkDoesNotExistException extends Exception {
    public LinkDoesNotExistException() {
        System.out.println("Link Does Not Exist!");
    }
}

And then add this function, in class A.

public static void openIfLinkExists(WebDriver driver, String URLName) throws LinkDoesNotExistException {
    try {
        HttpURLConnection.setFollowRedirects(false);
        HttpURLConnection conn = (HttpURLConnection) new URL(URLName).openConnection();
        conn.setRequestMethod("HEAD"); // Using HEAD since we wish to fetch only meta data
        if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
            driver.get(URLName);
        } else {
            throw new LinkDoesNotExistException();
        }
    } catch (Exception e) {
        throw new LinkDoesNotExistException();
    }
}

Now, instead of using driver.get(url) simply use openIfLinkExists(driver, url) within a try-catch block.

try {
    WebDriver driver = new FirefoxDriver();
    openLinkIfExist(driver, url);
    // Continues with execution if link exist
} catch(LinkDoesNotExistException e) {
    // Exceutes this block if the link does not exist
}



回答2:


Other way around is if you are just looking solution for firefox browser then you can do something like this:

if(driver.getTitle() == 'Problem loading page') {
 return false;
}

Or you can have multiple conditions for different browser.




回答3:


I like your approach and I think such optimization will improve the performance of your UI tests greatly. If I had to do it, I would add an API layer to my Selenium framework. We need to keep the SRP. Since you just need a very simple API call (only the response status), maybe a single Sender class will do the job just fine. If you decide to extend it in future a Command pattern will be a good fit.

When the code driver.get(url); runs, if the URL is not able to access (if server is not reachable) then it should throw an exception that server is not reachable and the code should stop executing the next line driver.findElement(By.id("loginUsername")).sendKeys(username);

One advice on this one - the API call (checking the Server accessibility) can be utilized as a test fixture. Either Fresh fixture or even better - Shared fixture, in case the Server returns 500 type of error, then no need for you to run the entire test suite (you can handle it in a TestSuiteContext object). By doing this, you'll save creating driver and browser instances for those just being destroyed right after.

it should throw an exception

You can create your own custom exceptions (e.g. ServerAvailabilityException) in Java. Example:

public class CustomException extends Exception{}



回答4:


Try this one:

try {
    driver.get(url);
} catch (Exception e) {
    logger.log(Level.SEVERE, "Exception Occured:", e);
}


来源:https://stackoverflow.com/questions/33338959/how-to-use-exception-handling-in-selenium-webdriver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!