Java覆盖现有的类方法

时间:2014-08-13 13:55:19

标签: java internet-explorer selenium junit

我遇到了一个稍微复杂的问题。

情况是我在一个基于硒的JUnittests自动化的项目上工作。出于这个原因,我编写了一个testsuite和一个abstractTestclass(作为几个测试类的基础)。此外,我尝试构建我的项目,以便必须实现测试用例的程序员只需要在selenium IDE中记录它们并导出到JUnit-test-classes。为了达到这个目标,需要进行一些更改,因为抛出的selenium-java-code和标准selenium包的一些方法和功能都有一些小错误...就像IE有时没有点击... 为了避免这些错误,我覆盖了FFDriver和IEDriver类,特别是' findElement'方法。这很好用!

但现在我遇到了一个新问题。 IE有时不会点击非显示元素的已知问题。我也有一个解决方法(使用Javascript命令而不是click())。但是当我想到如何实现时,我希望这样做,就像我通过覆盖驱动程序类解决的问题一样,我开始重写RemoteWebElement类。

这就是问题所在。如果我覆盖RemoteWebElement类来覆盖click()方法,我必须在整个项目而不是标准上使用我的新RemoteWebElement2_0类。起初猜测并不像看起来那么糟糕(就像我必须对Driver类做同样的事情)。但后来我意识到我的findElement方法提供了一个RemoteWebElement而不是我的RemoteWebElement2_0。我认为没有机会改变findElement方法来传递我的RemoteWebElement2_0并且无法进行向下传播。

我有以下想法来解决这个问题但不知道如何实现它们,或者即使它们是可实现的:

  • 1。)直接覆盖原始的RemoteWebElement类(应该可以但是如何?)
  • 2。)避免在findElement方法中返回正常的RemoteWebElement
  • 3。)修改selenium IDE以使用click()方法但不是使用costum实现
  • 4。)使用click()方法解决问题,使用另一种解决方法
  • 5。)不能进行向下转换!?

有人能帮帮我吗?我知道它有点奇怪,但请尽量了解我并且不知道问你是不是!

这是我的代码:

IEDriver类 - >

import static org.junit.Assert.fail;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.remote.RemoteWebElement;

public class InternetExplorerDriver2_0 extends InternetExplorerDriver {

    private static InternetExplorerDriver2_0 instance = null;
    private long startTime;
    private long stopTime;
    private By olderBy;

    private InternetExplorerDriver2_0() {
        super();
    }

    public static synchronized InternetExplorerDriver2_0 getInstance() {
        if (instance == null) {
            instance = new InternetExplorerDriver2_0();
        }
        return instance;
    }

    @Override
    public RemoteWebElement2_0 findElement(By by) {
        return elementSearch(by, InternetExplorerDriver2_0.getInstance());
    }

    private RemoteWebElement2_0 elementSearch(By by,
            InternetExplorerDriver driver) {
        startTime = System.currentTimeMillis();
        RemoteWebElement helpingElement = null;
        RemoteWebElement2_0 h2 = null;
        isElementPresent(by);
        try {

            //this not allowed downcast causes problems :(

            helpingElement = (RemoteWebElement) super.findElement(by);
            h2 = (RemoteWebElement2_0) helpingElement;
        } catch (Exception e) {
            System.out.println("[error] method 'elementSearch' incomplete" + e.getLocalizedMessage());
            fail("Test not successfull!");
        } finally {
            stopTime = System.currentTimeMillis();
            timeWarning(by.toString());
        }
        olderBy = by;
        return h2;
    }

    private boolean isElementPresent(By by) {
        try {
            super.findElement(by);
            return true;
        } catch (NoSuchElementException e1) {
            try {
                InternetExplorerDriver2_0.getInstance().findElement(olderBy).click();
                super.findElement(by);
                return true;
            } catch (Exception e2) {
                stopTime = System.currentTimeMillis();
                timeWarning(by.toString());
                AllTest.updateLogger("[main] ERROR\tThe following expression could not be solved: " + by);
                fail("Test not successfull! --> Error: Element not found. Please check the failed XPath's");
                return false;
            }
        }
    }

    private void timeWarning(String s) {
        if (stopTime - startTime > 500) {
            AllTest.updateLogger("[main] WARNING\tHigh response-time detected: " + (stopTime - startTime) + " ms [@element: " + s + "]");
        }
    }
}

RemoteWebDriver2_0类 - >

import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotVisibleException;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.RemoteWebElement;

public class RemoteWebElement2_0 extends RemoteWebElement {

    public RemoteWebElement2_0() {
        super();
    }

    @Override
    public void click() {
        try {
            super.click();
        } catch (ElementNotVisibleException e1) {

            //Here starts the workaround for the IEDriver.click problem

            try {
                RemoteWebDriver helpDriver = (RemoteWebDriver) this.getWrappedDriver();
                helpDriver.executeScript("arguments[0].click();", this.getWrappedDriver().findElement(By.id("eb_format_12h")));
            } catch (Exception e2) {

            }
        }
    }
}

如果您需要更多代码,请索取。

向上致谢!!!

1 个答案:

答案 0 :(得分:1)

我不是硒的专家,但你可以做的是返回原始RemoteWebElement的包装

在您的InternetExplorerDriver2_0覆盖方法

  @Override
    public RemoteWebElement findElement(By by) {
      RemoteWebElement originalElement = super.findElement(by);
      if (originalElement == null){
      return null;
      }
      return new RemoteWebElementWrapper(originalElement);
    }

现在创建包装类,并覆盖超类中的所有方法,如下面的示例

public class RemoteWebElementWrapper extends RemoteWebElement {

    private final RemoteWebElement instance;
    public RemoteWebElementWrapper(RemoteWebElement instance) {
        super();
        this.instance = instance;
    }
@Override
List<WebElement> findElementsByLinkText(String using){
return instance.findElementsByLinkText(using)
}
@Override
List<WebElement> findElementsByName(String using){
instance.findElementsByName(using)
}
@Override
List<WebElement>    findElementsByPartialLinkText(String using){
instance.findElementsByPartialLinkText(using)
}
//etc
}