Accessing an element with unknown id but known path - java

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.

Related

Best way to find element with the same signature in Selenium?

I've been asked this question on a interview. What is the best way to find particular button on a page, from two identical buttons?
Two buttons like this on a page, i need to find the second.
button class="button-signin" name="btnlogin_login" value="Login" type="submit"> Sign In /button>
I've answered that I'd locate both and choose what I need from the list - they said that it's no good, because page can be changed. Can you suggest me the good way to do this?
If they said to find always the second element I would go for a solution like this:
List<WebElement> buttons = driver.findElements(By.class("button-signin"));
if(buttons.size() > 1){
buttons.get(1);
}
But what dont make sense for me is what they told you, than the page can change...Technically if the page change you should modify yours tests to make them easier to find elements save time and make them more readable, you cant do a test forever as a page is not forever.
Basically, the buttons must be child elements of some HTML elements.
Case 1: Parent are different, you can refer to each button by specify different parent e.g. cssSelector("#component1 > button") and cssSelector("#component2 > button").
Case 2: They have the same parent or path are identical, there are a couple options.
Use index such as XPath //button[2] or CssSelector button:nth-child(2)
Change the application, add something to differentiate the buttons
For case 2, I do think there is no point to have the 2 buttons which have the exactly same properties in the application. Personally, I prefer the option#2

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

Organsing Html(text) appropriately

I have a document with all the html that I want to manipulate but its all over the place.
I can get it fairly tidy using
Elements paragraphs = document.select("p");
But its not the format that I want it in.
For example if its a table that I want to organise how do I just say take in the first set of elements eg(everything on a particular day monday) then everything on tuesday...
Im not sure how to select it correctly. As I want to put the txt into arraylists of class type.
In the html each set of info I want starts with td and ends with /td
So how do I select the first td then the second one then the third one etc.
Thanks for the help.
I am not sure, that I understand your porblem correctly and since I can't comment I am posting it as an answer.
You can select all of your td's and then get their childs
$('td').children('li').each(function(index, element) {
and add them to your array here
});

Selenium - auto completion (prediction text)

I am new to selenium web driver.
When I try to auto-complete a particular text and select an option from the prediction text list as given below, it selects the appropriate option.
The problem is after the phrase gets populated in the text box, the prediction text list is displayed again, due to which it is unable to perform the next step.
I am using xpath to select the option from the prediction text list:
driver.findElement(By.xpath("//div[#class='mui-pt-bd']//li[2]")).click();
Please let me know what I can do regarding this.
Try adding some synchronization code to wait for the prediction list. After that call the click method. See http://docs.seleniumhq.org/docs/04_webdriver_advanced.jsp
First, make sure there are no trailing spaces for the prediction text that you chose by clicking from the list. If there are, it might trigger the prediction text list to open up again.
If this not the case, the only thing that I can think of is, clicking elsewhere within the same frame/form so that the prediction text list gets closed.
Another thought is that, after choosing one item, the usually expected behavior is for the drop-down to close. If that is not happening manually, then, you might want to make sure it is not a bug with the Application itself.

How to get Selenium Webdriver to recognize elements with changing id numbers within it

how do I get the xpath or css or ANYthing to click this ok button??? Problem is these ids and other attributes have tags that are changed every time a user goes to this particular page
--ea3b2e21-3847-47de-860c-3596695fbb35-- so i don't know what to do
Ok
All you can do here is try and find some part of the element that does not change. If you can add some sample html it would help.
Have you read the
docs for dynamic elements?

Categories

Resources