How to locate search links in google in Selenium for testing - selenium

I am trying to search Google for Selenium, then run down the list of links by clicking each one, printing the page title, then navigating back.
List<WebElement> linkElements = driver.findElements( **<insert code here>** );
for(WebElement elem: linkElements)
{
String text = elem.getText();
driver.findElement(By.linkText(text)).click();
System.out.println("Title of link\t:\t" + driver.getTitle());
driver.navigate().back();
}
To find the elements, I have tried By.tagName("a") which doesn't work because it gets ALL the links, not just the search ones. Using Firebug, I see that each search link has a class of r used on the header h3, and the a tag nested inside it.
See the following:
<h3 class="r">
<a href="/url sa=t&rct=j&q=selenium&source=web&cd=1&cad=rja&ved=0CC8QFjAA&url=http%3A%2F%2Fseleniumhq.org%2F&ei=y4eNUYiIGuS7iwL-r4DADA&usg=AFQjCNHCelhj_BWssRX2H0HZCcPqhgBrRg&sig2=WBhmm65gCH7RQxIv9vgrug&bvm=bv.46340616,d.cGE" onmousedown="return rwt(this,'','','','1','AFQjCNHCelhj_BWssRX2H0HZCcPqhgBrRg','WBhmm65gCH7RQxIv9vgrug','0CC8QFjAA','','',event)"><em>Selenium</em> - Web Browser Automation
</a></h3>
What code can I insert to make this work?

You have a lot of solution for doing it. There's mine. You keep your way like
// You get all links in a list
List<WebElement> linkElements = driver.findElements(By.xpath("//h3/a"));
// for each element(link) you click() on it
for(WebElement elem: linkElements)
{
elem.click();
// i suggest to put a wait right there
System.out.println("Title of link\t:\t" + driver.getTitle());
driver.navigate().back();
}
i don't know why you were trying to complicate with getText() etc.

Try below New Code
WebDriver driver;
driver = new FirefoxDriver();
driver.get("http://www.google.com");
driver.findElement(By.id("gbqfq")).sendKeys("Selenium");
Thread.sleep(1500L);
driver.findElement(By.id("gbqfb")).click();
Thread.sleep(1500L);
List<WebElement> linkElements = driver.findElements(By.xpath("//h3[#class='r']/a"));
for(int i=0;i<=linkElements.size();i++)
{
String text = linkElements.get(i).getText();
driver.findElement(By.linkText(text)).click();
Thread.sleep(2000L);
System.out.println("Title of link\t:\t" + driver.getTitle());
Thread.sleep(2000L);
driver.navigate().back();
linkElements = driver.findElements(By.xpath("//h3[#class='r']/a"));
}

try searching for this selector:
'.g:nth-child('+clickPosition+') h3.r a'
where "clickPosition" is the SERP result array key. Careful though, google now implements an "onmousedown" event that will change the href attribute to their redirect.

Related

Send keys not working , right xpath and id (Selenium)

Tried sendomg keys , right relative xpath or ID used but still not working properly
Tried using absolute xpath , relative xpath also ID. Tried using selassist and chropath still not working. Could there be something preventing it?
public void LoginWebSystem() {
driver = new ChromeDriver();
driver.get("http://localhost:82");
WebElement email = driver.findElement(By.id("login_username"));
email.sendKeys("superadmin");
System.out.println("Username Set");
WebElement password = driver.findElement(By.id("login_password"));
password.sendKeys("nelsoft121586");
System.out.println("Password Set");
WebElement login = driver.findElement(By.id("login_submit"));
login.click();
System.out.println("Login Button Clicked");
String newUrl = driver.getCurrentUrl();
if(newUrl.equalsIgnoreCase("http://localhost:82/controlpanel.php")){
System.out.println("Login Success");
}
else {
System.out.println("Login Failed");
}
driver.findElement(By.partialLinkText("Product")).click();
System.out.println("Successful in proceeding to Product Page");
driver.findElement(By.id("createlink")).click();
System.out.println("Successful in proceeding to Create Product by Detailed");
driver.switchTo().alert().accept();
System.out.println("Successful in clicking alert button");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
}
#Test (priority=1)
public void ProductDetails() {
WebElement product = driver.findElement(By.xpath(" //*[#id="text-product"]"));
product.sendKeys("superadmin");
}
}
Expected output should input superadmin to product textbox
You have a typo in your XPath expression:
WebElement product = driver.findElement(By.xpath(" //*[#id="text-product"]"));
^ remove this space break
It's better to use By.Id locator strategy where possible as this is the fastest and the most robust way of identifying elements in DOM
Consider using Explicit Wait to ensure that the element is present and can be interacted with as it might be the case the element becomes available after document.readyState becomes complete. Check out How to use Selenium to test web applications using AJAX technology article for more detailed explanation.
new WebDriverWait(driver, 10)
.until(ExpectedConditions.elementToBeClickable(By.id("text-product")))
.click();
Make sure that your selector matches an <input> because if the id belongs to other element type like <div> it doesn't make a lot of sense to send keys there.

Selecting a drop down option

I'm simulating a mobile phone browser and tryng to select a dropdown item.
I'm using a css selector to find the combobox, when I check that css selector in the developers tool is found but not in my code
List<WebElement> linkElements = driver.findElements(By
.cssSelector(".show-deals-wrapper select"));
for (WebElement element : linkElements) {
if (element.isDisplayed()
&& ("Pay Monthly").equals(element.getText())) {
element.click();
break;
}
}
The web is https://www.o2.co.uk/shop in mobile version.
I'm really new in Selenium, learning bit a bit. Sorry if the question is so easy.
Many thanks in advance.
Regards
You can use javascript to make the element visible first. then do your job as it is and finally make that element invisible again. see the code portion below:
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("document.getElementById('elementID').style.display='block'");
Select select = new Select(driver.findElement(elementID));
select.selectByIndex(pos);
js.executeScript("document.getElementById('elementID').style.display='none'");
I think this will help you.
This is how I handle selects with webdriver. I hope this helps. Also I am using python
Select(driver.find_element_by_css_selector('.show-deals-wrapper.select')).select_by_visible_text("Pay Monthly")
u can aslo do like below:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollBy(0,300)", "");
driver.findElement(By.id("dataFilterSelectSelectBoxItArrowContainer")).click();
List<WebElement> linkElements = driver.findElements(By
.cssSelector(" #dataFilterSelectSelectBoxItOptions>li>a"));
System.out.println("size is "+linkElements.size());
for (WebElement element : linkElements) {
System.out.println("size is "+element.getText());
if (("ur text").equals(element.getText())) {
element.click();
break;
}
}
this will click on what sort tariff u want.

FindallElements using className does not work but using the same code with xpath works

For practice I was working on code and faced a very strange problem. I am trying to find the list of all elements using className. When I check the list size it returned me 0 but the same class when used with xpath works. My code is below
WebDriver driver = new FirefoxDriver();
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://www.localbanya.com/home/search?searchKeyword=dove");
driver.findElement(By.xpath("//*[#class='ms-choice']")).click();
Thread.sleep(2000);
driver.findElement(By.xpath("//*[#class='ms-drop bottom']//li[4]/label")).click();
driver.findElement(By.cssSelector(".proceed-button.button")).click();
Thread.sleep(1000);
List<WebElement> prList = driver.findElements(By.xpath("//*[#class='prName']"));
// This particular code does not work but same class name used above works
//----Interesting not working
//List<WebElement> prList = driver.findElements(By.className(".prName"));
System.out.println(prList.size());
for (WebElement web : prList)
{
System.out.println(web.getText());
}
//driver.close();
}
List<WebElement> prList = driver.findElements(By.className("prName"));
It will work, no need to use . while you are using By.className. . is required when you use css selector.

StaleElementReferenceException when trying to reidentify the object

I am facing problem to identify the object when i move forward and comeback to parent page.
Here is the scenario. I would like to click on each link in a home page and print page title and navigate back to home page.
Following is the code which i tried. It works fine clicking on the first link and coming back to HomePage. At this point of time, the List Object needs to be identified excluding already visited links. How to do that?
In QTP, we have RefreshObject and Init to do this. Is there a similar method in WebDriver?
WebDriver driver = new FirefoxDriver();
driver.get("http://www.googl.com/");
driver.manage().window().maximize();
List<WebElement> objWEs = driver.findElements(By.tagName("a"));
for(WebElement e:objWEs)
{
if(!e.getText().isEmpty())
{
e.click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
}
driver.close();
As soon as you navigate to another web-page, or even switch into an iframe in the same web-page, any WebElement object that you have in memory is potentially "stale".
One optional solution, is to list down all the element IDs, and then iterate that list instead:
Set<String> linkIds = new HashSet<String>();
List<WebElement> links = driver.findElements(By.tagName("a"));
for (WebElement link : links)
{
if(!link.getText().isEmpty())
linkIds.add(link.getAttribute("id"));
}
for (String linkId : linkIds)
{
driver.findElement(By.id(linkId)).click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
Please note, however, that all the above is under the assumption that each link has a unique ID, and that all the links remain in the web-page when you navigate back into it. If this is not the case in the specific web-page that you are accessing, then an alternative approach is required here.
Instead of iterating the link-IDs, you can iterate the link-indexes, assuming that the links remain in the same order when you navigate in and out of the web-page. This is somewhat less efficient though, because you have to retrieve the entire list of all the links at the beginning of each iteration.
for (int i=0; true; i++)
{
List<WebElement> links = driver.findElements(By.tagName("a"));
if (i >= links.size())
break;
links.get(i).click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
The code above should work even if the links do not remain in the same order when you navigate back into the web-page. However, under such scenario, you will most likely miss out on some of them.
Here is the complete code for my above problem.
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(1, TimeUnit.MINUTES);
driver.get("http://www.googl.com/");
driver.manage().window().maximize();
for (int i=0; true; i++)
{
List<WebElement> links = driver.findElements(By.tagName("a"));
if (i >= links.size())
break;
WebElement ele=links.get(i);
if(!ele.getText().isEmpty())
{
ele.click();
System.out.println(driver.getTitle());
driver.navigate().back();
}
}
driver.close();

selenium span link li not working

I am new to selenium. I am practicing to write a test case on http://www.countdown.tfl.gov.uk. Below are the steps I followed:
a) I opened the browser to selenium Web Driver
b) Found the search text Box and enter H32 and clicked on search button to selenium.
Till this part it works fine.
Now on the page I am actually getting two records on the left side of the page under the search. I am actually trying to click on the first one i.e. "Towards Southall,Townhall" link. Nothing is happening.
Below is my code:
public class CountdownTest {
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver)
}
//open the countdowntfl page
private WebDriver openWebDriver(){
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.get("http://www.countdown.tfl.gov.uk");
return driver;
}
private void searchforBus(WebDriver driver,String search){
WebElement searchBox = driver.findElement(By.xpath("//input[#id='initialSearchField']"));
searchBox.sendKeys(search);
WebElement searchButton = driver.findElement(By.xpath("//button[#id='ext-gen35']"));
searchButton.click();
}
private void selectrouteDirection(WebDriver driver){
WebElement towardssouthallLink= driver.findElement(By.xpath("//span[#id='ext-gen165']']"));
((WebElement) towardssouthallLink).click();
}
}
Please help me.
Thanks.
Since you are getting NoSuchElement Exception now, you may try the following code with the usage of WebDriver explicit wait.
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement towardssouthallLink = wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("(//*[#id='route-search']//li/span)[1]")));
towardssouthallLink.click();
Or WebDriver implicit wait
WebDriver driver = WebDriverFactory.getWebDriver("FireFox");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get("http://www.countdown.tfl.gov.uk");
Tips:
The search results need some time to be retrieved, so please use Explicit wait or Implicit wait.
Don't use locators like span[#id='ext-gen165'], they are ExtJs auto generated.
In this case, css selector can also be used: #route-search li:nth-of-type(1) > span
You aren't calling selectrouteDirection.
You probably want:
#Test
public void tflpageOpen(){
WebDriver driver = openWebDriver();
searchforBus(driver,"H32");
selectrouteDirection(driver);
}
You also don't need to cast here:
((WebElement) towardssouthallLink).click();
It's already a WebElement anyway.
I found that id for those links are dynamically generated. ids are of the form 'ext-genXXX' where XXX is number which is dynamically generated hence varies each time.
Actually, you should try with linkText:
For 'Towards Southall, Town Hall'
driver.findElement(By.linkText("Towards Southall, Town Hall")).click
For 'Towards Hounslow, Bus Station'
driver.findElement(By.linkText("Towards Hounslow, Bus Station")).click
Here is a logic:
Get all elements which have id starts with 'ext-gen' & iterate over it & click on link with matching text. Following is Ruby code(sorry, I don't know Java well):
links = driver.find_elements(:xpath, "//span[starts-with(#id, 'ext-gen')]")
links.each do |link|
if link.text == "Towards Southall, Town Hall"
link.click
break
end
end