Selenium IE .click()工作不一致

时间:2014-08-12 09:48:56

标签: java internet-explorer selenium junit click

我有以下问题。我使用Selenium 2.42.2测试我们公司的Intranet站点。因此,我使用Testsuite实现了一个示例Testcase。我用Firefox 31和IE 11测试这个测试用例。一切正常,但有时似乎IE没有点击某些元素。它非常令人困惑,因为有时候它可以正常工作,有时也不会。但是到目前为止,我还没有成功地解决以下问题:

  • 检查缩放级别并以所有可能的方式设置
  • 设置所有可能的等待(显式,隐式,一些奇怪的变体)
  • 使用'sendkeys(\ n)'代替.click()

唯一有效的解决方案是双击。但这会引发firefox的新问题以及是否发生此错误。

是否有人有提示或任何想法导致问题?

感谢您的帮助。

附加代码:

@RunWith(Parameterized.class)
public class SeleniumTest_WD_used extends AbstractSelenium {

    public SeleniumTest_WD_used(RemoteWebDriver d) {
        driver = d;
    }

    private String baseUrl = "company.intranet.site.com";

    @Override
    @Before
    public void setUp() {
        driver.get(baseUrl);
        driver.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS);
    }

    @Test
    public void worldClock_autoCity_Test_with_ES() throws InterruptedException {
        Thread.sleep(2000);
        driver.findElement(By.xpath("some XPath")).click();
        Thread.sleep(2000);
        new Select(driver.findElement(By.id("some ID"))).selectByVisibleText("Some Text");
        driver.findElement(By.cssSelector("Some Css_Element")).click();
        driver.findElement(By.xpath("some XPath")).click();
        RemoteWebElement e1 = (RemoteWebElement) driver.findElement(By.xpath("some XPath"));
        Assert.assertEquals("Some Assert", e1.getText());
    }
}

并以下列方式覆盖IE和FF驱动程序的'findElement'方法(但如果我使用标准方法,我也会遇到此错误):

public class FirefoxDriver2_0 extends FirefoxDriver {
private static FirefoxDriver2_0 instance = null;
private long startTime;
private long stopTime;

private FirefoxDriver2_0() {
    super();
}

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

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

private RemoteWebElement elementSearch(By by, FirefoxDriver driver) {
    startTime = System.currentTimeMillis();
    RemoteWebElement helpingElement = null;
    isElementPresent(by);
    try {
        helpingElement = (RemoteWebElement) super.findElement(by);
    } catch (Exception e) {
        AllTest.updateLogger("[error] method 'elementSearch' incomplete");
        fail("Test not successfull!");
    } finally {
        stopTime = System.currentTimeMillis();
        timeWarning(by.toString());
    }
    return helpingElement;
}

private boolean isElementPresent(By by) {
    try {
        super.findElement(by);
        return true;
    } catch (NoSuchElementException e) {
        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 + "]");
    }
}

如果您需要更多代码或信息,请索取。我有两个更相关的类1.)一个初始化测试的Testsuite和一个抽象类作为我的测试用例的父类。

1 个答案:

答案 0 :(得分:0)

现在我找到了解决方案!

正如您在我的问题中所看到的,Code I覆盖了FF和IE驱动程序中的findElement方法。这是解决这个非常恼人的问题的关键。因为我发现IE有时简单不点击某些元素(主要是发送ajax请求的元素)。我想这是因为IE不直接关注这些元素。 IE很慢,需要更多时间才需要双击元素(1.设置焦点,2。真正点击)。以下是解决方案:

您可以从IE覆盖findElement方法并添加一个简单的By-element来保存请求的元素。如果现在无法通过此方法找到元素,因为未单击父级,则可以再次单击此方法中的父级,并且víila可以正常工作!

对于这个解决方案,构建一个自己的类(例如名为:InternetExplorerDriver2_0)非常重要,它是一个单例(用于在自己的类中执行单击)并覆盖标准的findElement方法。

(我想很清楚,在以下测试中你必须使用你改变的IEDriver类而不是原来的'InternetExplorerDriver'类)

您可以在此处找到已更改的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.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebElement;

public class InternetExplorerDriver2_0 extends InternetExplorerDriver {

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

    private InternetExplorerDriver2_0() {
        super(caps);
    }

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

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

    private RemoteWebElement elementSearch(By by, InternetExplorerDriver driver) {
        startTime = System.currentTimeMillis();
        RemoteWebElement helpingElement = null;
        isElementPresent(by);
        try {
            helpingElement = (RemoteWebElement) super.findElement(by);
        } catch (Exception e) {
            System.out.println("[error] method 'elementSearch' incomplete");
            fail("Test not successfull!");
        } finally {
            stopTime = System.currentTimeMillis();
            timeWarning(by.toString());
        }
        olderBy = by;
        return helpingElement;
    }

    private boolean isElementPresent(By by) {
        try {
            super.findElement(by);
            return true;
        } catch (NoSuchElementException e1) {

            //the following lines are the important!!!

            try {
                InternetExplorerDriver2_0.getInstance(caps).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 + "]");
        }
    }
}

我知道这不是一个非常干净的解决方案,但这是一个很好的解决方法,节省了很多时间!