In selenium, how to located two elements have same span class name? - selenium

I need use selenium to located two elements. However, they both have same span class name. My code:
select_button = driver.find_elements_by_xpath("//span[#class='mat-button-wrapper']")
The issue is: I can this command 10 times, 6 times it locates my element, ( select button), but the other 4 times, it landed on the other button. How do I make sure it is 10 out of 10 times it will located my "select " button?

In case there are 2 elements with the same xpath as you mentioned you can use (//span[#class='mat-button-wrapper'])[1] xpath to access the first element and (//span[#class='mat-button-wrapper'])[2] for the second.
However I guess it's possible to locate the desired element with relation to some other element. I will do it if you present the web page link.

Related

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

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

xpath on the site is constantly changing

Peace. I registered a test on the amazon site. Doing a search of 11 iphone and then coming to a page of full products i choose first but its xpath
// span [contains (text (), 'Apple iPhone 11 (64GB) - Black')]
The problem is that I can use this xpath but tomorrow the xpath will be renamed because the first product is changed for example:
// span [contains (text (), 'Apple iPhone 11 Pro (64GB) - Space Gray')]
But I always choose the first product among all iphones even when the product changes?
Thanks.
This is the page
https://www.amazon.co.uk/s?k=iphone+11&crid=3GCCCW0Q2Z1MQ&sprefix=iph%2Caps%2C220&ref=nb_sb_noss_2
Use index and following xpath to get the first element.
(//a[#class='a-link-normal a-text-normal']/span)[1]
Always try to find something on the page that is very unlikely to change. If the element that you're looking for doesn't have such properties, look at it's ancestors.
For example, in this case, you can see that one of this span's ancestors have cel_widget_id="MAIN-SEARCH_RESULTS" which'll most likely remain constant. So, the following xpath:
//span[#cel_widget_id="MAIN-SEARCH_RESULTS"]//h2/a/span
will give you all such titles. You can get the first index as
(//span[#cel_widget_id="MAIN-SEARCH_RESULTS"]//h2/a/span)[1]
You could use the class of the search item span:
//span[#class="a-size-medium a-color-base a-text-normal"]
Then if you can do:
first_iphone = driver.find_element_by_xpath('//span[#class="a-size-medium a-color-base a-text-normal"]')
Although all search items are all the same class, (in this case a-size-medium a-color-base a-text-normal) the find_element_by_xpath method will only look for the first one.

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

How to click an element with reference to another web element in Selenium WebDriver(Java)?

There are many span tags as mentioned in the image below and each has its own a-tag with unique id as "chooseitem". I need to choose particular a tag using names in the span tags.
Need to click the a-tag button using the text Mayo Chicken from the above HTML snippet in the image.
I have tried the below Selenium script
WebElement select = driver.findElement(By.xpath("//*[contains(text(),'Mayo Chicken (Single)')]"));
WebElement add = select.findElement(By.id("chooseitem"));
It doesn't work for me.
driver.findElement(By.id("chooseitem"));
The above code chooses the first item in the page by default as its id is also 'chooseitem', but need to define what to be chosen.
Can anybody help me out?
We need to get the common parent(ancestor) element of the chicked and the clickable 'a' tag, then we can navigate to the tag 'a'. Below xpath should ideally work.
"//span[contains(text(),'Mayo chicken')]/ancestor::div[4]//a"
Note: Here i have used div[4] because fourth parent is the common ancestor for 'Mayo chicken' and tag 'a'.
For more details about different xpath axis refer this->https://www.w3schools.com/xml/xpath_axes.asp
Hope this helps you. thanks.
You can do that by using the xpath position, press F12 for developer tools click on "Select element button", click the element that interests you on the page, as in your picture you will see one or more lines highlighted, right click the line -> Copy -> Copy xpath. You will have something like the line below:
//*[#id="comment-76500216"]/td[2]/div/span[1]
The xpath position will be:
//td[2]/div/span[1]
You can use that when you have multiple elements that share the name or id or so on.
And you will have:
WebElement select = driver.findElement(By.xpath("//td[2]/div/span[1]"));
PS: I used google chrome

How to locate 5 different choose file option having same xpath in selenium webdriver?

enter image description here
I created my own xpath using the value as
.//*[#onclick='return clickFileUpload('openssme1')']
But it is not locating the choose file option individually.
Please help me to locate them individually so that i can choose 5 files.
If I want to select a specific element and I know the position in the result generated by the xpath. Then you can simply append [n] to the end of the xpath, where n is the position number.
(//button[text()="Choose File"])[1]
You can select your element with other unique identifier. In your case, you can choose the number at the left of your button (the number)
Something like this :
//*[#id='uploaderList']/tr/td[contains(text(),'1')]/../td/button