how can I click only one of the elements in a class with multiple elements? - selenium

ok so I cannot share the website I'm trying to automate but I'll share a screen shots of the inspect view.
ill add the code i used and the log i got from it
as you can see the class: data-command has three elements within in the number is dynamic but I need to click on the last one, i do not want to use absolut xpath as the class: data-command is dynamic.
ill add the code i used and the log i got from it
how do i click the last element
##{element_value}= Get WebElements class:data-value
#{elements_name}= Get WebElements class:data-label
#{element_commands}= Get WebElements class:data-command
WHILE ${i} < 5
#Log To Console ${element_commands[${i}]}
Click Element ${element_commands[${i}]}
Sleep 5s
#Capture Page Screenshot
Run Keyword And Warn On Failure Page Should Contain ${graph}
${i}= Evaluate ${i} + ${one}
END

I'm not familiar with robot framework, but is case data-command class is a unique locator, the following XPath will give you the last child inside that element:
"(//div[#class='data-command']//*)[last()]"

You can get elements store it in collection/list and then get the last one and click it:
List<WebElement> elements= driver.findElements(By.css(".data-command"));
element = elements.get(list.size() - 1); //Click only the last in the list

Related

How can I check that a dropdown field is disabled using selenium?

I am trying to write a function in selenium to check if a Reasons dropdown is showing as disabled, but can't quite get the xpath right. The code for the dropdown is in the pic, the function I'm working on is the second one (InputDisabled), having based it on the working first one (SearchDisabled):
` public By SearchDisabled(string searchId) => By.XPath($"//div[#id='{searchId}']//div[contains(#class, 'v-input--is-disabled')]");
public By InputDisabled(string inputId) => By.XPath($"//div[#id='{inputId}']//div[contains(#class, 'v-input--is-disabled')]");`
The inputId going into it is 'ai-confirm-allergy-modal-reason'. I've tried it as 'input[contains...' and 'contains(#disabled, 'disabled'...' among other things, but my xpath knowledge isn't great yet!
dropdown code
Use below code
String value = driver.findElement(By.XPath("//input[contains(#id, 'ai-confirm-allergy')]").getAttribute("disabled");
Assert.AssertEquals(value, "disabled");
I do not quite get your question.
well if you are trying to use xpath to locate an element, you can just use the id; assuming that it is unique.so:
driver.findElement(By.xpath("//input[contains(#id, 'ai-confirm-allergy')]")
should locate the webelement.
However, your xpath for the SearchDisabled is locating a div containing class 'v-input--is-disabled' with in another div with id of '{searchId}';
the same logic goes for the next one. your xpath is trying to locate a div containing class 'v-input--is-disabled' which is located with in another div located using input id. I don't think this combination can locate the element highlighted in the picture.

selenium python how to find and click element that change everytime

im trying to find an element with dinamic values , for example <span class="ms-Button-label label-175" id="id__177">Save</span> in inspect element, the id and class values tend to change for every refresh, how can i in this case find the element in selenium? i tried troguht xpath but seems doesnt work because can not find the path, i was thinking to find "Save" world torught always find by xpath but actually i dont know if im doing well : driver.find_element_by_xpath(//span(#.... but then? how can insert element if it changes everytime? thanks!
Something like this may work:
driver.find_element_by_xpath('//span[text()="Save"]')
But this will fail, if there is more than one button with text "Save" on the page.
In that case you may try to find some specific outer element (div, form, etc.) which does not change and contains the button. Then find the button inside of it.
With few requests with driver:
specific_div = driver.find_element_by_id("my_specific_div")
button = specific_div.find_element_by_tag_name("span") # e.g. there is only one span in that div
Or with more specific xpath:
button = driver.find_element_by_xpath('//div[#class="some-specific-class"]/span[text()="Save"]')
If needed, search for more nested elements before the button, so you can get more narrow search field.
More examples in the docs.

How to get the clicked element in selenium when we don't know what are we clicking

I am clicking with the help of following lione oc code->
actions.moveToElement(objDriver.findElement(By.id("id_popcode")),coordinates.getX(),coordinates1.getY()-1).doubleClick().build().perform();
Basically i double click at a position(x,y) in our application. Individually we cannot click that particular element bcoz it has to be clicked at particular (x,y) itself. So i want to get the properties of that clicked element(which i click using actions command which i mentioned above) liked id, classname. Can some one help me with this...kinda stuck here..........
edit:
try execute.elementFromPoint() with JavascriptExecutor to get element by coordinates
JavascriptExecutor js = (JavascriptExecutor)driver;
WebElement theElement = (WebElement)js.executeScript("return document.elementFromPoint(arguments[0], arguments[1])", coordinates.getX(), coordinates1.getY()-1);
System.out.println(theElement.getAttribute("tagName"));
System.out.println(theElement.getAttribute("class"));
old:
you are using negative value in getY()-1 which mean coordinates above the element, it maybe the parent or preceding-sibling of element try to select it using xpath
WebElement popcodeBefore = objDriver.findElement(By.xpath("//*[#id='id_popcode']/parent::*"));
// Or
// WebElement popcodeBefore = objDriver.findElement(By.xpath("//*[#id='id_popcode']/preceding-sibling::*"));
System.out.println(popcodeBefore.getAttribute("class"));
actions.moveToElement(popcodeBefore).doubleClick().build().perform();
If you have any specific text at that particular coordinates make use of it. I too had the same issue like this where I need to double click on a cell which had text 0.00%. I have done hovering action first using the text and then performed the double-click
Ignore the syntax issues since I am working on the protractor these days
browser.driver.actions().mouseMove(driver.findElement(by.xpath("//*[text()='00')]").build().perform();
and then perform the click
Still, you have issues, check if you have any attribute like ng-click which can be helpful to get the coordinates for that particular location. please always share the HTML code so that It may help us to check more deeply

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();