Skip to content

test: Cover bundled app templates with a smoke test - #2504

Open
karangattu wants to merge 14 commits into
mainfrom
run-better-templates-tests
Open

karangattu wants to merge 14 commits into
mainfrom
run-better-templates-tests

Conversation

@karangattu

@karangattu karangattu commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

shiny create copies shiny/templates/ verbatim. Nothing in CI ran these files. Five chat templates shipped a Chat(messages=...) call that raised on startup (#2488).

Change

This PR extends tests/playwright/examples/test_shiny_create.py with a parametrized test that launches every bundled template entrypoint (app.py, app-core.py, app-express.py, including the nested markdown-stream chat templates). template_entrypoints() discovers them from the same find_templates() helper that shiny create uses, and skips the app templates already covered by test_template_examples.

The apps run as real Shiny apps in a child process, so it needs a browser. No model server and no real API key.

A sitecustomize.py stub module keeps the provider classes inert. Python imports sitecustomize from PYTHONPATH before python -m shiny, so DummyChatClient replaces the chatlas provider constructors (and langchain_openai.ChatOpenAI when that package is absent) inside the app's own process. Any template that actually reaches a provider fails loudly. The Shiny side stays real, so ui.Chat still raises on messages= without history=.

validate_example() now takes an optional env that it forwards to run_shiny_app, which is how the stub path and the dummy provider keys reach the child process.

Result

The new test found three broken markdown-stream templates before this PR. Two missed the input import. One missed the Ollama model. This PR fixes all three.

Closes #2488.

karangattu and others added 14 commits September 23, 2026 13:48
Each template entrypoint now builds its App with dummy keys.
The run needs no browser and no model server.

The new guard also scans Chat calls for messages= without history=.
It covers templates and the bundled skill references.

The smoke test found three broken markdown-stream templates.
Two missed the input import. One missed the Ollama model.
This commit fixes all three.
Real provider constructors validate against servers and packages.
That validation changes across chatlas releases. Newer chatlas
queries the model server and requires provider packages at build
time. The test must not depend on that behavior.

Stub all provider classes. Keep the Shiny side real. ui.Chat
still raises on messages= without history=. The smoke test still
catches that startup failure.
The oldest-deps job pins shiny's own deps to their floors. Two
template deps break there for reasons outside this repo. python-dotenv
is absent, so app_utils.load_dotenv warns. The xarray floor no longer
imports under NumPy 2, which breaks import plotly.express.

Stub dotenv when it is missing. Skip a template when its traceback
shows it failed on its own import line. A failure on any other
template line is still a template bug and still fails.
Walk the exception cause chain when deciding if a template failed
on its own import line. Express wraps load errors in RuntimeError,
which hid the template frame.

Bump the shinychat floor to 0.6.0. The bundled chat templates pass
greeting= to ui.Chat, which older releases reject. The lock file
already pins 0.6.0.
A missing module skips only for an allowlisted optional dependency.
A typo'd helper name or a deleted sibling file fails instead.

A bad from-import fails even on an import line: the source resolved,
so the name is wrong. A helper that raises while loading (a missing
data file, for example) fails too. Only an error raised inside
third-party import code skips, with unit tests pinning each rule.
Drop the exception classifier. Any template-load failure now fails
the test, including wrapped Express errors. Skips hid real bugs.

Exempt this file in the oldest-deps job instead. Its version floors
cannot import the templates' plotting stack together. The exemption
lives in the workflow, not in the test.

Purge imported helper modules by file location. A future helper
name cannot leak state into the next template unnoticed.
The bundled chat templates pass greeting= to the ui.Chat
constructor. shinychat 0.4.0 only has greeting= on chat.ui().
The constructor form arrived in 0.5.0, so set that floor.
The smoke test is exempt there, so add a tiny compat test that keeps
running: build an express Chat with greeting=, bookmark it, register
a submit handler, render it. It fails if the shinychat floor ever
drops an API the templates rely on. No key is needed under a stub
session.

Also evict shadowed helper modules before each load, so a stale
cached copy cannot win over the template's own file.
Ensure calls using messages= explicitly specify history=False (as ast.Constant(value=False)), catching history=True, history=None, and omitted history. Add unit tests covering these cases.
@karangattu
karangattu requested a review from schloerke October 2, 2026 04:53

This branch has not been deployed

No deployments
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.

Templates aren't exercised by CI: 5 chat templates were broken for days

1 participant