@@ -2,88 +2,150 @@ import { test, expect, Page } from '@playwright/test';
22import { cloneAndGetLatestTag } from './getTags' ;
33import { compareCSVFiles } from './compareCSV' ;
44
5-
6-
75export async function testEEcircuit ( page : Page , url : string ) {
8- const consoleErrors : string [ ] = [ ] ;
9-
10- let isSimCompleted : boolean = false ;
11-
12- // Listen for console errors
13- page . on ( 'console' , ( msg : any ) => {
14- if ( msg . type ( ) === 'error' ) {
15- consoleErrors . push ( msg . text ( ) ) ;
16- console . log ( 'Error:' , msg . text ( ) ) ;
6+ const consoleErrors : string [ ] = [ ] ;
7+ const allRequests : {
8+ url : string ;
9+ method : string ;
10+ status ?: number ;
11+ headers ?: Record < string , string > ;
12+ responseHeaders ?: Record < string , string > ;
13+ fromCache ?: boolean ;
14+ } [ ] = [ ] ;
15+
16+ let isSimCompleted = false ;
17+
18+ // Capture console errors / logs
19+ page . on ( 'console' , ( msg ) => {
20+ const t = msg . type ( ) ;
21+ const text = msg . text ( ) ;
22+ console . log ( `[console:${ t } ] ${ text } ` ) ;
23+ if ( t === 'error' ) {
24+ consoleErrors . push ( text ) ;
25+ }
26+ if ( text . startsWith ( 'Simulation run completed' ) ) {
27+ isSimCompleted = true ;
28+ }
29+ } ) ;
30+
31+ // Capture network requests & responses
32+ page . on ( 'requestfinished' , async ( request ) => {
33+ try {
34+ const response = await request . response ( ) ;
35+ // Safely detect whether the response was served from cache; Playwright's Response type may not include fromCache in typings.
36+ const resAny = response as any ;
37+ let fromCache = false ;
38+ if ( resAny ) {
39+ if ( typeof resAny . fromCache === 'function' ) {
40+ try {
41+ fromCache = resAny . fromCache ( ) ;
42+ } catch {
43+ fromCache = false ;
44+ }
45+ } else if ( typeof resAny . fromCache === 'boolean' ) {
46+ fromCache = resAny . fromCache ;
47+ } else if ( typeof resAny . fromServiceWorker === 'boolean' ) {
48+ // some Playwright versions expose different flags; use as fallback
49+ fromCache = resAny . fromServiceWorker ;
1750 }
18-
19- if ( msg . text ( ) . startsWith ( 'Simulation run completed' ) ) {
20- isSimCompleted = true ;
21-
22- } ;
23- } ) ;
24-
25- // Function to wait for the simulation to complete
26- function waitForSimCompletion ( ) : Promise < void > {
27- return new Promise ( ( resolve ) => {
28- const checkCompletion = ( ) => {
29- if ( isSimCompleted ) {
30- resolve ( ) ;
31- } else {
32- // Re-check after the next console message or event loop tick
33- page . once ( 'console' , checkCompletion ) ;
34- }
35- } ;
36- checkCompletion ( ) ;
37- } ) ;
51+ }
52+ const reqInfo = {
53+ url : request . url ( ) ,
54+ method : request . method ( ) ,
55+ status : response ?. status ( ) ,
56+ headers : request . headers ( ) ,
57+ responseHeaders : response ?. headers ( ) ,
58+ fromCache,
59+ } ;
60+ allRequests . push ( reqInfo ) ;
61+ console . log ( `[req finished] ${ reqInfo . method } ${ reqInfo . url } => ${ reqInfo . status } ` ) ;
62+ } catch ( err ) {
63+ console . log ( '[reqfinished] error capturing response:' , err ) ;
3864 }
65+ } ) ;
66+
67+ page . on ( 'requestfailed' , ( request ) => {
68+ console . log ( `[req failed] ${ request . method ( ) } ${ request . url ( ) } — ${ request . failure ( ) ?. errorText } ` ) ;
69+ allRequests . push ( {
70+ url : request . url ( ) ,
71+ method : request . method ( ) ,
72+ status : undefined ,
73+ headers : request . headers ( ) ,
74+ responseHeaders : undefined ,
75+ fromCache : false ,
76+ } ) ;
77+ } ) ;
78+
79+ // Helper to wait for simulation completion via console
80+ function waitForSimCompletion ( ) : Promise < void > {
81+ return new Promise ( ( resolve ) => {
82+ if ( isSimCompleted ) {
83+ return resolve ( ) ;
84+ }
85+ const listener = ( ) => {
86+ if ( isSimCompleted ) {
87+ resolve ( ) ;
88+ } else {
89+ page . once ( 'console' , listener ) ;
90+ }
91+ } ;
92+ page . once ( 'console' , listener ) ;
93+ } ) ;
94+ }
3995
96+ // Start
97+ console . log ( '*** Navigating to URL:' , url ) ;
98+ const resp = await page . goto ( url , { waitUntil : 'networkidle' } ) ;
99+ console . log ( 'Page.goto response status:' , resp ?. status ( ) , 'url:' , resp ?. url ( ) ) ;
40100
41- await page . goto ( url ) ;
42-
43- await expect ( page ) . toHaveTitle ( / E E c i r c u i t / ) ;
44-
45- await page . getByRole ( 'button' , { name : 'Run' } ) . click ( ) ;
46-
47- await page . getByRole ( 'button' , { name : 'De-select all' } ) . click ( ) ;
48- await page . getByRole ( 'button' , { name : 'Select all' , exact : true } ) . click ( ) ;
49- await page . getByRole ( 'button' , { name : 'De-select all' } ) . click ( ) ;
50- await page . locator ( 'label' ) . filter ( { hasText : 'v(2)' } ) . locator ( 'span' ) . first ( ) . click ( ) ;
51- await page . getByRole ( 'button' , { name : 'Colorize' } ) . click ( ) ;
52- await page . getByRole ( 'button' , { name : 'Reset' } ) . click ( ) ;
53- await page . getByRole ( 'button' , { name : 'Settings' } ) . click ( ) ;
54- //await page.getByLabel('Close').click();
55-
56- await page . getByRole ( 'button' , { name : 'Run' } ) . click ( ) ;
101+ await expect ( page ) . toHaveTitle ( / E E c i r c u i t / ) ;
57102
58- await page . waitForTimeout ( 1000 ) ;
59- expect ( consoleErrors . length ) . toBe ( 0 ) ;
103+ // Now perform UI actions
104+ await page . getByRole ( 'button' , { name : 'Run' } ) . click ( ) ;
105+ await page . getByRole ( 'button' , { name : 'De-select all' } ) . click ( ) ;
106+ await page . getByRole ( 'button' , { name : 'Select all' , exact : true } ) . click ( ) ;
107+ await page . getByRole ( 'button' , { name : 'De-select all' } ) . click ( ) ;
108+ await page . locator ( 'label' ) . filter ( { hasText : 'v(2)' } ) . locator ( 'span' ) . first ( ) . click ( ) ;
109+ await page . getByRole ( 'button' , { name : 'Colorize' } ) . click ( ) ;
110+ await page . getByRole ( 'button' , { name : 'Reset' } ) . click ( ) ;
111+ await page . getByRole ( 'button' , { name : 'Settings' } ) . click ( ) ;
112+ await page . getByRole ( 'button' , { name : 'Run' } ) . click ( ) ;
60113
61- await page . getByRole ( 'tab' , { name : 'Info' } ) . click ( ) ;
114+ // Small wait to allow requests to fire
115+ await page . waitForTimeout ( 1000 ) ;
62116
63- // Wait for simulation to complete without using a timeout
64- await waitForSimCompletion ( ) ;
117+ console . log ( 'Console errors so far:' , consoleErrors ) ;
118+ expect ( consoleErrors . length , 'there were console errors' ) . toBe ( 0 ) ;
65119
66- const text = await page . getByLabel ( 'info ', { exact : true } ) . inputValue ( ) ;
120+ await page . getByRole ( 'tab ', { name : 'Info' } ) . click ( ) ;
67121
68- const match = text . match ( / n g s p i c e - ( \d + ) / ) ;
69- const number = match ? parseInt ( match [ 1 ] ) : null ;
122+ await waitForSimCompletion ( ) ;
123+ console . log ( 'Simulation completed per console log' ) ;
70124
71- console . log ( 'ngspice version from EEcircuit:' , number ) ;
125+ const text = await page . getByLabel ( 'info' , { exact : true } ) . inputValue ( ) ;
126+ console . log ( 'Info tab content:' , text ) ;
72127
73- const tag = await cloneAndGetLatestTag ( 'https://github.com/danchitnis/ngspice-sf-mirror' , './tests/repos' ) ;
128+ const match = text . match ( / n g s p i c e - ( \d + ) / ) ;
129+ const number = match ? parseInt ( match [ 1 ] ) : null ;
130+ console . log ( 'Parsed ngspice version from UI:' , number ) ;
74131
75- const version = parseInt ( tag ?. split ( '-' ) [ 1 ] ?? '' ) ;
132+ const tag = await cloneAndGetLatestTag ( 'https://github.com/danchitnis/ngspice-sf-mirror' , './tests/repos' ) ;
133+ const version = parseInt ( tag ?. split ( '-' ) [ 1 ] ?? '' ) ;
134+ console . log ( 'Latest ngspice version from repo:' , version ) ;
76135
77- console . log ( 'ngspice version from repo:' , version ) ;
136+ expect ( number ) . toBe ( version ) ;
78137
79- expect ( number ) . toBe ( version ) ;
138+ await page . getByRole ( 'tab' , { name : 'CSV' } ) . click ( ) ;
139+ const downloadPromise = page . waitForEvent ( 'download' ) ;
140+ await page . getByRole ( 'button' , { name : 'Download' } ) . click ( ) ;
80141
81- await page . getByRole ( 'tab' , { name : 'CSV' } ) . click ( ) ;
82- const downloadPromise = page . waitForEvent ( 'download' ) ;
83- await page . getByRole ( 'button' , { name : 'Download' } ) . click ( ) ;
142+ const download = await downloadPromise ;
143+ console . log ( 'Download started, suggested filename:' , download . suggestedFilename ( ) ) ;
144+ await download . saveAs ( './tests/output/' + download . suggestedFilename ( ) ) ;
84145
85- const download = await downloadPromise ;
86- await download . saveAs ( './tests/output/' + download . suggestedFilename ( ) ) ;
146+ const outPath = './tests/output/' + download . suggestedFilename ( ) ;
147+ console . log ( 'Saved CSV to:' , outPath ) ;
87148
88- const compare = await compareCSVFiles ( './tests/lib/EEcircuit.csv' , './tests/output/' + download . suggestedFilename ( ) ) ;
89- }
149+ const compare = await compareCSVFiles ( './tests/lib/EEcircuit.csv' , outPath ) ;
150+ console . log ( 'CSV compare result:' , compare ) ;
151+ }
0 commit comments