Skip to content

Commit 5eb5d2a

Browse files
committed
Added script to monitor console and page error
1 parent e424d21 commit 5eb5d2a

5 files changed

Lines changed: 177 additions & 70 deletions

File tree

logs/combined.log

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,3 +371,35 @@
371371
{"level":"info","message":"info","meta":"Test Case Completed : Drag and Drop Status : passed","service":"job-posting-service","timestamp":"2025-10-04T16:46:03.026Z"}
372372
{"level":"info","message":"info","meta":"Executing Step : findElement - WebHelper.findElement ","service":"job-posting-service","timestamp":"2025-10-04T16:46:03.120Z"}
373373
{"level":"info","message":"info","meta":"Test Case Completed : Drag and Drop Using Mouse Hover Status : passed","service":"job-posting-service","timestamp":"2025-10-04T16:46:16.676Z"}
374+
{"level":"info","message":"playwright-framework-template undefined","service":"job-posting-service","timestamp":"2025-10-04T17:04:13.473Z"}
375+
{"level":"info","message":"info","meta":"Test Suite Started : , 1 tests","service":"job-posting-service","timestamp":"2025-10-04T17:04:13.902Z"}
376+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:04:16.866Z"}
377+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : failed","service":"job-posting-service","timestamp":"2025-10-04T17:05:24.097Z"}
378+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:05:29.518Z"}
379+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : failed","service":"job-posting-service","timestamp":"2025-10-04T17:06:58.203Z"}
380+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:07:03.730Z"}
381+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : failed","service":"job-posting-service","timestamp":"2025-10-04T17:08:12.060Z"}
382+
{"level":"info","message":"playwright-framework-template undefined","service":"job-posting-service","timestamp":"2025-10-04T17:09:24.362Z"}
383+
{"level":"info","message":"info","meta":"Test Suite Started : , 1 tests","service":"job-posting-service","timestamp":"2025-10-04T17:09:25.010Z"}
384+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:09:29.480Z"}
385+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : failed","service":"job-posting-service","timestamp":"2025-10-04T17:10:48.751Z"}
386+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:10:56.110Z"}
387+
{"level":"info","message":"playwright-framework-template undefined","service":"job-posting-service","timestamp":"2025-10-04T17:11:39.761Z"}
388+
{"level":"info","message":"info","meta":"Test Suite Started : , 1 tests","service":"job-posting-service","timestamp":"2025-10-04T17:11:40.500Z"}
389+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:11:45.871Z"}
390+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : failed","service":"job-posting-service","timestamp":"2025-10-04T17:14:20.422Z"}
391+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:14:27.887Z"}
392+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : failed","service":"job-posting-service","timestamp":"2025-10-04T17:16:15.670Z"}
393+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:16:20.517Z"}
394+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : interrupted","service":"job-posting-service","timestamp":"2025-10-04T17:18:48.454Z"}
395+
{"level":"info","message":"playwright-framework-template undefined","service":"job-posting-service","timestamp":"2025-10-04T17:18:48.638Z"}
396+
{"level":"info","message":"info","meta":"Test Suite Started : , 1 tests","service":"job-posting-service","timestamp":"2025-10-04T17:18:50.526Z"}
397+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:18:56.488Z"}
398+
{"level":"info","message":"playwright-framework-template undefined","service":"job-posting-service","timestamp":"2025-10-04T17:19:41.202Z"}
399+
{"level":"info","message":"info","meta":"Test Suite Started : , 1 tests","service":"job-posting-service","timestamp":"2025-10-04T17:19:41.795Z"}
400+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:19:47.319Z"}
401+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : passed","service":"job-posting-service","timestamp":"2025-10-04T17:21:44.568Z"}
402+
{"level":"info","message":"playwright-framework-template undefined","service":"job-posting-service","timestamp":"2025-10-04T17:25:36.839Z"}
403+
{"level":"info","message":"info","meta":"Test Suite Started : , 1 tests","service":"job-posting-service","timestamp":"2025-10-04T17:25:37.750Z"}
404+
{"level":"info","message":"info","meta":"Test Case Started : Check the exception and logs in console log","service":"job-posting-service","timestamp":"2025-10-04T17:25:42.200Z"}
405+
{"level":"info","message":"info","meta":"Test Case Completed : Check the exception and logs in console log Status : passed","service":"job-posting-service","timestamp":"2025-10-04T17:26:57.039Z"}

playwright.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default defineConfig({
3030
/* Fail the build on CI if you accidentally left test.only in the source code. */
3131
forbidOnly: !!process.env.CI,
3232
/* Retry on CI only */
33-
retries: process.env.CI ? 2 : Config.RETRY_FAILED,
33+
retries: process.env.CI ? 1 : Config.RETRY_FAILED,
3434
/* Opt out of parallel tests on CI. */
3535
workers: process.env.CI ? 1 : Config.WORKERS,
3636
/* Reporter to use. See https://playwright.dev/docs/test-reporters */

src/utils/harAnalyser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const analyzeHAR = async (harFilePath: string, htmlOututPath: string) =>
4141
}
4242

4343
// Identify error responses (status codes 4xx and 5xx)
44-
if (status >= 400) {
44+
if (status !== 200) {
4545
findings.errorResponses.push({
4646
url,
4747
method,

tests/fixtures/customFixtures.ts

Lines changed: 69 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import { test as base, BrowserContext, Browser, Page, TestInfo, VideoMode,expect } from '@playwright/test'
1+
import { test as base, BrowserContext, Browser, Page, TestInfo, VideoMode, expect } from '@playwright/test'
22
import { ApiHelper, SshHelper, WebHelper } from "../../src/helper";
33
import { pwApi } from 'pw-api-plugin';
44
import { analyzeHAR } from '@src/utils/harAnalyser';
55
import { JsonReader } from '@src/utils/reader/jsonReader';
66

77
type MyMixtures = {
8-
context: BrowserContext
8+
context: BrowserContext
99
}
1010

1111
// Initialize browser context with HAR recording
@@ -16,7 +16,8 @@ const initHarRecording = async (browser: Browser, testInfo: TestInfo) => {
1616
recordHar: {
1717
path: harFilePath,
1818
mode: 'full',
19-
urlFilter: /api.practicesoftwaretesting.com/,
19+
// urlFilter: /api.practicesoftwaretesting.com/,
20+
urlFilter: /.*/,
2021
},
2122
...(testInfo.project.metadata?.video ? {
2223
recordVideo: {
@@ -44,78 +45,78 @@ const teardownHarRecording = async (page: Page, testInfo: TestInfo, videoMode: '
4445
await testInfo.attach('Network Console', { path: `./test-results/${fileName}.html`, contentType: 'text/html' })
4546
}
4647

47-
export const test = base.extend<{
48-
api: ApiHelper;
49-
web: WebHelper;
50-
ssh: SshHelper;
48+
export const test = base.extend<{
49+
api: ApiHelper;
50+
web: WebHelper;
51+
ssh: SshHelper;
5152
MyMixtures: any;
52-
json: JsonReader;
53+
json: JsonReader;
5354
config: { jsonPath: string };
5455
}>({
55-
config: async ({}, use) => {
56-
// Get JSON path from environment variable or use default
57-
const jsonPath = process.env.JSON_PATH || 'moataeldebsy.json';
58-
await use({ jsonPath });
59-
},
60-
api: async ({ page}, use) => {
61-
await use(new ApiHelper(page,pwApi))
62-
},
56+
config: async ({ }, use) => {
57+
// Get JSON path from environment variable or use default
58+
const jsonPath = process.env.JSON_PATH || 'moataeldebsy.json';
59+
await use({ jsonPath });
60+
},
61+
api: async ({ page }, use) => {
62+
await use(new ApiHelper(page, pwApi))
63+
},
6364

64-
web: async ({ page, browser,config }, use) => {
65-
console.log(config.jsonPath)
66-
const context = await browser.newContext();
67-
await use(new WebHelper(page, context,config.jsonPath));
68-
},
69-
ssh: async ({ }, use) => {
70-
await use(new SshHelper())
71-
},
72-
json:async({config},use)=>{
73-
console.log('Initializing JSON reader with:', config.jsonPath);
74-
await use(new JsonReader(config.jsonPath))
65+
web: async ({ page, browser, config }, use) => {
66+
console.log(config.jsonPath)
67+
const context = await browser.newContext();
68+
await use(new WebHelper(page, context, config.jsonPath));
69+
},
70+
ssh: async ({ }, use) => {
71+
await use(new SshHelper())
72+
},
73+
json: async ({ config }, use) => {
74+
console.log('Initializing JSON reader with:', config.jsonPath);
75+
await use(new JsonReader(config.jsonPath))
7576

76-
// npx playwright test --config:jsonPath=./alternative-config.json -- command to pass json filename
77+
// npx playwright test --config:jsonPath=./alternative-config.json -- command to pass json filename
7778

78-
//npx playwright test --config:jsonPath=./moataeldebsy.json --debug ./tests/e2e/moatazeldebsy/form.spec.ts
79-
},
80-
page: async ({ browser }, use, testInfo) => {
81-
// Initialize HAR recording
82-
const context = await initHarRecording(browser, testInfo);
83-
const page = await context.newPage();
84-
85-
// Array to store failed API details for this test run
86-
const failedApis: any = [];
87-
88-
// Add the response listener to the page
89-
page.on('response', (response) => {
90-
const request = response.request();
91-
// Filter for API calls (XHR or fetch requests) and non-200 status codes
92-
if (['xhr', 'fetch'].includes(request.resourceType()) && response.status() !== 200) {
93-
failedApis.push({
94-
url: request.url(),
95-
method: request.method(),
96-
status: response.status(),
97-
});
98-
}
79+
//npx playwright test --config:jsonPath=./moataeldebsy.json --debug ./tests/e2e/moatazeldebsy/form.spec.ts
80+
},
81+
page: async ({ browser }, use, testInfo) => {
82+
// Initialize HAR recording
83+
const context = await initHarRecording(browser, testInfo);
84+
const page = await context.newPage();
85+
86+
// Array to store failed API details for this test run
87+
const failedApis: any = [];
88+
89+
// Add the response listener to the page
90+
page.on('response', (response) => {
91+
const request = response.request();
92+
// Filter for API calls (XHR or fetch requests) and non-200 status codes
93+
if (['xhr', 'fetch'].includes(request.resourceType()) && response.status() !== 200) {
94+
failedApis.push({
95+
url: request.url(),
96+
method: request.method(),
97+
status: response.status(),
9998
});
100-
101-
// Proceed with the actual test execution
102-
await use(page);
103-
104-
// Log any failed APIs
105-
if (failedApis.length > 0) {
106-
console.log('\n--- Failed APIs Detected ---');
107-
console.log(failedApis);
108-
console.log('----------------------------\n');
109-
} else {
110-
console.log('All API calls for this test succeeded.');
111-
}
112-
113-
// Teardown HAR recording
114-
await teardownHarRecording(page, testInfo, 'on');
115-
},
116-
99+
}
100+
});
101+
102+
// Proceed with the actual test execution
103+
await use(page);
104+
105+
// Log any failed APIs
106+
if (failedApis.length > 0) {
107+
console.log('\n--- Failed APIs Detected ---');
108+
console.log(failedApis);
109+
console.log('----------------------------\n');
110+
} else {
111+
console.log('All API calls for this test succeeded.');
112+
}
113+
114+
// Teardown HAR recording
115+
await teardownHarRecording(page, testInfo, 'on');
116+
},
117+
117118
})
118119

119-
export type {TestInfo} from "@playwright/test"
120-
export {expect} from "@playwright/test"
120+
export type { TestInfo } from "@playwright/test"
121+
export { expect } from "@playwright/test"
121122

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { test} from "@tests/fixtures/test-options";
2+
import { expect } from "@playwright/test";
3+
4+
// @ts-check // Enables type checking in JavaScript files, good practice for Playwright tests.
5+
test
6+
7+
// Array to store console log messages of type 'error'.
8+
const logs: {
9+
message: string;
10+
type: string;
11+
}[] = []
12+
13+
// Array to store unhandled page errors (exceptions).
14+
const errorMsg: {
15+
name: string,
16+
message: string
17+
}[] = []
18+
19+
// Group tests related to error and console log checks.
20+
test.describe('error and console log check', () => {
21+
22+
// This block runs before each test in this describe block.
23+
test.beforeEach(async ({ page }) => {
24+
25+
// --- Console Log Listener ---
26+
// Attaches an event listener for 'console' events on the page.
27+
page.on('console', (msg) => {
28+
// Filter and store only console messages of type 'error'.
29+
if (msg.type() == 'error') {
30+
logs.push({ message: msg.text(), type: msg.type() })
31+
}
32+
})
33+
34+
// --- Page Error Listener ---
35+
// Attaches an event listener for unhandled 'pageerror' exceptions in the page's execution context.
36+
page.on('pageerror', (error) => {
37+
// Store the name and message of the unhandled error.
38+
errorMsg.push({ name: error.name, message: error.message })
39+
})
40+
41+
})
42+
43+
44+
test('Check the exception and logs in console log', async ({ page }, testInfo) => {
45+
46+
// Navigate to the target URL. This action will trigger the listeners
47+
// for any console errors or unhandled exceptions that occur during load.
48+
await page.goto('https://timesofindia.indiatimes.com/')
49+
50+
51+
// Format the collected console errors into a single string for attachment.
52+
const errorLogs = [...logs?.map(e => e.message)].join('\n')
53+
54+
// If console errors were found, attach them to the test report for debugging.
55+
if (logs?.length > 0) {
56+
await testInfo.attach('console logs', {
57+
body: errorLogs.toString(),
58+
contentType: 'text/plain'
59+
})
60+
}
61+
62+
// --- Assertions ---
63+
64+
// Soft assertion: Checks if no console errors were logged.
65+
// The test continues if this fails, but it's marked as a failure.
66+
expect.soft(logs.length).toBe(0)
67+
68+
// Hard assertion: Checks if no unhandled page errors/exceptions occurred.
69+
// The test fails immediately if this condition is not met.
70+
expect(errorMsg.length).toBe(0)
71+
72+
})
73+
74+
})

0 commit comments

Comments
 (0)