Skip to content

Commit cda74c3

Browse files
committed
Refactor testEEcircuit function to enhance error logging and request tracking
1 parent 31c0c8a commit cda74c3

1 file changed

Lines changed: 129 additions & 67 deletions

File tree

tests/lib/eecircuit-test.ts

Lines changed: 129 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2,88 +2,150 @@ import { test, expect, Page } from '@playwright/test';
22
import { cloneAndGetLatestTag } from './getTags';
33
import { compareCSVFiles } from './compareCSV';
44

5-
6-
75
export 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(/EEcircuit/);
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(/EEcircuit/);
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(/ngspice-(\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(/ngspice-(\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

Comments
 (0)