Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在java中为Selenium webdriver编写自己的自定义定位器?_Java_Selenium_Webdriver_Selenium Webdriver_Browser Automation - Fatal编程技术网

如何在java中为Selenium webdriver编写自己的自定义定位器?

如何在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")).* 如果有人能

我想写我自己的定位器来访问元素。WebDriver的API目前提供了八个定位器,允许按id、名称属性、标记名、完整或部分链接文本、XPath、类名和css选择器检索元素。但是,这些默认定位器现在对我来说还不够,因为我必须通过一个新属性访问元素。让我举个例子,这样你就能明白我到底想要什么

例如: 选择您的用户名:

现在,我想编写一段代码,以便使用myLocator定位器访问用户名按钮,如:

*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个多月的项目,我们刚刚实现了我们自己的“元素”对象,该对象包含一个类型和一个字符串。从这里开始,定位实现隐藏在另一层中。我想这和你想要达到的目标差不多。祝你好运