Selenium xpath gives matches only the visible elements - java

Selenium xpath gives matches only the visible elements. The HTML page contains lots of other elements which are not visible but present. When trying out the xpath on chrome console, it displays all the elements including the elements which are not visible. But when using the same xpath in selenium, it returns only elements which are visible at that point in time. Is this an expected behavior?

Yes, it's right. I also tried to made reference to elements that weren't in my page (because they were invisible) but I couldn't do that. If the elements are visible in the page you will have access to them.
I recommend you that, if this elements would be visible in some moment, for example, clicking a button, you will have to automatize all the proccess with Selenium and then made reference to them with Xpath, JQuery or whatever you want.
I expect it solves your doubts.

Related

Can we create an xpath for multiple visible & dynamic elements in Selenium?

I want to create an XPath for visible elements. I tried these two techniques.
1. By locator = By.xpath("//a[contains(#style, 'display: none')]")
// It gives the elements those are hidden by display: none property.
2. driver.findElement(locatorXPath).isDisplayed();
// It can throw exceptions like StaleElementException as locatorXPath is the locator for dynamic content i.e. loading icon.`
Is there any way we can create an XPath locator to get specific visible elements?
You cant create XPath for visible/invisible elements. The first your attempt would return you the element if it has the corresponding attribute. However this rarely happens. In the most cases the styles are assigned through CSS sheets.
XPath is about DOM structure, not about styling.

Why gettext() in selenium is returning a-singlespace-b instead of a-multiplespaces-b?

I am testing TodoMVC page's todo list and I came across a problem where in the DOM label tag of the element is having a text with many spaces between two letters, but on the UI it is showing letter single space then another letter, and when gettext() is performed on the element we are getting "a b" which is visible on the UI instead of the text present in label tag of that element.
This is how Selenium WebDriver works. Since it designed for UI testing, all interactions with Browser data are made from a user perspective.
Here is an extraction from Get Element Text W3C specification:
NOTE
The Get Element Text command intends to return an element’s text “as rendered”. An element’s rendered text is also used for locating a elements by their link text and partial link text.
One of the major inputs to this specification was the open source Selenium project. This was in wide-spread use before this specification written, and so had set user expectations of how the Get Element Text command should work. As such, the approach presented here is known to be flawed, but provides the best compatibility with existing users.

Why do some elements exist but not interactable/displayed?

I'm pretty new to testing, trying to gain a better understanding of what exactly is going on. I'm finding some of our test codes are failing when the css selector element has a waitUntilCanInteract or waitUntilDisplayed attached to it even though when I do a chrome inspect the element is showing up in the browser. Changing them to a waitUntilExists gets them to a passing point so I was wondering what exactly is going on to create this situation?
Precisesly Selenium deals with three unique states of an element.
Presence of element within the html: This state of an element can be detected through the ExpectedCondition presenceOfElementLocated() where the expectation is to check if the element is present in the DOM of a page. This does not necessarily mean that the element is visible.
Exmaple:
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("css_of_element")));
Visibility of element within the html: This state of an element can be detected through the ExpectedCondition visibilityOfElementLocated() where the expectation is to check if the element is present in the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0.
Exmaple:
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("css_of_element")));
Element to be clickable: This state of an element can be detected through the ExpectedCondition elementToBeClickable() where the expectation is to check if the element visible and enabled so that you can click it.
Exmaple:
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("css_of_element")));
You can find a detailed discussion in Selenium: Check for the presence of element
Well, the developers decided to make it so.
See, the elements can exist on the DOM but be invisible or un-interactable. But not the other way around.
If your tests are passing when waitingUntilExists and failing otherwise, you probably have to prolong the waiting period if you want to make them pass. But this is just my guesswork without seeing any of your code.
Simple answer is that sometimes when designer work on web pages especially while working on Foundation CSS framework or bootstrap, they intentionally hide the original CSS/HTML tags and elements while placing foundation or bootstrap based design overlays like fancy buttons on the page which causes the original elements to be hidden.
The best approach may be like:
I. You can declare a WebElement while calling an element to precisely targeting it and using moveToElement command instead of simply calling FindElement.By.xxxxx
ex:
//*** Calling a WebElement and using moveToElement command***//
WebElement (anyElementname) = browser.findElement(By.partialLinkText("xxxxxxxxxxx"));
action.moveToElement(anyElementname).perform();
//*** Waiting for 8 seconds***//
Thread.sleep(8000, 80000);
II. You can use 'waits' for providing page load time and interacting between elements
III. Avoid copying the overlayed css elemenet especially xpath, instead, copy the xpath from the original source of the Div/button/li
Let me know if it works for you or not. Cheers!

Accessing an element with unknown id but known path

I am working on a testing program that operates with very little information. In this particular case, my program doesn't know the ID of elements in the page before it runs, because the Javascript on the page dynamically assigns those at run time. The only constants I have is the structure and the text I'm looking for. I'm including a screenshot of one example of the DOM being generated. In this case I know that I want to access the button with text apply that is displayed next to the label with the text "To Location:" Is there a way to use xpath manipulate their relationship and ensure that I'm accessing the right element. I can't just access the apply button because there are 6 apply buttons on the page with dynamically generated IDs. The label's next to them are different so I'm trying to use that and manipulate the path's from there. Help?
This is possible. If you provide the entire html code I could provide a better xpath. But for what you pasted, here's a simple one that might work:
//td[div//label[text()='To Location:']]/following-sibling::td[1]//button[text()='Apply']
There's a slightly longer winded way but thats generating a list of elements by class and clicking the one with the right text
`var elements = driver.FindElements(By.Class("text-pb"));
foreach(var element in elements)
{
if(element.Text.Equals("Searched Text"))
{
element.click();
}
}`
that might work thats if you want to click the button.
i use these sort of things on the pages works site generates so it should do what your after.

Xpath is found even though web object not visible

I am automating a code using selenium 2.0. I select one (or several) user(s) from a list. Then I click on an add button which makes the user name(s) visible on a grid. Each user will have a valid Xpath when visible on the grid. However, even after erasing all user names from the grid which actually disappears if there is no user names displayed, the Xpath still does not return null. I am using Xpath to check if it returns null when the object (user name) is not visible, but it does not work as expected. Is there any other way to solve my problem? I am pretty new with Selenium. I am using selenium 2.0. Bellow is a section of my code. Your help will be very appreciated.
//Check if user is present on the grid
By checkuser = By.xpath( ".//*[#id='sharing_list']/tbody/tr/td[1]/span");
//if the grid is not empty, which means the grid is visible...
if(null!=checkuser) //where the problem is!!
{
//Click the button to erase the names in the grid, then the grid desapears
webDriver.findElement(By.xpath("//*[#id='sharing_list']/tbody/tr/td[4]/span")).click();
Thread.sleep(2000);
//more code
//............
}
I can see two things happening here:
First is that your XPath is generic enough that it is selecting some other element that isn't a user. To see if this is the case, then in Chrome, go to the page and do the necessary actions to get it in the state you want. Next, press Ctrl-Shift-J, click on Console, and type in $x("//*[#id='sharing_list']/tbody/tr/td[4]/span"). Chrome will then show you which element your selector is selecting.
Your task then, is to identify if its selecting some other element, or whether the element is just not visible. It is definitely possible to have an element on a page, but not visible, and WebDriver WILL select invisible elements (unless you are doing By.linkText()). If you want to check to see if an element is visible do a element.isDisplayed().

Categories

Resources