Specflow- Cannot access a disposed object- How can we resolve this issue - selenium-webdriver

I am getting this error "Cannot access a disposed object" in running multiple scenarios. When both scenarios are running individually its running fine but when both are running its showing error.
I am getting driver initialized but still its showing as disposed. refer screenshots:
[enter image description here](https://i.stack.imgur.com/3BbUr.png)
I tried googling it but no help
refer below code:
public class LoginAndLadingSteps : Driver
{
private static IWebDriver driver;
[BeforeScenario]
public static void Initialize()
{
driver = Driver.WebDriver;
}
LoginPage loginPage = new LoginPage(driver);
HomePage homepage = new HomePage(driver);
[Then(#"Proper error message should be showing")]
public void ThenProperErrorMessageShouldBeShowing()
{
Assert.IsTrue(noResult.getPageTitle().Contains("No Result"));
}
[AfterScenario]
public void AfterScenario()
{
if (driver != null)
{
driver.Close();
driver.Quit();
}
}
I tried using Hooks file also but no luck

Related

#After annotation doesnt recognize driver

As the title says I have created a Browser class where I initialize my WebDriver element with the browser I need. My issue comes in the #After class I am using that I call to close the browser window.
In my actions class I initialize the Webdriver and then I call iAmUsingBrowser to pass to my Browser class which browser I need to use
actions.java class contains the following code
Webdriver driver;
public void iAmUsingBrowser(String browser) {
driver = Browser.startBrowser(browser)
}
Browser.java contains the following code
static WebDriver driver;
public static WebDriver startBrowser(String browserName) {
switch (browserName.toUpperCase()) {
case "FIREFOX" -> {
System.setProperty("webdriver.firefox.geckodriver", "src/main/java/BrowserFiles/geckodriver.exe");
driver = new FirefoxDriver();
}
case "EDGE" -> {
System.setProperty("webdriver.edge.driver", "src/main/java/BrowserFiles/msedgedriver.exe");
driver = new EdgeDriver();
}
case "SAFARI" -> {
System.setProperty("webdriver.safari.driver", "");
driver = new SafariDriver();
}
default -> {
System.setProperty("webdriver.chrome.driver", "src/main/java/BrowserFiles/chromedriver.exe");
driver = new ChromeDriver();
}
}
return driver;
}
My issue comes in the actions.java class where i want to call driver.quit() and close the browser window.
#After
public void destroy() {
driver.quit();
}
When I use the above lines I get a nullPointerException for driver, but everywhere else I can use driver without any issues. What am I doing wrong and in my #After annotated class driver is null?

Getting InstantiationException when creating factory for a page using appium

I am running a test case using pagefactory method and have created an appium driver. I'm trying to initialising a page using pagefactory class like this:
The test class:
public class VerifyValidLogin {
#Test
public void CheckValidUser() throws MalformedURLException {
AppiumDriver driver = DeviceFactory.CreateDriver();
login login_page = PageFactory.initElements(driver, login.class);
}
}
DeviceFactory class:
public class DeviceFactory {
public static AppiumDriver<MobileElement> driver;
public static AppiumDriver CreateDriver() throws MalformedURLException {
DesiredCapabilities cap = new DesiredCapabilities();
cap.setCapability( capabilityName: 'deviceName', value: 'Something');
...
URL url = new URL("http://127.0.0.1:4723/wd/hub");
driver = new AppiumDriver<MobileElement>(url,cap);
System.out.print("Application started");
return driver;
}
}
Login class has element locators:
public class login {
AppiumDriver driver;
public login(AppiumDriver ldriver)
{
this.driver=ldriver;
}
#FindBy(how = How.XPATH,using ="xpath");
MobileElement SignInButton;
}
But i'm not sure where i am doing wrong.
The error is
java.lang.RuntimeException: java.lang.InstantiationException: com.Demo.pages.login
at org.openqa.selenium.support.PageFactory.instantiatePage(PageFactory.java:134)
at org.openqa.selenium.support.PageFactory.initElements(PageFactory.java:64)
at com.Demo.Testcases.VerifyValidLogin.CheckValidUser(VerifyValidLogin.java:18)
...
I am new to the automation testing so i'm not able to properly understand the error. Let me know if you need more details.
Initialise elements in constructor
public login(AppiumDriver ldriver)
{
this.driver=ldriver;
PageFactory.initElements(ldriver,this);
}

How to handle multiple step definition file in Cucumber with Selenium

I have two step definition files and in future, there will be multiple, I am unable to execute my code for logout, its working fine for login and one step definition file, and it continuously open chrome browser.
I have created a framework using page factory, below is my code:
Login Page:
public class LoginPage {
WebDriver driver;
public LoginPage(WebDriver driver) {
//this.driver=driver;
PageFactory.initElements(driver, this);
}
#FindBy(how=How.ID,using="username")
public WebElement usernametexbox;
#FindBy(how=How.ID,using="pass")
public WebElement passwordtextbox;
#FindBy(how=How.ID,using="submit")
public WebElement signin;
#FindBy(how=How.XPATH,using="//button[#class='btn']")
public WebElement acceptbutton;
public void enter_username(String username) {
usernametexbox.clear();
usernametexbox.sendKeys(username);
usernametexbox.getText();
}
public void enter_password(String password) {
passwordtextbox.clear();
passwordtextbox.sendKeys(password);
}
public void clickToSigninbutton() {
signin.click();
}
public void clickToAcceptbutton() {
acceptbutton.click();
}
public void fill_LoginDetails() {
enter_username("abc");
enter_password("def45");
}
}
Logout Page:
public class LogoutPage {
WebDriver driver;
public LogoutPage(WebDriver driver) {
//this.driver=driver;
PageFactory.initElements(driver, this);
}
#FindBy(how=How.XPATH,using="//*[#class='icon']")
public WebElement chevron;
#FindBy(how=How.XPATH,using="//a[#class='logout-link']")
public WebElement logoutlink;
public void clickTochevron() {
chevron.click();
}
public void clickToLogoutLink() {
link.click();
}
}
Property file reader:
public class PropertiesFileReader {
public Properties getproperty() throws IOException {
FileInputStream inputstream=null;
Properties properties=new Properties();
try {
properties.load(new FileInputStream("resources/config.properties"));
}catch(Exception e) {
System.out.println("Exception " +e);
}
return properties;
}
}
Browser utility:
public class BrowserUtility {
public static WebDriver openBrowser(WebDriver driver, String browserName, String url) throws InterruptedException {
if(browserName.equals("chrome")) {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get(url);
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
return driver;
}else if(browserName.equals("IE")) {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get(url);
Thread.sleep(5000);
return driver;
}else if(browserName.equals("Firefox")) {
System.setProperty("webdriver.chrome.driver", "D:\\chromedriver\\chromedriver.exe");
driver=new ChromeDriver();
driver.manage().window().maximize();
driver.get(url);
Thread.sleep(5000);
return driver;
}
return driver;
}
}
Login Stepdef:
public class StepDefinition {
public static WebDriver driver;
// public LoginPage loginpage;
// Properties properties=new Properties();
PropertiesFileReader obj=new PropertiesFileReader();
#Given("^Open browser and enter url$")
public void open_browser_and_enter_url() throws Throwable {
Properties properties=obj.getproperty();
driver= BrowserUtility.openBrowser(driver, properties.getProperty("browser.Name"), properties.getProperty("URL"));
}
#Then("^Enter username and password$")
public void enter_username_and_password() throws Throwable {
LoginPage loginpage=new LoginPage(driver);
loginpage.fill_LoginDetails();
}
#Then("^click on sign in button$")
public void click_on_sign_in_button() throws Throwable {
new LoginPage(driver).clickToSigninbutton();
System.out.println("Sign-In successfully");
}
#Then("^Terms and conditions page open and click on Accept button$")
public void terms_and_conditions_page_open_and_click_on_Accept_button() throws Throwable {
new LoginPage(driver).clickToAcceptbutton();
}
}
Logout stepdef:
public class Logoutstepdef {
public static WebDriver driver;
PropertiesFileReader obj=new PropertiesFileReader();
#Given("^Chevron near username$")
public void chevron_near_username() throws Throwable {
Properties properties=obj.getproperty();
driver= BrowserUtility.openBrowser(driver,
properties.getProperty("browser.Name"), properties.getProperty("URL"));
LogoutPage logoutpage=new LogoutPage(driver);
logoutpage.clickTochevron();
}
#Then("^click on chevron and it should get expands$")
public void click_on_chevron_and_it_should_get_expands() throws
Throwable {
System.out.println("when user click on checvron it should
further expands a window");
}
#Then("^click on Logout link$")
public void click_on_Logout_link() throws Throwable {
new LogoutPage(driver).clickToLogoutLink();
}
}
Expected Results: Application should get automated successfully for different step definition files and only one browser should get opened at a time.
Actual Results: I have two step definition file and in future there will be multiple, I am unable to execute my code for logout, its working fine for login and one step definition file, and it continuously open chrome browser.
Your Then step is creating another instance of the page, that's why you get multiple browsers open.
Try doing this in your Logoutstepdef class:
public class Logoutstepdef {
public static WebDriver driver;
PropertiesFileReader obj=new PropertiesFileReader();
private LogoutPage logoutpage;
.....//the rest remains the same, until:
#Then("^click on Logout link$")
public void click_on_Logout_link() throws Throwable {
logoutpage.clickToLogoutLink();
}
}
There are similar questions here and here.
i would suggest to try gherkin with qaf. With QAF you don't need to manage driver or don't need to worry about page. All you need to extend WebdriverTestPage to your page class and you are done. You also can have steps in Page class itself. For example, with qaf your logout page may look like below:
public class LogoutPage extends WebDriverBaseTestPage<WebDriverTestPage>{
#FindBy(locator="xpath=//*[#class='icon']")
public WebElement chevron;
#FindBy(locator="xpath=//a[#class='logout-link']")
public WebElement logoutlink;
public void clickTochevron() {
chevron.click();
}
//#Then("^click on Logout link$") //you can use cucumber or qaf step annotation
#QAFTestStep(description="click on Logout link")
public void clickToLogoutLink() {
link.click();
}
}
Browser management (opening/closing browser) is taken care by QAF so depending on your configuration (sequential/parallel) qaf will provide thread safe drive sessions.
Furthermore, with locator repository you can eliminate one layer of page class. There are in-built steps available you can directly use. For example:
logoutpage.propeties
chevron.icon.loc=xpath=//*[#class='icon']
logout.link.loc=xpath=//a[#class='logout-link']
in your BDD you can directly use in-built steps as below:
Scenario: name of scenario
Given ...
When ...
Then verify 'chevron.icon.loc' is present
And click on 'logout.link.loc'
To make your locator self descriptive, you can go one step ahead as below:
logout.link.loc=xpath={"locator":"//a[#class='logout-link']","desc":"logout button"}
The description will be used in reporting to make it more meaningful.
There are lots of other feature that are crucial for functional test automation.

FAILED CONFIGURATION: #BeforeClass beforeClass

I am a beginner to Selenium and I am now using #DataProvider in TestNG framework to pass some values in a webpage (learning purpose). Below is my code:
package Framework;
import org.testng.annotations.Test;
import org.testng.annotations.DataProvider;
import org.testng.annotations.BeforeClass;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.annotations.AfterClass;
public class DataProv {
WebDriver d;
#Test(dataProvider = "dp", priority=0)
public void signin(String uname, String pwd) throws InterruptedException {
d.findElement(By.linkText("SIGN-ON")).click();
d.findElement(By.name("userName")).sendKeys(uname);
d.findElement(By.name("password")).sendKeys(pwd);
Thread.sleep(3000);
}
#Test(dataProvider = "dp1", priority=1)
public void reg(String fname) throws InterruptedException {
d.findElement(By.linkText("REGISTER")).click();
d.findElement(By.name("firstName")).sendKeys("fname");
d.findElement(By.name("register")).click();
Thread.sleep(3000);
}
#DataProvider
public Object[][] dp() {
return new Object[][] {
new Object[] { "Rachel", "India123" },
new Object[] { "Rita", "pass123" },
};
}
#DataProvider
public Object[][] dp1() {
return new Object[][] {
new Object[] { "Rachel"},
new Object[] { "Rita"},
};
}
#BeforeClass
public void beforeClass() {
d.manage().window().maximize();
d = new FirefoxDriver();
d.get("http://newtours.demoaut.com/");
}
#AfterClass
public void afterClass() {
d.close();
}
}
No, I am getting the following error
FAILED CONFIGURATION: #BeforeClass beforeClass
java.lang.NullPointerException
Can somebody help me in resolving this issue.
Thanks in advance
What is Null Pointer Exception?
This issue is coming because you are trying to maximise the browser without it being initialized.
You just have to reverse the order of launching the browser and then maximising it in your #BeforeClass method.
So when you say WebDriver d, reference d is NULL, so when you are trying to call the method manage() on d you basically are trying to call this method using null object i.e. null.manage() thats why Null Pointer Exception so you first have to intantiate it using d = new FirefoxDriver();
d = new FirefoxDriver();
d.manage().window().maximize();
Check your browser invoking method. I think your driver (d) is not able to find the driver under test . you need to point the driver path before invoking driver == new driver. below is the chrome driver code for your reference.
System.setProperty("webdriver.chrome.driver", System.getProperty("user.dir")+ "\\src\\test\\resources\\executables\\chromedriver.exe");
driver = new ChromeDriver();
driver.manage().window().maximize();

Camel blueprint testing and cucumber

Is it possible to combine cucumber with CamelBlueprintTestSupport? I have my runner class:
#RunWith(Cucumber.class)
#CucumberOptions(monochrome=true,
format={ "pretty", "html:target/cucumber"},
features = "C:/Users/Developer/workspace_camel/SRV002_PatronInformation/src/test/resources/cucumber/asynchronousErrorHandling.feature")
public class RunFeature_SRV002_PatronInformationTest {
}
and my blueprint test class with the scenarios:
public class SRV002_PatronInformationScenarioTest extends CamelBlueprintTestSupport {
#Override
protected String getBlueprintDescriptor() {
return "/OSGI-INF/blueprint/blueprint.xml";
}
#Given("^client communicates asynchronous via socket$")
public void client_communicates_asynchronous_via_socket() throws Throwable {
System.out.println("test");
}
#When("^client posts message$")
public void an_error_occurs_inside_the_integration() throws Throwable {
String endpoint = "netty4:tcp://localhost:5000?sync=false&textline=true";
template.sendBody(endpoint, "test");
}
#Then("^the integration should not return response to the client$")
public void the_integration_should_not_return_the_error_to_the_client() throws Throwable {
System.out.println("test");
}
}
The problem now is that, when I run this I run into nullpointerexception at template.sendbody because the context, bundle and routes haven't started. For some reason it seems adding #RunWith(Cucumber) prevents the camel routes from starting.
Anyone knows how this can be solved? Thanks
Souciance
Ok so I managed to solve this.
For reference look here:
http://camel.465427.n5.nabble.com/How-to-test-routes-when-using-another-TestRunner-td5772687.html
Thanks to Gregor Lenz for the help.
Essentially the key here is that in your Camel BlueprintTestSupport class, inside the test method, that starts the given scenario you need to add this.setUp(). See the code below:
In Cucumber
SRVXXX_FileTransferCamelRunner filetransfer = new SRVXXX_FileTransferCamelRunner();
#Given("^an input file$")
public void an_input_file() throws Throwable {
endpoint.append("file:C:/Camel/input?fileName=input.txt");
}
#When("^client puts the file in the input directory$")
public void client_puts_the_file_in_the_input_directory() throws Throwable {
filetransfer.testPutFile(fileData.toString(), endpoint.toString());
}
#Then("^the integration should move the file to the output directory$")
public void the_integration_should_move_the_file_to_the_output_directory() throws Throwable {
String outputPath = "C:/Camel/output/input.txt";
filetransfer.testFileHasMoved(outputPath);
}
In Camel
#Test
public void testPutFile(String body, String endpoint) throws Exception {
this.setUp();
template.sendBody(endpoint,body);
Thread.sleep(2000);
assertFileNotExists(endpoint);
}

Resources