How to select radiobutton through #FindBy annotation in selenium webdriver - selenium

While designing page object class we use #FindBy(name="value") i.e FindBy with name.
SO below code to find an webpage's textbox like username field.
#FindBy(name="username")
WebElement txtboxUname;
........//Inside testfunction we call this txtboxUname like below
txtboxuname.sendKeys("purnendu");
So for radio button page object how we define it through #FindBy???
Following code is not working
#FindBy(name="radio")
List<WebElement> radioBtnSelectTrip;
.......call inside function
radioBtnSelectTrip.get(0).click();
The above #FindBy technique is not working for radio button.can you please help how to define radiobutton through #FindBy and use it through Pagefactory

There are several techniques for UI mapping. While using #FindBy to map UI elements it is possible to map the element with xpath. However, you want to make sure the xpath is correct and only returns the target radio. See an example of how to find an element with xpath here
Explore more about the Annotation Type FindBy here
And,
#FindBy(name="radio")
List<WebElement> radioBtnSelectTrip;
will not return you ONE radio rather a list. To perform an action on a specific radio you need to add additional filter. such asif condition to match a unique criteria on the target radio button.
Edit Added code to explore how FindBy can be implementation in finding a specific radio
#FindBy(how = How.CSS, using = "[type='radio'][value='roundtrip']")
public WebElement roundTrip;
#FindBy(how = How.CSS, using = "[type='radio'][value='oneway']")
public WebElement oneWay;

You have a typo. If you want to return a radio button, you probably want to select by it's type: #FindBy(xpath="//input[#type='radio']").

Related

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/

Can we use click() functionality along with sendKeys()?

Can we use Click() functionality along with sendKeys()??
I just read a drop-down value using xpath and now i need to click on the particular value i have read. Actually its possible to use in two steps. But is there any option to read and click in a single code??
Thanks,
SK
Kindly try with this. I have used Enter key as a substitute for clicking.
driver.findElement(By.xpath("xpath")).sendKeys("Talk-Talk",K‌​eys.ENTER);
Hope this helps. Thanks.
If your requirement is to select some specific option in dropdown then use select class.
Go though this article for more info
But if you want to click on some element and then send some text, then you can user Action class.
WebElement wb = driver.findElement(By.xpath("your xpath"));
Actions action = new Actions(driver);
action.moveToElement(wb).click().moveToElement(wb,200, 0).sendkeys("text").build().perform();//you need to specify where you need to send text 200,0 is just as an example
Actions action = new Actions(driver);
WebElement MobileNumber = driver.findElement(By.xpath("yourxpath"));
action.moveToElement(MobileNumber).click().sendKeys("your text").build().perform();
Following the Java Docs, click() method returns void as follows:
void click()
Similarly, sendKeys() method also returns void as follows :
void sendKeys(java.lang.CharSequence... keysToSend)
So as per best programming practice we must not try to club-up click() method with sendKeys() method or vice versa. It would be ideal to achieve the intended task in two separate steps.

Page Factory #FindBy

I am currently learning page object model (POM) and I am trying to access a specific web element using #FindBy but I am not sure how to correctly write the syntax for my element into #FindBy?
What I have is:
driver.findElement(By.cssSelector("a[dta-qid='inventory']");
So my question is how do I place a[da-qid='inventory'] correctly into #FindBy?
By, a[da-qid='inventory'], what I mean is that it selects every <a> element whose da-qid value begins with 'inventory'.
Why do not you read through this? Use of #FindsBy is easier if you do that with How Enum. You have multiple options in that case. With cssSelector it should look like this
#FindBy(how = How.css, using = "a[dta-qid='inventory']")
WebElement foobar;
If you assume that multiple elements will be found using this selector, try the following:
#FindBy(css="a[da-qid='inventory']")
List<WebElement> elements;
Just don't forget to choose correctly between da-qid='inventory' and dta-qid='inventory'
You could use the XPath selector:
driver.findElement(By.xpath("//a[contains(#da-qid,'inventory')]");
or
#FindBy(xpath = "//a[contains(#da-qid,'inventory')]")
WebElement inventoryLink;
respectively
#FindAll(xpath = "//a[contains(#da-qid,'inventory')]")
List<WebElement> inventoryLinks;
Theoretically the XPath "//a[startsWith(#da-qid,'inventory')]" exists as well, but it didn't work in all WebDrivers for me.

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.

how to identify an object with the same name with name property

I want to find out an object with same name with different value? Here i am interested to identify based on the name only. Do we have index like property provided in QTP. In QTP, if two buttons with same can be distinguished by index, first button with index 0 and second button with 1.
Is there way to do the same in WebDriver?
I want to identify object with name meaning "By.name". How can i do that?
Thanks,
Uday
There are multiple options to achieve it (examples in java):
using findElements and get the appropriate element from the list of resulting web elements:
List<WebElement> elements = driver.findElements(By.name("test"));
WebElement element = elements.get(0);
use xpath based approach (indexing starts from 1 here):
WebElement element = driver.findElement(By.xpath('//input[#name="test"][1]'));
You can also use jQuery style syntax in your search..
For example in Chrome tools $('css selector')[0] will get you the first occurrence of some element.
Selenium comes with a JavaScript driver so you could instantiate that and use that against your site to leverage jQuery.