0
votes

I am trying to get Selenium, specifically WebDriver v2.31, to interact with Google Maps. I able to get as far as clicking the [first] Get Directions button to enter a pair of addresses and then click the Get Directions button under the two addresses. This results in a set of driving directions. What I cannot do is get Selenium to scroll to the bottom of the "Directions" panel so I can see the destination and the Save to My Maps link. I don't know if the problem arises because the scroll bar is generated by the browser.

I am able to perform a search on Yahoo! and scroll to the bottom of the results webpage; I think it is because there are no other frames or panels in the webpage's architecture. Although that being said, the browser generated the scroll bar, not the webpage.

I can build an Action with the mouse holding down and dragging the scroll bar down. I don't like that solution because if the page is sized differently or the panel is sized differently, it will cause a lot of recalculation to perform this action. I would prefer a solution that is similar to the single "document" window in Yahoo! or Google Code.

Any help would be greatly appreciated. I have been racking my brain over the internet for the last three days searching for a solution.

Thanks.

Steve

Addendum: As noted below. I am not trying to do anything with the map itself but rather the panel that contains the directions. I am using Google Maps because it is similar to an application I will have to test later. I need the ability to have [Selenium] WebDriver scroll to the bottom of the panel so I can select a "Next" link -- just like scrolling to the bottom of the Directions panel in Google Maps and seeing the Save link at the bottom.

I am not sure if I am using the correct terminology when I use the term panel. The problem is that it appears the panel generates the scroll bar dynamically when the web page is displayed.

driver.switchTo().frame(driver.findElement(By.id("spsizer")));
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("javascript:window.scrollBy(250,750)", element);
driver.switchTo().defaultContent();

Unfortunately the "panel" is not contained in a frame or is a frame ... as identified by the exception returned by Selenium:

 Exception in thread "main" org.openqa.selenium.NoSuchFrameException: Element is not a frame element: DIV

I believe I have determined that panel has an ID ("spsizer") using FireBug.

This also does not work:

element = driver.findElement(By.id("spsizer"));
JavascriptExecutor js = (JavascriptExecutor)driver;
js.executeScript("javascript:window.scrollBy(250,750)", element);

This just executes without scrolling to the bottom of the Directions panel but it also doesn't throw an exception.

2

2 Answers

1
votes

I am able to Save to My Maps link with following code given in below screen shot.

There is no need to have a recorded step to scroll down the panel, Selenium can locate and do actions on any web object in a Web page without being visible to the user.

enter image description here

Details of the code:

Line6: Command- waitForVisible Target- //div[@id='dir_sr']/a[@id='srlink']

I have added waitForVisible so that Selenium will wait for 5 seconds before the link Save to My Maps is visible. This will give enough synchronization time for the page to load after pressing the Get Directions button. //div[@id='dir_sr']/a[@id='srlink'] is the XPath locator for link Save to My Maps

Line7: Command- click Target- //div[@id='dir_sr']/a[@id='srlink']

Click on link Save to My Maps

Line8: Command- click Target- //button[@id='srsave']

Click on button Save

C#.Net WebDriver code for the same. Note that Google account User Name and Password has to be provided to save the map link.

using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;

namespace SeleniumTests
{
    public class GoogleMapSavingTest
    {
          static void Main(string[] args)
          {
              IWebDriver driver = new FirefoxDriver();
              driver.Navigate().GoToUrl("https://maps.google.com.au/");
              driver.FindElement(By.Id("d_launch")).Click();
              driver.FindElement(By.Id("d_d")).Clear();
              driver.FindElement(By.Id("d_d")).SendKeys("Franklin, ACT");
              driver.FindElement(By.Id("d_daddr")).Clear();
              driver.FindElement(By.Id("d_daddr")).SendKeys("Gungahlin, ACT");
              driver.FindElement(By.Id("d_d")).Click();
              driver.FindElement(By.Id("d_sub")).Click();
              for (int second = 0;; second++) 
              {
                    if (second >= 60) Assert.Fail("timeout");
                     try
                     {
                        if  (driver.FindElement(By.XPath("//div[@id='dir_sr']/a[@id='srlink']")).Displayed) break;
                    }
                    catch (Exception)
                    {}
                    Thread.Sleep(1000);
                }
             driver.FindElement(By.XPath("//div[@id='dir_sr']/a[@id='srlink']")).Click();
                driver.FindElement(By.Id("Email")).SendKeys("UserName");
                driver.FindElement(By.Id("Passwd")).SendKeys("Password");
                driver.FindElement(By.Id("signIn")).Click();
                for (int second = 0; ; second++)
                {
                    if (second >= 60) Assert.Fail("timeout");
                    try
                    {
                        if (driver.FindElement(By.XPath("//div[@id='dir_sr']/a[@id='srlink']")).Displayed) break;
                    }
                    catch (Exception)
                    { }
                    Thread.Sleep(1000);
                }
             driver.FindElement(By.XPath("//div[@id='dir_sr']/a[@id='srlink']")).Click();
            driver.FindElement(By.XPath("//button[@id='srsave']")).Click();


          }





}

}

0
votes

I know that there is a extension to Selenium that someone created on GitHub that is designed for automating map applications but I don't remember how to find it. I saw it though while browsing GitHub a few weeks ago and it uses image recognition via javascript ( I am not referring to Sikuli) . I think what you are looking for exists if you look hard enough for it.

I would avoid Sikuli if you are using a remote Grid, otherwise it might work for you. Also, when iframes are involved, it's a good idea to always try JavaScriptExecutor (with a switchTo frame) before you give up on automating the frame.

Until then, you can start by looking at WebDriverJS . Also, GhostDriver might be worth looking at even if it is just to get ideas.