Skip to content

Commit 50617c7

Browse files
DavertMikkobenguyent
authored andcommitted
added more fixes
1 parent 5234bb4 commit 50617c7

5 files changed

Lines changed: 88 additions & 53 deletions

File tree

lib/command/workers/runTests.js

Lines changed: 78 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -115,50 +115,97 @@ const config = deepMerge(getConfig(options.config || testRoot), overrideConfigs)
115115

116116
function initializeListeners() {
117117
// suite
118-
event.dispatcher.on(event.suite.before, suite => sendToParentThread({ event: event.suite.before, workerIndex, data: suite.simplify() }))
119-
event.dispatcher.on(event.suite.after, suite => sendToParentThread({ event: event.suite.after, workerIndex, data: suite.simplify() }))
118+
event.dispatcher.on(event.suite.before, suite => safelySendToParent({ event: event.suite.before, workerIndex, data: suite.simplify() }))
119+
event.dispatcher.on(event.suite.after, suite => safelySendToParent({ event: event.suite.after, workerIndex, data: suite.simplify() }))
120120

121121
// calculate duration
122122
event.dispatcher.on(event.test.started, test => (test.start = new Date()))
123123

124124
// tests
125-
event.dispatcher.on(event.test.before, test => sendToParentThread({ event: event.test.before, workerIndex, data: test.simplify() }))
126-
event.dispatcher.on(event.test.after, test => sendToParentThread({ event: event.test.after, workerIndex, data: test.simplify() }))
125+
event.dispatcher.on(event.test.before, test => safelySendToParent({ event: event.test.before, workerIndex, data: test.simplify() }))
126+
event.dispatcher.on(event.test.after, test => safelySendToParent({ event: event.test.after, workerIndex, data: test.simplify() }))
127127
// we should force-send correct errors to prevent race condition
128-
event.dispatcher.on(event.test.finished, (test, err) => sendToParentThread({ event: event.test.finished, workerIndex, data: { ...test.simplify(), err } }))
129-
event.dispatcher.on(event.test.failed, (test, err) => sendToParentThread({ event: event.test.failed, workerIndex, data: { ...test.simplify(), err } }))
130-
event.dispatcher.on(event.test.passed, (test, err) => sendToParentThread({ event: event.test.passed, workerIndex, data: { ...test.simplify(), err } }))
131-
event.dispatcher.on(event.test.started, test => sendToParentThread({ event: event.test.started, workerIndex, data: test.simplify() }))
132-
event.dispatcher.on(event.test.skipped, test => sendToParentThread({ event: event.test.skipped, workerIndex, data: test.simplify() }))
128+
event.dispatcher.on(event.test.finished, (test, err) => {
129+
const simplifiedData = test.simplify()
130+
const serializableErr = serializeError(err)
131+
safelySendToParent({ event: event.test.finished, workerIndex, data: { ...simplifiedData, err: serializableErr } })
132+
})
133+
event.dispatcher.on(event.test.failed, (test, err) => {
134+
const simplifiedData = test.simplify()
135+
const serializableErr = serializeError(err)
136+
safelySendToParent({ event: event.test.failed, workerIndex, data: { ...simplifiedData, err: serializableErr } })
137+
})
138+
event.dispatcher.on(event.test.passed, (test, err) => safelySendToParent({ event: event.test.passed, workerIndex, data: { ...test.simplify(), err } }))
139+
event.dispatcher.on(event.test.started, test => safelySendToParent({ event: event.test.started, workerIndex, data: test.simplify() }))
140+
event.dispatcher.on(event.test.skipped, test => safelySendToParent({ event: event.test.skipped, workerIndex, data: test.simplify() }))
133141

134142
// steps
135-
event.dispatcher.on(event.step.finished, step => sendToParentThread({ event: event.step.finished, workerIndex, data: step.simplify() }))
136-
event.dispatcher.on(event.step.started, step => sendToParentThread({ event: event.step.started, workerIndex, data: step.simplify() }))
137-
event.dispatcher.on(event.step.passed, step => sendToParentThread({ event: event.step.passed, workerIndex, data: step.simplify() }))
138-
event.dispatcher.on(event.step.failed, step => sendToParentThread({ event: event.step.failed, workerIndex, data: step.simplify() }))
143+
event.dispatcher.on(event.step.finished, step => safelySendToParent({ event: event.step.finished, workerIndex, data: step.simplify() }))
144+
event.dispatcher.on(event.step.started, step => safelySendToParent({ event: event.step.started, workerIndex, data: step.simplify() }))
145+
event.dispatcher.on(event.step.passed, step => safelySendToParent({ event: event.step.passed, workerIndex, data: step.simplify() }))
146+
event.dispatcher.on(event.step.failed, step => safelySendToParent({ event: event.step.failed, workerIndex, data: step.simplify() }))
147+
148+
event.dispatcher.on(event.hook.failed, (hook, err) => {
149+
const serializableErr = serializeError(err)
150+
safelySendToParent({ event: event.hook.failed, workerIndex, data: { ...hook.simplify(), err: serializableErr } })
151+
})
152+
event.dispatcher.on(event.hook.passed, hook => safelySendToParent({ event: event.hook.passed, workerIndex, data: hook.simplify() }))
153+
event.dispatcher.on(event.hook.finished, hook => safelySendToParent({ event: event.hook.finished, workerIndex, data: hook.simplify() }))
154+
155+
event.dispatcher.once(event.all.after, () => safelySendToParent({ event: event.all.after, workerIndex, data: container.result().simplify() }))
156+
// all
157+
event.dispatcher.once(event.all.result, () => {
158+
safelySendToParent({ event: event.all.result, workerIndex, data: container.result().simplify() })
159+
parentPort?.close()
160+
})
161+
}
139162

140-
event.dispatcher.on(event.hook.failed, (hook, err) => sendToParentThread({ event: event.hook.failed, workerIndex, data: { ...hook.simplify(), err } }))
141-
event.dispatcher.on(event.hook.passed, hook => sendToParentThread({ event: event.hook.passed, workerIndex, data: hook.simplify() }))
142-
event.dispatcher.on(event.hook.finished, hook => sendToParentThread({ event: event.hook.finished, workerIndex, data: hook.simplify() }))
163+
function disablePause() {
164+
global.pause = () => {}
165+
}
143166

144-
if (!poolMode) {
145-
// In regular mode, close worker after all tests are complete
146-
event.dispatcher.once(event.all.after, () => {
147-
sendToParentThread({ event: event.all.after, workerIndex, data: container.result().simplify() })
148-
})
149-
// all
150-
event.dispatcher.once(event.all.result, () => {
151-
sendToParentThread({ event: event.all.result, workerIndex, data: container.result().simplify() })
152-
parentPort?.close()
153-
})
154-
} else {
155-
// In pool mode, don't send result events for individual tests
156-
// Results will be sent once when the worker completes all tests
167+
function serializeError(err) {
168+
if (!err) return null
169+
try {
170+
return {
171+
message: err.message,
172+
stack: err.stack,
173+
name: err.name,
174+
actual: err.actual,
175+
expected: err.expected,
176+
}
177+
} catch {
178+
return { message: 'Error could not be serialized', name: 'Error' }
157179
}
158180
}
159181

160-
function disablePause() {
161-
global.pause = () => {}
182+
function safelySendToParent(data) {
183+
try {
184+
parentPort?.postMessage(data)
185+
} catch (cloneError) {
186+
// Fallback for non-serializable data
187+
const fallbackData = { ...data }
188+
189+
// Try to serialize error objects if present
190+
if (fallbackData.data && fallbackData.data.err) {
191+
fallbackData.data.err = serializeError(fallbackData.data.err)
192+
}
193+
194+
// If still fails, send minimal data
195+
try {
196+
parentPort?.postMessage(fallbackData)
197+
} catch (finalError) {
198+
parentPort?.postMessage({
199+
event: data.event,
200+
workerIndex,
201+
data: {
202+
title: fallbackData.data?.title || 'Unknown',
203+
state: fallbackData.data?.state || 'error',
204+
err: { message: 'Data could not be serialized' },
205+
},
206+
})
207+
}
208+
}
162209
}
163210

164211
function sendToParentThread(data) {

lib/helper/WebDriver.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ let webdriverio
22

33
import assert from 'assert'
44
import path from 'path'
5+
import crypto from 'crypto'
56
import Helper from '@codeceptjs/helper'
67
import promiseRetry from 'promise-retry'
78
import { includes as stringIncludes } from '../assert/include.js'
@@ -2626,7 +2627,6 @@ class WebDriver extends Helper {
26262627
*/
26272628
async openNewTab(url = 'about:blank', windowName = null) {
26282629
const client = this.browser
2629-
const crypto = require('crypto')
26302630
if (windowName == null) {
26312631
windowName = crypto.randomBytes(32).toString('hex')
26322632
}

lib/index.js

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import locator from './locator.js'
2222
import heal from './heal.js'
2323
import ai from './ai.js'
2424
import Workers from './workers.js'
25+
import Secret, { secret } from './secret.js'
2526

2627
export default {
2728
/** @type {typeof CodeceptJS.Codecept} */
@@ -61,25 +62,12 @@ export default {
6162
ai,
6263

6364
Workers,
65+
66+
/** @type {typeof CodeceptJS.Secret} */
67+
Secret,
68+
/** @type {typeof CodeceptJS.secret} */
69+
secret,
6470
}
6571

6672
// Named exports for ESM compatibility
67-
export {
68-
codecept,
69-
output,
70-
container,
71-
event,
72-
recorder,
73-
config,
74-
actor,
75-
helper,
76-
pause,
77-
within,
78-
dataTable,
79-
dataTableArgument,
80-
store,
81-
locator,
82-
heal,
83-
ai,
84-
Workers
85-
}
73+
export { codecept, output, container, event, recorder, config, actor, helper, pause, within, dataTable, dataTableArgument, store, locator, heal, ai, Workers, Secret, secret }

test/acceptance/session_test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ Scenario('should work with within @Puppeteer @Playwright', ({ I }) => {
137137
I.seeCheckboxIsChecked({ css: 'form[name=form1] input[name=first_test_radio]' })
138138
I.dontSeeCheckboxIsChecked({ css: 'form[name=form2] input[name=first_test_radio]' })
139139
})
140-
})
140+
}).retry(2)
141141

142142
Scenario('change page emulation @Playwright', async ({ I }) => {
143143
I.amOnPage('/')

test/docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ services:
22
test-rest:
33
<<: &test-service
44
build: ..
5-
entrypoint: ['']
5+
entrypoint: npx mocha
66
working_dir: /codecept
77
env_file: .env
88
volumes:

0 commit comments

Comments
 (0)