Zdůvodnění
Jediná kontrola odkazů webu hledala grepem href relativní ke kořeni. Zola píše absolutní, takže kontrola hlásila, že se všechny interní odkazy vyřešily, zatímco se nedívala na žádný. První kontrola, která rozhodla o každém odkazu, našla na publikovaném webu odkazy, které vracely 404, a každý pocházel ze sdíleného producenta: šablony skládající routu z identifikátoru místo ze slugu, který nese reference, grafu dávajícího druhům objektů stránky modulů, které nemají, a projekce dokumentu, která nechala odkazy Markdownu psané pro GitHub, aby se řešily proti URL stránky.
Interaktivní ovládací prvky měly stejný tvar. Sonda v prohlížeči měřila menu, rozbalovací seznamy a přepínač motivu na jedné stránce. Tlačítka kopírování, přepínače záložek, filtry, diagnóza, ukázka kontraktu, čipy changelogu, filtry grafu a oblasti posouvání klávesnicí se dodávaly bez testu toho, co dělají.
Seznam odkazů nebo ovládacích prvků by zastaral v den, kdy se stránka změní. Proto se obě množiny objevují z buildu a testy jsou vlastním vynucováním pravidla, ne recenzí, na kterou si někdo vzpomene.
Požadované chování
Každý odkaz se rozhoduje offline. scripts/ci/link-check klasifikuje každé href a src, které web vydává, a každý záznam sitemapy a každý z nich rozhoduje bez sítě:
- Odkaz na stejný původ se vyřeší na soubor pod
site/public. - Fragment pojmenovává id, které cílová stránka obsahuje.
- Odkaz do tohoto repozitáře na jeho forge se vyřeší proti gitu: blob je sledovaný soubor, tree sledovaný adresář, commit je v historii, která se publikuje, tag existuje.
- Vše, co nelze rozhodnout offline, se odmítne: jiný host,
javascript:, prázdný href, holé#. Mělký klon odmítne hlásit čistotu.
scripts/site-check ji spouští.
Odkazy promítnutého dokumentu se rozřešují u jejich zdroje. scripts/lib/project-links.awk rozřeší každý relativní odkaz promítnutého dokumentu vůči souboru, z něhož pochází:
- Dokument se stránkou se stává svou trasou.
- Sledovaný soubor nebo adresář se stane svým blobem nebo stromem na forge.
- Cesta, kterou git nesleduje, si ponechá text a ztratí odkaz.
Každý ovládací prvek je nárokován. scripts/ci/interaction-check objevuje každý ovládací prvek na každé stránce. Ovládací prvek je prvek formuláře, summary, prvek, který nechá jednat direktiva Alpine nebo vazba Flowbite, ARIA role widgetu, vazba grafu nebo oblast posouvání dosažitelná klávesnicí. Zakázané prvky nejsou ovládací prvky a ovládací prvek uvnitř <template> se počítá. Každý ovládací prvek musí nárokovat právě jedna specifikace pod scripts/lib/interaction-specs/. Nenárokovaný prvek selže, dvakrát nárokovaný selže a selže i specifikace, která nenárokuje nic. Každý výraz Alpine na každé stránce se musí zkompilovat: text vložený do řetězce JavaScriptu se rozbije na prvním apostrofu a Alpine pak direktivu beze zvuku zahodí, čímž přestaly filtrovat filtry doktrín a případů užití. Text, který direktiva potřebuje, se nese v datovém atributu, který šablona escapuje, a čte se přes $el.dataset. scripts/site-check to spouští.
Každý ovládací prvek dělá, co říká jeho specifikace. scripts/interaction-probe otevře každou stránku, která nese ovládací prvek, a poskytuje testovaný build na jeho publikovaném originu. Prohlížeč klasifikuje živý dokument stejným pravidlem a každá specifikace ovládá každý prvek, který si nárokuje. Stránka selže, když:
- chování neplatí
- živý počet ovládacích prvků specifikace se liší od značkování
- konzole hlásí chybu nebo se nezachytí výjimka
- požadavek opouští origin webu
- specifikace ovládá méně prvků, než tvrdí
V CI běží jako kontrola interaction-probe ve vlastní úloze. S MJ_PROBE_LIVE=1 pohání publikovaný web, čímž se validuje nasazení.
Chování při selhání
link-checkkončí s 10 a jedním zjištěním na každý rozbitý odkaz, které jmenuje stránku, odkaz a důvod, proč se nevyřeší. Končí s 12, když web chybí nebo je klon příliš mělký na rozhodnutí.interaction-checkskončí s kódem 10 a jmenuje stránku a podpis neobsazeného či dvojitě obsazeného ovládacího prvku, specifikaci, která nic nenárokuje, nebo direktivu, jejíž výraz se nezkompiluje.interaction-probeskončí kódem 10 a pojmenuje stránku, specifikaci a chování, které neplatilo. Bez prohlížeče se lokálně přeskočí a podCI=trueskončí kódem 12.
Ověření
scripts/ci/link-checkascripts/ci/interaction-checknad sestaveným webem, obojí spouštíscripts/site-check.scripts/interaction-probenad sestaveným webem. Po nasazeníMJ_PROBE_LIVE=1 scripts/interaction-probezkontroluje commit, o kterémscripts/pages verifyříká, že se servíruje.test/cases/335_every_link_resolves.sh,test/cases/336_every_control_is_claimed.shatest/cases/337_every_control_does_what_it_says.shvždy porušují to, co jejich kontrola odmítá, a odmítnutí dokazují.