Home > database >  Is there a way to call a java method that extends a webdriver class?
Is there a way to call a java method that extends a webdriver class?

Time:02-11

I am working with the WebDriverManager java library. It provides a generic manager that can be parameterized to act as a specific manager (for Chrome, Firefox, etc.). I am using it with Selenium Webdriver and Junit 5's @Parameterized and @ValueSource annotations so that I can run my tests on multiple browsers. I created an implementation as per the WebDriverManager documentation:

 public class WebTest {

 WebDriver driver = null;


 @ParameterizedTest
 @ValueSource(classes = { ChromeDriver.class, FirefoxDriver.class })
 public void navigateToUrl(String url, Class<? extends WebDriver> webDriverClass) { //WebDriver class gets extended
 driver = WebDriverManager.getInstance(webDriverClass).create();
 driver.manage().window().maximize();
 driver.get(url);

In the class containing my Cucumber step definitions, I tried calling the navigateToUrl method, but there was a compilation error like this:

  public class WebAppStepDefinitions {
  private final WebTest webTest = new WebTest();


  @Given("^I have navigated to the web url \"([^\"]*)\"$")
  public void navigateToUrl(String url) {
  webTest.navigateToUrl(url, Class<? extends WebDriver > webDriverClass); //error on this line: `Cannot resolve symbol webDriverClass`
  }

enter image description here

How Do I correctly call the navigateToUrl located in the WebTest class?

CodePudding user response:

According to the @ValueSource documentation, you cannot use this annotation to pass instances of some class. This annotation can be used only to pass primitive values, strings, and CLASSES (not objects). You can use the classes to test if some method or some object is an instance of the parameter class. You cannot use it to pass instances to a method.

INSTEAD, what you can do is use the @MethodSource API to pass the name of the method that can provide (return) those instances for you (look for the paragraph talking about multiple arguments). For example, I think you can do something like this:

@ParameterizedTest
@MethodSource("getWebDrivers")
public void navigateToUrl(String url, List<WebDriver> drivers) {
 driver = WebDriverManager.getInstance(webDriverClass).create();
 driver.manage().window().maximize();
 driver.get(url);
}


public Stream<Arguments> getWebDriversAndUrl() {
    List<WebDrivers> drivers = new ArrayList<>();
    ... // Here you need to instantiate your drivers (skip if you have them already instantiated and set as global variables.
    drivers.add(chromeDriver);
    drivers.add(firefoxDriver);
    return return Stream.of(
        arguments("url1", drivers),
        arguments("url2", drivers);
}

UPDATE:

Your implementation has a compile error because you failed to declare the parameter for the web driver class in the step definition. The step definition has only one argument. This line

webTest.navigateToUrl(String url, Class<? extends WebDriver > webDriverClass);

needs to be

webTest.navigateToUrl(url, webDriverClass);

The problem is that you have an URL that you are passing as an argument in the step definition, but not a Class object.

If you are calling the method from inside the step definition, you don't even need to use @ValueSource. All you need is a data table and pass the parameters that way directly from the step definition:

@Given("^I have navigated to the web url$")
public void navigateToUrl(DataTable table) {
    List<list> data = table.raw();
    // iterate thru list and call driver.get(url);

}

Your test step should be something like this:

Given I have navigated to the web url
| url | chrome |
| url | firefox |

Since you cannot pass the Class instance directly because it is not a data type supported by Cucumber, and creating a custom type is more trouble than it is worth for this use case. You will use the WebDriverManager to getIntance() using the browser name instead of the driver class.

  • Related