WEBDRIVER
The biggest change in Selenium recently has been the inclusion of the WebDriver API. Driving a browser natively as a user would either locally or on a remote machine using the Selenium server, it marks a leap forward in terms of browser automation.
Selenium WebDriver fits in the same role as RC did, and has incorporated the original 1.x bindings. It refers to both the language bindings and the implementations of the individual browser controlling code. This is commonly referred to as just WebDriver or sometimes as Selenium 2.
Selenium 1.0 + WebDriver = Selenium 2.0
- WebDriver is designed in a simpler and more concise programming interface along with addressing some limitations in the Selenium-RC API.
- WebDriver is a compact object-oriented API when compared to Selenium 1.0.
- It drives the browser much more effectively and overcomes the limitations of Selenium 1 that affected our functional test coverage, like the file upload or download, pop-ups, and dialogs barrier.
- WebDriver overcomes the limitation of Selenium RC's single-host origin policy.
DRIVER REQUIREMENTS
Through WebDriver, Selenium supports all major browsers on the market such as Chrom(ium), Firefox, Internet Explorer, Opera, and Safari. Where possible, WebDriver drives the browser using the browser's built-in support for automation, although not all browsers have official support for remote control.
WebDriver's aim is to emulate a real user's interaction with the browser as closely as possible. This is possible at varying levels in different browsers. For more details on the different driver idiosyncracies, please see
Driver Idiosyncracies.
Even though all the drivers share a single user-facing interface for contolling the browser, they have slightly different ways of setting up browser sessions. Since many of the driver implementations are provided by third parties, they are not included in the standard Selenium distribution.
Driver instantiation, profile management, and various browser specific settings are examples of parameters that have different requirements depending on the browser. This section explains the basic requirements for getting you started with the different browsers.
Adding Executables to your PATH
Most drivers require an extra executable for Selenium to communicate with the browser. You can manually specify where the executable lives before starting WebDriver, but this can make your tests less portable, as the executables will need to be in the same place on every machine, or included within your test code repository.
By adding a folder containing WebDriver's binaries to your system's path, Selenium will be able to locate the additional binaries without requiring your test code to locate the exact location of the driver.
- Create a directory to place the executables in, like C:\WebDriver\bin or /opt/WebDriver/bin
- Add the directory to your PATH:
- On Windows - Open a command prompt as administrator and the run the following command to permanently add the directory to your path for all users on your machine:
setx /m path "%path%;C:\WebDriver\bin\"
- Bash users on macOS and Linux - In a terminal:
export PATH=$PATH:/opt/WebDriver/bin >> ~/.profile
- You are now ready to test your changes. Close all open command prompts and open a new one. Type out the name of one of the binaries in the folder you created in the previous step, e.g:
chromedriver
. If your PATH is configured correctly, you will see some some output relating to the startup of the driver:
Starting ChromeDriver 2.25.426935 (820a95b0b81d33e42712f9198c215f703412e1a1) on port 9515 Only local connections are allowed.
You can regain control of your command prompt by pressing Ctrl + C.
Quick reference
Browser
|
Supported OS
|
Maintained by
|
Download
|
Issue Tracker
|
Chromium/Chrome
|
Windows
macOS
Linux
|
Google
|
|
|
Firefox
|
Windows
macOS
Linux
|
Mozilla
|
|
|
Edge
|
Windows 10
|
Microsoft
|
|
|
Internet Explorer
|
Windows
|
Selenium Project
|
|
|
Safari
|
macOS El Capitan and newer
|
Apple
|
Built in
|
|
Opera
|
Windows
macOS
Linux
|
Opera
|
|
|
Chromium/Chrome
To drive Chrome or Chromium, you have to download
chromedriver and put it in a folder that is on your system's path.
On Linux or macOS, this means modifying the PATH environmental variable. You can see what directories, separated by a colon, make up your system's path by executing the following command:
$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
To include chromedriver on the path if it isn't already, make sure you include the chromedriver binary's parent directory. The following line will set the PATH environmental variable its current content, plus an additional path added after the colon:
$ export PATH="$PATH:/path/to/chromedriver"
When chromedriver is available on your path, you should be able to execute the _chromedriver_ executable from any directory.
To instantiate a Chrome/Chromium session, you can do the following:
WebDriver driver = new ChromeDriver();
Remember that you have to set the path to the chromedriver executable. This is possible using the following line:
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
require "selenium-webdriver" driver = Selenium::WebDriver.for :chrome
The chromedriver is implemented as a WebDriver remote server that by exposing Chrome's internal automation proxy interface instructs the browser what to do.
Firefox
Starting with Selenium 3, Mozilla has taken over implementation of Firefox Driver, with
geckodriver. The new driver for Firefox is called geckodriver and works with Firefox 48 and newer. Since the Firefox WebDriver is under development, the newer the Firefox version the better the support.
As geckodriver is the new default way of launching Firefox, you can instantiate Firefox in the same way as Selenium 2:
WebDriver driver = new FirefoxDriver();
require "selenium-webdriver" driver = Selenium::WebDriver.for :firefox
If you prefer not to set geckodriver's location using PATH, set the geckodriver binary location programmatically:
System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");
It is also possible to set the property at run time:
mvn test -Dwebdriver.gecko.driver=/path/to/geckodriver
It is currently possible to revert to the older, more feature complete Firefox driver, by installing Firefox
47.0.1 or
45 ESR and specifying a desired capability of marionette as false. Later releases of Firefox are no longer compatible.
Edge
Edge is Microsoft's newest browser, included with Windows 10 and Server 2016. Updates to Edge are bundled with major Windows updates, so you'll need to download a binary which matches the build number of your currently installed build of Windows. The
Edge Developer site contains links to all the available binaries. Bugs against the EdgeDriver implementation can be raised with
Microsoft. If you'd like to run tests against Edge, but aren't running Windows 10, Microsoft offer free VMs for testers on the
Edge Developer site.
WebDriver driver = new EdgeDriver();
If Edge driver is not present in your path, you can set the path using the following line:
System.setProperty("webdriver.edge.driver", "/path/to/edgedriver");
Internet Explorer
Internet Explorer was Microsoft's default browser until Windows 10, although it is still included in Windows 10. Internet Explorer Driver is the only driver The Selenium project aims to support the same releases
Microsoft considers current. Older releases may work, but will be unsupported.
While the Selenium project provides binaries for both the 32-bit and 64-bit versions of Internet Explorer, there are some
limitations with Internet Explorer 10 & 11 with the 64-bit driver, but using the 32-bit driver continues to work well. It should be noted that as Internet Explorer preferences are saved against the logged in user's account, some
additional setup is required.
WebDriver driver = new InternetExplorerDriver();
If Internet Explorer driver is not present in your path, you can set the path using the following line:
System.setProperty("webdriver.ie.driver", "/path/to/iedriver");
Microsoft also offer a WebDriver binary for
Internet Explorer 11 on Windows 7 & 8.1. It has not been updated since 2014 and is based of a draft version of the W3 specification.
Jim Evans has an excellent writeup on Microsoft's implementation.
Opera
Current releases of Opera are built on top of the Chromium engine, and WebDriver is now supported via the closed-source
Opera Chromium Driver, which can be
added to your PATH or as a system property.
Instantiating a driver session is similar to Firefox and Chromium:
WebDriver driver = new OperaDriver();
require "selenium-webdriver" driver = Selenium::WebDriver.for :opera
Safari
Starting with Safari 10 on macOS El Capitan and Sierra, WebDriver support is included with each release of the browser. To enable support:
- Enable the Developer menu from Safari preferences
- Check the Allow Remote Automation option from with the Develop menu
- Run
/usr/bin/safaridriver -p 1337
from the terminal for the first time and type your password at the prompt to authorise WebDriver
You can then start a driver session using:
WebDriver driver = new SafariDriver();
Those looking to automate Safari on iOS should look to the
Appium project. Whilst Safari was previously available for Windows, Apple has long since dropped support, making it a poor choice of test platform.
Mock browsers
HtmlUnit
HtmlUnit is a "GUI-Less browser for Java programs". It models HTML documents and provides an API that allows you to invoke pages, fill out forms, click links, etc. It has JavaScript support and is able to work with AJAX libraries, simulating Chrome, Firefox or Internet Explorer depending on the configuration used. It has been moved to a
new location.
The source is maintained on svn.
PhantomJS
PhantomJS is a headless browser based on Webkit, albeit a version much older than that used by Google Chrome or Safari. . Whilst historically a popular choice, it would now be wise to avoid PhantomJS. The project has been unmaintained
since the 5th of August, so whilst the web will continue to change, PhantomJS will not be updated. This was after Google announced the ability to run Chrome headlessly, something also now offered by Mozilla's Firefox.
BROWSER LAUNCHING AND MANIPULATION
Ruby
Ruby is not installed by default on Windows. Download the latest
version and run the installer. You can leave all settings at default values, except at the Installation Destination and Optional Tasks screen check Add Ruby executables to your PATH checkbox. To drive any browser, you have to install selenium-webdriver Ruby gem. To install it, open command prompt and type this:
$ gem install selenium-webdriver
Internet Explorer
Internet Explorer is installed by default on Windows, so no installation is needed. To drive Internet Explorer on Windows, you have to download the latest
Internet Explorer Driver and put the file into a folder that is in PATH. To find out which directories are in PATH, type echo %PATH% in command prompt.
$ echo %PATH% C:\Ruby200\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
C:\Ruby200\bin looks like a good place. Unzip `IEDriverServer` file and move `IEDriverServer.exe` there. This should open a new Internet Explorer window:
System.setProperty("webdriver.ie.driver", /path/to/internetexplorerdriver); WebDriver driver = new InternetExplorerDriver();
require "selenium-webdriver" driver = Selenium::WebDriver.for :internet_explorer
WAITS
WebDriver can generally be said to have a blocking API. Because it is an out-of-process library thatinstructs the browser what to do, and because the web platform has an intrinsically asynchronous nature, WebDriver doesn't track the active, real-time state of the DOM. This comes with some challenges that we will discuss here.
From experience, most intermittents that arise from use of Selenium and WebDriver are connected to race conditions that occur between the browser and the user's instructions. An example could be that the user instructs the browser to navigate to a page, then gets a no such element error when trying to find an element.
Consider the following document:
<!doctype html> <meta charset=utf-8> <title>Race Condition Example<title> <script> var initialised = false; window.addEventListener("load", function() { var newElement = document.createElement("p"); newElement.textContent = "Hello from JavaScript!"; document.body.appendChild(newElement); initialised = true; }); </script>
The WebDriver instructions might look innocent enough:
driver.navigate("file:///race_condition.html") el = driver.find_element_by_tag_name("p") assert el.text == "Hello from JavaScript!"
The issue here is that the default
page load strategy used in WebDriver listens for the document.readyState to change to "complete" before returning from the call to navigate. Because the p element is added after the document has completed loading, this WebDriver script might be intermittent. It “might” be intermittent because no guarantees can be made about elements or events that trigger asynchronously without explicitly waiting—or blocking—on those events.
Fortunately, using the normal instruction set available on the
WebElement interface—such as WebElement.click and WebElement.sendKeys—are guaranteed to be synchronous, in that the function calls won't return (or the callback won't trigger in callback-style languages) until the command has been completed in the browser. The advanced user interaction APIs,
Keyboard and
Mouse, are exceptions as they are explicitly intended as “do what I say” asynchronous commands.
Waiting is having the automated task execution elapse a certain amount of time before continuing with the next step.
To overcome the problem of race conditions between the browser and your WebDriver script, most Selenium clients ship with a wait package. When employing a wait, you are using what is commonly referred to as an
explicit wait.
Explicit waiting
Explicit waits are available to Selenium clients for imperative, procedural languages. They allow your code to halt program execution, or freeze the thread, until the condition you pass it resolves. The condition is called with a certain frequency until the timeout of the wait is elapsed. This means that for as long as the condition returns a falsy value, it will keep trying and waiting.
Since explicit waits allow you to wait for a condition to occur, they make a good fit for synchronising the state between the browser and its DOM, and your WebDriver script.
To remedy our buggy instruction set from earlier, we could employ a wait to have the findElement call wait until the dynamically added element from the script has been added to the DOM:
from selenium.webdriver.support.ui import WebDriverWait def document_initialised(driver): return driver.execute_script("return initialised") driver.navigate("file:///race_condition.html") WebDriverWait(driver).until(document_initialised) el = driver.find_element_by_tag_name("p") assert el.text == "Hello from JavaScript!"
We pass in the condition as a function reference that the wait will run repeatedly until its return value is truthy. A “truthful” return value is anything that evaluates to boolean true in the language at hand, such as a string, number, a boolean, an object (including a WebElement), or a populated (non-empty) sequence or list. That means an empty list evaluates to false. When the condition is truthful and the blocking wait is aborted, the return value from the condition becomes the return value of the wait.
With this knowledge, and because the wait utility ignores no such element errors by default, we can refactor our instructions to be more concise:
from selenium.webdriver.support.ui import WebDriverWait driver.navigate("file:///race_condition.html") el = WebDriverWait(driver).until(lambda d: return d.find_element_by_tag_name("p")) assert el.text == "Hello from JavaScript!"
In that example, we pass in an anonymous function (but we could also define it explicitly as we did earlier so it may be reused). The first and only argument that is passed to our condition is always a reference to our driver object, WebDriver (called d in the example). In a multi-threaded environment, you should be careful to operate on the driver reference passed in to the condition rather than the reference to the driver in the outer scope.
Because the wait will swallow no such element errors that are raised when the element isn't found, the condition will retry until the element is found. Then it will take the return value, a WebElement, and pass it back through to our script.
If the condition fails, e.g. a truthful return value from the condition is never reached, the wait will throw/raise an error/exception called a timeout error.
Options
The wait condition can be customised to match your needs. Sometimes it's unnecessary to wait the full extent of the default timeout, as the penalty for not hitting a successful condition can be expensive.
The wait lets you pass in an argument to override the timeout:
WebDriverWait(driver, timeout=3).until(some_condition)
Expected conditions
Because it's quite a common occurrence to have to synchronise the DOM and your instructions, most clients also come with a set of predefined expected conditions. As might be obvious by the name, they are conditions that are predefined for frequent wait operations.
The conditions available in the different language bindings vary, but this is a non-exhaustive list of a few:
alert is present
element exists
element is visible
title contains
title is
element staleness
visible text
You can refer to the API documentation for each client binding to find an exhaustive list of expected conditions:
Implicit waiting
There is a second type of wait that is distinct from
explicit waits called implicit waiting. By implicitly waiting, WebDriver polls the DOM for a certain duration when trying to find any element. This can be useful when certain elements on the webpage are not available immediately and need some time to load.
Implicit waiting for elements to appear is disabled by default and will need to be manually enabled on a per-session basis. Mixing
explicit waits and implicit waiting will cause unintended consequences, namely waits sleeping for the maximum time even if the element is available or condition is true.
Warning: Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example, setting an implicit wait of 10 seconds and an explicit wait of 15 seconds could cause a timeout to occur after 20 seconds.
An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0, meaning disabled. Once set, the implicit wait is set for the life of the session.
WebDriver driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://somedomain/url_that_delays_loading"); WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
FluentWait
FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition.
Users may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.
// Waiting 30 seconds for an element to be present on the page, checking // for its presence once every 5 seconds. Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(30, SECONDS) .pollingEvery(5, SECONDS) .ignoring(NoSuchElementException.class); WebElement foo = wait.until(new Function<WebDriver, WebElement>() { public WebElement apply(WebDriver driver) { return driver.findElement(By.id("foo")); } });
FluentWait<By> fluentWait = new FluentWait<By>(By.tagName("TEXTAREA")); fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS); fluentWait.withTimeout(1000, TimeUnit.MILLISECONDS); fluentWait.until(new Predicate<By>() { public boolean apply(By by) { try { return browser.findElement(by).isDisplayed(); } catch (NoSuchElementException ex) { return false; } } }); browser.findElement(By.tagName("TEXTAREA")).sendKeys("text to enter");
SUPPORT CLASSES
JAVASCRIPT ALERTS, PROMPTS AND CONFIRMATIONS
WebDriver provides an API for working with the three types of native popup message offered by JavaScript. These popups are styled by the browser and offer limited customisation.
Alerts
The simplest of these is referred to as an alert, which shows a custom message, and a single button which dismisses the alert, labelled in most browsers as OK. It can also be dismissed in most browsers by pressing the close button, but this will always do the same thing as the OK button. See an example alert.
WebDriver can get the text from the popup and accept or dismiss these alerts.
//Click the link to activate the alert driver.findElement(By.linkText("See an example alert")).click(); //Wait for the alert to be displayed and store it in a variable Alert alert = wait.until(ExpectedConditions.alertIsPresent()); //Store the alert text in a variable String text = alert.getText(); //Press the OK button alert.accept(); # Click the link to activate the alert driver.find_element_by_link_text("See an example alert").click() # Wait for the alert to be displayed and store it in a variable alert = wait.until(expected_conditions.alert_is_present()) # Store the alert text in a variable text = alert.text # Press the OK button alert.accept()
Confirm
A confirm box is similar to an alert, except the user can also choose to cancel the message. See a sample confirm.
This example also shows a different approach to storing an alert:
//Click the link to activate the alert driver.findElement(By.linkText("See a sample confirm")).click(); //Wait for the alert to be displayed wait.until(ExpectedConditions.alertIsPresent()); //Store the alert in a variable Alert alert = driver.switchTo().alert(); //Store the alert in a variable for reuse String text = alert.getText(); //Press the Cancel button alert.dismiss(); # Click the link to activate the alert driver.find_element_by_link_text("See a sample confirm").click() # Wait for the alert to be displayed wait.until(expected_conditions.alert_is_present()) # Store the alert in a variable for reuse alert = driver.switch_to.alert # Store the alert text in a variable text = alert.text # Press the Cancel button alert.dismiss()
Prompt
Prompts are similar to confirm boxes, except they also include a text input. Similar to working with form elements, you can use WebDriver's send keys to fill in a response. This will completely replace the placeholder text. Pressing the cancel button will not submit any text. See a sample prompt.
//Click the link to activate the alert driver.findElement(By.linkText("See a sample prompt")).click(); //Wait for the alert to be displayed and store it in a variable Alert alert = wait.until(ExpectedConditions.alertIsPresent()); //Type your message alert.sendKeys("Selenium"); //Press the OK button alert.accept(); # Click the link to activate the alert driver.find_element_by_link_text("See a sample prompt").click() # Wait for the alert to be displayed wait.until(expected_conditions.alert_is_present()) # Store the alert in a variable for reuse alert = Alert(driver) # Type your message alert.send_keys("Selenium") # Press the OK button alert.accept()
HTTP PROXIES
PAGE LOADING STRATEGY
WEB ELEMENTS
KEYBOARD
MOUSE
WEBDRIVER
Selenium最近的最大变化是包含了WebDriver API。以本地方式作为用户驱动浏览器将在本地或使用Selenium服务器的远程计算机上运行,这标志着浏览器自动化方面的一次飞跃。
Selenium WebDriver与RC的作用相同,并且包含原始的1.x绑定。它涉及语言绑定和各个浏览器控制代码的实现。这通常被称为WebDriver 或有时被称为Selenium 2。
Selenium 1.0 + WebDriver = Selenium 2.0
- WebDriver的设计更简单,更简洁的编程界面,同时解决了Selenium-RC API中的一些限制。
- 与Selenium 1.0相比,WebDriver是一个紧凑的面向对象API。
- 它更有效地驱动浏览器,并克服了Selenium 1的局限性,这些限制影响了我们的功能测试覆盖范围,如文件上传或下载,弹出窗口和对话框屏障。
- WebDriver克服了Selenium RC的单主机起源策略的局限性 。
驱动要求
通过WebDriver,Selenium支持市场上所有主流浏览器,如Chrom(ium),Firefox,Internet Explorer,Opera和Safari。在可能的情况下,WebDriver使用浏览器对自动化的内置支持来驱动浏览器,但并非所有浏览器都支持远程控制。
WebDriver的目标是尽可能模仿真实用户与浏览器的交互。在不同的浏览器中,这是可能的。有关不同驱动程序特性的更多详细信息,请参阅
驱动程序特性。
即使所有驱动程序共享一个用于控制浏览器的面向用户的界面,但它们在设置浏览器会话方面略有不同。由于许多驱动程序实现由第三方提供,因此它们不包含在标准的Selenium发行版中。
驱动程序实例化,配置文件管理以及各种浏览器特定设置是根据浏览器具有不同要求的参数示例。本节介绍让您开始使用不同浏览器的基本要求。
将可执行文件添加到您的PATH
大多数驱动程序需要一个额外的可执行文件让Selenium与浏览器通信。您可以在启动WebDriver之前手动指定可执行文件的位置,但这可能会使测试的可移植性降低,因为可执行文件需要位于每台计算机的相同位置,或者包含在测试代码库中。
通过将包含WebDriver二进制文件的文件夹添加到系统路径中,Selenium将能够找到其他二进制文件,而无需您的测试代码来查找驱动程序的确切位置。
- 创建一个目录来放置浏览器驱动可执行文件,例如 C:\ WebDriver \ bin或/ opt / WebDriver / bin
- 将该目录添加到系统环境变量PATH中:
- 在Windows上 - 以管理员身份打开命令提示符,然后运行以下命令将该目录永久地添加到您计算机上所有用户的路径中:
setx /m path “%path%;C:\WebDriver \bin\”
- 在macOS和Linux上使用bash用户 - 在终端中:
export PATH=$PATH:/opt/WebDriver/bin >> 〜/.profile
- 您现在可以验证您的更改是否有效。关闭所有打开的命令提示符并打开一个新提示符。在上一步创建的文件夹中输入其中一个二进制文件的名称,例如:
chromedriver
。如果您的PATH配置正确,您会看到一些与驱动程序启动有关的输出:
Starting ChromeDriver 2.25.426935 (820a95b0b81d33e42712f9198c215f703412e1a1) on port 9515 Only local connections are allowed.
按下,您可以重新获得对命令提示符的控制Ctrl + C。
快速参考
浏览器
|
支持的OS
|
由...维护
|
下载
|
问题跟踪器
|
铬/铬
|
Windows
macOS
Linux
|
谷歌
|
|
|
火狐
|
Windows
macOS
Linux
|
Mozilla
|
|
|
边缘
|
Windows 10
|
微软
|
|
|
IE浏览器
|
视窗
|
硒项目
|
|
|
苹果浏览器
|
macOS El Capitan和更新的
|
苹果
|
内置
|
|
歌剧
|
Windows
macOS
Linux
|
歌剧
|
|
|
铬/铬
在Linux或macOS上,这意味着修改PATH环境变量。您可以通过执行以下命令来查看以冒号分隔的目录是否构成系统的路径:
$ echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
如果路径中尚未包含chromedriver,请确保包含chromedriver二进制文件的父目录。以下行将设置PATH环境变量的当前内容,并在冒号后添加一个额外的路径:
$ export PATH="$PATH:/path/to/chromedriver"
当您的路径上有可用的chromedriver时,您应该能够从任何目录执行_chromedriver_可执行文件。
要实例化Chrome / Chromium会话,您可以执行以下操作:
WebDriver driver = new ChromeDriver();
请记住,您必须将路径设置为chromedriver可执行文件。这可以使用以下行:
System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
require "selenium-webdriver" driver = Selenium::WebDriver.for :chrome
chromedriver被当作WebDriver远程服务器,它通过公开chrome的内部自动代理接口来指挥浏览器做什么
火狐
从Selenium 3开始,Mozilla利用
geckodriver接管了Firefox Driver的实现。Firefox的新驱动称为geckodriver,适用于Firefox 48及更新版本。由于Firefox WebDriver正在开发中,Firefox版本越新越好。
由于geckodriver是启动Firefox的新默认方式,因此您可以像Selenium 2一样实例化Firefox:
WebDriver driver = new FirefoxDriver();
require "selenium-webdriver" driver = Selenium::WebDriver.for :firefox
如果您不想使用PATH设置geckodriver的位置,请以编程方式设置geckodriver二进制位置:
System.setProperty("webdriver.gecko.driver", "/path/to/geckodriver");
也可以在运行时设置属性:
mvn test -Dwebdriver.gecko.driver=/path/to/geckodriver
目前有可能通过安装Firefox
47.0.1 或
45 ESR 并将所需的木偶功能指定为 false来恢复到较老的,功能更完整的Firefox驱动程序 。Firefox的后续版本不再兼容。
Edge
Edge是Microsoft最新的浏览器,包含在Windows 10和Server 2016中。Edge的更新与主要Windows更新捆绑在一起,因此您需要下载与您当前安装的Windows版本号相匹配的二进制文件。该
边缘开发人员网站 包含指向所有可用的二进制文件。
微软可以提出针对EdgeDriver实施的错误 。如果您希望针对Edge运行测试,但不运行Windows 10,Microsoft会在
Edge开发人员网站上为测试人员提供免费虚拟机。
WebDriver driver = new EdgeDriver();
如果Edge驱动程序不在您的路径中,则可以使用以下行设置路径:
System.setProperty("webdriver.edge.driver", "/path/to/edgedriver");
IE浏览器
在Windows 10之前,Internet Explorer是微软的默认浏览器,尽管它仍然包含在Windows 10中。Internet Explorer驱动程序是唯一的驱动程序Selenium项目旨在支持
Microsoft认为的最新版本 。旧版本可能有效,但不受支持。
虽然Selenium项目为32位和64位版本的Internet Explorer提供了二进制文件,但Internet Explorer 10和11在64位驱动程序方面存在一些
局限性,但使用32位驱动程序仍能正常运行。应该注意的是,由于Internet Explorer首选项是针对登录用户的帐户保存的,
因此需要进行一些
额外的设置。
WebDriver driver = new InternetExplorerDriver();
如果Internet Explorer驱动程序不在您的路径中,则可以使用以下行来设置路径:
System.setProperty("webdriver.ie.driver", "/path/to/iedriver");
Opera
实例化驱动程序会话与Firefox和Chromium类似:
WebDriver driver = new OperaDriver();
require "selenium-webdriver" driver = Selenium::WebDriver.for :opera
Safari
从macOS El Capitan和Sierra上的Safari 10开始,每个浏览器版本都包含WebDriver支持。启用支持:
- 从Safari偏好设置启用开发者菜单
- 使用“显影”菜单检查“ 允许远程自动化”选项
- 跑
/ usr / bin / safaridriver -p 1337
从终端第一次,并在提示输入您的密码授权WebDriver
然后可以使用以下命令启动驱动程序会话
WebDriver driver = new SafariDriver();
那些希望在iOS上自动化Safari的人应该看看
Appium项目。虽然以前Safari可用于Windows,但Apple早已不再维护,使其成为测试平台的糟糕选择。
模拟浏览器
HtmlUnit
HtmlUnit是一个“Java程序的无GUI浏览器”。它模拟HTML文档,并提供一个API,使您可以调用页面,填写表单,单击链接等。它支持JavaScript,可以使用AJAX库,根据所用配置模拟Chrome,Firefox或Internet Explorer。它已被移到一个
新的位置。
源代码保存在svn上。
PhantomJS
PhantomJS是一款基于Webkit的无头浏览器,尽管它的版本比Google Chrome或Safari使用的版本要早得多。。虽然历史上流行的选择,但避免PhantomJS现在是明智的。该项目
自8月5日以来一直未得到维护 ,因此虽然网络将继续发生变化,但PhantomJS不会更新。这是在谷歌宣布无线运行Chrome的能力之后,现在Mozilla的Firefox也提供了一些功能。
浏览器启动和操作
Ruby
在Windows上默认不安装Ruby。下载最新
版本并运行安装程序。您可以将所有设置保留为默认值,除了在“ 安装目标”和“可选任务”屏幕中检查将Ruby可执行文件添加到PATH复选框。要驱动任何浏览器,您必须安装selenium-webdriver Ruby gem。要安装它,请打开命令提示符并输入:
$ gem install selenium-webdriver
IE浏览器
Internet Explorer默认安装在Windows上,因此不需要安装。要在Windows上驱动Internet Explorer,必须下载最新的
Internet Explorer驱动程序,并将该文件放入PATH中的文件夹中。要找出PATH中的哪些目录,请在命令提示符下键入echo%PATH%。
$ echo %PATH% C:\Ruby200\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem
C:\ Ruby200 \ bin看起来像个好地方。解压缩`IEDriverServer`文件并将`IEDriverServer.exe`移动到那里。这应该打开一个新的Internet Explorer窗口:
System.setProperty("webdriver.ie.driver", /path/to/internetexplorerdriver); WebDriver driver = new InternetExplorerDriver();
require "selenium-webdriver" driver = Selenium::WebDriver.for :internet_explorer
WAITS功能
通常可以说WebDriver具有阻塞API。由于它是一个进程外库,它 指示浏览器执行什么操作,并且因为Web平台具有内在的异步特性,所以WebDriver不会跟踪DOM的活动实时状态。这带来了一些挑战,我们将在这里讨论。。
根据经验,使用Selenium和WebDriver产生的大部分间歇性事件都与浏览器和用户指令之间出现的争用条件相关联。一个例子可能是用户指示浏览器导航到页面,然后在尝试查找元素时没有发现此类元素错误。
参考以下文件:
<!doctype html> <meta charset=utf-8> <title>Race Condition Example<title> <script> var initialised = false; window.addEventListener("load", function() { var newElement = document.createElement("p"); newElement.textContent = "Hello from JavaScript!"; document.body.appendChild(newElement); initialised = true; }); </script>
WebDriver指令可能看起来无辜:
driver.navigate("file:///race_condition.html") el = driver.find_element_by_tag_name("p") assert el.text == "Hello from JavaScript!"
这里的问题是WebDriver中使用的默认页面加载策略监听文档。readyState更改为“complete”,然后从调用返回导航。因为p元素是在文档完成加载之后添加的,所以这个WebDriver脚本可能是间歇性的。它“可能”是间歇性的,因为不能对异步触发的元素或事件作出保证,而不需要显式地等待或阻塞这些事件。
幸运的是,使用
WebElement接口上可用的普通指令集(例如WebElement.click和WebElement.sendKeys)保证是同步的,因为函数调用不会返回(或者回调将不会以回调式触发语言),直到浏览器中的命令完成。高级用户交互API
键盘和
鼠标是例外,因为它们显式地用作“按我说的做”异步命令。
在继续下一步之前,等待会让自动任务执行过去一段时间。
为了克服浏览器和WebDriver脚本之间的竞争状况问题,大多数Selenium客户端都附带一个等待包。当采用等待时,您正在使用通常被称为
显式等待的内容。
显式等待
Selenium客户端可以使用显式等待来使用命令式的过程语言。它们允许您的代码停止程序执行,或者冻结线程,直到您通过的条件得到解决。以特定频率调用条件,直到等待超时。这意味着只要条件返回一个虚假值,它就会继续尝试和等待。
由于显式等待允许您等待条件发生,因此它们非常适合于同步浏览器及其DOM和WebDriver脚本之间的状态。
为了补救我们早期的错误指令集,我们可以等待findElement调用等待,直到脚本中动态添加的元素被添加到DOM:
from selenium.webdriver.support.ui import WebDriverWait def document_initialised(driver): return driver.execute_script("return initialised") driver.navigate("file:///race_condition.html") WebDriverWait(driver).until(document_initialised) el = driver.find_element_by_tag_name("p") assert el.text == "Hello from JavaScript!"
我们将条件作为函数引用传递,等待将重复运行,直到其返回值为真。一个“真实的”返回值是任何在手头语言中评估为boolean true的东西,如字符串,数字,布尔值,对象(包括WebElement)或填充(非空)序列或列表。这意味着一个空列表的计算结果为false。当条件是真实的并且阻塞等待被中止时,来自条件的返回值变成等待的返回值。
有了这些知识,并且由于等待实用程序默认情况下不会忽略此类元素错误,所以我们可以将我们的指示重构得更加简洁:
from selenium.webdriver.support.ui import WebDriverWait driver.navigate("file:///race_condition.html") el = WebDriverWait(driver).until(lambda d: return d.find_element_by_tag_name("p")) assert el.text == "Hello from JavaScript!"
在这个例子中,我们传入一个匿名函数(但我们也可以像前面那样明确地定义它,以便它可以被重用)。传递给我们的条件的第一个也是唯一的参数始终是对我们的驱动程序对象WebDriver (在该示例中称为d)的引用。在多线程环境中,您应该小心地对传入条件的驱动程序引用进行操作,而不是在外部范围中对驱动程序的引用。
因为等待将不会消除元素未找到时引发的此类元素错误,则条件将重试,直到找到该元素。然后它将获得返回值,一个WebElement,并将其传回给我们的脚本。
如果条件失败,例如从条件得到的真实返回值永远不会达到,那么等待将抛出/引发称为超时错误的错误/异常。
选项
等待条件可以定制以满足您的需求。有时没有必要等待默认超时的全部范围,因为没有达到成功条件的代价会很昂贵。
等待让你传入一个参数来覆盖超时:
WebDriverWait(driver, timeout=3).until(some_condition)
预期条件
因为必须同步DOM和您的指令是很常见的事情,所以大多数客户还会附带一组预定义的预期条件。由名称可能很明显,它们是为频繁等待操作而预定义的条件。
不同语言绑定中可用的条件各不相同,但这是一个非穷举的列表:
警报存在
元素存在
元素是可见的
标题包含
标题是
元素陈旧
可见的文本
您可以参考每个客户端绑定的API文档以查找预期条件的详尽列表:
隐含的等待
还有第二种类型的等待与
显式等待不同, 称为隐式等待。通过隐式等待,WebDriver在尝试查找任何元素时轮询DOM一段时间。当网页上的某些元素不可立即使用并需要一些时间加载时,这可能很有用。
默认情况下隐式等待元素出现,并且需要在每个会话的基础上手动启用。混合
明确的等待和隐含的等待将导致意想不到的后果,即等待最大时间睡眠,即使元素可用或条件为真。
警告: 不要混合隐式和显式等待。这样做会导致无法预测的等待时间。例如,设置10秒的隐式等待和15秒的明确等待可能会导致20秒后发生超时。
隐含的等待是告诉WebDriver在尝试查找一个或多个元素(如果它们不是立即可用的)时轮询DOM一段时间。默认设置为0,意味着禁用。一旦设置,隐含的等待就设置为会话的整个生命周期。
WebDriver driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("http://somedomain/url_that_delays_loading"); WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
FluentWait
FluentWait实例定义了等待条件的最长时间以及检查条件的频率。
用户可以配置等待,以在等待时忽略特定类型的异常,例如NoSuchElementException在页面上搜索元素时。
// Waiting 30 seconds for an element to be present on the page, checking // for its presence once every 5 seconds. Wait<WebDriver> wait = new FluentWait<WebDriver>(driver) .withTimeout(30, SECONDS) .pollingEvery(5, SECONDS) .ignoring(NoSuchElementException.class); WebElement foo = wait.until(new Function<WebDriver, WebElement>() { public WebElement apply(WebDriver driver) { return driver.findElement(By.id("foo")); } });
FluentWait<By> fluentWait = new FluentWait<By>(By.tagName("TEXTAREA")); fluentWait.pollingEvery(100, TimeUnit.MILLISECONDS); fluentWait.withTimeout(1000, TimeUnit.MILLISECONDS); fluentWait.until(new Predicate<By>() { public boolean apply(By by) { try { return browser.findElement(by).isDisplayed(); } catch (NoSuchElementException ex) { return false; } } }); browser.findElement(By.tagName("TEXTAREA")).sendKeys("text to enter");
支持类
JAVASCRIPT警报,提示和确认
WebDriver提供了一个用于处理JavaScript提供的三种本地弹出消息的API。这些弹出窗口由浏览器设置并提供有限的自定义。
Alerts
其中最简单的就是一个警报,它显示了一个自定义消息,以及一个按钮,它解除了警报,在大多数浏览器中标记为OK。它也可以通过按下关闭按钮在大多数浏览器中被解散,但是这总是和OK按钮一样。查看示例警报。
WebDriver可以从弹出窗口中获取文本并接受或拒绝这些警报。
//Click the link to activate the alert driver.findElement(By.linkText("See an example alert")).click(); //Wait for the alert to be displayed and store it in a variable Alert alert = wait.until(ExpectedConditions.alertIsPresent()); //Store the alert text in a variable String text = alert.getText(); //Press the OK button alert.accept(); # Click the link to activate the alert driver.find_element_by_link_text("See an example alert").click() # Wait for the alert to be displayed and store it in a variable alert = wait.until(expected_conditions.alert_is_present()) # Store the alert text in a variable text = alert.text # Press the OK button alert.accept()
Confirm
确认框与提示类似,除了用户也可以选择取消消息。查看样本确认。
此示例还显示了一种用于存储警报的不同方法:
//Click the link to activate the alert driver.findElement(By.linkText("See a sample confirm")).click(); //Wait for the alert to be displayed wait.until(ExpectedConditions.alertIsPresent()); //Store the alert in a variable Alert alert = driver.switchTo().alert(); //Store the alert in a variable for reuse String text = alert.getText(); //Press the Cancel button alert.dismiss(); # Click the link to activate the alert driver.find_element_by_link_text("See a sample confirm").click() # Wait for the alert to be displayed wait.until(expected_conditions.alert_is_present()) # Store the alert in a variable for reuse alert = driver.switch_to.alert # Store the alert text in a variable text = alert.text # Press the Cancel button alert.dismiss()
Prompt
提示与确认框相似,除了它们还包含文本输入。与使用表单元素类似,您可以使用WebDriver的发送键来填写响应。这将完全取代占位符文本。按取消按钮不会提交任何文本。 查看示例提示。
//Click the link to activate the alert driver.findElement(By.linkText("See a sample prompt")).click(); //Wait for the alert to be displayed and store it in a variable Alert alert = wait.until(ExpectedConditions.alertIsPresent()); //Type your message alert.sendKeys("Selenium"); //Press the OK button alert.accept(); # Click the link to activate the alert driver.find_element_by_link_text("See a sample prompt").click() # Wait for the alert to be displayed wait.until(expected_conditions.alert_is_present()) # Store the alert in a variable for reuse alert = Alert(driver) # Type your message alert.send_keys("Selenium") # Press the OK button alert.accept()
HTTP代理
页面加载策略
WEB元素
键盘
鼠标
- Selenium WebDriver + Python 环境配置
1. 下载必要工具及安装包 1.1.[Python开发环境] 下载并安装Python 2.7.x版本(当前支持2.x版本,不要下载最新的3.X的版本因为python3并非完全兼容python2) ...
- python + selenium WebDriver的环境配置
想试用python语言来学习selenium WebDriver,首先需要搭建一个测试环境,从python安装到浏览器插件配置的详细步骤,总结如下: 一.python环境配置 1.从官网下载最新的一个 ...
- PHP_环境配置_python脚本_2017
Apache配置 需要安装:VC2015 httpd-2.4.16-win32-VC14.zip VC14就是2015的环境. 又比如:php-5.6.12-Win32-VC11-x86 VC11就是 ...
- 解读ASP.NET 5 & MVC6系列(4):核心技术与环境配置
asp.net 5是下一代的asp.net,该版本进行了全部重写以适用于跨平台,新新版本中,微软引入了如下工具与命令:DNVM.DNX.DNU. DNVM(.NET Version Manager): ...
- Mongodb学习笔记一(Mongodb环境配置)
Mongodb学习 说明: MongoDB由databases组成,database由collections组成,collection由documents组成,document由fileds组成.Mo ...
- JMeter学习-038-JMeter Linux 环境配置
1.1.下载 Download URL:http://mirrors.tuna.tsinghua.edu.cn/apache//jmeter/binaries/apache-jmeter-3.0.tg ...
- cocos2dx && Lua 环境配置
需要的材料: 1.vs2013 2.python-2.7.3(2.7.x高于2.7的版本可能会出现错误) 3.Sublime Text 2(破解的) 4.cocos2dx-3.2 步骤: 1.安装vs ...
- Selenium+Python的环境配置
因为项目的原因,最近较多的使用了UFT来进行自动化测试工作,半年没有使用Selenium了,于是在自己的电脑上重新配置了基于python3.x的selenium环境,配置过程大致如下: 1. Sele ...
- Direct2D教程(外篇)环境配置
2014年世界杯首场淘汰赛马上开始了,闲着没事,整理以前的博客草稿打发时间,意外的发现这篇文章,本来是打算加入到Direct2D那个系列的,不知道为什么把它给遗漏了.环境配置,对于熟手来说,不是什么重 ...
随机推荐
- JavaScript 钩子
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <script s ...
- JS中void(0)操作符的使用
今天 在看源码时,发现这种写法 if(value === void(0)){ // } 以前没有见过这种写法,感觉就是判断一个变量是否有值,官网上是这样说的: void运算符 对给定的表达式进行求值, ...
- Linux下配置GitHub
一.注册GitHub账号 二.在linux命令行输入 git config --global user.name "YOUR NAME" #配置github账号 git confi ...
- 关于APP设计规范和一些图层命名
首先,本人大学计算机专业出身,学过编程,工作的时候做过 产品经理,设计师,前端工程师,对工作的流程都有一些见解. 现在主攻前端工程师,做Web APP.今天收到设计师的设计稿,一看图层分类,这让我感觉 ...
- 一个高性能跨平台基于Python的Waitress WSGI Server的介绍!
对于Python来说,它有很多web框架,常见的有jango.Flask.Tornado .sanic等,比如Odoo.Superset都基于Flask框架进行开发的开源平台,具有强大的功能.在Lin ...
- day7 对字母数字的编排
1.函数fun()的功能:在s数组内寻找并且统计t数组在s数组中出现的次数 输入字符串:函数scanf()函数不好用,会出现很多bug,因此不使用scanf() 效果理想: 2.函数fun()功能:将 ...
- 《剑指offer》面试题61. 扑克牌中的顺子
问题描述 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的.2-10为数字本身,A为1,J为11,Q为12,K为13,而大.小王为 0 ,可以看成任意数字.A 不能视为 14. 示例 ...
- 微信小程序云开发指南
一.初识云开发 官方文档 小程序·云开发是微信团队联合腾讯云推出的专业的小程序开发服务. 开发者可以使用云开发快速开发小程序.小游戏.公众号网页等,并且原生打通微信开放能力. 开发者无需搭建服务器,可 ...
- 【刷题-LeetCode】121 Best Time to Buy and Sell Stock
Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of a gi ...
- 带你学习Flood Fill算法与最短路模型
一.Flood Fill(连通块问题) 0.简介 Flood Fill(洪水覆盖) 可以在线性的时间复杂内,找到某个点所在的连通块! 注:基于宽搜的思想,深搜也可以做但可能会爆栈 flood fill ...