diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 6959f26dc..000000000 --- a/.flake8 +++ /dev/null @@ -1,4 +0,0 @@ -[flake8] -exclude = - __pycache__, -ignore = E501 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..f7d2b9c6a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.approved.txt text eol=lf \ No newline at end of file diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 93b6c0bbe..4045e3ba0 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -9,10 +9,10 @@ jobs: continue-on-error: true strategy: matrix: - python-version: [3.9.23, 3.13.5, 3.14.0-rc.3] # pypy-3.9 - # python-version: [{earliest: 3.9}, {latest: 3.13.0}] # pypy-3.9 - rf-version: [6.1.1, 7.3.2] - selenium-version: [4.28.1, 4.29.0, 4.30.0, 4.31.0, 4.32.0, 4.33.0, 4.34.2] + python-version: [3.10.16, 3.13.5, 3.14.4, pypy-3.10] + # python-version: [{earliest: 3.10}, {latest: 3.14.0-rc.3}, {pypy: pypy-3.10}] + rf-version: [6.1.1, 7.4.2] + selenium-version: [4.29.0, 4.30.0, 4.31.0, 4.32.0, 4.33.0, 4.34.2, 4.43.0] browser: [chrome] # firefox, chrome, headlesschrome, edge steps: @@ -44,12 +44,12 @@ jobs: export DISPLAY=:99.0 Xvfb -ac :99 -screen 0 1280x1024x16 > /dev/null 2>&1 & - name: Install dependencies - if: matrix.python-version != 'pypy-3.7' + if: matrix.python-version != 'pypy-3.10' run: | python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Install dependencies for pypy - if: matrix.python-version == 'pypy-3.9' + if: matrix.python-version == 'pypy-3.10' run: | python -m pip install --upgrade pip pip install -r requirements.txt @@ -68,7 +68,7 @@ jobs: echo "WEBDRIVERPATH=$($SELENIUM_MANAGER_EXE --browser chrome --debug | awk '/INFO[[:space:]]Driver path:/ {print $NF;exit}')" >> "$GITHUB_ENV" echo "$WEBDRIVERPATH" - name: Generate stub file for ${{ matrix.python-version }} - if: matrix.python-version != 'pypy-3.9' + if: matrix.python-version != 'pypy-3.10' run: | invoke gen-stub @@ -84,12 +84,12 @@ jobs: # xvfb-run --auto-servernum python atest/run.py --zip ${{ matrix.browser }} - name: Run tests with latest python and latest robot framework - if: matrix.python-version == '3.13.0' && matrix.rf-version == '7.2.2' + if: matrix.python-version == '3.14.4' && matrix.rf-version == '7.4.1' run: | xvfb-run --auto-servernum python atest/run.py --zip ${{ matrix.browser }} # - name: Run tests with Selenium Grid - # if: matrix.python-version == '3.11' && matrix.rf-version == '3.2.2' && matrix.python-version != 'pypy-3.9' + # if: matrix.python-version == '3.11' && matrix.rf-version == '3.2.2' && matrix.python-version != 'pypy-3.10' # run: | # wget --no-verbose --output-document=./selenium-server-standalone.jar http://selenium-release.storage.googleapis.com/3.141/selenium-server-standalone-3.141.59.jar # sudo chmod u+x ./selenium-server-standalone.jar diff --git a/.github/workflows/Select.yml b/.github/workflows/Select.yml index dcb89c7e4..1bdb7c02e 100644 --- a/.github/workflows/Select.yml +++ b/.github/workflows/Select.yml @@ -10,33 +10,37 @@ jobs: matrix: config: - description: latest - python-version: 3.13.10 - rf-version: 7.4.1 - selenium-version: 4.39.0 + python-version: 3.14.4 + rf-version: 7.4.2 + selenium-version: 4.44.0 browser: chrome - description: previous python-version: 3.12.12 rf-version: 7.3.2 - selenium-version: 4.38.0 + selenium-version: 4.40.0 browser: chrome - description: older_rf_version python-version: 3.11.14 rf-version: 6.1.1 selenium-version: 4.37.0 browser: chrome - + - description: latest_firefox + python-version: 3.14.4 + rf-version: 7.4.1 + selenium-version: 4.39.0 + browser: firefox steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: Configuration Description run: | echo "${{ matrix.config.description }} configuration" echo "Testing with RF v${{ matrix.config.rf-version }}, Selenium v${{ matrix.config.selenium-version}}, Python v${{ matrix.config.python-version }} under ${{ matrix.config.browser }}" - name: Set up Python ${{ matrix.config.python-version }} - uses: actions/setup-python@v5 + uses: actions/setup-python@v6 with: python-version: ${{ matrix.config.python-version }} - name: Setup ${{ matrix.config.browser }} browser - uses: browser-actions/setup-chrome@v1 + uses: browser-actions/setup-chrome@v2 with: chrome-version: latest install-dependencies: true @@ -71,9 +75,45 @@ jobs: run: | xvfb-run --auto-servernum python atest/run.py --zip ${{ matrix.config.browser }} - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v7 if: failure() with: - name: sl_$${{ matrix.config.python-version }}_$${{ matrix.config.rf-version }}_$${{ matrix.config.selenium-version }}_$${{ matrix.config.browser }} + name: sl_${{ matrix.config.python-version }}_${{ matrix.config.rf-version }}_${{ matrix.config.selenium-version }}_${{ matrix.config.browser }} path: atest/zip_results - overwrite: true \ No newline at end of file + overwrite: true + ruff: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: "3.14.4" + + - name: Install dev dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements-dev.txt + + - name: Ruff format check + id: format + continue-on-error: true + run: | + python -m invoke formatter --check + + - name: Ruff lint + id: lint + continue-on-error: true + run: | + python -m invoke lint + + - name: Fail if any Ruff step failed + if: always() + run: | + echo "format outcome: ${{ steps.format.outcome }}" + echo "lint outcome: ${{ steps.lint.outcome }}" + if [ "${{ steps.format.outcome }}" != "success" ] || [ "${{ steps.lint.outcome }}" != "success" ]; then + exit 1 + fi \ No newline at end of file diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index ffb9d6ff8..677200817 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -118,21 +118,23 @@ needed in internal code. When docstrings are added, they should follow `PEP-257`_. See `Documentation`_ section below for more details about documentation syntax, generating docs, etc. -The code should be formatted with `Black`_ and errors found by `flake8`_ -should be fixed. Black and flake8 can be run by using -command:: +The code should be formatted and linted with `Ruff`_. See Development commands below for more details. - inv lint +Development commands +~~~~~~~~~~~~~~~~~~~~ -By default flake8 ignores line length error E501, but it does not ignore -warning W503. In practice Black formats list access like this:: +Use `invoke`_ tasks for common local checks and test runs:: - list[1 : 2] + inv formatter --check # Check formatting with Ruff + inv formatter # Format source files with Ruff + inv lint # Run Ruff lint checks + inv lint --fix # Apply safe Ruff lint fixes + inv utest # Run unit tests + inv atest # Run acceptance tests (headlesschrome) -But flake8 will display an warning about it. This should be manually -fixed to look like:: - - list[1:2] +Run these before opening a pull request so local results are close to CI. +Use the project virtual environment and pinned dependencies from +``requirements-dev.txt`` for consistent results across local runs and CI. Documentation ------------- @@ -160,7 +162,7 @@ individual keywords. Keyword documentation can be easily created using `invoke`_ task:: - inv keyword_documentation + inv kw-docs Resulting docs should be verified before the code is committed. @@ -245,5 +247,4 @@ the same code as your changes. In that case you should .. _utest/README.rst: https://github.com/robotframework/SeleniumLibrary/blob/master/utest/README.rst .. _sync your fork: https://help.github.com/articles/syncing-a-fork/ .. _resolve conflicts: https://help.github.com/articles/resolving-a-merge-conflict-from-the-command-line -.. _Black: https://github.com/psf/black -.. _flake8: https://github.com/PyCQA/flake8 \ No newline at end of file +.. _Ruff: https://github.com/astral-sh/ruff \ No newline at end of file diff --git a/README.rst b/README.rst index 1f4346024..2ec34f134 100644 --- a/README.rst +++ b/README.rst @@ -10,7 +10,7 @@ SeleniumLibrary_ is a web testing library for `Robot Framework`_ that utilizes the Selenium_ tool internally. The project is hosted on GitHub_ and downloads can be found from PyPI_. -SeleniumLibrary currently works with Selenium 4. It supports Python 3.8 through 3.13. +SeleniumLibrary currently works with Selenium 4. It supports Python 3.10 through 3.13. In addition to the normal Python_ interpreter, it works also with PyPy_. diff --git a/atest/acceptance/1-plugin/OpenBrowserExample.py b/atest/acceptance/1-plugin/OpenBrowserExample.py index 2cb006f24..ab04db3bf 100644 --- a/atest/acceptance/1-plugin/OpenBrowserExample.py +++ b/atest/acceptance/1-plugin/OpenBrowserExample.py @@ -121,7 +121,12 @@ def create_driver( ) def create_seleniumwire( - self, desired_capabilities, remote_url, options=None, service_log_path=None, service=None, + self, + desired_capabilities, + remote_url, + options=None, + service_log_path=None, + service=None, ): logger.info(self.extra_dictionary) return webdriver.Chrome() diff --git a/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot b/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot index 5e9a07e6d..d4877f042 100644 --- a/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot +++ b/atest/acceptance/2-event_firing_webdriver/event_firing_webdriver.robot @@ -10,7 +10,7 @@ ${event_firing_or_none} ${NONE} *** Test Cases *** Open Browser To Start Page - [Tags] NoGrid + [Tags] NoGrid SKIP_ON_WINDOWS [Documentation] ... LOG 1:30 DEBUG Wrapping driver to event_firing_webdriver. ... LOG 1:32 INFO Got driver also from SeleniumLibrary. diff --git a/atest/acceptance/create_webdriver.robot b/atest/acceptance/create_webdriver.robot index 9f3796ddf..d87c80086 100644 --- a/atest/acceptance/create_webdriver.robot +++ b/atest/acceptance/create_webdriver.robot @@ -8,7 +8,7 @@ Create Webdriver Creates Functioning WebDriver [Documentation] ... LOG 1:1 INFO REGEXP: Creating an instance of the \\w+ WebDriver. ... LOG 1:18 DEBUG REGEXP: Created \\w+ WebDriver instance with session id (\\w|-)+. - [Tags] Known Issue Internet Explorer Known Issue Safari + [Tags] Known Issue Internet Explorer Known Issue Safari SKIP_ON_WINDOWS [Setup] Set Driver Variables Create Webdriver ${DRIVER_NAME} kwargs=${KWARGS} Go To ${FRONT_PAGE} diff --git a/atest/acceptance/entry_point.robot b/atest/acceptance/entry_point.robot index a92c3740a..631d1a553 100644 --- a/atest/acceptance/entry_point.robot +++ b/atest/acceptance/entry_point.robot @@ -7,7 +7,7 @@ Entry Point Version ${process} = Run Process ... python -m SeleniumLibrary.entry --version ... shell=True - ... cwd=${EXECDIR}/src + ... cwd=${EXECDIR}${/}src Log ${process.stdout} Log ${process.stderr} Should Be Equal As Integers ${process.rc} 0 @@ -17,18 +17,18 @@ Entry Point Version Entry Point Translation ${process} = Run Process - ... python -m SeleniumLibrary.entry translation ${OUTPUT_DIR}/translation.json + ... python -m SeleniumLibrary.entry translation ${OUTPUT_DIR}${/}translation.json ... shell=True - ... cwd=${EXECDIR}/src + ... cwd=${EXECDIR}${/}src Log ${process.stdout} Log ${process.stderr} Should Be Equal As Integers ${process.rc} 0 Should Be Empty ${process.stderr} - Should Be Equal ${process.stdout} Translation file created in ${OUTPUT_DIR}/translation.json + Should Be Equal ${process.stdout} Translation file created in ${OUTPUT_DIR}${/}translation.json ${process} = Run Process - ... python -m SeleniumLibrary.entry translation --compare ${OUTPUT_DIR}/translation.json + ... python -m SeleniumLibrary.entry translation --compare ${OUTPUT_DIR}${/}translation.json ... shell=True - ... cwd=${EXECDIR}/src + ... cwd=${EXECDIR}${/}src Log ${process.stdout} Log ${process.stderr} Should Be Equal As Integers ${process.rc} 0 diff --git a/atest/acceptance/keywords/draganddropframe.robot b/atest/acceptance/keywords/draganddropframe.robot new file mode 100644 index 000000000..089915b96 --- /dev/null +++ b/atest/acceptance/keywords/draganddropframe.robot @@ -0,0 +1,81 @@ +*** Settings *** +Documentation Tests for the custom Drag And Drop Across Frames keyword +... in cross-frame drag-and-drop scenarios. +Resource ../resource.robot +Test Setup Go To Page "frames/draganddrop.html" + +*** Test Cases *** +Drag And Drop Across Frames Works From Default Content + [Tags] Known Issue Firefox + [Documentation] Verifies drag-and-drop from default content to a target inside an iframe. + Wait Until Page Contains Element id=defaultSource 10s + Drag And Drop Across Frames id=defaultSource id=target id=targetFrame + Select Frame id=targetFrame + Element Should Contain id=target Dropped Successfully! + Unselect Frame + +Drag And Drop Across Frames Works From Source Frame + [Tags] Known Issue Firefox + [Documentation] Verifies drag-and-drop from a source iframe to a target iframe. + Wait Until Page Contains Element id=sourceFrame 10s + Select Frame id=sourceFrame + Wait Until Page Contains Element id=frameSource 10s + Unselect Frame + Drag And Drop Across Frames id=frameSource id=target id=targetFrame id=sourceFrame + Select Frame id=targetFrame + Element Should Contain id=target Dropped Successfully! + Unselect Frame + +Drag And Drop Across Frames Returns To Default Content + [Documentation] Verifies that the keyword returns to default content after execution. + Wait Until Page Contains Element id=defaultSource 10s + Drag And Drop Across Frames id=defaultSource id=target id=targetFrame + Page Should Not Contain Element id=target + +Drag And Drop Across Frames Hides Default Source Element + [Tags] Known Issue Firefox + [Documentation] Verifies that the default source element becomes hidden after a successful drop. + Wait Until Page Contains Element id=defaultSource 10s + Drag And Drop Across Frames id=defaultSource id=target id=targetFrame + Element Should Not Be Visible id=defaultSource + +Drag And Drop Across Frames Hides Frame Source Element + [Tags] Known Issue Firefox + [Documentation] Verifies that the frame source element becomes hidden after a successful drop. + Wait Until Page Contains Element id=sourceFrame 10s + Drag And Drop Across Frames id=frameSource id=target id=targetFrame id=sourceFrame + Select Frame id=sourceFrame + Element Should Not Be Visible id=frameSource + Unselect Frame + +Drag And Drop Across Frames Fails With Invalid Target Frame + [Documentation] Verifies that the keyword fails when the target frame locator is invalid. + Wait Until Page Contains Element id=defaultSource 10s + Run Keyword And Expect Error + ... Element with locator 'id=missingFrame' not found. + ... Drag And Drop Across Frames + ... id=defaultSource id=target id=missingFrame + +Drag And Drop Across Frames Fails With Invalid Target + [Documentation] Verifies that the keyword fails when the target element is not found inside the target iframe. + Wait Until Page Contains Element id=defaultSource 10s + Run Keyword And Expect Error + ... Element with locator 'id=missingTarget' not found. + ... Drag And Drop Across Frames + ... id=defaultSource id=missingTarget id=targetFrame + +Drag And Drop Across Frames Fails With Invalid Source Frame + [Documentation] Verifies that the keyword fails when the source frame locator is invalid. + Wait Until Page Contains Element id=defaultSource 10s + Run Keyword And Expect Error + ... Element with locator 'id=missingSourceFrame' not found. + ... Drag And Drop Across Frames + ... id=frameSource id=target id=targetFrame id=missingSourceFrame + +Drag And Drop Across Frames Fails With Invalid Source + [Documentation] Verifies that the keyword fails when the source element is not found. + Wait Until Page Contains Element id=defaultSource 10s + Run Keyword And Expect Error + ... Element with locator 'id=missingSource' not found. + ... Drag And Drop Across Frames + ... id=missingSource id=target id=targetFrame \ No newline at end of file diff --git a/atest/acceptance/keywords/mouse.robot b/atest/acceptance/keywords/mouse.robot index 5aff5c109..734eb2d01 100644 --- a/atest/acceptance/keywords/mouse.robot +++ b/atest/acceptance/keywords/mouse.robot @@ -15,7 +15,7 @@ Mouse Over ... Mouse Over not_there Mouse Over Error - [Tags] Known Issue Safari + [Tags] Known Issue Safari Known Issue Firefox Mouse Over el_for_mouseover Sleep 0.1secs Textfield Value Should Be el_for_mouseover mouseover el_for_mouseover diff --git a/atest/acceptance/keywords/page_load_timeout.robot b/atest/acceptance/keywords/page_load_timeout.robot index 100bfe2c7..d701f1c0c 100644 --- a/atest/acceptance/keywords/page_load_timeout.robot +++ b/atest/acceptance/keywords/page_load_timeout.robot @@ -6,6 +6,7 @@ Test Teardown Close Browser And Reset Page Load Timeout *** Test Cases *** Should Open Browser With Default Page Load Timeout + [Tags] SKIP_ON_WINDOWS [Documentation] Verify that 'Open Browser' changes the page load timeout. ... LOG 1.1.1:26 DEBUG REGEXP: POST http://localhost:\\d{2,5}/session/[a-f0-9-]+/timeouts {['\\\"]pageLoad['\\\"]: 300000} ... LOG 1.1.1:28 DEBUG STARTS: Remote response: status=200 diff --git a/atest/acceptance/keywords/textfields.robot b/atest/acceptance/keywords/textfields.robot index 6c3a41a3e..b957b1f97 100644 --- a/atest/acceptance/keywords/textfields.robot +++ b/atest/acceptance/keywords/textfields.robot @@ -77,9 +77,50 @@ Press Key Attempt Clear Element Text On Non-Editable Field Run Keyword And Expect Error * Clear Element Text can_send_email +Input Password Accepts Secret Type + [Tags] require-rf-7.4 + [Setup] Go To Page "forms/login.html" + Set Environment Variable TEST_PASSWORD s3cret-pass + VAR ${pw: Secret} %{TEST_PASSWORD} + Input Text username_field my_username + Input Password password_field ${pw} + ${value}= Get Value password_field + Should Be Equal ${value} s3cret-pass + +Input Text Accepts Secret Type + [Tags] require-rf-7.4 + [Setup] Go To Page "forms/login.html" + Set Environment Variable TEST_USERNAME my_username + VAR ${user: Secret} %{TEST_USERNAME} + Input Text username_field ${user} + ${value}= Get Value username_field + Should Be Equal ${value} my_username + +Input Password With Plain String Still Works + [Setup] Go To Page "forms/login.html" + [Documentation] Backwards compatibility — plain str must still be accepted. + Input Text username_field my_username + Input Password password_field plain-pass + ${value}= Get Value password_field + Should Be Equal ${value} plain-pass + +Input Password Does Not Log Secret Value + [Tags] require-rf-7.4 NoGrid + [Setup] Go To Page "forms/login.html" + [Documentation] + ... LOG 3:1 INFO Typing password into text field 'password_field'. + Set Environment Variable TEST_PASSWORD must-not-leak + VAR ${pw: Secret} %{TEST_PASSWORD} + Input Password password_field ${pw} + *** Keywords *** Open Browser To Start Page Disabling Chrome Leaked Password Detection [Arguments] ${alias}=${None} - Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} - ... options=add_experimental_option("prefs", {"profile.password_manager_leak_detection": False}) alias=${alias} \ No newline at end of file + ${browser}= Evaluate "${BROWSER}".replace(" ", "").lower() + IF "${browser}" in ["chrome", "googlechrome", "gc", "headlesschrome"] + Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} + ... options=add_experimental_option("prefs", {"profile.password_manager_leak_detection": False}) alias=${alias} + ELSE + Open Browser ${FRONT PAGE} ${BROWSER} remote_url=${REMOTE_URL} alias=${alias} + END diff --git a/atest/acceptance/multiple_browsers_options.robot b/atest/acceptance/multiple_browsers_options.robot index 2349c9195..81c9c94ae 100644 --- a/atest/acceptance/multiple_browsers_options.robot +++ b/atest/acceptance/multiple_browsers_options.robot @@ -8,6 +8,7 @@ Documentation Creating test which would work on all browser is not possible. *** Test Cases *** Chrome Browser With Selenium Options As String + [Tags] SKIP_ON_WINDOWS [Documentation] ... LOG 1:13 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].* ... LOG 1:13 DEBUG REGEXP: .*args['\\\"]: \\\[['\\\"]--disable-dev-shm-usage['\\\"].* @@ -15,6 +16,7 @@ Chrome Browser With Selenium Options As String ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument("--disable-dev-shm-usage") Chrome Browser With Selenium Options As String With Attribute As True + [Tags] SKIP_ON_WINDOWS [Documentation] ... LOG 1:13 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].* ... LOG 1:13 DEBUG REGEXP: .*args['\\\"]: \\\[['\\\"]--disable-dev-shm-usage['\\\"].* @@ -23,7 +25,7 @@ Chrome Browser With Selenium Options As String With Attribute As True ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; add_argument ( "--headless=new" ) Chrome Browser With Selenium Options With Complex Object - [Tags] NoGrid + [Tags] NoGrid SKIP_ON_WINDOWS [Documentation] ... LOG 1:13 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].* ... LOG 1:13 DEBUG REGEXP: .*['\\\"]mobileEmulation['\\\"]: {['\\\"]deviceName['\\\"]: ['\\\"]Galaxy S5['\\\"].* @@ -32,6 +34,7 @@ Chrome Browser With Selenium Options With Complex Object ... desired_capabilities=${DESIRED_CAPABILITIES} options=add_argument ( "--disable-dev-shm-usage" ) ; add_experimental_option( "mobileEmulation" , { 'deviceName' : 'Galaxy S5'}) Chrome Browser With Selenium Options Object + [Tags] SKIP_ON_WINDOWS [Documentation] ... LOG 2:13 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].* ... LOG 2:13 DEBUG REGEXP: .*args['\\\"]: \\\[['\\\"]--disable-dev-shm-usage['\\\"].* @@ -46,6 +49,7 @@ Chrome Browser With Selenium Options Invalid Method Chrome Browser With Selenium Options Argument With Semicolon + [Tags] SKIP_ON_WINDOWS [Documentation] ... LOG 1:13 DEBUG REGEXP: .*['\\\"]goog:chromeOptions['\\\"].* ... LOG 1:13 DEBUG REGEXP: .*\\\[['\\\"]has;semicolon['\\\"].* diff --git a/atest/acceptance/multiple_browsers_service.robot b/atest/acceptance/multiple_browsers_service.robot index e47c917a0..2f98d99ec 100644 --- a/atest/acceptance/multiple_browsers_service.robot +++ b/atest/acceptance/multiple_browsers_service.robot @@ -2,6 +2,7 @@ Suite Teardown Close All Browsers Library ../resources/testlibs/get_driver_path.py Resource resource.robot +Test Tags SKIP_ON_WINDOWS # Force Tags Known Issue Firefox Known Issue Safari Known Issue Internet Explorer Documentation Creating test which would work on all browser is not possible. ... These tests are for Chrome only. @@ -11,11 +12,13 @@ Chrome Browser With Chrome Service As String [Documentation] ... LOG 2:3 DEBUG STARTS: Started executable: ... LOG 2:4 DEBUG GLOB: POST*/session* + [Tags] Known Issue Firefox Known Issue Safari Known Issue Internet Explorer ${driver_path}= Get Driver Path Chrome Open Browser ${FRONT PAGE} Chrome remote_url=${REMOTE_URL} ... service=executable_path='${driver_path}' Chrome Browser With Chrome Service As String With service_args As List + [Tags] Known Issue Firefox Known Issue Safari Known Issue Internet Explorer Open Browser ${FRONT PAGE} Chrome remote_url=${REMOTE_URL} ... service=service_args=['--append-log', '--readable-timestamp']; log_output='${OUTPUT_DIR}/chromedriverlog.txt' File Should Exist ${OUTPUT_DIR}/chromedriverlog.txt @@ -23,6 +26,7 @@ Chrome Browser With Chrome Service As String With service_args As List # ... service=service_args=['--append-log', '--readable-timestamp'] Firefox Browser With Firefox Service As String + [Tags] Known Issue Chrome Known Issue Safari Known Issue Internet Explorer [Documentation] ... LOG 2:3 DEBUG STARTS: Started executable: ... LOG 2:4 DEBUG GLOB: POST*/session* diff --git a/atest/acceptance/open_and_close.robot b/atest/acceptance/open_and_close.robot index 6a0d7a75e..187edad7e 100644 --- a/atest/acceptance/open_and_close.robot +++ b/atest/acceptance/open_and_close.robot @@ -15,6 +15,7 @@ Close Browser Does Nothing When No Browser Is Opened Close Browser Browser Open With Not Well-Formed URL Should Close + [Tags] SKIP_ON_WINDOWS [Documentation] Verify after incomplete 'Open Browser' browser closes ... LOG 1.1:34 DEBUG STARTS: Opened browser with session id ... LOG 1.1:34 DEBUG REGEXP: .*but failed to open url.* diff --git a/atest/resources/html/frames/draganddrop.html b/atest/resources/html/frames/draganddrop.html new file mode 100644 index 000000000..98421dd5f --- /dev/null +++ b/atest/resources/html/frames/draganddrop.html @@ -0,0 +1,260 @@ + + + + + Drag And Drop Across Frames Test Page + + + + +

Drag And Drop Across Frames Test Page

+ +
Default Source
+ +
+ + +
+ +
+ + + + + \ No newline at end of file diff --git a/atest/resources/testlibs/get_driver_path.py b/atest/resources/testlibs/get_driver_path.py index 95c11e924..19d838e0e 100644 --- a/atest/resources/testlibs/get_driver_path.py +++ b/atest/resources/testlibs/get_driver_path.py @@ -18,6 +18,7 @@ def _import_options(self, browser): return options.Options """ + from selenium import webdriver from selenium.webdriver.common import driver_finder import importlib @@ -30,12 +31,12 @@ def get_driver_path(browser): options = importlib.import_module(f"selenium.webdriver.{browser}.options") args = inspect.signature(driver_finder.DriverFinder.__init__).parameters.keys() - if ('service' in args) and ('options' in args): + if ("service" in args) and ("options" in args): # Selenium V4.20.0 or greater finder = driver_finder.DriverFinder(service.Service(), options.Options()) return finder.get_driver_path() else: # Selenium v4.19.0 and prior finder = driver_finder.DriverFinder() - func = getattr(finder, 'get_path') + func = getattr(finder, "get_path") return finder.get_path(service.Service(), options.Options()) diff --git a/atest/run.py b/atest/run.py index d386ea7db..8ae0049bf 100755 --- a/atest/run.py +++ b/atest/run.py @@ -43,6 +43,7 @@ import zipfile from contextlib import contextmanager import os +import re import sys import argparse import textwrap @@ -181,7 +182,7 @@ def _grid_status(status=False, role="hub"): @contextmanager -def http_server(interpreter, port:int): +def http_server(interpreter, port: int): serverlog = open(os.path.join(RESULTS_DIR, "serverlog.txt"), "w") interpreter = "python" if not interpreter else interpreter process = subprocess.Popen( @@ -211,11 +212,23 @@ def execute_tests(interpreter, browser, rf_options, grid, event_firing, port): if platform.system() == "Darwin": runner.append("--exclude") runner.append("SKIP_ON_MAC") - + if platform.system() == "Windows": + runner.append("--exclude") + runner.append("SKIP_ON_WINDOWS") options.extend([opt.format(browser=browser) for opt in ROBOT_OPTIONS]) if rf_options: options += rf_options - options += ["--exclude", f"known issue {browser.replace('headless', '')}", "--exclude", "triage"] + options += [ + "--exclude", + f"known issue {browser.replace('headless', '')}", + "--exclude", + "triage", + ] + rf_ver = tuple( + int(re.match(r"\d+", x).group()) for x in robot_version.split(".")[:2] + ) + if rf_ver < (7, 4): + options.extend(["--exclude", "require-rf-7.4"]) command = runner if grid: command += [ @@ -259,7 +272,7 @@ def process_output(browser): return exit.code -def create_zip(browser = None): +def create_zip(browser=None): if os.path.exists(ZIP_DIR): shutil.rmtree(ZIP_DIR) os.mkdir(ZIP_DIR) diff --git a/docs/SeleniumLibrary-6.9.0.rst b/docs/SeleniumLibrary-6.9.0.rst new file mode 100644 index 000000000..b395ca42b --- /dev/null +++ b/docs/SeleniumLibrary-6.9.0.rst @@ -0,0 +1,199 @@ +===================== +SeleniumLibrary 6.9.0 +===================== + + +.. default-role:: code + + +SeleniumLibrary_ is a web testing library for `Robot Framework`_ that utilizes +the Selenium_ tool internally. SeleniumLibrary 6.9.0 is a new release with several +enhancements and bug fixes. A couple new keywords, for drag and drop as well as +getting css properties, have been added. Secret type support has be added. An issue +with using lists with chaining locators has been fixed. Several of the minim required +versions have been updated. More information about all the bug fixes and enhancements +can be found in these release notes. + +If you have pip_ installed, just run + +:: + + pip install --upgrade robotframework-seleniumlibrary + +to install the latest available release or use + +:: + + pip install robotframework-seleniumlibrary==6.9.0 + +to install exactly this version. Alternatively you can download the source +distribution from PyPI_ and install it manually. + +SeleniumLibrary 6.9.0 was released on Sunday May 17, 2026. SeleniumLibrary supports +Python 3.10 through 3.14, Selenium 4.29.0 through 4.44.0 and +Robot Framework 6.1.1 and 7.4.2. + +.. _Robot Framework: http://robotframework.org +.. _SeleniumLibrary: https://github.com/robotframework/SeleniumLibrary +.. _Selenium: http://seleniumhq.org +.. _pip: http://pip-installer.org +.. _PyPI: https://pypi.python.org/pypi/robotframework-seleniumlibrary +.. _issue tracker: https://github.com/robotframework/SeleniumLibrary/issues?q=milestone%3Av6.9.0 + + +.. contents:: + :depth: 2 + :local: + +Most important enhancements +=========================== + +- "Open Browser" keyword documentation has broken links which were fixed (`#1976`_) +- Chaining locators with lists does not work with Robot Framework 6.1 or above (`#1962`_) + There was an issue with the types which prevented using chained locators as lists. This + has been resolved in this release. +- Fix deprecation warnings and improve logging in tests (`#1974`_) +- Added "Drag And Drop Across Frames" keyword for cross-frame drag and drop support (`#1953`_) + Note the still remains an issue with Firefox related to drag and drop. This change does + note resolve the issue within gecko driver and Firefox. +- Input Password does not accept Secret type (`#1966`_) + We have added support for the Secret Type into this release. +- Added "Get CSS Property Value" keyword to retrieve computed CSS values (`#1969`_) +- Selenium manager fails to download firefox/edge with lower versions of selenium (`#1986`_) + +There were also several changes that are focused on internal processes and operations +- Migrate lint/format tooling to Ruff, update CI matrix, and stabilize cross-platform/firefox tests (`#1978`_) +- Update cookie validation regex in Get Cookies test (`#1973`_) +- Added new GitHub Actions workflow and performed yearly update on cookie test suite (`#1955`_) + +Acknowledgements +================ + +I want to give a large shout out to [Yuri](https://github.com/yuriverweij) who had a large hand in getting +this release out the door including resolving issues, reviewing code changes, and fixing up our processes +and tooling, amongst all the other contributions he made towards this release. Some of these include + +- Update cookie validation regex in Get Cookies test (`#1973`_) +- Fix deprecation warnings and improve logging in tests (`#1974`_) +- Review restriction on running ApprovalTests under Windows (`#1884`_) +- Migrate lint/format tooling to Ruff, update CI matrix, and stabilize cross-platform/firefox tests (`#1978`_) + +Yuri along with [Tatu](https://github.com/aaltat) brought in the Secret type into this release. And thank you +to [petobarki](https://github.com/petobarki) for reporting and asking for this feature/support. + +- Input Password does not accept Secret type (`#1966`_) + +I also want to thank a couple of first time contributors. Let me thank [Vamsi](https://github.com/b-vamsipunnam) for a +couple new keywords + +- Added "Drag And Drop Across Frames" keyword for cross-frame drag and drop support (`#1953`_) +- Added "Get CSS Property Value" keyword to retrieve computed CSS values (`#1969`_) + +And I also want to recognize and thank [Jaroslav Cerman](https://github.com/antivirak) for fixing a type error in deprecation message (`#1947`_). +Great job Jaroslav and Vamsi on these first time contributions! + +I also want to thank +- [jjaakkola-atostek](https://github.com/jjaakkola-atostek) for reporting that chaining locators with lists does not work with Robot Framework 6.1 or above (`#1962`_) +- [Slava Semushin](https://github.com/php-coder) for reporting the "Open Browser" keyword documentation has broken links (`#1976`_) + +And I once again want to recognize and give my thanks to the ongoing support by Tatu Aalto. + + +Full list of fixes and enhancements +=================================== + +.. list-table:: + :header-rows: 1 + + * - ID + - Type + - Priority + - Summary + * - `#1962`_ + - bug + - critical + - Chaining locators with lists does not work with Robot Framework 6.1 or above + * - `#1973`_ + - bug + - high + - Update cookie validation regex in Get Cookies test + * - `#1953`_ + - enhancement + - high + - Add "Drag And Drop Across Frames" keyword for cross-frame drag and drop support + * - `#1955`_ + - enhancement + - high + - Added new GitHub Actions workflow and performed yearly update on cookie test suite + * - `#1966`_ + - enhancement + - high + - Input Password does not accept Secret type + * - `#1969`_ + - enhancement + - high + - Add "Get CSS Property Value" keyword to retrieve computed CSS values + * - `#1974`_ + - enhancement + - high + - Fix deprecation warnings and improve logging in tests + * - `#1978`_ + - enhancement + - high + - Migrate lint/format tooling to Ruff, update CI matrix, and stabilize cross-platform/firefox tests + * - `#1986`_ + - enhancement + - high + - Selenium manager fails to download firefox/edge with lower versions of selenium + * - `#1947`_ + - bug + - medium + - Fix typo in deprecation message + * - `#1976`_ + - bug + - medium + - "Open Browser" keyword documentation has broken links + * - `#1921`_ + - enhancement + - medium + - Use Dependabot to update deps automatically + * - `#1884`_ + - --- + - medium + - Review restriction on running ApprovalTests under Windows + * - `#1967`_ + - --- + - medium + - Bump actions/upload-artifact from 4 to 7 + * - `#1963`_ + - bug + - --- + - `#1962`_ fix cascading locators + * - `#1956`_ + - --- + - --- + - Dependabot + * - `#1971`_ + - --- + - --- + - Fixed doc formating issue within xpath examples + +Altogether 17 issues. View on the `issue tracker `__. + +.. _#1962: https://github.com/robotframework/SeleniumLibrary/issues/1962 +.. _#1973: https://github.com/robotframework/SeleniumLibrary/issues/1973 +.. _#1953: https://github.com/robotframework/SeleniumLibrary/issues/1953 +.. _#1955: https://github.com/robotframework/SeleniumLibrary/issues/1955 +.. _#1966: https://github.com/robotframework/SeleniumLibrary/issues/1966 +.. _#1969: https://github.com/robotframework/SeleniumLibrary/issues/1969 +.. _#1974: https://github.com/robotframework/SeleniumLibrary/issues/1974 +.. _#1978: https://github.com/robotframework/SeleniumLibrary/issues/1978 +.. _#1986: https://github.com/robotframework/SeleniumLibrary/issues/1986 +.. _#1947: https://github.com/robotframework/SeleniumLibrary/issues/1947 +.. _#1976: https://github.com/robotframework/SeleniumLibrary/issues/1976 +.. _#1921: https://github.com/robotframework/SeleniumLibrary/issues/1921 +.. _#1884: https://github.com/robotframework/SeleniumLibrary/issues/1884 +.. _#1967: https://github.com/robotframework/SeleniumLibrary/issues/1967 +.. _#1963: https://github.com/robotframework/SeleniumLibrary/issues/1963 +.. _#1956: https://github.com/robotframework/SeleniumLibrary/issues/1956 +.. _#1971: https://github.com/robotframework/SeleniumLibrary/issues/1971 diff --git a/docs/SeleniumLibrary.html b/docs/SeleniumLibrary.html index f24e5de38..288957d5a 100644 --- a/docs/SeleniumLibrary.html +++ b/docs/SeleniumLibrary.html @@ -9,7 +9,7 @@