Skip to content

Commit 6bd2b80

Browse files
authored
Add Github Actions for testing major Sphinx versions (#62)
* test builds * fix typos * fix sphinx versions * remove Python 3.8 * install `breathe` * try installing piccolo_theme * try installing wheel * try `setup.py install` * try with python * only use breathe on Sphinx < 7 * remove query param from css file * only show breathe docs on Sphinx < 7 * bump sphinx version used in docs * try running playwright in CI * use more recent GitHub actions
1 parent f2bca91 commit 6bd2b80

File tree

13 files changed

+205
-39
lines changed

13 files changed

+205
-39
lines changed

.github/workflows/tests.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
name: Test Suite
2+
3+
on:
4+
push:
5+
branches: ["master"]
6+
pull_request:
7+
branches: ["master"]
8+
9+
jobs:
10+
test_sphinx:
11+
runs-on: ubuntu-latest
12+
strategy:
13+
matrix:
14+
python-version: ["3.9", "3.10", "3.11"]
15+
sphinx-version: ["7.2.2", "6.2.1", "5.3.0"]
16+
17+
steps:
18+
- uses: actions/checkout@v3
19+
- name: Set up Python ${{ matrix.python-version }}
20+
uses: actions/setup-python@v4
21+
with:
22+
python-version: ${{ matrix.python-version }}
23+
- name: Install Sphinx ${{ matrix.sphinx-version }}
24+
run: |
25+
python -m pip install --upgrade pip
26+
pip install Sphinx==${{ matrix.sphinx-version }}
27+
- name: Install breathe
28+
run: pip install breathe==4.35.0
29+
- name: Install wheel
30+
run: pip install wheel
31+
- name: Install piccolo_theme
32+
run: python setup.py install
33+
- name: Build docs
34+
run: make html
35+
working-directory: ./docs
36+
- name: "Setup Node"
37+
uses: actions/setup-node@v3
38+
with:
39+
node-version: 18
40+
- name: Install Playwright
41+
run: pip install -r requirements/e2e-requirements.txt
42+
- name: Ensure Chromium is installed
43+
run: python -m playwright install chromium --with-deps
44+
- name: Start Playwright tests
45+
run: ./scripts/run-e2e-tests.sh
46+
- uses: actions/upload-artifact@v3
47+
with:
48+
name: playwright-artifacts
49+
path: videos/
50+
if: always()

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ dist/
55
piccolo_theme.egg-info/
66
build/
77
docs/_build/
8+
videos/

docs/src/conf.py

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
import datetime
1414
import os
1515
import sys
16+
17+
import sphinx
18+
1619
sys.path.insert(0, os.path.abspath('../..'))
1720

1821

@@ -31,7 +34,6 @@
3134
# ones.
3235
extensions = [
3336
'sphinx.ext.autodoc',
34-
'breathe'
3537
]
3638

3739
# Add any paths that contain templates here, relative to this directory.
@@ -72,14 +74,25 @@
7274
# so a file named "default.css" will overwrite the builtin "default.css".
7375
html_static_path = []
7476

75-
breathe_projects = {
76-
"cpp_demo": "./cpp_breathe_demo",
77-
"c_demo": "./c_breathe_demo"
78-
}
79-
breathe_default_project = "cpp_demo"
80-
breathe_domain_by_extension = {
81-
"h": "c",
82-
"c": "c",
83-
"hpp": "cpp",
84-
"cpp": "cpp"
85-
}
77+
if sphinx.version_info[0] < 7:
78+
# Breathe only works on certain Sphinx versions.
79+
80+
extensions.append('breathe')
81+
82+
breathe_projects = {
83+
"cpp_demo": "./cpp_breathe_demo",
84+
"c_demo": "./c_breathe_demo"
85+
}
86+
breathe_default_project = "cpp_demo"
87+
breathe_domain_by_extension = {
88+
"h": "c",
89+
"c": "c",
90+
"hpp": "cpp",
91+
"cpp": "cpp"
92+
}
93+
94+
# By using tags, we can exclude the breathe examples from the docs using
95+
# the ``only`` directive.
96+
tags.add('include_breathe') # noqa # type: ignore
97+
else:
98+
tags.add('exclude_breathe') # noqa # type: ignore

docs/src/demo.rst

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,19 @@ Autodoc
1717
Breathe
1818
-------
1919

20-
.. doxygenclass:: CppClass
21-
:members:
20+
.. only:: include_breathe
2221

23-
.. doxygenfunction:: cpp_function
22+
.. doxygenclass:: CppClass
23+
:members:
2424

25-
.. doxygenfunction:: c_function
26-
:project: c_demo
25+
.. doxygenfunction:: cpp_function
26+
27+
.. doxygenfunction:: c_function
28+
:project: c_demo
29+
30+
.. only:: exclude_breathe
31+
32+
We can't demo Breathe on this version of Sphinx.
2733

2834
-------------------------------------------------------------------------------
2935

e2e/README.rst

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
e2e tests
2+
=========
3+
4+
We use Playwright to make sure the theme works on multiple versions of Sphinx.
5+
6+
It is run automatically in GitHub Actions.
7+
8+
To run it locally:
9+
10+
.. code-block:: bash
11+
12+
pip install -r requirements/e2e-requirements.txt
13+
playwright install chromium
14+
15+
Make sure the local docs have been built, as this is what we test against:
16+
17+
.. code-block:: bash
18+
19+
cd docs
20+
make html
21+
22+
Then from the root of the project, run the Playwright tests:
23+
24+
.. code-block:: bash
25+
26+
./scripts/run-e2e-tests.sh
27+
28+
You can see the tests run in the browser using the ``--headed`` flag:
29+
30+
.. code-block:: bash
31+
32+
./scripts/run-e2e-tests.sh --headed

e2e/conftest.py

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import os
2+
import time
3+
from http.client import HTTPConnection
4+
from subprocess import PIPE, Popen
5+
6+
import pytest
7+
8+
9+
HOST = "localhost"
10+
PORT = 8000
11+
BASE_URL = f"http://{HOST}:{PORT}"
12+
DOCS_DIRECTORY = os.path.join(
13+
os.path.dirname(os.path.dirname(__file__)), "docs", "build", "html"
14+
)
15+
16+
17+
@pytest.fixture
18+
def browser_context_args():
19+
return {"record_video_dir": "videos/"}
20+
21+
22+
@pytest.fixture
23+
def context(context):
24+
# We don't need a really long timeout.
25+
# The timeout determins how long Playwright waits for a HTML element to
26+
# become available.
27+
# By default it's 30 seconds, which is way too long when testing an app
28+
# locally.
29+
context.set_default_timeout(5000)
30+
yield context
31+
32+
33+
@pytest.fixture(autouse=True)
34+
def dev_server():
35+
"""
36+
Running dev server and Playwright test in parallel.
37+
More info https://til.simonwillison.net/pytest/playwright-pytest
38+
"""
39+
process = Popen(
40+
[
41+
"python3",
42+
"-m",
43+
"http.server",
44+
"--bind",
45+
str(HOST),
46+
"--directory",
47+
DOCS_DIRECTORY,
48+
str(PORT),
49+
],
50+
stdout=PIPE,
51+
)
52+
retries = 5
53+
while retries > 0:
54+
conn = HTTPConnection(f"{HOST}:{PORT}")
55+
try:
56+
conn.request("HEAD", "/")
57+
response = conn.getresponse()
58+
if response is not None:
59+
yield process
60+
break
61+
except ConnectionRefusedError:
62+
time.sleep(1)
63+
retries -= 1
64+
65+
if not retries:
66+
raise RuntimeError("Failed to start http server")
67+
else:
68+
process.terminate()
69+
process.wait()

e2e/test_homepage.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import re
2+
23
from playwright.sync_api import Page, expect
34

5+
from conftest import BASE_URL
6+
47

58
def test_homepage(page: Page):
6-
page.goto("http://localhost:8000/")
9+
page.goto(BASE_URL)
710
# Expect a title "to contain" a substring.
811
expect(page).to_have_title(re.compile("Piccolo Theme"))
912

@@ -18,28 +21,28 @@ def test_homepage(page: Page):
1821
'https://github.com/piccolo-orm/piccolo_theme/'))
1922

2023
# Dark Mode
21-
page.goto("http://localhost:8000/")
24+
page.goto(BASE_URL)
2225
expect(page.locator('html')).to_have_attribute("data-mode", "light")
2326
page.locator("#mode_toggle").click()
2427
expect(page.locator('html')).to_have_attribute("data-mode", "dark")
2528
page.locator("#mode_toggle").click()
2629
expect(page.locator('html')).to_have_attribute("data-mode", "darkest")
2730

2831
# Search for Configuration
29-
page.goto("http://localhost:8000/")
32+
page.goto(BASE_URL)
3033
page.locator(
3134
'//*[@id="searchbox"]/div/form/input[1]').fill("Configuration")
3235
page.locator('//*[@id="searchbox"]/div/form/input[2]').click()
3336
expect(page).to_have_title(re.compile("Search"))
3437

3538
# Check external Sphinx Link
36-
page.goto("http://localhost:8000/")
39+
page.goto(BASE_URL)
3740
link = page.locator('//*[@id="piccolo-theme"]/p/a')
3841
expect(link).to_have_text("Sphinx")
3942
expect(link).to_have_attribute(
4043
"href", "https://www.sphinx-doc.org/en/master/")
4144

4245
# Link Check Setup
43-
page.goto("http://localhost:8000/")
46+
page.goto(BASE_URL)
4447
page.locator('//*[@id="piccolo-theme"]/div/ul/li[1]/a').click()
4548
expect(page).to_have_title(re.compile("Setup"))

piccolo_theme/theme.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[theme]
22
inherit = basic
3-
stylesheet = basic_mod.css?v=0.7.0-1
3+
stylesheet = basic_mod.css
44
pygments_style = default
55
sidebars = globaltoc.html
66

requirements/doc-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
Sphinx==6.1.3
1+
Sphinx==6.2.1
22
sphinx-autobuild==2021.3.14
33
breathe==4.35.0

requirements/e2e-requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
pytest==7.4.0
2+
pytest-playwright==0.4.2

0 commit comments

Comments
 (0)