how to ignore core locator for one element - jdi

locators tree
In my case i have a selector list not in a core window. For window used locator ".uni-DialogBox" but listLocator(.gwt-Label.selectbox-item__label) not in this dom [ERROR 54:49.549] : >>> NewOrderWindow.orderType (>css='.uni-DialogBox'>css='.gwt-Label.selectbox-item__label')
, see screen. How ignore parent locator only for one locator?

You can use #Root annotation for an element in order to use only its locator like
#Root #UI("'.gwt-Label.selectbox-item__label")
UIElement enter;
Or switch off inherited locators for the whole project in test.properties
smart.search=off
or
smart.search=false

Related

XPATH for Dynamic Drop Down Arrows based on Selenium GUI

I am new to this GUI Scripting.... My requirement is I want to click on the drop down arrow, & inside there are some elemets with tree structure to select the particular node/alarm..
So Intially I need to crack the XPATH for the drop down arrow of "COUNTERS" enter image description here
enter image description here
Tired Xpath by using absolute Xpath as below :
WebDriverWait(self.driver, 70).until(
EC.element_to_be_clickable((By.XPATH,
"/html/body/div/pm-application/epic-layout/div/div/div/div[5]/div[4]/epic-layout-panel/div/div/div/pm-reporting/epic-layout/div/div/div/div[3]/div[4]/epic-layout-panel/div/pm-tree-wrapper/div/div/div[1]/div[2]/div[1]/div[2]/div/div[2]/div/div[1]/div/div/div[3]/span/i")))
Also with Relative paths as well :
WebDriverWait(self.driver, 70).until(
EC.element_to_be_clickable((By.XPATH, "//div[#id='1483f603-ed09-6586-16e8-fc074ea8f908']//span//i[#class='icon tree-node-arrow collapsed']")))
WebDriverWait(self.driver, 70).until(
EC.element_to_be_clickable((By.XPATH,
"//*[#class='virtual-tree']//*[#class='icon tree-node-arrow collapsed']")))
WebDriverWait(self.driver, 70).until(
EC.element_to_be_clickable((By.XPATH,
"//i[#class='icon tree-node-arrow expanded']")))
But still I am facing below issue , Please help me to resolve this issues
AttributeError: 'str' object has no attribute 'find_element'
Please read about CSS selectors and Xpath selectors. Both of them don't like white or empty spaces.
It is a good practice to give Selenium the element actual tag, and not just asterisk sign.
Here is an example of the find element using CSS selector:
"div[class*='tree-node']"
This selector will return all the div elements that their class attribute contains the phrase "tree-node".
Using xpath you can find element by their attributes as well, or by the text written inside them:
"//div[contains(text(),'333')]"
This selector will give all div elements that have the text 333 inside them

Selenium xpath failing to find element (other xpath tools prove it's there)

Selenium FindElement:
driver.FindElement(By.XPath($"//*[contains(text(), '{text}')]"));
Throws:
no such element: Unable to locate element:
{
"method":"xpath",
"selector":"//*[contains(text(), '269424ae-4d74-4a68-91e0-1603f2d674a0')]"
}
(Session info: chrome=74.0.3729.169)
(Driver info:
chromedriver=74.0.3729.6 (255758eccf3d244491b8a1317aa76e1ce10d57e9-refs/branch-heads/3729#{#29}),
platform=Linux 4.18.0-20-generic x86_64)
But it's definitely there and the xpath is valid because I can use AngleSharp to parse the driver's page source with the same xpath expression:
new HtmlParser()
.ParseDocument(driver.PageSource)
.SelectSingleNode($"//*[contains(text(), '{text}')]");
The target element is a div containing a guid:
<div class="home-project-title-text"> 269424ae-4d74-4a68-91e0-1603f2d674a0 </div>
This is with
dotnet core 2.2
chrome webdriver
Chrome 74
Ubuntu 18.04
EDIT1
Interestingly the document.evaluate in the browser console also fails with this xpath expression. I use this as a helper function for running xpath:
selectSingle = xpath => document.evaluate(xpath, document).iterateNext()
and then find that this returns null:
> selectSingle("//*[contains(text(), '269424ae-4d74-4a68-91e0-1603f2d674a0')]")
> null
but it's definitely there and has the expected text, e.g. I can use a different xpath expression to manually locate and check it's text content:
> selectSingle("//*[#id='app']/div/div[1]/div[3]/div/div[1]/div/div[1]/div")
.textContent
.trim()
== "269424ae-4d74-4a68-91e0-1603f2d674a0"
> true
EDIT2
So the cause was that the div was being created in react like this:
React.createElement(
"div",
{className = "home-project-title-text"},
" ",
"269424ae-4d74-4a68-91e0-1603f2d674a0",
" ");
I think this roughly means that the div has three textnodes as children (is that valid?). The result looks 100% normal - it renders perfectly and inspecting the element with devtools looks like a single text node and .textContent returns the concatenated string.
Now that you gave some more information (how this element is created):
Yes, it is possible that an XML element has as its children several separate text nodes. However, this is usually not the case if the text nodes are adjacent to each other, instead of separated by child elements.
If '269424ae-4d74-4a68-91e0-1603f2d674a0' is indeed the second text node, then
//*[contains(text(), '269424ae-4d74-4a68-91e0-1603f2d674a0')]
will indeed not return this div element. You should not think of this as "breaking XPath", it is just that the precise semantics of the expression are:
Find an element with any name whose first text node contains '269424ae-4d74-4a68-91e0-1603f2d674a0'.
text() actually selects all text nodes of an element, but XPath functions such as contains() silenty select only the first one.
What you actually would like to select is
an element with any name where any text node contains '269424ae-4d74-4a68-91e0-1603f2d674a0'
And an expression to achieve exactly that is:
//*[text()[contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]]
You can test those expressions with a small toy document such as:
<div className="home-project-title-text">
<other/>
269424ae-4d74-4a68-91e0-1603f2d674a0
<other/>
</div>
Where other elements are forcing the div element to contain three separate text nodes, two of them containing whitespace only.
Finally, if you already know that the element you are looking for is a div, then you should look specifically for that:
//div[text()[contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]]
It might be the case the element lives in an iframe, if this is the case - you will have to use IWebDriver.SwitchTo() function in order to switch to the required iframe prior to attempting locating the element.
It might be the case the element is not immediately available, i.e. it's being loaded by an AJAX request, in that case you will need to use WebDriverWait class so Selenium could wait till the element appears in DOM prior to interacting with it.
Try the following xpath.See if you get any luck.
//div[#class='home-project-title-text'][contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]
EDIT
//div[contains(.,'269424ae-4d74-4a68-91e0-1603f2d674a0')]

RobotFrameWork: Class name changes how to navigate Robot to 2e TR and 6e TC

If a class name changes all the time, but a column is always there.
how to navigate RFW to 2nd row and 6 column?
(instead of class name)
https://www.investing.com/equities/pre-market
In ROBOT Framework, you can access the element by several ways. See http://robotframework.org/Selenium2Library/Selenium2Library.html . See section 'Locating elements".
The most common way is by id, name, class, xpath and css_selectors. So, let's assume that it is not possible to get locator by id, name & class due its dynamically changes during page load. So, we will use absolute xpath expressioin for this solution.
In xpath, you can access the node either by i) relative xpath or ii) absolute xpath.
If the class or id are dynamic and keep changing, then just use it's absolute xpath.
Before that, it is highly recommended if you install an add-on in your web browser for checking/inspecting the xpath element/expression. For firefox, just install 'ChroPath' extension.
The absolute xpath expression below will return a single matching node for ROW=2, COLUMN=6..
/html[1]/body[1]/div[5]/section[1]/div[6]/table[1]/tbody[1]/tr[2]/td[6]
The absolute xpath expression below will return all matching nodes for all rows, COLUMN=6..
/html[1]/body[1]/div[5]/section[1]/div[6]/table[1]/tbody[1]/tr/td[6]
Then, in ROBOT Framework, you can access this element like below..
${xpath}= Set Variable /html[1]/body[1]/div[5]/section[1]/div[6]/table[1]/tbody[1]/tr[2]/td[6]
Wait until Page Contains Element xpath=${xpath}
${output} = Get Text xpath=${xpath} #if you want the text of this column.
Click Element xpath=${xpath} #This will simply click the element

Unable to recognize Element with relative xpath or other locator

I am facing an issue where I am unable to locate Element on webpage with any type of locator expect Absolute xpath. Here are details:
URL : https://semantic-ui.com/modules/dropdown.html#selection
Required Element Screen shot:
Manually created Xpath Screen shot( Please note that I am able to recognize Element in web application with manually created xpath but Same xpath is not working in selenium code)
But Same xpath is not working in selenium script.
PLEASE NOTE THAT I AM ABLE TO IDENTIFY SAME OBJECT WITH Absolute xpath
Please help to me to understand reason for this.
Here is code:
public static WebDriver driver;
public static void main(String[] args) {
driver= new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("https://semantic-ui.com/modules/dropdown.html");
//Selection
driver.findElement(By.xpath("//div[#class='ui selection dropdown upward']")).click();
driver.findElement(By.xpath("//div[#class='menu transition visible']/div[text()='Female']")).click();
System.out.println("Done");
This may be issue with your first x-path. You may try the following code. It may work.
driver.findElement(By.xpath("//div[#class='ui selection dropdown']").click();
driver.findElement(By.xpath("//div[#class='menu transition visible']/div[text()='Male']").click();
You are missing a preceding wildcard in you driver.FindElement XPath.
Instead of driver.findElement(By.xpath("//div..."));, do driver.findElement(By.xpath("//*div..."));.
Currently, what your code is doing is telling the XPath locator to find a first level div (not easily possible, as the first item is almost always the document body), but the wildcard of "*" tells it that it can look for the div at any level.
As an aside, please edit your answer up top with actual code instead of pictures so others with the same problem can find their solution easier.
Longshot:
You are using Chrome to look at the source, but Selenium is using Firefox.
There is a chance that the source is rendered differently between the two browsers. Specifically, your xpath is relying on an exact match of class. I do know that FireFox is notorious for modifying source output.
I haven't done any testing but I would not be surprised if the class is in a different order and it's failing on an exact match.
There are two solutions if that is the case:
Don't do a single exact match (xpath = "") but instead do a mix of contains joined with && (contains ui && contains selection && dropdown)
Don't rely on the output from the console tab. Instead "View Page Source" and view what is actually being sent instead of what is being interpreted by the browser
Find the dropdown container element firstly, then use it to find self descendant, like option etc.
driver.get("https://semantic-ui.com/modules/dropdown.html");
// find dropdown container element
WebElement dropdownWrapper = driver.findElement(
By.xpath("//div[#class='html']/div[input[#name='gender']]"));
// expand drop down options by click on the container element
dropdownWrapper.click();
// or click the down arrow
dropdownWrapper.findElement(By.css('i')).click();
// select option
dropdownWrapper.findElement(By.xpath(".//div[text()='Female']")).click();
To locate the element with text as Gender and select the option Female you can use the following Locator Strategy :
Code Block :
System.setProperty("webdriver.chrome.driver", "C:\\path\\to\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://semantic-ui.com/modules/dropdown.html#selection");
driver.findElement(By.xpath("//div[#class='another dropdown example']//div[#class='ui dropdown selection']")).click();
driver.findElement(By.xpath("//div[#class='another dropdown example']//div[#class='ui dropdown selection active visible']//div[#class='menu transition visible']//div[#class='item' and contains(.,'Female')]")).click();
System.out.println("Gender Female selected.");
Console Output :
Gender Female selected.
This might be helpful to clearify how selectors are working in general:
.(dot): Dot at starting represents the current node. It tells us that the processing will start from the current node.
. .(double dot): It will select parent of current node. For example, //table/. . will return div element because div is the parent of table element.
‘*’: is used to select all the element nodes descending from the current node. For example:
/table/*: It will select all child elements of a table element.
//*: It will select all elements in the document.
//*[#id = ‘username’]: It will select any element in document which has an attribute named “id” with the specified value “username”.
#: It represents an attribute which selects id, name, className, etc. For example:
#id: It will select all elements that are defined with the id attribute in the document. No matter where it is defined in the document.
//img/#alt: It will select all the img elements that are defined with the #alt attribute.
//td[#*]: It will select all td elements with any attribute.
Here is a link to the article:
https://www.scientecheasy.com/2020/07/selenium-xpath-example.html/

Why my Selenium web driver is not clicking on Element identified by id?

My Selenium web driver is not clicking on this tree node. I don't know exactly what we say it tree node or something else so this is image and I highlighted the element.
This right arrow part on which I want to click
And this is my code:
//wait.until(ExpectedConditions.elementToBeClickable(By.id("iconDiv")));
WebElement taskdropElementid = driver.findElement(By.id("iconDiv"));
System.out.println(taskdropElementid.getAttribute("class"));
if(taskdropElementid.getAttribute("class").equals("RightArrow"))
taskdropElementid.click();
Printing statement is giving me output dropdown. I think it should give RightArrow and when I am uncommenting wait part then it is continuously wait for the element to be clickable.
What am I doing wrong?
Printing statement is giving me output dropdown
That means there are multiple elements with the same id iconDiv and unfortunately you're locating other element instead which has class name dropdown.
If you want to locate element with class name RightArrow, You should try using By.cssSelector() to locate it uniquely as below :-
WebElement taskdropElementid = driver.findElement(By.cssSelector("div#iconDiv.RightArrow"));
taskdropElementid.click();