【问题标题】:Xpath can't click to button (Button id & value dynamically changes) Selenium WebDriver JavaXpath 无法单击按钮(按钮 id 和值动态更改) Selenium WebDriver Java
【发布时间】:2017-12-26 08:05:04
【问题描述】:
<form action="/assessments/1290/questions" id="questionform" method="post">
  <div class="happiness-reaction__item animated fadeIn selected">
    I often get upset over minor issues.
    <div class="inputs">

      <input id="choice_14832" value="14832" name="Answers[0].Choices" data-scv-reaction-id="strongly-disagree1" spellcheck="true" type="radio">
      <label class="u" for="choice_14832">
        <i class="sc-strongly-disagree"></i>
      </label>

      <input id="choice_14833" value="14833" name="Answers[0].Choices" data-scv-reaction-id="slightly-disagree1" spellcheck="true" type="radio">
      <label class="u" for="choice_14833">
        <i class="sc-slightly-disagree"></i>
      </label>

      <input id="choice_14834" value="14834" name="Answers[0].Choices" data-scv-reaction-id="none1" spellcheck="true" type="radio">
      <label class="u" for="choice_14834">
        <i class="sc-none"></i>
      </label>

      <input id="choice_14835" value="14835" name="Answers[0].Choices" data-scv-reaction-id="slightly-agree1" spellcheck="true" type="radio">
      <label class="u" for="choice_14835">
        <i class="sc-slightly-agree"></i>
      </label>

      <input id="choice_14836" value="14836" name="Answers[0].Choices" data-scv-reaction-id="strongly-agree1" spellcheck="true" type="radio">
      <label class="u" for="choice_14836">
        <i class="sc-strongly-agree"></i>
      </label>
    </div>
  </div>
                 .....

我想点击那个单选按钮。由于 ID 和值等动态变化,我应该可以通过使用 XPATH 进行简单的点击,但我不能。我没有收到任何错误,但按钮保持未点击状态。

Check this picture please

到目前为止,我无法点击:

WebElement button = driver.findElement(By.xpath(".//*[@id='questionform']/div[1]/div/label[1]/i"));
button.click();

已编辑:我添加了此信息,以防万一有人想要有关我正在谈论的页面的更多详细信息。必须有一种方法可以在没有变通方法的情况下单击那个简单的按钮。

“我知道问这个问题太费劲了,但是你可以去“supercareer.com”,把 Personality under 评估一下,看看我到底在说什么。注意:不一定是真正的邮件,简单注册 1 点击,无需验证,您可以访问我正在谈论的问题。这是提供有关我的问题 100% 信息的唯一方法。”

【问题讨论】:

  • 我猜应该只有一个 div 而不是两个
  • 我正在使用 FireBug 提取 Xpath ,我没有错误,但我会仔细检查。 @santhosh kumar,我想如果你把代码滑到左边,你会看到第二个 div。由于我的复制粘贴,它不可见
  • 好的……你能用chrome提取动态xpath吗?你有没有添加一些隐式等待?
  • 我也尝试过隐式等待。不是解决方案。我会尝试使用 chrome-Driver 并让您知道。
  • 您愿意点击哪个单选按钮(按钮)?所有的选择都一样吗(全部不同意)?谢谢

标签: java selenium xpath selenium-webdriver selenium-firefoxdriver


【解决方案1】:

在这种情况下,您要做的是找到一个“容器”元素,其中包含您要从中选择的所有选项。在这种情况下,我们可以使用问题文本使用 XPath 找到包含所有 5 个选项的 DIV。从那里,您可以根据I 标签的类名选择所需的选项,例如&lt;i class="sc-strongly-agree"&gt;。因此,只要提供问题文本和所需的选择,我们就可以做出选择。

在这种情况下,您可能会一遍又一遍地使用相同的代码,您通常希望创建一个函数来处理这种情况。此外,由于您重复选择 5 个选项之一,我更喜欢使用枚举。您可以使用字符串,但您必须处理各种潜在的输入,如果有人拼错或以某种方式拼写错误,脚本就会失败。枚举使选择所需的选项变得容易,因为 IDE 总是向您显示选择,使其变得不费吹灰之力。如果你打错了枚举,它将无法编译……而且最好早点知道脚本是否会失败。枚举也是这些选择的容器,因此如果类名发生变化,您可以更改枚举中的类名,并且所有脚本都是固定的。

功能

public static void selectChoice(String question, Choices choice)
{
    driver.findElement(By.xpath("//div[contains(@class,'happiness-reaction__item')][contains(.,'" + question + "')]//i[@class='" + choice.value() + "']")).click();
}

枚举

public enum Choices
{
    STRONGLYDISAGREE("sc-strongly-disagree"),
    SLIGHTLYDISAGREE("sc-slightly-disagree"),
    NONE("sc-none"),
    SLIGHTLYAGREE("sc-slightly-agree"),
    STRONGLYAGREE("sc-strongly-agree");

    private String value;

    Choices(String value)
    {
        this.value = value;
    }

    public String value()
    {
        return value;
    }
}

这就是你的称呼

selectChoice("I often get upset over minor issues.", Choices.STRONGLYAGREE);

【讨论】:

    【解决方案2】:

    如果您不能使用 ID 和 Value - 请使用任何其他属性。在您的情况下,“data-scv-reaction-id”是一个不错的选择)

    //*[@data-scv-reaction-id='strongly-disagree1']
    

    【讨论】:

    • 我在此页面上还有 5 个其他问题要选择,它们也具有相同的 id + 相同的值,例如“强烈反对 1”,所以它不能帮助我像你所说的那样识别它。
    • 其他的有稍微不同意1、稍微同意1、无等值,不一样。但是,如果您在页面上还有其他元素,而不仅仅是描述 - 请提供完整信息,以便我们为您提供正确答案
    • 我知道问这个问题太费劲了,但你可以去“supercareer.com”,然后对 Personality under Assessments 进行评估,看看我到底在说什么。注意:不必是真实邮件,只需单击即可注册,无需验证即可访问我正在谈论的问题。这是就我的问题提供 100% 信息的唯一方法。
    【解决方案3】:

    所以让我们这样理解:

    1. 每个问题都有一个反应部分。
    2. 每个反应部分都有多个反应按钮/图标。

    我遇到过这样的情况,需要通过以下方式处理:

    public void reactToQuestion(字符串问题,字符串反应){ // 获取问题元素 // 例如。问题=“我总是完成我工作的各个方面。” By locQuestion = By.xpath("//*[text()='" + question + "']"); WebElement 元素 = driver.findElement(locQuestion); // 获取问题的父 'div' 容器 WebElement 容器 = element.findElement(".."); // 获得对问题的相对反应 // 反应 = 'strongly-disagree1'、'slightly-disagree1' 等。 By locReaction = By.xpath(".//*[@class='inputs']/input[@data-scv-reaction-id="+reaction +"]"); WebElement 反应 = container.findElement(locReaction); 反应.click(); }

    如果有任何问题,请尝试让我知道。

    祝你好运。

    【讨论】:

    • 我没试过,但我的问题也是这个,你不能通过文本定位问题,因为问题会通过随机化 5 x 5 出现。唯一不变的是元素的位置(xpaths)。基本上,每一页,我从 20 个问题池中随机抽取 5 个问题。(问题是相同的,但由于它是随机的,因此很难通过文本找到它)
    • 根据您定义的问题陈述,请求的解决方案是“定位情感图标”。您可以修改方法以任何方式定位问题。但问题的症结在于,您只能定位与“定位问题”相关的情感图标。
    • 不幸的是,到目前为止,我无法解决这个问题。我什至尝试了不同的 webdriver / 版本,因为我没有任何问题可以找到任何容器或元素。无论如何,如果有人愿意弄脏他们的手,我想给一个测试帐户。
    • 当然可以。在 github 上发布一个测试项目或在linkedin/twitter 上给我发消息。我的 SO 个人资料页面上的详细信息。
    【解决方案4】:

    作为一个通用的 xpath,第一个输入来自问题,它可能是这样的:

    //form[@id='questionform']/div//input
    

    如果您需要任何input 来解决某个问题:

    //form[@id='questionform']/div[contains(@class, 'happiness-reaction')]//input
    

    如果您需要某个问题的某个答案,那么:

    //form[@id='questionform']/div[contains(@class, 'happiness-reaction')]//input[@data-scv-reaction-id='strongly-disagree1']
    

    如果您需要为问题和/或答案添加参数,那么:

    //form[@id='questionform']/div[contains(@class, 'part_of_question_class')]//input[@data-scv-reaction-id='desired_answer_attr']
    

    这些参数可以存储在数组/列表或任何你喜欢的形式。

    所有这些都可以在 css 中完成:

    form#questionform>div input
    form#questionform>div[class*=happiness-reaction] input
    form#questionform>div[class*=happiness-reaction] input[data-scv-reaction-id='strongly-disagree1']
    

    你明白了。

    【讨论】:

    • 我还没有尝试解决问题作为您的最后一个建议 (css) ,但仍然无法通过 Xpath 单击它。我也尝试过您的 xpath 格式,无论我做什么,硒的行为就像“驱动程序已成功找到并单击了元素”。
    【解决方案5】:

    以下是我用来保持 xpath 简洁且更易于更改的几个技巧。

    1. 您可以通过在 xpath 末尾添加 .. 来引用比您要选择的元素更深的元素。例如,我会使用&lt;i class="x" /&gt; 来区分要点击的内容,然后使用.. 选择父&lt;label /&gt;

    2. 您可以在 xpath 中间使用// 作为通配符来浏览不感兴趣的元素。

    例如:By.xpath("//form[@id='questionform']//i[@class='sc-strongly-disagree']/..")

    【讨论】:

      猜你喜欢
      • 2016-11-26
      • 1970-01-01
      • 2021-11-09
      • 2016-03-02
      • 2020-03-16
      • 2015-04-25
      • 2021-12-20
      • 2014-01-04
      • 1970-01-01
      相关资源
      最近更新 更多