问题
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