Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessibility test Kitchen Sink with Playwright #1260

Merged
merged 56 commits into from
Apr 14, 2023

Conversation

gabalafou
Copy link
Collaborator

@gabalafou gabalafou commented Mar 22, 2023

Closes #1168.

This pull request adds accessibility tests for the Kitchen Sink section of the PyData Sphinx Theme docs in order to check the theme for accessibility issues. As such it adds two major dependencies:

  1. pytest-playwright to the Python test dependencies
  2. axe-core to the Node (npm) dev dependencies

It updates the Nox file accordingly, and adds instructions to the docs.

Though mentioned already in the files added and changed, it bears repeating here: doing an accessibility check with axe-core is only a first-pass at testing for accessibility, since automated accessibility checks can only catch a fraction of web accessibility issues.

Install pytest-playwright and (npm) axe-core
Write test that scans admonitions with Axe

How to run test:

nox -s compile
nox -s docs
python -m http.server -d docs/_build/html/
nox -s test -- -k accessibility
@trallard trallard added the tag: accessibility Issues related to accessibility issues or efforts label Mar 22, 2023
@trallard trallard self-requested a review March 22, 2023 17:23
Copy link
Collaborator Author

@gabalafou gabalafou left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done self reviewing!

To whoever reviews my PR, please bear in mind that I am a novice Python programmer, so please do not hesitate to call out any anti-patterns or code smells.

We'll also want to think about how we integrate this code into Github Actions, but rather than hold back this PR until everything is fleshed out, I wanted to get up some working code now to help anchor the conversation about what to do next.

For those who are curious, I have pasted the output from accessibility tests in a gist.

Most of the failures are color contrast issues, but there are also: landmarks need to be unique, scrollable regions need to be keyboard focusable, and links need to be clearly distinguishable.

noxfile.py Outdated Show resolved Hide resolved
package-lock.json Outdated Show resolved Hide resolved
pyproject.toml Outdated Show resolved Hide resolved
tests/README.md Outdated Show resolved Hide resolved
tests/README.md Outdated Show resolved Hide resolved
tests/test_accessibility.py Outdated Show resolved Hide resolved
tests/utils.py Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
docs/community/setup.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@drammock drammock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this! here's a first pass with some comments. Please ping when you're ready for a second review.

docs/community/setup.md Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
tests/README.md Outdated Show resolved Hide resolved
tests/test_accessibility.py Outdated Show resolved Hide resolved
tests/test_accessibility.py Outdated Show resolved Hide resolved
tests/utils.py Outdated Show resolved Hide resolved
tests/utils.py Outdated Show resolved Hide resolved
tests/README.md Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
Copy link
Collaborator

@trallard trallard left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a first pass review - lmk if there is anything need clarification

docs/community/topics/accessibility.md Outdated Show resolved Hide resolved
docs/community/topics/accessibility.md Show resolved Hide resolved
docs/community/setup.md Outdated Show resolved Hide resolved
tests/README.md Outdated Show resolved Hide resolved
tests/README.md Outdated Show resolved Hide resolved
tests/utils.py Outdated Show resolved Hide resolved
tests/utils.py Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
noxfile.py Outdated Show resolved Hide resolved
tests/utils.py Outdated Show resolved Hide resolved
gabalafou and others added 12 commits March 27, 2023 09:20
Co-authored-by: Daniel McCloy <dan@mccloy.info>
Co-authored-by: Tania Allard <taniar.allard@gmail.com>
Co-authored-by: Tania Allard <taniar.allard@gmail.com>
Co-authored-by: Tania Allard <taniar.allard@gmail.com>
Co-authored-by: Tania Allard <taniar.allard@gmail.com>
Co-authored-by: Tania Allard <taniar.allard@gmail.com>
- add pytest-base-url plugin
- push more test setup into page fixture
- add license header to pretty_axe_results
- move pretty_axe_results and check_warnings to utils/
rm package-lock.json
rm -r node_modules
stb npm install --include=dev
@drammock
Copy link
Collaborator

I think #1260 (comment) got missed in the last review rounds, so I'm brining it back up and highlighting it here.

One thing I don't like right now is that the following command fails:

nox -s test -- -k a11y

FWIW, locally this command runs for me (there are failures, but they're not due to missing playwright).

I've been pushing commits today to get the CIs to run (and then to get them to succeed) and in the process I noticed that pytest-axe supposedly has a built-in pytest mark that you can use to decorate tests; then running pytest --axe should run only those tests, and the absence of --axe should skip them. That seems to me like a pretty handy way to separate out the a11y tests. However, I tried quickly and couldn't get it to work, probably because I'm doing something wrong. Maybe you can get it to work @gabalafou? But even if so, pytest-axe is a public archive repo; so IDK if we want to use it if it's no longer maintained.

As an aside: I'm having trouble wrapping my head around all of this so it's hard to say what is the best approach. I think what we have here is (simplified):

├── .github/workflows/tests.yml
│   ├── run-pytest        -> runs on various OSes and Python versions; calls `pytest` directly
│   ├── build-site        -> runs on 3 OSes; calls `sphinx-build`;
│   │                        checks for (un)expected build warnings
│   ├── new-a11y-CI-test  -> ***MISSING / NOT WORKING YET***
│   └── audit             -> old lighthouse job; "needs" build-site; runs on ubuntu only;
│                            creates small site (just kitchen sink), runs `sphinx-build`,
│                            and runs the lighthouse action on that static site.
│
├── noxfile.py
│   ├── docs  ->  calls `stb compile` and `sphinx-build`
│   └── a11y  ->  calls `playwright install`, `nox -s docs`, and `pytest -k a11y`
│
└── tests/
    ├── test_build.py  -> calls `sphinx-build` via a factory function
    └── test_a11y.py   -> sets up a webserver and calls `axe.run()` a bunch of times

The mix-and-match of stb versus sphinx-build, calling pytest or sphinx-build or stb directly vs calling the nox job... it all has my head spinning; currently we don't use nox in our CI config (except for the "compile MO files" step of the run-pytest job? why??)

Probably this deserves its own issue for discussion, but in the meantime we need to implement the new a11y CI test somehow so if we can quickly converge on what we should be doing everywhere then we can just do that in one place now and then (I or someone else) can propogate that decision to the other CI jobs.

Thoughts/advice from anyone are very welcome.

@gabalafou
Copy link
Collaborator Author

FWIW, locally this command runs for me (there are failures, but they're not due to missing playwright).

That's odd. This is how it looks in my terminal

@drammock
Copy link
Collaborator

Not sure what's different. I definitely don't have playwright installed globally (which playwright returns nothing), and it is in the relevant nox env:

$ ll .nox/a11y/bin/playwright 
-rwxrwxr-x 1 drmccloy drmccloy 247 Apr 12 15:41 .nox/a11y/bin/playwright*

@trallard
Copy link
Collaborator

The mix-and-match of stb versus sphinx-build, calling pytest or sphinx-build or stb directly vs calling the nox job... it all has my head spinning; currently we don't use nox in our CI config (except for the "compile MO files" step of the run-pytest job? why??)

Probably this deserves its own issue for discussion

I am really confused about this mix as well. So I'd be +1 on moving this to a separate discussion in the interest of standardisation

we need to implement the new a11y CI test somehow

@gabalafou and I are meeting today so will make sure to discuss this PR and come up with a "good enough" approach to get this moving

@drammock
Copy link
Collaborator

@gabalafou and I are meeting today so will make sure to discuss this PR and come up with a "good enough" approach to get this moving

excellent. I'll open a new issue about untangling the mix for the whole project.

noxfile.py Outdated Show resolved Hide resolved
]
test = ["pytest", "pytest-cov", "pytest-regressions"]
dev = ["pyyaml", "pre-commit", "nox", "pydata-sphinx-theme[doc,test]"]
a11y = ["pytest-playwright"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this to a separate env - since it is not needed for the general tests

process.wait()


@pytest.mark.a11y
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided register this as a custom mark instead of using the -k pytest flag for string matching

tests/test_a11y.py Outdated Show resolved Hide resolved
@trallard
Copy link
Collaborator

@drammock and @gabalafou - I just pushed some changes that should fix the issue with missing dependencies.
I tested locally by running.

nox -s test

nox -s a11y

And all runs as expected. I also made changes to address the concerns re having separate sessions and as long as the CI is happy I suppose we can call this our first iteration and improve on top of this

Comment on lines +100 to +104
if os.environ.get("CI") or os.environ.get("GITPOD_WORKSPACE_ID"):
# CI and other cloud environments are potentially missing system
# dependencies, so we tell Playwright to also install the system
# dependencies
session.run("playwright", "install", "--with-deps")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had initially removed this until I had to update the CI tests and realised I duplicated a lot of code trying to use pytest directly like in other tests.
So, for now, I am leaving this here and calling tests through nox.

Note: I am unsure if we should keep the GITPOD_WORKSPACE_ID bit. I am a Gitpod user, but I wonder if it will confuse the rest of the folks who do not use Gitpod.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't heard of Gitpod, but I wasn't confused :) I figured "probably some containerized thing" (I've since looked it up).

@trallard
Copy link
Collaborator

🎉 Tests are running in CI and can be run locally with nox.

I will wait for @drammock to give this a last check but I think this can be merged and we can iterate on reporting and the such from here onwards

Copy link
Collaborator

@drammock drammock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one tiny typo that I'll commit through the web interface, then let's merge. Thanks @gabalafou and @trallard !!

Comment on lines +73 to +86
@pytest.mark.parametrize(
"url_page,selector",
[
("admonitions.html", "#admonitions"),
("api.html", "#api-documentation"),
("blocks.html", "#blocks"),
("generic.html", "#generic-items"),
("images.html", "#images-figures"),
("lists.html", "#lists"),
("structure.html", "#structural-elements"),
("structure.html", "#structural-elements-2"),
("tables.html", "#tables"),
("typography.html", "#typography"),
],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😍

Comment on lines +100 to +104
if os.environ.get("CI") or os.environ.get("GITPOD_WORKSPACE_ID"):
# CI and other cloud environments are potentially missing system
# dependencies, so we tell Playwright to also install the system
# dependencies
session.run("playwright", "install", "--with-deps")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hadn't heard of Gitpod, but I wasn't confused :) I figured "probably some containerized thing" (I've since looked it up).

tests/test_a11y.py Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tag: accessibility Issues related to accessibility issues or efforts
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ENH - Improvements to automated accessibility tests
5 participants