如何在java中为Selenium webdriver编写自己的自定义定位器?
我想写我自己的定位器来访问元素。WebDriver的API目前提供了八个定位器,允许按id、名称属性、标记名、完整或部分链接文本、XPath、类名和css选择器检索元素。但是,这些默认定位器现在对我来说还不够,因为我必须通过一个新属性访问元素。让我举个例子,这样你就能明白我到底想要什么 例如: 选择您的用户名: 现在,我想编写一段代码,以便使用myLocator定位器访问用户名按钮,如:如何在java中为Selenium webdriver编写自己的自定义定位器?,java,selenium,webdriver,selenium-webdriver,browser-automation,Java,Selenium,Webdriver,Selenium Webdriver,Browser Automation,我想写我自己的定位器来访问元素。WebDriver的API目前提供了八个定位器,允许按id、名称属性、标记名、完整或部分链接文本、XPath、类名和css选择器检索元素。但是,这些默认定位器现在对我来说还不够,因为我必须通过一个新属性访问元素。让我举个例子,这样你就能明白我到底想要什么 例如: 选择您的用户名: 现在,我想编写一段代码,以便使用myLocator定位器访问用户名按钮,如: *driver.findElement(By.myLocator("username")).* 如果有人能
*driver.findElement(By.myLocator("username")).*
如果有人能告诉我们如何重写BY类来添加我自己的定位器,这将非常有帮助
提前感谢您的帮助。我知道这并不能真正回答您的问题,但为什么不使用Xpath呢? 构建一个新的定位器而不是仅仅在DOM中爬行似乎需要很多额外的工作 例如:driver.findElementBy.Xpath//div[@username='YourUsername']
我可以举一个更好的例子,详细介绍您正在使用的属性和页面。就像Michiel回答的那样,我觉得您可以通过Selenium已经提供的功能实现您想要的功能。如果由于开发人员更改ID和元素名称而需要避免维护开销,则可以创建一个单独的文件来跟踪需要定位的元素
//EG. (not Java I know :))
string usernameXPath = "//div[@username='YourUsername']";
如果有变化,你可以保持这个。您甚至可以更进一步,为每个“其他类型”的元素实现一个类,并在构造函数中围绕它放置一个XPath。XPath非常灵活,因为它提供了“contains”和“parent::div”等函数。也许可以查看更多的XPath阅读
编辑:还值得注意的是,C绑定的最新版本说明如下:
.Net:将更新CustomFinderType属性引入到
.NET FindByAttribute。这允许在中使用自定义By子类
寻呼机工厂。自定义查找器必须是By的子类,并且
它必须公开接受字符串参数的公共构造函数
希望这也在下一个Java版本中出现:您需要对By类进行子类化,并为findElement和findElements方法提供实现,因为这是实际元素查找的“肉”所在
然后,您应该能够将其与普通驱动程序一起使用。FindElement然后。您可以执行以下操作:
private final String myLocator = "//*[contains(@id,'username') and contains (@type,'text') and contains (text(),'exactly what I want')]";
private final String myLocator = "//*[contains(@id,'%s') and contains (@type,'text') and contains (text(),'exactly what I want')]";
因此,您可以按照自己的意愿编写定位器,这取决于所映射的属性,无需单击或选择5行
此外,您可以在该定位器中使用通配符,只需将任何要用作参数的内容替换为%s,如下所示:
private final String myLocator = "//*[contains(@id,'username') and contains (@type,'text') and contains (text(),'exactly what I want')]";
private final String myLocator = "//*[contains(@id,'%s') and contains (@type,'text') and contains (text(),'exactly what I want')]";
然后创建一个动态元素,如下所示:
private WebElement usernameSelectElement(String text) {
return driver.findElement(By.xpath(String.format(myLocator, text)));
}
其用法如下:
public void clickMyElement(text){
usernameSelectElement(text).click();
}
在我看来,您的示例过于复杂。使用c
using OpenQA.Selenium;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class ImageBy : By
{
public ImageBy(string imageByString)
{
FindElementMethod = (ISearchContext context) =>
{
IWebElement mockElement = context.FindElement(By.XPath("//img[@src='" + imageByString + "']"));
return mockElement;
};
FindElementsMethod = (ISearchContext context) =>
{
ReadOnlyCollection<IWebElement> mockElements = context.FindElements(By.XPath("//img[@src='" + imageByString + "']"));
return mockElements;
};
}
}
使用Java
import java.util.List;
import org.openqa.selenium.By;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebElement;
public class ByImageSrc extends By
{
private final String imageByString;
public ByImageSrc(String imageByString)
{
this.imageByString = imageByString;
}
@Override
public List<WebElement> findElements(SearchContext context)
{
List<WebElement> mockElements = context.findElements(By.xpath("//img[@src='" + imageByString + "']"));
return mockElements;
}
}
看起来您必须编写一些自定义组件。也许这个链接可以帮助你。1.2.我以前读过Web驱动程序API,我的理解是,我必须为我的新定位器创建一个新类,该定位器将从org.openqa.selenium.By类继承。然而,我没有找到好的知识库文章来解释这个实现。谢谢你的评论。这不是不可能的,但是有很多工作要做。你的思路是正确的。不过,您已经了解了SeleniumJavadoc。您可以从这些.class文件中引用并实现您自己的WIN方法。我下载了selenium项目,并查看了By class和从By class继承的其他类。祝我好运,谢谢。谢谢你的快速回答。实际上,在我们当前的环境中,xpath在大多数情况下都不起作用,因为内部结构经常变化,在某些情况下这是不可能的。这就是为什么设计人员决定为自动化目的添加一个新属性,他们不希望我们使用元素的id或名称,因为他们也会根据自己的需求不时更改。再次感谢。谢谢你的回复。我们目前的项目是非常非常大的长期项目。开始时,我们还想创建一个单独的文件来保存更改,但是我们发现,在整个项目生命周期中,这样做会更痛苦。然后我们决定实现新的定位器,以避免将来出现任何问题。我目前正在从事一个已经运行了15个多月的项目,我们刚刚实现了我们自己的“元素”对象,该对象包含一个类型和一个字符串。从这里开始,定位实现隐藏在另一层中。我想这和你想要达到的目标差不多。祝你好运