如何使用 Selenium 和 Java 定位约束验证文本

发布于 2025-01-10 06:44:39 字数 9555 浏览 0 评论 0原文

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

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

org.openqa.selenium.NoSuchElementException:没有这样的元素:无法定位元素:{“method”:“css选择器”,“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
}

当我检查表单字段时,我看到 < code>id 等于 amount,那为什么我在 Selenium 中找不到这个元素呢?

输入图片此处描述

这是我的完整脚本:

WebUI.openBrowser('')

WebUI.navigateToUrl('Foo')

WebUI.setText(findTestObject('Object Repository/Page_bar/input_concat(Recipient, , s email address)_email'), '[email protected]')

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="[email protected]" 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>

相关问题:如何获取文本Selenium 中的 HTML5 输入字段错误消息?

I'm trying to make a Selenium test script that checks if a bootstrap validation popover appears when submitting a form containing a bad value.

My script below returns this error:

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

Relevant code:

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
}

When I inspect the form field, I see the id equals amount, so why am I unable to find this element in Selenium?

enter image description here

Here's my full script:

WebUI.openBrowser('')

WebUI.navigateToUrl('Foo')

WebUI.setText(findTestObject('Object Repository/Page_bar/input_concat(Recipient, , s email address)_email'), '[email protected]')

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()

Full 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 &<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="[email protected]" 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>

Related Question: How to get the text from the HTML5 input field error message in Selenium?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦在夏天 2025-01-17 06:44:39

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

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

  • 使用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"));
    

由于它是一个 元素作为替代方案,您还可以尝试以下 定位策略

  • 使用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"));
    

参考

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

The popover is the HTML5 Constraint validation message which is the outcome of Constraint API's element.setCustomValidity() method.

To retrieve the text Value must be less than or equal to 10000. you need to induce WebDriverWait for the elementToBeClickable() and you can use either of the locator strategies:

  • Using cssSelector:

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

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

As it is a <label> element as an alternative you can also try the following locator strategies:

  • Using cssSelector:

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

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

Instead you can also try for the visibilityOfElementLocated() as follows:

  • Using cssSelector:

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

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

References

You can find a couple of relevant detailed discussion in:

他不在意 2025-01-17 06:44:39

根据您在问题中提供的代码,您甚至在打开您要处理的网页之前尝试访问网络元素。
如果您刚刚省略了 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")));

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

According to the code you presenting in the question you are trying to access a web element before even opening the web page you are trying to work on.
In case you just omitted driver.get(the_page_url) and the code filling and submitting the form the error here may be caused by several causes:

  1. You are missing a delay. You can not locate the pop-up immediately after clicking the submit button, it takes some short time for pop-up to appear. The preferred approach here is to use Expected Conditions explicit waits, something like this:
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement field = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("amount")));
  1. The elements you are trying to access are inside an iframe.
    In this case you will have to switch into that iframe first in order to access elements inside it, as following:
driver.switchTo().frame(driver.findElement(By.id(the_iframe_id)));

and then continue with

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

To give you better answer we have to see the page you are working on, to see all your actual code and to debug what actually happens there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文