How to pass dynamic value into xpath in selenium, java? - selenium

I have a website, where i open contract and get the unique contractId. Then, i need to go to other page and search this id in table with pagination. I wrote code which goes to next page if this requesid(it's a link) is not found and if it exist, it just opens this requestId. But there is a problem with initialization of webelement where i'm trying add dynamic value. Selenium gives error below and i have no idea how to solve it
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//span[#class='link__text' and text()='222254']/../../..//input"}
(Session info: chrome=89.0.4389.72)
contractId is the variable where i store dynamic value that changes every test run. This is how the code looks like:
csecp.waitForElementVisibility(csecp.getContractStatusEmergencyChangeHeader());
int totalPages = Integer.parseInt(csecp.getTotalPagesString().getText());
for(int i = 0; i < totalPages; i++) {
csecp.sleep(500);
if (**csecp.prepareWebElementWithDynamicXpath(csecp.getContractDynamicValue(),contractId).isDisplayed()**) {
csecp.prepareWebElementWithDynamicXpath(csecp.getContractDynamicValue(),contractId).click();
csecp.waitForElementVisibility(csecp.getConfirmAMLApprovalButton());
csecp.getConfirmAMLApprovalButton().click();
break;
}
csecp.waitForElementVisibility(csecp.getNextPageButton());
csecp.getNextPageButton().click();
}
This is how i'm trying to pass dynamic valueinto xpath
private String contractDynamicValue = "//span[#class='link__text' and text()='xxxxx']/../../..//input";
public WebElement prepareWebElementWithDynamicXpath (String xpathValue, String substitutionValue ) {
return getWebDriver().findElement(By.xpath(xpathValue.replace("xxxxx", substitutionValue)));
}

You can define and use this XPath locator as following:
String contractDynamicValue = "//span[#class='link__text' and text()='%s']/../../..//input";
public WebElement prepareWebElementWithDynamicXpath (String xpathTemplate, String substitutionValue ) {
String xpath = String.format(xpathTemplate,substitutionValue);
return getWebDriver().findElement(By.xpath(xpath));
}

See the xpath that you are using is
//span[#class='link__text' and text()='xxxxx']/../../..//input
and if you wanna make xxxxx as dynamic, you could do following :-
string sub_value = "222254";
//span[#class='link__text' and text()='"+sub_value+"']/../../..//input

It's always the best solution to get element by text and the following element. For dynamic elements, you can use XPath like
//div[.='Dummy_text']/following::span[text()='test_text']
You can see some tutorials from here
https://www.guru99.com/xpath-selenium.html

Related

Getting error while inserting Customized String in xpath in Webdriver

Iam trying to locate elements in a webpage. Elements are arranged in rows. For all the rows(or elements), the common attribute is "pfobj". With the help of list interface i have listed out all the elements having attribute pfobj. While finding element with xpath iam getting error. I tried to insert srting pfobj inside xpath argument.
code for a particular element:
WebElement eachelement = driver.findElement(By.xpath("//*[#pfobj=\"pfobj1\"]"));
I want to run for all elements by using loop. so i need to insert "pfobj"(which will iterate by increasing the value) in the place of "pfobj1".
I have tried the several ways but iam getting error:
String slash1 = "\\";
String pfobj = pfobj1;
String slash2 = "\\";
String final = slash1 + pfobj + slash2
Can someone please help me out with this issue
You can try this code :
for ( WebElement element: List) {
if (element.getAttribute("pfobj").equals("pfobj")){
// do what you want
}
}
List is your element list
From what I take from this question is that there are several elements in your HTML having value of pfobj attribute as pfobj1, pfobj2, and so on.
If you want to compare all such elements in a loop, you can do like -
List<WebElement> your_list = driver.findElements(By.xpath("//input[contains(#pfobj,'pfobj')]"))
int counter = 1;
for(WebElement your_element : your_list )
{
if(your_element.getAttribute("pfobj").equals("pfobj" + counter))
{
//do whatever you want
}
counter++;
}

Element present fails due to iframe issue for getting image src using Selenium WebDriver

As we know iframe can be counted using frameslist but that doesn't work for me and gives blank output although frame count gives me count as 2. I'm using Selenium WebDriver and Java.
Basically I want to get img source's data-mce-src starts with cid and dfsrc ends with # according to below screenshot.
I tried :
public static final String imageAttachment="css=img[data-mce-src^='cid']&&[data-mce-src$='#']";
which works fine using sIsElementPresent in selenium 1.0 but it fails in webdriver using findElement. In fact it doesn't identify iframe itself.
Expected:
css=img[data-mce-src^='cid']&&[data-mce-src$='#'] element present?
Code:
WebElement we = null;
List <WebElement> framesList = webDriver().findElements(By.tagName("iframe"));
for (WebElement frame:framesList){
System.out.println(frame.getText()); // returns nothing
}
int listSize = framesList.size();
webDriver().findElement(By.xpath("//iframe"));
System.out.println(listSize);
Also tried:
webDriver().switchTo().frame(webDriver().findElements(By.tagName("iframe"));
we = webDriver().findElement(By.cssSelector("html body div img"));
System.out.println(we.getAttribute("src")); // returns nothing
You should try as below :-
webDriver().switchTo().frame("Editor1_body_ifr");
we = webDriver().findElement(By.cssSelector("body#tinymce img"));
System.out.println(we.getAttribute("src"));
try {
webDriver().switchTo().frame("Editor1_body_ifr");
we = webDriver().findElement(By.cssSelector("html body img"));
System.out.println(we.getAttribute("src"));
System.out.println(we.getAttribute("data-mce-src"));
System.out.println(we.getAttribute("dfsrc"));
} finally {
webDriver.switchTo().defaultContent();
}

Selenium Xpath Not Matching Items

I am trying to use Selenium's Xpath ability to be able to find an set of elements. I have used FirePath on FireFox to create and test the Xpath that I have come up with and that is working just fine but when I use the Xpath in my c# test with Selenium nothing is returned.
var MiElements = this._driver.FindElements(By.XPath("//div[#class='context-menu-item' and descendant::div[text()='Action Selected Jobs']]"));
and the Html looks like this:-
Can Anyone please point me right as everything that I have read the web says to me that this Xpath is correct.
Thanking you all in-advance.
Please post the actual HTML, so we can simply "drop it in" into a HTML file and try it ourselves but I noticed that there is a trailing space at the end of the class name:
<div title="Actions Selected Jobs." class="context-menu-item " .....
So force XPath to strip the trailing spaces first:
var MiElements = this._driver.FindElements(By.XPath("//div[normalize-space(#class)='context-menu-item' and descendant::div[text()='Action Selected Jobs']]"));
Perhaps you don't take into consideration the time that the elements need to load and you look for them when they aren't yet "searchable". UPDATE I skipped examples regarding this issue. See Slanec's comment.
Anyway, Selenium recommends to avoid searching by xpath whenever it is possible, because of being slower and more "fragile".
You could find your element like this:
//see the method code below
WebElement div = findDivByTitle("Action Selected Jobs");
//example of searching for one (first found) element
if (div != null) {
WebElement myElement = div.findElement(By.className("context-menu-item"));
}
......
//example of searching for all the elements
if (div != null) {
WebElement myElement = div.findElements(By.className("context-menu-item-inner"));
}
//try to wrap the code above in convenient method/s with expressive names
//and separate it from test code
......
WebElement findDivByTitle(final String divTitle) {
List<WebElement> foundDivs = this._driver.findElements(By.tagName("div"));
for (WebElement div : foundDivs) {
if (element.getAttribute("title").equals(divTitle)) {
return element;
}
}
return null;
}
This is approximate code (based on your explanation), you should adapt it better to your purposes. Again, remember to take the load time into account and to separate your utility code from the test code.
Hope it helps.

How to grab just element id - using Selenium WebDriver 2

EDIT:
I also tried this
var webElements1 = (Driver.FindElements(By.XPath("//*[#id='ctl00_ContentPlaceHolder1_Control1_lstCategory']//input"))).ToList();
I get the empty Text
I am trying to find a way to grab just ID from the list i am getting and below is my code and a print shot of my screen.
//WebDriver getting a list of Text
the below code returns me the correct number of records but it just give me the Text but I am after Text and Id of an particular Text
I tried this:
var webElements1 = (Driver.FindElements(By.XPath("//*[#id='ctl00_ContentPlaceHolder1_Control1_lstCategory']/tbody/tr/td/span"))).ToList();
this
var webElements2 = (Driver.FindElements(By.XPath("//*[#id='ctl00_ContentPlaceHolder1_Control1_lstCategory']/tbody/tr/td"))).ToList();
and this...
var webElements3 = (Driver.FindElements(By.XPath("//*[#id='ctl00_ContentPlaceHolder1_Control1_lstCategory']"))).ToList();
the all code of line gives me the correct returns but without Id.
Here is the print screen of my page:
After getting all the elements using below method, run in loop to get all element's ids:
List<WebElement> element = driver.findElements(By.XPath("//*[#id='ctl00_ContentPlaceHolder1_Control1_lstCategory']//input")));
for(WebElement ele:elements)
{
ele.getAttribute("id"); // for getting id of each element
ele.getText(); //for getting text of each element
}
1) i'll try to share the idea of the approach I would choose to resolve your issue:
getElementsByTagName('input');//returns array of elements
2) using js executor get element's attribute , ID in particular, iterating through the whole array returned by getElementsByTagName('input') and getting theirs IDs.
//sample of code I used to find color attribute:
public String jsGetColor(String cssSelector){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x=$(\'"+css+"\');");
stringBuilder.append("return x.css('color')");
String res= (String) js.executeScript(stringBuilder.toString());
return res;
}
this is simply my assumtion how it be possible to try. hope it somehow helps you)
If you only need one id:
String id = driver.findElement(By.xpath("//*[contains(text(), 'Your text')]")).getAttribute("id");

How can we pick html elements value using web driver

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