WebDriver:如何检查页面对象Web元素是否存在?
将页面对象与 webdriver 结合使用时如何检查元素是否存在。
到目前为止我都是这样做的。
DefaultPage defaultPage = PageFactory.initElements(this.driver,
DefaultPage.class);
assertTrue(defaultPage.isUserCreateMenuLinkPresent());
页面对象:
public class DefaultPage {
@FindBy(id = "link_i_user_create")
private WebElement userCreateMenuLink;
public boolean isUserCreateMenuLinkPresent() {
try {
this.userCreateMenuLink.getTagName();
return true;
} catch (NoSuchElementException e) {
return false;
}
}
}
但我无法相信这种 try/catch 是人们应该做的事情。 那么检查元素是否存在(使用页面对象)的更好方法是什么?
How to check if an Element exists, when using Page Objects with webdriver.
So far I am doing it this way.
DefaultPage defaultPage = PageFactory.initElements(this.driver,
DefaultPage.class);
assertTrue(defaultPage.isUserCreateMenuLinkPresent());
Page Object:
public class DefaultPage {
@FindBy(id = "link_i_user_create")
private WebElement userCreateMenuLink;
public boolean isUserCreateMenuLinkPresent() {
try {
this.userCreateMenuLink.getTagName();
return true;
} catch (NoSuchElementException e) {
return false;
}
}
}
But I can not believe that this try/catch is the way one should do it. So what would be a better way to check if the elements exits (with using Page Objects)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
问题在于模式本身。它使用 @FindBy 注释(PageFactory 使用它来初始化必须由 Proxy 包装的字段),将标准元素替换为其包含 InvocableHandler 的代理实例。
每次尝试访问用 @FindBy 注释的字段时,调用处理程序都会尝试使用默认的 ElementLocator 查找元素。问题是,如果 ElementLocator.findElement() 方法中没有出现任何元素,则会抛出 TimeoutException / NoSuchElementException DOM。
因此,每次需要检查元素是否显示时,都必须搜索元素列表并检查其大小。
解决此问题的另一种方法是创建您自己的 LocatingElementHandler 和 ElementLocator 实现。
因此,如果您需要自己的 isDisplayed() 方法返回 false 而不是 Exception,那么您可以将 ElementLocator 中的 findElement() 方法替换为类似的内容:
并向 LocatingElementHandler.invoke() 添加新条件,
例如:
The problem is the pattern itself. It uses @FindBy annotation (used by PageFactory to init the fields that must be wrapped by Proxy) that replaces the standard elements with their proxy instances which contain InvocationHandler.
Each time you try to access a field, annotated with @FindBy, the invocation handler tries to find the element using the default ElementLocator.The problem is that the ElementLocator.findElement() method throws an TimeoutException / NoSuchElementException if there are no elements presented in the DOM.
Therefore, each time you need to check whether an element is displayed or not you have to search for a List of elements and check its size.
Another way to solve this problem is to create your own implementation of LocatingElementHandler and ElementLocator
So, if you need your own isDisplayed() method to return false instead of Exception, you have to replace the findElement() method in ElementLocator with something like that:
And add new conditions to LocatingElementHandler.invoke()
Something like:
Webdriver 被设计为在未找到元素时抛出异常,因此没有任何方法可以验证 Webdriver 中元素是否存在。
检查此 - http://groups.google.com/group/webdriver/browse_thread/线程/909a9b6cb568e341
Webdriver is designed to throw an exception if an element is not found, So there aren't any methods to verify presence of an element in Webdriver.
Check this - http://groups.google.com/group/webdriver/browse_thread/thread/909a9b6cb568e341
@Ralph:我用同样的方式来做:try/catch。我从来没有找到其他方法。
您可以替换超类中的try/catch 块并将其设计为通用。换句话说:您可以编写一个需要 WebElement 类型的对象的方法。这个方法包含try/catch块并返回true/false...
所以我在测试框架的超类中编写了以下公共方法,现在能够在每个页面对象中使用它:
我不知道为什么这没有在WebDriver中实现...
否则你可以使用WebDriverWait。
@Ralph: I do it the same way: try/catch. I've never found another way.
You could swap out the try/catch block in a super class and design it generic. In other words: You could write a method which expects an object of type WebElement. This method contains the try/catch block and return true/false...
So I wrote the following public method in the test framework's super class and am now able to use it in every page object:
I don't know why this is not implemented in WebDriver...
Otherwise you could use WebDriverWait.
我正在使用这种模式,对我来说效果很好:
或者:
I'm using this pattern, works fine for me:
or:
我最近看到了这篇旧帖子,相信我找到了一个解决方案。
我正在测试一个带有
添加用户
按钮的页面。单击该按钮时,会出现各种可编辑文本字段(名字、姓氏、电子邮件等)和一个下拉列表。单击
Cancel
按钮后,字段消失并且不再存在。将WebDriverWait
与ExpectedConditions.visibilityOf()
一起使用将不起作用,因为元素不再存在于DOM
中。我发现
@FindAll
对我来说是一个解决方案,尽管我必须承认我的测试在我的 List 断言中运行明显缓慢。对于您的代码,如下所示:
不过,我可以在自己的测试中使用类似的东西,并且这似乎是避免“没有此类元素”异常的可靠方法。它基本上是断言的页面对象改编:driver.findElements(By.locator).size()
driver.findElements(By.locator).size()
driver.findElements(By.locator).size()
1.
.I recently came across this old post and believe I've found one solution.
I was testing a page that had an
Add User
button. When the button was clicked, various editable text fields appeared (for First Name, Last Name, Email, etc..) and a single dropdown.When a
Cancel
button was clicked, the fields disappeared and no longer existed. UsingWebDriverWait
withExpectedConditions.visibilityOf()
would not work since the elements no longer existed in theDOM
.I found that
@FindAll
was a solution for me, though I must admit my test ran noticeably slow at the my List assertion.For your code, something like this:
I am able to use something similar in my own tests though, and it seems like a dependable way to skirt the 'No such element' exception. It's basically a page object adaptation of asserting:
driver.findElements(By.locator).size() < 1
.这是访问页面上可选元素的一个很好的模式:
在测试中,您可以使用以下断言:
Here is a nice pattern to access optional elements on a page:
In a test, you could then use the following assertions:
Arquillian 已在 石墨烯扩展。
检查
ElementLocatorConditionFactory.isPresent()
函数。他们或多或少做了您在问题中所写的内容(来自
ExpectedConditions.findElement
中硒支持.jar):Arquillian has implemented that feature in Graphene extension.
Check
ElementLocatorConditionFactory.isPresent()
function.They more or less do what you wrote in your question (from
ExpectedConditions.findElement
in selenium-support.jar) :使用 C# 绑定:
您告诉 Selenium 获取与该 Id 匹配的所有元素并将它们放入
IWebElement
列表中。然后,您可以在列表上调用.Any()
,如果至少找到一个IWebElement
,则该列表的计算结果为 true。Using C# bindings:
You're telling Selenium to grab all elements that match that Id and put them into a List of
IWebElement
. You then call.Any()
on the list which evaluates to true if at least oneIWebElement
was found.尝试一下,这在 pom 中绝对可以工作,
这肯定可以在带有 try catch 的页面对象模型中工作
try this is defiantly work in pom
this will definitely work in page object model surround with try catch