我有以下问题。我使用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 + "]");
}
}
}
我知道这不是完美的解决方案,但这是一个很好的解决方案,节省了很多时间!