1

I have a question about passing a parameter to the gradle build script. First of all I have a selenium test class:

public class TestHH extends HHTest{

    @Parameters({ "platform", "browser", "version"})
    @BeforeTest(alwaysRun = true)
    public void setup(String platform, String browser, String url, String version) throws MalformedURLException {
        DesiredCapabilities caps = new DesiredCapabilities();
        caps.setPlatform(org.openqa.selenium.Platform.WIN10);
        System.setProperty("java.net.preferIPv4stack", "true");
        caps.setCapability("SeleniumTests", "redhat5 && amd64");

        assertEquals(System.getProperty(url), url);

        if (browser.equalsIgnoreCase("firefox")) {
            System.out.println("Executing on Firefox");
            String Hub = "http://localhost:4444/wd/hub";

            caps = DesiredCapabilities.firefox();
            caps.setBrowserName("firefox");

            System.setProperty("webdriver.gecko.driver", "/opt/geckodriver.exe");

            driver = new RemoteWebDriver(new URL(Hub), caps);

            driver.navigate().to(url);
            driver.manage().window().maximize();

        } else if (browser.equalsIgnoreCase("chrome")) {
            System.out.println("Executing on Chrome");
            String Hub = "http://localhost:4444/wd/hub";

            caps = DesiredCapabilities.chrome();
            caps.setBrowserName("chrome");
            ChromeOptions options = new ChromeOptions();
            System.setProperty("webdriver.chrome.driver", "/opt/chromedriver.exe");
            caps.setCapability(ChromeOptions.CAPABILITY, options);

            options.addArguments("--start-maximized");
            driver = new RemoteWebDriver(new URL(Hub), caps);
            driver.navigate().to(url);
        } else {
            throw new IllegalArgumentException("The Browser Type is undefined");
        }
    }

This is my build.gradle script:

apply plugin: 'java'
apply plugin: 'eclipse'


jar {
    version  '1.0'
    baseName 'SeleniumStarter'
    extension '.jar'
}

sourceCompatibility = 1.8
targetCompatibility = 1.8


description = ""

repositories {

    mavenCentral()
    mavenLocal() 
}

ext.seleniumVersion = '3.7.1'

dependencies {
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version:seleniumVersion
    compile group: 'org.seleniumhq.selenium', name: 'selenium-server', version:seleniumVersion
    compile group: 'org.seleniumhq.selenium', name: 'selenium-edge-driver', version:seleniumVersion
    compile group: 'org.seleniumhq.selenium', name: 'selenium-firefox-driver', version:seleniumVersion
    compile group: 'org.seleniumhq.selenium', name: 'selenium-chrome-driver', version:seleniumVersion
    compile group: 'org.seleniumhq.selenium', name: 'selenium-api', version:seleniumVersion
    compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version:seleniumVersion

    compile group: 'org.uncommons', name: 'reportng', version:'1.1.4'
    testCompile group: 'junit', name: 'junit', version:'4.12'
    testCompile group: 'org.testng', name: 'testng', version:'6.11'
}

test {

    systemProperties(System.getProperties())
     println 'test'
     println System.properties['url'] // print for testing purposes 

     systemProperty 'url', System.getProperty('url')
     useTestNG() {
       suites 'src/test/resources/TestHH.xml'

     }

 }

eclipse {
  classpath {
  containers 'org.springsource.ide.eclipse.gradle.classpathcontainer'}
}

// A custom task to show report on tests that have run
task viewResults(dependsOn: ['test'] , type:Exec) {
        workingDir './build/reports/tests'      
        commandLine 'cmd', '/c', 'start index.html' 
}

task wrapper(type: Wrapper) {
    gradleVersion = '2.10' //we want gradle 2.10 to run this project
}

task logInfo (dependsOn: test){
    logging.captureStandardOutput LogLevel.INFO
    doLast {

        println 'test'
        println System.properties['url']
        println 'url'



    }

}

The parameter which I'm trying to pass by using gradle command is an url. I'm passing other parameters like platform, browser, version by using the testng xml file.

I start the following command to pass the required parameter but it doesn't work.

  gradle test -Durl="http://live-test1.hamburg.de"

It launches Firefox and Chrome without any url.

I'm getting this output with an exception after I've started the above command :

FAILURE: Build failed with an exception.
java.lang.AssertionError
undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
Jaw. M.
  • 139
  • 2
  • 15
  • I am not able to recreate the problem. Please take a look at [this](https://gist.github.com/krmahadevan/76527d3cc073f38c6dc218e4b8c9c4ae) gist post that I created, which shares all the information from my side along with the console output. Can you please share the complete stacktrace (or) perhaps create a simple standalone project, upload it to github, update your question and share its link ? – Krishnan Mahadevan Jan 21 '18 at 03:07

2 Answers2

1

The error you are seeing says it all :

java.lang.AssertionError

You have tried to invoke System.getProperty(url) in the line :

assertEquals(System.getProperty(url), url);

If you look at the Java Docs of System Properties the Properties object supports the following system properties :

  • "file.separator"
  • "java.class.path"
  • "java.home"
  • "java.vendor"
  • "java.vendor.url"
  • "java.version"
  • "line.separator"
  • "os.arch"
  • "os.name"
  • "os.version"
  • "path.separator"
  • "user.dir"
  • "user.home"
  • ""user.name""

So clearly, System.getProperty(url) is not a valid expression which returns unexpected results (possibly a NULL or a NullPointerException) which is not a valid type of argument for assertEquals. Hence, assertEquals fails and you see a java.lang.AssertionError.

undetected Selenium
  • 183,867
  • 41
  • 278
  • 352
  • Thanks for your answer. Could you give me an advice how to pass the String url instead of using _System.getProperty(url)_ ? – Jaw. M. Jan 20 '18 at 13:34
  • Either you can have a stored `url` as a `String` and you can always use the `WebDriver` instance as **driver.getCurrentUrl();** to retrieve the current url. – undetected Selenium Jan 20 '18 at 13:43
  • @DebanjanB - Not sure why you state that `System.getProperty()` is not a valid expression, when the OP is basically trying to pass a valid URL via a JVM argument from the command prompt and then read it in the source code via the `System.getProperty()` call. – Krishnan Mahadevan Jan 21 '18 at 02:53
  • @Jaw.M.- I think there's something wrong with your TestNG suite xml. The assertion failure seems to indicate that the URL that you passed via the command line doesn't seem to match with what you passed via parameters from your suite xml. I am also seeing that you perhaps haven't shared the proper code, because your `@Parameters` annotation on `@BeforeTest` method has just 3 parameters being mentioned, but your method accepts 4 parameters and none of the parameters have been marked with `@Optional` annotation. So TestNG should ideally speaking not even execute your `@BeforeTest` method – Krishnan Mahadevan Jan 21 '18 at 03:11
  • Thanks @KrishnanMahadevan I have referred the JavaDocs with the link being embedded within the keywords and **System.getProperty(url)** doesn't seem to me as a valid call. Perhaps `System.getProperty("java.vendor.url")` looks like a valid one. Let me know if I am missing something. – undetected Selenium Jan 21 '18 at 14:24
  • @DebanjanB You are correct and wrong as well. `System.getProperty(url)` would be a valid call if `url` is a constant. In its current form, it treats `url` as a variable. So it would look for the value of the variable `url` and use that value as the key to query from `System.getProperty()`. You are talking about built-in JVM properties and the user is talking about custom user-defined properties. They both are two different things. `java.vendor.url` I believe retrieves information about the vendor providing the JDK/JRE. – Krishnan Mahadevan Jan 22 '18 at 03:20
  • @DebanjanB - The user wants to pass a random url to his code. Its not a good idea to override built-in JVM arguments with values that don't make any sense for those variables. The key here was that the OP should have been using `System.getProperty("url")` and not `System.getProperty(url)` – Krishnan Mahadevan Jan 22 '18 at 03:20
1

The problem lies in your code.

The crux of the issue lies in the statement in your setup() method.

You have

assertEquals(System.getProperty(url), url);

The problem with this line is that System.getProperty() accepts a String constant as a key for which it would retrieve a value.

So ideally speaking since you are passing in the JVM value from the command line via

gradle test -Durl="http://live-test1.hamburg.de"

Notice here your JVM argument's name is "url"

Your java code should be reading the value of this JVM argument via

System.getProperty("url")

and not via

System.getProperty(url)

The former statement instructs Java to query for the value of "url" from the list of JVM arguments passed.

The latter statement instructs Java to query from the list of JVM arguments for a key, which could be anything [ Since url is a variable ].

So please change

assertEquals(System.getProperty(url), url);

to

assertEquals(System.getProperty("url"), url);

I also noticed that you have a mismatch in the number of parameters in your setup() method.

It currently reads as

@Parameters({ "platform", "browser", "version"})
@BeforeTest(alwaysRun = true)
public void setup(String platform, String browser, String url, String version) throws MalformedURLException {
...
}

So you are instructing TestNG to inject 3 parameter values from what it finds as <parameters> values from the suite xml file, but your method actually contains 4 parameters. So TestNG wouldn't know what to inject for the variable String url and thus throw an exception which would look like below

org.testng.TestNGException: 
Parameter 'url' is required by BeforeTest on method beforeTest but has not been marked @Optional or defined
Krishnan Mahadevan
  • 14,121
  • 6
  • 34
  • 66
  • Thanks for your great help. I've understood the missing steps. So I've changed to `assertEquals(System.getProperty("url"), url);` and add the missing parameter url to the TestNG Annotation: `@Parameters({ "platform", "browser", "url", "version" }) @BeforeTest(alwaysRun = true) public void setup(String platform, String browser, String url, String version)` Unfortunately I'm still getting the same output after `-Durl=http://live-test1.hamburg.de` : **java.lang.AssertionError** So I assume there is something missing on my build.gradle script as well. Do you have an idea? – Jaw. M. Jan 22 '18 at 11:04
  • @Jaw.M.- Can you show us the content of your testng suite xml file ? The value that you pass via `` is what gets injected into the `setup()` method by TestNG. You can try adding a `System.out.println()` that prints out the values of both `System.getProperty("url")` and the value of "url" to see what is the difference. – Krishnan Mahadevan Jan 22 '18 at 11:12
  • This is the required content of my xml file which I'm using for passing the parameter: `` The output of `System.out.println(System.getProperty("url"));` is http://live-test1.hamburg.de after passing parameter `-Durl=http://live-test1.hamburg.de` which is correct. Still having issue with the method`assertEquals(System.getProperty(url), url);` – Jaw. M. Jan 22 '18 at 18:49
  • Thanks @KrishnanMahadevan . I've tried your TestSample [link](https://gist.github.com/krmahadevan/76527d3cc073f38c6dc218e4b8c9c4ae) out for passing parameter and it worked for me. – Jaw. M. Jan 23 '18 at 12:43