【问题标题】:org.openqa.selenium.ElementNotVisibleException: element not interactable on radio buttonsorg.openqa.selenium.ElementNotVisibleException:单选按钮上的元素不可交互
【发布时间】:2019-10-19 03:07:45
【问题描述】:

我查看了所有以前的解决方案,但似乎没有任何帮助。你是我唯一的希望欧比万。任何建议将不胜感激。谢谢。

我正在为我们的网站编写一些迟来的集成测试。这是一项评估数百个问题的评估,每个问题都要求用户使用单选按钮从 x 个答案中选择一个。当我点击这些单选按钮之一时,我收到错误消息:

org.openqa.selenium.ElementNotVisibleException: element not interactable
  (Session info: chrome=74.0.3729.169)
  (Driver info: chromedriver=74.0.3729.6     (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729@{#29}),platform=Windows

...

我已经尝试更新到最新的 ChromeDriver 和 Selenium、添加等待、验证我有正确的按钮等。

我也尝试过 Gecko 驱动程序并收到此错误:

org.openqa.selenium.ElementNotInteractableException: 元素 无法滚动到视图中

我正在浏览的 HTML(片段):

  <td width="100%" align="left">
    <table cellpadding="0" cellspacing="0">
      <tbody>
        <tr>
          <td valign="middle"><span class="radio"
            style="background-position: 0px -80px;"></span><input
            tabindex="5" type="radio"
            style="align: center; vertical-align: middle;"
            class="styled" name="PID9.QID1.RID1" id="PID9.QID1.RID1"
            value="6"></td>
          <td valign="middle"><span class="std_size2">&nbsp;&nbsp;</span></td>
          <td valign="middle"><span class="std_size2">Married</span></td>
        </tr>
      </tbody>
    </table>
  </td>

测试代码(包括我评论的一些替代尝试):

private String doAssesment()
{
    assertTrue(driver.getTitle().equals("Couple Assessment"));

    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    WebElement decisionTree = driver.findElement(By.name("decision_tree"));
    List<WebElement> inputs = decisionTree.findElements(By.tagName("input"));

    for (WebElement button : inputs)
    {
        System.out.println("type=" + button.getAttribute("type"));
        if (button.getAttribute("type").equals("radio"))
        {
            // wait.until(ExpectedConditions.visibilityOf(button));
            // new Actions(driver).moveToElement(button).perform();

            button.click();
            break;
        }
    }

    return driver.getTitle();
}

我看到的一个可能的问题是单选按钮注入了 onchange javascript(这是正确的术语吗?)。

Javascript:

var Custom = {
  init: function() {
    var inputs = document.getElementsByTagName("input"),
      span = Array(),
      textnode, option, active;
    for (a = 0; a < inputs.length; a++) {
      if ((inputs[a].type == "checkbox" || inputs[a].type == "radio") && inputs[a].className == "styled") {
        span[a] = document.createElement("span");
        span[a].className = inputs[a].type;

        if (inputs[a].checked == true) {
          if (inputs[a].type == "checkbox") {
            position = "0 -" + (checkboxHeight * 2) + "px";
            span[a].style.backgroundPosition = position;
          } else {
            position = "0 -" + (radioHeight * 2) + "px";
            span[a].style.backgroundPosition = position;
          }
        }
        inputs[a].parentNode.insertBefore(span[a], inputs[a]);
        inputs[a].onchange = Custom.clear;
        span[a].onmousedown = Custom.pushed;
        span[a].onmouseup = Custom.check;
        document.onmouseup = Custom.clear;
      }
    }
    inputs = document.getElementsByTagName("select");
    for (a = 0; a < inputs.length; a++) {
      if (inputs[a].className == "styled") {
        option = inputs[a].getElementsByTagName("option");
        active = option[0].childNodes[0].nodeValue;
        textnode = document.createTextNode(active);
        for (b = 0; b < option.length; b++) {
          if (option[b].selected == true) {
            textnode = document.createTextNode(option[b].childNodes[0].nodeValue);
          }
        }
        span[a] = document.createElement("span");
        span[a].className = "select";
        span[a].id = "select" + inputs[a].name;
        span[a].appendChild(textnode);
        inputs[a].parentNode.insertBefore(span[a], inputs[a]);
        inputs[a].onchange = Custom.choose;
      }
    }
  },
  pushed: function() {
    element = this.nextSibling;
    if (element.checked == true && element.type == "checkbox") {
      this.style.backgroundPosition = "0 -" + checkboxHeight * 3 + "px";
    } else if (element.checked == true && element.type == "radio") {
      this.style.backgroundPosition = "0 -" + radioHeight * 3 + "px";
    } else if (element.checked != true && element.type == "checkbox") {
      this.style.backgroundPosition = "0 -" + checkboxHeight + "px";
    } else {
      this.style.backgroundPosition = "0 -" + radioHeight + "px";
    }
  },
  check: function() {
    element = this.nextSibling;
    if (element.checked == true && element.type == "checkbox") {
      this.style.backgroundPosition = "0 0";
      element.checked = false;
    } else {
      if (element.type == "checkbox") {
        this.style.backgroundPosition = "0 -" + checkboxHeight * 2 + "px";
      } else {
        this.style.backgroundPosition = "0 -" + radioHeight * 2 + "px";
        group = this.nextSibling.name;
        inputs = document.getElementsByTagName("input");
        for (a = 0; a < inputs.length; a++) {
          if (inputs[a].name == group && inputs[a] != this.nextSibling) {
            inputs[a].previousSibling.style.backgroundPosition = "0 0";
          }
        }
      }
      element.checked = true;
    }
  },
  clear: function() {
    inputs = document.getElementsByTagName("input");
    for (var b = 0; b < inputs.length; b++) {
      if (inputs[b].type == "checkbox" && inputs[b].checked == true && inputs[b].className == "styled") {
        inputs[b].previousSibling.style.backgroundPosition = "0 -" + checkboxHeight * 2 + "px";
      } else if (inputs[b].type == "checkbox" && inputs[b].className == "styled") {
        inputs[b].previousSibling.style.backgroundPosition = "0 0";
      } else if (inputs[b].type == "radio" && inputs[b].checked == true && inputs[b].className == "styled") {
        inputs[b].previousSibling.style.backgroundPosition = "0 -" + radioHeight * 2 + "px";
      } else if (inputs[b].type == "radio" && inputs[b].className == "styled") {
        inputs[b].previousSibling.style.backgroundPosition = "0 0";
      }
    }
  },
  choose: function() {
    option = this.getElementsByTagName("option");
    for (d = 0; d < option.length; d++) {
      if (option[d].selected == true) {
        document.getElementById("select" + this.name).childNodes[0].nodeValue = option[d].childNodes[0].nodeValue;
      }
    }
  }
}
window.onload = Custom.init;

<
/script>

【问题讨论】:

  • 我认为我们需要查看实际的页面。我猜表格可以滚动,当 selenium 向下滚动页面以到达元素时,它不会滚动表格,导致您尝试单击的元素不“可见”。

标签: selenium radio-button selenium-chromedriver selenium-firefoxdriver


【解决方案1】:

原来单选按钮位于“隐藏”按钮的跨度中。将代码更改为在跨度中单击,它似乎正在工作。

    private String doAssesment()
{
    assertTrue(driver.getTitle().equals("Couple Assessment"));

    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

    WebElement decisionTree = driver.findElement(By.name("decision_tree"));
    List<WebElement> inputs = decisionTree.findElements(By.className("radio"));
    WebElement button = inputs.get(4);

    button.click();

    return driver.getTitle();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-03
    • 2014-11-13
    • 1970-01-01
    • 2021-09-22
    • 1970-01-01
    相关资源
    最近更新 更多