'safardriver closes automatically before driver.close() is called in @Aftermethod

I'm running below test scripts in safari browser version 5.1.7 on windows 7.

After running @test method I'm calling driver.quit() in @aftermethod. But safari browser is closing before it reaches @aftermethod and throws java.lang.NullPointerException error. Due to this new safari browser instance is not opening after browser is closed. How to resolve this issue?how to override the safari shutdown? Below is the execution log

  public class Test{
            WebDriver driver;
        @BeforeMethod
        public void init()
        {
            driver = invokeSafariDriver();
        }

    public static WebDriver invokeSafariDriver() throws InterruptedException
        {
            //logger.log(LogStatus.INFO, "Launching Chrome driver");
            System.out.println("Launching Safari driver");

            System.setProperty("webdriver.safari.noinstall", "true");
            WebDriver driver = new SafariDriver();
            driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
            driver.manage().window().maximize();
            Thread.sleep(2000);
            return driver;
        }

        @Test
        public void launch
        {
            driver.get("www.google.com");
        }


      @AfterMethod(alwaysRun=true)
        public void closeBrowser()
        {
            try{
                System.out.println("Closing the browser");
                logger.log(LogStatus.INFO, "Closing the Browser");
                driver.quit();
            }
            catch(Exception e){
                driver.close();

            }

        }

Dec 01, 2016 4:54:45 PM org.openqa.selenium.safari.SafariDriverServer start
INFO: Server started on port 7469
Dec 01, 2016 4:54:45 PM org.openqa.selenium.safari.SafariDriverCommandExecutor start
INFO: Launching Safari
Dec 01, 2016 4:54:45 PM org.openqa.selenium.safari.SafariDriverCommandExecutor start
INFO: Waiting for SafariDriver to connect
Dec 01, 2016 4:54:48 PM org.openqa.selenium.safari.SafariDriverChannelHandler$1 operationComplete
INFO: Connection opened
Dec 01, 2016 4:54:48 PM org.openqa.selenium.safari.SafariDriverCommandExecutor start
INFO: Driver connected in 3408 ms
Dec 01, 2016 4:54:48 PM org.openqa.selenium.safari.SafariDriverCommandExecutor stop
INFO: Shutting down
Dec 01, 2016 4:54:48 PM org.openqa.selenium.safari.SafariDriverCommandExecutor stop
INFO: Closing connection
Dec 01, 2016 4:54:49 PM org.openqa.selenium.safari.SafariDriverCommandExecutor stop
INFO: Stopping Safari
Dec 01, 2016 4:54:49 PM org.openqa.selenium.os.UnixProcess$SeleniumWatchDog destroyHarder
INFO: Command failed to close cleanly. Destroying forcefully (v2). org.openqa.selenium.os.UnixProcess$SeleniumWatchDog@c540f5a
Dec 01, 2016 4:54:49 PM org.openqa.selenium.safari.SafariDriverCommandExecutor stop
INFO: Stopping server
Dec 01, 2016 4:54:49 PM org.openqa.selenium.safari.SafariDriverServer stop
INFO: Stopping server
Dec 01, 2016 4:54:49 PM org.openqa.selenium.safari.SafariDriverCommandExecutor stop
INFO: Shutdown complete
FAILED CONFIGURATION: @AfterMethod closeBroser
java.lang.NullPointerException
at com.test.betawoohoo.Example.closeBroser(Example.java:289)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:84)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)


Solution 1:[1]

You should define Webdriver outside the init() method so that it can be accessible in other methods also.

    WebDriver driver;

    @BeforeMethod
    public void init()
    {
        driver = new SafariDriver();
    }
    
    @Test
    public void launch
    {
        driver.get("www.google.com");
    }

    @AfterMethod
    public void tearDown()
    {
        driver.quit();
    }

Solution 2:[2]

You should initialize WebDriver instance first and then use it

WebDriver driver;

@BeforeMethod
public void init()
{
    driver = new SafariDriver();
}

@Test
public void launch
{
    driver.get("www.google.com");
}

@AfterMethod
public void tearDown()
{
    driver.quit();
}

Solution 3:[3]

Try this,

public class Test{
        public WebDriver driver;

        @BeforeMethod
        public void init()
        {
            invokeSafariDriver();
        }

    public static void invokeSafariDriver() throws InterruptedException
        {
            //logger.log(LogStatus.INFO, "Launching Chrome driver");
            System.out.println("Launching Safari driver");

            System.setProperty("webdriver.safari.noinstall", "true");
            driver = new SafariDriver();
            driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
            driver.manage().window().maximize();
            Thread.sleep(2000);
            //return driver;
        }

        @Test
        public void launch()
        {
            driver.get("www.google.com");
        }


      @AfterMethod(alwaysRun=true)
        public void closeBrowser()
        {
            try{
                System.out.println("Closing the browser");
                logger.log(LogStatus.INFO, "Closing the Browser");
                driver.quit();
            }
            catch(Exception e){
                driver.close();

            }

        }

Solution 4:[4]

You can only change driver name inside your fun invokeSafariDriver() , so as following :

  public class Test{
            WebDriver driver;
        @BeforeMethod
        public void init()
        {
            driver = invokeSafariDriver();
        }

    public static WebDriver invokeSafariDriver() throws InterruptedException
        {
            //logger.log(LogStatus.INFO, "Launching Chrome driver");
            System.out.println("Launching Safari driver");

            System.setProperty("webdriver.safari.noinstall", "true");
            WebDriver driver1 = new SafariDriver();
            driver1.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
            driver1.manage().window().maximize();
            Thread.sleep(2000);
            return driver1;
        }

        @Test
        public void launch
        {
            driver.get("www.google.com");
        }


      @AfterMethod(alwaysRun=true)
        public void closeBrowser()
        {
            try{
                System.out.println("Closing the browser");
                logger.log(LogStatus.INFO, "Closing the Browser");
                driver.quit();
            }
            catch(Exception e){
                driver.close();
   }   }

This to keep you code structure as it , but I recommend to use pom (Page object mode) as a Pattern/Structure with following link:

https://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 JGFMK
Solution 2
Solution 3 Girish Bellamkonda
Solution 4 Software Tester at ExpandCart