Selenium Webdriver Wiki

  1. Selenium Webdriver
  2. Selenium Auto Testing
  3. Selenium Browser Drivers
  4. Selenium Webdriver Download

The InternetExplorerDriver is a standalone server which implements WebDriver's wire protocol. This driver has been tested with IE 7, 8, 9, 10, and 11 on appropriate combinations of Vista, Windows 7, Windows 8, and Windows 8.1. As of 15 April 2014, IE 6 is no longer supported.

The driver supports running 32-bit and 64-bit versions of the browser. The choice of how to determine which 'bit-ness' to use in launching the browser depends on which version of the IEDriverServer.exe is launched. If the 32-bit version of IEDriverServer.exe is launched, the 32-bit version of IE will be launched. Similarly, if the 64-bit version of IEDriverServer.exe is launched, the 64-bit version of IE will be launched.

  1. From selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait # available since 2.4.0 from selenium.webdriver.support import expected_conditions as EC # available since 2.26.0 ff = webdriver.
  2. The advantage to using generators with selenium-webdriver/testing is your code will work with and without the promise manager, so you can convert one test at a time.. Another advantage to this approach is your code will work today with Nod.

Installing

You do not need to run an installer before using the InternetExplorerDriver, though some configuration is required.The standalone server executable must be downloaded from the Downloads page and placed in your PATH.

Pros

  • Runs in a real browser and supports Javascript

Selenium WebDriver is the successor to Selenium RC. Selenium WebDriver accepts commands (sent in Selenese, or via a Client API) and sends them to a browser. This is implemented through a browser-specific browser driver, which sends commands to a browser and retrieves results. SeleniumHQ / selenium. Pull requests 93. Projects 1 Wiki Insights Code. Pull requests 93. Pulse Dismiss. We have two conflicting goals with the WebDriver project. First, we strive to emulate the user as closely as possible. This means using native events rather than simulating the events. The Selenium RC project was merged with the separate WebDriver project to create Selenium WebDriver, also known as Selenium 2.0. The latest version, Selenium 3.0, was released in October 2016. This release replaced the original Selenium Core with one based on the WebDriver, so that it was no longer necessary to install and configure a Selenium.

The WebDriverJS library uses a promise manager to ease the pain of working with a purely asynchronous API. Rather than writing a long chain of promises, the promise manager allows you to write code as if WebDriverJS had a synchronous, blocking API (like all of the other Selenium language bindings). The selenium-webdriver.

Cons

  • Obviously the InternetExplorerDriver will only work on Windows!
  • Comparatively slow (though still pretty snappy :)

Command-Line Switches

As a standalone executable, the behavior of the IE driver can be modified through various command-line arguments. To set the value of these command-line arguments, you should consult the documentation for the language binding you are using. The command line switches supported are described in the table below. All -<switch>, --<switch> and /<switch> are supported.

SwitchMeaning
--port=<portNumber>Specifies the port on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 5555.
--host=<hostAdapterIPAddress>Specifies the IP address of the host adapter on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 127.0.0.1.
--log-level=<logLevel>Specifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.
--log-file=<logFile>Specifies the full path and file name of the log file. Defaults to stdout.
--extract-path=<path>Specifies the full path to the directory used to extract supporting files used by the server. Defaults to the TEMP directory if not specified.
--silentSuppresses diagnostic output when the server is started.
Selenium webdriver wiki

Important System Properties

The following system properties (read using System.getProperty() and set using System.setProperty() in Java code or the '-DpropertyName=value' command line flag) are used by the InternetExplorerDriver:

PropertyWhat it means
webdriver.ie.driverThe location of the IE driver binary.
webdriver.ie.driver.hostSpecifies the IP address of the host adapter on which the IE driver will listen.
webdriver.ie.driver.loglevelSpecifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.
webdriver.ie.driver.logfileSpecifies the full path and file name of the log file.
webdriver.ie.driver.silentSuppresses diagnostic output when the IE driver is started.
webdriver.ie.driver.extractpathSpecifies the full path to the directory used to extract supporting files used by the server. Defaults to the TEMP directory if not specified.

Required Configuration

  • The IEDriverServer exectuable must be downloaded and placed in your PATH.
  • On IE 7 or higher on Windows Vista or Windows 7, you must set the Protected Mode settings for each zone to be the same value. The value can be on or off, as long as it is the same for every zone. To set the Protected Mode settings, choose 'Internet Options...' from the Tools menu, and click on the Security tab. For each zone, there will be a check box at the bottom of the tab labeled 'Enable Protected Mode'.
  • Additionally, 'Enhanced Protected Mode' must be disabled for IE 10 and higher. This option is found in the Advanced tab of the Internet Options dialog.
  • The browser zoom level must be set to 100% so that the native mouse events can be set to the correct coordinates.
  • For Windows 10, you also need to set 'Change the size of text, apps, and other items' to 100% in display settings.
  • For IE 11 only, you will need to set a registry entry on the target computer so that the driver can maintain a connection to the instance of Internet Explorer it creates. For 32-bit Windows installations, the key you must examine in the registry editor is HKEY_LOCAL_MACHINESOFTWAREMicrosoftInternet ExplorerMainFeatureControlFEATURE_BFCACHE. For 64-bit Windows installations, the key is HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftInternet ExplorerMainFeatureControlFEATURE_BFCACHE. Please note that the FEATURE_BFCACHE subkey may or may not be present, and should be created if it is not present. Important: Inside this key, create a DWORD value named iexplore.exe with the value of 0.

Native Events and Internet Explorer

As the InternetExplorerDriver is Windows-only, it attempts to use so-called 'native', or OS-level events to perform mouse and keyboard operations in the browser. This is in contrast to using simulated JavaScript events for the same operations. The advantage of using native events is that it does not rely on the JavaScript sandbox, and it ensures proper JavaScript event propagation within the browser. However, there are currently some issues with mouse events when the IE browser window does not have focus, and when attempting to hover over elements.

Browser Focus

The challenge is that IE itself appears to not fully respect the Windows messages we send the IE browser window (WM_MOUSEDOWN and WM_MOUSEUP) if the window doesn't have the focus. Specifically, the element being clicked on will receive a focus window around it, but the click will not be processed by the element. Arguably, we shouldn't be sending messages at all; rather, we should be using the SendInput() API, but that API explicitly requires the window to have the focus. We have two conflicting goals with the WebDriver project.

First, we strive to emulate the user as closely as possible. This means using native events rather than simulating the events using JavaScript.

Second, we want to not require focus of the browser window being automated. This means that just forcing the browser window to the foreground is suboptimal.

An additional consideration is the possibility of multiple IE instances running under multiple WebDriver instances, which means any such 'bring the window to the foreground' solution will have to be wrapped in some sort of synchronizing construct (mutex?) within the IE driver's C++ code. Even so, this code will still be subject to race conditions, if, for example, the user brings another window to the foreground between the driver bringing IE to the foreground and executing the native event.

The discussion around the requirements of the driver and how to prioritize these two conflicting goals is ongoing. The current prevailing wisdom is to prioritize the former over the latter, and document that your machine will be unavailable for other tasks when using the IE driver. However, that decision is far from finalized, and the code to implement it is likely to be rather complicated.

Hovering Over Elements

When you attempt to hover over elements, and your physical mouse cursor is within the boundaries of the IE browser window, the hover will not work. More specifically, the hover will appear to work for a fraction of a second, and then the element will revert back to its previous state. The prevailing theory why this occurs is that IE is doing hit-testing of some sort during its event loop, which causes it to respond to the physical mouse position when the physical cursor is within the window bounds. The WebDriver development team has been unable to discover a workaround for this behavior of IE.

Clicking <option> Elements or Submitting Forms and alert()

There are two places where the IE driver does not interact with elements using native events. This is in clicking <option> elements within a <select> element. Under normal circumstances, the IE driver calculates where to click based on the position and size of the element, typically as returned by the JavaScript getBoundingClientRect() method. However, for <option> elements, getBoundingClientRect() returns a rectangle with zero position and zero size. The IE driver handles this one scenario by using the click() Automation Atom, which essentially sets the .selected property of the element and simulates the onChange event in JavaScript. However, this means that if the onChange event of the <select> element contains JavaScript code that calls alert(), confirm() or prompt(), calling WebElement's click() method will hang until the modal dialog is manually dismissed. There is no known workaround for this behavior using only WebDriver code.

Selenium Webdriver

Similarly, there are some scenarios when submitting an HTML form via WebElement's submit() method may have the same effect. This can happen if the driver calls the JavaScript submit() function on the form, and there is an onSubmit event handler that calls the JavaScript alert(), confirm(), or prompt() functions.

This restriction is filed as issue 3508 (on Google Code).

Multiple instances of InternetExplorerDriver

With the creation of the IEDriverServer.exe, it should be possible to create and use multiple simultaneous instances of the InternetExplorerDriver. However, this functionality is largely untested, and there may be issues with cookies, window focus, and the like. If you attempt to use multiple instances of the IE driver, and run into such issues, consider using the RemoteWebDriver and virtual machines.

There are 2 solutions for problem with cookies (and another session items) shared between multiple instances of InternetExplorer.

The first is to start your InternetExplorer in private mode. After that InternetExplorer will be started with clean session data and will not save changed session data at quiting. To do so you need to pass 2 specific capabilities to driver: ie.forceCreateProcessApi with true value and ie.browserCommandLineSwitches with -private value. Be note that it will work only for InternetExplorer 8 and newer, and Windows Registry HKLM_CURRENT_USERSoftwareMicrosoftInternet ExplorerMain path should contain key TabProcGrowth with 0 value.

The second is to clean session during InternetExplorer starting. For this you need to pass specific ie.ensureCleanSession capability with true value to driver. This clears the cache for all running instances of InternetExplorer, including those started manually.

Running IEDriverServer.exe Remotely

The HTTP server started by the IEDriverServer.exe sets an access control list to only accept connections from the local machine, and disallows incoming connections from remote machines. At present, this cannot be changed without modifying the source code to the IEDriverServer.exe. To run the Internet Explorer driver on a remote machine, use the Java standalone remote server in connection with your language binding's equivalent of RemoteWebDriver.

Running IEDriverServer.exe Under a Windows Service

Attempting to use IEDriverServer.exe as part of a Windows Service application is expressly unsupported. Service processes, and processes spawned by them, have much different requirements than those executing in a regular user context. IEDriverServer.exe is explicitly untested in that environment, and includes Windows API calls that are documented to be prohibited to be used in service processes. While it may be possible to get the IE driver to work while running under a service process, users encountering problems in that environment will need to seek out their own solutions.

Introduction

The WebDriverJS library uses a promise manager to ease the pain of working with a purely asynchronous API. Rather than writing a long chain of promises, the promise manager allows you to write code as if WebDriverJS had a synchronous, blocking API (like all of the other Selenium language bindings). For instance, instead of

you can write

Unforutnately, there is no such thing as a free lunch. With WebDriverJS, using the promise manager comes at the cost of increased complexity (for the Selenium maintainers--the promise module is a 3300 line beast) and reduced debuggability. For debugging, suppose you inserted a debugger statement:

When is this script going to pause - after WebDriver loads google.com, or after it schedules the command to load google.com? Since the promise manager abstracts away the async nature of the API, it hides that you need to expicitly use a callback to break after a command executes:

JavaScript has evolved in many ways since WebDriverJS was originally created. Not only did the community standardize the behavior and API for promises, but promises were added to the language itself. The next version of JavaScript, ES2017, adds support for async functions, greatly simplyfing the process of writing and maintaining asynchronous code. At this point, the benefits of the promise manager no longer outweigh its costs, so it will soon be deprecated and removed from WebDriverJS. The remainder of this guide will explain how users can migrate off the promise manager and effectively use the async constructs available today.

Moving to async/await

Step 1: Disabling the Promise Manager

As outlined in issue 2969, WebDriverJS' promise manager will be deprecated and disabled by default with the first Node LTS release that includes native support for async functions. This feature is currently available in Node 7.x, hidden behind the --harmony_async_await flag.

Selenium Auto Testing

Instead of waiting for the LTS, you can disable the promise manager today either by setting an environment variable, SELENIUM_PROMISE_MANAGER=0, or through the promise module's API (promise.USE_PROMISE_MANAGER = false).

When the promise manager is disabled, any attempt to create a managed promise will generate an error, so expect your scripts to fail the first time you try running with the promise manager.

Step 2: Migrate Direct Usages of Managed Promises

Search your code for every instance where you create a promise.Promise object, either using the constructor, or the resolve/reject factories. Replace these calls with the equivalent listed in the table below. These functions will automatically switch from managed to native promises when the promise manager is disabled.

OriginalReplacement
new promise.Promise()promise.createPromise()
promise.Promise.resolve()promise.fulfilled()
promise.Promise.reject()promise.rejected()

Step 3: Migrate Off of the Promise Manager

At this point, you should be ready to migrate off of the promise manager. Unfortunately, there's no automated way to update your code; you basically have to disable the promise manager, see what fails, update some code, and try again. To understand how your code will, fail, consider a test for our Google Search example:

Inside theTestFunction, when the promise manager is enabled, it will capture every WebDriver command and block its execution until those before it have completed. Thus, even though driver.findElement() on line (2) is immediately scheduled, it will not start execution until the command on line (1) completes.

When you disable the promise manager, every command will start executing as soon as its scheduled. The exact behavior depends on the specific browser, but essentially, the command to find an element on line (2) will start executing before the page requested on line (1) has loaded.

You will need to update your code to explicitly link each action so it does not start until previous commands have finished. Presented below are three options for how to update your code.

Option 1: Use classic promise chaining

Your first option is to adopt classic promise chaining (yes, the very thing the promise manager was created to avoid). This will make your code far more verbose, but it will work with and without the promise manager and you won't need to use the selenium-webdriver/testing module for mocha-based tests.

Option 2: Migrate to Generators

Your second option is to update your code to use asynchronouse generator functions. The selenium-webdriver/testing module already handles these out of the box. You can also use third-party libraries like task.js for the same effect. Basically, change each of your test functions to a generator, and yield on a promise. The generator wrapper will transparently wait for the promise to resolve before resuming the function. It's important to note, however, asynchronous generators are not currently supported natively in JavaScript, so you will have to use selenium-webdriver or another library for this to work.

The advantage to using generators with selenium-webdriver/testing is your code will work with and without the promise manager, so you can convert one test at a time. Another advantage to this approach is your code will work today with Node 6 & 7. When async/await support is added to Node (it's currently hidden behind a flag in Node 7), you can migrate from generators with find-and-replace, converting function*() to async function() and yield to await.

Selenium Webdriver Wiki

The selenium-webdriver/example directory contains an example of our Google Search test written with and without generators so you can compare the two side-by-side.

Option 3: Migrate to async/await

Your final option is to switch to async/await. As mentioned above, these language features are currently hidden behind a flag in Node 7, so you will have to run with --harmony_async_awaitor you will have to transpile your code with Babel (setting up Babel is left as an exercise for the reader).

Compared to generators, there is one more catch to using async/await: they do not play well with the promise manager, so you must ensure the promise manager is disabled. There is a complete working example of a test written using async/await provided in the selenium-webdriver/example directory:

This example disables the promise manager globally. In order to migrate tests bit-by-bit, you can selectively disable the promise manager in before/after blocks:

Selenium Browser Drivers

Miscellaneous Tips

Use Logging To Find Unmigrated Code

Selenium Webdriver Download

While the promise manager can be easily toggled through an enviornment variable, constantly running your code in the two modes can be tedious. Selenium's promise module provides logging to report every instance of unsynchronized code running through the promise manager (which, in code, is actually called the ControlFlow). You can enable this logging, then work through the messages to update each instance of commands that have not be properly chained (depending on the option you chose above).

Enabling logging is only two extra lines:

With logging, the example above will produce messages like: