1+ import puppeteer from 'puppeteer' ;
2+ import fs from 'fs' ;
3+ import path from 'path' ;
4+ import { fileURLToPath } from 'url' ;
5+
6+ const __filename = fileURLToPath ( import . meta. url ) ;
7+ const __dirname = path . dirname ( __filename ) ;
8+
9+ async function captureBrowserResults ( testFile = 'comprehensive-browser-verification.html' ) {
10+ console . log ( 'Starting browser test capture...' ) ;
11+
12+ const browser = await puppeteer . launch ( {
13+ headless : false ,
14+ defaultViewport : { width : 1920 , height : 1080 }
15+ } ) ;
16+
17+ try {
18+ const page = await browser . newPage ( ) ;
19+
20+ // Navigate to our test file
21+ const testFilePath = path . resolve ( __dirname , testFile ) ;
22+ await page . goto ( `file://${ testFilePath } ` ) ;
23+
24+ console . log ( 'Waiting for tests to complete...' ) ;
25+
26+ // Wait for tests to finish (look for results element)
27+ await page . waitForSelector ( '#results' , { timeout : 30000 } ) ;
28+
29+ // Wait a bit more for all tests to complete
30+ await new Promise ( resolve => setTimeout ( resolve , 3000 ) ) ;
31+
32+ // Capture browser info
33+ const browserInfo = await page . evaluate ( ( ) => {
34+ // eslint-disable-next-line no-undef
35+ const infoElement = document . getElementById ( 'browser-info' ) ;
36+ return infoElement ? infoElement . innerText : 'Browser info not found' ;
37+ } ) ;
38+
39+ // Capture expressions results
40+ const expressions = await page . evaluate ( ( ) => {
41+ // eslint-disable-next-line no-undef
42+ const expressionResults = document . querySelectorAll ( '.expression-result' ) ;
43+ const results = [ ] ;
44+
45+ expressionResults . forEach ( ( result , index ) => {
46+ const expression = result . querySelector ( '.expression' ) ?. innerText || `Expression ${ index } ` ;
47+ const resultValue = result . querySelector ( '.result' ) ?. innerText || '' ;
48+ const type = result . querySelector ( '.type' ) ?. innerText || '' ;
49+ const error = result . querySelector ( '.error' ) ?. innerText || '' ;
50+
51+ results . push ( {
52+ expression,
53+ result : resultValue ,
54+ type : type . replace ( 'Type: ' , '' ) ,
55+ error : error . replace ( 'Error: ' , '' )
56+ } ) ;
57+ } ) ;
58+
59+ return results ;
60+ } ) ;
61+
62+ // Create test results format for compatibility
63+ const testResults = expressions . map ( expr => ( {
64+ testName : expr . expression ,
65+ status : expr . error ? '✗ FAIL' : '✓ PASS' ,
66+ expectedType : '' ,
67+ actualType : expr . type ,
68+ expectedValue : '' ,
69+ actualValue : expr . result ,
70+ error : expr . error ,
71+ comparison : expr . error ? `Browser throws: ${ expr . error } ` : `Browser returns: ${ expr . result } ` ,
72+ behaviorNote : ''
73+ } ) ) ;
74+
75+ const summary = `Total: ${ testResults . length } | Passed: ${ testResults . filter ( r => r . status === '✓ PASS' ) . length } | Failed: ${ testResults . filter ( r => r . status === '✗ FAIL' ) . length } ` ;
76+
77+ // Generate report
78+ const report = {
79+ timestamp : new Date ( ) . toISOString ( ) ,
80+ browserInfo,
81+ summary,
82+ testResults
83+ } ;
84+
85+ // Save detailed report
86+ const reportPath = path . join ( __dirname , 'browser-test-results.json' ) ;
87+ fs . writeFileSync ( reportPath , JSON . stringify ( report , null , 2 ) ) ;
88+
89+ // Generate human-readable report
90+ const humanReadableReport = generateHumanReadableReport ( report ) ;
91+ const humanReportPath = path . join ( __dirname , 'browser-test-results.txt' ) ;
92+ fs . writeFileSync ( humanReportPath , humanReadableReport ) ;
93+
94+ console . log ( '\n=== BROWSER TEST RESULTS ===' ) ;
95+ console . log ( browserInfo ) ;
96+ console . log ( '\n' + summary ) ;
97+ console . log ( '\nDetailed results saved to:' ) ;
98+ console . log ( '- browser-test-results.json (structured data)' ) ;
99+ console . log ( '- browser-test-results.txt (human readable)' ) ;
100+
101+ // Show some key findings
102+ const passed = testResults . filter ( r => r . status . includes ( 'PASS' ) ) . length ;
103+ const failed = testResults . filter ( r => r . status . includes ( 'FAIL' ) ) . length ;
104+ const warnings = testResults . filter ( r => r . status . includes ( 'WARNING' ) ) . length ;
105+ const skipped = testResults . filter ( r => r . status . includes ( 'SKIP' ) ) . length ;
106+
107+ console . log ( `\n=== KEY FINDINGS ===` ) ;
108+ console . log ( `Passed: ${ passed } ` ) ;
109+ console . log ( `Failed: ${ failed } ` ) ;
110+ console . log ( `Warnings: ${ warnings } ` ) ;
111+ console . log ( `Skipped: ${ skipped } ` ) ;
112+
113+ // Show some interesting discrepancies
114+ const discrepancies = testResults . filter ( r =>
115+ r . status . includes ( 'WARNING' ) ||
116+ ( r . status . includes ( 'PASS' ) && r . comparison && ! r . comparison . includes ( 'Expected' ) )
117+ ) ;
118+
119+ if ( discrepancies . length > 0 ) {
120+ console . log ( `\n=== INTERESTING DISCREPANCIES ===` ) ;
121+ discrepancies . slice ( 0 , 10 ) . forEach ( d => {
122+ console . log ( `\n${ d . testName } :` ) ;
123+ console . log ( ` Expected: ${ d . expectedType } - ${ d . expectedValue } ` ) ;
124+ console . log ( ` Actual: ${ d . actualType } - ${ d . actualValue } ` ) ;
125+ if ( d . comparison ) console . log ( ` Browser: ${ d . comparison } ` ) ;
126+ } ) ;
127+ }
128+
129+ } catch ( error ) {
130+ console . error ( 'Error capturing browser results:' , error ) ;
131+ } finally {
132+ await browser . close ( ) ;
133+ }
134+ }
135+
136+ function generateHumanReadableReport ( report ) {
137+ let output = '' ;
138+
139+ output += 'CSS TYPED OM BROWSER VERIFICATION RESULTS\n' ;
140+ output += '==========================================\n\n' ;
141+ output += `Timestamp: ${ report . timestamp } \n\n` ;
142+
143+ output += 'BROWSER INFORMATION\n' ;
144+ output += '-------------------\n' ;
145+ output += report . browserInfo + '\n\n' ;
146+
147+ output += 'SUMMARY\n' ;
148+ output += '-------\n' ;
149+ output += report . summary + '\n\n' ;
150+
151+ output += 'DETAILED TEST RESULTS\n' ;
152+ output += '---------------------\n' ;
153+
154+ const categories = { } ;
155+ report . testResults . forEach ( result => {
156+ const category = result . testName . split ( ':' ) [ 0 ] ;
157+ if ( ! categories [ category ] ) categories [ category ] = [ ] ;
158+ categories [ category ] . push ( result ) ;
159+ } ) ;
160+
161+ Object . entries ( categories ) . forEach ( ( [ category , tests ] ) => {
162+ output += `\n${ category . toUpperCase ( ) } \n` ;
163+ output += '-' . repeat ( category . length ) + '\n' ;
164+
165+ tests . forEach ( test => {
166+ output += `\n${ test . testName } \n` ;
167+ output += ` Status: ${ test . status } \n` ;
168+ output += ` Expected Type: ${ test . expectedType } \n` ;
169+ output += ` Actual Type: ${ test . actualType } \n` ;
170+ output += ` Expected Value: ${ test . expectedValue } \n` ;
171+ output += ` Actual Value: ${ test . actualValue } \n` ;
172+
173+ if ( test . error ) output += ` Error: ${ test . error } \n` ;
174+ if ( test . comparison ) output += ` Browser Behavior: ${ test . comparison } \n` ;
175+ if ( test . behaviorNote ) output += ` Note: ${ test . behaviorNote } \n` ;
176+ } ) ;
177+ } ) ;
178+
179+ return output ;
180+ }
181+
182+ // Run the capture
183+ const testFile = process . argv [ 2 ] || 'comprehensive-browser-verification.html' ;
184+ captureBrowserResults ( testFile ) . catch ( console . error ) ;
0 commit comments