I have a method called test, where I have defined a Webdriver object like this:
FirefoxProfile firefoxprofile = new FirefoxProfile();
firefoxprofile.setAssumeUntrustedCertificateIssuer(false);
WebDriver driver = new FirefoxDriver(firefoxprofile);
Selenium selenium = new WebDriverBackedSelenium(driver, "https://10.17.17.212:4343");
i can use selenium commands in this function, like
selenium.click() etc.
but I cannot use them in function that I call from this function.
e.g. i call a function called set() (private int set)
inside set
i resolved it by declaring WebDriver variable as static.
in my code it looks like:
public class BaseSeleniumTest extends SeleneseTestBase {
static WebDriver driver;
#BeforeClass
public static void firefoxSetUp() throws MalformedURLException {
driver = new FirefoxDriver();
}
#Before
public void homePageRefresh() throws IOException {
driver.get(propertyKeysLoader("login.base.url"));
}
#AfterClass
public static void closeFirefox(){
driver.quit();
}
....
//blablabla}
Make selenium object outside method and declare it as static so that you could use it globally.
Related
1.Creating a page in which declaring driver as RemoteDriver.
2.Calling a function where again I’m declaring a driver as RemoteDriver.
3.Running a test where I’m declaring driver as RemoteDriver.
4.Trying to access the AppiumDriver method in my test method.
I had the similar problem and solved it using the below code.
Public class DriverManager {
private static ThreadLocal<WebDriver> webDriver = new ThreadLocal<WebDriver>();
private static AppiumDriver driver;
private static DesiredCapabilities caps = new DesiredCapabilities();
public void initDriver(String browser){
if (browser.equalsIgnoreCase("chrome")){
caps.setCapability("");
....
....
webDriver.set(driver = new AppiumDriver(new URL("<<.../hub>>"), caps));
}
}
public AppiumDriver getDriver() throws Exception {
return driver;
}
}
Im trying to pass a WebDriver object outside my main method, but it isnt being resolved to a variable.
I am trying to pass 'driver a' parameter to the method NavigateGoogle. Not a common way to use Selenium but im new and its been eating at me. Code below, Any suggestions?
package day2;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class WebDriverDemo {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
System.setProperty("webdriver.chrome.driver","C:\\Users\\Abu\\Desktop\\Web Drivers\\chromedriver.exe");
}
public boolean NavigateGoogle(driver a) {
//'Driver a' parameter cannot be resolved to a type
a.get("http://www.google.com");
return true;
}
}
I think you mean to make the method signature:
public boolean NavigateToGoogle(WebDriver a) {
a.get("http://www.google.com");
return true;
}
WebDriver is a type, but driver is not. You declared WebDriver driver earlier, so the method signature parameter should match.
Also, you are setting your chromedriver.exe path AFTER you try to initialize WebDriver, which is wrong. The statements should be flipped:
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver","C:\\Users\\Abu\\Desktop\\Web Drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
}
As I understand from your question what you looking for is to pass a driver in the method NavigateGoogle(driver a) if that is what you are looking for then the below solution hopefully helps....
public static void main(String[] args) {
System.setProperty("webdriver.chrome.driver","C:\\Users\\Abu\\Desktop\\Web Drivers\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
NavigateGoogle(driver);
}
In the above piece of code the system path is been set and an instance of WebDriver is defined as "driver" The next line of code driver is passed to the function NavigateGoogle(driver)
public boolean NavigateGoogle(WebDriver driver) {
a.get("http://www.google.com");
return true;
}
The above code is the function that is defined to pass the driver.
Further more
WebDriver driver = new ChromeDriver(); //"driver" is just a instance of WebDriver
WebDriver a = new ChromeDriver(); //"a" is just a instance of WebDriver
It's always good to follow a self explainable instance.
I have a parent web test which is called by the test class like this:
public class Webtest
{
protected static WebDriver driver;
#BeforeMethod
public static WebDriver openUrl(String URL)
{
driver = new FirefoxDriver();
driver.get(URL);
System.out.println("Driver started :"+ driver);
return driver;
}
public static WebDriver closeDriver(){
driver.quit();
System.out.println("Driver closed :"+ driver);
}
}
Now I implement the above in a test class extending it.
public class testClass extends WebTest
{
#Test
public void TC01()
{ System.out.println("Test1:" + driver);
// Do something using driver
}
#Test
public void TC02()
{
System.out.println("Test2:" + driver);
// Do something
}
}
Now the results:
Driver started :FirefoxDriver: firefox on MAC (dfe4e055-4555-0d4d-8a83-a9a802159ea7)
Test1:FirefoxDriver: firefox on MAC (dfe4e055-4555-0d4d-8a83-a9a802159ea7)
Driver closed :FirefoxDriver: firefox on MAC (dfe4e055-4555-0d4d-8a83-a9a802159ea7)
Driver started :FirefoxDriver: firefox on MAC (1370df47-483b-574c-9792-9bb5fa077364)
Test2:FirefoxDriver: firefox on MAC (1370df47-483b-574c-9792-9bb5fa077364)
[Error] resulted in an exception: The FirefoxDriver cannot be used after quit() was called.
Basically, I assume the test2 is using the previous driver. I haven't called the second driver to quit yet but am getting the error. I did put sleep in between every method and tried to but nothing worked. Any help? I am using firefox 46.
Since you defined your openUrl method as a #BeforeMethod it is being called before all other methods, so when your testClass calls TC01, it opens a new browser first. Then when you call TC02, the #BeforeMethod gets invoked again and another, new WebDriver is created. That does not explain the last line error, though. I'm not sure why it would ever execute the quit method since the closeDriver method never seems to be called.
Here is the solution to your Question:
You need to address a lot of issues in your code as follows:
In Webtest class, within closeDriver() method, you are quit the driver driver.quit() still you trying to get WebDriver in return public static WebDriver closeDriver().
So change it to public static void closeDriver()
In testClass class, you are trying to extend WebTest but your base class is Webtest.
So change it to public class testClass extends Webtest
To work with Selenium 3.4.0 along with geckodriver v 0.16.1 & latest Mozilla Firefox 53.x you need to download the latest gecko driver and mention the absolute path in your code theough System.setProperty before you initialise the driver as follows:
System.setProperty("webdriver.gecko.driver", "C:\\your_directory\\geckodriver.exe");
driver = new FirefoxDriver();
In Webtest I can see your are accepting the URL as an argument public static WebDriver openUrl(String URL) but I dont see you passing it from Webtest. Keep it simple, define the String URL within openUrl() method as follows:
String URL = "http://gmail.com";
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
driver = new FirefoxDriver();
driver.get(URL);
In closeDriver() you are quitting the driver by driver.quit(); next if you System.out.println("Driver closed :"+ driver); you won't get any realtime value of the driver instance but only null.
Finally, the entire chaos is created because you have added #BeforeMethod annotation to open the driver but haven't released it closeDriver() method using #AfterMethod annotation. Add the annotation #AfterMethod.
Here is your own working code along with some simple tweaks:
class Webtest :
public class Webtest
{
protected static WebDriver driver;
#BeforeMethod
public static WebDriver openUrl()
{
String URL = "http://gmail.com";
System.setProperty("webdriver.gecko.driver", "C:\\Utility\\BrowserDrivers\\geckodriver.exe");
driver = new FirefoxDriver();
driver.get(URL);
System.out.println("Within openUrl() - Driver started :"+ driver);
return driver;
}
#AfterMethod
public static void closeDriver()
{
driver.quit();
System.out.println("Driver closed :"+ driver);
}
}
class testClass :
public class testClass extends Webtest
{
#Test
public void TC01()
{
System.out.println("Within TC01 - Test1:" + driver);
// Do something using driver
}
#Test
public void TC02()
{
System.out.println("Within TC02 - Test2:" + driver);
// Do something
}
}
Let me know if this Answers your Question.
I started encountering problems when I use static objects reference for WebDriver and run the tests in parallel.
public static WebDriver driver;
Hence I decided to use non-static object reference for the WebDriver.
private WebDriver driver;
Now when I use POM with Page Factory, my understanding is that everytime I create a Test I will have to be creating a new Object in the test class as shown below.
/* Constructor in the Page Object class */
private WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
PageFactory.initElements(driver, this);
}
2 testcases as shown below in the same class.
private LoginPage loginPage;
#Test
public void testCase1() {
loginPage = new LoginPage(getDriver());
loginPage.sendkeys("sometext");
}
#Test
public void testCase2() {
loginPage = new LoginPage(getDriver());
loginPage.sendkeys("sometext");
}
My question here is a
Am I right in creating page object for every test cases?
Is there any way I can optimize this? Because One doubt I got is that non-static object reference may be getting overridden and causing problems in one of the methods if I run them in parallel.
Sorry if my query is naive. Any help would be appreciated.
You do not need to initialize it again. Also, initialize the pages in #BeforeTest rather than in test cases.
Here i would like to give you example of Page object model. Hope you can relate this.
My Main test:
#Before
public void SelectBrowser(){
driver = WebUtils.SelectBrowser(driver,"Chrome");
}
#Test
public void LoginToGmail() throws InterruptedException{
//WebDriver driver = new FirefoxDriver();
//MAximize the Screen
driver.manage().window().maximize();
//Go to Gmail Login Page
SignInPage SignInPage = new SignInPage();
WebUtils.GoToSignInPageForPropertyFile(driver, "URL");
//Click on Next
SignInPage.ClickToLogin(driver, By.cssSelector("input[id='next']"));
Now Supporting class:
GoToSignInPageForPropertyFile method will be in WebUtils
Whatever i write in Webutils will be used by each page object class.
For e.g.
public class WebUtils {
public static pageobject.SignInPage GoToSignInPageForPropertyFile(WebDriver driver, String URL) {
ReadFileData File = new ReadFileData();
Properties Values = File.ReadFile();
driver.get(Values.getProperty("URL"));
return PageFactory.initElements(driver, pageobject.SignInPage.class);
}
}
Now the method ClickToLogin is defined under SignInPage class as:
public class SignInPage {
public EmailViewPage ClickToLogin(WebDriver driver, By by) {
WebUtils.Click(driver, by);
return PageFactory.initElements(driver, EmailViewPage.class);
}
}
Which will further be in Webutils
public class WebUtils {
public static void Click(WebDriver driver, By by) {
WebElement Element = driver.findElement(by);
Element.click();
}
}
I'm trying to test one specific Selenium's Actions class method, which is as below.
public Actions sendKeys(java.lang.CharSequence... keysToSend)
Sends keys to the active element. This differs from calling WebElement.sendKeys(CharSequence...) on the active element.
public class Demo_1 {
private WebDriver driver;
private Actions action;
private String baseUrl;
#Before
public void setUp() throws Exception {
File file = new File("C:\\Users\\ProgramFiles\\firefox.exe");
FirefoxProfile profile = new FirefoxProfile();
FirefoxBinary binary = new FirefoxBinary(file);
driver = new FirefoxDriver(binary, profile);
action = new Actions(driver);
baseUrl = "http://www.mortgagecalculator.org";
}
#Test
public void testUntitled() throws Exception {
driver.get(baseUrl + "/");
driver.findElement(By.name("param[homevalue]")).click();
driver.findElement(By.name("param[homevalue]")).clear();
action.sendKeys("300000");
}
#After
public void tearDown() throws Exception {
//driver.quit();
}
}
I can do this alternatively, but in some cases when there is no WebElement, action.sendKeys can help to send CharSequence without any WebElement as parameter.
Can some come up with similar kind of issue, as the above code is not working :(
Cause its Actions class object so you need to tell the driver the actions you are performing.
action.sendKeys("300000").perform();
Will do the needful.