Skip to content

ci(docs): run docs/app tests in CI and guard Upload from being evaluated#6551

Open
adhami3310 wants to merge 13 commits into
mainfrom
khaleel/docs-tests-in-ci
Open

ci(docs): run docs/app tests in CI and guard Upload from being evaluated#6551
adhami3310 wants to merge 13 commits into
mainfrom
khaleel/docs-tests-in-ci

Conversation

@adhami3310
Copy link
Copy Markdown
Member

Summary

  • Add docs_tests workflow that runs pytest tests/ in docs/app on changes to docs/**, the upload component, or the workflow itself — docs tests previously ran in nobody's CI.
  • Add tests/test_upload_not_evaluated.py: a single subprocess-based test that imports reflex_docs.pages cold and asserts Upload.is_used is still False. Catches rx.upload(...) calls leaking into an executed markdown block (python exec / python demo / python demo exec / python eval) or a frontmatter preview lambda.
  • Fix the regression that check surfaced: the Upload: preview lambda in docs/library/forms/upload.md frontmatter was being eval'd at route-build time, instantiating an upload component and forcing the docs site to register the upload HTTP endpoint. Removing the lambda falls through to the non-interactive fragment fallback in component.py:540-541, so no Upload is constructed during build.
  • Drive-by cleanup of dead test scaffolding and a rotted monkeypatch (details below).

Why this matters

Upload.is_used flips to True the moment rx.upload(...) / rx.upload.root(...) is constructed. The reflex app reads that flag (and an on-disk marker it writes) to decide whether to register the /_upload endpoint. The docs site never needs uploads, so any code path that builds an Upload component during compilation is a bug that leaves the docs site serving an unused endpoint.

Drive-by cleanup

  • docs/app/tests/test_agent_files.py: 5 monkeypatch.setattr calls targeted reflex_base.config.get_config, but agent_files._plugin does from reflex_base.config import get_config at module load, so the local name was never being patched. Repointed to agent_files._plugin.get_config. Three tests had silently rotted because docs/app tests didn't run in CI.
  • Deleted docs/app/tests/conftest.py (Playwright fixtures + video-recording hook, used by no test), docs/app/tests/utils.py (helper imported by no test), and the orphan docs/app/tests/assets/chakra_color_mode_provider.js.

Test plan

  • cd docs/app && uv run pytest tests/ passes locally (315 passed, 1 skipped).
  • cd docs/app && uv run pytest tests/test_upload_not_evaluated.py passes.
  • Reverting the upload.md frontmatter change makes test_upload_not_evaluated fail with the expected message.
  • CI docs tests workflow runs and goes green on this PR.
  • Visual check: confirm the library/forms/upload docs page still renders correctly without the Upload: preview lambda (the auto-generated preview box for the Upload component will fall back to an empty fragment).

Adds a docs_tests workflow that runs `pytest tests/` in docs/app on
changes to docs/**, plus a new test that loads `reflex_docs.pages` in a
subprocess and asserts `Upload.is_used` stayed False — catches
regressions where an `rx.upload(...)` call sneaks into an executed
markdown block or a frontmatter preview lambda.

Fixes the one regression the new check surfaced: the `Upload:` preview
lambda in `library/forms/upload.md` frontmatter was being eval'd at
route-build time, instantiating an upload component and forcing the
docs site to mount the upload endpoint. Removing the lambda falls
through to the non-interactive fragment fallback in
`component.py:540-541`, so no Upload is constructed.

Side cleanup along the way:

- `test_agent_files.py` monkeypatched `reflex_base.config.get_config`,
  but `agent_files._plugin` does `from reflex_base.config import
  get_config` at module load. Patch `agent_files._plugin.get_config`
  instead — 3 tests had silently rotted because docs/app tests never
  ran in CI.
- Delete unused docs/app/tests/conftest.py (Playwright fixtures + video
  hook used by no test), utils.py (helper imported by no test), and
  the orphan tests/assets/chakra_color_mode_provider.js asset.
@adhami3310 adhami3310 requested review from a team and Alek99 as code owners May 21, 2026 17:46
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented May 21, 2026

Greptile Summary

This PR adds a docs_tests CI workflow that runs pytest tests/ in docs/app and introduces a subprocess-based regression test (test_upload_not_evaluated.py) that guards against Upload.is_used being flipped during docs compilation. It also fixes the root cause: a components: frontmatter preview lambda in upload.md that was constructing an rx.upload(...) at route-build time.

  • New CI workflow (docs_tests.yml): triggers on changes to docs/**, the upload component source, or the workflow itself; uses the shared setup_build_env action and runs uv run --no-sync pytest tests/ -v from ./docs/app.
  • Regression test (test_upload_not_evaluated.py): spawns a fresh subprocess, imports reflex_docs.pages, and asserts Upload.is_used is still False; correctly isolated from in-process module caching.
  • Monkeypatch fix (test_agent_files.py): repoints 5 monkeypatch.setattr calls from the never-patched reflex_base.config.get_config to the correctly-scoped agent_files._plugin.get_config, unblocking three silently-rotted tests.
  • Docs fix (upload.md): removes the Upload: preview lambda and demotes rx.upload.root demo block to a plain fenced block, eliminating the source of the leaking Upload instantiation.
  • Dead code removal: deletes orphaned conftest.py (Playwright fixtures), utils.py, and chakra_color_mode_provider.js.

Confidence Score: 4/5

Safe to merge; changes are well-scoped to CI infrastructure, test correctness, and a docs-build regression fix.

The core regression fix (removing the Upload preview lambda) and the monkeypatch corrections are straightforward and low-risk. The new subprocess test is solid in design but omits a timeout parameter on subprocess.run — if import reflex_docs.pages ever hangs, the test silently blocks until the 20-minute job limit rather than failing quickly with a clear message.

docs/app/tests/test_upload_not_evaluated.py — the missing subprocess timeout is worth addressing before this lands.

Important Files Changed

Filename Overview
.github/workflows/docs_tests.yml New CI workflow that runs docs pytest suite on changes to docs/**, the upload component, or the workflow itself; correctly pins permissions, uses the shared build env action, and sets a 20-minute job timeout.
docs/app/tests/test_upload_not_evaluated.py New subprocess-based regression test that verifies importing reflex_docs.pages does not flip Upload.is_used; missing timeout on subprocess.run means a hung import blocks the CI job for up to 20 minutes.
docs/app/tests/test_agent_files.py Fixed 5 monkeypatch targets from the never-patched reflex_base.config.get_config to the correctly-scoped agent_files._plugin.get_config, unblocking three silently-rotted tests.
docs/library/forms/upload.md Removed the Upload: preview lambda that was eval'd at route-build time (causing Upload.is_used to flip) and demoted the rx.upload.root demo to a plain fenced block; both changes are intentional and correct.
docs/app/tests/conftest.py Deleted; was Playwright fixtures + video-recording hook used by no test.
docs/app/tests/utils.py Deleted; was a helper imported by no test.
docs/app/tests/assets/chakra_color_mode_provider.js Deleted orphan JS asset used by no test.

Reviews (1): Last reviewed commit: "ci(docs): run docs/app tests in CI and g..." | Re-trigger Greptile

Comment thread docs/app/tests/test_upload_not_evaluated.py Outdated
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 21, 2026

Merging this PR will not alter performance

✅ 24 untouched benchmarks


Comparing khaleel/docs-tests-in-ci (a2069be) with main (6bb44d5)

Open in CodSpeed

adhami3310 added 12 commits May 21, 2026 11:01
Match marketing/tests/test_routes.py: import the routes module via a
pytest fixture, then assert `Upload.is_used` stayed False. No subprocess
plumbing — the assertion sees the current flag, which reflects whether
*any* code path constructed an Upload component during compilation, so
the check works regardless of test order.
- test_breadcrumbs, test_docgen_double_eval, test_routes: imports
  resolve through the workspace venv (`reflex_docs` is installed as a
  workspace member), so `sys.path.append('docs/app')` was redundant.
- test_doc_links: `check_doc_links` is a bare script at
  docs/app/scripts/, not a package. Load it via `importlib.util` from
  its file path instead of poking sys.path.
`docs/app/scripts/check_doc_links.py` was a bare script that
test_doc_links.py could only import via sys.path or importlib.util
gymnastics. Move it into the installed `reflex_docs` package so the
test (and anyone else) can `from reflex_docs.scripts.check_doc_links
import ...` directly.

- Move the file to `docs/app/reflex_docs/scripts/check_doc_links.py`
  with an `__init__.py` so it's a proper package.
- Update the default `--md-root` / `--sitemap` paths since the script
  is two directories deeper now.
- Switch the integration workflow to `python -m
  reflex_docs.scripts.check_doc_links`.
- Drop the importlib spec/loader block from test_doc_links.py in
  favour of a normal import.
…from pytest

The script's only consumer was a workflow step; nothing ran it
interactively. Strip `main()` + the argparse/sys imports and keep the
module as a library only. Add
`test_docs_links_against_exported_sitemap` to test_doc_links.py: it
calls `check()` against the real docs root and the exported sitemap,
and `pytest.skip`s when `.web/public/sitemap.xml` is absent so
`pytest tests/` still passes without a build. Switch the integration
workflow step to `uv run pytest tests/test_doc_links.py`.
Wire the link-check pytest into the `reflex-docs` job in the root
integration_tests workflow: the existing prod-mode integration.sh
already builds the site (populating .web/public/sitemap.xml), so a
follow-up `pytest tests/test_doc_links.py` runs against a real sitemap
instead of skipping.

Also delete docs/app/.github/workflows/integration_tests.yml. That
file was a leftover from when docs/app shipped as its own repository —
GitHub Actions only reads .github/workflows/ at the repo root, so the
file (and its sibling codespell.yml/pre-commit.yml/unit_tests.yml) has
never run in this monorepo. The /docs link validation it described is
now hosted by the active workflow above.
Skipping the link test is fine for `pytest tests/` on a dev machine
that hasn't run an export, but in CI a missing sitemap means the
workflow forgot to build the docs — silently skipping there hides a
broken pipeline. Promote the skip to `pytest.fail` when the `CI` env
var is set (GitHub Actions, GitLab, CircleCI, etc. all set it).
Use a pytest primitive instead of the env-var branching: mark the
end-to-end link test xfail (run=False) when sitemap.xml is absent, and
pass --runxfail in the CI step. Locally `pytest tests/` still no-ops
the test when the docs haven't been built; in CI --runxfail neuters
the marker so a missing sitemap surfaces as a real failure instead of
a silent skip.
The link checker's only consumer is its own test file; a dedicated
module under reflex_docs.scripts was extra indirection for no benefit.
Inline the helpers (`_normalize`, `_walk_blocks`, `check`, etc.) at
the top of tests/test_doc_links.py and delete
docs/app/reflex_docs/scripts/ entirely.
`uv sync` was running from the repo root, which doesn't install the
docs/app workspace member (it isn't listed in the root
`[tool.uv.sources]`), leaving `agent_files` off sys.path and breaking
test collection in docs_tests.yml. Add a `working-directory` input to
the action so callers can point uv at the right workspace project, and
set it to `./docs/app` in docs_tests.yml.
router_attributes.md linked to `/docs/pages/dynamic_routing` in two
places. The source file is `docs/pages/dynamic_routing.md` but the
served URL is `/docs/pages/dynamic-routing/` (docgen rewrites
underscores to hyphens). Switch the links to the hyphenated form so
they resolve.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant