Reputation: 1879
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?
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?
Upvotes: 0
Views: 577
Reputation: 193188
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"));
You can find a couple of relevant detailed discussion in:
Upvotes: 1
Reputation: 33361
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:
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement field = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("amount")));
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.
Upvotes: 0