Commit Graph

132 Commits

Author SHA1 Message Date
Mark
0818f71566 fix: upgrade Pillow to 12.x for native AVIF support
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m38s
CI / ci (pull_request) Successful in 2m9s
Pillow 11.0.x did not include native AVIF support — that was added in
11.1.0. The ~=11.0.0 pin restricted upgrades to 11.0.x, so the
libavif-dev system package installed in the Dockerfile was never used
(pip installs pre-compiled wheels that bundle their own libraries).

Bump to Pillow ~=12.1 which ships native AVIF encoding/decoding in its
PyPI wheels out of the box.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-02 16:10:26 +00:00
3799d76bed Merge pull request 'fix(docker): add libavif-dev for AVIF image upload support' (#26) from fix/avif-support into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 1m33s
Reviewed-on: #26
2026-03-02 16:00:17 +00:00
Mark
fbe8546b37 fix(docker): add libavif-dev for AVIF image upload support
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 2m53s
CI / ci (pull_request) Successful in 3m27s
Pillow 11 supports AVIF natively but requires libavif to be installed
at the system level. Without it, uploading AVIF images via Wagtail's
image chooser causes an unhandled 500 error.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-02 15:52:57 +00:00
a59d21cfcb Merge pull request 'fix(csp): skip restrictive CSP on Wagtail/Django admin paths' (#25) from fix/csp-wagtail-admin into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 23s
Reviewed-on: #25
2026-03-02 15:36:12 +00:00
Mark
43594777e0 fix(csp): skip restrictive CSP on Wagtail/Django admin paths
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m11s
CI / ci (pull_request) Successful in 1m22s
The SecurityHeadersMiddleware applied a strict style-src policy to all
responses, blocking inline styles that Wagtail admin relies on for
layout. Skip the custom CSP for /cms/ and /django-admin/ paths.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-02 15:34:09 +00:00
f7c89be05c Merge pull request 'fix(makefile): point DC at prod compose file' (#24) from fix/makefile-prod-compose into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 25s
Reviewed-on: #24
2026-03-02 15:03:15 +00:00
Mark
2e7949ac23 fix(makefile): point DC at prod compose file
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m11s
CI / ci (pull_request) Successful in 1m23s
The Makefile used bare 'docker compose' which picks up the dev
docker-compose.yml when run from the app directory on prod. Point
it at the absolute path to docker-compose.prod.yml instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-02 15:01:27 +00:00
f5c2f87820 Merge pull request 'feat: add Makefile for Docker and Django ops' (#23) from feat/makefile into main
Some checks failed
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / deploy (push) Has been skipped
CI / nightly-e2e (push) Failing after 54s
Reviewed-on: #23
2026-03-01 14:26:51 +00:00
codex_a
abbc3c3d1d feat: add Makefile for Docker and Django ops
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m13s
CI / ci (pull_request) Successful in 1m25s
Covers:
- Docker: build, up, run, down, restart, logs, ps, bash, psql
- Django: migrate, makemigrations, showmigrations, createsuperuser,
  collectstatic, shell, dbshell
- Tailwind: install, build, watch
- Testing: pytest unit and E2E targets
- Custom commands: seed, check-content, purge-comments

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 14:24:13 +00:00
c028a83bef Merge pull request 'fix: nav/footer wireframe alignment, honeypot CSP fix, comment E2E coverage' (#22) from fix/ui-cleanup into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 25s
Reviewed-on: #22
2026-03-01 12:35:20 +00:00
codex_a
155c8f7569 fix: nav/footer wireframe, honeypot CSP, explore topics, comment E2E coverage
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m11s
CI / ci (pull_request) Successful in 1m25s
- Replace nav inline newsletter form with Subscribe CTA link per wireframe
- Remove newsletter form from footer; add Connect section with social/RSS links
- Fix honeypot inputs using hidden attribute (inline style blocked by CSP)
- Add available_tags to HomePage.get_context for Explore Topics section
- Add data-comment-form attribute to main comment form for reliable locating
- Seed approved comment in E2E content for reply flow testing
- Expand test_comments.py: moderation message, not-immediately-visible,
  missing fields, reply form visible, reply submission
- Make COMMENT_RATE_LIMIT_PER_MINUTE configurable; set 100 in dev to prevent
  E2E test exhaustion; update rate limit unit test with override_settings
- Update newsletter/home E2E tests to reflect nav form removal
- Update unit test to assert no nav/footer newsletter forms

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 12:17:55 +00:00
d83f7db57c Merge pull request 'fix: migrate STATICFILES_STORAGE to STORAGES (Django 5.2)' (#21) from fix/storages-django52 into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 25s
Reviewed-on: #21
2026-03-01 11:51:04 +00:00
codex_a
221c8c19c2 fix: migrate STATICFILES_STORAGE to STORAGES for Django 5.2 compat
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m6s
CI / ci (pull_request) Successful in 1m25s
Django 5.1+ removes STATICFILES_STORAGE in favour of the STORAGES dict.
The old setting was silently ignored on Django 5.2, causing StaticFilesStorage
(the default) to be used instead of CompressedManifestStaticFilesStorage.

Result: no content-hashed filenames, no staticfiles.json manifest, and
Cloudflare caching /static/css/styles.css indefinitely with no cache
busting on deploy.

Fix: use STORAGES in base.py (CompressedManifestStaticFilesStorage) and
development.py (plain StaticFilesStorage, whitenoise disabled in dev).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 11:47:37 +00:00
c0cd4e5037 Merge pull request 'fix: allow Google Fonts in CSP' (#20) from fix/csp-google-fonts into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 23s
Reviewed-on: #20
2026-03-01 11:35:13 +00:00
codex_a
78c4313874 fix: allow Google Fonts in CSP
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m8s
CI / ci (pull_request) Successful in 1m25s
style-src and font-src were 'self' only, blocking fonts.googleapis.com
stylesheet and fonts.gstatic.com font files. Add both origins so
Space Grotesk, Inter and Fira Code load correctly in production.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 11:31:41 +00:00
ec89a5fe35 Merge pull request 'feat: implement Tailwind CSS styling' (#19) from feat/styling into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 22s
Reviewed-on: #19
Reviewed-by: codex_b <codex_b@linteldigital.com>
2026-03-01 11:27:33 +00:00
codex_a
71fe06edd1 fix: address QA review findings
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m6s
CI / ci (pull_request) Successful in 1m24s
1. Typography: install @tailwindcss/typography and add to plugins so prose
   classes render correctly in article/about/legal templates.

2. Callout block: fix icon branches to match CalloutBlock.ICON_CHOICES
   (info/warning/trophy/tip). Previous template branched on error/success
   which are unreachable; info fell through to else silently.

3. Nav newsletter feedback: remove 'hidden' class from desktop nav
   data-newsletter-message element. JS sets textContent only; hidden
   class prevented message from ever being visible.

4. Popular Articles sidebar: add numbered Popular Articles widget to home
   page sidebar matching wireframe, using latest_articles context with
   alternating cyan/pink number accents and read_time_mins.

Rebuild CSS: typography plugin grows output from 24KB to 47KB.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 11:20:57 +00:00
codex_a
bff59eec06 fix: move mobile menu outside nav to prevent playwright strict mode violation
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m4s
CI / ci (pull_request) Successful in 1m23s
Playwright strict mode requires exactly one match for form[data-newsletter-form]
inside nav. Having desktop + mobile forms both inside <nav> caused a strict
violation. Mobile menu div is now outside the closing </nav> tag; JS toggle
uses getElementById so position doesn't matter.

Rebuild CSS to match template changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 10:43:17 +00:00
codex_a
8b83712cbf fix: address code review issues and rebuild CSS
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Failing after 1m4s
CI / ci (pull_request) Successful in 1m22s
- nav: add functional mobile menu panel with JS toggle
- nav: hamburger now shows/hides mobile-menu with aria-expanded state
- about_page: full styled layout (header, prose body, author aside)
- legal_page: full styled layout (header with last-updated, max-w-3xl prose)
- article: fix aside newsletter label to 'Subscribe' for E2E test
- CSS: rebuild after all template changes (4.8KB → 24.3KB)
  Committed CSS must match CI build — rebuilt after ALL template edits

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 10:25:33 +00:00
codex_a
73ef38a144 fix: resolve E2E test failures
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / ci (pull_request) Failing after 1m23s
CI / pr-e2e (pull_request) Failing after 1m35s
- nav: replace hidden newsletter form + Subscribe link with visible inline form
- nav: fix theme toggle aria-label to 'Toggle theme' (was 'Toggle Dark Mode')
- article_page: wrap share buttons in <section aria-label='Share this article'>

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 10:14:36 +00:00
codex_a
1c7b96f723 feat: implement Tailwind CSS styling based on wireframe design
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / ci (pull_request) Successful in 1m24s
CI / pr-e2e (pull_request) Failing after 3m21s
- Add brand colours, fonts (Space Grotesk/Inter/Fira Code), box shadows to tailwind.config.js
- Add bg-grid-pattern, text-gradient, scrollbar, selection styles to input.css
- Add Google Fonts link and dark-mode body classes to base.html
- Style nav, footer, cookie banner, newsletter form components
- Style homepage: featured article, 12-col editorial grid, sidebar widgets
- Style article list: header, tag filters, horizontal article cards, pagination
- Style article page: hero header, prose body, share sidebar, related cards, comments
- Style code blocks and callout blocks
- CSS output grows from 4.8KB to 24KB with all brand utilities compiled

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 10:02:23 +00:00
a880643d65 Merge pull request 'fix: cd to site dir before docker compose commands' (#18) from fix/deploy-workdir into main
All checks were successful
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Successful in 25s
2026-03-01 09:40:43 +00:00
codex_a
229c0f8b48 fix: cd to site dir before docker compose commands
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m7s
CI / ci (pull_request) Successful in 1m15s
docker compose stats the cwd when parsing compose files; if cwd is
not accessible to the deploy user the command fails.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-01 09:38:54 +00:00
d7bfb44ced Merge pull request 'fix: remove sudo from deploy script' (#17) from fix/deploy-no-sudo into main
Some checks failed
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / deploy (push) Has been skipped
CI / nightly-e2e (push) Failing after 44s
2026-02-28 22:16:30 +00:00
codex_a
ec3e1ee1bf fix: remove sudo from deploy script, use docker compose directly
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Failing after 42s
CI / ci (pull_request) Successful in 1m1s
deploy user has no sudo for systemctl. Instead:
- Use 'docker compose up -d --force-recreate' to recreate the web
  container without needing systemctl
- Change Restart=always so systemd re-attaches after the container
  is recreated
- Replace 'sudo journalctl' with 'docker compose logs' in error path

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 22:15:02 +00:00
44ffae7f99 Merge pull request 'fix: auto-set Wagtail site hostname on startup' (#16) from fix/prod-site-hostname into main
Some checks failed
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Failing after 2m30s
2026-02-28 22:08:29 +00:00
codex_a
c9dab3e93b fix: use correct Host header in deploy health check
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Failing after 44s
CI / ci (pull_request) Successful in 1m2s
ALLOWED_HOSTS doesn't include localhost, so curl with default Host
header always gets a 400 and the health check fails.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 21:55:58 +00:00
codex_a
349f1db721 fix: auto-set Wagtail site hostname from ALLOWED_HOSTS on startup
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m4s
CI / ci (pull_request) Successful in 1m15s
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 21:54:27 +00:00
de56b564c5 Merge pull request 'feat: production deploy pipeline' (#15) from feat/deploy-pipeline into main
Some checks failed
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Failing after 1s
2026-02-28 21:50:04 +00:00
codex_a
833ff378ea fix: use entrypoint script for prod container startup
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m4s
CI / ci (pull_request) Successful in 1m15s
YAML folded block scalar (>) was preserving newlines for more-indented
continuation lines, so gunicorn received no arguments and defaulted to
binding on 127.0.0.1:8000. Replace with an explicit entrypoint script
so all args are passed correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 21:47:02 +00:00
codex_a
754b0ca5f6 fix: set build context to app/ in prod compose
The compose file lives in /srv/sum/nohype/ while the code is in
/srv/sum/nohype/app/ so the Dockerfile is at app/Dockerfile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 21:42:06 +00:00
03fcbdb5ad Merge pull request 'feat: production deploy pipeline' (#14) from feat/deploy-pipeline into main
Some checks failed
CI / ci (push) Has been skipped
CI / pr-e2e (push) Has been skipped
CI / nightly-e2e (push) Has been skipped
CI / deploy (push) Failing after 5s
Reviewed-on: #14
2026-02-28 21:40:03 +00:00
codex_a
0cbac68ec1 feat: add production deploy pipeline and fix dev CSS
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / deploy (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m4s
CI / ci (pull_request) Successful in 1m23s
Dev:
- Add tailwind install + build to docker-compose startup so CSS is built
  inside the container — not dependent on local filesystem

Production (docker-compose.prod.yml):
- Gunicorn on 127.0.0.1:8001, bind-mounted static/media to host paths
  so Caddy can serve them directly
- Runs migrate, tailwind build, collectstatic on startup

Settings (production.py):
- Disable SECURE_SSL_REDIRECT (Caddy handles redirects; Django would loop)
- Add CSRF_TRUSTED_ORIGINS for nohypeai.net

CI (.gitea/workflows/ci.yml):
- Add push-to-main trigger
- Add deploy job: SSHes to lintel-prod-01 as deploy, runs deploy/deploy.sh

Server config (deploy/):
- deploy/caddy/nohype.caddy — Caddy site config for nohypeai.net
- deploy/sum-nohype.service — systemd unit for the compose stack
- deploy/deploy.sh — deploy script (pull, build, restart)

One-time manual steps required on lintel-prod-01 (need root):
  sudo cp deploy/sum-nohype.service /etc/systemd/system/
  sudo cp deploy/caddy/nohype.caddy /etc/caddy/sites-enabled/
  sudo systemctl daemon-reload && sudo systemctl enable sum-nohype
  sudo systemctl reload caddy

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 21:34:13 +00:00
4c27cfe1dd Merge pull request 'fix: make docker compose up work out of the box' (#13) from fix/dev-setup into main
Reviewed-on: #13
2026-02-28 21:00:10 +00:00
codex_a
a598727888 fix: fix all dev static/media serving issues
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m4s
CI / ci (pull_request) Successful in 1m22s
- Remove WhiteNoise from MIDDLEWARE in development: it intercepts /static/
  requests and serves from STATIC_ROOT, which is empty without collectstatic.
  Django's runserver serves static files natively with DEBUG=True.
- Switch to StaticFilesStorage in dev: no manifest required.
- Add media URL pattern in DEBUG mode: runserver does not serve MEDIA_ROOT
  automatically, so uploaded images were 404ing in local dev.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 20:57:54 +00:00
36eb0f1dd2 Merge pull request 'fix: use plain StaticFilesStorage in dev settings' (#10) from fix/seed-default-site into main
Reviewed-on: #10
2026-02-28 20:48:44 +00:00
codex_a
f950e3cd5e fix: use plain StaticFilesStorage in dev settings
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m4s
CI / ci (pull_request) Successful in 1m24s
CompressedManifestStaticFilesStorage requires collectstatic to generate a
manifest before it can serve anything. Dev containers never run collectstatic
so every static asset 404s. Override to StaticFilesStorage in dev so Django
serves files directly from STATICFILES_DIRS and app static directories.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 20:46:23 +00:00
311ad80320 Merge pull request 'fix: update ALL site records in seed, not just is_default_site' (#9) from fix/seed-default-site into main
Reviewed-on: #9
2026-02-28 20:42:24 +00:00
codex_a
08e003e165 fix: update ALL site records in seed, not just is_default_site
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m4s
CI / ci (pull_request) Successful in 1m22s
Wagtail's initial migration creates a localhost:80 site. Wagtail matches
incoming requests by hostname before ever checking is_default_site, so
updating only the is_default_site record left localhost:80 still pointing
at the Welcome page. Fix by updating root_page on every site.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 20:40:20 +00:00
076aaa0b9e Merge pull request 'fix: update existing default site in seed command' (#8) from fix/seed-default-site into main
Reviewed-on: #8
2026-02-28 20:35:15 +00:00
codex_a
7b2ad4cfe5 fix: remove server-specific playwright volume from dev compose, auto-seed on startup
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m6s
CI / ci (pull_request) Successful in 1m23s
- /opt/playwright-tools/browsers only exists on agent-workspace; mounting it
  in docker-compose.yml breaks local dev for everyone else
- seed_e2e_content is idempotent so safe to run on every startup; removes the
  manual step that nobody knew about

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 20:33:40 +00:00
codex_a
56e53478ea fix: update existing default site in seed command instead of hardcoding 127.0.0.1
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m10s
CI / ci (pull_request) Successful in 1m22s
Wagtail initialises the default site with hostname 'localhost'. The previous
get_or_create on '127.0.0.1' left the localhost site intact (still pointing
to the Welcome page), so browsers got the wrong root page.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 20:31:20 +00:00
96f9eca19d Merge pull request 'feat: comprehensive Playwright E2E test suite' (#7) from tests/e2e into main
Reviewed-on: #7
2026-02-28 20:25:29 +00:00
codex_a
f6edcadd46 fix: run E2E tests properly with mounted browsers and real postgres
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / pr-e2e (pull_request) Successful in 1m33s
CI / ci (pull_request) Successful in 2m18s
- Mount /opt/playwright-tools/browsers into web container (docker-compose.yml
  and CI docker run) — never download browsers, use the ones on this host
- Set PLAYWRIGHT_BROWSERS_PATH in all container envs (compose + CI)
- Drop 'playwright install chromium' steps from pr-e2e and nightly-e2e jobs
- Bump playwright requirement to ~1.57.0 to match the installed browser builds
- Fix seed_e2e_content: de-duplicate default Site entries left by unit test
  fixtures so Wagtail always routes to the seeded home page
- Fix test_comments_section_absent_when_disabled: use exact=True on heading
  locator to avoid matching 'No Comments Article' h1 as 'Comments' heading
- Fix test_copy_link_button_updates_text: use [data-copy-link] data-attr
  locator (stable across text change) and force-override clipboard.writeText
  via page.evaluate() rather than relying on init_script polyfill

E2E suite verified locally: 34 passed via docker compose exec

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 20:20:18 +00:00
codex_a
4992b0cb9d fix: resolve 5 E2E test failures from first CI run
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / ci (pull_request) Successful in 1m22s
CI / pr-e2e (pull_request) Failing after 1m32s
- test_homepage_title_contains_brand: to_have_title() requires a string or
  regex, not a lambda; switch to re.compile('No Hype AI')
- test_granular_preferences_save_dismisses_banner: wrong element clicked to
  open <details>; use 'details summary' locator directly
- test_subscribe_invalid_email_shows_error: browser HTML5 email validation
  swallows the submit event before the JS handler fires; add 'novalidate' via
  evaluate() so the fetch still runs and the server returns 400
- test_copy_link_button_updates_text: clipboard API unavailable in headless
  Docker; add polyfill + pre-grant permissions in conftest page fixture so
  the JS success path runs and button text becomes 'Copied'
- test_comments_section_absent_when_disabled: guard against Wagtail's
  add_child() resetting BooleanField defaults by calling an explicit
  .update(comments_enabled=False) + re-setting on the instance before
  save_revision().publish(); also tighten test to assert 200 + correct title

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 19:47:13 +00:00
codex_a
9d323d2040 feat: add comprehensive Playwright E2E test suite
Some checks failed
CI / nightly-e2e (pull_request) Has been skipped
CI / ci (pull_request) Successful in 1m22s
CI / pr-e2e (pull_request) Failing after 3m28s
- Create e2e/ directory with 7 test modules covering:
  - Home page: title, nav links, theme toggle, newsletter form
  - Cookie consent: accept all, reject all, granular prefs, persistence
  - Article index: loads, tag filter, click-through navigation
  - Article detail: title/read-time, share section, comments, newsletter aside, related
  - Comments: valid submit → redirect, empty body → error display, disabled check
  - Newsletter: JS confirmation message, invalid email error, aside form, duplicate
  - Feeds: RSS/sitemap/robots.txt validity, tag feed, seeded content present
- Extend seed_e2e_content management command with tagged article, about page,
  no-comments article, and legal pages for richer test coverage
- Add seed command tests (create + idempotency) to keep coverage ≥ 90%
- Add pr-e2e CI job (runs on pull_request): builds image, starts postgres + app,
  installs playwright, runs pytest e2e/
- Update nightly-e2e to run full e2e/ suite alongside legacy journey test
- Add --ignore=e2e to unit-test pytest step (coverage must not include browser tests)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 19:30:43 +00:00
aeb0afb2ea Merge pull request 'Run migrations before starting dev server' (#6) from fix/run-migrations-on-startup into main
Reviewed-on: #6
2026-02-28 19:13:57 +00:00
codex_a
b73a2d4d72 Run migrations before starting dev server
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / ci (pull_request) Successful in 1m21s
Chains 'migrate --noinput' before 'runserver' in the web
service command so migrations are applied automatically on
'docker compose up'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-02-28 18:53:32 +00:00
7d226bc4ef Merge pull request 'fix: docker fix' (#5) from fix/docker-apt-retries into main
Reviewed-on: #5
2026-02-28 18:32:29 +00:00
Mark
9b677741cb fix: docker fix
All checks were successful
CI / nightly-e2e (pull_request) Has been skipped
CI / ci (pull_request) Successful in 3m27s
2026-02-28 18:27:56 +00:00