I am running tests with WebDriver, when a test fails, the browser does not close. On a Windows machine this is a huge problem because I then have several instances of the Firefox still running in the background. Kindly advise
Here's the code :
public static WebDriver driver;
private String sTestCaseName;
#BeforeMethod
public void beforeMethod() throws Exception {
DOMConfigurator.configure("log4j.xml");
sTestCaseName = Constant.Login_Name;
Log.startTestCase(sTestCaseName);
new BaseClass(driver);
}
#Test(description = "Login", enabled = true)
public void TestLogin_Success() throws Exception {
try {
driver = new FirefoxDriver();
LoginBuilder.Execute(driver);
Log.info("Successfully Login!");
} catch (Exception e) {
Log.error(e.getMessage());
throw (e);
}
}
#Test(description = "Login_Failed", enabled = true)
public void TestLogin_Failed() throws Exception {
try {
driver = new FirefoxDriver();
LoginBuilder.Execute_Failed(driver);
Log.info("Unsuccessfully Login!");
} catch (Exception e) {
Log.error(e.getMessage());
throw (e);
}
}
#AfterMethod
public void afterMethod() {
Log.endTestCase(sTestCaseName);
driver.close();
}
Add finally block to your try catch block.
Close the WebDriver there.
Sample code snippet
try {
....
....
} catch(Exception e) {
....
....
} finally {
....
driver.close();
}
More info on Dispose, Close and Quit - Difference between webdriver.Dispose(), .Close() and .Quit()
Call driver.quit() instead of driver.close()
#AfterMethod
public void afterMethod() {
Log.endTestCase(sTestCaseName);
driver.quit();
}
Why don't you try to use #AfterClass
Related
I've posted below some sample code which I've done so far and I'm getting an Exception java.lang.NullPointerException.
Base Class:
public class TestBase {
public static WebDriver driver= null;
#BeforeSuite
public void initialize(){
System.setProperty("webdriver.chrome.driver","...chromedriver_win32\\chromedriver.exe");
WebDriver driver=new ChromeDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("abcd.com");
}
#AfterSuite
public void TearDownTest()
{
TestBase.driver.quit();
}
}
Login Page:
public class LoginPage {
WebDriver driver;
public LoginPage(WebDriver driver)
{
this.driver= driver;
}
#FindBy(how=How.XPATH, using="//*[#id='email_id']") WebElement EmailTextBox;
#FindBy(how=How.XPATH, using="//*[#id='password']")WebElement PassworTextBox;
#FindBy(how=How.XPATH, using="//*[#id='frm_login']/div[4]/input") WebElement LoginButton;
public void setemail(String strmail)
{
EmailTextBox.sendKeys(strmail);
}
public void setpwd(String strpwd)
{
try
{
PassworTextBox.sendKeys(strpwd);
}
catch (TimeoutException e)
{
System.out.println("Time out exception " + e);
}
catch (ElementNotSelectableException e) {
System.out.println("Element not selectable exception " + e);
} catch (NoSuchElementException e) {
System.out.println("No such element found " + e);
} catch (ElementNotVisibleException e) {
e.printStackTrace();
} catch (Exception e) {
System.out.println("Something Wrong " + e);
}
}
public void ClickLoginBtn()
{
LoginButton.click();
}
}
LoginTest class:
public class LoginTest extends TestBase{
#Test
public void init()
{
System.out.println("In the init method");
LoginPage lg=PageFactory.initElements(driver, LoginPage.class);
lg.setpwd("123123");
lg.setemail("abc#gmail.com");
lg.ClickLoginBtn();
}
}
I am getting the NullPointerException while setting the username and password. Could you please help me?
I am new to the POM with PageFactory so I dont have any idea How to resolve it but If anyone can help me with that it would be big help to me.
You shouldn't initialise the WebDriver instance i.e. driver twice as follows:
public static WebDriver driver= null;
and
WebDriver driver=new ChromeDriver();
Keep the global declaration as:
public static WebDriver driver= null;
And channge the line as:
driver=new ChromeDriver();
Try to add a timeout after driver.get("abcd.com"); to be sure page has finished to load, and can find WebElements defining EmailTextBox and PassworTextBox.
Or use a WebDriverWait like this
new WebDriverWait(driver, 10))
.until(ExpectedConditions.visibilityOf(By.id("someid")));
I hope you have initialized the page factory elements like so
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
In your Test class,
I would place
LoginPage lg = new LoginPage(driver);
Read more here:
https://www.seleniumeasy.com/selenium-tutorials/page-factory-pattern-in-selenium-webdriver
I have a problem accessing some of my xpaths. We use a hybrid testing framework.
public class logoutMenu {
public static void run(WebDriver driver) {
Properties prop = new Properties();
InputStream selectproductsidebarobjectrepository;
try {
selectproductsidebarobjectrepository = new FileInputStream(
"C:/thisisthepath/ObjectRepositories/SignInPageObjectRepository");
prop.load(selectproductsidebarobjectrepository);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement logoutNormal = driver.findElement(By.xpath(prop.getProperty("logoutnormal")));
Actions actions = new Actions(driver);
actions.moveToElement(logoutNormal).build().perform();
WebElement logoutHover = driver.findElement(By.xpath(prop.getProperty("logouthover")));
logoutHover.click();
WebElement logoutPushed = driver.findElement(By.xpath(prop.getProperty("logoutpushed")));
logoutPushed.click();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (selectproductsidebarobjectrepository != null) {
try {
selectproductsidebarobjectrepository.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ORIGINAL PROBLEM:
It tells me that the xpath cannot be accessed if it is null. It's null because of this line: InputStream selectproductsidebarobjectrepository = null;. If I take away the = null; part of it, I get a different error: "The local variable selectproductsidebarobjectrepository may not have been initialized" which also makes sense.
What can I make selectproductsidebarobjectrepository equal to that isn't null?
NEW ISSUE:
Cleaned up the code. Got rid of the null. Got rid of the extra bracket. Still coming up as:
java.lang.IllegalArgumentException: Cannot find elements when the XPath expression is null.
at org.openqa.selenium.By.xpath(By.java:113)
at SelectProductSidebar.logoutMenu.run(logoutMenu.java:29)
at CommonFunctions.FunctionCheck.test(FunctionCheck.java:19)
Here is the script that calls this class:
public class FunctionCheck {
#Test
public void test() throws Exception {
WebDriver driver;
String baseUrl;
driver = new FirefoxDriver();
baseUrl = "http://www.MATTDAMON.com/";
driver.get(baseUrl + "MATT/MATT/MATT/MATT");
Thread.sleep(3000);
LoginPage.enterValidCredentials.run(driver);
SelectProductSidebar.logoutMenu.run(driver);
In case I'm screwing up a lot more than I initially though (probably true), here is the text file selectproductsidebarobjectrepository:
logoutnormal=//img[contains(#src,'log_out_normal')]
logouthover=//img[contains(#src,'log_out_hover')]
logoutpushed=//img[contains(#src,'log_out_pushed')]
I'm probably doing something really stupid but I'm absolutely blind to what it is right now.
This works fine for me after removing the extra brace.
public class logoutMenu {
public static void run(WebDriver driver) {
Properties prop = new Properties();
InputStream selectproductsidebarobjectrepository;
try {
selectproductsidebarobjectrepository = new FileInputStream(
"C:/thisisthepath/ObjectRepositories/SignInPageObjectRepository");
prop.load(selectproductsidebarobjectrepository);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement logoutNormal = driver.findElement(By.xpath(prop.getProperty("log_out_normal")));
Actions actions = new Actions(driver);
actions.moveToElement(logoutNormal).build().perform();
WebElement logoutHover = driver.findElement(By.xpath(prop.getProperty("log_out_hover")));
logoutHover.click();
WebElement logoutPushed = driver.findElement(By.xpath(prop.getProperty("log_out_pushed")));
logoutPushed.click();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (selectproductsidebarobjectrepository != null) {
try {
selectproductsidebarobjectrepository.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
I have below piece of code which checks if a webpage is loaded within 1 min or not. I receive Unreachable catch block for TimeoutException. Could anybody tell me why?. Thanks
public class PageLoadedin1min {
public static void main(String[] args) {
WebDriver driver =new FirefoxDriver();
driver.manage().timeouts().pageLoadTimeout(1, TimeUnit.SECONDS) ;
try
{
driver.get("http://localhost/login.do");
System.out.println("Page Loaded in a min");
}
catch(TimeoutException e)
{
System.out.println("Page is not loaded in a min");
}
}
}
I am using Java with Webdriver, and I am having problem with taking screenshots with failed test.
My jUnit test:
....
public class TestGoogleHomePage extends Browser {
....
#Test
public void testLoadGoogle() {
//this test will fail
}
}
My Browser class:
public class Browser {
protected static WebDriver driver;
public Browser() {
driver = new FirefoxDriver();
}
.....
#Rule
public TestWatcher watchman = new TestWatcher() {
#Override
protected void failed(Throwable e, Description description) {
File scrFile = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File(
"C:\\screenshot.png"));
} catch (IOException e1) {
System.out.println("Fail to take screen shot");
}
// this won't work
// driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
#Override
protected void succeeded(Description description) {
....
}
};
#After
public void closeBrowser() {
driver.quit();
}
}
The execution of the test will result in the following error message (part of the error message):
org.openqa.selenium.remote.SessionNotFoundException: The FirefoxDriver cannot be used after quit() was called.
Looks like it is complaining about my #After method.
I have tried to change the Browser class to be:
public class Browser {
protected static WebDriver driver;
public Browser() {
driver = new FirefoxDriver();
}
.....
#Rule
public TestWatcher watchman = new TestWatcher() {
#Override
protected void failed(Throwable e, Description description) {
File scrFile = ((TakesScreenshot) driver)
.getScreenshotAs(OutputType.FILE);
try {
FileUtils.copyFile(scrFile, new File(
"C:\\screenshot.png"));
} catch (IOException e1) {
System.out.println("Fail to take screen shot");
}
driver.quit();
}
#Override
protected void succeeded(Description description) {
....
driver.quit();
}
};
}
And the above codes work fine. But I don't want to quit the driver there because there might be something else I want to clean up after each test run, and I want to close the browser in the #After method.
Is there a way I can do that?
The problem is because of the following code:
#After
public void closeBrowser() {
driver.quit();
}
The driver.quit() is attempting to close the browser after EVERY test; and it is getting executed before the call-back methods of your TestWatcher. This is preventing TestWatcher from getting a handle of the driver. Try using a more restrictive life-cycle annotation like #AfterClass or #AfterSuite.
When I run a test with Robotium, I use an assertion to verify that there is specific text on the page, but it fails. However, when I run the test without the assertion, the test passes. Why would this be?
Here is my code:
import com.jayway.android.robotium.solo.Solo;
import android.test.ActivityInstrumentationTestCase2;
import android.test.suitebuilder.annotation.Smoke;
#SuppressWarnings("unchecked")
public class ODPRobotiumTest extends ActivityInstrumentationTestCase2 {
private static final String TARGET_PACKAGE_ID = "com.gravitymobile.app.hornbill";
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.vzw.odp.LaunchActivity";
private static Class<?>launcherActivityClass;
static{
try{
launcherActivityClass = Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e){
throw new RuntimeException(e);
}
}
#SuppressWarnings({ "unchecked", "deprecation" })
public ODPRobotiumTest() throws ClassNotFoundException{
super(TARGET_PACKAGE_ID, launcherActivityClass);
}
private Solo solo;
#Override
protected void setUp() throws Exception{
solo = new Solo(getInstrumentation(), getActivity());
}
#Smoke
public void testLine1(){
try {
assertTrue(solo.searchText("Easy to Find")) ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#Smoke
public void testLine2(){
try{
solo.searchText("Hassle-Free");
}catch(Exception e){
e.printStackTrace();
}
}
#Smoke
public void testLine3(){
solo.searchText("Trust");
}
public void testLine4(){
solo.searchText("Verizon Curated Wallpaper");
}
public void testLine5(){
solo.searchText("Taco's");
}
#Override
public void tearDown() throws Exception{
try{
solo.finalize();
}catch(Throwable e){
e.printStackTrace();
}
getActivity().finish();
super.tearDown();
}
}
The test in testLine1 is the test that fails. But like I said before, when I don't use the assertTrue, and just solo.searchTest("Easy to find"), the test will pass. I don't understand.
Thanks for any help!
If you don't assert anything then your test will pass cause nothing can fail.
Obviously the text you are searching is either missing from the screen, your configuration of the test runner is wrong or you are not even using the correct mechanisms for searching.
I just found out the content that I am trying to verify is HTML. So since Robotium doesn't work with HTML, or any other web component, it won't verify the text I'm looking for.
Thank you to all who offered help!