I am working on finding a solution how to generate a Selenium locator to an element:
<a name="page" data-role="button" data-mini="true" data-inline="true" href="https://blablabla/bla/bla/bla/?formTemplatesList_start=120" data-aid="paginator-link-last">Last</a>
My ideas:
#FindBy(how = How.PARTIAL_LINK_TEXT, using = "paginator-link-last")
public WebElement lastTemplateButton;
#FindBy(how = How.XPATH, using = "//a[#data-aid='paginator-link-last']")
public WebElement lastTemplateButton;
It does not work... I have no other ideas.
I receive NULL POINTER EXCEPTION when I run:
public void selectTemplateToEdit() {
CustomWaitImpl.waitForElementDisplayed(editEvalTemplateLocators.getLastTemplateButton());
editEvalTemplateLocators.getLastTemplateButton().click();
}
can you try the following:
#FindBy(how = How.XPATH, using = "//a[#data-aid = 'paginator-link-last']")
Public WebElement lastTemplateButton;
OR
#FindBy(how = How.XPATH, using = "//a[#data-aid = 'paginator-link-last' and contains(text(), Last]")
Public WebElement lastTemplateButton;
If any of it works, I would recommend just removing the, how = How.XPATH and simply just doing the following code below as a reference:
#FindBy(using = "//a[#data-aid = 'paginator-link-last' and contains(text(), Last]")
Try with this xpath and also use webDrver wait
//a[contains(text(),'Last')]
Related
I am trying to fetch the text ($315.50) from:
<td id="balance" class="ng-binding">$315.50</td>
I am not succeeding though, I have tried:
#FindBy(how = How.CSS, using = "#balance")
private WebElement balance;
and
#FindBy(how = How.ID, using = "#balance")
private WebElement balance;
With these selectors I than do:
System.out.println("Balance" + balance)
as result I get
Balance[[ChromeDriver: chrome on WINDOWS (4ccbccdb5b54de0526e0ec68db88a48c)] -> css selector: #balance]
Or if try to do something else with it, I get errors saying that the methods receives an empty string.
For other elements in my test framework I can do manage to fetch the text from elements. The general setup does not seem to be the problem. Anyone an idea what I am doing wrong in this specific example?
Considering the HTML:
<td id="balance" class="ng-binding">$315.50</td>
To identify the element you can use either of the following locator strategies:
Using id:
#FindBy(how = How.ID, using = "balance")
private WebElement balance;
Using cssSelector:
#FindBy(how = How.CSS, using = "td#balance")
private WebElement balance;
Using xpath:
#FindBy(how = How.XPATH, using = "//td[#id='balance']")
private WebElement balance;
To print the text:
Using getText():
System.out.println(balance.getText())
Using getAttribute("innerHTML"):
System.out.println(balance.getAttribute("innerHTML"))
Using getAttribute("innerText"):
System.out.println(balance.getAttribute("innerText"))
Using getAttribute("textContent"):
System.out.println(balance.getAttribute("textContent"))
I have been trying to check if an image is displayed on my page using the image id. I have looked through similar posts but cannot find one that solves my problem.
I don't know why my error message says css selector, I am trying to find the element using its id.
Any ideas would be great, thanks?
Test:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
IWebElement BannerImageElement = driver.FindElement(By.Id("HomePageBanner"));
driver.Navigate().GoToUrl(HomeUrl);
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
Assert.True(BannerImageElement.Displayed);
}
Index.cshtml
#model HomeViewModel
#{
ViewData["Title"] = _loc[Model.PageTabTitle];
}
<div class="text-center">
#section header_image{
<div class="bg-img" id="HomePageBanner">
}
</div>
</div>
_Layout.cshtml
<body>
<header>
#RenderSection("header_image", required: false)
</header>
</body>
Error:
Message:
OpenQA.Selenium.NoSuchElementException : no such element: Unable to locate element: {"method":"css selector","selector":"#HomePageBanner"}
(Session info: chrome=83.0.4103.61)
Stack Trace:
RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
RemoteWebDriver.FindElement(String mechanism, String value)
RemoteWebDriver.FindElementById(String id)
<>c__DisplayClass16_0.<Id>b__0(ISearchContext context)
By.FindElement(ISearchContext context)
RemoteWebDriver.FindElement(By by)
TestHomepageComponentsArePresent.CheckBannerImage() line 21
A few words:
Ideally, you need to start finding the WebElement only after you invoke Navigate().GoToUrl(). So the sequence would be:
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = driver.FindElement(By.Id("HomePageBanner"));
Though you have declared an instance of WebDriverWait as wait you but haven't utilized it while looking out for the element.
Finally, as per the discussion in Official locator strategies for the webdriver other then xpath all the other locator strategies are converted in to css-selectors while execution.
Solution
To check if an image is displayed on the webpage you have to induce WebDriverWait for the ElementIsVisible and you can use either of the following solutions:
Using Id:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.Id("HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
}
Using CssSelector:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.CssSelector("#HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
}
Using XPath:
public void CheckBannerImage()
{
var UrlRefLibrary = new UrlStrings();
string HomeUrl = UrlRefLibrary.GetHomePageLocalHostUrl();
using IWebDriver driver = new ChromeDriver();
driver.Navigate().GoToUrl(HomeUrl);
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='HomePageBanner']")));
Assert.True(BannerImageElement.Displayed);
}
Update
Incase you are using nuget packages you need to use SeleniumExtras.WaitHelpers.ExpectedConditions as follows:
Using Id:
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.Id("HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
Using CssSelector:
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.CssSelector("#HomePageBanner")));
Assert.True(BannerImageElement.Displayed);
Using XPath:
IWebElement BannerImageElement = new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementIsVisible(By.XPath("//*[#id='HomePageBanner']")));
Assert.True(BannerImageElement.Displayed);
References
You can find a couple of relevent discussions in:
WebDriverWait is not waiting for the element I specify
ExpectedConditions.ElementIsVisible returns TimeoutException even when element is present
I have radio buttons that when either radio button is selected, it gets a checked attribute.
This is how the HTML looks:
My implementation of getting the descendant that has a checked attribute:
public TestObject getCheckedTestObjectFromParent(String parentID){
WebDriver driver = DriverFactory.getWebDriver()
WebElement parentWebElement = driver.findElement(By.id(parentID))
List<WebElement> children = parentWebElement.findElements(By.xpath(".//*"))
println(children.size())
for(int i = 0; i < children.size(); i++){
TestObject childTestObject = getTestObjectFromWebElement(children[i])
if(WebUI.verifyElementHasAttribute(childTestObject, 'checked', 10, FailureHandling.OPTIONAL)){
return childTestObject
}
}
}
This is the helper method that I use for converting a WebElement to a TestObject :
public TestObject getTestObjectFromWebElement(WebElement element) {
TestObject object = new TestObject()
object.addProperty("xpath", ConditionType.CONTAINS, getXPathFromElement(element))
return object
}
Helper for getting xpath from WebElement :
protected String getXPathFromElement(WebElement element) {
String elementDescription = element.toString();
return elementDescription.substring(elementDescription.lastIndexOf("-> xpath: ") + 10, elementDescription.lastIndexOf("]"));
}
Am I missing something here or is there something wrong with the WebElement -> TestObject conversion? Also is this possible using only TestObject or only WebElement? If I could get child TestObjects containing certain attributes from a parent TestObject then I wouldn't need to make a mess using WebElements.
Edit
Another image of the HTML, this time with the first radio button checked. As you can see the second radio button no longer has the 'checked' attribute.
To retrieve the WebElement that is currently checked you can use either of the following Locator Strategies:
cssSelector:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.a-toggle.a-toggle--anycase#config-src-laserunits div[id^='config-src-laserunits-']>input.a-toggle__radio[checked]")));
xpath:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#class='a-toggle a-toggle--anycase' and #id='config-src-laserunits']//div[starts-with(#id, 'config-src-laserunits-')]/input[#class='a-toggle__radio' and #checked]")));
I was able to fix this by changing (".//*") to (".//*[#checked='checked']")
parentWebElement.findElement(By.xpath(".//*[#checked='checked']")
will find the element that has the attribute checked = 'checked'
Notice that a list is no longer needed as there can only be 1 checked radio button at a time.
Implementation
public TestObject getCheckedTestObjectFromParent(String parentID){
WebDriver driver = DriverFactory.getWebDriver()
WebElement parentWebElement = driver.findElement(By.id(parentID))
//there is only 1 checked child at a time, so there is no need for a list
WebElement checkedChild = parentWebElement.findElement(By.xpath(".//*[#checked='checked']"))
//convert the WebElement to a TestObject and return
return getTestObjectFromWebElement(checkedChild)
}
Try this Xpath
"//input[#id='config-src-laserunits-wavnmradio' and #checked='checked']"
Example:
List<WebElement> children = driver.findElements(By.xpath("//input[#id='config-src-laserunits-wavnmradio' and #checked='checked']"))
It should return size 1
EDIT
List<WebElement> children = driver.findElements(By.xpath("//input[#id='config-src-laserunits-wavnmradio']"));
for (int i=0;i<children.size();i++)
{
if(children.get(i).getAttribute("checked")!=null)
{
System.out.println("radio button is checked");
}
}
From the following HTML code
<div class="message-main-contents">
<div class="message-title">Title Message</div>
<div class="message-content">
<div class="licenseexpiryannouncement">
<div>
Message Content 1
<a class="licenseexpiryannouncement-installlicenselink">Link that can be clicked</a>
under Home> Upload.
</div>
<div>Message Content 2</div>
</div>
</div>
I am trying to retrieve the "Title Message" text using the following code but is returning empty string
#FindBy(how = How.XPATH, using = "//div[contains(#class, 'message-title')]")
private WebElement contentMessageTitle;
String titleMessage = contentMessageTitle.getText();
System.out.println(titleMessage);
I have also encountered this sometimes in my code that the getText() method do not return you with the text and instead return an empty string. I have found a workaround for this by reading the attribute value "textContent".
you can read the text using a workaround
String titleMessage = contentMessageTitle.getAttribute("textContent");
This way you can read the content of the 'contentMessageTitle' locator.
Here is the Answer to your Question:
#FindBy(how = How.XPATH, using = "//div[#class='message-title']")
private WebElement contentMessageTitle;
String titleMessage = contentMessageTitle.getText();
System.out.println(titleMessage);
or
#FindBy(how = How.XPATH, using = "//div[#class='message-main-contents']/div[#class='message-title']")
private WebElement contentMessageTitle;
String titleMessage = contentMessageTitle.getText();
System.out.println(titleMessage);
or
#FindBy(how = How.XPATH, using = "//div[#class='message-main-contents']/div[#class='message-title']")
private WebElement contentMessageTitle;
String titleMessage = contentMessageTitle.getAttribute("text");
System.out.println(titleMessage);
Let me know if this Answers your Question.
Hi i want to get value of html element using web driver how can i get it?I am explaining the scenario as below. I have a span element as below with value between the starting and closing tag .How can i get it?
<span id="foo">
some value
</span>
You have to use the webElement.getText() for that.
I worte a small unit test for you:
public class TestGetText
{
#Test
public void shouldReadSomevalue()
{
final WebDriver webDriver = new HtmlUnitDriver();
webDriver.get("http://s2server.de/stackoverflow/11719445.html");
final WebElement webElement = webDriver.findElement(By.id("foo"));
final String text = webElement.getText();
assertEquals("some value", text);
}
}
Try below solution -
String test = driver.findElement(By.id("lbHome")).getText();
System.out.println(test);
Try locating the element using XPath instead of ID, then using either
driver.findElement(By.xpath(“xpath for your lbl“)).getText()
or
String st = driver.findElement(By.xpath(“xpath to your lbl“)).getAttribute(“value”);
Source : SeleniumWiki