This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

Troubleshooting Assistance

How to solve WebDriver problems.

It is not always obvious the root cause of errors in Selenium.

  1. The most common Selenium-related error is a result of poor synchronization. Read about Waiting Strategies. If you aren’t sure if it is a synchronization strategy you can try temporarily hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

  2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple browsers.

  3. If you have questions about how to do things, check out the Support options for ways get assistance.

  4. If you think you’ve found a problem with Selenium code, go ahead and file a Bug Report on GitHub.

1 - Understanding Common Errors

How to solve various problems in your Selenium code.

The W3C WebDriver specification defines the errors a driver can return. Each language binding turns them into its own exception (or error) class, and the names are not always the same. Kotlin uses the Java classes, the Ruby classes are in Selenium::WebDriver::Error, and the JavaScript classes are in the selenium-webdriver/lib/error module.

W3C errorJavaPythonCSharpRubyJavaScript
detached shadow rootDetachedShadowRootExceptionDetachedShadowRootExceptionDetachedShadowRootExceptionDetachedShadowRootErrorDetachedShadowRootError
element click interceptedElementClickInterceptedExceptionElementClickInterceptedExceptionElementClickInterceptedExceptionElementClickInterceptedErrorElementClickInterceptedError
element not interactableElementNotInteractableExceptionElementNotInteractableExceptionElementNotInteractableExceptionElementNotInteractableErrorElementNotInteractableError
insecure certificateInsecureCertificateExceptionInsecureCertificateExceptionInsecureCertificateExceptionInsecureCertificateErrorInsecureCertificateError
invalid argumentInvalidArgumentExceptionInvalidArgumentExceptionWebDriverArgumentExceptionInvalidArgumentErrorInvalidArgumentError
invalid cookie domainInvalidCookieDomainExceptionInvalidCookieDomainExceptionInvalidCookieDomainExceptionInvalidCookieDomainErrorInvalidCookieDomainError
invalid element stateInvalidElementStateExceptionInvalidElementStateExceptionInvalidElementStateExceptionInvalidElementStateErrorInvalidElementStateError
invalid selectorInvalidSelectorExceptionInvalidSelectorExceptionInvalidSelectorExceptionInvalidSelectorErrorInvalidSelectorError
invalid session idNoSuchSessionExceptionInvalidSessionIdExceptionWebDriverExceptionInvalidSessionIdErrorNoSuchSessionError
javascript errorJavascriptExceptionJavascriptExceptionJavaScriptExceptionJavascriptErrorJavascriptError
move target out of boundsMoveTargetOutOfBoundsExceptionMoveTargetOutOfBoundsExceptionMoveTargetOutOfBoundsExceptionMoveTargetOutOfBoundsErrorMoveTargetOutOfBoundsError
no such alertNoAlertPresentExceptionNoAlertPresentExceptionNoAlertPresentExceptionNoSuchAlertErrorNoSuchAlertError
no such cookieNoSuchCookieExceptionNoSuchCookieExceptionNoSuchCookieExceptionNoSuchCookieErrorNoSuchCookieError
no such elementNoSuchElementExceptionNoSuchElementExceptionNoSuchElementExceptionNoSuchElementErrorNoSuchElementError
no such frameNoSuchFrameExceptionNoSuchFrameExceptionNoSuchFrameExceptionNoSuchFrameErrorNoSuchFrameError
no such shadow rootNoSuchShadowRootExceptionNoSuchShadowRootExceptionNoSuchShadowRootExceptionNoSuchShadowRootErrorNoSuchShadowRootError
no such windowNoSuchWindowExceptionNoSuchWindowExceptionNoSuchWindowExceptionNoSuchWindowErrorNoSuchWindowError
script timeoutScriptTimeoutExceptionTimeoutExceptionWebDriverTimeoutExceptionScriptTimeoutErrorScriptTimeoutError
session not createdSessionNotCreatedExceptionSessionNotCreatedExceptionInvalidOperationExceptionSessionNotCreatedErrorSessionNotCreatedError
stale element referenceStaleElementReferenceExceptionStaleElementReferenceExceptionStaleElementReferenceExceptionStaleElementReferenceErrorStaleElementReferenceError
timeoutTimeoutExceptionTimeoutExceptionWebDriverTimeoutExceptionTimeoutErrorTimeoutError
unable to capture screenScreenshotExceptionScreenshotExceptionInvalidOperationExceptionUnableToCaptureScreenErrorUnableToCaptureScreenError
unable to set cookieUnableToSetCookieExceptionUnableToSetCookieExceptionUnableToSetCookieExceptionUnableToSetCookieErrorUnableToSetCookieError
unexpected alert openUnhandledAlertExceptionUnexpectedAlertPresentExceptionUnhandledAlertExceptionUnexpectedAlertOpenErrorUnexpectedAlertOpenError
unknown commandUnsupportedCommandExceptionWebDriverExceptionNotImplementedExceptionUnknownCommandErrorUnknownCommandError
unknown errorWebDriverExceptionWebDriverExceptionUnknownErrorExceptionUnknownErrorWebDriverError
unknown methodUnsupportedCommandExceptionWebDriverExceptionUnknownMethodExceptionUnknownMethodErrorUnknownMethodError
unsupported operationUnsupportedCommandExceptionWebDriverExceptionUnsupportedOperationExceptionUnsupportedOperationErrorUnsupportedOperationError

All of these classes inherit from the base exception of their binding (WebDriverException in Java, Python and CSharp, WebDriverError in Ruby and JavaScript), except for the CSharp InvalidOperationException and NotImplementedException, which are .NET system exceptions.

InvalidSelectorException

CSS and XPath Selectors are sometimes difficult to get correct.

Likely Cause

  • The CSS or XPath selector you are trying to use has invalid characters or an invalid query.
  • You may have placed an XPATH value as a parameter to a CSS selector, or vice versa.
  • You may have used a CSS or XPATH selector as a parameter to an ID selector.

Possible Solutions

Run your selector through a validator service:

Or use a browser extension to get a known good value:

NoSuchElementException

The element can not be found at the exact moment you attempted to locate it.

Likely Cause

  • You are looking for the element in the wrong place (perhaps a previous action was unsuccessful).
  • You are looking for the element at the wrong time (the element has not shown up in the DOM, yet)
  • The locator has changed since you wrote the code

Possible Solutions

  • Make sure you are on the page you expect to be on, and that previous actions in your code completed correctly
  • Make sure you are using a proper Waiting Strategy
  • Use an interactive Selenium Wait Code Generator to create accurate explicit wait snippets for multiple supported languages including Java, Python, C#, JavaScript, and Ruby.
  • Update the locator with the browser’s devtools console or use a browser extension like:

StaleElementReferenceException

An element goes stale when it was previously located, but can not be currently accessed. Elements do not get relocated automatically; the driver creates a reference ID for the element and has a particular place it expects to find it in the DOM. If it can not find the element in the current DOM, any action using that element will result in this exception.

Likely Cause

This can happen when:

  • You have refreshed the page, or the DOM of the page has dynamically changed.
  • You have navigated to a different page.
  • You have switched to another window or into or out of a frame or iframe.

Possible Solutions

The DOM has changed

When the page is refreshed or items on the page have moved around, there is still an element with the desired locator on the page, it is just no longer accessible by the element object being used, and the element must be relocated before it can be used again. This is often done in one of two ways:

  • Always relocate the element every time you go to use it. The likelihood of the element going stale in the microseconds between locating and using the element is small, though possible. The downside is that this is not the most efficient approach, especially when running on a remote grid.

  • Wrap the Web Element with another object that stores the locator, and caches the located Selenium element. When taking actions with this wrapped object, you can attempt to use the cached object if previously located, and if it is stale, exception can be caught, the element relocated with the stored locator, and the method re-tried. This is more efficient, but it can cause problems if the locator you’re using references a different element (and not the one you want) after the page has changed.

The Context has changed

Element objects are stored for a given context, so if you move to a different context — like a different window or a different frame or iframe — the element reference will still be valid, but will be temporarily inaccessible. In this scenario, it won’t help to relocate the element, because it doesn’t exist in the current context. To fix this, you need to make sure to switch back to the correct context before using the element.

The Page has changed

This scenario is when you haven’t just changed contexts, you have navigated to another page and have destroyed the context in which the element was located. You can’t just relocate it from the current context, and you can’t switch back to an active context where it is valid. If this is the reason for your error, you must both navigate back to the correct location and relocate it.

ElementClickInterceptedException

This exception occurs when Selenium tries to click an element, but the click would instead be received by a different element. Before Selenium will click an element, it checks if the element is visible, unobscured by any other elements, and enabled - if the element is obscured, it will raise this exception.

Likely Cause

UI Elements Overlapping

Elements on the UI are typically placed next to each other, but occasionally elements may overlap. For example, a navbar always staying at the top of your window as you scroll a page. If that navbar happens to be covering an element we are trying to click, Selenium might believe it to be visible and enabled, but when you try to click it will throw this exception. Pop-ups and Modals are also common offenders here.

Animations

Elements with animations have the potential to cause this exception as well - it is recommended to wait for animations to cease before attempting to click an element.

Possible Solutions

Use Explicit Waits

Explicit Waits will likely be your best friend in these instances. A great way is to use ExpectedCondition.ToBeClickable() with WebDriverWait to wait until the right moment.

Scroll the Element into View

In instances where the element is out of view, but Selenium still registers the element as visible (e.g. navbars overlapping a section at the top of your screen), you can use the WebDriver.executeScript() method to execute a javascript function to scroll (e.g. WebDriver.executeScript('window.scrollBy(0,-250)')) or you can utilize the Actions class with Actions.moveToElement(element).

InvalidSessionIdException

Sometimes the session you’re trying to access is different than what’s currently available

Likely Cause

This usually occurs when the session has been deleted (e.g. driver.quit()) or if the session has changed, like when the last tab/browser has closed (e.g. driver.close())

Possible Solutions

Check your script for instances of driver.close() and driver.quit(), and any other possible causes of closed tabs/browsers. It could be that you are locating an element before you should/can.

SessionNotCreatedException

This exception occurs when the WebDriver is unable to create a new session for the browser. This often happens due to version mismatches, system-level restrictions, or configuration issues.

Likely Cause

  • The browser version and WebDriver version are incompatible (e.g., ChromeDriver v113 with Chrome v115).
  • macOS privacy settings may block the WebDriver from running.
  • The WebDriver binary is missing, inaccessible, or lacks the necessary execution permissions (e.g., on Linux/macOS, the driver file may not be executable).

Possible Solutions

  • Ensure the WebDriver version matches the browser version. For Chrome, check the browser version at chrome://settings/help and download the matching driver from ChromeDriver Downloads.
  • On macOS, go to System Settings > Privacy & Security, and allow the driver to run if blocked.
  • Verify the driver binary is executable (chmod +x /path/to/driver on Linux/macOS).

ElementNotInteractableException

This exception occurs when Selenium tries to interact with an element that is not interactable in its current state.

Likely Cause

  1. Unsupported Operation: Performing an action, like sendKeys, on an element that doesn’t support it (e.g., <form> or <label>).
  2. Multiple Elements Matching Locator: The locator targets a non-interactable element, such as a <td> tag, instead of the intended <input> field.
  3. Hidden Elements: The element is present in the DOM but not visible on the page due to CSS, the hidden attribute, or being outside the visible viewport.

Possible Solutions

  1. Use actions appropriate for the element type (e.g., use sendKeys with <input> fields only).
  2. Ensure locators uniquely identify the intended element to avoid incorrect matches.
  3. Check if the element is visible on the page before interacting with it. Use scrolling to bring the element into view, if required.
  4. Use explicit waits to ensure the element is interactable before performing actions.

DetachedShadowRootException

A shadow root was found earlier, but it is no longer attached to the DOM. This is the shadow root equivalent of a StaleElementReferenceException.

Likely Cause

  • The page was refreshed or the user navigated to another page after the shadow root was found.
  • The shadow host element was removed from the DOM or replaced by a new element.

Possible Solutions

  • Find the shadow host element again and get its shadow root before using it.
  • See Evaluating the Shadow DOM for how to work with shadow roots.

InsecureCertificateException

Navigating to a page made the browser show a certificate warning, which is usually the result of an expired, self-signed or otherwise invalid TLS certificate.

Likely Cause

  • The site under test uses a self-signed certificate, which is common in test environments.
  • The certificate has expired or does not match the domain name.

Possible Solutions

  • If you trust the site, set the acceptInsecureCerts capability to true in the browser options.
  • Otherwise, fix the certificate of the site under test.

InvalidArgumentException

The arguments passed to a command are invalid or malformed.

Likely Cause

  • A value of the wrong type was passed to a command, e.g., a number where a string is expected.
  • A URL passed to get is not a valid absolute URL (e.g., it is missing https://).
  • A browser option or capability has a value the driver does not accept.
  • The file passed for a file upload does not exist. In a remote session, the file must exist on the machine where the browser runs, unless a Local File Detector is used, which sends the file from the machine running the test.

Possible Solutions

  • Read the error message, which usually says which argument is invalid.
  • Check the values you pass to the failing command, and the capabilities used to start the session.

InvalidCookieDomainException

A cookie was added for a domain that is different from the domain of the current page.

Likely Cause

  • You are adding a cookie before navigating to the site it belongs to (e.g., on about:blank or the browser start page).
  • The cookie’s domain value does not match the current page.
  • The current page does not accept cookies, e.g., a file:// or data: URL.

Possible Solutions

InvalidElementStateException

A command cannot be completed because the element is in a state that does not allow it.

Likely Cause

  • You are trying to clear an element that is not editable, such as a disabled or read-only input.
  • You are trying to change an element that is disabled.

Possible Solutions

  • Check that the element is enabled and editable before interacting with it.
  • Wait for the application to enable the element, using an explicit wait.

JavascriptException

The JavaScript code passed to the driver failed while running in the browser.

Likely Cause

  • The script has a syntax error or throws an error.
  • The script uses a variable or element that does not exist on the current page.
  • The script uses arguments that were not passed to it.

Possible Solutions

  • Read the error message, which includes the JavaScript error raised by the browser.
  • Run the script in the browser’s developer tools console to debug it.
  • Prefer Selenium commands over JavaScript when there is a command that does the same thing.

MoveTargetOutOfBoundsException

An Actions command tried to move the pointer to a point outside of the browser’s viewport.

Likely Cause

  • The offset used in a move command puts the pointer outside of the viewport.
  • The target element is outside of the viewport and cannot be scrolled into it.
  • The browser window is too small for the page.

Possible Solutions

  • Check the offsets used with the mouse and pen actions. Depending on the origin of the move, offsets are relative to the viewport, to the current pointer position, or to the center of an element.
  • Scroll the element into view first, e.g., with the wheel actions.
  • Use a bigger browser window.

NoAlertPresentException

A command tried to use an alert, confirm or prompt dialog, but no dialog was open.

Likely Cause

  • The dialog has not opened yet.
  • The dialog was already closed, either by your code or by the unhandledPromptBehavior of the session.
  • The page opens a dialog that is built with HTML (a modal), which is not a JavaScript alert.

Possible Solutions

NoSuchCookieException

No cookie with the given name exists for the current page.

Likely Cause

  • The cookie has not been set yet, it has expired, or it was deleted.
  • The cookie belongs to a different domain or path than the current page.

Possible Solutions

  • Check that you are on a page of the domain and path the cookie belongs to.
  • Get all cookies to check which ones are available.
  • See Working with cookies.

NoSuchFrameException

A command to switch to a frame or iframe could not find it.

Likely Cause

  • The frame has not been loaded yet.
  • The locator, index, name or ID used to switch to the frame is wrong.
  • The frame is inside another frame, and the driver is not switched to the parent frame.

Possible Solutions

NoSuchShadowRootException

An element does not have a shadow root.

Likely Cause

  • The element is not a shadow host.
  • The shadow root has not been attached yet.

Possible Solutions

  • Check in the browser’s developer tools that you are getting the shadow root of the shadow host element.
  • Wait for the shadow root to be attached before getting it.
  • See Evaluating the Shadow DOM.

NoSuchWindowException

The window or tab the command was sent to does not exist.

Likely Cause

  • The window or tab the driver is switched to was closed, by your code (e.g., driver.close()) or by the page.
  • The window handle used to switch to a window is wrong.

Possible Solutions

  • After closing a window or tab, switch to another open window before sending more commands.
  • Get the current window handles to check which windows are available.
  • See Working with windows and tabs.

ScreenshotException

The browser could not take a screenshot.

Likely Cause

  • The page or element is too big for the browser to capture, e.g., a full page screenshot of a very long page.

Possible Solutions

  • Take a screenshot of the viewport or of a smaller element instead.

ScriptTimeoutException

A script passed to the driver did not finish before the script timeout expired.

Likely Cause

  • An asynchronous script did not call the callback function it receives as its last argument.
  • The script takes longer than the script timeout, which is 30 seconds by default.

Possible Solutions

  • Check that asynchronous scripts call the callback function in every code path.
  • Increase the script timeout if the script needs more time.

TimeoutException

An operation did not finish before its timeout expired.

Likely Cause

  • An explicit wait timed out because its condition was not met in time. This is the most common cause, and the exception is raised by the binding, not the driver.
  • A page took longer to load than the page load timeout, which is 300 seconds by default.

Possible Solutions

  • Check that the condition you are waiting for can be met, e.g., that the locator is correct.
  • Increase the timeout of the wait, if the application needs more time.
  • Use a different page load strategy if you do not need to wait for the whole page to load.

UnableToSetCookieException

The browser could not set a cookie.

Likely Cause

  • The cookie has invalid values, e.g., a malformed name, or an expiry date in the past.
  • The cookie is set as secure, and the current page does not use HTTPS.

Possible Solutions

  • Check the values of the cookie.
  • Use HTTPS pages when setting secure cookies.
  • See Working with cookies.

UnhandledAlertException

An alert, confirm or prompt dialog is open, and it blocks the command.

Likely Cause

  • The page opened a dialog that your code did not expect or did not close.

Possible Solutions

UnsupportedCommandException

The driver does not support the command. Java uses this exception for the unknown command, unknown method and unsupported operation W3C errors. See the table at the top of this page for the class each binding uses for each of these errors.

Likely Cause

  • The command is not part of the W3C WebDriver specification, or the driver has not implemented it yet.
  • The command only works with some browsers (e.g., a browser specific command used with another browser).
  • The driver is older than the Selenium version being used.

Possible Solutions

  • Check that the browser and driver support the command.
  • Update the browser and driver. Selenium Manager gets the driver that matches your browser automatically.

WebDriverException

An unknown error happened in the driver while processing the command. It is the base exception of most bindings, so it is also raised for errors that do not have a more specific class.

Likely Cause

  • The browser crashed or was closed while the command was running.
  • The driver could not connect to the browser.
  • An error in the browser or driver that is not described by any other error.

Possible Solutions

  • Read the full error message, which usually has more details.
  • Update the browser and driver to the latest versions.
  • Enable logging to get more information.

ElementNotVisibleException

This exception is thrown when the element you are trying to interact with is present in the DOM, but is not visible.

Likely Cause

This can occur in several situations:

  • Another element is blocking your intended element
  • The element is disabled/invisible to the user

Possible Solutions

This issue cannot always be resolved on the user’s end, however when it can it is usually solved by the following: using an explicit wait, or interacting with the page in such a way to make the element visible (scrolling, clicking a button, etc.)

1.1 - Unable to Locate Driver Error

Troubleshooting missing path to driver executable.

Historically, this is the most common error beginning Selenium users get when trying to run code for the first time:

The path to the driver executable must be set by the webdriver.chrome.driver system property; for more information, see https://chromedriver.chromium.org/. The latest version can be downloaded from https://chromedriver.chromium.org/downloads
The executable chromedriver needs to be available in the path.
The file geckodriver does not exist. The driver can be downloaded at https://github.com/mozilla/geckodriver/releases"
Unable to locate the chromedriver executable;

Likely cause

Through WebDriver, Selenium supports all major browsers. In order to drive the requested browser, Selenium needs to send commands to it via an executable driver. This error means the necessary driver could not be found by any of the means Selenium attempts to use.

Possible solutions

There are several ways to ensure Selenium gets the driver it needs.

Use the latest version of Selenium

As of Selenium 4.6, Selenium downloads the correct driver for you. You shouldn’t need to do anything. If you are using the latest version of Selenium and you are getting an error, please turn on logging and file a bug report with that information.

If you want to read more information about how Selenium manages driver downloads for you, you can read about the Selenium Manager.

Use the PATH environment variable

This option first requires manually downloading the driver.

This is a flexible option to change location of drivers without having to update your code, and will work on multiple machines without requiring that each machine put the drivers in the same place.

You can either place the drivers in a directory that is already listed in PATH, or you can place them in a directory and add it to PATH.

To see what directories are already on PATH, open a Terminal and execute:

echo $PATH

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile

You can test if it has been added correctly by checking the version of the driver:

chromedriver --version

To see what directories are already on PATH, open a Terminal and execute:

echo $PATH

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv

You can test if it has been added correctly by checking the version of the driver:

chromedriver --version

To see what directories are already on PATH, open a Command Prompt and execute:

echo %PATH%

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

setx PATH "%PATH%;C:\WebDriver\bin"

You can test if it has been added correctly by checking the version of the driver:

chromedriver.exe --version

Specify the location of the driver

If you cannot upgrade to the latest version of Selenium, you do not want Selenium to download drivers for you, and you can’t figure out the environment variables, you can specify the location of the driver in the Service object.

You first need to download the desired driver, then create an instance of the applicable Service class and set the path.

Specifying the location in the code itself has the advantage of not needing to figure out Environment Variables on your system, but has the drawback of making the code less flexible.

Driver management libraries

Before Selenium managed drivers itself, other projects were created to do so for you.

If you can’t use Selenium Manager because you are using an older version of Selenium (please upgrade), or need an advanced feature not yet implemented by Selenium Manager, you might try one of these tools to keep your drivers automatically updated:

Download the driver

NavegadorOS SuportadoMantido porDownloadRastreador de Problemas
Chromium/ChromeWindows/macOS/LinuxGoogleDownloadsProblemas
FirefoxWindows/macOS/LinuxMozillaDownloadsProblemas
EdgeWindows/macOS/LinuxMicrosoftDownloadsProblemas
Internet ExplorerWindowsProjeto SeleniumDownloadsProblemas
SafarimacOS High Sierra e superioresAppleIntegrado no SistemaProblemas

Nota: O Opera driver já não inclui as funcionalidades mais recentes do Selenium e oficialmente deixou de ser suportado.

2 - Logging Selenium commands

Getting information about Selenium execution.

Turning on logging is a valuable way to get extra information that might help you determine why you might be having a problem.

Getting a logger

Java logs are typically created per class. You can work with the default logger to work with all loggers. To filter out specific classes, see Filtering

Get the root logger:

    public void logging() throws IOException {

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the Selenium Logger project

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

    logger = logging.getLogger('selenium')

You must also create and add a log handler (StreamHandler, FileHandler, etc).

To save logs to a file, you can do this:

log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)

To display logs in the console, you can do this:

handler = logging.StreamHandler()
logger.addHandler(handler)

.NET logger is managed with a static class, so all access to logging is managed simply by referencing Log from the OpenQA.Selenium.Internal.Logging namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting $DEBUG = true.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default Logger class. This implementation provides some interesting additional features. Obtain the logger directly from the #loggerclass method on the Selenium::WebDriver module:

    logger = Selenium::WebDriver.logger
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')

Logger level

Logger level helps to filter out logs based on their severity.

Java has 7 logger levels: SEVERE, WARNING, INFO, CONFIG, FINE, FINER, and FINEST. The default is INFO.

You have to change both the level of the logger and the level of the handlers on the root logger:

        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);

Python has 6 logger levels: CRITICAL, ERROR, WARNING, INFO, DEBUG, and NOTSET. The default is WARNING

To change the level of the logger:

    logger.setLevel(logging.DEBUG)

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, -s to prevent PyTest from capturing the console. Second, -p no:logging, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

pytest -s -p no:logging

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

logging.basicConfig(level=logging.WARN)

.NET has 6 logger levels: Error, Warn, Info, Debug, Trace and None. The default level is Warn.

To change the level of the logger:

        {

Ruby logger has 5 logger levels: :debug, :info, :warn, :error, :fatal. As of Selenium v4.9.1, The default is :info.

To change the level of the logger:

    logger.level = :debug

JavaScript has 9 logger levels: OFF, SEVERE, WARNING, INFO, DEBUG, FINE, FINER, FINEST, ALL. The default is OFF.

To change the level of the logger:

logger.setLevel(logging.Level.INFO)

Actionable items

Things are logged as warnings if they are something the user needs to take action on. This is often used for deprecations. For various reasons, Selenium project does not follow standard Semantic Versioning practices. Our policy is to mark things as deprecated for 3 releases and then remove them, so deprecations may be logged as warnings.

Java logs actionable content at logger level WARN

Example:

May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning

Python logs actionable content at logger level — WARNING Details about deprecations are logged at this level.

Example:

WARNING  selenium:test_logging.py:23 this is a warning

.NET logs actionable content at logger level Warn.

Example:

11:04:40.986 WARN LoggingTest: this is a warning

Ruby logs actionable content at logger level — :warn. Details about deprecations are logged at this level.

For example:

2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 

Because these items can get annoying, we’ve provided an easy way to turn them off, see filtering section below.

Useful information

This is the default level where Selenium logs things that users should be aware of but do not need to take actions on. This might reference a new method or direct users to more information about something

Java logs useful information at logger level INFO

Example:

May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information

Python logs useful information at logger level — INFO

Example:

INFO     selenium:test_logging.py:22 this is useful information

.NET logs useful information at logger level Info.

Example:

11:04:40.986 INFO LoggingTest: this is useful information

Ruby logs useful information at logger level — :info.

Example:

2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 

Logs useful information at level: INFO

Debugging Details

The debug log level is used for information that may be needed for diagnosing issues and troubleshooting problems.

Java logs most debug content at logger level FINE

Example:

May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information

Python logs debugging details at logger level — DEBUG

Example:

DEBUG    selenium:test_logging.py:24 this is detailed debug information

.NET logs most debug content at logger level Debug.

Example:

11:04:40.986 DEBUG LoggingTest: this is detailed debug information

Ruby only provides one level for debugging, so all details are at logger level — :debug.

Example:

2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 

Logs debugging details at level: FINER and FINEST

Logger output

Logs can be displayed in the console or stored in a file. Different languages have different defaults.

By default all logs are sent to System.err. To direct output to a file, you need to add a handler:


      Path output = artifactsDir().resolve("selenium.xml");

By default all logs are sent to sys.stderr. To direct output somewhere else, you need to add a handler with either a StreamHandler or a FileHandler:

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

By default all logs are sent to System.Console.Error output. To direct output somewhere else, you need to add a handler with a FileLogHandler:

By default, logs are sent to the console in stdout.
To store the logs in a file:

    logger.output = file_name

JavaScript does not currently support sending output to a file.

To send logs to console output:

logging.installConsoleHandler()

Logger filtering

Java logging is managed on a per class level, so instead of using the root logger (Logger.getLogger("")), set the level you want to use on a per-class basis:

        logger.addHandler(handler);
Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:


            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using :deprecations.

These methods accept one or more symbols or an array of symbols:

    logger.ignore(:jwp_caps, :logger_info)

or

    logger.allow(%i[selenium_manager example_id])

3 - Como atualizar para Selenium 4

Interessado no Selenium 4? Veja este guia para realizar o upgrade para a ultima versão!

Atualizar para o Selenium 4 deve ser um processo sem dificuldades se você estiver usando uma das linguagens oficialmente suportadas (Ruby, JavaScript, C#, Python, and Java). Pode haver alguns casos em que alguns problemas podem acontecer, este guia irá ajudar você a resolvê-los. Vamos passar as etapas para atualizar as dependências do seu projeto e entender as depreciações e também as mudanças trazidas pela versão atualizada.

Estas são as etapas que seguiremos para atualizar para o Selenium 4:

  • Preparando nosso código de teste
  • Atualizando as dependências
  • Possíveis erros e mensagens de suspensão de uso

Nota: enquanto as versões do Selenium 3.x estavam sendo desenvolvidas, foi implementado o suporte padrão para W3C WebDriver. Este novo protocolo e o legado JSON Wire Protocol foram suportados. Através da versão 3.11, o código do Selenium passou a ser compátivel com o nível 1 da especificação W3C. A compatibilidade do código W3C na ultima versão do Selenium 3 irá funcionar como esperado na versão 4.

Preparando nosso código de teste

Selenium 4 remove suporte para protocolos legados e usa o W3C Webdriver por padrão. Para a maioria das coisas, essa implementação não irá afetar usuários finais. As maiores exeções são Capabilities e a classe Actions.

Recursos

Se os recursos de teste não forem estruturados para serem compatíveis com W3C, pode fazer com que uma sessão não seja iniciada. Aqui está a lista de recursos padrão do W3C WebDriver:

  • browserName
  • browserVersion (replaces version)
  • platformName (replaces platform)
  • acceptInsecureCerts
  • pageLoadStrategy
  • proxy
  • timeouts
  • unhandledPromptBehavior

Uma lista atualizada de recursos padrão pode ser encontrada aqui: W3C WebDriver.

Qualquer recurso que não esteja incluido na lista acima, precisa ser incluido um prefixo de fornecedor. Isso se aplica aos recursos específicos do navegador, bem como aos recursos específicos do fornecedor da nuvem. Por exemplo, se o seu fornecedor de nuvem usa os recursos build e name para seus testes, você precisa envolvê-los em um bloco cloud: options (verifique com seu fornecedor de nuvem o prefixo apropriado).

Antes

Move Code

DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)

Depois

Move Code

FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)

Utilitário para encontrar elemento (s) no Java

O utilitário para localizar elementos no Java (interfaces FindsBy) foram removidos visto que se destinavam apenas a uso interno. Os exemplos de código a seguir explicam isso melhor.

Encontrando um único elemento com findElement*

Antes
driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
Depois
driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));

Encontrando multiplos elementos com findElements*

Antes
driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
Depois
driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));

Atualizando as dependências

Verifique as subseções abaixo para isntalar o Selenium 4 e atualizar as dependências do seu projeto

Java

O processo de atualização do Selenium depende de qual ferramenta de compilação está sendo usada. Vamos mostrar as mais comuns para Java, como Maven e Gradle. A versão minínma do Java ainda é 8.

Maven

Antes
<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
Depois
<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
Após realizar a mudança, você pode executar mvn clean compile no mesmo diretório, onde o arquivo pom.xml está.

Gradle

Antes
plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
Depois
plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}

Após realizar a mudança, você pode executar ./gradlew clean build no mesmo diretório onde o arquivo build.gradleestá.

Para verifica todas as versões do Java, você pode ir até MVNRepository.

C#

O local para obter atualizações para Selenium 4 em C# é NuGet Dentro do pacaote Selenium.WebDriver você pode seguir as instruções para atualizar para ultima versão. Dentro do Visual Studio, através do NuGet Package Manager você pode executar:

PM> Install-Package Selenium.WebDriver -Version 4.4.0

Python

A mudança mais importante para usar o Python é a versão minima requerida. Para Selenium 4 a versão miníma requerida será Python3.7 ou superior. Mais detalhes podem ser encontrados aqui:Python Package Index. Para atualizar através da linha de comando, você pode executar:

pip install selenium==4.4.3

Ruby

Detalhes para atualizar para o Selenium 4 podem ser vistos aqui: selenium-webdriver gem in RubyGems Para instalar a ultima versão, você pode executar:

gem install selenium-webdriver

Para adicioná-lo ao seu Gemfile:

gem 'selenium-webdriver', '~> 4.4.0'

JavaScript

O pacote selenium-webdriver pode ser encontrado pelo Node package manager, npmjs. Selenium 4 pode ser encontrado aqui. Para instalar, você pode executar:

npm install selenium-webdriver

Ou, atualize o seu package.json e execute npm install:

{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}

Possíveis erros e mensagens de descontinuação

Aqui temos um conjunto de exemplos de código que o ajudarão a superar as mensagens de descontinuação, que você pode encontrar após atualizar para o Selenium 4.

Java

Waits e Timeout

Os parametros que eram esperados de ser recebidos em um Timeout trocaram de (long time, TimeUnit unit) para o (Duration duration).

Antes
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
Depois
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
As esperas(waits) também esperam parâmetros diferentes agora. O WebDriverWait agora espera uma Duration em vez de um tempo limite long em segundos e milissegundos. Os métodos utilitários withTimeout e pollingEvery do FluentWait passaram do (long time, TimeUnit unit) para o (Duration duration).

Antes
new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
Depois
new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);

A fusão de recursos não estã mais alterando o objeto de invocação

Antes era possível fundir um conjunto diferente de recursos em outro counjunto, e isso alterava o objeto de chamada. Agora, o resultado da operação de fusão precisa ser atribuído.

Antes
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

//Como resultado, o objeto `options` estava sendo modificado.
Depois
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// O resultado da chamada `merge`  precisa ser atribuído a um objeto.

Firefox Legacy

Antes do GeckoDriver existir, o projeto Selenium tinha uma implementação de driver para automatizar o Firefox(versão<48). Entretanto, esta implementação não é mais necessária, pois não funciona nas versões mais recentes do Firefox. Para evitar graves problemas ao atualizar para o Selenium 4, a opção setLegacy será mostrada como obsoleta. A recomendação é parar de utilizar a implementação antiga e depender apenas do GeckoDriver. O código a seguir mostrará a linha setLegacy obsoleta após atualizar.

FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);

BrowserType

A interface BrowserType existe há um bom tempo, más ela está ficando obsoleta a favor da nova interface Browser.

Antes
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
Depois
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);

C#

AddAdditionalCapability está descontinuada

Em vez dela, AddAdditionalOption é recomendada. Aqui está um exemplo mostrando isso:

Antes
var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
Depois
var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);

Python

executable_path foi descontinuada, por favor, passe um Service object

No Selenium 4, você precisara definir o executable_path a partir de um objeto Service para evitar avisos de depreciação. (Ou não defina o caminho e, em vez disso, certifique-se de que o driver que você precisa esteja no System PATH.)

Antes
from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
Depois
from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)

Resumo

Passamos pelas principais mudanças a serem levadas em consideração ao atualizar para o Selenium 4. Cobrimos os diferentes aspectos a serem cobertos quando o código de teste é preparado para a atualização, incluindo sugestões sobre como evitar possíveis problemas que podem aparecer ao usar a nova versão do Selenium. Para finalizar, também abordamos um conjunto de possíveis problemas com os quais você pode se deparar depois da atualização e compartilhamos possíveis correções para esses problemas.

Este tópico foi originalmente postado no site https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4