访问 class 变量时出现 Selenium NoSuchElementException
Selenium NoSuchElementException when accessing a class variable
所以,我有一个 class A,它有一个 (public static WebElement element1, element2)。
public class myClass {
public static WebElement element1, element2;
public myClass(){
WebDriver driver = new FirefoxDriver();
this.element1 = driver.findElement(By.id("button"));
this.element2 = driver.findElement(By.id("text"));
}
}
然后我有一个测试 class,其中有一个名为 @Test public void testClassA 的方法。
@Test
public void testClassA(){
myClass m = new myClass();
m.element1.click();
m.element2.sendKeys("input something");
}
问题是我收到 org.openqa.selenium.NoSuchElementException:无法定位元素:{} 错误。我认为我的错误正在发生,因为 element2 位于下一页,它在单击按钮后显示。我应该在我的代码中做什么,以便当我将两个元素分配给 findBy 方法时,测试将通过第一次单击然后将键发送到 element2?
正如您提到的 element2 出现在下一页中,您必须等到新页面加载。如果没有这个等待,如果你试图找到 element2,它将抛出异常,因为在页面更改之前在当前页面上找不到该元素。
解决方案:
1) 在element1 click() 方法后添加一个Explicit wait。您可以等到 element2 在 click() 之后出现。
m.element1.click();
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("text")));
m.element2.sendKeys("input something");
2) 简单但我不推荐这个。使用 Thread.sleep() 等待新页面加载。
3) 使用页面对象设计模式。
您可以使用webdriver implicitwait 等待页面上的元素加载一段时间。
driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
正如您在上面的代码中看到的,我用了 8 秒来加载页面上的 elemnet。 Read more about wait in Webdriver
使用 try catch 块来处理异常。
@Test
public void testClassA(){
driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
try{
myClass m = new myClass();
m.element1.click();
m.element2.sendKeys("input something");
}catch(NoSuchElementException e){
e.printStackTrace();
}
}
The way you have written the code will break in scenarios where
elements are dynamic and also on page navigation.
在不同的 class 中找到网络元素并在测试中使用该 class 的对象不是一个好习惯 class.
正如您在代码中看到的那样:myClass m = new myClass();
,当创建 myClass
的对象时,构造函数被触发并且驱动程序同时找到 element1
和 element2
一次。而且,由于element2还是没有显示,所以抛出异常。
我不知道是什么促使您遵循这种做法,而是 仅在您真正需要时才查找网络元素。 似乎有很多选择,这取决于如何你想设计你的代码。
- 使用相同的 class 查找元素并对其执行操作。
- 使用不同的方法来查找网络元素,而不是使用构造函数来查找它们。
- 如果你想让事情变得通用,请为 webdriver 操作使用关键字。
- 如果需要,使用属性文件来存储定位器和数据。
更多标准做法(我猜是):
- 使用 Page Objects 查找网络元素。
- 除了页面对象外,还使用 PageFactory。
很好的参考:http://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html
所以,我有一个 class A,它有一个 (public static WebElement element1, element2)。
public class myClass {
public static WebElement element1, element2;
public myClass(){
WebDriver driver = new FirefoxDriver();
this.element1 = driver.findElement(By.id("button"));
this.element2 = driver.findElement(By.id("text"));
}
}
然后我有一个测试 class,其中有一个名为 @Test public void testClassA 的方法。
@Test
public void testClassA(){
myClass m = new myClass();
m.element1.click();
m.element2.sendKeys("input something");
}
问题是我收到 org.openqa.selenium.NoSuchElementException:无法定位元素:{} 错误。我认为我的错误正在发生,因为 element2 位于下一页,它在单击按钮后显示。我应该在我的代码中做什么,以便当我将两个元素分配给 findBy 方法时,测试将通过第一次单击然后将键发送到 element2?
正如您提到的 element2 出现在下一页中,您必须等到新页面加载。如果没有这个等待,如果你试图找到 element2,它将抛出异常,因为在页面更改之前在当前页面上找不到该元素。
解决方案:
1) 在element1 click() 方法后添加一个Explicit wait。您可以等到 element2 在 click() 之后出现。
m.element1.click();
WebElement myDynamicElement = (new WebDriverWait(driver, 10)).until(ExpectedConditions.presenceOfElementLocated(By.id("text")));
m.element2.sendKeys("input something");
2) 简单但我不推荐这个。使用 Thread.sleep() 等待新页面加载。
3) 使用页面对象设计模式。
您可以使用webdriver implicitwait 等待页面上的元素加载一段时间。
driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
正如您在上面的代码中看到的,我用了 8 秒来加载页面上的 elemnet。 Read more about wait in Webdriver
使用 try catch 块来处理异常。
@Test
public void testClassA(){
driver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
try{
myClass m = new myClass();
m.element1.click();
m.element2.sendKeys("input something");
}catch(NoSuchElementException e){
e.printStackTrace();
}
}
The way you have written the code will break in scenarios where elements are dynamic and also on page navigation.
在不同的 class 中找到网络元素并在测试中使用该 class 的对象不是一个好习惯 class.
正如您在代码中看到的那样:myClass m = new myClass();
,当创建 myClass
的对象时,构造函数被触发并且驱动程序同时找到 element1
和 element2
一次。而且,由于element2还是没有显示,所以抛出异常。
我不知道是什么促使您遵循这种做法,而是 仅在您真正需要时才查找网络元素。 似乎有很多选择,这取决于如何你想设计你的代码。
- 使用相同的 class 查找元素并对其执行操作。
- 使用不同的方法来查找网络元素,而不是使用构造函数来查找它们。
- 如果你想让事情变得通用,请为 webdriver 操作使用关键字。
- 如果需要,使用属性文件来存储定位器和数据。
更多标准做法(我猜是):
- 使用 Page Objects 查找网络元素。
- 除了页面对象外,还使用 PageFactory。
很好的参考:http://www.guru99.com/page-object-model-pom-page-factory-in-selenium-ultimate-guide.html