Locate Tweet 'like' button using xPath (Selenium, Python) - selenium

I am trying to locate a tweet like button using xPath.
If I go to https://twitter.com/BillGates and use Chrome developer tools, I can see:
That the like button for the first tweet is located at:
/html/body/div[2]/div/div/div[2]/main/div/div/div/div[1]/div/div[2]/div/div/div[2]/section/div/div/div[1]/div/div/div/div/article/div/div[2]/div[2]/div[2]/div[3]/div[3]/div/div/div[1]/svg/g/path
That the first tweet like button has:
< path d="M12 [lots of numbers]">
I tried to use both Python + Selenium and XPath Helper Chrome extension but with both approaches I cannot find the button.
I have tried without success using the full xPath and also the query below:
.find_element_by_xpath("//path[starts-with(#d, 'M')]").click()
Actually, I cannot get anything past the last div. //svg, //g and //path all get zero results. //div on the other hand, gets me 900+ results...
Appreciate if anyone can help to point me in the right direction.
Thanks!

I highly recommend not using Twitter to practice automation.
Anyways, i've seen that the likes buttons has data-testid attribute which it's value is unique to that element you are looking for, so we can easily get all the likes buttons elements like this:
//div[#data-testid="like"]
Or with css selector like this:
div[data-testid="like"]
Assuming you are writing in Python, Then we can use find_elements method to get all the elements in a list.
like_buttons = driver.find_elements_by_xpath("//div[#data-testid="like"]")
And easily click any tweet's like button you'd by index,
like_buttons[0].click() # 0 Is the first tweet, 1 is the 2nd etc...
Note that you might need to perform a hover on this element and then click it,
So if the driver find the element, but it's not clickable, it must be it.

Related

Unable to click on Radio Button

Please, I don't know why but I can't click on this radio button.
I'm trying by xpath, css, id... but anything works.
Always I get the error: no such element: Unable to locate element
And I added an explicit wait, but it still not working.
Now, I'm trying it but not works as well:
WebElement radio = driver.findElement(By.xpath("//div[#class='form-inputs-container']/ul/li[3]/label"));
radio.click();
I need click on multiple destinations radio on this website:
https://www.turismocity.com.br/
Can you help me, please ?
RadioButton
It looks like your xpath is wrong Try with below xpath it will work
//form[#class="tc-form-full-flight"]//label[#for="tt1"]/following-sibling::div
For first radio button: //form[#class="tc-form-full-flight"]//label[#for="tt1"]/following-sibling::div
For second radio button: //form[#class="tc-form-full-flight"]//label[#for="tt2"]/following-sibling::div
For third radio button: //form[#class="tc-form-full-flight"]//label[#for="tt3"]/following-sibling::div
Hope this will be helpful!!!
This should work //input[#id='tt3'] or //input[#value='MultiDestino']
You can evaluate xpath in chrome console like this $x("//input[#value='MultiDestino']")
The xpath you have returned empty []
Locator is incorrect. More than that - even if it was valid, this way of finding elements is unreliable (you've used an element position - [3] in case of order change, locator will brake). I suggest css selector:
input[value='MultiDestino']
For locators, you should always start with something that is highly unlikely to change. Typically that's IDs, names, and various other custom attributes depending on the site. In this site's case, the three radio buttons you are looking at each have an ID.
Side note... sometimes sites/pages don't respect HTML standards that require the ID to be unique on the page so even if your desired element has an ID, always check to make sure it's unique on the page. In this case, the IDs are unique.
To click the multiple destinations radio button, you can use the code below.
driver.findElement(By.id("tt3")).click();
In some of your comments, it looks like Selenium might be having a hard time clicking on the INPUT itself and the LABEL is working. If that's the case, then you can change the locator slightly and use the code below
driver.findElement(By.cssSelector("#tt3 + label")).click();
In the CSS selector above, # means ID and + means next sibling. See the W3C docs for more info.

How to handle dynamic id

I am trying to explore log In button xpath with this site https://www.componence.com/login, by just recording and play back.Then I tried to get it through firepath and chrome browser default xpath copier.
But it looks like every time submit button xpath get changed with page load. I got following xpath for "Sign IN" button.
.//*[#id='yui_patched_v3_11_0_1_1487250469606_202']
.//*[#id='yui_patched_v3_11_0_1_1487251369606_202']
.//*[#id='yui_patched_v3_11_0_1_1487250229606_202']
.//*[#id='yui_patched_v3_11_0_1_1487254369606_202']
Can you please help me to retrieve correct xpath of Sign IN button which I can use with selenium IDE?
You can use below XPath to handle dynamic id:
//button[starts-with(#id, "yui_patched_v3_11_0_1_")]
But better solution is to use text content of element:
//button[normalize-space(text())="Sign In"]
I will have to disagree with the second statement of #Andersson, since it will work for .com but not for .nl.
As I see the site has a second language and my opinion is to avoid using selectors based on text on a multi-language environment.
Also as I see the id seems does not have a meaningful value, in this case try to identify a unique parent section and go from there.
One option for css/xpath would be:
css: form.sign-in-form button
xpath: //form[contains(#class, 'sign-in-form')]//button

Selenium Webdriver Onlink Text

What command in webdriver should I use to make sure it clicks the specific text i.e Last Month
the code is
<div class="dt_padded_medium_div">
<a onclick="setLastMonth()" href="#">Last Month</a>
I tried xpath by using firepath but still doesnt work
it was
//*[#id='block-2']/div/div[3]/table/tbody/tr[1]/td[5]
I used
driver.findElement(By.xpath("//*[#id='block-2']/div/div[3]/table/tbody/tr[1]/td[5]")).click();
but still didnt work, am I missing something?
Update:
Got the Code working guys, thanks for the help!
If there is only one 'a' element in the page with this text, try this XPath:
//a[text()='Last Month']
If there are more than one element, please, post the full HTML tree else we're unable to write a xpath without know the tag path and ensure it will work
Are you sure your xPath is correct?
Install FirePath on Firefox and experiment with your xPath as on screenshot below.
Also, that does look like a long and brittle xPath. Look up xPath cheat sheets to learn how to make your xPath more robust.
In your case I would imagine something like:
//*[#id='block-2']/descendant::a[text()='Last Month']
(get the element with a particular ID, then search for an <a></a> in that element, no matter how deep, with a particular text)
In your question, you have used a "id" that is not shown in your code, where is #id='block-2'. It is possible for you to have used the wrong id. For us to help you, can you please provide the whole HTML code?
What I can suggest based on the information you have provided is:
Making sure the Xpath you have provided is unique, there is an add-on for Firefox called Firebug you can use. It will help you find out the xpath you are after fast and easy. What you need to do is basically:
download firefox and install it;
download firebug add-on and install it to firefox;
you will notice there is a small bug symbol to the top right of your tool bar, please enable it;
you will see a console pops out, click on inspection button and click on any web element you want to inspect and its html code will be highlighted in the console;
right click on the highlighted code and choose to copy its xpath to clipboard. This way you will never get your xpath wrong.
Here is a quick tutorial:
http://www.wikihow.com/Find-XPath-Using-Firebug
P.S. There are more than one way to locate a webelement, please consider using the following options as well:
Css selector
class name
id
This link will direct you to an awesome cheat cheet.
http://scraping.pro/res/xpath-cheat/xpath_css_dom_recipes.pdf
Hope it helps.
Please try to use below code to click on the text Last Month
driver.findElement(By.xpath(".//a[text()='Last Month']")).click();
Hope this helps.
You can use below code to click on the link containing the text 'Last Month'
driver.findElement(By.linkText("Last Month")).click();
First of all make sure that your xpath works correctly, try to use more specific xpath other than just td[5] or smthn like that, for example above could be like:
//div[#class='dt_padded_medium_div']/a[#href] - meaning, we need to find <div> element with specific parent and within it <a> element that has href property
There are a few possibilities.
If you're site doesn´t get rewritten to much you could just go for the link name via
driver.findElement(By.linkName("Last Month");
You could also go for any of the attributes if your site is subject of many rewrites like this and just put "href" and "#" or "onclick" and "setLastMonth()" as arguments when calling it.
static WebElement getLink(String Attribute, String Value /*String ItemText*/){
List<WebElement> Elements = driver.findElements(By.tagName("a"));
for(int Counter = 0, Counter < Elements.size(); Counter++){
if(Elements.get(Counter).getAttribute(Attribute).contains(Value) /* && Elements.get(Counter).getText().equals(ItemText){
return Elements.get(Counter);
}
}
return null;
}
If you remove the comments it will go completely sure and check for the Attributes and the displayed text.

Is it possible to search for a dynamic button if the beginning of he ID is always the same?

I am using Selenium in some automation testing. On a certain page i need to click a button. This same page is used multiple times and when i originally tried to use the full xpath it would work on one of the pages but not the other. The full xpath for each page is slightly different so i dont want to use that.
The xpath of the button looks like this
.//*[#id='approve-gen8149262f2cdc49958632185c33b8e82f']
On both pages the id always starts with approve and then gets some generated numbers.
I am wondering if there is a way to search for just a section of the id so i can look for "approve" in order to find the button i need to click.
I have tried a number of things with no luck thus far.
You can also use CSS selector:
[id^="approve"]
Using XPath, you can select an element where one of its attribute begins with a given string. For instance:
//*[starts-with(#id, "approve-gen")]
See also:
Selecting elements whose attribute begins with something in XPath
You can also use the xpath with contains. for eg.
//*[contains(#id, 'approve-gen')]
Make sure that there are no other locators with id starts with 'approve-gen'.
Use
Step 1:
From the Given Info I have assumed the CSS Selector as
css=button[id*='approve-gen']
Also look for the Other Attributes of button that will bring uniqueness.
Step 2:
Perform Click on the button
driver.findElement(By.cssSelector("button[id*='approve-gen']")).click();

How to handle dynamic id from xpath

I am trying to explore IDE with this site http://www.barnesandnoble.com/, by just recording and play back.
1.In the search box just enter any text to search,
2.Ten click on All Products, select Books.
When i record its xpath is as below
/html/body[#id='CDS']/div[#id='navContainer']/div[#id='bnnav2011']/div[#id='yui_3_3_0_1_1355746621091_93']/div[#id='bn-global-header']/div[#id='yui_3_3_0_1_1355746621091_92']/div[#id='yui_3_3_0_1_1355746621091_91']/form[#id='qs']/div[#id='yui_3_3_0_1_1355746621091_90']/div[#id='yui_3_3_0_1_1355746621091_89']/ul[#id='yui_3_3_0_1_1355746621091_88']/li[#id='yui_3_3_0_1_1355746621091_99']
But when we play ti again it gives error,[error] locator not found:
Wehn i search for its xpath , its chnaged and is as below
/html/body[#id='CDS']/div[#id='navContainer']/div[#id='bnnav2011']/div[#id='yui_3_3_0_1_1355748592221_91']/div[#id='bn-global-header']/div[#id='yui_3_3_0_1_1355748592221_97']/div[#id='yui_3_3_0_1_1355748592221_96']/form[#id='qs']/div[#id='yui_3_3_0_1_1355748592221_95']/div[#id='yui_3_3_0_1_1355748592221_94']/ul[#id='yui_3_3_0_1_1355748592221_93']/li[#id='yui_3_3_0_1_1355748592221_98']
Observe that, its ID's are changing.
Can any one tell me how to handle this ?
The IDE is not very smart at generating XPath queries, in fact, there isn't an automated tool out there that will calculate a reliable XPath query. Why? The reason is because to generate the XPath query, it will walk down the tree from the top (at the html element), down to the element you are interacting with.
Whilst this is fine for a lot of things, if you have elements that have dynamic values (dynamic text/ID/name/classes or even if it changes position), it's never going to work.
You'll need to look at a different way to get it, so you'll have to override what the IDE is giving you.
Looking at the source, they give whatever is selected a class value of ui-selectmenu-selected. So when the page loads, the 'All Products' list item (li) will have that class, when you change the item the new item will have that class.
So you could use this XPath:
//li[#class='ui-selectmenu-selected']
Or, this CSS selector:
li.ui-selectmenu-selected
Or, use this XPath to get the 'All Products' item specifically. It will start one level up, using the actual menu, then go down and find the item:
//ul[#class='ui-selectmenu']/li[text()='All Products' and not(#class='ui-selectmenu-hidden')]
You can try using xpath: Position. It seems that the IDs are changing all the time.
As an answer to your question you should move away from id's and try using xpath or css selectors where you can select the nth child of the parent.
Since you are new to selenium I would like to point to my notes here at.-
http://selenium-testing-notes.blogspot.in/
it will help you through a lot of other pitfalls I fell in.
The best way I found to help with selectors is to work with firebug with firepath installed. This setup can help you verifying your xpath and css selectors.
I saw your question based on that answer is first you need to add on fire-path in Firefox .Using firepath you can find the xpath locator. it is very simple to you
Example:
driver.find_element_by_xpath("see![image which i have attached in this question][1] the xpath path locator details").click()
Hi Arran i am able to click the All Products button using the xpath you have given ( xpath= //ul[#class='ui-selectmenu']/li[text()='All Products' and not(#class='ui-selectmenu-hidden')]
and also get the list available. But then not able to click the Books item from the Menu.