Как сделать "class listener" для WebDriver действий

Всем привет,

Использую Maven+TestNG+Java, хочу узнать какой Listener правильно использовать а главное КАК для WebDriver и TestNG.

 

Цели:

- вывод в консоль действий WebDriver

- вывод в репорт(использую org.testng.xslt) действий, т.е чтобы каждый тесткейс в репорте имел инфу что делал вебдрайвер 

Правда говоря видом "org.testng.xslt" репорта неочень доволен, но на даный момент это лучший для темплейт который я нашел...

Log прикрутить нужно,

по сути нужно перезагрузить все функции веб драйвера, которые вы используете , и в конце каждой функции выводить что то в консоль.

если нужен пример могу скинуть сорсы

Taras, если я правильно вас понимаю - вы предлагаете переписывать главные функции Click, SendKeys, etc? используя Reporter.log() - для репорта, System.out.println() - для консоли?

именно

Вебдрайвер использует java.util.logging.Logger. Отсюда и плясать.

У RemoteWebDriver есть метод setLogLevel (до версии 2.20 - статический). Самый просто метод передать туда Level.INFO и будет лог в консоль сыпать.

Хочу сделать что-то на примере такого:

[2012.03.09 18:57:04] Calling method WebDriver::find_element( xpath, //input[ @id='Password' ] )
[2012.03.09 18:57:04] Calling method WebElement::send_keys( ***** )
[2012.03.09 18:57:04] Returning from WebElement::send_keys
[2012.03.09 18:57:04] Calling method WebElement::submit( )
[2012.03.09 18:57:19] Returning from WebElement::submit
[2012.03.09 18:57:19] Calling method WebDriver::find_element( xpath, //h2 )
[2012.03.09 18:57:19] Calling method WebDriver::page_source( )
[2012.03.09 18:57:19] Detected locale: en
[2012.03.09 18:57:19] Calling method WebDriver::element_present?( xpath, //div[ @class='header' and text()

Есть идеи?

Можно поступить как посоветовал Taras. Сделать свой класс - наследник какого-нибудь вебдрайвера и переопределить интересующие методы, добавив в каждый логирование.
Либо же можно заоверрайдить метод execute у вебдрайвера и добавить туда более общее логирование, вроде такого

WebDriver driver = new FirefoxDriver() {
    @Override
    protected Response execute(String driverCommand, Map<String, ?> parameters) {
// добавить сюда логирование приходящих данных                
        return super.execute(driverCommand, parameters);
    }
};

 

для этих целей вам надо использовать интерфейс WebDriverEventListener, который позволит вам подключаться в разным событиям

 

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.events.WebDriverEventListener;
 
public class MyWebDriverEventListener implements WebDriverEventListener {
 
    public void afterChangeValueOf(WebElement element, WebDriver selenium) {}
    public void afterClickOn(WebElement element, WebDriver selenium) {}
    public void afterFindBy(By by, WebElement element, WebDriver selenium) {}
    public void afterNavigateBack(WebDriver selenium) {}
    public void afterNavigateForward(WebDriver selenium) {}
    public void afterNavigateTo(String url, WebDriver selenium) {}
    public void afterScript(String script, WebDriver selenium) {}
    public void beforeChangeValueOf(WebElement element, WebDriver selenium) {}
    public void beforeClickOn(WebElement element, WebDriver selenium) {}
    public void beforeFindBy(By by, WebElement element, WebDriver selenium) {}
    public void beforeNavigateBack(WebDriver selenium) {}
    public void beforeNavigateForward(WebDriver selenium) {}
    public void beforeNavigateTo(String url, WebDriver selenium) {}
    public void beforeScript(String script, WebDriver selenium) {}
    public void onException(Throwable error, WebDriver selenium) {}
 
}

а дальше надо его подключить к WebDriver

selenium = new EventFiringWebDriver(driver).register(eventListener);

более детально на вопрос КАК вам думаю сможет ответить уже готовая статья http://blog.simon-reekie.me/2011/05/21/logging-selenium-2-events-in-twist/

2 лайка

Есть совсем экзотический способ с помощью Java Dynamic Proxy. Чтобы не писать логирование для каждого метода можно это сделать один раз в своем Invocation Handler и использовать его для любого типа драйвера.

Примерный код ниже. Главное не забыть проверить args на null :).

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyInvocationHandler implements InvocationHandler {

    private WebDriver webDriver;

    public MyInvocationHandler(WebDriver webDriver) {
        this.webDriver = webDriver;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("method name = " + method.getName());
        for (int i = 0; i < args.length; i++) {
            Object arg = args[i];
            System.out.println("arg["+i+"] = " + arg);
        }
        return method.invoke(webDriver, args);
    }

    public static void main(String[] args) {
        HtmlUnitDriver aDriver = new HtmlUnitDriver();

        WebDriver proxyWebDriver = (WebDriver) Proxy.newProxyInstance(MyInvocationHandler.class.getClassLoader(),
                new Class[]{WebDriver.class}new MyInvocationHandler(aDriver));

        proxyWebDriver.get("http://google.com");
    }
 

 

 

Подробнее о Java Dynamic Proxies тут http://www.javaworld.com/javaworld/jw-11-2000/jw-1110-proxy.html
2 лайка

Супер, всем спасибо за помощь, буду пробовать... о результатах отпишуть чуть позже.

+1 СПС Мишаня! Прикрутили, работает )

 

1 лайк