Required groovy files
In the previous posting we defined the pom file that we need for our build environment.
Now we will setup some groovy files to get selenium and groovy running interactively.
ConsoleWaiter.groovy
The idea of Groovy Console I found on some other sides. Honour goes for instance too:
http://josefbetancourt.wordpress.com/tag/eclipse-2/
I copied some code of this, and put it under src/test/groovy/com/jankester/selenium/test/utils:
package com.jankester.selenium.test.utils
/**
* File: ConsoleWaiter.groovy
*/
import groovy.lang.Binding;
import groovy.ui.Console;
/**
* Provides a wrapper for the console.
*
* Based on source by John Green
* Adapted from: http://www.oehive.org/files/ConsoleWaiter.groovy
* Released under the Eclipse Public License
* http://www.eclipse.org/legal/epl-v10.html
*
* I added methods to allow use from Java.
*
* The run() method launches the console and causes this thread
* to sleep until the console's window is closed.
* Allows easy interaction with the objects alive at a given
* point in an application's execution, like in a debugger
* session.
*
* Example 1:
* new ConsoleWaiter().run()
*
*
* Example 2:
* def waiter = new ConsoleWaiter()
* waiter.console.setVariable("node", node)
* waiter.run()
*
*/
class ConsoleWaiter {
Console console
Object source
boolean done = false;
/** */
public ConsoleWaiter(Console inConsole){
this.console = inConsole
}
/** */
public ConsoleWaiter(Object source){
console =
new Console(getClass().classLoader,
new Binding())
this.source = source
console.setVariable("source", source)
}
/** */
public void setVar(String key, Object value){
console.setVariable(key, value)
}
/** */
public void setVar(String key, List values){
console.setVariable(key, values)
}
/** */
public void setVar(String key, Object[] values){
console.setVariable(key, values)
}
/** */
public void run() {
console.run()
// I'm a little surprised that this exit() can be private.
console.frame.windowClosing = this.&exit
console.frame.windowClosed = this.&exit
while (!done) {
sleep 1000
}
}
/** */
public boolean isDone(){
return done;
}
/** */
public void exit(EventObject evt = null) {
done = true
}
/** */
public Console getConsole(){
return console;
}
}
The Groovy console is supposed to get started by my main program, and blocks the thread of my main program. Only when you close the Groovy Console, the main program will continue (and exit).
You can give the groovy console a binding, and thus put it in direct contact with any context you set up before. In our case, we want to have selenium driver loaded in our context.
Selenium setup
The groovy class to start our selenium, uses following code:
package com.jankester.selenium.test
import java.io.File
import java.util.logging.Level
import org.apache.log4j.LogManager
import org.apache.log4j.Logger
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriverService
import org.openqa.selenium.firefox.FirefoxDriver
import org.openqa.selenium.firefox.FirefoxProfile
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.logging.LoggingPreferences
import org.openqa.selenium.remote.DesiredCapabilities
import org.openqa.selenium.remote.RemoteWebDriver
import org.openqa.selenium.logging.LogType
import org.openqa.selenium.remote.CapabilityType
import com.opera.core.systems.OperaDriver
class WebDriverSetup {
private static WebDriverSetup setup;
protected static Logger logger = LogManager.getLogger(WebDriverSetup.class);
protected WebDriver driver;
protected Utils utils;
protected String startUrl;
protected String username;
protected String password;
public static WebDriverSetup getInstance() {
if (setup == null) {
setup = new WebDriverSetup();
}
}
private WebDriverSetup() {
startUrl = PropertyHolder.testProperties.getProperty("StartUrl");
String browser = PropertyHolder.testProperties.getProperty("BrowserType");
username = PropertyHolder.testProperties.getProperty("LoginUserName");
password = PropertyHolder.testProperties.getProperty("LoginPassword");
if (browser.equalsIgnoreCase("*firefox")) {
driver = getFirefoxDriver();
logger.info("Started firefox driver");
}
else if (browser.equalsIgnoreCase("*iexplore")) {
driver = getIEDriver();
logger.info("Started internetexplorer driver");
}
else if (browser.equalsIgnoreCase("*googlechrome")) {
driver = getGoogleChromeDriver();
logger.info("Started Googlechrome driver");
}
else if (browser.equalsIgnoreCase("*opera")) {
driver = new OperaDriver();
logger.info("Started opera driver");
}
/* open the url */
logger.info("Connecting to starturl: " + startUrl);
driver.get(startUrl);
logger.info("Connected to starturl");
}
private WebDriver getFirefoxDriver() {
logger.info("Starting firefox driver");
DesiredCapabilities caps = DesiredCapabilities.firefox();
FirefoxProfile firefoxProfile = new FirefoxProfile();
caps.setCapability(FirefoxDriver.PROFILE, firefoxProfile);
//use setting in log4j to switch on logging of firefox driver
Logger log4jLogger = LogManager.getLogger("org.openqa");
if (log4jLogger.isInfoEnabled()) {
LoggingPreferences logs = new LoggingPreferences();
logs.enable(LogType.DRIVER, Level.INFO);
caps.setCapability(CapabilityType.LOGGING_PREFS, logs);
logger.info("Logging of firefox driver is enabled");
String userDir = System.getProperty("user.dir");
System.setProperty("webdriver.firefox.logfile", "target/firefox-console.log");
System.setProperty("webdriver.log.file","${userDir}/target/firefox-driver.log");
}
WebDriver ffDriver = new FirefoxDriver(caps);
return ffDriver;
}
private WebDriver getIEDriver() {
logger.info("Starting iexplorer driver");
DesiredCapabilities ieCapabilities = DesiredCapabilities.internetExplorer();
ieCapabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
InternetExplorerDriver ieDriver = new InternetExplorerDriver(ieCapabilities);
return ieDriver;
}
private WebDriver getGoogleChromeDriver() {
logger.info("Starting googlechrome driver");
DesiredCapabilities chromeCapabilities = DesiredCapabilities.chrome();
System.setProperty("webdriver.chrome.driver", PropertyHolder.testProperties.("ChromedriverPath"));
ChromeDriverService service = new ChromeDriverService.Builder()
.usingChromeDriverExecutable(new File(PropertyHolder.testProperties.("ChromedriverPath")))
.usingAnyFreePort().build();
logger.info("Starting chrome driver service..");
service.start();
WebDriver driverGC = new RemoteWebDriver(service.getUrl(),chromeCapabilities);
return driverGC;
}
public void close() {
logger.info("Closing driver now");
driver.close();
}
}
PropertyHolder
In our pom profiles we define several variables. They get merged into src/test/resources/test.properties. Our groovy classes need these variables, and get access to these variables over a PropertyHolder class:
package com.jankester.selenium.test
class PropertyHolder {
public static Properties testProperties = new Properties();
static {
InputStream is = PropertyHolder.class.classLoader.getResourceAsStream('test.properties');
testProperties.load(is);
//def theConfig = new ConfigSlurper().parse(is.getText());
}
}
RunSeleniumConsole
Now the final part is about starting the main program. You can do this with:
package com.jankester.selenium.test
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.By as By;
import com.jankester.selenium.test.SeleniumConstants as SeleniumConstants;
import com.jankester.selenium.test.utils.ConsoleWaiter;
import com.jankester.selenium.test.utils.Utils;
class RunSeleniumConsole {
private static Logger logger = LogManager.getLogger(RunSeleniumConsole.class);
static main(args) {
logger.info("Starting selenium session with console");
WebDriverSetup setup = WebDriverSetup.getInstance();
//set bindings
Actions actions = new Actions(setup.driver);
ConsoleWaiter waiter = new ConsoleWaiter(setup);
logger.info("Setting bindings for driver,actions,utils,logger");
waiter.setVar("driver", setup.driver);
waiter.setVar("actions",actions);
waiter.setVar("logger",logger);
waiter.setVar("startUrl",setup.startUrl);
waiter.setVar("By",By);
waiter.run();
setup.close();
}
}
With this all in plae, you should be able to run your first console with:
mvn clean test -P firefox,development,run-console
You may get a failure for log4j initialisation. But you can just add a log4j.xml to your src/main/resources folder, and that problem should be solved.
Good Luck!
Next
Remaining topics are:
- create your own utils directory
- examples
- save your groovy scripts
- replay your saved groovy scripts as junit tests
- add firebug xpi during startup
At the end of the series I will also add complete source code example.
Comments
For example, when I run using console I get an exception then I change in the project which I have added to selenium-groovy-console public project. Now I do not get the changed method invoked. class files are not reloaded.