From 062a7b84a81c38b02da9d8a81c3b33943b3919c4 Mon Sep 17 00:00:00 2001 From: David Smith Date: Fri, 6 Dec 2024 07:03:18 +0000 Subject: [PATCH] Update all the things --- .github/workflows/main.yml | 63 +++++++++++++++++++ .travis.yml | 61 ------------------ CODE_OF_CONDUCT.md | 13 +--- MANIFEST.in | 14 ++++- README.rst | 36 ++++------- axe_selenium_python/axe.py | 7 +-- axe_selenium_python/package-lock.json | 24 +++++-- axe_selenium_python/package.json | 2 +- axe_selenium_python/tests/conftest.py | 31 --------- .../tests/requirements/flake8.txt | 2 - .../tests/requirements/tests.txt | 4 -- package-lock.json | 11 +++- package.json | 2 +- pyproject.toml | 25 ++++++++ setup.cfg | 5 -- setup.py | 32 ---------- .../tests => tests}/__init__.py | 0 tests/requirements/lint.txt | 3 + tests/requirements/tests.txt | 4 ++ .../tests => tests}/src/axe.min.js | 0 .../tests => tests}/test_axe.py | 11 ++-- .../tests => tests}/test_page.html | 0 tox.ini | 22 +++---- 23 files changed, 168 insertions(+), 204 deletions(-) create mode 100644 .github/workflows/main.yml delete mode 100755 .travis.yml delete mode 100644 axe_selenium_python/tests/conftest.py delete mode 100644 axe_selenium_python/tests/requirements/flake8.txt delete mode 100644 axe_selenium_python/tests/requirements/tests.txt create mode 100644 pyproject.toml delete mode 100644 setup.cfg delete mode 100644 setup.py rename {axe_selenium_python/tests => tests}/__init__.py (100%) create mode 100644 tests/requirements/lint.txt create mode 100644 tests/requirements/tests.txt rename {axe_selenium_python/tests => tests}/src/axe.min.js (100%) rename {axe_selenium_python/tests => tests}/test_axe.py (90%) mode change 100755 => 100644 rename {axe_selenium_python/tests => tests}/test_page.html (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..fadd9b9 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,63 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + +concurrency: + group: ${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + tests: + name: Python ${{ matrix.python-version }} + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: + - '3.12' + - '3.13' + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - uses: browser-actions/setup-geckodriver@latest + + - name: Install uv + uses: astral-sh/setup-uv@v4 + with: + enable-cache: true + cache-dependency-glob: tests/requirements/*.txt + + - name: Install dependencies + run: uv pip install --system tox tox-uv + + - name: NPM Install + run: npm install + + - name: Run tox targets for ${{ matrix.python-version }} + run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .) + + lint: + name: Lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip tox + - name: Run lint + run: tox -e lint diff --git a/.travis.yml b/.travis.yml deleted file mode 100755 index 94516fc..0000000 --- a/.travis.yml +++ /dev/null @@ -1,61 +0,0 @@ -sudo: required -language: python -node_js: stable -addons: - firefox: latest-nightly - chrome: stable - -cache: - directories: - - $HOME/.cache/pip - - $HOME/virtualenv/python2.7.9/lib/python2.7/site-packages - - node_modules - -before_install: - - wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/$CHROMEDRIVER/chromedriver_linux64.zip - - mkdir $HOME/chromedriver && unzip /tmp/chromedriver.zip -d $HOME/chromedriver - - export PATH=$HOME/chromedriver:$PATH - - wget -O /tmp/geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v$GECKODRIVER/geckodriver-v$GECKODRIVER-linux64.tar.gz - - mkdir $HOME/geckodriver && tar xvf /tmp/geckodriver.tar.gz -C $HOME/geckodriver - - export PATH=$HOME/geckodriver:$PATH - - firefox --version - - geckodriver --version -install: - - pip install tox - -before_script: - - npm install -script: tox - -jobs: - include: - - stage: - python: 3.6 - env: TOXENV=py36 MOZ_HEADLESS=1 GECKODRIVER=0.23.0 CHROMEDRIVER=2.40 - - stage: - python: 2.7 - env: TOXENV=py27 MOZ_HEADLESS=1 GECKODRIVER=0.23.0 CHROMEDRIVER=2.40 - - stage: - python: 3.6 - before_install: skip - install: pip install tox - env: TOXENV=flake8 - - stage: deploy - before_install: skip - install: skip - script: skip - skip_cleanup: true - deploy: - provider: pypi - user: kimberlythegeek - password: - secure: LHsL91XR32/M4r5ETAvaN/vUTakYByIfdwdCw6EI59LBvSnwaSant010QIl39+uafuev57yzUC/Y+orefczjkJnG3KdQBNS0Rt/zWIMw0Dr6Fp41Vg66e5URK/FRIwK36WlWzOcd3GkrQLLaDeqnXVzDWVMuXPP9/1ssu6mvriSeLctPsmX5N6m4yZwxNtpFsTLEh+BumXiamCuqjTI0RpyqxYlUVfio0G5LWeY9rkPskrwbSbc8xhq/PMk/ecLtlAxdn8AwgjLYCAt9d6NRfgL4Yp0R+kkfUQsX1Wf8A/pBNRr8Ht8Hy4CNlnEphgao4fgVEY4dc6tZL3FXOU9jQSmbChoANlbPzDhO+nb6d/QW5vLHVDufKyRQqtFxD90XFXlWFc/0gnD6tPZhi+UEFmBMoo9ugWDnYUeBd1T3lbwKT7sOmOQS58WhDVMLxPwr2BfgItGrNsaVHmzx9v0BnxZvD5ilmvNPrad6Rcsa0N8GtNXpnbyaupWzA97bemzuLqNHOjTm6TMZWRol6lLEJsJ1MRs7xWI4DYztXzlWITH7rvf6NNyvXKe9FPV3Lfoei3k1mT8QuEh6bIEFpBKRVV0ObQVSfFQ4M4wbgDBb3CbHVqMqFHgi98mpUo9tNGm4uzZCXw3hfEQpUPugKaH+VHoaylE+MR+fOhsyVlLQluM= - on: - tags: true - branch: master - distributions: "sdist bdist_wheel" - skip_cleanup: true - -after_success: - - pip install coveralls - - coveralls diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 498baa3..7f33e3c 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,15 +1,4 @@ # Community Participation Guidelines -This repository is governed by Mozilla's code of conduct and etiquette guidelines. -For more details, please read the -[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/). +This repository is governed by Django's code of conduct. See https://www.djangoproject.com/conduct/. -## How to Report -For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page. - - diff --git a/MANIFEST.in b/MANIFEST.in index 0db5497..9a24508 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,14 @@ -include LICENSE.txt README.rst axe_selenium_python/node_modules/axe-core/axe.min.js axe_selenium_python/tests/test_page.html +include CODE_OF_CONDUCT.md +include LICENSE.txt +include README.rst +include tox.ini +include axe_selenium_python/node_modules/axe-core/axe.min.js +include tests/test_page.html +include package.json +include package-lock.json +include axe_selenium_python/package-lock.json +include axe_selenium_python/package.json recursive-include *.rst *.txt +recursive-include tests *.js +recursive-include tests *.py +recursive-include tests *.txt diff --git a/README.rst b/README.rst index 22089cc..35e00c2 100755 --- a/README.rst +++ b/README.rst @@ -3,36 +3,25 @@ axe-selenium-python axe-selenium-python integrates aXe and selenium to enable automated web accessibility testing. -**This version of axe-selenium-python is using axe-core@4.0.2.** +**This version of axe-selenium-python is using axe-core@4.10.2.** .. image:: https://img.shields.io/badge/license-MPL%202.0-blue.svg - :target: https://github.com/mozilla-services/axe-selenium-python/blob/master/LICENSE.txt + :target: https://github.com/axe-selenium-python/axe-selenium-python/blob/master/LICENSE.txt :alt: License .. image:: https://img.shields.io/pypi/v/axe-selenium-python.svg :target: https://pypi.org/project/axe-selenium-python/ :alt: PyPI -.. image:: https://img.shields.io/travis/mozilla-services/axe-selenium-python.svg - :target: https://travis-ci.org/mozilla-services/axe-selenium-python - :alt: Travis -.. image:: https://img.shields.io/github/issues-raw/mozilla-services/axe-selenium-python.svg - :target: https://github.com/mozilla-services/axe-selenium-python/issues +.. image:: https://img.shields.io/github/issues-raw/axe-selenium-python/axe-selenium-python.svg + :target: https://github.com/axe-selenium-python/axe-selenium-python/issues :alt: Issues -.. image:: https://api.dependabot.com/badges/status?host=github&repo=mozilla-services/axe-selenium-python - :target: https://dependabot.com - :alt: Dependabot -.. image:: https://coveralls.io/repos/github/mozilla-services/axe-selenium-python/badge.svg?branch=master - :target: https://coveralls.io/github/mozilla-services/axe-selenium-python?branch=master - :alt: Coveralls - - Requirements ------------ You will need the following prerequisites in order to use axe-selenium-python: -- selenium >= 3.0.0 -- Python 2.7 or 3.6 +- selenium >= 4.2 +- Python 3.12+ - The appropriate driver for the browser you intend to use, downloaded and added to your path, e.g. geckodriver for Firefox: - `geckodriver `_ downloaded and `added to your PATH `_ @@ -88,16 +77,15 @@ You can run the tests using $ tox -Resources ---------- - -- `Issue Tracker `_ -- `Code `_ -- `pytest-axe `_ - CHANGELOG ^^^^^^^^^^^^^^ +version 3.0 +*********** + +- Bumped minimum Python version to 3.12 +- Updated axe to ``axe-core@4.10.2`` + version 2.1.5 ************* **Breaks backwards compatibility**: diff --git a/axe_selenium_python/axe.py b/axe_selenium_python/axe.py index b2fae3d..9ec5616 100755 --- a/axe_selenium_python/axe.py +++ b/axe_selenium_python/axe.py @@ -4,14 +4,13 @@ import json import os -from io import open _DEFAULT_SCRIPT = os.path.join( os.path.dirname(__file__), "node_modules", "axe-core", "axe.min.js" ) -class Axe(object): +class Axe: def __init__(self, selenium, script_url=_DEFAULT_SCRIPT): self.script_url = script_url self.selenium = selenium @@ -23,7 +22,7 @@ def inject(self): :param script_url: location of the axe-core script. :type script_url: string """ - with open(self.script_url, "r", encoding="utf8") as f: + with open(self.script_url, encoding="utf8") as f: self.selenium.execute_script(f.read()) def run(self, context=None, options=None): @@ -110,6 +109,6 @@ def write_results(self, data, name=None): with open(filepath, "w", encoding="utf8") as f: try: - f.write(unicode(json.dumps(data, indent=4))) + f.write(json.dumps(data, indent=4)) except NameError: f.write(json.dumps(data, indent=4)) diff --git a/axe_selenium_python/package-lock.json b/axe_selenium_python/package-lock.json index d31a08f..3175c0f 100644 --- a/axe_selenium_python/package-lock.json +++ b/axe_selenium_python/package-lock.json @@ -1,13 +1,25 @@ { "name": "axe-selenium-python", "version": "0.0.1", - "lockfileVersion": 1, + "lockfileVersion": 3, "requires": true, - "dependencies": { - "axe-core": { - "version": "4.0.2", - "resolved": "https://nexus.corp.indeed.com/repository/npm/axe-core/-/axe-core-4.0.2.tgz", - "integrity": "sha512-arU1h31OGFu+LPrOLGZ7nB45v940NMDMEJeNmbutu57P+UFDVnkZg3e+J1I2HJRZ9hT7gO8J91dn/PMrAiKakA==" + "packages": { + "": { + "name": "axe-selenium-python", + "version": "0.0.1", + "license": "MPL-2.0", + "dependencies": { + "axe-core": "^4.10.2" + } + }, + "node_modules/axe-core": { + "version": "4.10.2", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.2.tgz", + "integrity": "sha512-RE3mdQ7P3FRSe7eqCWoeQ/Z9QXrtniSjp1wUjt5nRC3WIpz5rSCve6o3fsZ2aCpJtrZjSZgjwXAoTO5k4tEI0w==", + "license": "MPL-2.0", + "engines": { + "node": ">=4" + } } } } diff --git a/axe_selenium_python/package.json b/axe_selenium_python/package.json index 3e618c0..033045d 100644 --- a/axe_selenium_python/package.json +++ b/axe_selenium_python/package.json @@ -17,6 +17,6 @@ }, "homepage": "https://github.com/kimberlythegeek/axe-selenium-python#readme", "dependencies": { - "axe-core": ">=4.0.2" + "axe-core": "^4.10.2" } } diff --git a/axe_selenium_python/tests/conftest.py b/axe_selenium_python/tests/conftest.py deleted file mode 100644 index 875d86b..0000000 --- a/axe_selenium_python/tests/conftest.py +++ /dev/null @@ -1,31 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -from datetime import datetime - -import pytest -from py.xml import html - - -@pytest.mark.optionalhook -def pytest_html_results_table_header(cells): - """Add description and sortable time header to HTML report.""" - cells.insert(2, html.th("Description")) - cells.insert(0, html.th("Time", class_="sortable time", col="time")) - - -@pytest.mark.optionalhook -def pytest_html_results_table_row(report, cells): - """Add description and sortable time column to HTML report.""" - cells.insert(2, html.td(report.description)) - cells.insert(1, html.td(datetime.utcnow(), class_="col-time")) - - -@pytest.mark.hookwrapper -def pytest_runtest_makereport(item, call): - """Make HTML report using test-function docstrings as description.""" - outcome = yield - report = outcome.get_result() - # add docstring to 'description' column - report.description = str(item.function.__doc__) diff --git a/axe_selenium_python/tests/requirements/flake8.txt b/axe_selenium_python/tests/requirements/flake8.txt deleted file mode 100644 index 73cc7ec..0000000 --- a/axe_selenium_python/tests/requirements/flake8.txt +++ /dev/null @@ -1,2 +0,0 @@ -flake8==3.5.0 -flake8-isort==2.5 diff --git a/axe_selenium_python/tests/requirements/tests.txt b/axe_selenium_python/tests/requirements/tests.txt deleted file mode 100644 index 85cd994..0000000 --- a/axe_selenium_python/tests/requirements/tests.txt +++ /dev/null @@ -1,4 +0,0 @@ -pytest==3.9.2 -selenium==3.14.1 -pytest-html==1.19.0 -pytest-mock==1.10.0 diff --git a/package-lock.json b/package-lock.json index 0509214..f36b4db 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,14 @@ { "name": "axe-selenium-python", "version": "0.0.1", - "lockfileVersion": 1 + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "axe-selenium-python", + "version": "0.0.1", + "hasInstallScript": true, + "license": "MPL-2.0" + } + } } diff --git a/package.json b/package.json index 5fbc8d5..48c7bc1 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "Integrate axe-core with python", "main": "index.js", "scripts": { - "install": "cd axe_selenium_python && npm install" + "install": "cd axe_selenium_python && npm install && npm ls" }, "repository": { "type": "git", diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c856707 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,25 @@ +[build-system] +requires = ["setuptools>=64", "setuptools-scm>=8"] +build-backend = "setuptools.build_meta" + +[project] +name = "axe-selenium-python" +description = "Python library to integrate axe and selenium for web accessibility testing." +dynamic = ["version"] +readme = "README.rst" +authors = [ + {name="Kimberly Sereduck", email="ksereduck@mozilla.com"} +] +license = {"text" = "Mozilla Public License 2.0 (MPL 2.0)"} +keywords = ["axe-core", "selenium", "pytest-selenium", "accessibility" , "automation", "mozilla"] +requires-python = ">=3.12" +dependencies = [ + "selenium>=4.2", + "pytest>=3.0", +] + +[project.urls] +"Homepage" = "https://github.com/axe-selenium-python/axe-selenium-python" +"Issues" = "https://github.com/axe-selenium-python/axe-selenium-python/issues" + +[tool.setuptools_scm] \ No newline at end of file diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 79bc678..0000000 --- a/setup.cfg +++ /dev/null @@ -1,5 +0,0 @@ -[bdist_wheel] -# This flag says that the code is written to work on both Python 2 and Python -# 3. If at all possible, it is good practice to do this. If you cannot, you -# will need to generate wheels for each Python version that you support. -universal=1 diff --git a/setup.py b/setup.py deleted file mode 100644 index ed58bbd..0000000 --- a/setup.py +++ /dev/null @@ -1,32 +0,0 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - - -from setuptools import find_packages, setup - -with open("./README.rst") as f: - readme = f.read() - -setup( - name="axe-selenium-python", - use_scm_version=True, - setup_requires=["setuptools_scm"], - description="Python library to integrate axe and selenium for web \ - accessibility testing.", - long_description=open("README.rst").read(), - url="http://github.com/mozilla-services/axe-selenium-python", - author="Kimberly Sereduck", - author_email="ksereduck@mozilla.com", - packages=find_packages(), - package_data={ - "axe_selenium_python": [ - "axe_selenium_python/node_modules/axe-core/axe.min.js", - "axe_selenium_python/tests/test_page.html", - ] - }, - include_package_data=True, - install_requires=["selenium>=3.0.2", "pytest>=3.0"], - license="Mozilla Public License 2.0 (MPL 2.0)", - keywords="axe-core selenium pytest-selenium accessibility automation mozilla", -) diff --git a/axe_selenium_python/tests/__init__.py b/tests/__init__.py similarity index 100% rename from axe_selenium_python/tests/__init__.py rename to tests/__init__.py diff --git a/tests/requirements/lint.txt b/tests/requirements/lint.txt new file mode 100644 index 0000000..f086aa4 --- /dev/null +++ b/tests/requirements/lint.txt @@ -0,0 +1,3 @@ +flake8 +isort +black diff --git a/tests/requirements/tests.txt b/tests/requirements/tests.txt new file mode 100644 index 0000000..a2c0535 --- /dev/null +++ b/tests/requirements/tests.txt @@ -0,0 +1,4 @@ +pytest +selenium +pytest-html +pytest-mock \ No newline at end of file diff --git a/axe_selenium_python/tests/src/axe.min.js b/tests/src/axe.min.js similarity index 100% rename from axe_selenium_python/tests/src/axe.min.js rename to tests/src/axe.min.js diff --git a/axe_selenium_python/tests/test_axe.py b/tests/test_axe.py old mode 100755 new mode 100644 similarity index 90% rename from axe_selenium_python/tests/test_axe.py rename to tests/test_axe.py index 34f0aa7..bd38343 --- a/axe_selenium_python/tests/test_axe.py +++ b/tests/test_axe.py @@ -8,7 +8,7 @@ import pytest from selenium import webdriver -from ..axe import Axe +from axe_selenium_python import Axe _DEFAULT_TEST_FILE = path.join(path.dirname(__file__), "test_page.html") @@ -25,6 +25,7 @@ def chrome_driver(): opts = webdriver.ChromeOptions() opts.headless = True opts.add_argument("--no-sandbox") + opts.add_argument("--headless") driver_path = getenv("CHROMEDRIVER_PATH") driver = ( webdriver.Chrome(options=opts, executable_path=driver_path) @@ -40,10 +41,10 @@ def test_run_axe_sample_page_firefox(firefox_driver): """Run axe against sample page and verify JSON output is as expected.""" data = _perform_axe_run(firefox_driver) - assert len(data["inapplicable"]) == 61 + assert len(data["inapplicable"]) == 75 assert len(data["incomplete"]) == 0 assert len(data["passes"]) == 6 - assert len(data["violations"]) == 8 + assert len(data["violations"]) == 9 @pytest.mark.nondestructive @@ -51,10 +52,10 @@ def test_run_axe_sample_page_chrome(chrome_driver): """Run axe against sample page and verify JSON output is as expected.""" data = _perform_axe_run(chrome_driver) - assert len(data["inapplicable"]) == 61 + assert len(data["inapplicable"]) == 75 assert len(data["incomplete"]) == 0 assert len(data["passes"]) == 6 - assert len(data["violations"]) == 8 + assert len(data["violations"]) == 9 def _perform_axe_run(driver): diff --git a/axe_selenium_python/tests/test_page.html b/tests/test_page.html similarity index 100% rename from axe_selenium_python/tests/test_page.html rename to tests/test_page.html diff --git a/tox.ini b/tox.ini index 5f669ba..46512ca 100644 --- a/tox.ini +++ b/tox.ini @@ -1,25 +1,19 @@ [tox] -envlist = py27, py36, flake8 +envlist = py312, py313, lint skipsdist = true [testenv] setenv = MOZ_HEADLESS = 1 -deps = -raxe_selenium_python/tests/requirements/tests.txt +deps = -rtests/requirements/tests.txt commands = pytest -rsx --verbose -[testenv:flake8] -deps = -raxe_selenium_python/tests/requirements/flake8.txt -commands = flake8 {posargs:.} +[testenv:lint] +deps = -rtests/requirements/lint.txt +commands = + flake8 axe_selenium_python tests + isort axe_selenium_python tests --check --dif + black axe_selenium_python tests --check [flake8] max-line-length = 88 -# Black will break a line before a binary operator when splitting a block -# of code over multiple lines. This is so that Black is compliant with the -# recent changes in the PEP8 style guide. -ignore = W503 - -[isort] -default_section = THIRDPARTY -known_first_party = axe-selenium-python -skip = build, .tox