首页 > 解决方案 > Selenium 完全找不到可见和可交互的元素

问题描述

我有一个应用程序,它曾经在 Selenium 框架中具有 JavaScript 等待功能。但是,这会导致 Angular9 出现无法解决的问题,因此必须将其删除以替换为更好的东西。

现在我正在努力解决 Selenium 100% 无法找到明显可见和可交互的元素。当我单步执行代码时,在单击元素的行处中断,它工作正常。但即使使用 WebdriverWait,手动运行代码时也永远找不到它。

标记:

<app-grafikk-radio>
 <hb-felt>
  <div translate="" class="hb-animation--appear hb-felt">
   <legend class="hb-legend" data-e2e-selector="hva-sporsmaal">
    <span translate="">Hva skal lånet/tilskuddet brukes til?</span>    
    <hb-hjelpetekst _nghost-ysl-c55="">    
     <div _ngcontent-ysl-c55="" class="hb-hjelpetekst">
      <button _ngcontent-ysl-c55="" type="button" class="hb-hjelpetekst-knapp" title="Åpne hjelpetekst"">
       <span _ngcontent-ysl-c55="">Åpne hjelpetekst</span><!----><!---->
       <hb-ikon _ngcontent-ysl-c55="" nghost-ysl-c56="">
        <span _ngcontent-ysl-c56="" class="hb-ikon hb-ikon-- >
         <svg _ngcontent-ysl-c56="" focusable="false">
          <use _ngcontent-ysl-c56="" xlink:href="images/sprite.symbol.svg#ikon-sporsmalstegn"></use>
         </svg>
        </span><!---->
       </hb-ikon>
      </button><!---->
     </div></hb-hjelpetekst><!---->
    </legend><!---->
    <ul class="hb-liste hb-liste--minimal hb-liste--hva">
     <li>
      <input type="radio" class="hb-grafikkradio ng-untouched ng-pristine ng-invalid" id="hva-KJOPE" data-e2e-selector="hva-KJOPE">
       <label class="hb-label" for="hva-KJOPE">Kjøpe bolig <span aria-hidden="true" class="hb-ikon hb-ikon--bolig-kjope">
        <svg focusable="false">
         <use xlink:href="/images/bolig-sprite.svg#ikon-bolig-kjope">
         </use>
        </svg>
       </span>
      </label>
     </li>
 <li>
  ...

Java/Selenium 代码:

@FindBy(id = "hva-KJOPE")
public WebElement kjopeBolig;

kjopeBolig.sendKeys(Keys.SPACE);
//kjopeBolig.click(); //sendKeys SPACE used because click() allmost always get the "ElementInterceptedError - other element would receive the click"

现在,如前所述,当单步执行 Java 代码并中断overtaBolig.sendKeys(Keys.SPACE);行时,它工作正常。

但是在正常运行时,它会导致

org.openqa.selenium.NoSuchElementException:没有这样的元素:无法找到元素:{“method”:“css selector”,“selector”:“#hva-KJOPE”}

我尝试等待元素可点击,如下所示:

WebDriverWait wait = new WebDriverWait(driver, 10); 
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(kjopeBolig));
element.click();

但这也行不通。它只是超时:

org.openqa.selenium.TimeoutException:预期条件失败:等待元素可点击:[[ChromeDriver: chrome on LINUX (5f31d37458a386bf0baea00a34aa3688)] -> id: hva-KJOPE](尝试 10 秒,间隔 500 毫秒)

有任何想法吗?我怀疑使用原始 JavaScript 等待方法是有原因的,但我能找到的人都不知道,代码已经有几年了。我可以尝试其他方法/技术吗?

编辑:经过更多测试,发现同一页面上的所有(单选)按钮都存在此问题。

标签: javaseleniumwebdriverwebdriverwait

解决方案


当我遇到这种情况时,我有时使用的一种方法是在 Chrome 中使用检查并通过完整的 Xpath 获取(我认为这有点 hacky,总是尽可能使用 uniqueID,但它通常会得到结果)。
要获取它,请加载 html 页面,使元素在 chrome 中可见-> 右键单击​​ -> 检查 - 如果它没有立即在元素上突出显示它,请再次单击右键检查 -> 将鼠标悬停在您想要的元素上检查中的元素菜单并右键单击元素->复制->完整Xpath(或ID,如果您想仔细检查您是否有正确的没有语法错误的)-然后将其粘贴到您的驱动程序中获取方法我不是熟悉它的注释版本,但是我倾向于使用它的静态实现,如下所示:

WebElement element = DRIVER.findElement(By.xpath("paste/xpathOrId/here"));
元素.click();

完成任务的类似方式,只是一条不同的路线,在检查时您应该检查的另一件事是您要单击的元素是否位于您想要的最低级别的子标签中,即如果它是跨度内的按钮,请确保它是您选择的按钮,因为有时容器内的元素在容器本身之后开始,并且 Selenium 单击该元素的最左上角有时单击会丢失,如果您是这种情况要么需要更改您选择的 id,要么使用 offset 方法手动更改点击发生的位置。


推荐阅读