Manual Test Matrix — V17 Runtime Verification
Date: 2026-03-01
Purpose: Systematic runtime testing of all migrated features before go-live.
Environment: https://{client-slug}.progresssystems.ie
How to Use
- Test each row on the running v17 site
- Mark Pass/Fail/N/A in the Status column
- Note any issues in the Notes column
- Test in both Chrome and Safari/Mobile
- For multi-language items, test in both English and Irish (ga-IE)
1. Navigation & Layout (P0)
| # |
Test Case |
Expected |
Status |
Notes |
| 1.1 |
Homepage loads without errors |
Page renders, no console errors |
|
|
| 1.2 |
Menu1 (default) — desktop navigation |
All links work, dropdowns open on hover |
|
|
| 1.3 |
Menu1 — mobile hamburger toggle |
Menu collapses/expands, all links accessible |
|
|
| 1.4 |
Menu2 — hamburger toggle + mega-menu |
data-bs-toggle="collapse" works, submenus expand |
|
|
| 1.5 |
Menu3 — dual logo swap on scroll |
Transparent logo at top → solid logo on scroll |
|
|
| 1.6 |
Menu4 — alternative layout |
Menu renders correctly, links work |
|
|
| 1.7 |
Footer renders correctly |
All footer links, address, social links visible |
|
|
| 1.8 |
Sticky navigation (stickyNav) |
Nav sticks on scroll, unsticks at top |
|
|
| 1.9 |
Search — submit search query |
Results page loads, results displayed |
|
|
| 1.10 |
Cookie notice banner |
Banner appears, dismiss works, persists |
|
|
| 1.11 |
"Go to Top" button |
Appears on scroll, scrolls to top on click |
|
|
2. Homepage & Sliders (P0)
| # |
Test Case |
Expected |
Status |
Notes |
| 2.1 |
Homepage hero slider |
Slick carousel auto-plays, manual arrows work |
|
|
| 2.2 |
Homepage grid content blocks |
All BlockGrid content renders with correct layout |
|
|
| 2.3 |
AOS animations on scroll |
Elements animate in on scroll (fade-up, etc.) |
|
|
| 2.4 |
Lazy loaded images |
Images load as user scrolls (check lazyload class) |
|
|
| 2.5 |
Spotlight controls |
Spotlight boxes render with icons, links, colors |
|
|
| 2.6 |
Split picture slider |
Background image loads with responsive data-bgset (13 widths) |
|
|
| 2.7 |
News slider on homepage |
News articles carousel works |
|
|
| # |
Test Case |
Expected |
Status |
Notes |
| 3.1 |
All page images load (no broken images) |
No 404s in Network tab for images |
|
|
| 3.2 |
WebP format switching |
<picture> serves WebP to supporting browsers |
|
|
| 3.3 |
Image gallery — fancybox lightbox |
Click image → opens in fancybox overlay |
|
|
| 3.4 |
Gallery page — header color |
Background color renders without ## double-hash |
|
|
| 3.5 |
Video popout — fancybox |
Click play → video opens in modal |
|
|
| 3.6 |
YouTube embed |
YouTube iframe renders, plays on click |
|
|
| 3.7 |
Vimeo embed |
Vimeo iframe renders, plays on click |
|
|
| 3.8 |
Internal video |
HTML5 video player works |
|
|
| 3.9 |
SEO Open Graph image |
Check <meta property="og:image"> in page source |
|
|
4. Calculators (P1)
| # |
Test Case |
Expected |
Status |
Notes |
| 4.1 |
Calculator Large — page loads |
Calculator renders with sliders, inputs, labels |
|
|
| 4.2 |
Loan amount slider — drag |
Slider moves, amount updates in real-time |
|
|
| 4.3 |
Term slider — drag |
Slider moves, term updates in real-time |
|
|
| 4.4 |
Slider increment/decrement buttons |
+/- buttons adjust slider values |
|
|
| 4.5 |
Touch support on mobile |
Sliders work with touch drag |
|
|
| 4.6 |
Frequency toggle (Weekly/Fortnightly/Monthly) |
Repayment amount recalculates per frequency |
|
|
| 4.7 |
Apply/Enquire buttons |
Buttons visible, link to correct pages |
|
|
| 4.8 |
Calculator Small widget |
Compact calculator renders, calculates correctly |
|
|
| 4.9 |
Calculator Icon variant |
Icon carousel works, calculator loads on selection |
|
|
| 4.10 |
Calculator labels (dictionary) |
Labels show translated text, not key names |
|
|
| 4.11 |
Calculator labels — Irish (ga-IE) |
Irish translations display correctly |
|
|
| 4.12 |
Disclaimer text |
Disclaimer renders below calculator |
|
|
| 4.13 |
Variable rate calculator |
Variable rate inputs work correctly |
|
|
| # |
Test Case |
Expected |
Status |
Notes |
| 5.1 |
Contact form — renders |
Form fields visible, styled correctly |
|
|
| 5.2 |
Contact form — submit |
Form submits, success message appears |
|
|
| 5.3 |
Contact form — validation |
Required fields show errors on empty submit |
|
|
| 5.4 |
Popup form — modal opens |
Modal appears with form inside |
|
|
| 5.5 |
Popup form — submit |
Form submits from modal, success shown |
|
|
| 5.6 |
Loan box accordion — form inside |
Form renders inside accordion panel |
|
|
| 5.7 |
Email template — sent on submit |
Check email received with correct formatting |
|
|
| 5.8 |
Form — no duplicate scripts |
No console errors from duplicate jQuery Validate |
|
|
| 5.9 |
Datepicker in forms |
Date picker opens, selects date correctly |
|
|
6. News & Articles (P1)
| # |
Test Case |
Expected |
Status |
Notes |
| 6.1 |
News listing page |
Articles listed, images load |
|
|
| 6.2 |
News category dropdown filter |
Dropdown works (BS5 form-select), filters articles |
|
|
| 6.3 |
News pagination |
Next/Previous links work |
|
|
| 6.4 |
Article detail page |
Full article renders with metadata |
|
|
| 6.5 |
Related articles |
Related articles section shows relevant articles |
|
|
| 6.6 |
Top story layout (5 articles) |
Featured + 4 sub-articles layout correct |
|
|
| 6.7 |
News slider (detailed) |
Slick carousel with news items |
|
|
| 6.8 |
Latest articles widget |
Recent articles partial renders correctly |
|
|
7. Accordion & FAQ (P1)
| # |
Test Case |
Expected |
Status |
Notes |
| 7.1 |
FAQ page loads |
Accordion items render |
|
|
| 7.2 |
Accordion expand/collapse |
Click header → content toggles (data-bs-toggle="collapse") |
|
|
| 7.3 |
Accordion — only one open |
Opening one closes others (data-bs-parent) |
|
|
| 7.4 |
FAQ with Schema.org markup |
Check page source for FAQPage schema |
|
|
| 7.5 |
Loan box accordion |
Accordion with loan details + forms |
|
|
8. Login & Authentication (P1)
| # |
Test Case |
Expected |
Status |
Notes |
| 8.1 |
Login page loads |
Login form renders, JS works (MasterLogin layout) |
|
|
| 8.2 |
Login page — scripts loaded |
Check Network tab: bootstrap, slick, fancybox, lazysizes all load |
|
|
| 8.3 |
Login buttons in menu |
Login/Logout buttons visible, dictionary text correct |
|
|
| 8.4 |
Customer-only page — unauthenticated |
Redirects to login or shows access denied |
|
|
| 8.5 |
Customer-only page — authenticated |
Content visible after login |
|
|
9. Testimonials (P2)
| # |
Test Case |
Expected |
Status |
Notes |
| 9.1 |
Testimonials page loads |
Testimonial cards render |
|
|
| 9.2 |
Testimonial carousel |
Slick carousel works, auto-play + manual |
|
|
| 9.3 |
Testimonial card — image |
Author image loads (MediaWithCrops) |
|
|
| 9.4 |
Testimonial card — AOS animation |
Cards animate in on scroll |
|
|
10. Maps & Addresses (P2)
| # |
Test Case |
Expected |
Status |
Notes |
| 10.1 |
Google Map renders |
Map loads with correct location |
|
|
| 10.2 |
Map directions |
"Get Directions" uses geolocation, shows route |
|
|
| 10.3 |
Address list |
Addresses render with opening times |
|
|
| 10.4 |
Mapbox integration |
Mapbox map loads (if configured) |
|
|
| # |
Test Case |
Expected |
Status |
Notes |
| 11.1 |
Local scripts have ?v= hash |
Check Network tab — all local JS/CSS have version hash |
|
|
| 11.2 |
No external CDN references |
All assets served locally (no unpkg.com, cdnjs, etc.) |
|
|
| 11.3 |
LazySizes loaded |
lazySizes.min.js loads in Network tab |
|
|
| 11.4 |
No console errors on any page |
Check DevTools console on homepage, article, calculator |
|
|
12. Multi-Language / Irish (P2)
| # |
Test Case |
Expected |
Status |
Notes |
| 12.1 |
Switch to Irish (ga-IE) |
Language switcher works |
|
|
| 12.2 |
Cookie notice — Irish |
cookieNotice dictionary value shows Irish text |
|
|
| 12.3 |
Calculator labels — Irish |
All calculator.* and Calc_* keys show Irish |
|
|
| 12.4 |
Login buttons — Irish |
Login/Logout text in Irish |
|
|
| 12.5 |
Data protection pages — Irish |
GDPR labels in Irish |
|
|
| 12.6 |
Address/Opening times — Irish |
Labels in Irish |
|
|
13. Responsive / Mobile (P2)
| # |
Test Case |
Expected |
Status |
Notes |
| 13.1 |
Homepage — mobile viewport (375px) |
Layout stacks correctly, no horizontal scroll |
|
|
| 13.2 |
Menu — mobile collapse |
Hamburger menu works |
|
|
| 13.3 |
Calculator — mobile |
Sliders work with touch, layout fits |
|
|
| 13.4 |
News filter — mobile |
Dropdown full-width on small screens |
|
|
| 13.5 |
Accordion — mobile |
Touch expand/collapse works |
|
|
| 13.6 |
Image gallery — mobile |
Fancybox lightbox works on mobile |
|
|
| 13.7 |
Tables — mobile |
Tables scroll horizontally or stack |
|
|
14. Error Handling (P3)
| # |
Test Case |
Expected |
Status |
Notes |
| 14.1 |
404 page |
Navigate to /nonexistent → custom 404 page |
|
|
| 14.2 |
500 error page |
Trigger error → custom 500 page (in production) |
|
|
| 14.3 |
Sitemap.xml |
/sitemap.xml renders valid XML |
|
|
| 14.4 |
Robots.txt |
/robots.txt renders correctly |
|
|
15. Backoffice (P3)
| # |
Test Case |
Expected |
Status |
Notes |
| 15.1 |
Umbraco backoffice loads |
/umbraco renders login |
|
|
| 15.2 |
Content tree loads |
All content nodes visible |
|
|
| 15.3 |
BlockGrid editor |
Edit a page with BlockGrid → blocks render in editor |
|
|
| 15.4 |
News list view |
News parent node shows list view (table/grid) |
|
|
| 15.5 |
Testimonials list view |
Testimonials parent shows list view |
|
|
| 15.6 |
Forms dashboard |
Umbraco Forms entries visible |
|
|
| 15.7 |
Media library |
Media items accessible, images render |
|
|
16. Two-Factor Authentication / 2FA (P1)
v8 had a custom Progress.Umbraco2FA project migrated into src/www/Security/. These tests verify the 2FA flow works end-to-end on the v17 frontend login.
| # |
Test Case |
Expected |
Status |
Notes |
| 16.1 |
Login with 2FA disabled |
Normal username/password login succeeds, no 2FA prompt |
|
|
| 16.2 |
Login with 2FA enabled — TOTP prompt appears |
After correct password, page advances to 2FA code entry step |
|
|
| 16.3 |
TOTP code entry — correct code |
Enter valid 6-digit TOTP code → logged in, redirected to member area |
|
|
| 16.4 |
TOTP code entry — incorrect code |
Enter wrong code → clear error message, stay on 2FA page |
|
|
| 16.5 |
TOTP code entry — expired code |
Enter code from previous 30-second window → rejected |
|
|
| 16.6 |
QR code setup — enroll new device |
Navigate to 2FA setup → QR code renders → scan with authenticator → verify first code → 2FA enabled |
|
|
| 16.7 |
QR code image loads |
QR code <img> or inline SVG renders without 404 or broken image |
|
|
| 16.8 |
Backup codes — generation |
On 2FA setup page, backup codes are displayed or downloadable |
|
|
| 16.9 |
Backup codes — use one to log in |
Enter a backup code instead of TOTP → logs in successfully |
|
|
| 16.10 |
Backup code — single-use enforcement |
Re-use an already-used backup code → rejected |
|
|
| 16.11 |
Remember device / remember browser |
Check "remember this device" → next login from same browser skips 2FA |
|
|
| 16.12 |
Remember device — different browser |
Remember device cookie does not carry to different browser |
|
|
| 16.13 |
Disable 2FA |
On security settings, disable 2FA → subsequent logins use password only |
|
|
| 16.14 |
TokenAuthentication page |
/token-authentication route renders, token workflow initialises |
|
|
17. User Migration Verification (P1)
Members and admin users were migrated from v8. These tests confirm migrated credentials, roles, and permissions survived the migration intact.
| # |
Test Case |
Expected |
Status |
Notes |
| 17.1 |
Migrated admin user — backoffice login |
Admin can log in to /umbraco with original credentials |
|
|
| 17.2 |
Migrated admin user — full access |
Admin sees complete content tree and all sections (Content, Media, Settings, Members) |
|
|
| 17.3 |
Migrated editor user — backoffice login |
Editor logs in with original credentials |
|
|
| 17.4 |
Migrated editor user — restricted access |
Editor does NOT see Settings or Users section (only Content and Media) |
|
|
| 17.5 |
Migrated member — frontend login |
Credit union member logs in on public site with original password |
|
|
| 17.6 |
Migrated member — member-only content |
After login, customer-only pages (CustomerOnlyPage1) are accessible |
|
|
| 17.7 |
Migrated member — member group preserved |
In backoffice Members section: member belongs to correct group |
|
|
| 17.8 |
Password reset flow |
Member requests password reset → receives email → clicks link → sets new password → can log in |
|
|
| 17.9 |
User group permissions not escalated |
Editor-level user cannot access Settings, create content types, or manage users |
|
|
| 17.10 |
UserGroupSaveProtectionHandler active |
Attempt to save a protected user group → notification fires or change is rejected |
|
|
| 17.11 |
UserGroupDeleteProtectionHandler active |
Attempt to delete a protected user group → deletion is blocked |
|
|
18. Content Migration Verification (P1)
Spot-check that migrated content is correct. Focus on property types with known migration complexity: ColorPicker, DropDown.Flexible, MediaPicker3, BlockGrid, RTE.
| # |
Test Case |
Expected |
Status |
Notes |
| 18.1 |
Homepage — all BlockGrid blocks render |
No blank areas, no "null" text, no missing images |
|
|
| 18.2 |
Standard page — RTE content renders |
Body text shows formatted text, lists, links (not raw HTML) |
|
|
| 18.3 |
Standard page — header image |
Page header image loads correctly via MediaWithCrops |
|
|
| 18.4 |
ColorPicker values — no ## prefix |
Inspect inline style: must be #e47d51 not ##e47d51 |
|
|
| 18.5 |
EyeDropper color property |
Component using Umbraco.ColorPicker.EyeDropper renders correct hex color |
|
|
| 18.6 |
DropDown.Flexible — gradient property |
CTA Curves component renders with correct gradient class |
|
|
| 18.7 |
DropDown.Flexible — buttonStyle property |
Component renders correct button variant class |
|
|
| 18.8 |
NestedContent → BlockList migration |
Page with former NestedContent (FAQ items, loan boxes) → all items present, original order |
|
|
| 18.9 |
BlockGrid row count matches v8 |
Compare 2-3 content-heavy pages: row/block count in v17 matches v8 |
|
|
| 18.10 |
Media library — migrated images accessible |
Spot-check 5-10 images in Media section: thumbnails load, names correct |
|
|
| 18.11 |
News articles — count matches |
Published article count in v17 matches v8 |
|
|
| 18.12 |
News article — body content |
Migrated news article: full body text and images render correctly |
|
|
| 18.13 |
Testimonials — all items present |
Testimonial count in v17 matches v8 |
|
|
| 18.14 |
Dictionary items — count |
v17 dictionary items >= v8 count (169 items) |
|
|
| 18.15 |
LoanBox — loan purpose data |
Loan box component: loan purpose IDs are populated (J8 fix) |
|
|
| 18.16 |
Gallery — items present |
Gallery listing shows correct count; individual galleries show correct images |
|
|
| 18.17 |
calculatorsConfiguration node |
Node 2129 published and accessible; CalculatorService reads without errors |
|
|
19. Data Protection / GDPR (P1)
Data protection components are 100% complete (5 components, 3 camelCase duplicates removed). These tests verify end-to-end user-facing GDPR flows.
| # |
Test Case |
Expected |
Status |
Notes |
| 19.1 |
Privacy policy page renders |
/privacy-policy loads with full body text |
|
|
| 19.2 |
Cookies page renders |
/cookies loads, categories and descriptions visible |
|
|
| 19.3 |
Terms and conditions page |
/terms-and-conditions loads with formatted text |
|
|
| 19.4 |
Cookie consent banner — first visit |
Banner appears on first load in private/new browser |
|
|
| 19.5 |
Cookie consent — accept all |
"Accept all" dismisses banner, sets consent cookie |
|
|
| 19.6 |
Cookie consent — reject non-essential |
Decline option: banner dismisses, only essential cookies set |
|
|
| 19.7 |
Cookie consent — persists across pages |
After accepting, navigate to another page — banner does not reappear |
|
|
| 19.8 |
Cookie consent — persists across sessions |
Close and reopen browser — banner does not reappear |
|
|
| 19.9 |
Cookie notice — Irish (ga-IE) |
cookieNotice dictionary value shows Irish text |
|
|
| 19.10 |
Data protection page — Irish |
GDPR pages have Irish-language variants via language switcher |
|
|
| 19.11 |
Right-to-be-forgotten / data deletion |
If "delete my data" form exists: renders and submits without errors |
|
|
| 19.12 |
Form consent checkbox |
GDPR consent checkbox present on forms; form cannot submit without checking it |
|
|
20. Calculator — Deep Testing (P1)
Extends section 4 with business-logic depth. Run against live calculator pages.
| # |
Test Case |
Expected |
Status |
Notes |
| 20.1 |
Loan purpose dropdown — selection |
Selecting a purpose updates the displayed interest rate |
|
|
| 20.2 |
Loan purpose — interest rate display |
Correct rate shown (verify against calculatorsConfiguration values) |
|
|
| 20.3 |
Loan purpose — loanPurposeId populated |
Hidden loanPurposeId field must not be empty (J8 fix) |
|
|
| 20.4 |
Min/max loan amount enforced |
Slider clamps at configured bounds, no NaN |
|
|
| 20.5 |
Min/max term enforced |
Term slider clamps at min/max, repayment updates at boundaries |
|
|
| 20.6 |
Weekly repayment calculation |
Frequency=Weekly → correct weekly figure |
|
|
| 20.7 |
Fortnightly repayment calculation |
Frequency=Fortnightly → correct fortnightly figure |
|
|
| 20.8 |
Monthly repayment calculation |
Frequency=Monthly → base repayment figure correct |
|
|
| 20.9 |
Currency formatting |
Amounts display with correct symbol and separator (en-IE: EUR) |
|
|
| 20.10 |
Calculator API endpoint responds |
Network tab: AJAX call returns HTTP 200 and valid JSON |
|
|
| 20.11 |
Calculator API — no CORS error |
API call succeeds without CORS violation |
|
|
| 20.12 |
Apply/Enquire link — correct destination |
Buttons link to correct loan application URL (not / or #) |
|
|
| 20.13 |
Variable rate calculator — rate type toggle |
Fixed/variable toggle updates rate and repayment |
|
|
| 20.14 |
Calculator Small — frequency W/F/M |
Frequency toggle works on compact widget (J6 fix) |
|
|
| 20.15 |
Calculator Icon — icon images load |
Icon carousel loads loan type icons (no broken images) |
|
|
| 20.16 |
Calculator — form validation on Apply |
Missing required fields show validation messages |
|
|
| 20.17 |
Calculator — Irish labels (deep) |
All labels including frequency, currency, errors appear in Irish |
|
|
| 20.18 |
CommonBondRange lookup |
Postcode/eligibility lookup returns correct results (if table populated) |
|
|
21. Error Handling — Deep Testing (P2)
Extends section 14 with production vs development mode, API errors, and graceful degradation.
| # |
Test Case |
Expected |
Status |
Notes |
| 21.1 |
404 — custom HTML page served |
Non-existent URL → branded 404, not generic IIS/Kestrel error |
|
|
| 21.2 |
404 — correct HTTP status code |
404 page returns HTTP 404, not 200 (soft 404) |
|
|
| 21.3 |
500 — custom error page (production) |
ASPNETCORE_ENVIRONMENT=Production → branded 500.html |
|
|
| 21.4 |
500 — developer exception page (development) |
ASPNETCORE_ENVIRONMENT=Development → full stack trace |
|
|
| 21.5 |
Form — server validation error |
Server-side validation failure → error in same page, form not cleared |
|
|
| 21.6 |
Calculator API — error response |
Non-200 API response → UI shows error state, not NaN or hang |
|
|
| 21.7 |
Media not found |
Deleted media URL → 404 page, not unhandled exception |
|
|
| 21.8 |
Unpublished content URL |
Unpublished node URL → 404 page |
|
|
| 21.9 |
JS error — page still usable |
Component JS error → remaining components still function |
|
|
| 21.10 |
Form resubmission on refresh |
After form submit, page refresh doesn't silently double-submit |
|
|
22. Accessibility (P2)
Critical accessibility barriers. Use axe DevTools, VoiceOver (macOS/iOS), or NVDA (Windows).
Note: Accessibility review was not part of the migration scope. The tests below are provided for reference and can be addressed as a separate project if requested.
| # |
Test Case |
Expected |
Status |
Notes |
| 22.1 |
Keyboard navigation — tab order |
Tab moves in logical reading order |
|
|
| 22.2 |
Skip navigation link |
First Tab activates "Skip to main content" link |
|
|
| 22.3 |
Navigation menu — keyboard accessible |
All menu items reachable with Tab + Enter |
|
|
| 22.4 |
Hamburger menu — keyboard toggle |
Button focusable, Enter/Space toggles menu |
|
|
| 22.5 |
Accordion — keyboard expand/collapse |
Tab to header → Enter/Space toggles |
|
|
| 22.6 |
Modal/popup — focus trap |
Focus moves into modal; Tab cycles within; Escape closes |
|
|
| 22.7 |
Images — alt text present |
All <img> have alt; decorative images have alt="" |
|
|
| 22.8 |
Form fields — labels associated |
Every input has <label> via for/id or aria-label |
|
|
| 22.9 |
Form errors — announced to screen reader |
Errors linked via aria-describedby or ARIA live region |
|
|
| 22.10 |
Color contrast — body text |
Body text meets WCAG AA (4.5:1 minimum) |
|
|
| 22.11 |
Color contrast — buttons |
Button text contrast meets WCAG AA |
|
|
| 22.12 |
Focus indicator visible |
All interactive elements show visible focus ring |
|
|
| 22.13 |
ARIA roles on landmarks |
Page has <header>, <nav>, <main>, <footer> landmarks |
|
|
| 22.14 |
Carousel — accessible controls |
Arrows have descriptive aria-label, keyboard-focusable |
|
|
| 22.15 |
Heading hierarchy |
Each page has exactly one <h1>; h1 > h2 > h3 logical |
|
|
23. Email Notifications (P1)
25 v8 Umbraco Forms email templates converted (commits 782d347, a70bb0c). Test with real email addresses.
Note: The notification system is migrated but SMTP must be configured by the client in their hosting environment. These tests require a working SMTP configuration.
| # |
Test Case |
Expected |
Status |
Notes |
| 23.1 |
Contact form — email received |
Submit contact form → email arrives within 2 minutes |
|
|
| 23.2 |
Email — correct recipient |
Email received at configured address, not hardcoded dev address |
|
|
| 23.3 |
Email — subject line correct |
Subject matches template configuration |
|
|
| 23.4 |
Email — form field values in body |
All submitted values appear correctly in email body |
|
|
| 23.5 |
Email — HTML formatting |
Email renders as formatted HTML in Gmail/Outlook |
|
|
| 23.6 |
Email — no HttpContext.Current error |
No server error on form submit (v8 pattern fix) |
|
|
| 23.7 |
Email — no broken images |
Logo/header images in template render or are absent, no broken placeholders |
|
|
| 23.8 |
Popup form — email sent |
Submit via popup → email received |
|
|
| 23.9 |
Loan enquiry form — email sent |
Submit loan enquiry → email received with correct subject |
|
|
| 23.10 |
Reply-to header set correctly |
"Reply" in email client addresses the form submitter, not system sender |
|
|
| 23.11 |
Email — no duplicate sends |
Form submit produces exactly one email |
|
|
24. SEO — Deep Testing (P2)
Extends section 3.9 with structured data, canonical URLs, and meta tags.
| # |
Test Case |
Expected |
Status |
Notes |
| 24.1 |
<title> tag — unique per page |
Homepage, article, FAQ each have distinct <title> |
|
|
| 24.2 |
Meta description present |
<meta name="description"> populated on key pages |
|
|
| 24.3 |
Canonical URL tag |
<link rel="canonical"> matches page URL on all pages |
|
|
| 24.4 |
Open Graph — title |
<meta property="og:title"> present and matches title |
|
|
| 24.5 |
Open Graph — description |
<meta property="og:description"> populated |
|
|
| 24.6 |
Open Graph — image |
<meta property="og:image"> resolves to accessible image URL |
|
|
| 24.7 |
Open Graph — type |
og:type = website (general) or article (news) |
|
|
| 24.8 |
FAQ Schema.org — FAQPage |
FAQ pages have <script type="application/ld+json"> with valid FAQPage schema |
|
|
| 24.9 |
FAQ schema — question/answer pairs |
Each question appears as mainEntity with acceptedAnswer |
|
|
| 24.10 |
hreflang tags — English |
<link rel="alternate" hreflang="en"> present on English pages |
|
|
| 24.11 |
hreflang tags — Irish |
<link rel="alternate" hreflang="ga"> on bilingual pages |
|
|
| 24.12 |
Robots meta tag |
Indexable pages do NOT have noindex |
|
|
| 24.13 |
Sitemap — all public pages listed |
/sitemap.xml includes all published pages, no member-only pages |
|
|
| 24.14 |
Sitemap — correct <loc> values |
<loc> entries use production domain, not localhost |
|
|
| 24.15 |
Robots.txt — no important pages blocked |
/robots.txt doesn't block /, /news/, etc. |
|
|
25. Third-Party Integrations (P2)
v8 used several third-party services. Mapbox API key moved to appsettings.json. Verify integrations work in v17.
| # |
Test Case |
Expected |
Status |
Notes |
| 25.1 |
Mapbox map — loads |
Map tile layer renders, no API key error |
|
|
| 25.2 |
Mapbox — correct location pin |
Pin at correct address for this client |
|
|
| 25.3 |
Mapbox — no API key in page source |
Token not hardcoded in HTML/JS; loaded from appsettings.json |
|
|
| 25.4 |
Google Analytics (GA4) — tag present |
GA4 gtag.js or GTM snippet in <head> |
|
|
| 25.5 |
GA4 — page view fires |
GA4 Realtime shows page view on homepage load |
|
|
| 25.6 |
GA4 — no double-fire |
Each navigation fires exactly one page_view event |
|
|
| 25.7 |
Trustpilot widget |
Widget loads and displays review score |
|
|
| 25.8 |
Facebook/social embed |
Embeds load without console errors |
|
|
| 25.9 |
Twitter/X embed |
Tweet embeds render |
|
|
| 25.10 |
YouTube — consent-aware loading |
YouTube iframes respect cookie consent (if consent-aware) |
|
|
| 25.11 |
Obsoleted widgets — no broken placeholders |
Pages don't have broken placeholders from removed third-party widgets |
|
|
| 25.12 |
Umbraco Forms — anti-forgery token |
Form POST includes anti-forgery token, no HTTP 400 on first submit |
|
|
26. Security (P2)
ScriptHelper has CSP nonce support scaffolded but not yet activated. HTTPS enforced via hosting.
Note: Security testing and penetration testing were not part of the migration scope. The tests below are basic checks only.
| # |
Test Case |
Expected |
Status |
Notes |
| 26.1 |
HTTPS enforced — HTTP redirects |
http:// → automatic redirect to https:// |
|
|
| 26.2 |
HTTPS — valid TLS certificate |
Certificate valid, not expired, no mixed-content warnings |
|
|
| 26.3 |
HSTS header |
Strict-Transport-Security header present |
|
|
| 26.4 |
X-Frame-Options or CSP frame-ancestors |
Clickjacking protection present |
|
|
| 26.5 |
X-Content-Type-Options |
nosniff header present |
|
|
| 26.6 |
No sensitive data in page source |
No connection strings, API keys, or internal paths visible |
|
|
| 26.7 |
Backoffice — not publicly browsable |
/umbraco/api/ endpoints require auth; unauthenticated → 401 |
|
|
| 26.8 |
Member-only content — protected |
Direct URL to CustomerOnlyPage1 without session → 401 or redirect |
|
|
| 26.9 |
Form — XSS input rejected or escaped |
<script>alert(1)</script> in form field → escaped, not executed |
|
|
| 26.10 |
Anti-forgery token on all POST forms |
All forms have __RequestVerificationToken hidden field |
|
|
| 26.11 |
Referrer-Policy header |
Referrer-Policy header present |
|
|
| 26.12 |
CSP nonce scaffolding |
ScriptHelper-rendered <script> tags have nonce attribute |
|
|
Page-level and user-perceived performance. Run against warm server using Lighthouse and DevTools.
Note: Performance testing was not part of the migration scope. The tests below are provided as baseline checks for the client's QA process.
| # |
Test Case |
Expected |
Status |
Notes |
| 27.1 |
Homepage LCP |
Lighthouse LCP <= 2.5s desktop, <= 4s mobile |
|
|
| 27.2 |
Homepage CLS |
Lighthouse CLS <= 0.1; no visible layout jumps |
|
|
| 27.3 |
Homepage INP |
Lighthouse INP <= 200ms |
|
|
| 27.4 |
Homepage TTFB |
Network tab: TTFB <= 600ms |
|
|
| 27.5 |
Total page weight — homepage |
Total transferred <= 3 MB on first load |
|
|
| 27.6 |
Total page weight — calculator |
Total transferred <= 4 MB |
|
|
| 27.7 |
No render-blocking resources |
Lighthouse: no critical CSS/JS blocking first paint |
|
|
| 27.8 |
Images served at correct size |
Lighthouse: no images at 3x display resolution without srcset |
|
|
| 27.9 |
Gzip / Brotli compression |
Content-Encoding: br or gzip on HTML/JS/CSS |
|
|
| 27.10 |
Static assets — long cache lifetime |
Hashed assets have long Cache-Control TTL |
|
|
| 27.11 |
AOS vendor files served locally |
aos.min.js and aos.min.css from same origin (commit 9d2c1cf) |
|
|
| 27.12 |
Slick carousel served locally |
slick.min.js and slick.css from local /vendor/ |
|
|
Summary
| Section |
Test Cases |
Priority |
| 1. Navigation & Layout |
11 |
P0 |
| 2. Homepage & Sliders |
7 |
P0 |
| 3. Images & Media |
9 |
P0 |
| 4. Calculators |
13 |
P1 |
| 5. Forms |
9 |
P1 |
| 6. News & Articles |
8 |
P1 |
| 7. Accordion & FAQ |
5 |
P1 |
| 8. Login & Authentication |
5 |
P1 |
| 9. Testimonials |
4 |
P2 |
| 10. Maps & Addresses |
4 |
P2 |
| 11. Cache Busting & Performance |
4 |
P2 |
| 12. Multi-Language / Irish |
6 |
P2 |
| 13. Responsive / Mobile |
7 |
P2 |
| 14. Error Handling |
4 |
P3 |
| 15. Backoffice |
7 |
P3 |
| 16. Two-Factor Authentication / 2FA |
14 |
P1 |
| 17. User Migration Verification |
11 |
P1 |
| 18. Content Migration Verification |
17 |
P1 |
| 19. Data Protection / GDPR |
12 |
P1 |
| 20. Calculator — Deep Testing |
18 |
P1 |
| 21. Error Handling — Deep Testing |
10 |
P2 |
| 22. Accessibility |
15 |
P2 |
| 23. Email Notifications |
11 |
P1 |
| 24. SEO — Deep Testing |
15 |
P2 |
| 25. Third-Party Integrations |
12 |
P2 |
| 26. Security |
12 |
P2 |
| 27. Performance |
12 |
P2 |
| Total |
251 |
|