0

我正在尝试制作一个 Selenium 测试脚本,用于检查在提交包含错误值的表单时是否出现引导验证弹出框。

我下面的脚本返回此错误:

org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#amount"}

相关代码:

WebDriver driver = new ChromeDriver()
WebElement field = driver.findElement(By.id("amount"));  //errors here every execution
Boolean is_valid = (Boolean)WebUI.executeScript("return arguments[0].checkValidity();", field);

if (!is_valid) {
     //intentionally fail test
}

当我检查表单字段时,我看到idequals amount,为什么我无法在 Selenium 中找到这个元素?

关于 SO 的相关问题

在此处输入图像描述

编辑 这是我为简洁起见省略的完整脚本:

WebUI.openBrowser('')

WebUI.navigateToUrl('Foo')

WebUI.setText(findTestObject('Object Repository/Page_bar/input_concat(Recipient, , s email address)_email'), 'fakepersonaluser1@example.com')

WebUI.setText(findTestObject('Object Repository/Page_bar/input_Amount (USD)_amount'), '10001')

WebUI.click(findTestObject('Object Repository/Page_bar/button_Send Payment'))

 
WebDriver driver = new ChromeDriver() WebElement field =
driver.findElement(By.id("amount")); Boolean is_valid =
(Boolean)WebUI.executeScript("return arguments[0].checkValidity();", field);

if (!is_valid) { //intentionally fail test }

WebUI.closeBrowser()

完整的 HTML:

<body cz-shortcut-listen="true">
    <div id="__nuxt"><!----><div id="__layout"><div data-v-f1473ce4=""><header data-v-7ea66436="" data-v-f1473ce4="" class="sr-header"><div data-v-7ea66436="" class="custom-container"><div data-v-7ea66436="" class="header-wrap"><div data-v-7ea66436="" class="row"><div data-v-7ea66436="" class="col-6"><div data-v-7ea66436="" class="header-left d-flex align-items-center"><span data-v-7ea66436="" class="d-block d-md-none mobile-menu-trigger"><i data-v-7ea66436="" class="fa-solid fa-bars"></i></span> <a data-v-7ea66436="" href="/" class="nuxt-link-active"><img data-v-7ea66436="" src="/images/logo-icon.png" alt="" class="sr-logo"></a> <div data-v-7ea66436="" class="user-portal d-none d-md-block"><ul data-v-7ea66436="" class="sr-nav nav"><li data-v-7ea66436=""><a data-v-7ea66436="" href="/" class="active nuxt-link-active">Dashboard</a></li></ul></div></div></div> <div data-v-7ea66436="" class="col-6"><div data-v-7ea66436="" class="sr-user-profile position-relative d-flex justify-content-end align-items-center h-100"><span data-v-7ea66436="" class="position-relative notification-icon"><!----> <img data-v-7ea66436="" src="/images/bxs-bell.svg" alt=""></span> <ul data-v-7ea66436="" class="snapr-notification"><li data-v-7ea66436="" class="d-flex align-items-center justify-content-between"><p data-v-7ea66436="">You have no unseen notifications</p></li></ul> <div data-v-7ea66436="" class="sr-profile clearfix"><img data-v-7ea66436="" src="https://storage.googleapis.com/snapr-dev.appspot.com/images/aXmr0zJOqqhOTBpPenxgerP3CNH3.jfif" alt="" class="avatar"> <a data-v-7ea66436="" href="/" class="d-none d-md-inline-block nuxt-link-active">Mark</a> <ul data-v-7ea66436="" class="sr__profile-links"><li data-v-7ea66436=""><a data-v-7ea66436="" href="/profile" class="">Settings</a></li> <li data-v-7ea66436=""><a data-v-7ea66436="" href="javascript:void(0)">Logout</a></li></ul></div></div></div></div></div></div></header> <main data-v-f1473ce4="" class="sr__main-body"><div data-v-f1473ce4="" class="custom-container"><h2 data-v-f1473ce4="" class="text-white mb-1">Welcome, Test Biz</h2> <p data-v-f1473ce4="" class="mb-4 mb-md-0">SnapRefund is fast, simple, and secure</p> <div data-v-f1473ce4="" class="body-wrapper clearfix"><div data-v-f00dedfc="" data-v-f1473ce4="" class="d-flex flex-wrap sr__profile-tabs mb-xl-5 justify-content-center"><a data-v-f00dedfc="" href="javascript:void(0)" class="closePosition closeBtn"><i data-v-f00dedfc="" class="fa fa-close fa-2x" aria-hidden="true"></i></a> <a data-v-f00dedfc="" href="/send-payment" aria-current="page" class="sr__tab nuxt-link-exact-active nuxt-link-active"><div data-v-f00dedfc="" class="d-flex align-items-center"><span data-v-f00dedfc="" class="icon-box"><img data-v-f00dedfc="" src="/images/ionic-ios-send.svg" alt=""></span> <span data-v-f00dedfc="" class="sr__tab-title">Send <br data-v-f00dedfc=""> Payment</span></div></a> <a data-v-f00dedfc="" href="/pending-payment" class="sr__tab"><div data-v-f00dedfc="" class="d-flex align-items-center"><span data-v-f00dedfc="" class="icon-box"><img data-v-f00dedfc="" src="/images/open-reload.svg" alt=""></span> <span data-v-f00dedfc="" class="sr__tab-title">Pending <br data-v-f00dedfc="">Payments</span></div></a> <a data-v-f00dedfc="" href="/transactions" class="sr__tab"><div data-v-f00dedfc="" class="d-flex align-items-center"><span data-v-f00dedfc="" class="icon-box"><img data-v-f00dedfc="" src="/images/ionic-ios-paper.svg" alt=""></span> <span data-v-f00dedfc="" class="sr__tab-title">Transaction <br data-v-f00dedfc="">History</span></div></a> <a data-v-f00dedfc="" href="/bank-card" class="sr__tab"><div data-v-f00dedfc="" class="d-flex align-items-center"><span data-v-f00dedfc="" class="icon-box"><img data-v-f00dedfc="" src="/images/ionic-ios-card.svg" alt=""></span> <span data-v-f00dedfc="" class="sr__tab-title">Banks &amp;<br data-v-f00dedfc="">Cards</span></div></a> <a data-v-f00dedfc="" href="/my-wallet" class="sr__tab"><div data-v-f00dedfc="" class="d-flex align-items-center"><span data-v-f00dedfc="" class="icon-box"><img data-v-f00dedfc="" src="/images/ionic-ios-wallet.svg" alt=""></span> <span data-v-f00dedfc="" class="sr__tab-title">Wallet</span></div></a> <a data-v-f00dedfc="" href="/my-preference" class="sr__tab"><div data-v-f00dedfc="" class="d-flex align-items-center"><span data-v-f00dedfc="" class="icon-box"><img data-v-f00dedfc="" src="/images/ionic-ios-settings.svg" alt=""></span> <span data-v-f00dedfc="" class="sr__tab-title">Preferences</span></div></a></div> <div data-v-f1473ce4="" class="body-content"><div data-v-f1473ce4="" class="row"><div data-v-f896e768="" data-v-f1473ce4="" class="col-xl-6 offset-xl-3 px-xl-5"><div data-v-f896e768="" class="sr__send-payment-card sr__card"><h2 data-v-f896e768="" class="text-white text-center">Send a Payment</h2> <p data-v-f896e768="" class="text-center mb-5">Fast. Simple. Secure.</p> <form data-v-f896e768=""><div data-v-f896e768="" class="mb-4"><label data-v-f896e768="" for="email" class="d-block">Recipient's email address</label> <input data-v-f896e768="" type="text" id="email" placeholder="recipient@example.com" name="email" required="required" class="d-block w-100"></div> <div data-v-f896e768="" class="mb-5"><label data-v-f896e768="" for="amount" class="d-block">Amount (USD)</label> <div data-v-f896e768="" class="position-relative adjust-dollar-sign"><input data-v-f896e768="" type="number" id="amount" placeholder="0.00" step=".01" min="0" max="10000" name="amount" required="required" class="d-block w-100"> <i data-v-f896e768="" class="fa-solid fa-dollar-sign"></i></div></div> <div data-v-f896e768="" class="d-flex justify-content-center"><button data-v-f896e768="" type="submit" class="sr__button me-3">Send Payment</button></div></form></div></div></div></div></div></div></main></div></div></div><script>window.__NUXT__=function(t){return{staticAssetsBase:"/_nuxt/static/1645950364",layout:"default",error:t,state:t,serverRendered:!1,routePath:"/",config:{_app:{basePath:"/",assetsPath:"/_nuxt/",cdnURL:t}}}}(null)</script><script src="/_nuxt/aee8d4c.js" defer=""></script><script src="/_nuxt/31db832.js" defer=""></script><script src="/_nuxt/b069f1c.js" defer=""></script><script src="/_nuxt/b379d09.js" defer=""></script>
  

<div id="ryq5aiihF" role="status" aria-live="polite" aria-atomic="false" class="toasted-container top-right fit-to-screen"></div></body>
4

2 回答 2

1

弹出框是HTML5 约束验证消息,它是约束 API 的 element.setCustomValidity()方法的结果。

要检索文本值必须小于或等于 10000。您需要为elementToBeClickable()引入WebDriverWait ,并且可以使用以下任一定位器策略

  • 使用cssSelector

    WebElement amount = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("input#amount[name='amount']")));
    System.out.println(amount.getAttribute("validationMessage"));
    
  • 使用xpath

    WebElement amount = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[@id='amount' and @name='amount']")));
    System.out.println(amount.getAttribute("validationMessage"));
    

由于它是<label>一种替代元素,您还可以尝试以下定位器策略

  • 使用cssSelector

    WebElement amount = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("label[for='amount']")));
    System.out.println(amount.getAttribute("validationMessage"));
    
  • 使用xpath

    WebElement amount = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//label[@for='amount']")));
    System.out.println(amount.getAttribute("validationMessage"));
    

相反,您也可以尝试visibilityOfElementLocated()如下:

  • 使用cssSelector

    WebElement amount = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("label[for='amount']")));
    System.out.println(amount.getAttribute("validationMessage"));
    
  • 使用xpath

    WebElement amount = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//label[@for='amount']")));
    System.out.println(amount.getAttribute("validationMessage"));
    

参考

您可以在以下位置找到一些相关的详细讨论:

于 2022-02-27T18:58:16.647 回答
0

根据您在问题中提供的代码,您甚至在打开您尝试处理的网页之前就尝试访问 Web 元素。
如果您只是省略driver.get(the_page_url)了代码填写和提交表单,则此处的错误可能是由多种原因引起的:

  1. 你错过了一个延迟。单击提交按钮后,您无法立即找到弹出窗口,弹出窗口需要一些时间才能出现。这里的首选方法是使用预期条件显式等待,如下所示:
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement field = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("amount")));
  1. 您尝试访问的元素位于 iframe 内。
    在这种情况下,您必须先切换到该 iframe 才能访问其中的元素,如下所示:
driver.switchTo().frame(driver.findElement(By.id(the_iframe_id)));

然后继续

WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement field = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("amount")));

为了给您更好的答案,我们必须查看您正在处理的页面,查看所有实际代码并调试那里实际发生的情况。

于 2022-02-27T12:01:03.050 回答