Better way to add PhantomJS binary to a maven proj

2019-05-23 07:33发布

问题:

I tried using the phantomjs-maven-plugin to install phantomjs binary. I wanted to run my tests on a Tomcat7 server that is why I need to configure binary automatically.

Here is my pom.xml

<properties>
    <ghostdriver.version>1.2.0</ghostdriver.version>
    <phantomjs.version>1.9.7</phantomjs.version>
    <phantomjs-maven-plugin.version>0.7</phantomjs-maven-plugin.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>2.47.1</version>
    </dependency>

    <dependency>
        <groupId>com.github.detro</groupId>
        <artifactId>phantomjsdriver</artifactId>
        <version>${ghostdriver.version}</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.containers</groupId>
        <!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->
        <artifactId>jersey-container-servlet</artifactId>
        <version>2.21</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
        <artifactId>jersey-client</artifactId>
        <version>2.21</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-json-jackson</artifactId>
        <version>2.21</version>
    </dependency>
</dependencies>

<build>
    <sourceDirectory>src</sourceDirectory>

    <plugins>

        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.3</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

        <plugin>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <warSourceDirectory>WebContent</warSourceDirectory>
                <failOnMissingWebXml>false</failOnMissingWebXml>
            </configuration>
        </plugin>

        <plugin>
            <groupId>com.github.klieber</groupId>
            <artifactId>phantomjs-maven-plugin</artifactId>
            <version>${phantomjs-maven-plugin.version}</version>
            <executions>
                <execution>
                    <goals>
                        <goal>install</goal>
                    </goals>
                </execution>
            </executions>
            <configuration>
                <version>1.9.7</version>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.17</version>
            <configuration>
                <systemPropertyVariables>
                    <phantomjs.binary>${phantomjs.binary}</phantomjs.binary>
                </systemPropertyVariables>
            </configuration>
        </plugin>

    </plugins>

</build>

And then here is how I am initializing the webdriver ....just look the constructor and skip to the main() function in bottom

public class FindTrains {

    private WebDriver driver;
    //private WebDriverWait wait;
    JavascriptExecutor js;

    String baseURL = "http://www.indianrail.gov.in/inet_Srcdest.html";

    public FindTrains(){

        driver = new PhantomJSDriver();
        //((HtmlUnitDriver)driver).setJavascriptEnabled(true);
        //wait = new WebDriverWait(driver, 2);
        js = (JavascriptExecutor) driver;
    }

    public void getTrains(String src, String dest){
        driver.get(baseURL);    

        WebElement elemSrc =  driver.findElement(By.xpath(xpathSrc));
        setAttributeValue(elemSrc, src.toUpperCase());

        WebElement elemDest = driver.findElement(By.xpath(xpathDest));
        setAttributeValue(elemDest, dest.toUpperCase());        

        WebElement elemGetDetails = driver.findElement(By.xpath("//*[@id='formId']/table/tbody/tr/td/table/tbody/tr[2]/td[2]/table/tbody/tr/td/table/tbody/tr[16]/td[2]/input[1]"));
        elemGetDetails.click();

        System.out.println(driver.getCurrentUrl()+ " "+ driver.getTitle());

    }

    public void setAttributeValue(WebElement elem, String value){
        String scriptSetAttrValue = "arguments[0].setAttribute(arguments[1],arguments[2]);";        
        js.executeScript(scriptSetAttrValue, elem, "value", value);
    }
    public static void main(String [] args){
        System.out.println(System.getProperty("phantomjs.binary"));
        new FindTrains().getTrains("nad", "ndls");

    }
} 

So the problem is that the I am unable to verify that my whether the binary has been installed or not ....and even if it did, then why does main() prints null for system.property("phantomjs.binary")

I provided my complete pom.xml and java code... please help me see what I am doing wrong

Edit:

In the main() function I invoke FindTrains by creating an object of FindTrains and calling getTrains() on that object. but since the driver is not configured because of missing binary ....the first line of main() prints null.

回答1:

You can use WebDriverManager. Simply add the following dependency:

<dependency>
   <groupId>io.github.bonigarcia</groupId>
   <artifactId>webdrivermanager</artifactId>
    <version>3.6.0</version>
</dependency>

And then, in your code call to:

WebDriverManager.phantomjs().setup();

WebDriverManager downloads the latest version of the required PhantomJS binary to be used with Selenium WebDriver.



回答2:

The reason that the system property is not set is because you are using the maven-surefire-plugin to set it. That is the plugin that runs all your JUnit tests during the maven test phase. So any JUnit tests that surefire executes will have the system property available. However, it sounds like you are running a main() method of a class and not a JUnit at all so of course the system property isn't there.

I'm really unclear about what you are actually doing/expecting. Is this test ran as part of your maven build process? That is what the phantomjs-maven-plugin is built for, it's not built for embedding phantomjs into a Java application.