selenium webdriver Findelement confused - selenium

I have looked around forum and haven't find right answer for my misunderstanding.
Let's say we have html code:
<h3 id="param_search_0" class="mygray open" data-searchparam="any42" data-id="0">Text here</h3>
So if I get element by tag "h3" like this:
IWebElement get_element = Element_from_above.FindElement(By.Tag("h3"));
What element will I get (select for later use), just text? If yes so how can I select full line element, or seperate, text and inside parameters, from <h3></h3> loop.
Thank you and sorry for this maybe stupid question.

Giving you an answer in Java, as you have not specified the language that you're using:
Suppose that you've created a web-driver instance:
WebDriver driver = new FirefoxDriver();
First, you need to access the web-page in which you are interested, using the URL of that web-page:
driver.get(url);
Then, you can either get the first <h3> element in the web-page:
WebElement element = driver.findElement(By.tagName("h3"));
Or you can get a list of all the <h3> elements in the web-page:
List<WebElement> elements = driver.findElements(By.tagName("h3"));
Then, you can get various attributes of that element.
For example, in order to get "the entire line" as you call it:
String line = element.getAttribute("outerHTML");
For example, in order to get "just the text" as you call it:
String line = element.getAttribute("innerHTML");
And in a similar manner, you can get the value of each and every attribute within the element...

Related

Selenium: How to find text on page containing html tags? (Text Node)

I updated the question after it was answered!
I try to find a text in a list on the webpage, which contains a html tag like <p> text </p>.
Heres a screenshot how it does look like on the webpage:
Screenshot of text to search for
Inside the "inspect" i used //*[text()='<p> First do this, then this</p>'] which could be found as seen above in the screenshot.
In the code im using this codeline to find the text:
webDriver.FindElement(By.XPath("//*[text()='<p> First do this, then this</p>']"))
But during the test run it gives this error message:
OpenQA.Selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":"//*[text()='
First do this, then this']"}
As you can see, selenium does somehow ignore the html tags <p> </p>
Answer and solution from cruisepandey:
Thanks to #cruisepandey i know now, my text is inside a textnode.
The only way to get the text out is using this code:
var ele = webDriver.FindElement(By.XPath("//table[#class='mud-table-root']//tbody/tr[1]/td[2]"));
Console.WriteLine(ele.Text);
The output of this here is:
<p> First do this, then this</p>
That's a text node, you cannot simply use text() method from xpath v1.0
You can try with below xpath :
(//table[#class='mud-table-root']//tbody/tr)[1]/td[2]
Code:
var ele = webDriver.FindElement(By.XPath("//table[#class='mud-table-root']//tbody/tr[1]/td[2]/text()"));
Console.WriteLine(ele.Text);
Code (With explicit waits) : in you want to click on it.
var ele = new WebDriverWait(webDriver, TimeSpan.FromSeconds(20)).Until(ExpectedConditions.ElementToBeClickable(By.XPath("(//table[#class='mud-table-root']//tbody/tr)[1]/td[2]")));
Console.WriteLine(ele.Text);
p is the element tag name, not part of it's text.
Also possibly there are spaces in the text. In this case I prefer using contains instead of exactly equation text check.
Try this instead:
webDriver.FindElement(By.XPath("//p[contains(text(),'First do this, then this')]"))

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/

When and how can I locate an element by tag name using Selenium WebDriver? Please explain with an example

I have used most of the element locators while testing with Selenium, but very low frequently used the 'TagName' locator. Please give an example.
Now supposing, a software web element does not have any ID or Class Name, then how can we locate that element in Selenium WebDriver? The answer is there are many alternatives of the Selenium WebDriver element locators and one of them is locating an element by tag name.
Locating an element by tag name is not too much popular because in most of cases, we will have other alternatives of element locators. But yes, if there is not any alternative then you can use the element's DOM tag name to locate that element in webdriver.
Here you can select the tagname as a locator like:
// Locating the element by tagName and store its text in variable 'dropdown'.
String dropdown = driver.findElement(By.tagName("select")).getText();
Thanks to the deprecation of By.tagName you should use By.css for Shah's answer...
String dropdown = driver.findElement(By.css("select")).getText();
We use the actual name of the tag like <a> for anchor and <table> for table and input for <input>. This helps to get all the elements with a given tag name.
Example: to select the first element of a given input
var dialog = driver.FindElement(By.ClassName("ladialog"));
var save = dialog.FindElements(By.TagName("input"))[0];
save.Click();
Also importantly, the tagName locating strategy can be used to get or fetch all the links on a webpage and print them to console. Try this:
// Get all links in a webpage
List<WebElement> allLinks = driver.findElements(By.tagName("a"));
System.out.println("Links count is: " + allLinks.size());
for(WebElement link : allLinks)
System.out.println(link.getText());

How to locate an element using selenium webdriver which doesn't have unique identifier like Name, Id, title etc?

I am new to Selenium. Not sure how to handle this scenario. I am working on a website which has several buttons with following code,
<a class="Some big class name" datacommunication="SelectItem" token="some token number" model-id="Id1" element="button">
<i class="classname">Book Ticket</i>
</a>
<a class="Some big class name" datacommunication="SelectItem" token="some token number" model-id="Id2" element="button">
<i class="classname">Book Ticket</i>
</a>
I tried to click on it using following commands,
ele = driver.FindElement(By.ClassName("Some big class name")); but it fails with following message, Compound class names are not supported. Consider searching for one class name and filtering the results.
ele = driver.FindElement(By.CssSelector("a[model-id='Id1']")); fails with 'Test method TestBot.HomeTest.bookTicket threw exception:
OpenQA.Selenium.WebDriverTimeoutException: Timed out after 10 seconds'
Tried using XPATH,
ele = driver.FindElement(By.XPath("\\\a[#model-id='Id1']")); doesn't work either.
I have no control on html. Can't change it.
Please let me know how to identify elements in such scenarios.
You can't have spaces in class names. Those are actually multiple classes separated by a space. You can find the above elements using a css selector
var ele = driver.FindElements(By.CssSelector(".Some.big.class.name"))
Of course, this will find both elements. To find just the first, you could use
var ele = driver.FindElement(By.CssSelector("a[model-id='Id1']"))
You can find help on css selectors here: http://www.w3schools.com/cssref/css_selectors.asp
Update:
I just noticed your XPath appears to have the slashes the wrong way around. If you wish to use XPath, try
//a[#model-id='Id1']
Note, however, that css selectors perform better than XPath.
There are multiple number of ways to locate your WebElement in Selenium WebDriver.
But always remember all are based on you attribute or combination of HTML tags so case could be any of them
1- First way is using id
2- 2nd one is Name
3- Class Name
4- Some time you can used Tagname
5- Some time linkText
6- Some time partial link text
7- Using xpath
8- Using css selector
So in you case we need to take help of Xpath and Css Selector
So xpath of you elements
Syntax : //[#attribute ='value of selected tag']
Example
id1: //a[#model-id='Id1']
id2: //a[#model-id='Id2']
For both element following are the css Selector
Syntax [attribute ='value']
id1:
a[model-id='Id1']
id2:
a[model-id='Id2']
http://www.slideshare.net/weekendtesting/css-selector-29312437
http://www.slideshare.net/weekendtesting/locators-in-selenium-bnt-09
Thanks a lot for help. I have used following code to overcome above mentioned issue,
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("a[data-model-id='c5']"))).Click();
With above code, I am able to click on the button.
Thanks again for your help and knowledge sharing.
Amit
You can locate by using xpath.
WebElement ele = driver.findElement(By.xpath("//*[#class='Some big class name']"));
there is difference between findElements and findElement.
FindElement: findElement returns a single element.
FindElements : returns a list of same element.As in this example there are multiple classes with same class name , so use driver.findElements method .
driver.findElements will return a list of all elements with that class name .
Now , you have list of all elements but you want only one of the element.
So iterate over list to get a single element out of a list.
List<WebElement> elementList= driver.FindElement(By.ClassName("Some.big.class.name"));
Iterator itr = elementList.iterator();
while(itr.hasNext())
{
WebElement element = itr.next();
if(element.getAttribute("model-id").equals("Id1")){
element.click();
break;
}//if block ends here
}//while loop ends here
You can also use XPATH , if nothing works
To identify the elements in selenium there are multiple ways.
To see the details please refer BY Class.
Try to find the way which can identify the element uniquely. Start with id if available and if nothing works go for XPATH. XPATH is slower than id and CSS selector.

selenium webdriver code to click on 'Album' in facebook

I am not able to click on 'Albums' in Facebook.
The HTML is Albums how to locate the element 'Albums' in selenium web driver.
I tried with using driver.findelement(By.xpath(span[#class="_3sz"]) showing error as element not found
And, the html looks the following:
<span class="_3sz">Albums</span>
If I am understanding your problem correctly then that xpath you mentioned returns more than one elements. Use a text based search which is more easier and specific.
driver.findelement(By.xpath("//*[.='Albums']").click();
And, here . is used to directly point to the parent element. Additional wait might be needed to wait for the element to interact. Also, I am assuming you are trying to click the element.
EDIT
Driver = new ChromeDriver();
WebDriverWait wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(10));
Driver.Navigate().GoToUrl("http://www.facebook.com");
Driver.Manage().Window.Maximize();
Driver.FindElement(By.CssSelector("#email")).SendKeys("your email");
Driver.FindElement(By.CssSelector("#pass")).SendKeys("your pass");
Driver.FindElement(By.CssSelector("[type='submit'][value='Log In']")).Click();
Driver.FindElement(By.CssSelector(".fbxWelcomeBoxName")).Click();
Driver.FindElement(By.XPath("//*[.='Photos']")).Click();
wait.Until(ExpectedConditions.ElementIsVisible(By.XPath("//*[.='Albums']")));
Driver.FindElement(By.XPath("//*[.='Albums']")).Click();
By albumname = By.XPath("//strong[.='2014']"); //this should be your album name. In my case it's 2014
wait.Until(ExpectedConditions.ElementExists(albumname));
Driver.FindElement(albumname).Click();
wait.Until(ExpectedConditions.ElementExists(By.CssSelector(".fbPhotoAlbumHeader.fbPhotoAlbumOptionsPresent [type='file']")));
Driver.FindElement(By.CssSelector(".fbPhotoAlbumHeader.fbPhotoAlbumOptionsPresent [type='file']")).SendKeys(#"D:\Users\Saifur\Desktop\FacebookPicture\150232_585410621540701_1836495431_a.jpg");
wait.Until(ExpectedConditions.ElementExists(By.CssSelector(".pvm.phl.footerBox.uiBoxWhite")));
Driver.SwitchTo().ActiveElement();
wait.Until(ExpectedConditions.ElementExists(By.CssSelector("[name='postPhotosButton']")));
Driver.FindElement(By.CssSelector("[name='postPhotosButton']")).Click();
Notice mine is C#
It always best practice to follow this sequence while selecting elements.
1) ID
2) CSS
3) XPath (This will have some issues with different browsers specially IE)
In this case, considering this is no other span class with same name. It would have work like this "span._3sz". Simple and powerful.