如何记录WebDriver调用,代理不起作用

时间:2018-08-08 19:51:02

标签: java selenium dynamic-proxy

我正在尝试为RemoteWebDriver编写代理,以为诸如findElement等方法添加自定义日志记录。作为一个实验,我发现了一个TimingHandler,它仅为方法提供了开始/停止时间戳记-在硒之外还可以正常工作。但是,我无法使其与RemoteWebDriver一起使用。

问题:    关于RemoteWebDriver是否有某些东西可以阻止使用代理?    我执行不正确吗?    有其他/更好的方法吗?

public class TimingDynamicInvocationHandler implements InvocationHandler {

  private static final Logger logger = LogManager.getLogger(TimingDynamicInvocationHandler.class.getName());

  private final Map<String, Method> methods = new HashMap<>();

  private Object target;

  public TimingDynamicInvocationHandler(Object target) {
      this.target = target;

      for(Method method: target.getClass().getDeclaredMethods()) {
        System.out.println("TDIHandler method: " + method.getName());
          this.methods.put(method.getName(), method);
      }
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) 
    throws Throwable {
      System.out.println("invoke method: " + method.getName());
      long start = System.nanoTime();
      Object result = methods.get(method.getName()).invoke(target, args);
      long elapsed = System.nanoTime() - start;

      logger.info("Executing {} finished in {} ns", method.getName(), 
        elapsed);

      return result;
  }
}

我正在使用TestNG,并且具有BaseTest类,所有测试均从此扩展。我使用beforeMethod创建驱动程序。没有代理,我将执行以下操作,并且按预期运行:

 driver = new RemoteWebDriver(new URL(HUB_URL), caps);
 driver.get(APP_URL);
 driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

但是,当我更改为使用代理时,它会挂起:

    RemoteWebDriver rrDriver = new RemoteWebDriver(new URL(HUB_URL), caps);
    TimingDynamicInvocationHandler handler = new TimingDynamicInvocationHandler(rrDriver);
    Class<?> proxyClass = Proxy.getProxyClass(WebDriver.class.getClassLoader(), WebDriver.class);
    driver = (WebDriver) proxyClass.getConstructor(TimingDynamicInvocationHandler.class).newInstance(handler);

我得到以下输出:

12:06:06.941 [main] ERROR BaseTest 175 beforeMethod - java.lang.NoSuchMethodException: com.sun.proxy.$Proxy22.<init>(com.timr.utils.aop.TimingDynamicInvocationHandler)

1 个答案:

答案 0 :(得分:0)

它认为RemoteWebDriver不是动态代理的理想选择,因为它已经是在硒客户端org.openqa.selenium.remote.Augmenter.java中找到的CompoundHandler的一部分,请参阅:CompoundHandler实现InvocationHandler。

我选择了一个更简单的解决方案来扩展每个驱动程序类,即RemoteWebDriver,ChromeDriver和FirefoxDriver。

public class ChromeLoggingDriver extends ChromeDriver {
  private static final Logger log = LogManager.getLogger(ChromeLoggingDriver.class.getName());

  public ChromeLoggingDriver(ChromeOptions options) {
    super(options);
  } 

  @Override
  public void get(String url) {
    log.info("url: " + url);
    super.get(url);
  }

  @Override
  public String getCurrentUrl() {
    String url = super.getCurrentUrl();
    log.info(url);
    return url;
  }

  @Override
  public String getTitle() {
    String title = super.getTitle();
    log.info(title);
    return title;
  }

  @Override
  public List<WebElement> findElements(By by) {
    log.info(by.toString());
    return super.findElements(by);
  }

  @Override
  public WebElement findElement(By by) {
    log.info(by.toString());
    return super.findElement(by);
  }

  // ... 

  @Override
  public void close() {
    log.info("");
    super.close();
  }

  @Override
  public void quit() {
    log.info("");
    super.quit();
  }
}