Selenium automation with xpath for all browsers - selenium

I am new to selenium automation and I am trying to figure out how to handle the code for an element that shows different xpath for different browsers.
//xpath for IE
private readonly By ByPermIE = By.XPath("//*[#id='group-permissions']/div[1]/div[2]/span[2]");
//xpath for chrome
private readonly By ByPermChrome = By.XPath("//*[#id='group-permissions']/div[1]/div[1]/span[2]");
If I am performing some action on this element on different browsers how do I use these elements in the test case. I am planning to extend this to three more browsers. So, should I use if else conditions everywhere? Is there any alternate of best practice for such cases?

You can use below xpath for you case.
private readonly By ByPermChrome = By.XPath("//*[#id='group-permissions']/div[1]//span[text() = 'text that span contains']");

You can write xpath as relative as possible.It is not advisable to write absolute xpaths.
For your above case use below xpath which works in both the browsers.
By.XPath("//*[#id='group-permissions']//span[2]");
or
By.XPath("//*[#id='group-permissions']//span[text()='someThing']");
Refer this for more info regarding xpath.

if u post ur html code, than it will be easy. But as there is no html given, i can suggest u a way like below:
//u can use if condition here
if(driver.findElements(By.XPath("//*[#id='group-permissions']/div[1]/div[2]/span[2]")).size()==1){
//perform operation here
}
else
//perform operation here
This is an alternative way as there is no html code.
If u give the html code, i think we can suggest u more be

One suggestion I can give here is you can use OR conditions in xpaths. Say OR OR .
Xpath OR returns successful as soon it hits the first correct one.

Related

Getting description using selenium xpath

I am trying to get the job description for job search page indeed.com This is how it looks like
Provide technical leadership around
QA
automation to IT teams. Work with various team to promote
QA
processes, practices and standardization....
Any idea how can I get that description? I tried the following:
//span[contains(#class,'summary')]
That does not give me the text description. Should I xpath or is there any other solution? Thanks in advance for your time.
This XPath are correct.
//span[contains(#class,'summary')]
//span[#class='summary']
I'm a Python guy, But I translated it to Java. You can do:
element = driver.findElement(By.name("summary"));
element = driver.findElement(By.className("summary"));
element = driver.findElement(By.cssSelector('span[class="summary"]');
And remember that If you want the element text, every element has the method .getText(), the find* functions only retrieve the element/s.
Double check you were not using driver.findElements(By.xpath()) in plural. In that case you should first retrieve the individual elements. Then access to the .getText() method.
description = driver.findElement(By.className("summary")).getText();
System.out.print(description);
Alternatively you could do:
description = driver.findElement(By.className("summary"));
description_text = description.getAttribute("innerHTML");
System.out.print(description_text);
If your problem is that your element is not visible or reachable (stale). Then you can use javascript.
element = driver.executeScript("return document.querySelector('span[class=\"summary\"]');");
For more reference:
https://seleniumhq.github.io/selenium/docs/api/java/org/openqa/selenium/WebElement.html

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.

in selenium xpath and innerHTML

I am new to selenium. I want to automate the select option present on my webpage. I am trying to use select with xpath. Is it possible to get the innerHTML without having id but only with xpath?
If yes how ? If no then how to solve the issue with select.
Yes, it is possible. Start here: http://www.w3schools.com/xpath/.
And here's a quick dropdown example in python:
from selenium.webdriver import Chrome
SETTINGS_PAGE_URL = 'chrome://settings/browser'
SEARCH_ENGINE_DROPDOWN_ID = 'defaultSearchEngine'
SEARCH_ENGINE_CHOICE_XPATH = '//option[text()="Google"]'
browser = Chrome()
browser.get(SETTINGS_PAGE_URL)
dropdown = browser.find_element_by_id(SEARCH_ENGINE_DROPDOWN_ID)
option = dropdown.find_element_by_xpath(SEARCH_ENGINE_CHOICE_XPATH)
option.click()
Anyways - without the HTML code of the page, I can give you only general advice about XPath. See this page: http://zvon.org/xxl/XPathTutorial/Output/example1.html
It helped me a lot understanding the XPath approach

Finding text on page with Selenium 2

How can I check whether a given text string is present on the current page using Selenium?
The code is this:
def elem = driver.findElement(By.xpath("//*[contains(.,'search_text')]"));
if (elem == null) println("The text is not found on the page!");
If your searching the whole page for some text , then providing an xpath or selector to find an element is not necessary. The following code might help..
Assert.assertEquals(driver.getPageSource().contains("text_to_search"), true);
For some reason, certain elements don't seem to respond to the "generic" search listed in the other answer. At least not in Selenium2library under Robot Framework which is where I needed this incantation to find the particular element:
xpath=//script[contains(#src, 'super-sekret-url.example.com')]
A simpler (but probably less efficient) alternative to XPaths is to just get all the visible text in the page body like so:
def pageText = browser.findElement(By.tagName("body")).getText();
Then if you're using JUnit or something, you can use an assertion to check that the string you are searching for is contained in it.
assertThat("Text not found on page", pageText, containsString(searchText));
Using an XPath is perhaps more efficient, but this way is simpler to understand for those unfamiliar with it. Also, an AssertionError generated by assertThat will include the text that does exist on the page, which may be desirable for debugging as anybody looking at the logs can clearly see what text is on the page if what we are looking for isn't.