Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Java generic interface in Clojure

I'm trying to get the hang of clojure in a selenium2/webdriver project using the webdriver-clj wrapper for webdriver.

However, since the webinterface is heavily scripted, I need to have an option to wait until certain elements are created by the script, instead of on page load.

So I was trying to create a wait-for function in clojure, using the WebDriverWait class to test for an element by attribute, preferably using clojure syntax from the webdriver/by- functions.

However, the waiter class until method takes a generic Interface (com.google.common.base.Function) as a parameter, and since my Java knowledge is near nonexistant, this is proving too much for my fledgling clojure skills.

Anyone out there with clojure-java interop skills and an idea how to implement the following java code in clojure so it combines with the webdriver/by- syntax ?

Function<WebDriver, WebElement> presenceOfElementLocated(final By locator) {
return new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
};}

// ...
driver.get("http://www.google.com");
WebDriverWait wait = new WebDriverWait(driver, /*seconds=*/3);
WebElement element =
wait.until(presenceOfElementLocated(By.name("q"))

The result should make something like this possible

(defn test []
  (let [driver (webdriver/new-driver :firefox)]
    (webdriver/get driver "http://127.0.0.1/")
    (webdriver/wait-for (webdriver/by-name "button"))
    ))
like image 462
NielsK Avatar asked Oct 22 '10 17:10

NielsK


1 Answers

I don't know anything about webdriver, but the clojure ways to implement an interface are proxy and reify (and deftype and defrecord, but those are probably not relevant here). With reify, implementing that interface would look something like

(defn presence-of-element-located [locator]
   (reify Function
      (apply [this driver]
         (.findElement driver locator))))

Clojure doesn't handle generics in any way, but the type parameters of Java generics don't exist at runtime, so you should be able to pass your implementation of the Function interface to anything expecting any kind of Function.

like image 99
Jouni K. Seppänen Avatar answered Oct 19 '22 01:10

Jouni K. Seppänen