Selenium - Check if an element is under another one - java

I'm using Selenium to do Java test.
I know that i can check if an element is enable or displayed with this :
isDisplayed
isEnabled
Is it possible to check if an element is not visible, in the case that this element is under another ? For example, if a div is under another one.
With that i want to check GUI element. For example if a button move under element, etc ...
Any ideas ?
thanks for helping _

selenium.isElementPresent() or selenium.isVisible()
those may help you.
isElementPresent() - This method basically tests if the element we are looking for is present somewhere on the page.
isVisible() - looks for display: none style tag - this might throw a null pointer if we aren't careful...thus to see if an element is visible first check if the element is present using isElementPresent() method. Then try checking if the element is visible!

I think constructing your locator like this might do it.
By TOP = By.xpath(".//div");
By UNDER = By.xpath("..//..//div");
By elementUNDERtheTOP = new ByChained(TOP, UNDER);
This is the equivilant of:
driver.findElement(TOP).findElement(UNDER);
This is possible to do with XPath but I don't think you could do this with a CSS locator because a CSS locator would not be able to traverse up the DOM tree to parent elements.

Lets say you want to click an element, but that element is "behind"/"below" (aka 'obstructed' by anlother element), Selenium will actually throw a ElementClickIntercepted exception. As part of the exception message, it also returns which point you tried to click and which other element (tag, class) did intercept the click. By simply attemping to click an element and specifically catching this type of exception, you get the information you're looking for, if you catch such an exception => element not clickable (at the given coordinates - in most cases the default click point (or if you use actions: the offset you define)), if no exception => element is clickable.

The solution for Python is here.
It should be easy to convert it to Java.

Related

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!

Not able to click an element present under LinearLayout in the Appium

I want to click the country on Country code page while registering.
However, I have tried every findbyElement method i can to click the element, but it always result in
No Such Element Error.
Can anybody please help me in that.
PS: I have used xpath, ID and List. But its not working, If you have any idea from the tried methods, please do share as I am new to Appium and can be wrong.
Thanks
screenshot
Dumpfile screenshot
DumpfileforUIautomator
You can try by using xpath or name
driver.findElement(By.xpath("//android.widget.TextView[#text='India']")).click();
or
driver.findElement(By.Name("India")).click();
or
driver.findElement(new By.ByName("India")).click();
or
driver.findElement(By.xpath("//android.widget.TextView[#index='2']")).click();
The issue is that You are locating wrong control, You should be targeting radio-button/check-box control, not label next to it.
Try locating that control, not label.
driver.findElement(By.className("CheckBox Locator")).click();
try one of this solutions:
List<MobileElements> listElement = driver.findElements(By.id("com.bondevalue.BondEvalue:id/country_rb"))
System.out.println("Size: " + listElement.size());
and then check out if this is returning any result. If it does than elements are found.
Than You have to find parent layout com.bondevalue.BondEvalue:id/listlayout and find every in list, and find child elements (checkboxes) like shown, and when found desired element by text (com.bondevalue.BondEvalue:id/labelk) then click on check box (com.bondevalue.BondEvalue:id/country_rb).
Hope this helps...
Based on the screenshot of the checkbox control, it looks like the resource id is -not- unique, which is probably why the element is designated as NAF (not accessible friendly).
Therefore, I would instead access the textview immediately following it, then use preceding-sibling to access the desired checkbox:
driver.findElement(By.xpath("//android.widget.TextView[#text='+91']/preceding-sibling::android.widget.CheckBox"))

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.

Not able to click element

Trying to click on service by using xpath
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/header/section/div[2]/div/div/ul/li[2]/a")));
driver.findElement(By.xpath("/html/body/header/section/div[2]/div/div/ul/li[2]/a")).click();
but element is not getting selected/clicked.please help
try as follows (if the element is not inside a frame):
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//a[#id='menu1']/span[text()='Service']")));
driver.findElement(By.xpath("//a[#id='menu1']/span[text()='Service']")).click();
If above code does not work. then it is most probably the element is inside a frame.
If the element is inside a frame (the element is a child of an iframe tag), then first switch to the element and find the element.
My detailed answer about switching b/w frames here,
in selenium web driver how to choose the correct iframe
driver.findElement(By.xpath("//*[#id='menu1']"))
try to use this. else
driver.findElement(By.id("menu1"))

selenium very similar xpaths?

I have two buttons on a page that have really similar xpaths -
the button im trying to click -
/html/body/div[#id='wrapper']/div[#id='content']/div[#id='contentarea']/div[#id='votecontent']/div[#id='votetext']/div[#id='voteboxes']/div[#id='votenow'][2]/form/input[2]
and the other button im trying to ignore -
/html/body/div[#id='wrapper']/div[#id='content']/div[#id='contentarea']/div[#id='votecontent']/div[#id='votetext']/div[#id='voteboxes']/div[#id='votenow'][1]/form/input[2]
the only difference between the two is the
[#id='votenow'][1]
and
[#id='votenow'][2]
but I can't figure out how to interact with the one that has the votenow[2], whichever way I go about it, it always seems to interact with the first one because that's the first one it finds
this is for java using the firefox driver, any suggestions would be great :)
Just find them both and get the desired one by index:
List<WebElement> buttons = driver.findElements(By.xpath("your xpath"));
WebElement secondButton = buttons.get(1);
First
Please talk to your developers! It is really bad practice to assign the same id to two different elements (in your case buttons) on the same page! It makes life for DEV and QA unnecessarily harder than it need be!
Second
The xpath-expressions you posted already contain the differentiation between these two buttons. So you just need to find the first one and click it.
via xpath:
You can use xpath - should be enough to search for the elements with id="votenow". As said before, you can be pretty precise in this case and already filter for the 2nd button:
WebElement button02 = driver.findElement(By.xpath("//div[#id='votenow'][2]/form/input[2]"));
button02.click();
via id:
As #alecxe already pointed out, you can also first go for a more general search of several elements and then filter the right one out. Personally I would use the id in this case:
List<WebElement> buttonWrappers = driver.findElements(By.id("votenow"));
// you want the button-input-element in the 2nd wrapper element, indexing starts at 0, so do this:
WebElement button02 = buttonWrappers.get(1).findElement(By.xpath("//input[2]"));
// since it seems there are several input elements below the desired div, you can use xpath again

Categories

Resources