Unable to Locate an Element using xpath for live updating fields - selenium-webdriver

Every time the request id changes on selecting a live update field.
Am trying to get the request id through the xpath
This is the source code.
<form id="itemscreen334-33504-" class="itemscreen addMode v_334 ajaxForm form-initialized" method="POST" enctype="multipart/form-data" requestid="18310" style="visibility: visible; opacity: 1;">
Java Code:
WebElement form = driver.findElement(By.xpath("//form[Class='itemscreen addMode v_334 ajaxForm form-initialized')]"));
System.out.println("form-->" + form);
String requestNo = form.getAttribute("requestid");
System.out.println("requestNo----------->" + requestNo);
Selenium Error:
Exception in thread "main"
org.openqa.selenium.InvalidSelectorException: The given selector
//form[Class='itemscreen addMode v_334 ajaxForm form-initialized')] is
either invalid or does not result in a WebElement. The following error
occurred: InvalidSelectorError: Unable to locate an element with the
xpath expression //form[Class='itemscreen addMode v_334 ajaxForm
form-initialized')] because of the following error: [Exception... "The
expression is not a legal expression." code: "12" nsresult:
"0x805b0033 (SyntaxError)" location: ""]
How can i get the request id using xpath?

Actually you are providing wrong xpath, your xpath expression is looks like cssSelector, Try as below :-
WebElement form = driver.findElement(By.cssSelector("form.itemscreen.addMode.v_334.ajaxForm.form-initialized"));
String requestNo = form.getAttribute("requestid");
System.out.println("requestNo----------->" + requestNo);
Or if you want to use xpath try as below with correct xpath :-
WebElement form = driver.findElement(By.xpath("//form[#class = 'itemscreen addMode v_334 ajaxForm form-initialized']"));
String requestNo = form.getAttribute("requestid");
System.out.println("requestNo----------->" + requestNo);
Note :-if you want partial match with class attribute, you should use xpath as By.xpath("//form[contains(#class, 'itemscreen addMode')]") and cssSelector as By.cssSelector("form.itemscreen.addMode")

Related

If for some field getText() returns NULL then what other functions could use to get the string of that field?

I was asked this question in an interview.
If you cannot get the string by getText() because it returns NULL. Then how would you get the string of a field in selenium webdriver?
There can be several ways:
Using selenium with getting the attributes of the element:
InnerText can be empty in some cases, thats why you can also try with innerHTML.
var innertext = element.getAttribute("innerText");
var innerHtml = element.getAttribute("innerHTML");
Or you can execute js script
var element = element(by.id('something');
var response = browser.executeScript('var el = arguments[0]; return {text: el.innerText, html: el.innerHTML};', element);
console.log(response.text)
console.log(response.html)
There is also a variant of execute script from selenium, document query element and return the innerText or innerHTML or and other property from it.

How do I solve this problem where I get 'unable to locate the element' error when trying to click on a button that expands on click

I'm trying to click on a button that expands on click but selenium is unable to locate the element. The element identified seems to be correct. I am using the Page Object Model here.
I tried to first simply find the element and click on it and then also tried to use ActionChains. Tried changing the element value and the methods of identifying such as ID, XPath, CSS Selector but nothing seems to work.
HTML:
<tr style="border-top:1px solid #e6e6e6;"><td style="display:inline-block;"><div class="expand"><i id="expand_2971740_2086074" class="fa fa-plus-circle" onclick="" style="display: block;"></i><i style="display: none;" id="collapse_2971740_2086074" class="fa fa-minus-circle" onclick="closeBundleCourses(2971740,2086074)"></i></div></td><td class="text-center">Course1Jan</td><td class="text-center">19-06-2019</td><td class="text-center">0</td><td class="text-center">1</td></tr>
Code trials:
click_plus_button = 'expand_2971740_2086074' #id
def __init__(self,driver):
self.driver = driver
def enroll_user(self,firstname,lastname,email):
self.driver.find_element_by_link_text(self.go_to_manage_users).click()
self.driver.find_element_by_class_name(self.expand_manage_users).click()
time.sleep(2)
actions = ActionChains(self.driver)
actions.move_to_element(self.driver.find_element_by_id(self.click_plus_button)).click().perform()
self.driver.find_element_by_id(self.manage_users_firstname).send_keys(manage_users_firstname)
self.driver.find_element_by_id(self.manage_users_lastname).send_keys(manage_users_lastname)
self.driver.find_element_by_id(self.manage_users_email).send_keys(manage_users_email)
Expected Result:
Expected Result
Actual Result:
Actual Result
The desired element is a dynamic element so to click() on the element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "div.expand i.fa.fa-plus-circle[id^='expand_']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[#class='expand']//i[#class='fa fa-plus-circle' and starts-with(#id, 'expand_')]"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

How to get Text from H1 Tag which has no arguments in Web Driver?

<html>
<head>...</head>
<body>
<h1>Phonetic Translator</h1>
<br>
<link rel="stylesheet" href="/style.css" type="text/css">
<title>electRa Phonetic Translator</title>
<p>Today's password is:</p>
<h1>
MQQJXJLCQZ
<hr width="80%">
</h1>
<p>The phonetic translation is:</p>
<h3>
...
</h3>
...
</body>
<html>
Hi,
I want to get the text MQQJXJLCQZ. As there are two H1 tags after Body. I have used XPath to get the text value but unfortunately I am getting the error message Type mismatch: cannot convert from String to WebElement
The code I have written is :
String PasswordxPath = "/html/body/h1[2]/text()";
WebElement H1Element = driver.findElement(By.xpath(PasswordxPath));
WebElement getPassword = H1Element.getText();
Please, can someone correct this code or suggest another way to get the text Value ?
Thanks,
UPDATE1
I have used string to get the text value, but now i am unable to put this value in the form using sendKeys. Error log as below:
Element info: {Using=xpath, value=/html/body/h1[2]/text()} at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Nativ‌​‌​e Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknow‌​‌​n Source)
I had a similar problem where getText() wasn't working.
Try using getAttribute("innerHTML")
Replace WebElement by String in the last line :
String PasswordxPath = "/html/body/h1[2]/text()";
WebElement H1Element = driver.findElement(By.xpath(PasswordxPath));
String getPassword = H1Element.getText();
As said, here is the problem
WebElement getPassword = H1Element.getText();
getText() returns the String value but not WebElement. So you need to use String here, like
String getPassword = H1Element.getText();

selenium throws "option element is not in a select" exception

I am writing selenium automation against an Angular 2 application. In the application, there is a field the user can type in to filter a dropdown that appears as soon as they start typing. The HTML looks like this:
<input> /* this is where the user starts typing */
<datalist>
<option>Option 1</option>
<option>Option 2</option>
...
</datalist>
I am getting the input element and entering partial text:
WebElement inputField = driver.findElement(By.xpath(".//input[#name='inputField']"));
inputField.clear();
inputField.sendKeys(partialText);
This is working as expected. The list drops down and is filtered appropriately. Next I find the element containing the option I want:
WebElement option =
driver.findElement(By.xpath(".//datalist/option[contains(text(), '" + myOption + "')]"));
That call is successful. But when I try to click() on it, I get:
org.openqa.selenium.WebDriverException: unknown error: option element is not in a select
I tried using Actions and Robot, but I ran into two problems:
1) As soon as I tried to press the down arrow, the dropdown closed, and 2) I don't know how, even if I could somehow select an option, I could get the text to see if I had the right option selected.
How can I select an option?
Thanks!
Try clicking the option element using javascriptExecutor.Look at below example.
WebElement elementToSelect =
driver.findElement(By.xpath(".//datalist/option[contains(text(), '" + myOption + "')]"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", elementToSelect);

Selenium Web driver: How to get preceding element from a nested span text using Java code?

I have a web page with below HTML format. This is just a sample and a part of code.
<div id="content">
........... Many other tags go in here......
<div id="1234"> // This id number is not constant and so cant hard code in xpath
<img class="float-right ng-scope" width="85" data-ng-click="highlightItem()" data-ng if="showThumbnail" ng-src="/server/image" src="/server/image">
<p>
<span data-ng-transclude="" data-ng-class="{ selected: isActive }">
<span class="ng-scope">My sample text</span>
<br class="ng-scope">
</span>
</p>
</div>
</div>
I have the text "My sample text" as my input. (There are many such div blocks and each has different span text). With this, I need to find the img element and click on it. I tried the below code : (referenceText variable = "My sample text")
String xPath = "//div[#id='content']//span[contains(text(),'" + referenceText + "')]";
// Get element of the text i.e get span element
WebElement element = getWebElementByXpath(getWebDriver(), xPath); // Gets span element
// Works fine !
// Get its parent element which is again another span
WebElement parentElement = getParentElement(element, xPath); // Gets next level span
// Works fine !
// Get its parent element p
WebElement grandParentElement = getParentElement(parentElement, xPath);
// Does not get its parent element 'p' instead return span element again
// Get preceding element for p which is img element
grandParentElement.findElement(By.xpath("./preceding-sibling::img")).click();
// Does not work as element p is not obtained.
getParentElement method is as below:
public static WebElement getParentElement(WebElement element, String xPath){
return element.findElement(By.xpath((xPath + "/..")));
}
Problem : I am able to get the span element and its parent span element but unable to get the p element and its sibling element img. I want to get img element using the span element. Any help on this would be great ! Thanks in advance.
Try the below XPAth for the image tag having "My sample text" as span value.
//div[#id='content']//div[.//span[span='My sample text']]/img
Refer http://www.xpathtester.com/xpath/b1d50008dd4be8ab7545548c4b8238f5
Simple open browser and check unique css locator, then check if that locator works for U in java code.
Try this xpath for getting grandparent 'p' from the 'span', with text "My sample text":
//span[.='My sample text']/../..
Try this xpath for getting the sibling 'img' of grandparent 'p', from the 'span' with text "My sample text":
//span[.='My sample text']/../../preceding-sibling::img
Try out with:
//span[.='My sample text']/ancestor::div/img
Thanks all for your help ! The below Xpath worked fine for me.
String xPath = "//div/p/span/span[contains(text(),'My Sample Text')]/../../..//img"

Resources