diff --git a/apps/blog/tests/test_admin_experience.py b/apps/blog/tests/test_admin_experience.py index 9b2c611..035099c 100644 --- a/apps/blog/tests/test_admin_experience.py +++ b/apps/blog/tests/test_admin_experience.py @@ -1,3 +1,5 @@ +from datetime import timedelta + import pytest from django.test import override_settings from django.utils import timezone @@ -32,7 +34,7 @@ def test_published_date_preserved_when_explicitly_set(home_page): index = ArticleIndexPage(title="Articles", slug="articles") home_page.add_child(instance=index) author = AuthorFactory() - custom_date = timezone.now() - timezone.timedelta(days=30) + custom_date = timezone.now() - timedelta(days=30) article = ArticlePage( title="Custom Date", slug="custom-date", @@ -60,7 +62,7 @@ def test_homepage_orders_articles_by_published_date(home_page): author=author, summary="s", body=[("rich_text", "

body

")], - published_date=timezone.now() - timezone.timedelta(days=10), + published_date=timezone.now() - timedelta(days=10), ) index.add_child(instance=older) older.save_revision().publish() @@ -94,7 +96,7 @@ def test_article_index_orders_by_published_date(home_page, rf): author=author, summary="s", body=[("rich_text", "

b

")], - published_date=timezone.now() - timezone.timedelta(days=5), + published_date=timezone.now() - timedelta(days=5), ) index.add_child(instance=old) old.save_revision().publish() diff --git a/apps/core/management/commands/seed_e2e_content.py b/apps/core/management/commands/seed_e2e_content.py index c4a6f57..068c049 100644 --- a/apps/core/management/commands/seed_e2e_content.py +++ b/apps/core/management/commands/seed_e2e_content.py @@ -20,6 +20,8 @@ class Command(BaseCommand): def handle(self, *args, **options): import datetime + from django.utils import timezone + root = Page.get_first_root_node() home = HomePage.objects.child_of(root).first() @@ -43,6 +45,9 @@ class Command(BaseCommand): ) # Primary article — comments enabled, used by nightly journey test + # published_date is set explicitly to ensure deterministic ordering + # (most recent first) so this article appears at the top of listings. + now = timezone.now() article = ArticlePage.objects.child_of(article_index).filter(slug="nightly-playwright-journey").first() if article is None: article = ArticlePage( @@ -52,9 +57,12 @@ class Command(BaseCommand): summary="Seeded article for nightly browser journey.", body=[("rich_text", "

Seeded article body for nightly browser checks.

")], comments_enabled=True, + published_date=now, ) article_index.add_child(instance=article) article.save_revision().publish() + # Ensure deterministic ordering — primary article always newest + ArticlePage.objects.filter(pk=article.pk).update(published_date=now) # Seed one approved top-level comment on the primary article for reply E2E tests if not Comment.objects.filter(article=article, author_name="E2E Approved Commenter").exists(): @@ -78,9 +86,13 @@ class Command(BaseCommand): summary="An article with tags for E2E filter tests.", body=[("rich_text", "

This article is tagged with AI Tools.

")], comments_enabled=True, + published_date=now - datetime.timedelta(hours=1), ) article_index.add_child(instance=tagged_article) tagged_article.save_revision().publish() + ArticlePage.objects.filter(pk=tagged_article.pk).update( + published_date=now - datetime.timedelta(hours=1) + ) tagged_article.tags.add(tag) tagged_article.save() @@ -94,6 +106,7 @@ class Command(BaseCommand): summary="An article with comments disabled.", body=[("rich_text", "

Comments are disabled on this one.

")], comments_enabled=False, + published_date=now - datetime.timedelta(hours=2), ) article_index.add_child(instance=no_comments_article) # Explicitly persist False after add_child (which internally calls save()) @@ -101,6 +114,9 @@ class Command(BaseCommand): ArticlePage.objects.filter(pk=no_comments_article.pk).update(comments_enabled=False) no_comments_article.comments_enabled = False no_comments_article.save_revision().publish() + ArticlePage.objects.filter(pk=no_comments_article.pk).update( + published_date=now - datetime.timedelta(hours=2) + ) # About page if not AboutPage.objects.child_of(home).filter(slug="about").exists(): diff --git a/apps/core/tests/test_nightly_e2e_playwright.py b/apps/core/tests/test_nightly_e2e_playwright.py index af38e24..ba67373 100644 --- a/apps/core/tests/test_nightly_e2e_playwright.py +++ b/apps/core/tests/test_nightly_e2e_playwright.py @@ -32,7 +32,7 @@ def test_nightly_playwright_journey() -> None: article_url = article_href if article_href.startswith("http") else f"{base_url}{article_href}" page.goto(article_url, wait_until="networkidle") - expect(page.get_by_role("heading", name="Comments")).to_be_visible() + expect(page.get_by_role("heading", name="Comments", exact=True)).to_be_visible() expect(page.get_by_role("button", name="Post comment")).to_be_visible() page.goto(f"{base_url}/feed/", wait_until="networkidle") diff --git a/e2e/test_admin_experience.py b/e2e/test_admin_experience.py index d47f85a..5823a0f 100644 --- a/e2e/test_admin_experience.py +++ b/e2e/test_admin_experience.py @@ -19,7 +19,7 @@ def admin_login(page: Page, base_url: str) -> None: def test_articles_menu_item_visible(page: Page, base_url: str) -> None: """The admin sidebar should contain an 'Articles' menu item.""" admin_login(page, base_url) - sidebar = page.locator("[data-side-panel]").first + sidebar = page.locator("#wagtail-sidebar") articles_link = sidebar.get_by_role("link", name="Articles") expect(articles_link).to_be_visible() @@ -47,8 +47,8 @@ def test_article_editor_has_tabs(page: Page, base_url: str) -> None: """The article editor should have Content, Metadata, Publishing, and SEO tabs.""" admin_login(page, base_url) page.goto(f"{base_url}/cms/articles/", wait_until="networkidle") - # Click the first article to edit it - page.get_by_text("Nightly Playwright Journey").first.click() + # Click the first article title link to edit it + page.get_by_role("link", name="Nightly Playwright Journey").first.click() page.wait_for_load_state("networkidle") expect(page.get_by_role("tab", name="Content")).to_be_visible() expect(page.get_by_role("tab", name="Metadata")).to_be_visible()