Cannot run parallel tests with #Factory testng annotation on java - java

So I use #Factory to run one test with 5 different emails, but I get wrong number of arguments exception and I can't see the full error trace on console. I use TestNG. Here's my code:
package com.task.lab.facadetask;
public class GmailTest {
private WebDriver driver;
private static List<User> usersList;
static List<TestMessage> mess;
public GmailTest(){}
#Factory(dataProviderClass = GmailTest.class, dataProvider = "getData")
public GmailTest(WebDriver driver,List<User> usersList, List<TestMessage> mess ){
this.driver = driver;
GmailTest.usersList = usersList;
GmailTest.mess = mess;
}
#BeforeMethod
public void setUpDriver(){
driver = DriverObject.getDriver();
}
#DataProvider
public static Object[][] getData() {
File usersXml = new File("src\\\\main\\\\java\\\\com\\\\task\\\\lab\\\\facadetask\\\\testdata\\\\users.xml");
try {
usersList = JAXB.unmarshal(usersXml);
} catch (JAXBException e) {
e.printStackTrace();
}
TestMessages messages = UnMarshell.unmarshaller();
assert messages != null;
mess = messages.getTestMessages();
return new Object[][]{
{mess.get(0), usersList.get(0)},
{mess.get(1), usersList.get(1)},
{mess.get(2), usersList.get(2)},
};
}
#Test
public void testGmail(TestMessage message, User users) {
String gmailURL = "https://accounts.google.com/signin";
driver.get(gmailURL);
Login loginPage = new Login();
loginPage.login(users.getEmail(), users.getPassword());
GmailMessage gmailPage = new GmailMessage();
gmailPage.sendMessage(message.getReceiver(), message.getSubject(), message.getMessage());
gmailPage.removeMessage();
Assert.assertTrue(gmailPage.isRemoved());
}
#AfterMethod
public void quitBrowser(){
try{
driver.close();
}finally{
driver.quit();
}
}
}
My assumption is that it could be caused by changing the original non static lists of users and messages to static, but DataProvider method needs to be static. Could someone guide me on what am I doing wrong?
UPD:So, I removed #BeforeMethod and included driver in #DataProvider as Krishnan suggested but it gives me the same error, wrong number of arguments. Here's what the DataProvider starts with for now:
#DataProvider
public static Object[][] getData() {
driver = DriverObject.getDriver();
File usersXml = new File //The rest remains the same
Also, I tried to initialize driver in BeforeMethod but in this case Test doesn't see it. It looks like this:
#BeforeMethod
public void setUpDriver(){
WebDriver driver = DriverObject.getDriver();
}
Maybe someone can provide me with a valid analogue of Factory so I can run 5 parallel tests simultaniously? I am open for suggestions.

Your factory method is defined to accept 3 arguments.
#Factory(dataProviderClass = GmailTest.class, dataProvider = "getData")
public GmailTest(WebDriver driver,List<User> usersList, List<TestMessage> mess ){
this.driver = driver;
GmailTest.usersList = usersList;
GmailTest.mess = mess;
}
Your data provider is only providing 2 parameters. WebDriver is not being provided by your data provider.
You can do one of the following :
Either enhance your data provider to include the WebDriver object via a call to DriverObject.getDriver() and remove your #BeforeMethod method (or)
Alter your constructor's signature to not accept a WebDriver instance, but initialize the class's WebDriver instance via the #BeforeMethod.
That should fix your problem.
EDIT: The question has been updated. So updating my answer as well.
Looking at the updates to the question, the answer is still the same on a high level. Now including a sample as well, which explains the answer.
Mocking how the User class could look like
import java.util.ArrayList;
import java.util.List;
public class User {
private String name;
public User(String name) {
this.name = name;
}
public String getName() {
return name;
}
public static List<User> newUsers(String... names) {
List<User> users = new ArrayList<>();
for (String name : names) {
users.add(new User(name));
}
return users;
}
}
Mocking how the TestMessage class could look like
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class TestMessage {
private String text;
public TestMessage(String text) {
this.text = text;
}
public String getText() {
return text;
}
public static List<TestMessage> newMessages(int howMany) {
List<TestMessage> msgs = new ArrayList<>();
for (int i = 0; i < howMany; i++) {
msgs.add(new TestMessage(UUID.randomUUID().toString()));
}
return msgs;
}
}
Here's how the test class should look like
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;
import java.util.Collections;
import java.util.List;
public class GmailTest {
private WebDriver driver;
private List<User> users;
private List<TestMessage> testMessages;
#Factory(dataProvider = "getData")
public GmailTest(WebDriver driver, List<User> users, List<TestMessage> testMessages) {
this.driver = driver;
this.users = users;
this.testMessages = testMessages;
}
#Test
public void testMethod() {
Assert.assertNotNull(driver);
Assert.assertNotNull(users);
Assert.assertNotNull(testMessages);
}
#AfterClass
public void cleanupDrivers() {
if (driver != null) {
driver.quit();
}
}
#DataProvider(name = "getData")
public static Object[][] getData() {
List<User> users = User.newUsers("Jack", "Daniel", "John");
int size = users.size();
List<TestMessage> testMessages = TestMessage.newMessages(size);
Object[][] data = new Object[size][1];
for (int i = 0; i < size; i++) {
data[i] = new Object[]{new FirefoxDriver(), Collections.singletonList(users.get(i)),
Collections.singletonList(testMessages.get(0))};
}
return data;
}
}
Here's the execution logs
1518271888011 geckodriver INFO geckodriver 0.19.1
1518271888131 geckodriver INFO Listening on 127.0.0.1:14727
1518271888627 mozrunner::runner INFO Running command: "/Applications/Firefox.app/Contents/MacOS/firefox-bin" "-marionette" "-profile" "/var/folders/mj/81r6v7nn5lqgqgtfl18spfpw0000gn/T/rust_mozprofile.5mkpumai11hO"
1518271889362 Marionette INFO Enabled via --marionette
2018-02-10 19:41:30.336 plugin-container[53151:969522] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0xad33, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.
1518271890773 Marionette INFO Listening on port 52891
1518271890793 Marionette WARN TLS certificate errors will be ignored for this session
Feb 10, 2018 7:41:30 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
1518271890961 geckodriver INFO geckodriver 0.19.1
1518271891060 geckodriver INFO Listening on 127.0.0.1:6639
2018-02-10 19:41:31.225 plugin-container[53152:969613] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0xaa37, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.
1518271891259 mozrunner::runner INFO Running command: "/Applications/Firefox.app/Contents/MacOS/firefox-bin" "-marionette" "-profile" "/var/folders/mj/81r6v7nn5lqgqgtfl18spfpw0000gn/T/rust_mozprofile.npquNnysdwGI"
1518271891832 Marionette INFO Enabled via --marionette
2018-02-10 19:41:32.786 plugin-container[53155:969741] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0xab3f, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.
1518271893243 Marionette INFO Listening on port 53150
1518271893342 Marionette WARN TLS certificate errors will be ignored for this session
Feb 10, 2018 7:41:33 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
1518271893499 geckodriver INFO geckodriver 0.19.1
1518271893590 geckodriver INFO Listening on 127.0.0.1:48408
2018-02-10 19:41:33.681 plugin-container[53156:969822] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x7c37, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.
1518271893810 mozrunner::runner INFO Running command: "/Applications/Firefox.app/Contents/MacOS/firefox-bin" "-marionette" "-profile" "/var/folders/mj/81r6v7nn5lqgqgtfl18spfpw0000gn/T/rust_mozprofile.65SomKttNwQP"
1518271894377 Marionette INFO Enabled via --marionette
2018-02-10 19:41:35.326 plugin-container[53159:969958] *** CFMessagePort: bootstrap_register(): failed 1100 (0x44c) 'Permission denied', port = 0x1523b, name = 'com.apple.tsm.portname'
See /usr/include/servers/bootstrap_defs.h for the error codes.
1518271895785 Marionette INFO Listening on port 53451
1518271895824 Marionette WARN TLS certificate errors will be ignored for this session
Feb 10, 2018 7:41:35 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
[GFX1-]: Receive IPC close with reason=AbnormalShutdown
1518271896172 addons.xpi WARN Exception running bootstrap method shutdown on activity-stream#mozilla.org: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIObserverService.removeObserver]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: resource://activity-stream/lib/SnippetsFeed.jsm :: uninit :: line 125" data: no] Stack trace: uninit()#resource://activity-stream/lib/SnippetsFeed.jsm:125 < onAction()#resource://activity-stream/lib/SnippetsFeed.jsm:141 < _middleware/</<()#resource://activity-stream/lib/Store.jsm:51 < Store/this[method]()#resource://activity-stream/lib/Store.jsm:30 < uninit()#resource://activity-stream/lib/Store.jsm:153 < uninit()#resource://activity-stream/lib/ActivityStream.jsm:278 < uninit()#resource://gre/modules/addons/XPIProvider.jsm -> jar:file:///Applications/Firefox.app/Contents/Resources/browser/features/activity-stream#mozilla.org.xpi!/bootstrap.js:80 < shutdown()#resource://gre/modules/addons/XPIProvider.jsm -> jar:file:///Applications/Firefox.app/Contents/Resources/browser/features/activity-stream#mozilla.org.xpi!/bootstrap.js:196 < callBootstrapMethod()#resource://gre/modules/addons/XPIProvider.jsm:4406 < observe()#resource://gre/modules/addons/XPIProvider.jsm:2270 < GeckoDriver.prototype.quit()#driver.js:3381 < despatch()#server.js:560 < execute()#server.js:534 < onPacket/<()#server.js:509 < onPacket()#server.js:508 < _onJSONObjectReady/<()#transport.js:500
===============================================
Default Suite
Total tests run: 3, Failures: 0, Skips: 0
===============================================
Process finished with exit code 0

Related

Selenium test is overwritten by the second session while the parallel execution

I need some help to figure out the problem while cross-browser selenium java test execution through the Saucelabs. I'm running one test over 2 browsers selected from the Jenkins job.
While the execution one test is passed another one (the similar) is getting failure with the error: 504 Gateway Time-out. The server didn't respond in time.
So it's unable to move into the next step.
It seems like one test interrupts another. Both tests are running under their own tunnel and thread.
Aug 30, 2018 7:17:44 AM org.openqa.selenium.remote.ProtocolHandshake
createSession
INFO: Detected dialect: OSS
30-08-2018 07:17:49.235 [TestNG-PoolService-0] INFO
[com.***.tests.TestBase_Local:96] - Open a site URLDriver: RemoteWebDriver:
chrome on XP (4f5a5d685f4c44c9a5864e91cb8f11e9)
Driver: RemoteWebDriver: chrome on XP (4f5a5d685f4c44c9a5864e91cb8f11e9)
thread id:14 Timestamp :2018-08-30T07:17:49.370
30-08-2018 07:17:51.912 [TestNG-PoolService-0] INFO
[com.**.tests.TestBase_Local:35] - Select 'No thanks' on the popup
Aug 30, 2018 7:17:53 AM org.openqa.selenium.remote.ProtocolHandshake
createSession
INFO: Detected dialect: OSS
30-08-2018 07:17:58.886 [TestNG-PoolService-1] INFO
[com.**.tests.TestBase_Local:96] - Open a site URLDriver:
RemoteWebDriver: MicrosoftEdge on ANY (c6978c03531d408485588ba501ff0589)
Driver: RemoteWebDriver: MicrosoftEdge on ANY
(c6978c03531d408485588ba501ff0589)
thread id:15 Timestamp :2018-08-30T07:17:58.887
30-08-2018 07:18:03.406 [TestNG-PoolService-1] INFO
[com.**.tests.TestBase_Local:35] - Select 'No thanks' on the popup
30-08-2018 07:18:05.337 [TestNG-PoolService-1] INFO
[com.**.tests.TestBase_Local:38] - Search by input
Sharing the code:
public class Search extends RemoteTestBase {
#Test(dataProvider = "browsers")
public void SolrSearchTest(String browser, String version, String os, Method method) throws Exception {
this.createRemoteDriver(browser, version, os, method.getName());
System.out.println("Driver: " + driver.toString());
Application app = new Application(driver);
ConfigFileReader configRead = new ConfigFileReader();
WebDriverWait wait = new WebDriverWait(driver,100);
app.homePage().SelectNoThanks();
Log.info("Select 'No thanks' on the popup");
app.searchField().SearchBy(configRead.SearchInput());
Log.info("Search by input");
}
}
The extended RemoteTestBase class:
public class RemoteTestBase {
public WebDriver driver;
private static String baseUrl;
RandomDataSelect randomuser;
private PropertyLoader propertyRead;
public Logger Log = Logger.getLogger(TestBase_Local.class.getName());
private static final String SAUCE_ACCESS_KEY = System.getenv("SAUCE_ACCESS_KEY");
private static final String SAUCE_USERNAME = System.getenv("SAUCE_USERNAME");
#BeforeMethod
#DataProvider(name = "browsers", parallel = true)
public static Object[][] sauceBrowserDataProvider(Method testMethod) throws JSONException {
String browsersJSONArrayString = System.getenv("SAUCE_ONDEMAND_BROWSERS");
System.out.println(browsersJSONArrayString);
JSONArray browsersJSONArrayObj = new JSONArray(browsersJSONArrayString);
Object[][] browserObjArray = new Object[browsersJSONArrayObj.length()][3];
for (int i=0; i < browsersJSONArrayObj.length(); i++) {
JSONObject browserObj = (JSONObject)browsersJSONArrayObj.getJSONObject(i);
browserObjArray[i] = new Object[]{ browserObj.getString("browser"), browserObj.getString("browser-version"), browserObj.getString("os")};
}
return browserObjArray;
}
void createRemoteDriver(String browser, String version, String os, String methodName) throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
Class<? extends RemoteTestBase> SLclass = this.getClass();
capabilities.setCapability("browserName", browser);
if (version != null) {
capabilities.setCapability("browser-version", version);
}
capabilities.setCapability("platform", os);
capabilities.setCapability("name", SLclass.getSimpleName());
capabilities.setCapability("tunnelIdentifier", "***");
driver = (new RemoteWebDriver(new URL("http://" + SAUCE_USERNAME + ":" + SAUCE_ACCESS_KEY + "#ondemand.saucelabs.com:80/wd/hub"), capabilities));
randomuser = new RandomDataSelect();
propertyRead = new PropertyLoader();
baseUrl = propertyRead.getProperty("site.url");
getURL();
}
private void getURL () {
driver.get(baseUrl);
driver.manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
this.annotate("Visiting HDSupply page..." + driver.toString());
Log.info("Open a site URL" + "Driver: " + driver.toString());
}
private void printSessionId() {
String message = String.format("SauceOnDemandSessionID=%1$s job-name=%2$s",(((RemoteWebDriver) driver).getSessionId()).toString(), "some job name");
System.out.println(message);
}
#AfterMethod(description = "Throw the test execution results into saucelabs")
public void tearDown(ITestResult result) throws Exception {
((JavascriptExecutor) driver).executeScript("sauce:job-result=" + (result.isSuccess() ? "passed" : "failed"));
printSessionId();
driver.quit();
}
void annotate(String text) {
((JavascriptExecutor) driver).executeScript("sauce:context=" + text);
}
}
The suite.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Tests Suite" verbose="4" parallel="tests" data-provider-thread-count="2">
<test name="AllTests" parallel="methods">
<classes>
<class name="com.***.tests.Search"/>
</classes>
</test>
</suite>
Project info: java, selenium, testng, maven, saucelabs, jenkins
The problem lies in your test code. Its definitely related to race condition between your #Test methods [ you have your parallel="true" in your #DataProvider annotation and parallel="methods" ]
You need to refactor your code such that your driver object is thread safe.
Some of the ways in which you can do it is using :
ThreadLocal variants of WebDriver.
Create your webdriver instance and inject that as an attribute into the ITestResult object.
The below sample shows how to use a ThreadLocal variant to make your code thread-safe
import java.net.URL;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
public class RemoteTestBase {
public static final ThreadLocal<RemoteWebDriver> driver = new ThreadLocal<>();
private static String baseUrl;
private static final String SAUCE_ACCESS_KEY = System.getenv("SAUCE_ACCESS_KEY");
private static final String SAUCE_USERNAME = System.getenv("SAUCE_USERNAME");
void createRemoteDriver(String browser, String version, String os, String methodName)
throws Exception {
DesiredCapabilities capabilities = new DesiredCapabilities();
Class<? extends RemoteTestBase> SLclass = this.getClass();
capabilities.setCapability("browserName", browser);
if (version != null) {
capabilities.setCapability("browser-version", version);
}
capabilities.setCapability("platform", os);
capabilities.setCapability("name", SLclass.getSimpleName());
capabilities.setCapability("tunnelIdentifier", "***");
URL url = new URL(
"http://" +
SAUCE_USERNAME + ":" +
SAUCE_ACCESS_KEY + "#ondemand.saucelabs.com:80/wd/hub");
RemoteWebDriver rwd = new RemoteWebDriver(url, capabilities);
driver.set(rwd);
getURL();
}
protected static RemoteWebDriver getDriver() {
return driver.get();
}
private void getURL() {
getDriver().get(baseUrl);
getDriver().manage().timeouts().implicitlyWait(40, TimeUnit.SECONDS);
this.annotate("Visiting HDSupply page..." + driver.toString());
}
private void printSessionId() {
String message = String.format("SauceOnDemandSessionID=%1$s job-name=%2$s",
getDriver().getSessionId(), "some job name");
System.out.println(message);
}
#AfterMethod(description = "Throw the test execution results into saucelabs")
public void tearDown(ITestResult result) {
String txt = "sauce:job-result=" + (result.isSuccess() ? "passed" : "failed");
getDriver().executeScript(txt);
printSessionId();
getDriver().quit();
}
void annotate(String text) {
getDriver().executeScript("sauce:context=" + text);
}
}
All your sub-classes would try to access the RemoteWebDriver object via getDriver() method.
The caveat is that your #BeforeMethod needs to call createRemoteDriver() so that the RemoteWebDriver object gets instantiated and pushed into the ThreadLocal context which will be valid and be accessible within a #Test method.
The rule is always #BeforeMethod (driver instantiation happens) > #Test (driver gets consumed > #AfterMethod (driver cleanup should happen). This is the only combo wherein a RemoteWebDriver object is valid within a ThreadLocal context.

Discovering test with JUnit 5 doesn't execute LoggingListener (implementation of TestExecutionListeners)

I'm using JUnit Jupiter version 5.0.0 (Release version) and I'm trying to use the test discovery feature.
The documentation of Junit can be found in 7.1.1. Discovering Tests from http://junit.org/junit5/docs/5.0.0/user-guide/#launcher-api-discovery
My implementation is:
import static org.junit.platform.engine.discovery.ClassNameFilter.includeClassNamePatterns;
import static org.junit.platform.engine.discovery.DiscoverySelectors.selectPackage;
import org.junit.platform.launcher.Launcher;
import org.junit.platform.launcher.LauncherDiscoveryRequest;
import org.junit.platform.launcher.TestExecutionListener;
import org.junit.platform.launcher.TestIdentifier;
import org.junit.platform.launcher.TestPlan;
import org.junit.platform.launcher.core.LauncherDiscoveryRequestBuilder;
import org.junit.platform.launcher.core.LauncherFactory;
import org.junit.platform.launcher.listeners.LoggingListener;
public class MainPrueba {
public static void main(String[] args) throws InterruptedException {
Runnable task = () -> {
System.out.println("Runing thread INI");
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
.selectors(
selectPackage("org.package.qabootfx.test.ping")
//,selectClass(QabootfxApplicationTests.class)
)
.filters(
//includeClassNamePatterns(".*Test")
includeClassNamePatterns(".*")
)
.build();
Launcher launcher = LauncherFactory.create();
TestPlan testPlan = launcher.discover(request);
for (TestIdentifier root : testPlan.getRoots()) {
System.out.println("Root: " + root.toString());
for (TestIdentifier test : testPlan.getChildren(root)) {
System.out.println("Found test: " + test.toString());
}
}
// Register a listener of your choice
//TestExecutionListener listener = new SummaryGeneratingListener();
TestExecutionListener listener = LoggingListener.forJavaUtilLogging(); //new LoggingListener();
launcher.registerTestExecutionListeners(listener);
launcher.execute(request);
System.out.println("Runing thread END");
};
new Thread(task).start();
Thread.sleep(5000);
System.out.println("END");
}
}
Examining LoggingListener class implementation we can see that this must print to the console the results. For example:
package org.junit.platform.launcher.listeners;
#API(status = MAINTAINED, since = "1.0")
public class LoggingListener implements TestExecutionListener {
....
#Override
public void testPlanExecutionStarted(TestPlan testPlan) {
log("TestPlan Execution Started: %s", testPlan);
}
#Override
public void testPlanExecutionFinished(TestPlan testPlan) {
log("TestPlan Execution Finished: %s", testPlan);
}
...
}
and my Test class is:
public class QabootfxApplicationTest {
#Test
public void testAbout() {
System.out.println("TEST Execution.... QabootfxApplicationTests.testAbout()");
assertEquals(4, 5, "The optional assertion message is now the last parameter.");
}
}
I'm expecting see in the console something similar to:
2017-09-20 10:53:48.041 INFO 11596 --- TestPlan Execution Started: ....
2017-09-20 10:53:48.041 INFO 11596 --- TestPlan Execution Finished: ....
but I can't see nothing similar to "... TestPlan Execution Started...".
The console output is:
Runing thread INI
Root: TestIdentifier [uniqueId = '[engine:junit-jupiter]', parentId = null, displayName = 'JUnit Jupiter', legacyReportingName = 'JUnit Jupiter', source = null, tags = [], type = CONTAINER]
Found test: TestIdentifier [uniqueId = '[engine:junit-jupiter]/[class:org.package.qabootfx.test.ping.QabootfxApplicationTest]', parentId = '[engine:junit-jupiter]', displayName = 'QabootfxApplicationTest', legacyReportingName = 'org.package.qabootfx.test.ping.QabootfxApplicationTest', source = ClassSource [className = 'org.package.qabootfx.test.ping.QabootfxApplicationTest', filePosition = null], tags = [], type = CONTAINER]
TEST Executon.... QabootfxApplicationTests.testAbout()
Runing thread END
END
Could be a bug? or I'm implementing something wrong?
Why would you expect the listener created by LoggingListener.forJavaUtilLogging() to log anything at log level INFO... when the documentation explicitly states the following?
Create a LoggingListener which delegates to a java.util.logging.Logger using a log level of FINE.
If you want the LoggingListener to log messages at level INFO, you'll have to create it using the other factory method which accepts a log level like this LoggingListener.forJavaUtilLogging(Level.INFO).

IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; (Selenium)

commenting out the configuration results in this crash:
thufir#doge:~/NetBeansProjects/selenium$
thufir#doge:~/NetBeansProjects/selenium$ gradle clean fatJar;java -jar build/libs/selenium-all.jar
BUILD SUCCESSFUL in 1m 17s
4 actionable tasks: 4 executed
Jul 09, 2017 3:03:39 PM net.bounceme.dur.web.selenium.Main main
INFO: init..
Jul 09, 2017 3:03:41 PM net.bounceme.dur.web.selenium.Scraper scrape
INFO: {webdriver.gecko.driver=/usr/bin/firefox, url=http://www.google.com, url2=file:///home/thufir/wget/foo.html}
Exception in thread "main" java.lang.IllegalStateException: The path to the driver executable must be set by the webdriver.gecko.driver system property; for more information, see https://github.com/mozilla/geckodriver. The latest version can be downloaded from https://github.com/mozilla/geckodriver/releases
at com.google.common.base.Preconditions.checkState(Preconditions.java:738)
at org.openqa.selenium.remote.service.DriverService.findExecutable(DriverService.java:124)
at org.openqa.selenium.firefox.GeckoDriverService.access$100(GeckoDriverService.java:41)
at org.openqa.selenium.firefox.GeckoDriverService$Builder.findDefaultExecutable(GeckoDriverService.java:115)
at org.openqa.selenium.remote.service.DriverService$Builder.build(DriverService.java:330)
at org.openqa.selenium.firefox.FirefoxDriver.toExecutor(FirefoxDriver.java:207)
at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:108)
at org.openqa.selenium.firefox.FirefoxDriver.<init>(FirefoxDriver.java:104)
at net.bounceme.dur.web.selenium.Scraper.scrape(Scraper.java:24)
at net.bounceme.dur.web.selenium.Main.run(Main.java:20)
at net.bounceme.dur.web.selenium.Main.main(Main.java:15)
thufir#doge:~/NetBeansProjects/selenium$
thufir#doge:~/NetBeansProjects/selenium$
How or where do I integrate this?
{
"capabilities": {
"alwaysMatch": {
"moz:firefoxOptions": {
"binary": "/usr/local/firefox/bin/firefox",
"args": ["--no-remote"],
"prefs": {
"dom.ipc.processCount": 8
},
"log": {
"level": "trace"
}
}
}
}
}
I don't even know what that means.
code:
package net.bounceme.dur.web.selenium;
import java.util.Properties;
import java.util.logging.Logger;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Scraper {
private static final Logger log = Logger.getLogger(Scraper.class.getName());
public Scraper() {
}
public void scrape(Properties p) {
log.info(p.toString());
String key = "webdriver.gecko.driver";
String url = p.getProperty("url");
String value = p.getProperty(key);
// System.setProperty(key, value);
// System.setProperties(p);
WebDriver driver = new FirefoxDriver();
driver.get(url);
}
}
Preferrably the configuration would be in a properties file. What would the key/value pairs for that properties file?
You can perform the following steps:
Download the latest geckodriver from github.com/mozilla/geckodriver/releases
Check the location of firefox on your machine.
On Mac Firefox is at location: /Applications/Firefox.app/Contents/MacOS/firefox-bin
On Windows Firefox should be at the location: C:\Program Files (x86)\Mozilla Firefox\firefox.exe
Here is the code:
System.setProperty("webdriver.gecko.driver","/Users/monika/Downloads/geckodriver 2"); //the location of geckodriver on your machine
FirefoxOptions options = new FirefoxOptions();
options.setBinary("/Applications/Firefox.app/Contents/MacOS/firefox-bin"); //This is the location where you have installed Firefox on your machine
options.addArguments("--no-remote");
options.addPreference("dom.ipc.processCount",8);
FirefoxDriver driver = new FirefoxDriver(options);
driver.get("http://www.google.com");

Error starting org.neo4j.kernel.impl.factory.CommunityFacadeFactory

I have a simple java program trying to connect to the local instance of neo4j to create a sample database to play with but I keep getting;
Exception: Error starting org.neo4j.kernel.impl.factory.CommunityFacadeFactory, /home/mleonard/mbig/neodb/testeroo
Trace:[Ljava.lang.StackTraceElement;#7ce7d377
The stack trace is useless and the error is also not overly helpful.
The server is up and running
Starting Neo4j Server console-mode...
2015-08-11 15:28:06.466-0400 INFO Setting startup timeout to 120000ms
2015-08-11 15:28:23.311-0400 INFO Successfully started database
2015-08-11 15:28:25.920-0400 INFO Starting HTTP on port 7474 (24 threads available)
2015-08-11 15:28:26.972-0400 INFO Enabling HTTPS on port 7473
2015-08-11 15:28:28.247-0400 INFO Mounting static content at /webadmin
2015-08-11 15:28:28.704-0400 INFO Mounting static content at /browser
2015-08-11 15:28:30.321-0400 ERROR The class org.neo4j.server.rest.web.CollectUserAgentFilter is not assignable to the class com.sun.jersey.spi.container.ContainerRequestFilter. This class is ignored.
2015-08-11 15:28:31.677-0400 ERROR The class org.neo4j.server.rest.web.CollectUserAgentFilter is not assignable to the class com.sun.jersey.spi.container.ContainerRequestFilter. This class is ignored.
2015-08-11 15:28:32.165-0400 ERROR The class org.neo4j.server.rest.web.CollectUserAgentFilter is not assignable to the class com.sun.jersey.spi.container.ContainerRequestFilter. This class is ignored.
2015-08-11 15:28:33.031-0400 INFO Remote interface ready and available at http://localhost:7474/
And I can see that the database is created as the files and folders for the new database are created.
import java.io.File;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
public class Main {
private static enum RelTypes implements RelationshipType
{
WORKS,
FRIENDS,
NEMISIS
}
public static void main(String[] args)
{
System.out.println("Starting ARM4J");
GraphDatabaseService db = null ;
try
{
db = new GraphDatabaseFactory().newEmbeddedDatabaseBuilder(new File("/home/mleonard/mbig/neodb/testeroo"))
.loadPropertiesFromFile("/home/mleonard/mbig/neo4j-community-2.3.0-M02/conf/neo4j.properties")
.newGraphDatabase();
/*
try( Transaction tx = db.beginTx() )
{
Node matty = db.createNode();
matty.setProperty("name", "Matthew");
matty.setProperty("age", "31");
matty.setProperty("sex", "male");
Node jay = db.createNode();
jay.setProperty("name", "Jay");;
jay.setProperty("age", "35");
jay.setProperty("sex", "male");
org.neo4j.graphdb.Relationship r = matty.createRelationshipTo(jay, RelTypes.WORKS);
r.setProperty("years", "2");
tx.success();
}
*/
}
catch(Exception x)
{
System.out.println("Exception: " + x.getMessage());
System.out.println("Trace:" + x.getStackTrace().toString());
}
finally
{
if( db != null )
{
db.shutdown();
}
}
System.out.println("Stopping ARM4J");
}
}

Java rest server : make a unit test

I try to make a unit test for a standalone rest server. If I run the rest server it work nice. But I don't know how to make the UnitTest running.
My main class :
public class Main {
private static final int DEFAULT_PORT = 8080;
private final int serverPort;
private final Server restServer;
public Main(final int serverPort) throws Exception {
this.serverPort = serverPort;
restServer = configureServer();
restServer.start();
restServer.join();
}
public void close() throws Exception {
if (restServer != null) {
restServer.stop();
}
}
private Server configureServer() {
ResourceConfig resourceConfig = new ResourceConfig();
resourceConfig.packages(Main.class.getPackage().getName());
resourceConfig.register(JacksonFeature.class);
ServletContainer servletContainer = new ServletContainer(resourceConfig);
ServletHolder sh = new ServletHolder(servletContainer);
Server server = new Server(serverPort);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(sh, "/*");
server.setHandler(context);
return server;
}
public static void main(String[] args) throws Exception {
int serverPort = DEFAULT_PORT;
if (args.length >= 1) {
try {
serverPort = Integer.parseInt(args[0]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
new Main(serverPort);
}
The resource class :
#Path("builder")
public class ReportBuilderResource {
#POST
#Path("/build")
#Consumes(MediaType.APPLICATION_JSON)
#Produces({MediaType.TEXT_PLAIN})
public String makeReport(final ReportDescription reportDescription) {
return reportDescription.getName();
}
}
My Unit test class :
public class ReportBuilderResourceTest extends JerseyTest {
#Override
public AppDescriptor configure() {
return new WebAppDescriptor.Builder()
.initParam(WebComponent.RESOURCE_CONFIG_CLASS, ClassNamesResourceConfig.class.getName())
.initParam(ClassNamesResourceConfig.PROPERTY_CLASSNAMES, ReportBuilderResource.class.getName())
.build();
}
#Test
public void testBuildReport() throws Exception {
System.out.println("Test Build Report");
ReportDescription reportDescription = new ReportDescription();
JSONObject jsonObject = new JSONObject(reportDescription);
resource().path("builder/").post(jsonObject.toString());
}
And the output log :
juil. 31, 2015 9:48:53 AM com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer <init>
INFO: Creating low level InMemory test container configured at the base URI http://localhost:9998/
Running com.fdilogbox.report.serveur.ReportBuilderResourceTest
juil. 31, 2015 9:48:53 AM com.sun.jersey.test.framework.spi.container.inmemory.InMemoryTestContainerFactory$InMemoryTestContainer start
INFO: Starting low level InMemory test container
juil. 31, 2015 9:48:53 AM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.19 02/11/2015 03:25 AM'
Test Build Report
juil. 31, 2015 9:48:54 AM com.sun.jersey.api.container.filter.LoggingFilter filter
INFO: 1 * Server in-bound request
1 > POST http://localhost:9998/builder/
1 > Content-Type: text/plain
1 >
{"name":null,"report":null}
juil. 31, 2015 9:48:54 AM com.sun.jersey.api.container.filter.LoggingFilter$Adapter finish
INFO: 1 * Server out-bound response
1 < 405
1 < Allow: OPTIONS
1 <
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.497 sec <<< FAILURE! - in com.fdilogbox.report.serveur.ReportBuilderResourceTest
testBuildReport(com.fdilogbox.report.serveur.ReportBuilderResourceTest) Time elapsed: 0.496 sec <<< ERROR!
com.sun.jersey.api.client.UniformInterfaceException: Client response status: 405
at com.sun.jersey.api.client.WebResource.voidHandle(WebResource.java:709)
at com.sun.jersey.api.client.WebResource.post(WebResource.java:238)
at com.fdilogbox.report.serveur.ReportBuilderResourceTest.testBuildReport(ReportBuilderResourceTest.java:47)
I think the server is not "running" for the test. How can'I do this?
Your resource listens to "/builder", but the only method inside listens to "/builder/build". Since there is no method listening to #post and "/builder" you get a Http 405 - Method not allowed.
You can either remove #Path("/build") from the "makeReport" method, or change resource().path("builder/build")... in your test.
Btw:
You only need to add one of these contatiner adapters and this snippet to run a unit tests with Jersey 2:
public class ReportBuilderResourceTest extends JerseyTest {
#Override
protected Application configure() {
return new ResourceConfig(ReportBuilderResource.class);
}
...
}

Categories

Resources