11/**
22 * Service Detail Page E2E Tests
33 * Tests for individual service pages
4- * Note: Tests are generated dynamically per service
4+ * Note: Tests are dynamically generated for each service
55 */
66import { test , expect } from '@playwright/test'
7+ import { setupConsoleErrorChecker } from '@test/e2e/helpers/console-errors'
78
8- test . describe ( 'Service Detail Page' , ( ) => {
9- test . skip ( '@wip service page loads with content' , async ( { page } ) => {
10- // Expected: Service page should load with title and content
11- // Actual: Unknown - needs testing
12- // Note: Will dynamically generate tests per service
13- await page . goto ( '/services/example-service' )
14- await expect ( page . locator ( 'h1' ) ) . toBeVisible ( )
15- } )
9+ /**
10+ * Create a test suite for a specific service
11+ */
12+ function createServiceTests ( serviceId : string , serviceTitle : string ) {
13+ const serviceUrl = `/services/${ serviceId } `
1614
17- test . skip ( '@wip service overview section displays' , async ( { page } ) => {
18- // Expected: Should show service overview/description
19- // Actual: Unknown - needs testing
20- await page . goto ( '/services/example-service' )
21- await expect ( page . locator ( 'article, .service-content' ) ) . toBeVisible ( )
22- } )
15+ test . describe ( `Service: ${ serviceTitle } ` , ( ) => {
16+ test ( '@ready service page loads with content' , async ( { page } ) => {
17+ await page . goto ( serviceUrl )
18+ await page . waitForLoadState ( 'networkidle' )
2319
24- test . skip ( '@wip features/benefits list present' , async ( { page } ) => {
25- // Expected: Should show list of features or benefits
26- // Actual: Unknown - needs testing
27- await page . goto ( '/services/example-service' )
28- // Check for features list
29- } )
20+ // Page should have main content
21+ const main = page . locator ( 'main' )
22+ await expect ( main ) . toBeVisible ( )
3023
31- test . skip ( '@wip pricing information displays' , async ( { page } ) => {
32- // Expected: Should show pricing or consultation info
33- // Actual: Unknown - needs testing
34- await page . goto ( '/services/example-service' )
35- // Check for pricing section
36- } )
24+ // Should have h1 heading (page may have multiple h1 in suggested services, use first)
25+ const heading = page . locator ( 'h1' ) . first ( )
26+ await expect ( heading ) . toBeVisible ( )
3727
38- test . skip ( '@wip contact CTA present' , async ( { page } ) => {
39- // Expected: Should have CTA to contact or get started
40- // Actual: Unknown - needs testing
41- await page . goto ( '/services/example-service' )
42- const cta = page . locator ( 'a[href*="contact"], button:has-text("Contact")' )
43- // CTA may not always be present
44- } )
28+ // Should have article container with id (main article, not carousel articles)
29+ const article = page . locator ( 'article[itemscope]' )
30+ await expect ( article ) . toBeVisible ( )
31+ } )
4532
46- test . skip ( '@wip related services carousel displays' , async ( { page } ) => {
47- // Expected: Should show related services if applicable
48- // Actual: Unknown - needs testing
49- await page . goto ( '/services/example-service' )
50- // Check for carousel
51- } )
33+ test ( '@ready service title displays correctly' , async ( { page } ) => {
34+ await page . goto ( serviceUrl )
35+ // Use the main article heading, not headings from suggested services carousel
36+ const heading = page . locator ( 'h1#article-title' )
37+ await expect ( heading ) . toContainText ( serviceTitle )
38+ } )
39+
40+ test ( '@ready service content renders' , async ( { page } ) => {
41+ await page . goto ( serviceUrl )
5242
53- test . skip ( '@wip page has no console errors' , async ( { page } ) => {
54- // Expected: No console errors on page load
55- // Actual: Unknown - needs testing
56- await page . goto ( '/services/example-service' )
57- const errors : string [ ] = [ ]
58- page . on ( 'console' , ( msg ) => {
59- if ( msg . type ( ) === 'error' ) errors . push ( msg . text ( ) )
43+ // Should have content paragraphs
44+ const content = page . locator ( 'article p' )
45+ await expect ( content . first ( ) ) . toBeVisible ( )
46+ } )
47+
48+ test ( '@ready suggested services carousel displays' , async ( { page } ) => {
49+ await page . goto ( serviceUrl )
50+
51+ // Carousel should be present (if there are other services)
52+ const carousel = page . locator ( '.embla' )
53+ // Carousel only shows if there are other services, so check count
54+ const count = await carousel . count ( )
55+ if ( count > 0 ) {
56+ await expect ( carousel . first ( ) ) . toBeVisible ( )
57+ }
58+ } )
59+
60+ test ( '@ready page has no console errors' , async ( { page } ) => {
61+ const errorChecker = setupConsoleErrorChecker ( page )
62+ await page . goto ( serviceUrl )
63+ await page . waitForLoadState ( 'networkidle' )
64+
65+ const filtered404s = errorChecker . getFiltered404s ( )
66+ expect ( filtered404s . length ) . toBe ( 0 )
67+ } )
68+
69+ test ( '@ready page has no 404 errors' , async ( { page } ) => {
70+ const errorChecker = setupConsoleErrorChecker ( page )
71+ await page . goto ( serviceUrl )
72+ await page . waitForLoadState ( 'networkidle' )
73+
74+ const all404s = errorChecker . failed404s
75+ expect ( all404s . length ) . toBe ( 0 )
6076 } )
61- await page . reload ( )
62- expect ( errors ) . toHaveLength ( 0 )
6377 } )
64- } )
78+ }
79+
80+ // Generate tests for known services
81+ createServiceTests ( 'overview' , 'Services Overview' )
82+ createServiceTests ( 'create-custom-font-sets' , 'Create Custom Font Sets' )
0 commit comments