SVG and selenium - selenium

Hej Guys
I an using google visualization api to draw stacked bar chart. Its all fine but now i want to test it with selenium but having a hard time finding the elements in the google chart.
For example i want to click on the chart element but everytime i try to find an element by xpath i get exception "OpenQA.Selenium.NoSuchElementException: The element could not be found"
I read that with selenium its tricky to click on the svg images.
Is there anybody who know a solution cuz i m kind of desprate and i havent find a suitable solution on the net by myself.
My chart looks like this:
http://i48.tinypic.com/21o4swx.png
What i am trying todo is:
webdriver.Navigate().GoToUrl("http://localhost:59777/Tests/TestsMainView");
IWebElement element = webdriver.FindElement(By.XPath("/html/body/div/div[2]/div[2]/iframe/html/body/div/svg/g[2]/g/g[2]/rect[5]"));
Actions myAction = new Actions(webdriver);
myAction.Click(element).Perform();
Thread.Sleep(9999);
Thanks :)

Here is some advice that may help you. First your second line of code is should be
WebElement element = webdriver.FindElement(By.xpath("//img[contains(#src,'http://i48.tinypic.com/21o4swx.png')]"))
You had "IWebElement" (this was probably just a typo in your question). I changed the way the element is found searching for matching element instead of starting at the top level and working down. This is a better practice to narrow down the element you are attempting to interact with so that changes to the code don't instantly break your test. Also unless you start an xpath expression off with "//" or "xpath=" selenium Webdriver will not recognize it so even if your path never changed selenium Webdriver wouldn't be able to find it.
If I understand what you are trying to do then you can also remove lines 3-5 and replace them with the following,
element.click();
This will have selenium Webdriver zoom in on the chart provided by your link. I hope this helps

I noticed xpath cannot select anything within an svg tag. I managed to find elements using className or tagName selectors instead or you could even try cssSelectors but I am not sure about that one. Note that you can still use xpath to access parents of a node inside an svg using:
By.xpath("..");
Hope that will help.

Related

Getting "Nosuch element Exception" in Selenium Though XPATH is correct. Not sure is this due to Shadow DOM. Please confirm

I am trying to automate Salesforce application Using Selenium and getting NoSuchelementException though XPATH is correct and valid for particular object. When i have searched the issue, it might be reason for Shadow DOM.
For EX:
So XAPTH i have written like,
driver.findElement(By.xpath("//input[#name='Name']")).sendKeys("Jams");
or
driver.findElement(By.xpath("//input[#id='input-299']")).sendKeys("Jams");
This XPATH is highlighting in Console as well. But while automating it throws nosuchelement error.
So while checking for ShadowDOM option, am getting option like this for Name Object.
#shadow-root(user-agent)
Shadowroot DIV
-- nothing mentioned in div. it just open and closed tags.
How to automate this?
You can check if there are any iframes in your Dom. Simply do //iframe in your page developer mode(F12)> elements tab > search (Ctrf+F) area. If there are any, you will get the number of iframes.
Now if your textbox is in any of iframe use below code to go inside particular iframe first
driver.switch_to.frame("<name or Id of frame>")
then come out to frame use below:
driver.switch_to.parent_frame()
Also, if the issue is not related to frames check below for shadow-root related issue:
you can check below for shadow-root element ( Question is for Java, but you can co-relate):
How to interact with the elements within #shadow-root (open) while Clearing Browsing Data of Chrome Browser using cssSelector
The website contents are mostly created now using javascript. You may have to wait for certain elements to load before doing anything to it.
https://seleniumbyexamples.github.io/wait

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

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.

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.

Finding clickon Element using Selenium. (JAVA)

I spend hours already trying to find the way to find the Element using Selenium WebDriver. I assume I need to use driver.findElement(By.xpath("")), but I am not quite sure how.
I somehow need to find and click on "clickon" element. The problem is that part of that element is changing (see screenshot) I need to pick up from the file and putted into the xpath.
I would appreciate any help.
We have been rigorously searching for automated functional testing solutions recently, and we began with Selenium. The entire reason we decided to search for other solutions was that our application also has dynamic IDs with no other obvious XPath mechanism to identify them. Selenium is unable to identify these elements on the page without some additional knowledge, just as you would be unable to identify these elements on the page if you didn't already know what they are.
If you are controlling the DOM creation, consider adding a unique ID or class to this element.
We recently came across eggPlant from testPlant, and it is an interesting approach to functional testing. It's essentially image based. Other viable solutions are Ranorex or HP's QTP or SmartBear's TestComplete.
You can use xpath. If the div class is constant, you can use something like:
driver.findElement(By.xpath("list-row field-item")).click();
To view the xpath, you can install firefox plugin called 'xpath checker' found here and right click on the dom element and click 'View Xpath' option to get the xpath of the element and then you can use that xpath in your code.
Or you can even use regex in the xpath which is suitable for the similar problems. Xpath with regex is really powerful.
It seems that you want to click the div that has the on click attribute that contains certain text that doesn't change, ignoring the part that does. In that case, use an xpath like this:
//div[contains(#onclick, '/challenge/index/rfp_id/')]
This will select the first div with an onclick attribute with a value containing /challenge/index/rfp_id.

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.