Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions .flake8

This file was deleted.

1 change: 1 addition & 0 deletions .gitattibutes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.approved.txt text eol=lf
12 changes: 6 additions & 6 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ 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
python-version: [3.10.16, 3.13.5, 3.14.0-rc.3, pypy-3.10]
# python-version: [{earliest: 3.10}, {latest: 3.14.0-rc.3}, {pypy: pypy-3.10}]
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]
browser: [chrome] # firefox, chrome, headlesschrome, edge
Expand Down Expand Up @@ -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
Expand All @@ -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

Expand All @@ -89,7 +89,7 @@ jobs:
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
Expand Down
41 changes: 41 additions & 0 deletions .github/workflows/LintFormatCheck.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Lint and Format Check

on: [push, pull_request]

jobs:
ruff:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v6

- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"

- 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 format --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
14 changes: 9 additions & 5 deletions .github/workflows/Select.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,23 @@ jobs:
rf-version: 6.1.1
selenium-version: 4.37.0
browser: chrome

- description: latest
python-version: 3.13.10
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
Expand Down Expand Up @@ -74,6 +78,6 @@ jobs:
- uses: actions/upload-artifact@v4
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
29 changes: 15 additions & 14 deletions CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 format --check # Check formatting with Ruff
inv format # 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
-------------
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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
.. _Ruff: https://github.com/astral-sh/ruff
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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_.

Expand Down
7 changes: 6 additions & 1 deletion atest/acceptance/1-plugin/OpenBrowserExample.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
2 changes: 1 addition & 1 deletion atest/acceptance/keywords/mouse.robot
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions atest/acceptance/keywords/textfields.robot
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,10 @@ Attempt Clear Element Text On Non-Editable Field

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}
${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
5 changes: 3 additions & 2 deletions atest/resources/testlibs/get_driver_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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())
11 changes: 8 additions & 3 deletions atest/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,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(
Expand Down Expand Up @@ -215,7 +215,12 @@ def execute_tests(interpreter, browser, rf_options, grid, event_firing, port):
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",
]
command = runner
if grid:
command += [
Expand Down Expand Up @@ -259,7 +264,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)
Expand Down
2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ <h2><a class="toc-backref" href="#toc-entry-1" role="doc-backlink">Introduction<
<p><a class="reference external" href="https://github.com/robotframework/SeleniumLibrary">SeleniumLibrary</a> is a web testing library for <a class="reference external" href="https://robotframework.org">Robot Framework</a> that
utilizes the <a class="reference external" href="https://www.seleniumhq.org/">Selenium</a> tool internally. The project is hosted on <a class="reference external" href="https://github.com/robotframework/SeleniumLibrary">GitHub</a>
and downloads can be found from <a class="reference external" href="https://pypi.python.org/pypi/robotframework-seleniumlibrary">PyPI</a>.</p>
<p>SeleniumLibrary currently works with Selenium 4. It supports Python 3.8 through 3.13.
<p>SeleniumLibrary currently works with Selenium 4. It supports Python 3.10 through 3.13.
In addition to the normal <a class="reference external" href="https://python.org">Python</a> interpreter, it works also
with <a class="reference external" href="https://pypy.org">PyPy</a>.</p>
<p>SeleniumLibrary is based on the &quot;old SeleniumLibrary&quot; that was forked to
Expand Down
63 changes: 47 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,20 +1,51 @@
[tool.black]
target-version = ['py36']
exclude = '''
/(
| \.git
| \.venv
| _build
| dist
| generated
| src/SeleniumLibrary/__init__\.pyi
)/
'''
[tool.ruff]
target-version = "py310"
line-length = 88
exclude = [
"src/SeleniumLibrary/__init__.pyi",
]

[tool.ruff.lint]
select = [
"E",
"F",
"W",
"C90",
"I",
"N",
"B",
"PYI",
"PL",
"UP",
"A",
"C4",
"DTZ",
"ISC",
"ICN",
"INP",
"PIE",
"T20",
"PYI",
"PT",
"RSE",
"RET",
"SIM",
"RUF"
]
ignore = [
"E501", # line too long
"N803", # argument name should be lowercase
"N812", # lowercase imported as non lowercase
"N999", # Invalid module name: 'SeleniumLibrary'
"PLR0913", # too many arguments
"PLR2004", # Magic value used in comparison
"DTZ006", # No timezone specified
"PTH", # Use Path instead of os.path -> maybe soon
"N818", # exception naming convention
]

[tool.isort]
profile = "black"
src_paths="."
skip_glob = ["src/SeleniumLibrary/__init__.pyi"]
[tool.ruff.format]
quote-style = "double"


[tool.pytest.ini_options]
Expand Down
3 changes: 1 addition & 2 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ pytest-mockito == 0.0.4
pytest-approvaltests == 0.2.4
requests == 2.33.1
robotframework-pabot == 5.2.2
black == 26.3.1
flake8 == 6.1.0
ruff == 0.15.12

# Requirements needed when generating releases. See BUILD.rst for details.
rellu == 0.7
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
keywords = 'robotframework testing testautomation selenium webdriver web',
platforms = 'any',
classifiers = CLASSIFIERS,
python_requires = '>=3.8',
python_requires = '>=3.10',
install_requires = REQUIREMENTS,
package_dir = {'': 'src'},
packages = find_packages('src'),
Expand Down
Loading