0

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?

Testilla
  • 602
  • 8
  • 21
  • basically is your question: "how to call a method in java"? – fantaghirocco Feb 06 '22 at 17:49
  • @fantaghirocco, that's not the question. It's not as generic as that. Please read the question properly – Testilla Feb 06 '22 at 17:58
  • 1
    @fantaghirocco you need to read the question carefully. It is obvious that you either didn't understand the question or didn't read it well. The question is related on how to use this particular annotation correctly for a particular use case. In this case, the OP was using the wrong annotation. This wasn't even closely related to calling methods in Java. – hfontanez Feb 06 '22 at 20:11
  • 1
    @hfontanez, thanks. You obviously read the question and read it well. I will try your implementation, however, the WebdriverManager documentation says the ValueSource annotation could be used the way I have used it, but clearly, I am calling the method wrongly. See the doc: https://bonigarcia.dev/webdrivermanager/#generic-manager – Testilla Feb 06 '22 at 20:44
  • @Testilla I updated my answer to explain your error. – hfontanez Feb 06 '22 at 21:29

1 Answers1

0

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.

hfontanez
  • 5,774
  • 2
  • 25
  • 37
  • as suggested, I updated the line `webTest.navigateToUrl(url, webDriverClass);` but `webDriverClass` is not compiling. It's in red. It says: `Cannot resolve symbol 'webDriverClass'`. Do you know what could be wrong there? – Testilla Feb 06 '22 at 23:53
  • I told you in the update: you're only passing a single argument thru the step definition. And you cannot pass a `.class` parameter unless you create a custom data type. You either do my first suggestion or my second which was create a data table. – hfontanez Feb 07 '22 at 00:04
  • @Testilla any progress? – hfontanez Feb 07 '22 at 14:06
  • 1
    I wasnt aware that the Class instance is not a data type supported by Cucumber. Thanks for the info. I am working on the second suggested option. So far so good – Testilla Feb 07 '22 at 18:54
  • @Testilla bookmark this for future reference https://github.com/cucumber/cucumber-expressions#parameter-types – hfontanez Feb 07 '22 at 18:58
  • @Testilla don't forget to upvote my answer if was helpful and to click the checkmark if I completely answered this question for you. ;) – hfontanez Feb 07 '22 at 22:43
  • could you please take a look at this question to see if it's something you are able to answer? Thanks. https://stackoverflow.com/questions/75167903/is-there-a-way-to-pass-api-request-body-as-a-map-variable-in-a-pojo-builder-clas – Testilla Jan 19 '23 at 06:32