From 560c4e5628e18eda32ec9d719275b44a83638e1a Mon Sep 17 00:00:00 2001 From: Eric Arellano <14852634+Eric-Arellano@users.noreply.github.com> Date: Tue, 5 Dec 2023 12:15:39 -0500 Subject: [PATCH] Remove `qiskit` theme --- .github/workflows/main.yml | 16 +++---- CONTRIBUTING.md | 42 +++++++----------- Dockerfile | 4 +- README.md | 12 ++--- example_docs/docs/conf.py | 7 +-- package.json | 9 ++-- playwright.config.js | 17 ++----- pyproject.toml | 1 - src/qiskit_sphinx_theme/__init__.py | 1 - tests/js/{Dockerfile.base => Dockerfile} | 8 ++-- tests/js/Dockerfile.ecosystem | 16 ------- tests/js/Dockerfile.qiskit | 16 ------- tests/js/ecosystem.test.js | 20 --------- ...eft-side-bar-renders-correctly-1-linux.png | Bin 36776 -> 0 bytes tests/js/run_docker.py | 27 ++++++----- tests/js/{qiskit.test.js => tests.js} | 2 +- .../Jupyter-works-with-copybutton-1-linux.png | Bin ...esign-elements-have-no-shadows-1-linux.png | Bin .../admonitions-use-Carbon-style-1-linux.png | Bin .../api-docs-class-page-1-linux.png | Bin .../api-docs-function-page-1-linux.png | Bin .../api-docs-module-page-1-linux.png | Bin .../custom-directives-1-linux.png | Bin .../custom-directives-2-linux.png | Bin .../custom-directives-3-linux.png | Bin .../custom-directives-4-linux.png | Bin ...deprecations-look-like-warning-1-linux.png | Bin ...of-contents-have-correct-fonts-1-linux.png | Bin ...evious-releases-are-expandable-1-linux.png | Bin ...eft-side-bar-renders-correctly-1-linux.png | Bin ...ar-translations-are-expandable-1-linux.png | Bin ...-not-broken-by-our-page-layout-1-linux.png | Bin .../tables-align-with-qiskit-1-linux.png} | Bin ...ar-uses-custom-icons-on-mobile-1-linux.png | Bin ...custom-page-ToC-icon-on-tablet-1-linux.png | Bin ...ials-do-not-have-purple-border-1-linux.png | Bin tox.ini | 9 +--- 37 files changed, 57 insertions(+), 150 deletions(-) rename tests/js/{Dockerfile.base => Dockerfile} (83%) delete mode 100644 tests/js/Dockerfile.ecosystem delete mode 100644 tests/js/Dockerfile.qiskit delete mode 100644 tests/js/ecosystem.test.js delete mode 100644 tests/js/ecosystem.test.js-snapshots/left-side-bar-renders-correctly-1-linux.png rename tests/js/{qiskit.test.js => tests.js} (98%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/Jupyter-works-with-copybutton-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/Sphinx-Design-elements-have-no-shadows-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/admonitions-use-Carbon-style-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/api-docs-class-page-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/api-docs-function-page-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/api-docs-module-page-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/custom-directives-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/custom-directives-2-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/custom-directives-3-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/custom-directives-4-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/deprecations-look-like-warning-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/inline-table-of-contents-have-correct-fonts-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/left-side-bar-previous-releases-are-expandable-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/left-side-bar-renders-correctly-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/left-side-bar-translations-are-expandable-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/right-side-bar-is-not-broken-by-our-page-layout-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots/tables-align-with-qiskit-org-1-linux.png => tests.js-snapshots/tables-align-with-qiskit-1-linux.png} (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/top-nav-bar-uses-custom-icons-on-mobile-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/top-nav-bar-uses-custom-page-ToC-icon-on-tablet-1-linux.png (100%) rename tests/js/{qiskit.test.js-snapshots => tests.js-snapshots}/tutorials-do-not-have-purple-border-1-linux.png (100%) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 91df3e6b..14728087 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -6,7 +6,7 @@ jobs: runs-on: ubuntu-latest if: github.repository_owner == 'Qiskit' container: - # Keep in sync with tests/js/Dockerfile.base's base image. + # Keep in sync with tests/js/Dockerfile's base image. image: mcr.microsoft.com/playwright:v1.34.0-jammy steps: - uses: actions/checkout@v3 @@ -36,16 +36,11 @@ jobs: - name: Create artifacts/ folder run: mkdir artifacts - - name: Build Qiskit (Furo) theme - run: | - tox run -e qiskit - tar -zcvf qiskit_html_docs.tar.gz example_docs/docs/_qiskit_build - mv qiskit_html_docs.tar.gz artifacts/. - name: Build Ecosystem theme run: | - tox run -e ecosystem - tar -zcvf ecosystem_html_docs.tar.gz example_docs/docs/_ecosystem_build - mv ecosystem_html_docs.tar.gz artifacts/. + tox run -e docs + tar -zcvf html_docs.tar.gz example_docs/docs/_build + mv html_docs.tar.gz artifacts/. - name: Upload Sphinx builds uses: actions/upload-artifact@v3 if: always() @@ -55,8 +50,7 @@ jobs: - name: Run visual regression tests run: | - npm run _run-qiskit-tests - npm run _run-ecosystem-tests + npm run _run-tests - name: Upload snapshot results if: failure() uses: actions/upload-artifact@v3 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 694aab6a..cb339b7c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,6 @@ # Contributing -First read the overall Qiskit project contributing guidelines. These are all -included in the qiskit documentation: - -https://qiskit.org/documentation/contributing_to_qiskit.html +First read the overall [Qiskit project contributing guidelines](https://github.com/Qiskit/qiskit/blob/main/CONTRIBUTING.md#). ## Contributing to qiskit_sphinx_theme @@ -16,18 +13,17 @@ contributing to qiskit_sphinx_theme, these are documented below. There are a few important subfolders to be aware of: ### `/src` -This subfolder contains the HTML, CSS, and Python files that are used for the Qiskit themes. It has these folders: +This subfolder contains the HTML, CSS, and Python files that are used for the `qiskit-ecosystem` theme. It has these folders: -* `assets`: CSS and JavaScript for the `qiskit` theme. -* `ecosystem`: the code for the `qiskit-ecosystem` theme, which is built on top of the base `qiskit` theme. This folder only has overrides. -* `theme`: static files, like HTML templates, for the `qiskit` theme. +* `assets`: CSS +* `theme`: HTML templates and the `theme.conf` config file The top-level Python files are used for logic used by the theme, such as `translations.py` determining what URLs the HTML should use for translations support. ### `/example_docs` This subfolder contains a scaled down version of the Sphinx build that builds the documentation for the Qiskit repos. -It pulls styles from the `/src` subfolder. You can check any changes you are making to theme by building the documentation (see running locally section) and opening the HTML files generated in `example_docs/docs/_qiskit_build` and `example_docs/docs/_ecosystem_build`. +It pulls styles from the `/src` subfolder. You can check any changes you are making to theme by building the documentation (see running locally section) and opening the HTML files generated in `example_docs/docs/_build`. ### `/docs_guide` This subfolder contains guidance on how to write documentation and build sphinx projects for Qiskit and Qiskit Ecosystem projects. You can view the fully rendered docs guide at https://qisk.it/docs-guide @@ -38,18 +34,15 @@ This subfolder contains guidance on how to write documentation and build sphinx We use [Tox](https://tox.wiki/en/latest/), which you will need to install globally (e.g. using [`pipx`](https://pypa.github.io/pipx/)). * Run Python tests: `tox -e py` -* Build `example_docs/` with the `qiskit` theme: - 1. `tox -e qiskit` - 2. Open up `example_docs/docs/_qiskit_build/index.html` in your browser -* Build `example_docs/` with the `qiskit-ecosystem` theme: - 1. `tox -e ecosystem` - 2. Open up `example_docs/docs/_ecosystem_build/index.html` in your browser +* Build `example_docs/`: + 1. `tox -e docs` + 2. Open up `example_docs/docs/_build/index.html` in your browser * Build `docs_guide`: 1. `tox -e docs-guide` 2. Open up `docs_guide/_build/html/index.html` in your browser. * Run doctests for the docs guide: `tox -e doctest` -Sometimes Sphinx's caching can get in a bad state. First, try running `tox -e clean`, which will remove Sphinx's cache. If you are still having issues, try adding `-r` your command, e.g. `tox -e qiskit -r`. `-r` tells Tox to reinstall the dependencies. +Sometimes Sphinx's caching can get in a bad state. First, try running `tox -e clean`, which will remove Sphinx's cache. If you are still having issues, try adding `-r` your command, e.g. `tox -e docs -r`. `-r` tells Tox to reinstall the dependencies. ------ ## Visual regression testing @@ -85,21 +78,21 @@ First, you need to install: Then, to run the tests locally: 1. `npm install` -2. `npm run test-qiskit` or `npm run test-ecosystem`, depending on which theme you want. +2. `npm run test`. * Warning: the very first time you run the tests, they will fail because the `snapshot-results` folder will not yet exist. Try running again. -The docs will rebuild every time you run `npm run test-qiskit` and `npm run test-ecosystem`. +The docs will rebuild every time you run `npm run test`. ### How to update the expected snapshot for intentional changes First, get the `snapshot_results` folder, either by downloading it from CI or by running the tests locally. Then: 1. Find the "actual" snapshot for the failing test, such as `api-docs-class-page-1-actual.png`. -2. Copy that snapshot into the folder `tests/js/qiskit.test.js-snapshots` or `tests/js/ecosystem.test.js-snapshots`, depending on which theme failed. Rename the `-actual.png` file ending to be `-linux.png` and overwrite the prior file. +2. Copy that snapshot into the folder `tests/js/tests.js-snapshots`. Rename the `-actual.png` file ending to be `-linux.png` and overwrite the prior file. ### How to add a new snapshot -Copy the tests in `qiskit.test.js` or `ecosystem.test.js` for inspiration. Make sure the selector you use in `page.locator()` is accurate. Title the tests with a useful but concise description of what you're testing. +Copy the tests in `tests.js` for inspiration. Make sure the selector you use in `page.locator()` is accurate. Title the tests with a useful but concise description of what you're testing. Then, run the tests either locally or in CI to generate the snapshots. When running locally, the files will be added automatically. When using CI, follow the section [How to update the expected snapshot for intentional changes](#how-to-update-the-expected-snapshot-for-intentional-changes). @@ -110,19 +103,16 @@ We upload the docs builds to CI. So, you can download what the site will look li 1. Navigate to the GitHub Actions page for the "Tests" action. 2. Open the "Summary" page with the house icon. -3. Under the "Artifacts" section, there should be a "html_docs" entry. Download it. -4. Choose the theme you want, such as `qiskit_html_docs.tar.gz`, and un-tar it. Then, open the `index.html` page in a browser. +3. Under the "Artifacts" section, there should be a "html_docs" entry. Download it. Un-tar it, then open the `index.html` page in a browswer. Contributors with write access can also use live previews of the docs: GitHub will deploy a website using your changes. To use live previews, push your branch to `upstream` rather than your fork. GitHub will leave a comment with the link to the site. Please prefix your branch name with your initials, e.g. `EA/add-translations`, for good Git hygiene. ------ ## FYI: How Furo Theme Inheritance Works -We use Sphinx's inheritance future for our Furo-based `qiskit` theme, which we set in `theme/qiskit-sphinx-theme/theme.conf`. Sphinx will default to using all the files from Furo. But if we have a file with the same name as Furo, then Sphinx will use our copy. That allows us to override only what we care about. - -We try to keep changes to a minimum because every divergence we make from base Furo increases our maintenance burden. Hence we prioritise only making changes that are important to the Qiskit brand. If the change would be generally useful to other users of Furo, we try to contribute upstream to the Furo project itself. +We use Sphinx's inheritance feature because our theme is built on top of [Furo](https://github.com/pradyunsg/furo). The `furo` inheritance is configured in `theme/qiskit-sphinx-theme/theme.conf`. Sphinx will default to using all the files from Furo. But if we have a file with the same name as Furo, then Sphinx will use our copy. That allows us to override only what we care about. -The `qiskit-ecosystem` theme then inherits the `qiskit` theme to make some tweaks, although we're removing the `qiskit` theme so the themes are converging. +We try to keep changes to a minimum because every divergence we make from base Furo increases our maintenance burden. Hence we prioritise only making changes that are important to the Qiskit Ecosystem brand. If the change would be generally useful to other users of Furo, we try to contribute upstream to the Furo project itself. ### How to change HTML Copy the HTML template from Furo and save it in the same file path. Then, at the top of the file, add this header: diff --git a/Dockerfile b/Dockerfile index cb69a776..0c814924 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,7 @@ WORKDIR /app COPY . . -RUN tox run -e qiskit +RUN tox run -e docs EXPOSE 8000 -CMD ["python", "-m", "http.server", "-d", "example_docs/docs/_qiskit_build"] +CMD ["python", "-m", "http.server", "-d", "example_docs/docs/_build"] diff --git a/README.md b/README.md index d3de9313..15ec289c 100644 --- a/README.md +++ b/README.md @@ -10,14 +10,14 @@ See [Migrate from old Pytorch theme to new theme](https://github.com/Qiskit/qisk ## Overview This repository hosts three things: -- Qiskit Sphinx themes (located in the `src/` folder) -- Example Docs (located in the `example_docs/` folder) +- `qiskit-ecosystem` theme (located in the `src/` folder) +- example docs (located in the `example_docs/` folder) - Qiskit Docs Guide (located in the `docs_guide/` folder) -The Qiskit Sphinx Themes are the themes used by Qiskit Documentation (https://qiskit.org/documentation/) and Qiskit Ecosystem projects. +The `qiskit-ecosystem` theme is used by projects in the [Qiskit Ecosystem](https://qiskit.github.io/ecosystem). -The Example Docs is a minimal Sphinx project that is used for testing the Qiskit Sphinx Theme. Every -pull request will trigger [a GitHub workflow](https://github.com/Qiskit/qiskit_sphinx_theme/blob/main/.github/workflows/main.yml) that builds the Example Docs to make sure the changes do +The example docs are a minimal Sphinx project that is used for testing the Qiskit Sphinx Theme. Every +pull request will trigger [a GitHub workflow](https://github.com/Qiskit/qiskit_sphinx_theme/blob/main/.github/workflows/main.yml) that builds the example docs to make sure the changes do not introduce unintended changes. The Qiskit Docs Guide hosts instructions, guidelines and recommendations of good documentation @@ -34,7 +34,7 @@ pip install qiskit-sphinx-theme Then, set up the theme by updating `conf.py`: -1. Set `html_theme = "qiskit-ecosystem"` (only Qiskit Terra should use `qiskit`) +1. Set `html_theme = "qiskit-ecosystem"` 2. Add `"qiskit_sphinx_theme"` to `extensions` You also likely want to set `html_title` in `conf.py`. This results in the left sidebar having a more useful and concise name, along with the page title in the browser. Most projects will want to use this in their `conf.py`: diff --git a/example_docs/docs/conf.py b/example_docs/docs/conf.py index ec452b7a..9f466940 100644 --- a/example_docs/docs/conf.py +++ b/example_docs/docs/conf.py @@ -22,6 +22,8 @@ language = "en" release = "9.99" +html_theme = "qiskit-ecosystem" + # This allows including custom CSS and HTML templates. html_static_path = ["_static"] templates_path = ["_templates"] @@ -58,11 +60,6 @@ # for interpolation, i.e. Sphinx doesn't have built-in interpolation. html_title = f"{project} {release}" -# This allows us to test both the Qiskit and Qiskit Ecosystem themes. In normal repositories, `html_theme` -# would be set to one specific theme. -_THEME = os.getenv("THEME", "qiskit") -html_theme = _THEME - html_context = { # Users of the theme can set prior version numbers. They'll # show up in the sidebar under the "Previous Versions" section. diff --git a/package.json b/package.json index 4e6f0021..423bb1f1 100644 --- a/package.json +++ b/package.json @@ -15,11 +15,8 @@ }, "scripts": { "build": "webpack", - "start-qiskit": "http-server example_docs/docs/_qiskit_build -p 8080", - "start-ecosystem": "http-server example_docs/docs/_ecosystem_build -p 8081", - "test-qiskit": "tests/js/run_docker.py qiskit", - "test-ecosystem": "tests/js/run_docker.py ecosystem", - "_run-qiskit-tests": "THEME=qiskit playwright test", - "_run-ecosystem-tests": "THEME=ecosystem playwright test" + "start": "http-server example_docs/docs/_build -p 8080", + "test": "tests/js/run_docker.py", + "_run-tests": "playwright test" } } diff --git a/playwright.config.js b/playwright.config.js index 83f33465..e22404a1 100644 --- a/playwright.config.js +++ b/playwright.config.js @@ -13,23 +13,12 @@ import { defineConfig } from "@playwright/test"; -let testMatch; -let baseURL; -let startCommand; -if (process.env.THEME === "qiskit") { - testMatch = /.*qiskit.test.js/; - baseURL = "http://127.0.0.1:8080"; - startCommand = "start-qiskit"; -} else { - testMatch = /.*ecosystem.test.js/; - baseURL = "http://127.0.0.1:8081"; - startCommand = "start-ecosystem"; -} +const baseURL = "http://127.0.0.1:8080" export default defineConfig({ outputDir: "snapshot_results", workers: process.env.CI ? 1 : undefined, - testMatch, + testMatch: /.*tests\.js$/, expect: { toHaveScreenshot: { threshold: 0.01, // We expect colors to be near exact matches. @@ -41,7 +30,7 @@ export default defineConfig({ viewport: { width: 1920, height: 1080 }, }, webServer: { - command: `npm run ${startCommand}`, + command: "npm run start", url: baseURL, }, }); diff --git a/pyproject.toml b/pyproject.toml index 4b1a1fc9..ea6c8b90 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -32,7 +32,6 @@ dependencies = [ ] [project.entry-points."sphinx.html_themes"] -qiskit = "qiskit_sphinx_theme" qiskit-ecosystem = "qiskit_sphinx_theme" [project.urls] diff --git a/src/qiskit_sphinx_theme/__init__.py b/src/qiskit_sphinx_theme/__init__.py index 6eae68fd..5849d42b 100644 --- a/src/qiskit_sphinx_theme/__init__.py +++ b/src/qiskit_sphinx_theme/__init__.py @@ -85,7 +85,6 @@ def setup(app: sphinx.application.Sphinx) -> dict[str, bool]: previous_releases.setup(app) translations.setup(app) - app.add_html_theme("qiskit", _get_theme_absolute_path("theme/qiskit-sphinx-theme")) app.add_html_theme("qiskit-ecosystem", _get_theme_absolute_path("theme/qiskit-sphinx-theme")) app.connect("config-inited", activate_furo) diff --git a/tests/js/Dockerfile.base b/tests/js/Dockerfile similarity index 83% rename from tests/js/Dockerfile.base rename to tests/js/Dockerfile index 4bbbcd0c..9d5f49ae 100644 --- a/tests/js/Dockerfile.base +++ b/tests/js/Dockerfile @@ -11,15 +11,12 @@ # that they have been altered from the originals. -# A base Dockerfile to run our snapshot tests locally. This is to avoid issues with CI and local +# This Dockerfile allows us to run our snapshot tests locally. That avoids issues with CI and local # differing. In CI, we also run with the same base image. # See https://playwright.dev/docs/test-snapshots. # # Note that we build the Sphinx docs outside of this Docker image; we only need to run the # server inside Docker so that the docs are rendered the same locally and in CI. -# -# Each specific theme extends this base image to copy in the built docs and run their specific -# project with Playwright. # Keep this base image in sync with .github/workflows/main.yml. @@ -33,3 +30,6 @@ RUN npm ci # Copy over our tests. COPY playwright.config.js ./ COPY tests/js tests/js + +COPY example_docs/docs/_build example_docs/docs/_build +CMD [ "npm", "run", "_run-tests" ] diff --git a/tests/js/Dockerfile.ecosystem b/tests/js/Dockerfile.ecosystem deleted file mode 100644 index 918cd266..00000000 --- a/tests/js/Dockerfile.ecosystem +++ /dev/null @@ -1,16 +0,0 @@ -# This code is a Qiskit project. -# -# (C) Copyright IBM 2023. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -FROM qiskit_sphinx_theme_base - -COPY example_docs/docs/_ecosystem_build example_docs/docs/_ecosystem_build -CMD [ "npm", "run", "_run-ecosystem-tests"] diff --git a/tests/js/Dockerfile.qiskit b/tests/js/Dockerfile.qiskit deleted file mode 100644 index b431c78b..00000000 --- a/tests/js/Dockerfile.qiskit +++ /dev/null @@ -1,16 +0,0 @@ -# This code is a Qiskit project. -# -# (C) Copyright IBM 2023. -# -# This code is licensed under the Apache License, Version 2.0. You may -# obtain a copy of this license in the LICENSE.txt file in the root directory -# of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. -# -# Any modifications or derivative works of this code must retain this -# copyright notice, and modified files need to carry a notice indicating -# that they have been altered from the originals. - -FROM qiskit_sphinx_theme_base - -COPY example_docs/docs/_qiskit_build example_docs/docs/_qiskit_build -CMD [ "npm", "run", "_run-qiskit-tests" ] diff --git a/tests/js/ecosystem.test.js b/tests/js/ecosystem.test.js deleted file mode 100644 index d6da30db..00000000 --- a/tests/js/ecosystem.test.js +++ /dev/null @@ -1,20 +0,0 @@ -/* This code is a Qiskit project. - * - * (C) Copyright IBM 2023. - * - * This code is licensed under the Apache License, Version 2.0. You may - * obtain a copy of this license in the LICENSE.txt file in the root directory - * of this source tree or at http://www.apache.org/licenses/LICENSE-2.0. - * - * Any modifications or derivative works of this code must retain this - * copyright notice, and modified files need to carry a notice indicating - * that they have been altered from the originals. - */ - -import { expect, test } from "@playwright/test"; - -test("left side bar renders correctly", async ({ page }) => { - await page.goto(""); - const leftToC = page.locator(".sidebar-drawer"); - await expect(leftToC).toHaveScreenshot(); -}); diff --git a/tests/js/ecosystem.test.js-snapshots/left-side-bar-renders-correctly-1-linux.png b/tests/js/ecosystem.test.js-snapshots/left-side-bar-renders-correctly-1-linux.png deleted file mode 100644 index 49a6b331ed100c1c8a3d5183d0da1388300626fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36776 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 W`t9=BE0ANsAE}4(4|2r~Uj84u{ckz| diff --git a/tests/js/run_docker.py b/tests/js/run_docker.py index f4feba9f..b3da1ce7 100755 --- a/tests/js/run_docker.py +++ b/tests/js/run_docker.py @@ -12,23 +12,24 @@ # that they have been altered from the originals. import subprocess -import sys from pathlib import Path +TAG = "qiskit-sphinx-theme-snapshots" -def build_image(tag: str, dockerfile: str) -> None: + +def build_image() -> None: subprocess.run( - ["docker", "build", "-t", tag, "-f", f"tests/js/{dockerfile}", "."], + ["docker", "build", "-t", TAG, "-f", f"tests/js/Dockerfile", "."], check=True, ) -def build_docs(theme: str) -> None: - subprocess.run(["tox", "-e", theme], check=True) +def build_docs() -> None: + subprocess.run(["tox", "-e", "docs"], check=True) -def run_image(theme: str) -> None: - snapshot_folder = Path.cwd() / "tests" / "js" / f"{theme}.test.js-snapshots" +def run_image() -> None: + snapshot_folder = Path.cwd() / "tests" / "js" / "tests.js-snapshots" subprocess.run( [ "docker", @@ -38,19 +39,17 @@ def run_image(theme: str) -> None: "-v", f"{Path.cwd() / 'snapshot_results'}:/snapshot_results", "-v", - f"{snapshot_folder}:/tests/js/{theme}.test.js-snapshots", - f"qiskit_sphinx_theme_{theme}", + f"{snapshot_folder}:/tests/js/tests.js-snapshots", + TAG, ], check=True, ) def main() -> None: - build_image("qiskit_sphinx_theme_base", "Dockerfile.base") - theme = sys.argv[1] - build_docs(theme) - build_image(f"qiskit_sphinx_theme_{theme}", f"Dockerfile.{theme}") - run_image(theme) + build_image() + build_docs() + run_image() if __name__ == "__main__": diff --git a/tests/js/qiskit.test.js b/tests/js/tests.js similarity index 98% rename from tests/js/qiskit.test.js rename to tests/js/tests.js index eb6c20cf..d07d0d6c 100644 --- a/tests/js/qiskit.test.js +++ b/tests/js/tests.js @@ -87,7 +87,7 @@ test.describe("api docs", () => { }); }); -test("tables align with qiskit.org", async ({ page }) => { +test("tables align with qiskit.", async ({ page }) => { await page.goto("sphinx_guide/tables.html"); const gridTablesSection = page.locator("section#grid-tables"); await expect(gridTablesSection).toHaveScreenshot(); diff --git a/tests/js/qiskit.test.js-snapshots/Jupyter-works-with-copybutton-1-linux.png b/tests/js/tests.js-snapshots/Jupyter-works-with-copybutton-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/Jupyter-works-with-copybutton-1-linux.png rename to tests/js/tests.js-snapshots/Jupyter-works-with-copybutton-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/Sphinx-Design-elements-have-no-shadows-1-linux.png b/tests/js/tests.js-snapshots/Sphinx-Design-elements-have-no-shadows-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/Sphinx-Design-elements-have-no-shadows-1-linux.png rename to tests/js/tests.js-snapshots/Sphinx-Design-elements-have-no-shadows-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/admonitions-use-Carbon-style-1-linux.png b/tests/js/tests.js-snapshots/admonitions-use-Carbon-style-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/admonitions-use-Carbon-style-1-linux.png rename to tests/js/tests.js-snapshots/admonitions-use-Carbon-style-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/api-docs-class-page-1-linux.png b/tests/js/tests.js-snapshots/api-docs-class-page-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/api-docs-class-page-1-linux.png rename to tests/js/tests.js-snapshots/api-docs-class-page-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/api-docs-function-page-1-linux.png b/tests/js/tests.js-snapshots/api-docs-function-page-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/api-docs-function-page-1-linux.png rename to tests/js/tests.js-snapshots/api-docs-function-page-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/api-docs-module-page-1-linux.png b/tests/js/tests.js-snapshots/api-docs-module-page-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/api-docs-module-page-1-linux.png rename to tests/js/tests.js-snapshots/api-docs-module-page-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/custom-directives-1-linux.png b/tests/js/tests.js-snapshots/custom-directives-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/custom-directives-1-linux.png rename to tests/js/tests.js-snapshots/custom-directives-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/custom-directives-2-linux.png b/tests/js/tests.js-snapshots/custom-directives-2-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/custom-directives-2-linux.png rename to tests/js/tests.js-snapshots/custom-directives-2-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/custom-directives-3-linux.png b/tests/js/tests.js-snapshots/custom-directives-3-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/custom-directives-3-linux.png rename to tests/js/tests.js-snapshots/custom-directives-3-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/custom-directives-4-linux.png b/tests/js/tests.js-snapshots/custom-directives-4-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/custom-directives-4-linux.png rename to tests/js/tests.js-snapshots/custom-directives-4-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/deprecations-look-like-warning-1-linux.png b/tests/js/tests.js-snapshots/deprecations-look-like-warning-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/deprecations-look-like-warning-1-linux.png rename to tests/js/tests.js-snapshots/deprecations-look-like-warning-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/inline-table-of-contents-have-correct-fonts-1-linux.png b/tests/js/tests.js-snapshots/inline-table-of-contents-have-correct-fonts-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/inline-table-of-contents-have-correct-fonts-1-linux.png rename to tests/js/tests.js-snapshots/inline-table-of-contents-have-correct-fonts-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/left-side-bar-previous-releases-are-expandable-1-linux.png b/tests/js/tests.js-snapshots/left-side-bar-previous-releases-are-expandable-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/left-side-bar-previous-releases-are-expandable-1-linux.png rename to tests/js/tests.js-snapshots/left-side-bar-previous-releases-are-expandable-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/left-side-bar-renders-correctly-1-linux.png b/tests/js/tests.js-snapshots/left-side-bar-renders-correctly-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/left-side-bar-renders-correctly-1-linux.png rename to tests/js/tests.js-snapshots/left-side-bar-renders-correctly-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/left-side-bar-translations-are-expandable-1-linux.png b/tests/js/tests.js-snapshots/left-side-bar-translations-are-expandable-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/left-side-bar-translations-are-expandable-1-linux.png rename to tests/js/tests.js-snapshots/left-side-bar-translations-are-expandable-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/right-side-bar-is-not-broken-by-our-page-layout-1-linux.png b/tests/js/tests.js-snapshots/right-side-bar-is-not-broken-by-our-page-layout-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/right-side-bar-is-not-broken-by-our-page-layout-1-linux.png rename to tests/js/tests.js-snapshots/right-side-bar-is-not-broken-by-our-page-layout-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/tables-align-with-qiskit-org-1-linux.png b/tests/js/tests.js-snapshots/tables-align-with-qiskit-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/tables-align-with-qiskit-org-1-linux.png rename to tests/js/tests.js-snapshots/tables-align-with-qiskit-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/top-nav-bar-uses-custom-icons-on-mobile-1-linux.png b/tests/js/tests.js-snapshots/top-nav-bar-uses-custom-icons-on-mobile-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/top-nav-bar-uses-custom-icons-on-mobile-1-linux.png rename to tests/js/tests.js-snapshots/top-nav-bar-uses-custom-icons-on-mobile-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/top-nav-bar-uses-custom-page-ToC-icon-on-tablet-1-linux.png b/tests/js/tests.js-snapshots/top-nav-bar-uses-custom-page-ToC-icon-on-tablet-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/top-nav-bar-uses-custom-page-ToC-icon-on-tablet-1-linux.png rename to tests/js/tests.js-snapshots/top-nav-bar-uses-custom-page-ToC-icon-on-tablet-1-linux.png diff --git a/tests/js/qiskit.test.js-snapshots/tutorials-do-not-have-purple-border-1-linux.png b/tests/js/tests.js-snapshots/tutorials-do-not-have-purple-border-1-linux.png similarity index 100% rename from tests/js/qiskit.test.js-snapshots/tutorials-do-not-have-purple-border-1-linux.png rename to tests/js/tests.js-snapshots/tutorials-do-not-have-purple-border-1-linux.png diff --git a/tox.ini b/tox.ini index 1c4f11dd..647c566a 100644 --- a/tox.ini +++ b/tox.ini @@ -10,14 +10,9 @@ commands = pytest allowlist_externals = rm -[testenv:qiskit] +[testenv:docs] commands = - sphinx-build -W --keep-going -j auto {posargs} example_docs/docs/ example_docs/docs/_qiskit_build - -[testenv:ecosystem] -commands = - sphinx-build -W --keep-going -j auto {posargs} example_docs/docs/ example_docs/docs/_ecosystem_build -setenv = THEME=qiskit-ecosystem + sphinx-build -W --keep-going -j auto {posargs} example_docs/docs/ example_docs/docs/_build [testenv:clean] skip_install = true