119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
"""E2E: GitHub alert callouts render in the markdown rich-text editor.
|
|
|
|
Counterpart to ``test_markdown_rich_rendering.py`` (which covers headings,
|
|
lists, code blocks, tables, links and plain blockquotes): this pins the
|
|
GitHub-flavored *alert* construct — a blockquote whose first line is a
|
|
``[!NOTE]`` / ``[!TIP]`` / ``[!IMPORTANT]`` / ``[!WARNING]`` / ``[!CAUTION]``
|
|
marker. The ``GitHubAlertBlockquote`` TipTap extension turns those into
|
|
typed callouts carrying ``data-alert-type`` / ``data-alert-label`` attrs
|
|
(see ``TipTapGitHubAlert.ts``), distinct from a plain blockquote.
|
|
|
|
Seeded via the filesystem PUT endpoint (no agent run).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import shutil
|
|
from collections.abc import Iterator
|
|
from pathlib import Path
|
|
|
|
import httpx
|
|
import pytest
|
|
from playwright.sync_api import Page, expect
|
|
|
|
from tests.e2e_ui.conftest import switch_markdown_view_mode
|
|
|
|
_REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
_MARKDOWN_FILE_PATH = "alerts.md"
|
|
|
|
# One blockquote per GitHub alert type, plus a plain blockquote that must
|
|
# stay un-typed (no data-alert-type), so the test proves the marker — not
|
|
# blockquotes in general — is what produces the callout.
|
|
_MARKDOWN_CONTENT = """\
|
|
# Alert Gallery
|
|
|
|
> [!NOTE]
|
|
> Highlights information that users should take into account.
|
|
|
|
> [!TIP]
|
|
> Optional information to help a user be more successful.
|
|
|
|
> [!IMPORTANT]
|
|
> Crucial information necessary for users to succeed.
|
|
|
|
> [!WARNING]
|
|
> Critical content demanding immediate user attention.
|
|
|
|
> [!CAUTION]
|
|
> Negative potential consequences of an action.
|
|
|
|
> A plain blockquote with no alert marker.
|
|
"""
|
|
|
|
|
|
@pytest.fixture
|
|
def seeded_alerts_session(
|
|
seeded_session: tuple[str, str],
|
|
) -> Iterator[tuple[str, str]]:
|
|
base_url, session_id = seeded_session
|
|
resp = httpx.put(
|
|
f"{base_url}/v1/sessions/{session_id}"
|
|
f"/resources/environments/default/filesystem/{_MARKDOWN_FILE_PATH}",
|
|
json={"content": _MARKDOWN_CONTENT, "encoding": "utf-8"},
|
|
timeout=10.0,
|
|
)
|
|
resp.raise_for_status()
|
|
try:
|
|
yield (base_url, session_id)
|
|
finally:
|
|
shutil.rmtree(_REPO_ROOT / session_id, ignore_errors=True)
|
|
|
|
|
|
def test_github_alerts_render_as_typed_callouts(
|
|
page: Page,
|
|
seeded_alerts_session: tuple[str, str],
|
|
) -> None:
|
|
"""Each ``[!TYPE]`` blockquote renders as a typed alert; plain quotes don't."""
|
|
base_url, session_id = seeded_alerts_session
|
|
page.goto(f"{base_url}/c/{session_id}?file={_MARKDOWN_FILE_PATH}")
|
|
|
|
file_viewer = page.locator('[data-testid="file-viewer"]:visible')
|
|
expect(file_viewer).to_be_visible()
|
|
|
|
# Markdown opens in the rich-text editor by default, where GitHub alerts
|
|
# render as typed callout blockquotes.
|
|
editor = file_viewer.locator("[contenteditable='true']")
|
|
expect(editor).to_be_visible(timeout=10_000)
|
|
|
|
# Every alert type renders as a blockquote tagged with its lowercase
|
|
# data-alert-type and human-readable data-alert-label.
|
|
expected = {
|
|
"note": "Note",
|
|
"tip": "Tip",
|
|
"important": "Important",
|
|
"warning": "Warning",
|
|
"caution": "Caution",
|
|
}
|
|
for alert_type, label in expected.items():
|
|
callout = editor.locator(f'blockquote[data-alert-type="{alert_type}"]')
|
|
expect(callout).to_have_count(1)
|
|
expect(callout).to_have_attribute("data-alert-label", label)
|
|
|
|
# The marker text itself is consumed — the rendered callout shows the body,
|
|
# never the raw "[!NOTE]" syntax.
|
|
note = editor.locator('blockquote[data-alert-type="note"]')
|
|
expect(note).to_contain_text("Highlights information")
|
|
expect(note).not_to_contain_text("[!NOTE]")
|
|
|
|
# The plain blockquote stays an ordinary blockquote — no alert typing.
|
|
plain = editor.locator("blockquote:not([data-alert-type])").filter(
|
|
has_text="A plain blockquote"
|
|
)
|
|
expect(plain).to_have_count(1)
|
|
|
|
# Source view: the raw markers are visible verbatim.
|
|
switch_markdown_view_mode(page, file_viewer, "Source")
|
|
expect(file_viewer.locator("[contenteditable='true']")).to_have_count(0)
|
|
expect(file_viewer.get_by_text("[!WARNING]", exact=False)).to_be_visible(timeout=10_000)
|