@@ -74,6 +74,19 @@ function isHydrationMismatch(message: ConsoleMessage): boolean {
7474 return HYDRATION_MISMATCH_PATTERNS . some ( pattern => text . includes ( pattern ) )
7575}
7676
77+ /**
78+ * Detect Content-Security-Policy violations logged to the console.
79+ *
80+ * Browsers log CSP violations as console errors with a distinctive prefix.
81+ * Catching these in e2e tests ensures new external resources are added to the
82+ * CSP before they land in production.
83+ */
84+ function isCspViolation ( message : ConsoleMessage ) : boolean {
85+ if ( message . type ( ) !== 'error' ) return false
86+ const text = message . text ( )
87+ return text . includes ( 'Content-Security-Policy' ) || text . includes ( 'content security policy' )
88+ }
89+
7790/**
7891 * Extended test fixture with automatic external API mocking and hydration mismatch detection.
7992 *
@@ -83,7 +96,11 @@ function isHydrationMismatch(message: ConsoleMessage): boolean {
8396 * Hydration mismatches are detected via Vue's console.error output, which is always
8497 * emitted in production builds when server-rendered HTML doesn't match client expectations.
8598 */
86- export const test = base . extend < { mockExternalApis : void ; hydrationErrors : string [ ] } > ( {
99+ export const test = base . extend < {
100+ mockExternalApis : void
101+ hydrationErrors : string [ ]
102+ cspViolations : string [ ]
103+ } > ( {
87104 mockExternalApis : [
88105 async ( { page } , use ) => {
89106 await setupRouteMocking ( page )
@@ -103,6 +120,18 @@ export const test = base.extend<{ mockExternalApis: void; hydrationErrors: strin
103120
104121 await use ( errors )
105122 } ,
123+
124+ cspViolations : async ( { page } , use ) => {
125+ const violations : string [ ] = [ ]
126+
127+ page . on ( 'console' , message => {
128+ if ( isCspViolation ( message ) ) {
129+ violations . push ( message . text ( ) )
130+ }
131+ } )
132+
133+ await use ( violations )
134+ } ,
106135} )
107136
108137export { expect }
0 commit comments