feat: enhance medialib image handling and add asset URL resolution

- Implemented `resolveApiAssetUrl` function to normalize asset URLs based on API base.
- Updated `MedialibImage` component to utilize new asset URL resolution and added support for alt text and class properties.
- Enhanced image loading behavior with improved width measurement and focal point handling.
- Added placeholder image handling and improved accessibility with alt text.
- Introduced new test script for auditing broken links in skill documentation.
- Expanded seeded test content to include medialib entries and updated related tests for pagebuilder previews.
- Improved global setup and teardown logging for clarity on seeded content management.
This commit is contained in:
2026-05-17 00:52:41 +00:00
parent 958b45272d
commit 4020ad62c5
44 changed files with 4276 additions and 867 deletions
+115
View File
@@ -202,6 +202,19 @@ When adding new deterministic coverage, extend the seed data instead of assertin
## Which test type to use
## Checklist-facing minimum contract for derived projects
When this starter is used to build a real website project, the testing layer should usually cover these contracts explicitly:
1. deterministic seed setup for the data the suite depends on
2. API smoke coverage for public reads and important write/action behavior
3. desktop E2E coverage for core public journeys such as homepage, navigation, language switching, and 404 behavior
4. admin smoke coverage for stable collection/admin contracts
5. pagebuilder registry plus real preview rendering when the project uses block-based authoring
6. SSR validation through direct endpoint checks, and committed tests where the SSR contract is central and stable enough
Do not treat the test suite as an optional polish step. It is one of the delivery contracts of the project.
### API tests
Use `tests/api/` when validating:
@@ -249,6 +262,28 @@ Use `tests/e2e-mobile/` when validating:
Use `tests/e2e-visual/` only when layout/styling stability matters and a semantic DOM assertion is not enough.
## SSR validation placement
Do not try to prove every SSR property only through browser navigation.
Use direct SSR endpoint checks when:
- validating route acceptance and canonicalization
- validating SSR HTML content
- validating cache-hit / cache-miss behavior
- validating publication-window effects or cache invalidation after mutations
Use committed API/E2E tests when:
- the SSR-related behavior is stable enough to be a long-lived regression contract
- the project depends heavily on SSR for page-critical content
- a browser-level journey would otherwise hide SSR-specific regressions
Preferred rule:
- infrastructure-like SSR checks start as direct endpoint checks
- promote them into committed tests when the behavior is important and deterministic enough
## Admin config coverage strategy
Use a hybrid approach:
@@ -429,3 +464,83 @@ When extending or fixing tests:
5. Fix selectors or seed shape before widening scope.
Keep the test basis deterministic. Do not fall back to existing editorial demo content just because it is already present in the database.
## Admin E2E: Boot abwarten
Admin-SPA lädt Chunks asynchron. Vor Interaktionen auf sichtbares Login-Formular warten:
```ts
await page.goto("/login")
await expect(page.getByLabel(/Benutzername|Username/i)).toBeVisible({ timeout: 20000 })
```
Danach erst fill/click das Formular erscheint erst wenn die App vollständig gebootet ist.
## MailDev E-Mail-Testing
MailDev läuft im Docker-Stack (SMTP Port 25, Web-API Port 1080). Die REST-API erlaubt E-Mails zu lesen und zu löschen:
```ts
const MAILDEV = "https://{project}-maildev.code.testversion.online"
// Alle E-Mails abrufen
const res = await request.get(`${MAILDEV}/email`)
const emails = await res.json()
// Alle löschen (vor Test)
await request.delete(`${MAILDEV}/email/all`)
```
### Polling-Pattern für asynchrone E-Mails
Formular → Action-Hook sendet E-Mail via `context.smtp.sendMail()`. MailDev braucht Zeit zum Verarbeiten:
```ts
// Nach Form-Submit auf E-Mails warten
for (let i = 0; i < 15; i++) {
await new Promise((r) => setTimeout(r, 1000))
const res = await request.get(`${MAILDEV}/email`)
if (res.ok()) {
const emails = await res.json()
if (emails.length >= 2) break // Kunde + Betreiber
}
}
emails.find((e) => e.to.some((t) => t.address === "kunde@test.de"))
```
Wichtig: Tests mit MailDev müssen sequentiell laufen (`--workers=1`), da parallele Tests sich gegenseitig die MailDev-Inbox überschreiben.
## Admin pagebuilder registry coverage
For starter-like projects, committed admin coverage should include both sides of the pagebuilder contract:
1. registry/chooser coverage on a new entry form
2. actual preview rendering on an existing seeded entry
The second check is important because it catches failures that the chooser alone does not see:
- broken `meta.pagebuilder.blockRegistry.file` wiring
- preview components that no longer mount through the shared block renderer
- missing `_lookup` hydration for foreign media fields
- image widgets that work on the public site but fail in admin preview because the API base or URL resolution is wrong
Preferred starter pattern:
- seed one deterministic medialib image through the collection API
- seed one deterministic content entry that references that image in at least one pagebuilder block
- open that entry in `tests/e2e-admin/pagebuilder.spec.ts`
- assert both block text and `img[data-entry-id]` preview rendering
Keep this test generic. Do not tie it to customer-specific block sets unless the project has already diverged from the starter pattern.
## Delivery-checklist alignment
When using this skill together with `.agents/BUILD_CHECKLIST.md`, the testing phase should leave behind explicit evidence for:
- which specs were run
- which seed data was extended or reused
- whether admin smoke coverage exists for the configured collections
- whether pagebuilder preview rendering is covered when pagebuilder is in scope
- whether SSR was verified by direct endpoint checks, committed tests, or both
If that evidence only exists in chat history and not in the repo or task notes, the testing work is too fragile for later agents.