Visionary founders and management team from GOOG, SFDC, MSFT, AMZN
Overview of Talk Reasons to Switch Overview of Selenium v2 Issues/Workarounds in Selenium v2 Q/A
Selenium v2 Approach Example: driver = webdriver.Firefox() driver.find_element_by_xpath(“//a[text()=‘Create New Ad’”).click() driver.find_element_by_id(“ads_headline”).send_keys(“Selenium Testers Wanted”) Selenium server launches without needing proxy-based approach. Browser driver generates native keyboard/mouse clicks to more closely simulate user behavior. WebDriver API (REST-based) simpler. Browser-specific driver i.e.: IEDriver.dll (IE), webdriver.xpi (Firefox) + WebDriver API
Visibility Matters i.e. driver.find_element_by_id(“cms_toolbar_icon”).click() The X/Y coordinates of the element location are used to determine where to click. Hidden elements can no longer be acted upon until they are visible. The element gets focused and clicked. Some quirky issues with elements at top or bottom of the screen exist. CSS z-index takes precedence now; the top-most element will be the one that receives the mouse event. If you use any type of debug overlay tool (i.eDjango Debug Toolbar, Rails Footnotes, etc.) disable them before running your Selenium tests!
Using Cookies In the Django Debug Toolbar case, we can set a cookie called ‘djdt’ to disable the overlay.
You have to open a connection to the page before you can set the cookie. Exceptions usually get thrown otherwise.
Contrary to the documentation, setting cookies actually requires passing in a dictionary of name, value, and secure parameters.
To set cookies in IE, Protected Mode must be disabled for all zones. IE8 doesn’t appear to throw any exceptions if cookies can’t be set.
Implicit vs. Explicit Waits Implicit Waits vs. Explicit Implicit waits just need to be set once during setup(server-side polling) Use implicit waits for most page loads, assuming you have a unique DOM element present. Implicit waits complete once element present in DOM (click and other mouse events require visible elements). Explicit Waits Remember wait_for_page_load() and wait_for_condition() in Selenium v1? Use explicit waits for all other cases (i.e. popup dialogs that are already rendered in the DOM but aren’t shown, waiting for a DOM element to disappear, etc.): Use WebDriverWait’s anytime you need to avoid JS/database race conditions (client-side polling) Selenium v2.6.0+: ExpectedConditionsclass to handle often-used cases (clickable elements, text present, etc.) driver.implicitly_wait(30) (sets timeout for finding elements) from selenium.webdriver.support.ui import WebDriverWait WebDriverWait(driver, timeout=30).until(lambda driver: driver.find_element_by_css_selector("div.popup.contentul.tabs").is_displayed)) driver.find_element_by_id(“myelement”) driver.find_element_by_css_selector(“#myelement”) driver.find_element_by_xpath(“//div[@id=‘myelement’]”) WebDriverWait(driver, timeout=30).until(lambda x: driver.execute_script(“return jQuery.active === 0”) (wait for Ajax calls to complete)
Demo So how does this implicit/explicit wait stuff work? Let’s play Hearsay Social Says...http://hearsaysocialsays.appspot.com (Selenium v2 source code posted on the site) def play_level(): driver.find_element_by_name("b").click() WebDriverWait(driver, timeout=10).until(lambda driver: driver.find_element_by_name("s").get_attribute("value") == "Player's Turn") pcclicks = driver.execute_script("return pcclicks;") for pcclick in pcclicks[1:]: ele = "pl%s" % pcclick driver.find_element_by_name(ele).click() driver.find_element_by_name("b").click() # Alert box shows up. Let's dismiss it. driver.switch_to_alert() Alert(driver).accept() for i in xrange(20): play_level()
Hover states, drag-and-drop, motion-based gestures, HTML5…. Want more complex sequences of keyboard/mouse actions (i.e. right clicks, double clicks, drag/drop)? Use the ActionChains class. Creating hover states: also done through ActionChains class. Remember, the elements still have to be visible for them to be chained! Many advanced user interactions still somewhat experimental, so expect issues. from selenium.webdriver import ActionChains driver.get(‘http://www.espn.com’) menu_mlb= driver.find_element_by_id("menu-mlb") chain = ActionChains(driver) chain.move_to_element(menu_mlb).perform() chain.move_to_element(menu_mlb).click(scores).perform() (scores is not visible until MLB is selected) scores = driver.find_elements_by_css_selector("#menu-mlb div.mod-content ul li") scores.click()
Earlier blog postsabout Selenium encourage using CSS selectors instead of XPath:
div:contains(“Click here”)vs. //div[text()=“Click here”) Matching by inner text? You still may need to use XPath. CSS selectors supported in Selenium v1 are not standard (i.e. contains()) Selenium v2 relies on document.querySelector() for modern browsers (IE8+, Firefox 3.5+). If document.querySelector() isn’t supported, the Sizzle CSS engine is used. Even if you’re using a CSS3 selector, check whether it’s supported in IE. driver.find_element_by_css_selector(“#ad-summary:last-child") (breaks in IE7) driver.find_element_by_css_selector(“#ad-summary.last") (workaround: explicitly define the last element when rendering the HTML) CSS Selectors in Selenium v2
Other Tips & Tricks… Use Firebug with Selenium v2. Create a profile and installing the extension: firefox -ProfileManager --no-remote (launch profile manager and install Firebug extension) Specify profile directory: profile = FirefoxProfile(profile_directory=“/home/user/.mozilla/firefox/60f7of9x.selenium”) driver = webdriver.Firefox(firefox_profile=profile) Test on local browsers first, use SSH reverse tunneling when testing on remote devservers: Install Selenium server on host machine: java –jar selenium-server.jar (default port 4444) Create a SSH tunnel into remote machine: ssh-nNT -R 9999:<IP address of server>:4444 email@example.com(clients connect to port 9999) Login to remote machine and connect via webdriver.Remote() driver = webdriver.Remote(command_executor=http://localhost:9999/wd/hub) Using SauceLabs? Make sure your max-duration: option is set if your test runs exceed 30 mins. Can’t keep up with the Selenium v2 release cycles? Fix your version with selenium-version: option. Use exit signals handlers to issue driver.quit() commands to see your test results sooner.
Summary Selenium v2 gets closer to simulating the user experience with an entirely new architecture (WebDriver API + browser plug-in/extension). Your tests may start failing on clicking on hidden/non-visible elements, so disable your debug overlays and be aware of CSS z-index issues. Bugs/issues with generating events still persist, and you may encounter many browser quirks (i.e. dropdown boxes). WebDriver may run faster, though you may need to add more synchronization checkpoints with implicit/explicit waits. When using CSS selectors, use the ones supported across all browsers (especially IE).