diff --git a/config.toml b/config.toml index 46951cda65f8..1ee1d6da031d 100755 --- a/config.toml +++ b/config.toml @@ -1,4 +1,4 @@ -baseURL = "https://www.seleniumhq.org/" +baseURL = "" languageCode = "en-us" title = "SeleniumHQ Browser Automation" theme = "selenium" diff --git a/content/documentation/attr.html b/content/documentation/attr.html deleted file mode 100755 index 52a2c2a8b2c5..000000000000 --- a/content/documentation/attr.html +++ /dev/null @@ -1,326 +0,0 @@ - -Copyright and attributions - - - - - - -

Copyright and attributions

- -

The Selenium Documentation - -

Copyright © 2013-2016, Software Freedom Conservancy. - -

Every effort has been made to make this documentation - as complete and as accurate as possible, - but no warranty or fitness is implied. - The information provided is on an “as-is” basis. - The authors and the publisher shall have - neither liability nor responsibility to any person or entity - with respect to any loss or damages arising - from the information contained in this book. - No patent liability is assumed with respect - to the use of the information contained herein. - - -

Attributions

- -

Thanks to: - -

-
- -

Third-Party software used by Selenium documentation project: - - - - - - -
Software Version License
Highlight.js9.7.0BSD License
- - -

HTML version and source code

- -

An HTML version of this documentation is freely available from - https://seleniumhq.github.io/docs. - -

The source code for the examples included, - and for the book itself is available from the Selenium documentation repository - at https://github.com/seleniumhq/docs. - See instructions on how to check out the code via git at - https://help.github.com/articles/fetching-a-remote/. - - -

License

- -

All code and documentation originating from the Selenium project - is licensed under the Apache 2.0 license, - with the Software Freedom Conservancy - as the copyright holder. - -

The license is included here for convenience, - but you can also find it on the - Apache Foundation's websites: - -

                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/content/documentation/drivers.html b/content/documentation/drivers.html deleted file mode 100755 index 3d697e6c2356..000000000000 --- a/content/documentation/drivers.html +++ /dev/null @@ -1,64 +0,0 @@ - - -Driver idiosyncrasies - - - - - - - -

Driver idiosyncrasies

- - -

Shared capabilities

- -

pageLoadStrategy

-

When navigating to a new page via URL, by default Selenium will wait - until the page has fully loaded before responding. This works well for - beginners, but can cause long wait times on pages that load a large - number of third party resources. Using a non default strategy can make - test execution faster in cases like this, but can also introduce flakiness - where elements on the page change position as elements load in and change - size. - -

The page load strategy queries the - - document.readyState as described in the table below: - - - - - -
StrategyReady StateNotes
normalcompleteUsed by default, waits for all - resources to download
eagerinteractiveDOM access is ready, but other - resources like images may still be loading
noneAnyDoes not block WebDriver at all
- - -

Driver specific capabilities

- -

Firefox

-

Define Capabilities using FirefoxOptions

-

FirefoxOptions is the new way to define capabilities for the Firefox browser and should generally be used in preference to DesiredCapabilities.

-

-FirefoxOptions options = new FirefoxOptions();
-options.addPreference("network.proxy.type", 0);
-driver = new RemoteWebDriver(options);
-
- -

Setting a custom profile

-

It is possible to create a custom profile for Firefox as demonstrated below.

-

-FirefoxProfile profile = new FirefoxProfile();
-FirefoxOptions options = new FirefoxOptions();
-options.setProfile(profile);
-driver = new RemoteWebDriver(options);
-
- -

Internet Explorer

- -

fileUploadDialogTimeout

- -

In some environments, Internet Explorer may timeout when opening the - File Upload dialog. IEDriver has a default timeout of 1000ms, but you - can increase the timeout using the fileUploadDialogTimeout capability. diff --git a/content/documentation/grid.html b/content/documentation/grid.html deleted file mode 100755 index 634a7543a0fb..000000000000 --- a/content/documentation/grid.html +++ /dev/null @@ -1,300 +0,0 @@ - - -Selenium Grid - - - - - - - -

Selenium Grid

- -

Selenium Grid is a smart proxy server - that allows Selenium tests to route commands to remote web browser instances. - Its aim is to provide an easy way to run tests in parallel on multiple machines. - -

With Selenium Grid, - one server acts as the hub that routes JSON formatted test commands - to one or more registered Grid nodes. - Tests contact the hub to obtain access to remote browser instances. - The hub has a list of registered servers that it provides access to, - and allows us to control these instances. - -

Selenium Grid allows us to run tests in parallel on multiple machines, - and to manage different browser versions and browser configurations centrally - (instead of in each individual test). - -

Selenium Grid isn't a silver bullet. - It solves a subset of common delegation and distribution problems, - but will for example not manage your infrastructure - and might not suit your specific needs. - -

-

Purposes and main functionality of a Selenium Grid

-
-
-
Central entry point for all tests
-
Management and control of the nodes / environment where the browsers run on
-
Scaling
-
Running tests in parallel
-
Cross platform testing
-
Load balancing
-
- - -
-

Components of a Selenium Grid

-
- - - -
-
Hub
- - -

A hub is a central point where all your tests are sent to. - Each Selenium Grid consists of exactly one hub. The hub needs to be reachable from the - respective clients (i.e. CI server, Developer machine etc.) - The hub will connect one or more nodes - that tests will be delegated to. - - -

Nodes
- - -

Nodes are different Selenium instances - that will execute tests on individual computer systems. - There can be many nodes in a grid. - The machines which are nodes need do not need to be the same platform - or have the same browser selection as that of the hub or the other nodes. - A node on Windows might have the capability of - offering Internet Explorer as a browser option, - whereas this wouldn't be possible on Linux or Mac. -

- - - -
-

Setting up your own Selenium Grid

-
- -

To use Selenium Grid, - you need to maintain your own infrastructure for the nodes. - As this can be a cumbersome and time intense effort, - many organizations use IaaS providers - such as Amazon EC2 and Google Compute - to provide this infrastructure. - -

Other options include using providers such as Sauce Labs or Testing Bot who provide a Selenium Grid as a service in the cloud. - It is certainly possible to also run nodes on your own hardware. - This chapter will go into detail about the option of running your own grid, - complete with its own node infrastructure. - - -

Quick start

- -

This example will show you how to start the Selenium 2 Grid Hub, - and register both a WebDriver node and a Selenium 1 RC legacy node. - We’ll also show you how to call the grid from Java. - The hub and nodes are shown here running on the same machine, - but of course you can copy the selenium-server-standalone to multiple machines. - -

The selenium-server-standalone package includes the hub, - WebDriver, and legacy RC needed to run the grid. - ant is not required anymore. - You can download the selenium-server-standalone-.jar from - http://www.seleniumhq.org/download/. - - -

Step 1: Start the hub

- -

The hub is the central point that will receive test requests - and distribute them to the right nodes. - The distribution is done on a capabilities basis, - meaning a test requiring a set of capabilities - will only be distributed to nodes offering that set or subset of capabilities. - -

Because a test's desired capabilities are just what the name implies, desired, - the hub cannot guarantee that it will locate a node - fully matching the requested desired capabilities set. - -

Open a command prompt - and navigate to the directory where you copied - the selenium-server-standalone.jar file. - You start the hub by passing the -role hub flag - to the standalone server: - -

$ java -jar selenium-server-standalone.jar -role hub
- -

The hub will listen to port 4444 by default. - You can view the status of the hub by opening a browser window and navigating to - http://localhost:4444/grid/console. - -

To change the default port, - you can add the optional -port flag - with an integer representing the port to listen to when you run the command. - Also, all of the other options you see in the JSON config file (seen below) - are possible command-line flags. - -

You certainly can get by with only the simple command shown above, - but if you need more advanced configuration, - then you may also for convenience specify a JSON format config file - to configure the hub when you start it. - You can do it like so: - -

$ java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
- -

Below you will see an example of a hubConfig.json file. - We will go into more detail on how to provide node configuration files in step 2. - -

{"_comment" : "Configuration for Hub - hubConfig.json",
-  "host": ip,
-  "maxSession": 5,
-  "port": 4444,
-  "cleanupCycle": 5000,
-  "timeout": 300000,
-  "newSessionWaitTimeout": -1,
-  "servlets": [],
-  "prioritizer": null,
-  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
-  "throwOnCapabilityNotPresent": true,
-  "nodePolling": 180000,
-  "platform": "WINDOWS"}
- - -

Step 2: Start the nodes

- -

Regardless of whether you want to run a grid with new WebDriver functionality, - or a grid with Selenium 1 RC functionality, - or both at the same time, - you use the same selenium-server-standalone.jar file to start the nodes: - -

$ java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
- -

If a port is not specified through the -port flag, - a free port will be chosen. You can run multiple nodes on one machine - but if you do so, you need to be aware of your systems memory resources - and problems with screenshots if your tests take them. - - -

Configuration of node with options
- -

As mentioned, for backwards compatibility - “wd” and “rc” roles are still a valid subset of the “node” role. - But those roles limit the types of remote connections to their corresponding API, - while “node” allows both RC and WebDriver remote connections. - -

Passing JVM properties (using the -D flag - before the -jar argument) - on the command line as well, - and these will be picked up and propagated to the nodes: - -

-Dwebdriver.chrome.driver=chromedriver.exe
- - -
Configuration of node with JSON
- -

You can also start grid nodes that are configured - with a JSON configuration file - -

$ java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
- -

And here is an example of a nodeConfig.json file: - -

{
-  "capabilities": [
-    {
-      "browserName": "firefox",
-      "acceptSslCerts": true,
-      "javascriptEnabled": true,
-      "takesScreenshot": false,
-      "firefox_profile": "",
-      "browser-version": "27",
-      "platform": "WINDOWS",
-      "maxInstances": 5,
-      "firefox_binary": "",
-      "cleanSession": true
-    },
-    {
-      "browserName": "chrome",
-      "maxInstances": 5,
-      "platform": "WINDOWS",
-      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
-    },
-    {
-      "browserName": "internet explorer",
-      "maxInstances": 1,
-      "platform": "WINDOWS",
-      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
-    }
-  ],
-  "configuration": {
-    "_comment" : "Configuration for Node",
-    "cleanUpCycle": 2000,
-    "timeout": 30000,
-    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
-    "port": 5555,
-    "host": ip,
-    "register": true,
-    "hubPort": 4444,
-    "maxSession": 5
-  }
-}
- -
A note about the -host flag
- -

For both hub and node, if the -host flag is not specified, - 0.0.0.0 will be used by default. This will bind to all the - public (non-loopback) IPv4 interfaces of the machine. If you have a special - network configuration or any component that creates extra network interfaces, - it is advised to set the -host flag with a value that allows the - hub/node to be reachable from a different machine. - -

Specifying the Port
- -

The default TCP/IP port used by the hub is 4444. If you need to change the port please use above mentioned configurations

- -

Troubleshooting

- -
Using Log file
-

For advance troubleshooting you can specify log file to log system messeges. -For that start Selenium GRID hub or node with -log argument. Please see the below example -

-
java -jar selenium-server-standalone.jar -role hub -log log.txt
- -

Use your favorite text editor to open log file (log.txt in above example) to find "ERROR" logs if you get issues

- -
Using -debug argument
-

Also you can use -debug argument to print debug logs on console. -For that start Selenium GRID hub or node with -debug argument. Please see the below example -

-
java -jar selenium-server-standalone.jar -role hub -debug
- - -

Docker Selenium

-

Docker provides a convenient way to - provision and scale Selenium Grid infrastructure in a unit known as a container. Containers are standardised units of software that contain everything required - to run the desired application including all dependencies in a reliable and repeatable - way on different machines. - - The Selenium project maintains a set of Docker images which you can download - and run to get a working grid up and running quickly. Nodes are available for - both Firefox and Chrome. Full details of how to provision a grid can be found - within the Docker Selenium - repository. - -

Prerequisite

-

The only requirement to run a grid is to have Docker installed and working. - Install Docker - - diff --git a/content/documentation/guidelines.html b/content/documentation/guidelines.html deleted file mode 100755 index daa35d614acf..000000000000 --- a/content/documentation/guidelines.html +++ /dev/null @@ -1,283 +0,0 @@ - - -Guidelines and Recommendations - - - - - - - -

Guidelines and Recommendations

- -

A note on "Best Practices": We've intentionally avoided the phrase "Best -Practices" in this documentation. No one approach works for all situations. -We prefer the idea of "Guidelines and Recommendations." We encourage -you to read through these and thoughtfully decide what approaches -will work for you in your particular environment. - -

Functional testing is difficult to get right for many reasons. - As if application state, complexity, and dependencies don't make testing difficult enough, - dealing with browsers (especially with cross-browser incompatibilities) - makes writing good tests a challenge. - -

Selenium provides tools to make functional user interaction easier, - but doesn't help you write well-architected test suites. - In this chapter we offer advice, guidelines, and recommendations. - on how to approach functional web page automation. - -

This chapter records software design patterns popular - amongst many of the users of Selenium - that have proven successful over the years. - - -

Page object models

- -

Page Object is a Design Pattern which has become popular in test -automation for enhancing test maintenance and reducing code -duplication. A page object is an object-oriented class that serves as -an interface to a page of your AUT. The tests then use the methods of -this page object class whenever they need to interact with that page -of the UI. The benefit is that if the UI changes for the page, the -tests themselves don’t need to change; only the code within the page -object needs to change. Subsequently, all changes to support that new -UI are located in one place. - -

The Page Object Design Pattern provides the following advantage: - there is clean separation between test code and page specific code - such as locators (or their use if you’re using a UI map) and layout. - - -

Page object methods should return a value

- - - - -

Domain Specific Language

- -

A domain specific language (DSL) is a system which provides the user with -an expressive means of solving a problem. It allows a user to -interact with the system on their terms – not just programmer-speak. - -

Your users, in general, don't care how your site looks. They don't -care about the decoration, animations, or graphics. They -want to use your system to push their new employees through the -process with minimal difficulty. They want to book travel to Alaska. -They want to configure and buy unicorns at a discount. Your job as the -tester is to come as close as you can to “capturing” this mind-set. -With that in mind, we set about “modeling” the application you're -working on, such that the test scripts (the user's only pre-release -proxy) “speak” for and represent the user. - -

With Selenium, DSL is usually represented by methods, written to make -the API simple and readable – they enable a report between the -developers and the stakeholders (users, product owners, business -intelligence specialists, etc.). - - -

Benefits

- - - - -

Java

- -

Here is an example of a reasonable DSL method in Java. - For brevity's sake, it assumes the `driver` object is pre-defined - and available to the method. - -

/**
- * Takes a username and password, fills out the fields, and clicks "login".
- * @return An instance of the AccountPage
- */
-public AccountPage loginAsUser(String username, String password) {
-  WebElement loginField = driver.findElement(By.id("loginField"));
-  loginField.clear();
-  loginField.sendKeys(username);
-
-  // Fill out the password field. The locator we're using is "By.id", and we should
-  // have it defined elsewhere in the class.
-  WebElement passwordField = driver.findElement(By.id("password"));
-  passwordField.clear();
-  passwordField.sendKeys(password);
-
-  // Click the login button, which happens to have the id "submit".
-  driver.findElement(By.id("submit")).click();
-
-  // Create and return a new instance of the AccountPage (via the built-in Selenium
-  // PageFactory).
-  return PageFactory.newInstance(AccountPage.class);
-}
- -

This method completely abstracts the concepts of input fields, -buttons, clicking, and even pages from your test code. Using this -approach, all your tester has to do is call this method. This gives -you a maintenance advantage: if the login fields ever changed, you -would only ever have to change this method - not your tests. - -

public void loginTest() {
-    loginAsUser("cbrown", "cl0wn3");
-
-    // Now that we're logged in, do some other stuff--since we used a DSL to support
-    // our testers, it's as easy as choosing from available methods.
-    do.something();
-    do.somethingElse();
-    Assert.assertTrue("Something should have been done!", something.wasDone());
-
-    // Note that we still haven't referred to a button or web control anywhere in this
-    // script...
-}
- -

It bears repeating: one of your primary goals should be writing an -API that allows your tests to address the problem at hand, and NOT -the problem of the UI. The UI is a secondary concern for your -users – they don't care about the UI, they just want to get their job -done. Your test scripts should read like a laundry list of things -the user wants to DO, and the things they want to KNOW. The tests -should not concern themselves with HOW the UI requires you to go -about it. - - -

Generating application state

- -

Selenium should not be used to prepare a test case. All repetitive -actions, and preparation for a test case, should be done through other -methods. For example, most web UIs have authentication (e.g. a login -form). Eliminating logging in via web browser before every test will -improve both the speed and stability of the test. A method should be -created to gain access to the AUT (e.g. using an API to login and set a -cookie). Also, creating methods to pre-load data for -testing should not be done using Selenium. As mentioned previously, -existing APIs should be leveraged to create data for the AUT. - - -

Mock external services

- -

Eliminating the dependencies on external services will greatly improve -the speed and stability of your tests. - - -

Improved reporting

- -

Selenium is not designed to report on the status of test cases -run. Taking advantage of the built-in reporting capabilities of unit -test frameworks is a good start. Most unit test frameworks have -reports that can generate xUnit or HTML formatted reports. xUnit -reports are popular for importing results to a Continuous Integration -(CI) server like Jenkins, Travis, Bamboo, etc. Here are some links -for more information regarding report outputs for several languages. - - - -

Avoid sharing state

- -

Although mentioned in several places it is worth mentioning again. Ensure tests are isolated from one another. -

Don't share test data. Imagine several tests that each query the database for valid orders before picking one to perform an action on. Should two tests pick up the same order you are likely to get unexpected behaviour. -

Clean up stale data in the application that might be picked up by another test e.g. invalid order records. -

Create a new WebDriver instance per test. This helps ensure test isolation and makes parallelisation simpler. - -

Test independency

- -

Write each test as its own unit. Write the tests in a way that won't be reliant on other tests to complete: - -

Let's say there is a content management system with which you can create some custom content which then appears on your website as a module after publishing, and it may take some time to sync between the CMS and the application. - -

A wrong way of testing your module is that the content is created and published in one test, and then checking the module in another test. This is not feasible as the content may not be available immediately for the other test after publishing. -

Instead, you can create a stub content which can be turned on and off within the affected test, and use that for validating the module. However, for content creation, you can still have a separate test. - - -

Consider using a fluent API

- -

Martin Fowler coined the term "Fluent API". Selenium already -implements something like this in their FluentWait class which is -meant as an alternative to the standard Wait class. You could -enable the Fluent API design pattern in your page object and then -query the Google search page with a code snippet like this one: - -

driver.get( "http://www.google.com/webhp?hl=en&tab=ww" );
-GoogleSearchPage gsp = new GoogleSearchPage();
-gsp.withFluent().setSearchString().clickSearchButton();
- -

The Google page object class with this fluent behavior - might look like this: - -

public class GoogleSearchPage extends LoadableComponent<GoogleSearchPage> {
-  private final WebDriver driver;
-  private GSPFluentInterface gspfi;
-
-  public class GSPFluentInterface {
-    private GoogleSearchPage gsp;
-
-    public GSPFluentInterface(GoogleSearchPage googleSearchPage) {
-        gsp = googleSearchPage;
-    }
-
-    public GSPFluentInterface clickSearchButton() {
-        gsp.searchButton.click();
-        return this;
-    }
-
-    public GSPFluentInterface setSearchString( String sstr ) {
-        clearAndType( gsp.searchField, sstr );
-        return this;
-    }
-  }
-
-  @FindBy(id = "gbqfq") private WebElement searchField;
-  @FindBy(id = "gbqfb") private WebElement searchButton;
-  public GoogleSearchPage(WebDriver driver) {
-    gspfi = new GSPFluentInterface( this );
-    this.get(); // If load() fails, calls isLoaded() until page is finished loading
-    PageFactory.initElements(driver, this); // Initialize WebElements on page
-  }
-
-  public GSPFluentInterface withFluent() {
-    return gspfi;
-  }
-
-  public void clickSearchButton() {
-    searchButton.click();
-  }
-
-  public void setSearchString( String sstr ) {
-    clearAndType( searchField, sstr );
-  }
-
-  @Override
-  protected void isLoaded() throws Error {
-    Assert.assertTrue("Google search page is not yet loaded.", isSearchFieldVisible() );
-  }
-
-  @Override
-  protected void load() {
-    if ( isSFieldPresent ) {
-      Wait<WebDriver> wait = new WebDriverWait( driver, 3 );
-      wait.until( visibilityOfElementLocated( By.id("gbqfq") ) ).click();
-    }
-  }
-}
- - -

Fresh browser per test

- -

Start each test from a clean known state. - Ideally, spin up a new virtual machine for each test. - If spinning up a new virtual machine is not practical, - at least start a new WebDriver for each test. - For Firefox, start a WebDriver with your known profile. - -

FirefoxProfile profile = new FirefoxProfile(new File("pathToFirefoxProfile"));
-WebDriver driver = new FirefoxDriver(profile);
diff --git a/content/documentation/html-runner.html b/content/documentation/html-runner.html deleted file mode 100755 index 4bfc669a9ec7..000000000000 --- a/content/documentation/html-runner.html +++ /dev/null @@ -1,102 +0,0 @@ - - -Selenium HTML-runner - - - - - -

Selenium HTML-runner

- -

Selenium HTML-runner allows you to run Test Suites from a -command line. Test Suites are HTML exports from Selenium IDE or -campatible tools. - - -

Common information

-
-
  • Combination of releases of geckodriver / firefox / - selenium-html-runner matters. There might be a software - compatibility matrix somewhere. -
  • selenium-html-runner runs only Test Suite (not Test Case - what - is for example an export from Monitis Transaction Monitor). Be - sure you comply with this. -
  • For Linux users with no DISPLAY - you need to start html-runner - with Virtual display (search for xvfb) -
  • - -

    Example Linux environment

    -

    Install / download following software packages: -

    - -
    
    -[user@localhost ~]$ cat /etc/redhat-release
    -CentOS Linux release 7.4.1708 (Core)
    -
    -[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
    -xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
    -firefox-52.4.0-1.el7.centos.x86_64
    -java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
    -java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
    -
    - -

    -Test Suite example: -

    - -
    
    -[user@localhost ~]$ cat testsuite.html
    -<?xml version="1.0" encoding="UTF-8"?>
    -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    -<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    -<head>
    -  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
    -  <title>Test Suite</title>
    -</head>
    -<body>
    -<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
    -<tr><td><b>Test Suite</b></td></tr>
    -<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
    -</tbody></table>
    -</body>
    -</html>
    -
    -
    - -

    How to run selenium-html-runner headless

    - -

    Now, the most important part, an example of how to run the -selenium-html-runner! Your experience might vary depending on software -combinations - geckodriver/FF/html-runner releases. - -xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html - - -

    
    -[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
    -Multi-window mode is longer used as an option and will be ignored.
    -1510061109691   geckodriver     INFO    geckodriver 0.18.0
    -1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
    -1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
    -1510061111084   Marionette      INFO    Listening on port 43229
    -1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
    -Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
    -INFO: Detected dialect: W3C
    -2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
    -2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
    -2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
    -2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
    -2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
    -Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
    -INFO: |open | /auth_mellon.php |  |
    -Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
    -INFO: |waitForPageToLoad | 3000 |  |
    -.
    -.
    -.etc
    -
    -result:
    -PASS
    -
    -
    -
    diff --git a/content/documentation/install.html b/content/documentation/install.html deleted file mode 100755 index ebc351f7b157..000000000000 --- a/content/documentation/install.html +++ /dev/null @@ -1,77 +0,0 @@ - - -Installation - - - - - - - -

    Selenium installation

    - -

    Selenium setup is quite different from the setup of other commercial tools. - You don’t install a tool using Selenium binaries - but rather set up your test automation project to use such binaries - in the language of your choice. - The Selenium binary you would need - depends on the browsers you want to run your tests upon. - -

    Using browser specific JAR

    - -

    If you want to run tests only in a specific browser, - you can add the dependency for that browser in your pom.xml file. - For example, you should add following dependency in your pom.xml - file to run your tests only in Firefox: - -

    <dependency>
    -  <groupId>org.seleniumhq.selenium</groupId>
    -  <artifactId>selenium-firefox-driver</artifactId>
    -  <version>3.X</version>
    -</dependency>
    -
    - -

    In a similar manner, if you want to run tests only in Chrome, - you should add the following dependency: - -

    <dependency>
    -  <groupId>org.seleniumhq.selenium</groupId>
    -  <artifactId>selenium-chrome-driver</artifactId>
    -  <version>3.X</version>
    -</dependency>
    -
    - - -

    Using non browser specific JAR

    - -

    More often than not you would need to run tests - on more than one browser. - Hence you would use selenium-java - Maven dependency in your project. - The selenium-java JAR - contains the language bindings and the drivers - but not the server side piece. - -

    <dependency>
    -  <groupId>org.seleniumhq.selenium</groupId>
    -  <artifactId>selenium-java</artifactId>
    -  <version>3.X</version>
    -</dependency>
    -
    - - -

    Using standalone JAR

    - - -

    If you plan to use Selenium Grid - then you should download - selenium-server-standalone JAR file. - Selenium-server-standalone jar is never uploaded, - but all the components are available via - selenium-server. - The standalone JAR contains everything, - including the remote Selenium server - and the client-side bindings. - This means that if you use the selenium-server-standalone jar - in your project, then you don't have to add selenium-java - or a browser specific jar. diff --git a/content/documentation/intro.html b/content/documentation/intro.html deleted file mode 100755 index 00460f5c1625..000000000000 --- a/content/documentation/intro.html +++ /dev/null @@ -1,383 +0,0 @@ - - -Introduction - - - - - - - -

    Introduction

    - - -

    The Selenium project and tools

    - - -

    Selenium controls web browsers

    - -

    Selenium is many things, - but at its core it's a toolset for web browser automation - that uses the best techniques available - to remotely control browser instances - and emulate a user's interaction with the browser. - -

    It allows users to simulate common activities performed by end-users; - entering text into fields, - selecting drop-down values and checking boxes, - and clicking links in documents. - It also provides many other controls such as mouse movement, - arbitrary JavaScript execution, and much more. - -

    Although used primarily for front-end testing of websites, - Selenium is at its core a browser user agent library. - The interfaces are ubiquitous to their application, - which encourages composition with other libraries to suit your purpose. - - -

    One interface to rule them all

    - -

    One of the project's guiding principles - is to support a common interface for all (major) browser technologies. - Web browsers are incredibly complex, highly engineered applications, - performing their operations in completely different ways - but which frequently look the same while doing so. - Even though the text is rendered in the same fonts, - the images are displayed in the same place - and the links take you to the same destination. - What is happening underneath is as different as night and day. - Selenium “abstracts” these differences, - hiding their details and intricacies from the person writing the code. - This allows you to write several lines of code to perform a complicated workflow, - but these same lines will execute on Firefox, - Internet Explorer, Chrome, and all other supported browsers. - - -

    Tools and support

    - -

    Selenium's minimalist design approach gives it - versatility to be included as a component in bigger applications. - The surrounding infrastructure provided under the Selenium umbrella - gives you the tools to put together - your own grid of browsers - so tests can be run on different browsers and multiple operating systems - across a range of machines. - -

    Imagine a bank of computers in your server room or data centre - all firing up browsers at the same time - hitting your site's links, forms, - and tables—testing your application 24 hours a day. - Through the simple programming interface - provided for the most common languages, - these tests will run tirelessly in parallel, - reporting back to you when errors occur. - -

    It's an aim to help make this a reality for you, - by providing users with tools and documentation to not only control browsers, - but to make it easy to scale and deploy such grids. - - -

    Who uses Selenium

    - -

    Many of the most important companies in the world - have adopted Selenium for their browser-based testing, - often replacing years-long efforts involving other proprietary tools. - As it has grown in popularity, so have its requirements and challenges multiplied. - -

    As the web becomes more complicated - and new technologies are added to websites, - it's the mission of this project to keep up with them where possible. - Being an open source project, - this support is provided through the generous donation of time from many volunteers, - every one of which has a “day job”. - -

    Another mission of the project is to encourage - more volunteers to partake in this effort, - and build a strong community - so that the project can continue to keep up with emerging technologies - and remain a dominant platform for functional test automation. - - -

    History

    - -

    When Selenium 1 was released in 2004, - it was out of the necessity to reduce time spent - manually verifying consistent behaviour in the front-end of a web application. - It made use of what tools were available at the time, - and relied heavily on the injection of JavaScript to the web page under test - to emulate a user's interaction. - -

    Whilst JavaScript is a good tool to let you introspect the properties of the DOM - and to do certain client-side observations that you would otherwise not be able to do, - it falls short on the ability to naturally replicate a user's interactions - as if the mouse and keyboard are being used. - -

    Since then, Selenium has grown and matured a lot, - into a tool widely used by many—if not most—of - the largest organisations around the world. - Selenium has gone from a homebrewed test automation toolkit developed at Thoughtworks - for a niché audience and a specific use case, - to the world's de facto browser automation library. - -

    Just as Selenium RC made use of the tools of the trade available at the time, - Selenium WebDriver drives that tradition on by taking - the browser interaction part to the browser vendor's home turf, - and asking them to take responsibility of the backend, browser-facing implementations. - Recently this work has evolved into a W3C standardisation process - where the goal is to turn the WebDriver component in Selenium - into the du jeur remote control library for user agents. - - -

    On test automation

    - -

    First, start by asking yourself whether or not you really need to use a browser. - Odds are good that, at some point, if you're working on a complex web application, - you will need to open a browser and actually test it. - -

    Functional end-user tests such as Selenium tests are expensive to run, however. - Furthermore, they typically require substantial infrastructure - to be in place to be run effectively. - It's a good rule to always ask yourself if what you want to test - can be done using more lightweight test approaches such as unit tests - or with a lower-level approach. - -

    Once you have made the determination that you're in the web browser testing business, - and you have your Selenium environment ready to begin writing tests, - you will generally perform some combination of three steps: - -

      -
    1. Set up the data -
    2. Perform a discrete set of actions -
    3. Evaluate the results -
    - -

    You will want to keep these steps as short as possible; - one to two operations should be enough much of the time. - Browser automation has the reputation of being “flaky”, - but in reality that is because users frequently demand too much of it. - In later chapters, we will return to techniques you can use - to mitigate apparent intermittent problems in tests, - in particular on how to overcome race conditions - between the browser and WebDriver. - -

    By keeping your tests short - and using the web browser only when you have absolutely no alternative, - you can have many tests with minimal flake. - -

    A distinct advantage of Selenium tests - are their inherent ability to test all components of the application, - from backend to frontend, from a user's perspective. - So in other words, whilst functional tests may be expensive to run, - they also encompass large business-critical portions at one time. - - -

    Testing requirements

    - -

    As mentioned before, Selenium tests can be expensive to run. - To what extent depends on the browser you're running the tests against, - but historically browsers' behaviour has varied so much that it has often - been a stated goal to cross-test against multiple browsers. - -

    Selenium allows you to run the same instructions against multiple browsers - on multiple operating systems, - but the enumeration of all the possible browsers, - their different versions, and the many operating systems they run on - will quickly become a non-trival undertaking. - - -

    Let’s start with an example

    - -

    Larry has written a web site which allows users to order their own - custom unicorns. - -

    The general workflow (what we'll call the “happy path”) is something - like this: - -

    - -

    It would be tempting to write one grand Selenium script - to perform all these operations–many will try. - Resist the temptation! - Doing so will result in a test that - (a) takes a long time, - (b) will be subject to some common issues around page rendering timing issues, and - (c) is such that if it fails, - it won't give you a concise, “glanceable” method for diagnosing what went wrong. - -

    The preferred strategy for testing this scenario would be - to break it down to a series of independent, speedy tests, - each of which has one “reason” to exist. - -

    Let's pretend you want to test the second step: - Configuring your unicorn. - It will perform the following actions: - -

    - -

    Note that we're skipping the rest of these steps– - we will test the rest of the workflow in other small, discrete test cases, - after we're done with this one. - -

    To start off, you need to create an account. - Here you have some choices to make: - -

    - -

    Regardless of how you answer this question, - the solution is to make it part of the “set up the data” portion of the test– - if Larry has exposed an API which enables you (or anyone) - to create and update user accounts, - be sure to use that to answer this question– - if possible, you want to launch the browser only after you have a user “in hand”, - whose credentials you can just log in with. - -

    If each test for each workflow begins with the creation of a user account, - many seconds will be added to the execution of each test. - Calling an API and talking to a database are quick, - “headless” operations that don't require the expensive process of - opening a browser, navigating to the right pages, - clicking and waiting for the forms to be submitted, etc. - -

    Ideally, you can address this set-up phase in one line of code, - which will execute before any browser is launched: - -

    // Create a user who has read-only permissions--they can configure a unicorn,
    -// but they do not have payment information set up, nor do they have
    -// administrative privileges. At the time the user is created, its email
    -// address and password are randomly generated--you don't even need to
    -// know them.
    -User user = UserFactory.createCommonUser(); //This method is defined elsewhere.
    -
    -// Log in as this user.
    -// Logging in on this site takes you to your personal "My Account" page, so the
    -// AccountPage object is returned by the loginAs method, allowing you to then
    -// perform actions from the AccountPage.
    -AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
    - -

    As you can imagine, the UserFactory can be extended - to provide methods such as createAdminUser(), and createUserWithPayment(). - The point is, these two lines of code do not distract you from the ultimate purpose of this test: - configuring a unicorn. - -

    The intricacies of the Page Object model - will be discussed in later chapters, but we will introduce the concept here: - -

    Your tests should be composed of actions, - performed from the user's point of view, - within the context of pages in the site. - These pages are stored as objects, - which will contain specific information about how the web page is composed - and how actions are performed– - very little of which should concern you as a tester. - -

    What kind of unicorn do you want? - You might want pink, but not necessarily. - Purple has been quite popular lately. - Does she need sunglasses? Star tattoos? - These choices, while difficult, are your primary concern as a tester– - you need to ensure that your order fulfillment center - sends out the right unicorn to the right person, - and that starts with these choices. - -

    Notice that nowhere in that paragraph do we talk about buttons, - fields, drop-downs, radio buttons, or web forms. - Neither should your tests! - You want to write your code like the user trying to solve their problem. - Here is one way of doing this (continuing from the previous example): - -

    // The Unicorn is a top-level Object--it has attributes, which are set here. 
    -// This only stores the values; it does not fill out any web forms or interact
    -// with the browser in any way.
    -Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);
    -
    -// Since we're already "on" the account page, we have to use it to get to the
    -// actual place where you configure unicorns. Calling the "Add Unicorn" method
    -// takes us there.
    -AddUnicornPage addUnicornPage = accountPage.addUnicorn();
    -
    -// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
    -// its createUnicorn() method. This method will take Sparkles' attributes,
    -// fill out the form, and click submit.
    -UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
    - -

    Now that you've configured your unicorn, - you need to move on to step 3: making sure it actually worked. - -

    // The exists() method from UnicornConfirmationPage will take the Sparkles 
    -// object--a specification of the attributes you want to see, and compare
    -// them with the fields on the page.
    -Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
    - -

    Note that the tester still hasn't done anything but talk about unicorns in this code– - no buttons, no locators, no browser controls. - This method of modelling the application - allows you to keep these test-level commands in place and unchanging, - even if Larry decides next week that he no longer likes Ruby-on-Rails - and decides to re-implement the entire site - in the latest Haskell bindings with a Fortran front-end. - -

    Your page objects will require some small maintenance - in order to conform to the site redesign, - but these tests will remain the same. - Taking this basic design, - you will want to keep going through your workflows with the fewest browser-facing steps possible. - Your next workflow will involve adding a unicorn to the shopping cart. - You will probably want many iterations of this test in order to make sure the cart is keeping its state properly: - Is there more than one unicorn in the cart before you start? - How many can fit in the shopping cart? - If you create more than one with the same name and/or features, will it break? - Will it only keep the existing one or will it add another? - -

    Each time you move through the workflow, - you want to try to avoid having to create an account, - login as the user, and configure the unicorn. - Ideally, you'll be able to create an account - and pre-configure a unicorn via the API or database. - Then all you have to do is log in as the user, locate Sparkles, - and add her to the cart. - - -

    Types of testing

    - -

    TODO: Add paragraphs about acceptance testing, performance testing, - load testing, regression testing, test driven development, and/or - behavior-driven development (JBehave, Capybara, & Robot Framework), - with how they relate to Selenium. - - -

    About this documentation

    - -

    These docs, like the code itself, are maintained 100% by volunteers - within the Selenium community. - Many have been using it since its inception, - but many more have only been using it for a short while, - and have given their time to help improve the on-boarding experience - for new users. - -

    If there is an issue with the documentation, we want to know! - The best way to communicate an issue is to visit - https://github.com/seleniumhq/docs/issues - and search to see whether or not the issue has been filed already. - If not, feel free to open one! - -

    Many members of the community frequent - the #selenium IRC channel at irc.freenode.net. Feel free to drop in and ask questions - and if you get help which you think could be of use within these documents, - be sure to add your contribution! - We can update these documents, - but it's much easier for everyone when we get contributions - from outside the normal committers. diff --git a/content/documentation/quick.html b/content/documentation/quick.html deleted file mode 100755 index 28af668eab0c..000000000000 --- a/content/documentation/quick.html +++ /dev/null @@ -1,67 +0,0 @@ - - -Quick tour - - - - - - -

    Quick tour

    - -

    Selenium is not just one tool or API - but it composes many tools. - - -

    WebDriver

    - -

    WebDriver is also known as Selenium - 2. If you are beginning with desktop website test automation then you - are going to be using WebDriver APIs. WebDriver uses browser - automation APIs provided by browser vendors to control browser and - run tests. This is as if a real user is operating the browser. Since - WebDriver does not require its API to be compiled with application - code, it is not intrusive in nature. Hence, you are testing the - same application which you push live. - - -

    Selenium Remote Control

    - -

    Selenium Remote Control is also known - as Selenium 1. Selenium RC was the most prominent Selenium tool - before the advent of Selenium WebDriver. Selenium RC would use a - proxy server and inject JavaScript into a browser to be able to control - it. Given the intrusive nature Selenium RC had on a browser, - you could never be sure if what you were testing was the same as - the application you wanted to push live. Selenium 2 APIs yet contain Selenium RC APIs but - Selenium 3 would completely get rid of Selenium RC APIs. If you are - still using Selenium RC then you must - migrate to Selenium WebDriver. - - -

    Selenium IDE

    - -

    Selenium IDE is a - Firefox plugin which can be used to record test steps in Firefox itself. - Selenium IDE can be used to generate quick and dirty - test code in a variety of programming languages (i.e. C#, - Java, Python, and Ruby). Given the maintainability of code generated - through Selenium IDE, it is not recommended to use it for anything - more than getting acquainted with element locators or generating - throw away code. We're sure that once you get used to the - WebDriver API, you will never use Selenium IDE. - - -

    Selenium Grid

    - -

    Soon after development of WebDriver tests, you may face a need of - running your tests on multiple browser and operating system combinations. - This is where Selenium Grid - comes to the rescue. - - -

    Selenium HTML Runner

    - -

    This tool allows you to run Test Suites from the command - line. Test Suites are HTML exports from Selenium IDE or campatible - tools. Selenium HTML-runner diff --git a/content/documentation/rc.html b/content/documentation/rc.html deleted file mode 100755 index 870ba21c30f5..000000000000 --- a/content/documentation/rc.html +++ /dev/null @@ -1,11 +0,0 @@ - - -Selenium Remote Control - - - - - - - -

    Selenium Remote Control

    diff --git a/content/documentation/rctowd.html b/content/documentation/rctowd.html deleted file mode 100755 index 9fa00788ba89..000000000000 --- a/content/documentation/rctowd.html +++ /dev/null @@ -1,11 +0,0 @@ - - -Selenium Remote Control to WebDriver migration - - - - - - - -

    Selenium Remote Control to WebDriver migration

    diff --git a/content/documentation/remote.html b/content/documentation/remote.html deleted file mode 100755 index e9602b06a0ee..000000000000 --- a/content/documentation/remote.html +++ /dev/null @@ -1,180 +0,0 @@ - - -Remote WebDriver - - - - - - - -

    Remote WebDriver

    - -You can use WebDriver remotely the same way you would use it -locally. The primary difference is that a remote WebDriver needs to be -configured so that it can run your tests on a separate machine. - -A remote WebDriver is composed of two pieces: a client and a -server. The client is your WebDriver test and the server is simply a -Java servlet, which can be hosted in any modern JEE app server. - -

    The Remote WebDriver server

    - -The server will always run on the machine with the browser you want to -test. The server can be used either from the command line or through code -configuration. - - -

    Starting the server from the command line

    - -Once you have downloaded selenium-server-standalone-{VERSION}.jar, -place it on the computer with the browser you want to test. Then, from -the directory with the jar, run the following: - -
    $ java -jar selenium-server-standalone-{VERSION}.jar
    - - -

    Considerations for running the server

    - -The caller is expected to terminate each session properly, calling -either Selenium#stop() or WebDriver#quit. - -The selenium-server keeps in-memory logs for each ongoing session, -which are cleared when Selenium#stop() or WebDriver#quit is called. If -you forget to terminate these sessions, your server may leak memory. If -you keep extremely long-running sessions, you will probably need to -stop/quit every now and then (or increase memory with -Xmx jvm option). - - -

    Timeouts (from version 2.21)

    - -The server has two different timeouts, which can be set as follows: - -
    $ java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
    - -
    -
    browserTimeout
    -
    Controls how long the browser is allowed to hang (value in seconds). - -
    timeout
    -
    Controls how long the client is allowed to be gone - before the session is reclaimed (value in seconds). -
    - -

    The system property selenium.server.session.timeout - is no longer supported as of 2.21. - -

    Please note that the browserTimeout - is intended as a backup timeout mechanism - when the ordinary timeout mechanism fails, - which should be used mostly in grid/server environments - to ensure that crashed/lost processes do not stay around for too long, - polluting the runtime environment. - - -

    Configuring the server programmatically

    - -

    In theory, the process is as simple as mapping the DriverServlet to -a URL, but it's also possible to host the page in a lightweight -container, such as Jetty configured entirely in code. Steps to do this -follow. - -

    Download the "selenium-server.zip" and unpack. Put the JARs on the -CLASSPATH. Create a new class called AppServer. Here, I'm using -Jetty, so you'll need to download that as well: - -

    import org.mortbay.jetty.Connector;
    -import org.mortbay.jetty.Server;
    -import org.mortbay.jetty.nio.SelectChannelConnector;
    -import org.mortbay.jetty.security.SslSocketConnector;
    -import org.mortbay.jetty.webapp.WebAppContext;
    -
    -import javax.servlet.Servlet;
    -import java.io.File;
    -
    -import org.openqa.selenium.remote.server.DriverServlet;
    -
    -public class AppServer {
    -  private Server server = new Server();
    -
    -  public AppServer() throws Exception {
    -    WebAppContext context = new WebAppContext();
    -    context.setContextPath("");
    -    context.setWar(new File("."));
    -    server.addHandler(context);
    -
    -    context.addServlet(DriverServlet.class, "/wd/*");
    -
    -    SelectChannelConnector connector = new SelectChannelConnector();
    -    connector.setPort(3001);
    -    server.addConnector(connector);
    -
    -    server.start();
    -  }
    -}
    - -

    Running Remote WebDriver client

    - -

    First, we need to connect to the RemoteWebDriver. - We do this by pointing the URL to the address of the server running our tests. - In order to customize our configuration, we set desired capabilities. - Below is an example of instantiating a remote WebDriver object - pointing to our remote web server, www.example.com, - running our tests on Firefox. - -

    require 'selenium-webdriver'
    -
    -driver = Selenium::WebDriver.for :remote, url: "http://www.example.com", desired_capabilities: :firefox
    -driver.get "http://www.google.com"
    -driver.close
    - -

    To further customize our test configuration, we can add other desired capabilities. - - -

    Desired capabilities

    - -

    Desired capabilities can be expanded further. - All remote Webdriver capabilities are sent through JsonWireProtocol. - For a list of configurable capabilities, and more information on JsonWireProtocol, - please visit the documentation here. - -

    For example, suppose you wanted to run Chrome on Windows XP, - using Chrome version 27: - -

    caps = Selenium::WebDriver::Remote::Capabilities.chrome
    -caps.platform = Windows XP
    -caps.version = 27
    -
    -driver = Selenium::WebDriver.for :remote, :url => "http://www.example.com", :desired_capabilities => caps
    - - -

    Local file detector

    - -

    The Local File Detector allows the transfer of files from the client -machine to the remote server. For example, if a test needs to upload a -file to a web application, a remote WebDriver can automatically transfer -the file from the local machine to the remote web server during -runtime. This allows the file to be uploaded from the remote machine -running the test. It is not enabled by default and can be enabled in -the following way: - -

    - driver.setFileDetector(new LocalFileDetector());
    - @driver.file_detector = lambda do |args|
    -  # args => ["/path/to/file"]
    -  str = args.first.to_s
    -  str if File.exist?(str)
    -end
    -
    - -

    Once the above code is defined, you can upload a file in your test in the following way: - -

    - driver.get("http://sso.dev.saucelabs.com/test/guinea-file-upload");
    -WebElement upload = driver.findElement(By.id("myfile"));
    -upload.sendKeys("/Users/sso/the/local/path/to/darkbulb.jpg");
    - @driver.navigate.to "http://sso.dev.saucelabs.com/test/guinea-file-upload"
    -    element = @driver.find_element(:id, 'myfile')
    -    element.send_keys "/Users/sso/SauceLabs/sauce/hostess/maitred/maitred/public/images/darkbulb.jpg"
    -
    - diff --git a/content/documentation/start.html b/content/documentation/start.html deleted file mode 100755 index 8c89ada6c5e4..000000000000 --- a/content/documentation/start.html +++ /dev/null @@ -1,319 +0,0 @@ - - -Getting started with WebDriver - - - - - - - -

    Getting started with WebDriver

    - -

    Selenium supports automation of all the major browsers in the market - through the use of WebDriver. - WebDriver is an API and protocol that defines a language-neutral interface - for controlling the behaviour of web browsers. - Each browser is backed by a specific WebDriver implementation, called a *driver*. - The driver is the component responsible for delegating down to the browser, - and handles communication to and from Selenium and the browser. - -

    This separation is part of a conscious effort to have browser vendors - take responsibility for the implementation for their browsers. - Selenium makes use of these third party drivers where possible, - but also provides its own drivers maintained by the project - for the cases when this is not a reality. - -

    The Selenium framework ties all of these pieces together - through a user-facing interface that enables the different browser backends - to be used transparently, - enabling cross-browser and cross-platform automation. - -

    More details about drivers can be found in - Driver Idiosyncracies. - -

    Consumer browsers

    - -

    The Selenium framework officially supports the following browsers: - - - - - - - - - -
    Browser Maintainer Versions Supported
    Chromium Chromium All versions
    Firefox Mozilla 54 and newer
    Internet Explorer Selenium 6 and newer
    Opera Opera Chromium / Presto 10.5 and newer
    Safari Apple 10 and newer
    - -

    Specialised browsers

    - -

    There is also a set of specialized browsers out there - typically used in development environments. - We can make use of some of these browsers for automation purposes also, - and Selenium ties in support for the following specialized drivers: - - - - - - - - - - - - - - - -
    Driver Name Purpose Maintainer
    PhantomJSDriverHeadless PhantomJS browser backed by QtWebKit.GhostDriver project
    HtmlUnitDriverHeadless browser emulator backed by Rhino.Selenium project
    - -

    Other third party drivers and plugins

    - -

    Selenium can be extended through the use of plugins. Here are a number of plugins created and maintained by third parties. For more information on how to create your own plugin or have it listed, consult the docs. - -

    Please note that these plugins are not supported, maintained, hosted, or endorsed by the Selenium project. In addition, be advised that the plugins listed below are not necessarily licensed under the Apache License v.2.0. Some of the plugins are available under another free and open source software license; others are only available under a proprietary license. Any questions about plugins and their license of distribution need to be raised with their respective developer(s). - - - - - - - - - - - -
    BrowserLatest version
    Google ChromeDriver2.29 - 2017-04-04changelogissueswiki
    - -

    Locating elements

    - - -

    Locating one element

    - -

    One of the most fundamental techniques to learn when using WebDriver is -how to find elements on the page. WebDriver offers a number of built-in selector -types, amongst them finding an element by its ID attribute: - -

    -  WebElement cheese = driver.findElement(By.id("cheese"));
    -  driver.find_element_by_id("cheese")
    -  IWebElement element = driver.FindElement(By.Id("cheese"));
    -  driver.find_element(id: "cheese")
    -  driver.findElement(By.id('cheese'))
    -
    - -

    As seen in the example, locating elements in WebDriver is done on the -WebDriver instance object. The findElement(By) method returns -another fundamental object type, the WebElement. - -

    - -

    Once you have a reference to a web element that's been “found”, - you can narrow the scope of your search - by using the same call on that object instance: - -

    -  
    -    WebElement cheese = driver.findElement(By.id("cheese"));
    -    WebElement cheddar = cheese.findElement(By.id("cheddar"));
    -  
    -  
    -    cheese = driver.find_element_by_id("cheese")
    -    cheddar = cheese.find_elements_by_id("cheddar")
    -  
    -  
    -    cheese = driver.find_element(id: "cheese")
    -    cheddar = cheese.find_elements(id: "cheddar")
    -  
    -
    - -

    You can do this because both the WebDriver and WebElement types -implement the SearchContext -interface. In WebDriver, this is known as a role-based interface. -Role-based interfaces allow you to determine whether a particular -driver implementation supports a given feature. These interfaces are -clearly defined and try to adhere to having only a single role of -responsibility. You can read more about WebDriver's design and what -roles are supported in which drivers in the [Some Other Section Which -Must Be Named](#). - - -

    Consequently, the By interface used above also supports a -number of additional locator strategies. A nested lookup might not be -the most effective cheese location strategy since it requires two -separate commands to be issued to the browser; first searching the DOM -for an element with ID “cheese”, then a search for “cheddar” in a -narrowed context. - -

    To improve the performance slightly, we should try to use a more -specific locator: WebDriver supports looking up elements -by CSS locators, allowing us to combine the two previous locators into -one search: - -

    driver.findElement(By.cssSelector("#cheese #cheddar"));cheddar = driver.find_element_by_css_selector("#cheese #cheddar")
    - - -

    Locating multiple elements

    - -

    It's possible that the document we are working with may turn out to have an -ordered list of the cheese we like the best: - -

    <ol id=cheese>
    - <li id=cheddar>…
    - <li id=brie>…
    - <li id=rochefort>…
    - <li id=camembert>…
    -</ul>
    - -

    Since more cheese is undisputably better, and it would be cumbersome -to have to retrieve each of the items individually, a superior -technique for retrieving cheese is to make use of the pluralized -version findElements(By). This method returns a collection of web -elements. If only one element is found, it will still return a -collection (of one element). If no elements match the locator, an -empty list will be returned. - -

    -  List<WebElement> muchoCheese = driver.findElements(By.cssSelector("#cheese li"));
    -  mucho_cheese = driver.find_elements_by_css_selector("#cheese li")
    -  mucho_cheese = driver.find_elements(css: "#cheese li")
    -
    - - -

    Element selection strategies

    - -

    There are eight different built-in element location strategies in WebDriver: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    LocatorDescription
    class nameLocates elements whose class name contains the search value - (compound class names are not permitted)
    css selectorLocates elements matching a CSS selector
    idLocates elements whose ID attribute matches the search value
    nameLocates elements whose NAME attribute matches the search value
    link textLocates anchor elements whose visible text matches the search value
    partial link textLocates anchor elements whose visible text partially matches the search value
    tag nameLocates elements whose tag name matches the search value
    xpathLocates elements matching an XPath expression
    - - -

    Tips on using selectors

    - -

    In general, if HTML IDs are available, unique, and consistently -predictable, they are the preferred method for locating an element on -a page. They tend to work very quickly, and forego much processing -that comes with complicated DOM traversals. - -

    If unique IDs are unavailable, a well-written CSS selector is the -preferred method of locating an element. XPath works as well as CSS -selectors, but the syntax is complicated and frequently difficult to -debug. Though XPath selectors are very flexible, they're typically -not performance tested by browser vendors and tend to be quite slow. - -

    Selection strategies based on link text and partial link text have -drawbacks in that they only work on link elements. Additionally, they -call down to XPath selectors internally in WebDriver. - -

    Tag name can be a dangerous way to locate elements. There are -frequently multiple elements of the same tag present on the page. -This is mostly useful when calling the findElements(By) method which -returns a collection of elements. - -

    The recommendation is to keep your locators as compact and -readable as possible. Asking WebDriver to traverse the DOM structure -is an expensive operation, and the more you can narrow the scope of -your search, the better. - -

    Performing actions on the AUT

    - -

    You can set an element's text using the sendKeys method as follows: - -

    -  
    -    String name = "Charles";
    -    driver.findElement(By.name("name")).sendKeys(name);
    -  
    -  
    -    name = "Charles"
    -    driver.find_element_by_name("name").send_keys(name)
    -  
    -  
    -    name = "Charles"
    -    driver.find_element(name: "name").send_keys(name)
    -  
    -
    - -

    Some web applications use JavaScript libraries to add drag-and-drop -functionality. The following is a basic example of dragging one -element onto another element: - -

    -  
    -    WebElement source = driver.findElement(By.id("source"));
    -    WebElement target = driver.findElement(By.id("target"));
    -    new Actions(driver).dragAndDrop(source, target).build().perform();
    -  
    -  
    -    source = driver.find_element_by_id("source")
    -    target = driver.find_element_by_id("target")
    -    ActionChains(driver).drag_and_drop(source, target).perform()
    -  
    -  
    -    source = driver.find_element(id: "source")
    -    target = driver.find_element(id: "target")
    -    driver.action.drag_and_drop(source, target).perform
    -  
    -
    - - -

    Clicking on an element

    - -

    You can click on an element using the click method: - -

    -  driver.findElement(By.cssSelector("input[type='submit']")).click();
    -  driver.find_element_by_css_selector("input[type='submit']").click()
    -  driver.find_element(css: "input[type='submit']").click
    -
    diff --git a/content/documentation/support.html b/content/documentation/support.html deleted file mode 100755 index 9c7788334bbf..000000000000 --- a/content/documentation/support.html +++ /dev/null @@ -1,366 +0,0 @@ - - -Support Packages - - - - - - - -

    Support Packages

    - -

    Browser navigation

    - -

    There are commands for various webpage loading actions: - -

    - // Navigate to a URL (both of the statements below are
    -// functionally equivalent).
    -driver.get("https://www.google.com");
    -driver.navigate().to("https://www.google.com");
    -
    -// Go forward one page in the browser (if you're not on the
    -// last page that was viewed).
    -driver.navigate().forward();
    -
    -// Go back one page in the browser (if you're not on the
    -// first page that was viewed).
    -driver.navigate().back();
    -
    -// Refresh the current page.
    -driver.navigate().refresh();
    - # Navigate to a URL.
    -driver.get('https://www.google.com')
    -
    -# Go forward one page in the browser (if you're not on the
    -# last page that was viewed).
    -driver.forward()
    -
    -# Go back one page in the browser (if you're not on the
    -# first page that was viewed).
    -driver.back()
    -
    -# Refresh the current page.
    -driver.refresh()
    - # Navigate to a URL (both of the statements below are
    -# functionally equivalent).
    -driver.get('https://www.google.com')
    -driver.navigate.to('https://www.google.com')
    -
    -# Go forward one page in the browser (if you're not on the
    -# last page that was viewed).
    -driver.navigate.forward
    -
    -# Go back one page in the browser (if you're not on the
    -# first page that was viewed).
    -driver.navigate.back
    -
    -# Refresh the current page.
    -driver.navigate.refresh
    -
    - -

    Working with colours

    - -

    You will occasionally want to validate the colour of something as part of your tests; - the problem is that colour definitions on the web are not constant. - Wouldn't it be nice if there was an easy way to compare - a HEX representation of a colour with an RGB representation of a colour, - or an RGBA representation of a colour with a HSLA representation of a colour? - -

    Worry not. There's a solution: the Color class! - -

    First of all, you will need to import the class: - -

    - import org.openqa.selenium.support.Color;
    - from selenium.webdriver.support.color import Color
    - include Selenium::WebDriver::Support
    -
    - -

    You can now start creating colour objects. - Every colour object will need to be created from a string representation of your colour. - Supported colour representations are: - -

    - private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
    -private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
    -private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
    -private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
    -private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
    -private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
    -private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
    - HEX_COLOUR = Color.from_string('#2F7ED8')
    -RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
    -RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
    -RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
    -RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
    -HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
    -HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
    - HEX_COLOUR = Color.from_string('#2F7ED8')
    -RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
    -RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
    -RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
    -RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
    -HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
    -HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
    -
    - -

    The Color class also supports all of the base colour definitions - specified in http://www.w3.org/TR/css3-color/#html4. - -

    - private final Color BLACK = Color.fromString("black");
    -private final Color CHOCOLATE = Color.fromString("chocolate");
    -private final Color HOTPINK = Color.fromString("hotpink");
    - BLACK = Color.from_string('black')
    -CHOCOLATE = Color.from_string('chocolate')
    -HOTPINK = Color.from_string('hotpink')
    - BLACK = Color.from_string('black')
    -CHOCOLATE = Color.from_string('chocolate')
    -HOTPINK = Color.from_string('hotpink')
    -
    - -

    Sometimes browsers will return a colour value of "transparent" - if no colour has been set on an element. - The Color class also supports this: - -

    - private final Color TRANSPARENT = Color.fromString("transparent");
    - TRANSPARENT = Color.from_string('transparent')
    - TRANSPARENT = Color.from_string('transparent')
    -
    - -

    You can now safely query an element - to get its colour/background colour knowing that - any response will be correctly parsed - and converted into a valid Color object: - -

    - Color loginButtonColour = driver.findElement(By.id("login")).getCssValue("color");
    -Color loginButtonBackgroundColour = driver.findElement(By.id("login")).getCssValue("background-color");
    - login_button_colour = driver.find_element_by_id('login').value_of_css_property('color')
    -login_button_background_colour = driver.find_element_by_id('login').value_of_css_property('background-color');
    - login_button_colour = driver.find_element(id: 'login').css_value('color')
    -login_button_background_colour = driver.find_element(id: 'login').css_value('background-color');
    -
    - -

    You can then directly compare colour objects: - -

    - assert loginButtonBackgroundColour.equals(HOTPINK);
    - assert login_button_background_colour == HOTPINK
    - assert(login_button_background_colour == HOTPINK)
    -
    - -

    Or you can convert the colour into one of the following formats - and perform a static validation: - -

    - assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
    -assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
    -assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
    - assert login_button_background_colour.hex == '#ff69b4'
    -assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
    -assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
    - assert(login_button_background_colour.hex == '#ff69b4')
    -assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
    -assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
    -
    - -

    Colours are no longer a problem.

    - -

    Working with select elements

    - -

    Select elements can require quite a bit of boiler plate code to automate. - To reduce this and make your tests cleaner, there is a - Select class in the Selenium support package. - To use it, you will need the following import statement: - -

    - import org.openqa.selenium.support.ui.Select;
    - from selenium.webdriver.support.select import Select
    - include Selenium::WebDriver::Support
    -
    - -

    You are then able to create a Select object using a WebElement that -references a <select> element. - -

    - WebElement selectElement = driver.findElement(By.id("selectElementID"));
    -Select selectObject = new Select(selectElement);
    - select_element = driver.find_element_by_id('selectElementID')
    -select_object = Select(select_element)
    - select_element = driver.find_element(id: 'selectElementID')
    -select_object = Select(select_element)
    -
    - -

    The Select object will now give you a series of commands - that allow you to interact with a <select> element. - First of all, there are different ways of selecting an option - from the <select> element. - -

    <select>
    - <option value=value1>Bread</option>
    - <option value=value2 selected>Milk</option>
    - <option value=value3>Cheese</option>
    -</select>
    - -

    There are three ways to select the first option from the above element: - -

    - // Select an <option> based upon the <select> element's internal index
    -selectObject.selectByIndex(1);
    -
    -// Select an <option> based upon its value attribute
    -selectObject.selectByValue("value1");
    -
    -// Select an <option> based upon its text
    -selectObject.selectByVisibleText("Bread");
    - # Select an <option> based upon the <select> element's internal index
    -select_object.select_by_index(1)
    -
    -# Select an <option> based upon its value attribute
    -select_object.select_by_value('value1')
    -
    -# Select an <option> based upon its text
    -select_object.select_by_visible_text('Bread')
    - # Select an <option> based upon the <select> element's internal index
    -select_object.select_by(:index, 1)
    -
    -# Select an <option> based upon its value attribute
    -select_object.select_by(:value, 'value1')
    -
    -# Select an <option> based upon its text
    -select_object.select_by(:text, 'Bread')
    -
    - -

    You can then check which options are selected by using: - -

    - // Return a List<WebElement> of options that have been selected
    -List<WebElement> allSelectedOptions = selectObject.getAllSelectedOptions();
    -
    -// Return a WebElement referencing the first selection option found by walking down the DOM
    -WebElement firstSelectedOption = selectObject.getFirstSelectedOption();
    - # Return a list[WebElement] of options that have been selected
    -all_selected_options = select_object.all_selected_options
    -
    -# Return a WebElement referencing the first selection option found by walking down the DOM
    -first_selected_option = select_object.first_selected_option
    - # Return an Array[Element] of options that have been selected
    -all_selected_options = select_object.selected_options
    -
    -# Return a WebElement referencing the first selection option found by walking down the DOM
    -first_selected_option = select_object.first_selected_option
    -
    - -

    Or you may just be interested in what <option> elements - the <select> element contains: - -

    - // Return a List<WebElement> of options that the <select> element contains
    -List<WebElement> allAvailableOptions = selectObject.getOptions();
    - # Return a list[WebElement] of options that the <select> element contains
    -all_available_options = select_object.options
    - # Return an Array[Element] of options that the <select> element contains
    -all_available_options = select_object.options
    -
    - -

    If you want to deselect any elements, you now have four options: - -

    - // Deselect an <option> based upon the <select> element's internal index
    -selectObject.deselectByIndex(1);
    -
    -// Deselect an <option> based upon its value attribute
    -selectObject.deselectByValue("value1");
    -
    -// Deselect an <option> based upon its text
    -selectObject.deselectByVisibleText("Bread");
    -
    -// Deselect all selected <option> elements
    -selectObject.deselectAll();
    - # Deselect an <option> based upon the <select> element's internal index
    -select_object.deselect_by_index(1)
    -
    -# Deselect an <option> based upon its value attribute
    -select_object.deselect_by_value('value1')
    -
    -# Deselect an <option> based upon its text
    -select_object.deselect_by_visible_text('Bread')
    -
    -# Deselect all selected <option> elements
    -select_object.deselect_all()
    - # Deselect an <option> based upon the <select> element's internal index
    -select_object.deselect_by(:index, 1)
    -
    -# Deselect an <option> based upon its value attribute
    -select_object.deselect_by(:value, 'value1')
    -
    -# Deselect an <option> based upon its text
    -select_object.deselect_by(:text, 'Bread')
    -
    -# Deselect all selected <option> elements
    -select_object.deselect_all
    -
    - -

    Finally, some <select> elements allow you to select more than one option. - You can find out if your <select> element is one of these by using: - -

    - Boolean doesThisAllowMultipleSelections = selectObject.isMultiple();
    - does_this_allow_multiple_selections = select_object.is_multiple
    - does_this_allow_multiple_selections = select_object.multiple?
    -
    - -

    Mouse and keyboard actions in detail

    -

    Suppose you have an arbitrary web element e:

    - -
    - WebElement e = driver.findElement(By.id("testElement"));
    - e = driver.find_element_by_id("testElement")
    -
    - -

    You can simulate mouse clicking on e if it's visible and has a height and width that are greater than 0:

    - -
    - e.click();
    - e.click()
    -
    - -

    Moreover, it's possible to mimic hovering of the cursor over e. In order to do so, you'll need the following import statement: - -

    - import org.openqa.selenium.interactions.Actions;
    - from selenium.webdriver import ActionChains
    -
    - -

    With this statement in place, you can now move over the element in question:

    - -
    - Actions actions = new Actions(driver);
    -actions.moveToElement(e);
    -actions.perform();
    - actions = ActionChains(driver)
    -actions.move_to_element(e)
    -actions.perform()
    -
    - -

    If e is an input or textarea element, the following keyboard actions can be carried out:

    - -

    1. Enter a sequence of characters in e: - -

    - e.sendKeys("Test");
    - e.send_keys("Test")
    -
    - -

    2. Delete the text that's in e (if there is any): - -

    - e.clear();
    - e.clear()
    -
    - -

    Working with web elements

    diff --git a/content/documentation/typo.html b/content/documentation/typo.html deleted file mode 100755 index 3fbf0413ad56..000000000000 --- a/content/documentation/typo.html +++ /dev/null @@ -1,44 +0,0 @@ - - -Typographical conventions - - - - - - -

    Typographical conventions

    - -

    Capitalisation of titles

    - -

    One should avoid title capitalisation, - such as A Very Fine Heading, - and instead go for A very fine heading. - Gratutious capitalisation, or title case, - often show a misunderstanding of – or a disregard for – - orthographic conventions. - We prefer what is known as sentence case, - with a single initial capital to start headers. - -

    Line length

    - -

    When editing the documentation’s source, - which is written in plain HTML, - limit your line lengths to around 72 characters. - -

    Some of us take this one step further - and use what is called - semantic linefeeds, - which is a technique whereby the HTML source lines, - which are not read by the public, - are split at ‘natural breaks’ in the prose. - In other words, sentences are split - at natural breaks between clauses. - Instead of fussing with the lines of each paragraph - so that they all end near the right margin, - linefeeds can be added anywhere - that there is a break between ideas. - -

    This can make diffs very easy to read - when collaborating through git, - but it is not something we enforce contributors to use. diff --git a/content/documentation/wd.html b/content/documentation/wd.html deleted file mode 100755 index 0699ff1e3a00..000000000000 --- a/content/documentation/wd.html +++ /dev/null @@ -1,1461 +0,0 @@ - - -WebDriver - - - - - - - -

    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 - -

    - -

    Understanding The Components

    - - -

    Building a test suite using WebDriver will require you to understand and effectively use a number of different components. As with everything in software, different people use different terms for the same idea. Below is a breakdown of how terms are used in this description. - -

    Terminology

    - - - - - -

    The Parts and Pieces

    -

    At its minimum, WebDriver talks to a browser through a driver. Communication is two way: WebDriver passes commands to the browser through the driver, and recieves information back via the same route. -
    - - -

    The driver is specific to the browser, such as ChromeDriver for Google's Chrome/Chromium, GeckoDriver for Mozilla's Firefox, etc. The driver runs on the same system as the browser. This may, or may not be, the same system where the tests themselves are executing. - -

    This simple example above is direct communication. Communication to the browser may also be remote communication through Selenium Server or RemoteWebDriver. RemoteWebDriver runs on the same system as the driver and the browser. -
    - - - -

    Remote communication can also take place using Selenium Server or Selenium Grid, both of which in turn talk to the driver on the host system -
    - - - -

    Where Frameworks Fit In

    - -

    WebDriver has one job and one job only: communicate with the browser via any of the methods above. WebDriver doesn't know a thing about testing: it doesn't know how to compare things, assert pass or fail, and it certainly doesn't know a thing about reporting or Given/When/Then grammar. - -

    This is where various frameworks come in to play. At a minimum you'll need a test framework that matches the language bindings, eg NUnit for .NET, JUnit for Java, RSpec for Ruby, etc. - -

    The test framework is responsible for running and executing your WebDriver and related steps in your tests. As such, you can think of it looking akin to the following image. - -
    - - -

    Natural language frameworks/tools such as Cucumber may exist as part of that Test Framework box in the figure above, or they may wrap the Test Framework entirely in their own implementation. - -

    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. -

    - - -

    Quick reference

    - - - - - - - - - - - - - - - - - - - - - - -
    Browser - Supported OS - Maintained by - Download - Issue Tracker -
    Chromium/Chrome - Windows
    - macOS
    - Linux -
    Google - Downloads - Issues -
    Firefox - Windows
    - macOS
    - Linux -
    Mozilla - Downloads - Issues -
    Edge - Windows 10 - Microsoft - Downloads - Issues -
    Internet Explorer - Windows - Selenium Project - Downloads - Issues -
    Safari - macOS El Capitan and newer - Apple - Built in - Issues -
    Opera - Windows
    - macOS
    - Linux -
    Opera - Downloads - Issues -
    - - -

    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: - -

    - import org.openqa.selenium.WebDriver;
    -import org.openqa.selenium.chrome.ChromeDriver;
    -
    -WebDriver driver = new ChromeDriver();
    - #Simple assignment
    -from selenium.webdriver import Chrome
    -
    -driver = Chrome()
    - #Or use the context manager
    -from selenium.webdriver import Chrome
    -
    -with Chrome() as driver:
    -    #your code inside this indent
    - using OpenQA.Selenium;
    -using OpenQA.Selenium.Chrome;
    -
    -IWebDriver driver = new ChromeDriver();
    - require "selenium-webdriver"
    -
    -driver = Selenium::WebDriver.for :chrome
    - const {Builder} = require('selenium-webdriver');
    -
    -(async function myFunction() {
    -    let driver = await new Builder().forBrowser('chrome').build();
    -    //your code inside this block
    -})();
    -
    - -

    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");
    - Chrome(executable_path='/path/to/chromedriver')
    - Selenium::WebDriver::Chrome.driver_path = "/path/to/chromedriver"
    -
    - -

    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: - -

    - import org.openqa.selenium.WebDriver;
    -import org.openqa.selenium.Firefox.FirefoxDriver;
    -
    -WebDriver driver = new FirefoxDriver();
    - #Simple assignment
    -from selenium.webdriver import Firefox
    -
    -driver = Firefox()
    - #Or use the context manager
    -from selenium.webdriver import Firefox
    -
    -with Firefox() as driver:
    -   #your code inside this indent
    - using OpenQA.Selenium;
    -using OpenQA.Selenium.Firefox;
    -
    -IWebDriver driver = new FirefoxDriver();
    - require "selenium-webdriver"
    -
    -driver = Selenium::WebDriver.for :firefox
    - const {Builder} = require('selenium-webdriver');
    -
    -(async function myFunction() {
    -   let driver = await new Builder().forBrowser('firefox').build();
    -   //your code inside this block
    -})();
    -
    - - -

    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");
    -  Firefox(executable_path='/path/to/geckodriver')
    -  Selenium::WebDriver::Firefox.driver_path = "/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. - -

    - import org.openqa.selenium.WebDriver;
    -import org.openqa.selenium.edge.EdgeDriver;
    -
    -WebDriver driver = new EdgeDriver();
    -#Simple assignment
    -from selenium.webdriver import Edge
    -
    -driver = Edge()
    -#Or use the context manager
    -from selenium.webdriver import Edge
    -
    -with Edge() as driver:
    -   #your code inside this indent
    -using OpenQA.Selenium;
    -using OpenQA.Selenium.Edge;
    -
    -IWebDriver driver = new EdgeDriver();
    -require "selenium-webdriver"
    -
    -driver = Selenium::WebDriver.for :edge
    -const {Builder} = require('selenium-webdriver');
    -
    -(async function myFunction() {
    -   let driver = await new Builder().forBrowser('MicrosoftEdge').build();
    -   //your code inside this block
    -})();
    -
    - -

    If Edge driver is not present in your path, you can set the path using the following line: - -

    -  System.setProperty("webdriver.edge.driver", "C:/path/to/MicrosoftWebDriver.exe");
    -  Edge(executable_path='/path/to/MicrosoftWebDriver.exe')
    -  Selenium::WebDriver::Edge.driver_path = "C:\path\to\MicrosoftWebDriver.exe"
    -
    - - -

    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. - -

    - import org.openqa.selenium.WebDriver;
    -import org.openqa.selenium.ie.InternetExplorerDriver;
    -
    -WebDriver driver = new InternetExplorerDriver();
    - #Simple assignment
    -from selenium.webdriver import Ie
    -
    -driver = Ie()
    - #Or use the context manager
    -from selenium.webdriver import Ie
    -
    -with Ie() as driver:
    -   #your code inside this indent
    - using OpenQA.Selenium;
    -using OpenQA.Selenium.IE;
    -
    -IWebDriver driver = new InternetExplorerDriver();
    - require "selenium-webdriver"
    -
    -driver = Selenium::WebDriver.for :internet_explorer
    - const {Builder} = require('selenium-webdriver');
    -
    -(async function myFunction() {
    -   let driver = await new Builder().forBrowser('internet explorer').build();
    -   //your code inside this block
    -})();
    -
    - -

    If Internet Explorer driver is not present in your path, you can set the path using the following line: - -

    -  System.setProperty("webdriver.ie.driver", "C:/path/to/IEDriver.exe");
    -  Ie(executable_path='/path/to/IEDriverServer.exe')
    -  Selenium::WebDriver::IE.driver_path = "C:\path\to\IEDriver.exe"
    -
    - -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: - -

    - import org.openqa.selenium.WebDriver;
    -import org.openqa.selenium.opera.OperaDriver;
    -
    -WebDriver driver = new OperaDriver();
    -#Simple assignment
    -from selenium.webdriver import Opera
    -
    -driver = Opera()
    -#Or use the context manager
    -from selenium.webdriver import Opera
    -
    -with Opera() as driver:
    -   #your code inside this indent
    -using OpenQA.Selenium;
    -using OpenQA.Selenium.Opera;
    -
    -IWebDriver 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: - -

      -
    1. Enable the Developer menu from Safari preferences -
    2. Check the Allow Remote Automation option - from with the Develop menu -
    3. 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: -

    - import org.openqa.selenium.WebDriver;
    -import org.openqa.selenium.safari.SafariDriver;
    -
    -WebDriver driver = new SafariDriver();
    -#Simple assignment
    -from selenium.webdriver import Safari
    -
    -driver = Safari()
    - #Or use the context manager
    -from selenium.webdriver import Safari
    -
    -with Safari() as driver:
    -   #your code inside this indent
    - using OpenQA.Selenium;
    -using OpenQA.Selenium.Safari;
    -
    -IWebDriver driver = new SafariDriver();
    - require "selenium-webdriver"
    -
    -driver = Selenium::WebDriver.for :safari
    - const {Builder} = require('selenium-webdriver');
    -
    -(async function myFunction() {
    -   let driver = await new Builder().forBrowser('safari').build();
    -   //your code inside this block
    -})();
    -
    - -

    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
    - -Or, if you use Bundler, add this line to your application's Gemfile: - -
    gem "selenium-webdriver"
    - -And then execute the following command in prompt: - -
    $ bundle install
    - -

    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: - -
    require "selenium-webdriver"
    -driver = Selenium::WebDriver.for :internet_explorer
    - -

    Browser Navigation

    - -

    Navigate To

    - -

    The first thing you will want to do after launching a browser is to - open your website. This can be achieved in a single line: - -

    - 
    -//Convenient
    -driver.get("https://www.seleniumhq.org");
    -
    -//Longer way
    -driver.navigate().to("https://seleniumhq.github.io/docs/");
    - 
    - driver.get("https://www.seleniumhq.org")
    - 
    -# Convenient
    -driver.get 'https://www.seleniumhq.org'
    -
    -# Longer way
    -driver.navigate.to 'https://seleniumhq.github.io/docs/'
    - 
    - driver.Navigate().GoToUrl(@"http://google.com");
    - driver.get("https://seleniumhq.github.io/docs/");
    -
    - -

    Get Current URL

    - -

    You can read the current URL from the browser's address bar - using:

    -
    - driver.getCurrentUrl();
    - driver.current_url
    - driver.current_url
    - driver.Url;
    - await driver.getCurrentUrl();
    -
    - -

    Back

    -

    Pressing the browser's back button: -

    - driver.navigate().back();
    - driver.back()
    - driver.navigate.back
    - driver.Navigate().Back();
    - driver.back();
    -
    - -

    Forward

    -

    Pressing the browser's forward button: -

    -  driver.navigate().forward();
    -  driver.forward()
    -  driver.navigate.forward
    -  driver.Navigate().Forward();
    -  driver.forward();
    - 
    - -

    Refresh

    -

    Refresh the current page: -

    -  driver.navigate().refresh();
    -  driver.refresh()
    -  driver.navigate.refresh
    -  driver.Navigate().Refresh();
    -  driver.refresh();
    - 
    - -

    Get Title

    -

    You can read the current page title from the browser:

    -
    -  driver.getTitle();
    -  driver.title
    -  driver.title
    -  driver.Title;
    -  driver.getTitle();
    - 
    - -

    Windows and tabs

    -

    WebDriver doesn't make the distinction between windows and tabs. If - your site opens a new tab or window, Selenium will let you work with it - using a window handle. Each window has a unique identifier which remains - persistent in a single session. You can get the window handle of the - current window by using:

    -
    - driver.getWindowHandle();
    - driver.current_window_handle
    - driver.CurrentWindowHandle
    - driver.window_handle
    - await driver.getWindowHandle();
    -
    -

    Switching windows or tabs

    -

    Clicking a link which opens in a - new window will visible focus the new window or tab on screen, but - WebDriver will not know which window the Operating System considers - active. To work with the new window you will need to switch to it. If - you have only two tabs or windows open, and you know which window you - start with, by the process of elimination you can loop over both windows - or tabs that WebDriver can see, and switch to the one which is not the - original.

    -
    - //Store the ID of the original window
    -String originalWindow = driver.getWindowHandle();
    -
    -//Check we don't have other windows open already
    -assert driver.getWindowHandles().size() == 1;
    -
    -//Click the link which opens in a new window
    -driver.findElement(By.linkText("new window")).click();
    -
    -//Wait for the new window or tab
    -wait.until(numberOfWindowsToBe(2));
    -
    -//Loop through until we find a new window handle
    -for (String windowHandle : driver.getWindowHandles()) {
    -    if(!originalWindow.contentEquals(windowHandle)) {
    -        driver.switchTo().window(windowHandle);
    -        break;
    -    }
    -}
    -
    -//Wait for the new tab to finish loading content
    -wait.until(titleIs("Selenium documentation"));
    - from selenium import webdriver
    -from selenium.webdriver.support.ui import WebDriverWait
    -from selenium.webdriver.support import expected_conditions as EC
    -
    -# Start the driver
    -with webdriver.Firefox() as driver:
    -    # Open URL
    -    driver.get("https://seleniumhq.github.io/docs/wd.html")
    -
    -    # Setup wait for later
    -    wait = WebDriverWait(driver, 10)
    -
    -    # Store the ID of the original window
    -    original_window = driver.current_window_handle
    -
    -    # Check we don't have other windows open already
    -    assert len(driver.window_handles) == 1
    -
    -    # Click the link which opens in a new window
    -    driver.find_element_by_link_text("new window").click()
    -
    -    # Wait for the new window or tab
    -    wait.until(EC.number_of_windows_to_be(2))
    -
    -    # Loop through until we find a new window handle
    -    for window_handle in driver.window_handles:
    -        if window_handle != original_window:
    -            driver.switch_to.window(window_handle)
    -            break
    -
    -    # Wait for the new tab to finish loading content
    -    wait.until(EC.title_is("Selenium documentation"))
    - //Store the ID of the original window
    -String originalWindow = driver.CurrentWindowHandle;
    -
    -//Check we don't have other windows open already
    -Assert.AreEqual(driver.WindowHandles.Count, 1);
    -
    -//Click the link which opens in a new window
    -driver.FindElement(By.LinkText("new window")).Click();
    -
    -//Wait for the new window or tab
    -wait.Until(wd => wd.WindowHandles.Count == 2);
    -
    -//Loop through until we find a new window handle
    -foreach(String window in driver.WindowHandles)
    -{
    -    if(originalWindow != window)
    -    {
    -        driver.SwitchTo().Window(window);
    -        break;
    -    }
    -}
    -//Wait for the new tab to finish loading content
    -wait.Until(wd => wd.Title == "Selenium documentation");
    - #Store the ID of the original window
    -original_window = driver.window_handle
    -
    -#Check we don't have other windows open already
    -assert(driver.window_handles.length == 1, 'Expected one window')
    -
    -#Click the link which opens in a new window
    -driver.find_element(link: 'new window').click
    -
    -#Wait for the new window or tab
    -wait.until { driver.window_handles.length == 2 }
    -
    -#Loop through until we find a new window handle
    -driver.window_handles.each do |handle|
    -    if handle != original_window
    -        driver.switch_to.window handle
    -        break
    -    end
    -end
    -
    -#Wait for the new tab to finish loading content
    -wait.until { driver.title == 'Selenium documentation'}
    - 
    - //Store the ID of the original window
    -const originalWindow = await driver.getWindowHandle();
    -
    -//Check we don't have other windows open already
    -assert((await driver.getAllWindowHandles()).length === 1);
    -
    -//Click the link which opens in a new window
    -await driver.findElement(By.linkText('new window')).click();
    -
    -//Wait for the new window or tab
    -await driver.wait(function() {
    -    return driver.getAllWindowHandles().then(function(windows) {
    -        return windows.length === 2;
    -    });
    -}, 10000);
    -
    -//Loop through until we find a new window handle
    -const windows = (await driver.getAllWindowHandles());
    -for (let i = 0; i < windows.length; i++) {
    -    if(windows[i]!==originalWindow) {
    -        await driver.switchTo().window(windows[i]);
    -    }
    -}
    -
    -//Wait for the new tab to finish loading content
    -await driver.wait(until.titleIs('Selenium documentation'), 10000);
    -
    - -

    Closing a window or tab

    -

    When you are finished with a window or tab and it is not the - last window or tab open in your browser, you should close it and switch - back to the window you were using previously. Assuming you followed the - code sample in the previous section you will have the previous window - handle stored in a variable. Put this together and you will get:

    -
    - //Close the tab or window
    -driver.close();
    -
    -//Switch back to the old tab or window
    -driver.switchTo().window(originalWindow);
    - #Close the tab or window
    -driver.close()
    -
    -#Switch back to the old tab or window
    -driver.switch_to.window(original_window)
    - //Close the tab or window
    -driver.Close();
    -
    -//Switch back to the old tab or window
    -driver.SwitchTo().Window(originalWindow);
    - #Close the tab or window
    -driver.close
    -
    -#Switch back to the old tab or window
    -driver.switch_to.window original_window
    - //Close the tab or window
    -await driver.close();
    -
    -//Switch back to the old tab or window
    -await driver.switchTo().window(originalWindow);
    - 
    -
    -

    Forgetting to switch back to another window handle after closing a - window will leave WebDriver executing on the now closed page, and will - trigger a No Such Window Exception. You must switch - back to a valid window handle in order to continue execution.

    - -

    Quiting the browser at the end of a session

    -

    When you are finished with the browser session you should call quit, - instead of close: -

    - driver.quit();
    - driver.quit()
    - driver.Quit();
    - driver.quit
    - await driver.quit();
    -
    -

    Quit will: -

    -

    Failure to call quit will leave extra background processes and ports - running on your machine which could cause you problems later.

    -

    Some test frameworks offer methods and annotations which you can hook - into to tear down at the end of a test.

    -
    - /**
    - * Example using JUnit
    - * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
    - */
    -@AfterAll
    -public static void tearDown() {
    -    driver.quit();
    -}
    - /*
    -    Example using Visual Studio's UnitTesting
    -    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
    -*/
    -[TestCleanup]
    -public void TearDown()
    -{
    -    driver.Quit();
    -}
    -
    -

    If not running WebDriver in a test context, you may consider using - try / finally which is offered by most languages so that an exception - will still clean up the WebDriver session.

    -
    - try {
    -    //WebDriver code here...
    -} finally {
    -    driver.quit();
    -}
    - try:
    -    #WebDriver code here...
    -finally:
    -    driver.quit()
    - try {
    -    #WebDriver code here...
    -} finally {
    -    driver.Quit();
    -}
    - begin
    -    #WebDriver code here...
    -ensure
    -    driver.quit
    -end
    - try {
    -    //WebDriver code here...
    -} finally {
    -    await driver.quit();
    -}
    -
    -

    Python's WebDriver now supports the python context manager, - which when using the with keyword can automatically quit the driver at - the end of execution.

    -
    - with webdriver.Firefox() as driver:
    -    #WebDriver code here...
    -
    -#WebDriver will automatically quit after indentation
    -
    - -

    Window Management

    -

    Screen resolution can impact how your web application renders, so - WebDriver provides mechanisms for moving and resizing the browser - window. - -

    Get Window Size

    -

    Fetches the size of the browser window in pixels. -

    - //Access each dimension individually
    -int width = driver.manage().window().getSize().getWidth();
    -int height = driver.manage().window().getSize().getHeight();
    -
    -//Or store the dimensions and query them later
    -Dimension size = driver.manage().window().getSize();
    -int width1 = size.getWidth();
    -int height1 = size.getHeight();
    - //Access each dimension individually
    -width = driver.get_window_size().get("width")
    -height = driver.get_window_size().get("height")
    -
    -//Or store the dimensions and query them later
    -size = driver.get_window_size()
    -width1 = size.get("width")
    -height1 = size.get("height")
    -
    - -

    Set Window Size

    -

    Restores the window and sets the window size. -

    - driver.manage().window().setSize(new Dimension(1024, 768));
    - driver.set_window_size(1024,768)
    -
    - -

    Get Window Position

    -

    Fetches the coordinates of the top left coordinate of the browser window. -

    - //Access each dimension individually
    -int x = driver.manage().window().getPosition().getX();
    -int y = driver.manage().window()..getPosition().getY();
    -
    -//Or store the dimensions and query them later
    -Point position = driver.manage().window().getPosition();
    -int x1 = position.getX();
    -int y1 = position.getY();
    - //Access each dimension individually
    -x = driver.get_window_position().get('x')
    -y = driver.get_window_position().get('y')
    -
    -//Or store the dimensions and query them later
    -position = driver.get_window_position()
    -x1 = position.get('x')
    -y1 = position.get('y')
    -
    - -

    Set Window Position

    -

    Moves the window to the chosen position. -

    - //Move the window to the top left of the primary monitor
    -driver.manage().window().setPosition(new Point(0,0));
    - //Move the window to the top left of the primary monitor
    -driver.set_window_position(0, 0)
    -
    - -

    Maximise Window

    -

    Enlarges the window. For most operating systems, the window will fill - the screen, without blocking the operating system's own menus and - toolbars. -

    - driver.manage().window().maximize();
    - driver.maximize_window()
    -
    - -

    Fullscreen Window

    -

    Fills the entire screen, similar to pressing F11 in most browsers. -

    - driver.manage().window().fullscreen();
    - driver.fullscreen_window()
    -
    - -

    Waits

    - -

    WebDriver can generally be said to have a blocking API. - Because it is an out-of-process library that - instructs 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!"
    -
    -driver.get("file:///race_condition.html");
    -WebElement element = driver.findElement(By.tagName("p"));
    -assertEquals(element.getText(), "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 Wait

    - -

    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 Wait

    - -

    There is a second type of wait that is distinct from - explicit wait called implicit wait. - 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 waitis - 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"));
    -  
    -  
    -driver = Firefox()
    -driver.implicitly_wait(10)
    -driver.get("http://somedomain/url_that_delays_loading")
    -my_dynamic_element = driver.find_element_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 Load Strategy

    - -

    Web Element

    - -

    Represents a DOM element. WebElements can be found by searching from the - document root using a WebDriver instance, or by searching under another - WebElement: - -

    -  
    -driver.get('http://www.google.com')
    -  .then(() =>   driver.findElement(By.tagName('form')) )
    -  .then((searchForm) => searchForm.findElement(By.name('q')) )
    -  .then((searchBox) => searchBox.sendKeys('webdriver') );
    -  
    -  
    -driver = Firefox()
    -driver.get("http://www.google.com")
    -search_form = driver.find_element_by_tag_name("form")
    -search_box = search_form.find_element_by_name("q")
    -search_box.send_keys("webdriver")
    -  
    -
    - -

    Keyboard

    - -

    Mouse

    diff --git a/content/documentation/worst.html b/content/documentation/worst.html deleted file mode 100755 index 9fc3e1ef528b..000000000000 --- a/content/documentation/worst.html +++ /dev/null @@ -1,194 +0,0 @@ - - -Worst practices - - - - - - - -

    Worst practices

    - - -

    Captchas

    - -

    CAPTCHA, short for Completely Automated Public Turing test - to tell Computers and Humans Apart, - is explicitly designed to prevent automation, so don’t try! - There are two primary strategies to get around CAPTCHA checks: - -

    - - -

    File downloads

    - -

    Whilst it is possible to start a download - by clicking a link with a browser under Selenium's control, - the API does not expose download progress, - making it less than ideal for testing downloaded files. - This is because downloading files is not considered an important aspect - of emulating user interaction with the web platform. - Instead, find the link using Selenium - (and any required cookies) - and pass it to a HTTP request library like - libcurl. - - -

    HTTP response codes

    - -

    For some browser configurations in Selenium RC, - Selenium acted as a proxy between the browser - and the site being automated. - This meant that all browser traffic passed through Selenium - could be captured or manipulated. - The captureNetworkTraffic() method - purported to capture all of the network traffic between the browser - and the site being automated, - including HTTP response codes. - -

    Selenium WebDriver is a completely different approach - to browser automation, - preferring to act more like a user - and this is represented in the way you write tests with WebDriver. - In automated functional testing, - checking the status code - is not a particularly important detail of a test's failure; - the steps that preceded it are more important. - -

    The browser will always represent the HTTP status code, - imagine for example a 404 or a 500 error page. - A simple way to “fail fast” when you encounter one of these error pages - is to check the page title or content of a reliable point - (e.g. the <h1> tag) after every page load. - If you are using the page object model, - you can include this check in your class constructor - or similar point where the page load is expected. - Occasionally, the HTTP code may even be represented - in the browser's error page - and you could use WebDriver to read this - and improve your debugging output. - -

    Checking the webpage itself is in line - with WebDriver's ideal practice - of representing and asserting upon the user’s view of the website. - -

    If you insist, an advanced solution to capturing HTTP status codes - is to replicate the behaviour of Selenium RC by using a proxy. - WebDriver API provides the ability to set a proxy for the browser, - and there are a number of proxies that will - programmatically allow you to manipulate - the contents of requests sent to and received from the web server. - Using a proxy lets you decide how you want to respond - to redirection response codes. - Additionally, not every browser - makes the response codes available to WebDriver, - so opting to use a proxy - allows you to have a solution that works for every browser. - - -

    Gmail, email, and Facebook logins

    - -

    For multiple reasons, logging into sites like Gmail and Facebook - using WebDriver is not recommended. - Aside from being against the usage terms for these sites - (where you risk having the account shut down), - it is slow and unreliable. - -

    The ideal practice is to use the APIs that email providers offer, - or in the case of Facebook the developer tools service - which exposes an API for creating test accounts, friends and so forth. - Although using an API might seem like a bit of extra hard work, - you will be paid back in speed, reliability, and stability. - The API is also unlikely to change - whereas webpages and HTML locators change often - and require you to update your test framework. - -

    Logging in to third party sites using WebDriver - at any point of your test increases the risk - of your test failing because it makes your test longer. - A general rule of thumb is that longer tests - are more fragile and unreliable. - -

    WebDriver implementations that are - W3C conformant - also annotate the navigator object - with a webdriver property - so that Denial of Service attacks can be mitigated. - - -

    Test dependency

    -

    - A common idea and misconception about automated testing is regarding a - specific test order. Your tests should be able to run in any order, - and not rely on other tests to complete in order to be successful. -

    - - -

    Performance testing

    - -

    Performance testing using Selenium and WebDriver - is generally not advised. - Not because it is incapable - but because it is not optimised for the job - and you are unlikely to get good results. - -

    It may seem ideal to performance test - in the context of the user but a suite of WebDriver tests - are subjected to many points of external and internal fragility - which are beyond your control; - for example browser startup speed, - speed of HTTP servers, - response of third party servers that host JavaScript or CSS, - and the instrumentation penalty - of the WebDriver implementation itself. - Variation at these points will cause variation in your results. - It is difficult to separate the difference - between the performance of your website - and the performance of external resources, - and it is also hard to tell what the performance penalty is - for using WebDriver in the browser, - especially if you are injecting scripts. - -

    The other potential attraction is "saving time" — - carrying out functional and performance tests at the same time. - However, functional and performance tests have opposing objectives. - To test functionality, a tester may need to be patient - and wait for loading, - but this will cloud the performance testing results and vice versa. - -

    To improve the performance of your website, - you will need to be able to analyse overall performance - independent of environment differences, - identify poor code practices, - breakdown of performance of individual resources - (i.e. CSS or JavaScript) - in order to know what to improve. - There are performance testing tools available - that can do this job already, - and which provide reporting and analysis - which can even make improvement suggestions. - -

    Example (open source) packages to use are: Jmeter ? - - -

    Link spidering

    - -

    Using WebDriver to spider through links - is not a recommended practice not because it cannot be done, - but because it’s definitely not the most ideal tool. - WebDriver needs time to start up, - and can take several seconds up to a minute - depending on how your test is written, - just to get to the page and traverse through the DOM. - -

    Instead of using WebDriver for this, - you could save a ton of time - by executing a curl command, - or using a library such as BeautifulSoup - since these methods don’t rely - on creating a browser and navigating to a page. - You are saving tonnes of time by not using WebDriver for this task. diff --git a/docs_source_files/config.toml b/docs_source_files/config.toml index 34a54befbd87..b13f2b5d7ed1 100644 --- a/docs_source_files/config.toml +++ b/docs_source_files/config.toml @@ -1,4 +1,4 @@ -baseURL = "https://seleniumhq.github.io/docs/site" +baseURL = "" languageCode = "en-US" defaultContentLanguage = "en" # Force to have /en/my-page and /fr/my-page routes, even for default language. @@ -21,8 +21,8 @@ enableGitInfo = true [params] # Change default color scheme with a variant one. Can be "red", "blue", "green". themeVariant = "selenium" - editURL = "https://github.com/SeleniumHQ/docs/edit/gh-pages/docs_source_files/content/" - ghrepo = "https://github.com/SeleniumHQ/docs/" + editURL = "https://github.com/SeleniumHQ/site/edit/master/docs_source_files/content/" + ghrepo = "https://github.com/SeleniumHQ/site/" description = "Documentation for Selenium" showVisitedLinks = true disableBreadcrumb = false @@ -37,160 +37,160 @@ home = [ "HTML", "RSS", "JSON"] title = "Documentation for Selenium" weight = 1 languageName = "English" -baseURL = "https://seleniumhq.github.io/docs/site/en" +baseURL = "/documentation/en" [[Languages.en.menu.shortcuts]] name = " GitHub repo" identifier = "ds" -url = "https://github.com/SeleniumHQ/docs" +url = "https://github.com/SeleniumHQ/site" weight = 10 [[Languages.en.menu.shortcuts]] name = " Report a bug" -url = "https://github.com/seleniumhq/docs/issues" +url = "https://github.com/seleniumhq/site/issues" weight = 11 [[Languages.en.menu.shortcuts]] -name = " Credits" -url = "front_matter/copyright_and_attributions" +name = " Credits" +url = "/front_matter/copyright_and_attributions" weight = 20 [[Languages.en.menu.shortcuts]] name = " How to contribute" -url = "contributing" +url = "/contributing" weight = 30 [Languages.es] title = "Documentación de Selenium" weight = 2 languageName = "Español" -baseURL = "https://seleniumhq.github.io/docs/site/es" +baseURL = "/documentation/es" [[Languages.es.menu.shortcuts]] name = " Repo en GitHub" identifier = "ds" -url = "https://github.com/SeleniumHQ/docs" +url = "https://github.com/SeleniumHQ/site" weight = 10 [[Languages.es.menu.shortcuts]] name = " Reportar un problema" -url = "https://github.com/seleniumhq/docs/issues" +url = "https://github.com/seleniumhq/site/issues" weight = 11 [[Languages.es.menu.shortcuts]] -name = " Créditos" -url = "front_matter/copyright_and_attributions" +name = " Créditos" +url = "/front_matter/copyright_and_attributions" weight = 20 [[Languages.es.menu.shortcuts]] name = " Cómo contribuír" -url = "contributing" +url = "/contributing" weight = 30 [Languages.nl] title = "Selenium documentatie" weight = 3 languageName = "Nederlands" -baseURL = "https://seleniumhq.github.io/docs/site/nl" +baseURL = "/documentation/nl" [[Languages.nl.menu.shortcuts]] name = " GitHub repo" identifier = "ds" -url = "https://github.com/SeleniumHQ/docs" +url = "https://github.com/SeleniumHQ/site" weight = 10 [[Languages.nl.menu.shortcuts]] name = " Meld een probleem" -url = "https://github.com/seleniumhq/docs/issues" +url = "https://github.com/seleniumhq/site/issues" weight = 11 [[Languages.nl.menu.shortcuts]] -name = " Credits" -url = "front_matter/copyright_and_attributions" +name = " Credits" +url = "/front_matter/copyright_and_attributions" weight = 20 [[Languages.nl.menu.shortcuts]] name = " Hoe bij te dragen" -url = "contributing" +url = "/contributing" weight = 30 [Languages.zh-cn] title = "Selenium 文档" weight = 4 languageName = "中文简体" -baseURL = "https://seleniumhq.github.io/docs/site/zh-cn" +baseURL = "/documentation/zh-cn" [[Languages.zh-cn.menu.shortcuts]] name = " GitHub repo" identifier = "ds" -url = "https://github.com/SeleniumHQ/docs" +url = "https://github.com/SeleniumHQ/site" weight = 10 [[Languages.zh-cn.menu.shortcuts]] name = " Report a bug" -url = "https://github.com/seleniumhq/docs/issues" +url = "https://github.com/seleniumhq/site/issues" weight = 11 [[Languages.zh-cn.menu.shortcuts]] -name = " Credits" -url = "front_matter/copyright_and_attributions" +name = " Credits" +url = "/front_matter/copyright_and_attributions" weight = 20 [[Languages.zh-cn.menu.shortcuts]] name = " How to contribute" -url = "contributing" +url = "/contributing" weight = 30 [Languages.fr] title = "Documentation Selenium" weight = 5 languageName = "Français" -baseURL = "https://seleniumhq.github.io/docs/site/fr" +baseURL = "/documentation/fr" [[Languages.fr.menu.shortcuts]] name = " Signaler un problème" -url = "https://github.com/seleniumhq/docs/issues" +url = "https://github.com/seleniumhq/site/issues" weight = 11 [[Languages.fr.menu.shortcuts]] -name = " Crédits" -url = "front_matter/copyright_and_attributions" +name = " Crédits" +url = "/front_matter/copyright_and_attributions" weight = 20 [[Languages.fr.menu.shortcuts]] name = " Comment contribuer" -url = "contributing" +url = "/contributing" weight = 30 [[Languages.fr.menu.shortcuts]] name = " GitHub repo" identifier = "ds" -url = "https://github.com/SeleniumHQ/docs" +url = "https://github.com/SeleniumHQ/site" weight = 10 [Languages.ja] title = "Seleniumドキュメント" weight = 6 languageName = "日本語" -baseURL = "https://seleniumhq.github.io/docs/site/ja" +baseURL = "/documentation/ja" [[Languages.ja.menu.shortcuts]] name = " GitHub リポ" identifier = "ds" -url = "https://github.com/SeleniumHQ/docs" +url = "https://github.com/SeleniumHQ/site" weight = 10 [[Languages.ja.menu.shortcuts]] name = " バグ報告" -url = "https://github.com/seleniumhq/docs/issues" +url = "https://github.com/seleniumhq/site/issues" weight = 11 [[Languages.ja.menu.shortcuts]] -name = " クレジット" -url = "front_matter/copyright_and_attributions" +name = " クレジット" +url = "/front_matter/copyright_and_attributions" weight = 20 [[Languages.ja.menu.shortcuts]] name = " 貢献方法" -url = "contributing" +url = "/contributing" weight = 30 diff --git a/docs_source_files/content/front_matter/copyright_and_attributions.en.md b/docs_source_files/content/front_matter/copyright_and_attributions.en.md index 61cdff53b15e..e6fb190b1016 100644 --- a/docs_source_files/content/front_matter/copyright_and_attributions.en.md +++ b/docs_source_files/content/front_matter/copyright_and_attributions.en.md @@ -23,18 +23,30 @@ to the use of the information contained herein. ### Thanks to: -#### [Documentation](//github.com/SeleniumHQ/docs/) +#### [Selenium Main Repository](//github.com/SeleniumHQ/selenium/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} -#### [Selenium Main Repo](//github.com/SeleniumHQ/selenium/) +#### [Selenium IDE](//github.com/SeleniumHQ/selenium-ide/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium-ide/contributors?per_page=100" %}} #### [Docker Selenium](//github.com/SeleniumHQ/docker-selenium/) {{% ghcontributors "https://api.github.com/repos/seleniumhq/docker-selenium/contributors?per_page=100" %}} +#### [Selenium Website & Docs](//github.com/SeleniumHQ/site/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/site/contributors?per_page=100" %}} + +#### [Previous Selenium Website](//github.com/SeleniumHQ/www.seleniumhq.org/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/www.seleniumhq.org/contributors?per_page=100" %}} + +#### [Previous Documentation Rewrite Project](//github.com/SeleniumHQ/docs/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} + ## Third-Party software used by Selenium documentation project: @@ -270,4 +282,4 @@ but you can also find it on the WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -``` \ No newline at end of file +``` diff --git a/docs_source_files/content/front_matter/copyright_and_attributions.es.md b/docs_source_files/content/front_matter/copyright_and_attributions.es.md index 68dd4da42d52..69521466cf53 100644 --- a/docs_source_files/content/front_matter/copyright_and_attributions.es.md +++ b/docs_source_files/content/front_matter/copyright_and_attributions.es.md @@ -30,18 +30,30 @@ to the use of the information contained herein. ### Thanks to: -#### [Documentation](//github.com/SeleniumHQ/docs/) +#### [Selenium Main Repository](//github.com/SeleniumHQ/selenium/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} -#### [Selenium Main Repo](//github.com/SeleniumHQ/selenium/) +#### [Selenium IDE](//github.com/SeleniumHQ/selenium-ide/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium-ide/contributors?per_page=100" %}} #### [Docker Selenium](//github.com/SeleniumHQ/docker-selenium/) {{% ghcontributors "https://api.github.com/repos/seleniumhq/docker-selenium/contributors?per_page=100" %}} +#### [Selenium Website & Docs](//github.com/SeleniumHQ/site/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/site/contributors?per_page=100" %}} + +#### [Previous Selenium Website](//github.com/SeleniumHQ/www.seleniumhq.org/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/www.seleniumhq.org/contributors?per_page=100" %}} + +#### [Previous Documentation Rewrite Project](//github.com/SeleniumHQ/docs/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} + ## Third-Party software used by Selenium documentation project: @@ -277,4 +289,4 @@ but you can also find it on the WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -``` \ No newline at end of file +``` diff --git a/docs_source_files/content/front_matter/copyright_and_attributions.fr.md b/docs_source_files/content/front_matter/copyright_and_attributions.fr.md index 9a05a787e340..eced25be35d4 100644 --- a/docs_source_files/content/front_matter/copyright_and_attributions.fr.md +++ b/docs_source_files/content/front_matter/copyright_and_attributions.fr.md @@ -29,18 +29,30 @@ to the use of the information contained herein. ### Thanks to: -#### [Documentation](//github.com/SeleniumHQ/docs/) +#### [Selenium Main Repository](//github.com/SeleniumHQ/selenium/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} -#### [Selenium Main Repo](//github.com/SeleniumHQ/selenium/) +#### [Selenium IDE](//github.com/SeleniumHQ/selenium-ide/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium-ide/contributors?per_page=100" %}} #### [Docker Selenium](//github.com/SeleniumHQ/docker-selenium/) {{% ghcontributors "https://api.github.com/repos/seleniumhq/docker-selenium/contributors?per_page=100" %}} +#### [Selenium Website & Docs](//github.com/SeleniumHQ/site/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/site/contributors?per_page=100" %}} + +#### [Previous Selenium Website](//github.com/SeleniumHQ/www.seleniumhq.org/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/www.seleniumhq.org/contributors?per_page=100" %}} + +#### [Previous Documentation Rewrite Project](//github.com/SeleniumHQ/docs/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} + ## Third-Party software used by Selenium documentation project: @@ -276,4 +288,4 @@ but you can also find it on the WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -``` \ No newline at end of file +``` diff --git a/docs_source_files/content/front_matter/copyright_and_attributions.ja.md b/docs_source_files/content/front_matter/copyright_and_attributions.ja.md index 46eec24bbb95..72ee080e85b7 100644 --- a/docs_source_files/content/front_matter/copyright_and_attributions.ja.md +++ b/docs_source_files/content/front_matter/copyright_and_attributions.ja.md @@ -28,18 +28,30 @@ to the use of the information contained herein. ### Thanks to: -#### [Documentation](//github.com/SeleniumHQ/docs/) +#### [Selenium Main Repository](//github.com/SeleniumHQ/selenium/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} -#### [Selenium Main Repo](//github.com/SeleniumHQ/selenium/) +#### [Selenium IDE](//github.com/SeleniumHQ/selenium-ide/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium-ide/contributors?per_page=100" %}} #### [Docker Selenium](//github.com/SeleniumHQ/docker-selenium/) {{% ghcontributors "https://api.github.com/repos/seleniumhq/docker-selenium/contributors?per_page=100" %}} +#### [Selenium Website & Docs](//github.com/SeleniumHQ/site/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/site/contributors?per_page=100" %}} + +#### [Previous Selenium Website](//github.com/SeleniumHQ/www.seleniumhq.org/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/www.seleniumhq.org/contributors?per_page=100" %}} + +#### [Previous Documentation Rewrite Project](//github.com/SeleniumHQ/docs/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} + ## Third-Party software used by Selenium documentation project: diff --git a/docs_source_files/content/front_matter/copyright_and_attributions.nl.md b/docs_source_files/content/front_matter/copyright_and_attributions.nl.md index 2737b41cd208..b3d9c9bb7445 100644 --- a/docs_source_files/content/front_matter/copyright_and_attributions.nl.md +++ b/docs_source_files/content/front_matter/copyright_and_attributions.nl.md @@ -35,18 +35,30 @@ to the use of the information contained herein. ### Thanks to: -#### [Documentation](//github.com/SeleniumHQ/docs/) +#### [Selenium Main Repository](//github.com/SeleniumHQ/selenium/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} -#### [Selenium Main Repo](//github.com/SeleniumHQ/selenium/) +#### [Selenium IDE](//github.com/SeleniumHQ/selenium-ide/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium-ide/contributors?per_page=100" %}} #### [Docker Selenium](//github.com/SeleniumHQ/docker-selenium/) {{% ghcontributors "https://api.github.com/repos/seleniumhq/docker-selenium/contributors?per_page=100" %}} +#### [Selenium Website & Docs](//github.com/SeleniumHQ/site/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/site/contributors?per_page=100" %}} + +#### [Previous Selenium Website](//github.com/SeleniumHQ/www.seleniumhq.org/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/www.seleniumhq.org/contributors?per_page=100" %}} + +#### [Previous Documentation Rewrite Project](//github.com/SeleniumHQ/docs/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} + ## Third-Party software used by Selenium documentation project: diff --git a/docs_source_files/content/front_matter/copyright_and_attributions.zh-cn.md b/docs_source_files/content/front_matter/copyright_and_attributions.zh-cn.md index 7ccaa9be75db..9d11a4eef161 100644 --- a/docs_source_files/content/front_matter/copyright_and_attributions.zh-cn.md +++ b/docs_source_files/content/front_matter/copyright_and_attributions.zh-cn.md @@ -27,18 +27,30 @@ to the use of the information contained herein. ### Thanks to: -#### [Documentation](//github.com/SeleniumHQ/docs/) +#### [Selenium Main Repository](//github.com/SeleniumHQ/selenium/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} -#### [Selenium Main Repo](//github.com/SeleniumHQ/selenium/) +#### [Selenium IDE](//github.com/SeleniumHQ/selenium-ide/) -{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium/contributors?per_page=100" %}} +{{% ghcontributors "https://api.github.com/repos/seleniumhq/selenium-ide/contributors?per_page=100" %}} #### [Docker Selenium](//github.com/SeleniumHQ/docker-selenium/) {{% ghcontributors "https://api.github.com/repos/seleniumhq/docker-selenium/contributors?per_page=100" %}} +#### [Selenium Website & Docs](//github.com/SeleniumHQ/site/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/site/contributors?per_page=100" %}} + +#### [Previous Selenium Website](//github.com/SeleniumHQ/www.seleniumhq.org/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/www.seleniumhq.org/contributors?per_page=100" %}} + +#### [Previous Documentation Rewrite Project](//github.com/SeleniumHQ/docs/) + +{{% ghcontributors "https://api.github.com/repos/seleniumhq/docs/contributors?per_page=100" %}} + ## Third-Party software used by Selenium documentation project: | Software | Version | License | diff --git a/docs_source_files/layouts/partials/logo.html b/docs_source_files/layouts/partials/logo.html index c3559a118b1d..53a61ab3cfb7 100644 --- a/docs_source_files/layouts/partials/logo.html +++ b/docs_source_files/layouts/partials/logo.html @@ -1,4 +1,4 @@ -

    W3C WebDriver specification - that lets you write interchangeable code for all major web browsers. - -

    This project is made possible by volunteer contributors - who have put in thousands of hours of their own time, - and made the source code freely available - for anyone to use, enjoy, and improve. - -

    Selenium brings together browser vendors, engineers, and enthusiasts - to further an open discussion around automation of the web platform. - The project organises an annual conference - to teach and nurture the community. - -

    At the core of Selenium is WebDriver, - an interface to write instruction sets - that can be run interchangeably in many browsers. - Here is one of the simplest instructions you can make: - - -

    - import org.openqa.selenium.By;
    -import org.openqa.selenium.Keys;
    -import org.openqa.selenium.WebDriver;
    -import org.openqa.selenium.WebElement;
    -import org.openqa.selenium.firefox.FirefoxDriver;
    -import org.openqa.selenium.support.ui.WebDriverWait;
    -
    -import static org.openqa.selenium.support.ui.ExpectedConditions.presenceOfElementLocated;
    -
    -public class HelloSelenium {
    -
    -    public static void main(String[] args) {
    -        WebDriver driver = new FirefoxDriver();
    -        WebDriverWait wait = new WebDriverWait(driver, 10);
    -        try {
    -            driver.get("https://google.com/ncr");
    -            driver.findElement(By.name("q")).sendKeys("cheese" + Keys.ENTER);
    -            WebElement firstResult = wait.until(presenceOfElementLocated(By.cssSelector("h3>a")));
    -            System.out.println(firstResult.getText());
    -        } finally {
    -            driver.quit();
    -        }
    -    }
    -}
    - from selenium import webdriver
    -from selenium.webdriver.common.by import By
    -from selenium.webdriver.common.keys import Keys
    -from selenium.webdriver.support.ui import WebDriverWait
    -from selenium.webdriver.support.expected_conditions import presence_of_element_located
    -
    -#This example requires Selenium WebDriver 3.13 or newer
    -with webdriver.Firefox() as driver:
    -    wait = WebDriverWait(driver, 10)
    -    driver.get("https://google.com/ncr")
    -    driver.find_element_by_name("q").send_keys("cheese" + Keys.RETURN)
    -    first_result = wait.until(presence_of_element_located((By.CSS_SELECTOR, "h3>a")))
    -    print(first_result.text)
    - using System;
    -using Microsoft.VisualStudio.TestTools.UnitTesting;
    -using OpenQA.Selenium;
    -using OpenQA.Selenium.Firefox;
    -using OpenQA.Selenium.Support.UI;
    -
    -namespace Selenium.Docs
    -{
    -    [TestClass]
    -    public class HelloSelenium
    -    {
    -        private static IWebDriver driver;
    -
    -        [TestMethod]
    -        public void Example()
    -        {
    -            driver = new FirefoxDriver();
    -            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    -            driver.Navigate().GoToUrl("http://www.google.com/ncr");
    -            driver.FindElement(By.Name("q")).SendKeys("cheese" + Keys.Return);
    -            IWebElement firstResult = wait.Until(wd => wd.FindElement(By.CssSelector("h3>a")));
    -            Console.WriteLine(firstResult.Text);
    -        }
    -
    -        [TestCleanup]
    -        public void TearDown()
    -        {
    -            driver.Quit();
    -        }
    -    }
    -}
    - require 'selenium-webdriver'
    -
    -driver = Selenium::WebDriver.for :firefox
    -wait = Selenium::WebDriver::Wait.new(timeout: 10)
    -
    -begin
    -  driver.get 'https://google.com/ncr'
    -  driver.find_element(name: 'q').send_keys 'cheese', :return
    -  first_result = wait.until { driver.find_element(css: 'h3>a') }
    -  puts first_result.text
    -ensure
    -  driver.quit
    -end
    - const {Builder, By, Key, until} = require('selenium-webdriver');
    -
    -(async function example() {
    -    let driver = await new Builder().forBrowser('firefox').build();
    -    try {
    -        await driver.get('https://www.google.com/ncr');
    -        await driver.findElement(By.name('q')).sendKeys('cheese', Key.RETURN);
    -        let firstResult = await driver.wait(until.elementLocated(By.css('h3>a')),10000);
    -        console.log(await firstResult.getText());
    -    } finally {
    -        await driver.quit();
    -    }
    -})();
    - -

    See the Quick Tour - for a full explanation - of what goes on behind the scenes when you run this code. - You should continue on to the narrative documentation - to understand how you can install and - successfully use Selenium as a test automation tool, - and scaling simple tests like this to run - in large, distributed environments on multiple browsers, - on several different operating systems. - - -

    Getting started

    - -

    If you are new to Selenium, - we have a few resources that can help you - get up to speed right away. - -

    -
    - - -

    Narrative documentation

    - -

    Narrative documentation in chapter form - explaining how to use Selenium in detail, from bottom up. - -

    -
    - - -

    Front matter

    - -
    -
    + + + + + + + Page Redirection - Selenium Docs + + + +If you are not redirected automatically, follow this +link to the Selenium Docs. + +