Selenium IE .click()工作不一致



我有以下问题。我使用Selenium 2.42.2来测试我们公司的内网站点。因此,我用一个Testsuite实现了一个示例Testcase。我用Firefox 31和IE 11测试了这个测试用例。所有的工作都很好,但有时似乎IE不点击一些元素。这很让人困惑,因为有时它能正常工作,有时却不能。然而,到目前为止,我尝试了以下解决方案,但没有成功:

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

唯一有效的解决方案是双击。但是这会给火狐带来新的问题,如果这个错误没有发生。

谁有提示或任何想法是造成这个问题的原因?

感谢向上的帮助。

附加代码:

@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] ERRORtThe 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] WARNINGtHigh response-time detected: " + (stopTime-startTime) + " ms [@element: " + s + "]");
    }
}

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

现在我有办法了!

正如你在我的问题代码中看到的,我从FF和IE驱动程序中重写了finelement方法。这是解决这个烦人问题的关键。因为我发现IE有时不点击一些元素(主要是发送ajax请求的元素)。我猜这是因为IE没有直接关注这些元素。IE是缓慢的,需要更多的时间,或者你需要双击元素(1。2.设置焦点;真正点击)。下面是解决方案:

你可以覆盖IE中的finelement方法,并添加一个简单的By-element来保存所请求的元素。如果现在这个方法找不到元素,因为父元素没有被真正点击,你可以再次点击这个方法中的父元素,vóila它可以工作!

对于这个解决方案,它真的很重要,你建立一个自己的类(例如:InternetExplorerDriver2_0),这是一个单例(在自己的类中执行点击),并覆盖标准的findElement方法。

(我猜很明显,在接下来的测试中,你必须使用你改变的IEDriver类,而不是原来的'InternetExplorerDriver'类)

你可以在这里找到修改后的idriver类的代码:

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] ERRORtThe 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] WARNINGtHigh response-time detected: " + (stopTime - startTime) + " ms [@element: " + s + "]");
        }
    }
}

我知道这不是完美的解决方案,但这是一个很好的解决方案,节省了很多时间!

最新更新