Skip to content

Commit 9b9fb61

Browse files
committed
fix: flaky tests
1 parent 8b00115 commit 9b9fb61

2 files changed

Lines changed: 81 additions & 43 deletions

File tree

playwright/Utils/taskControlUtils.ts

Lines changed: 77 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -255,26 +255,45 @@ export function clearCapturedLogs(): void {
255255
* @param options.expectedIsHeld - Expected hold state (true for hold, false for resume)
256256
* @throws Error if verification fails with detailed error message
257257
*/
258-
export function verifyHoldLogs({expectedIsHeld}: {expectedIsHeld: boolean}): void {
259-
const holdResumeLogs = capturedLogs.filter((log) => log.includes('onHoldResume invoked'));
260-
const statusLogs = capturedLogs.filter((log) =>
261-
log.includes(expectedIsHeld ? 'WXCC_SDK_TASK_HOLD_SUCCESS' : 'WXCC_SDK_TASK_RESUME_SUCCESS')
262-
);
258+
export async function verifyHoldLogs({expectedIsHeld}: {expectedIsHeld: boolean}): Promise<void> {
259+
const expectedStatus = expectedIsHeld ? 'WXCC_SDK_TASK_HOLD_SUCCESS' : 'WXCC_SDK_TASK_RESUME_SUCCESS';
263260

264-
if (holdResumeLogs.length === 0) {
265-
throw new Error(
266-
`No 'onHoldResume invoked' logs found. Expected logs for isHeld: ${expectedIsHeld}. Captured logs: ${JSON.stringify(capturedLogs)}`
267-
);
268-
}
261+
try {
262+
await expect
263+
.poll(
264+
() => {
265+
const holdResumeLogs = capturedLogs.filter((log) => log.includes('onHoldResume invoked'));
266+
const statusLogs = capturedLogs.filter((log) => log.includes(expectedStatus));
267+
const lastHoldLog = holdResumeLogs[holdResumeLogs.length - 1] ?? '';
268+
return (
269+
holdResumeLogs.length > 0 && statusLogs.length > 0 && lastHoldLog.includes(`isHeld: ${expectedIsHeld}`)
270+
);
271+
},
272+
{timeout: OPERATION_TIMEOUT, intervals: [200, 400, 800, 1200]}
273+
)
274+
.toBeTruthy();
275+
} catch {
276+
const holdResumeLogs = capturedLogs.filter((log) => log.includes('onHoldResume invoked'));
277+
const statusLogs = capturedLogs.filter((log) => log.includes(expectedStatus));
278+
const lastHoldLog = holdResumeLogs[holdResumeLogs.length - 1];
279+
280+
if (holdResumeLogs.length === 0) {
281+
throw new Error(
282+
`No 'onHoldResume invoked' logs found. Expected logs for isHeld: ${expectedIsHeld}. Captured logs: ${JSON.stringify(capturedLogs)}`
283+
);
284+
}
269285

270-
if (statusLogs.length === 0) {
271-
const expectedStatus = expectedIsHeld ? 'WXCC_SDK_TASK_HOLD_SUCCESS' : 'WXCC_SDK_TASK_RESUME_SUCCESS';
272-
throw new Error(`No '${expectedStatus}' logs found. Captured logs: ${JSON.stringify(capturedLogs)}`);
273-
}
286+
if (statusLogs.length === 0) {
287+
throw new Error(`No '${expectedStatus}' logs found. Captured logs: ${JSON.stringify(capturedLogs)}`);
288+
}
289+
290+
if (!lastHoldLog?.includes(`isHeld: ${expectedIsHeld}`)) {
291+
throw new Error(`Expected 'isHeld: ${expectedIsHeld}' in log but found: ${lastHoldLog}`);
292+
}
274293

275-
const lastHoldLog = holdResumeLogs[holdResumeLogs.length - 1];
276-
if (!lastHoldLog.includes(`isHeld: ${expectedIsHeld}`)) {
277-
throw new Error(`Expected 'isHeld: ${expectedIsHeld}' in log but found: ${lastHoldLog}`);
294+
throw new Error(
295+
`Timed out validating hold logs for isHeld: ${expectedIsHeld}. Captured logs: ${JSON.stringify(capturedLogs)}`
296+
);
278297
}
279298
}
280299

@@ -284,30 +303,49 @@ export function verifyHoldLogs({expectedIsHeld}: {expectedIsHeld: boolean}): voi
284303
* @param options.expectedIsRecording - Expected recording state (true for recording, false for paused)
285304
* @throws Error if verification fails with detailed error message
286305
*/
287-
export function verifyRecordingLogs({expectedIsRecording}: {expectedIsRecording: boolean}): void {
288-
const recordingLogs = capturedLogs.filter((log) => log.includes('onRecordingToggle invoked'));
289-
const statusLogs = capturedLogs.filter((log) =>
290-
log.includes(
291-
expectedIsRecording ? 'WXCC_SDK_TASK_RESUME_RECORDING_SUCCESS' : 'WXCC_SDK_TASK_PAUSE_RECORDING_SUCCESS'
292-
)
293-
);
294-
295-
if (recordingLogs.length === 0) {
296-
throw new Error(
297-
`No 'onRecordingToggle invoked' logs found. Expected logs for isRecording: ${expectedIsRecording}. Captured logs: ${JSON.stringify(capturedLogs)}`
298-
);
299-
}
306+
export async function verifyRecordingLogs({expectedIsRecording}: {expectedIsRecording: boolean}): Promise<void> {
307+
const expectedStatus = expectedIsRecording
308+
? 'WXCC_SDK_TASK_RESUME_RECORDING_SUCCESS'
309+
: 'WXCC_SDK_TASK_PAUSE_RECORDING_SUCCESS';
300310

301-
if (statusLogs.length === 0) {
302-
const expectedStatus = expectedIsRecording
303-
? 'WXCC_SDK_TASK_RESUME_RECORDING_SUCCESS'
304-
: 'WXCC_SDK_TASK_PAUSE_RECORDING_SUCCESS';
305-
throw new Error(`No '${expectedStatus}' logs found. Captured logs: ${JSON.stringify(capturedLogs)}`);
306-
}
311+
try {
312+
await expect
313+
.poll(
314+
() => {
315+
const recordingLogs = capturedLogs.filter((log) => log.includes('onRecordingToggle invoked'));
316+
const statusLogs = capturedLogs.filter((log) => log.includes(expectedStatus));
317+
const lastRecordingLog = recordingLogs[recordingLogs.length - 1] ?? '';
318+
return (
319+
recordingLogs.length > 0 &&
320+
statusLogs.length > 0 &&
321+
lastRecordingLog.includes(`isRecording: ${expectedIsRecording}`)
322+
);
323+
},
324+
{timeout: OPERATION_TIMEOUT, intervals: [200, 400, 800, 1200]}
325+
)
326+
.toBeTruthy();
327+
} catch {
328+
const recordingLogs = capturedLogs.filter((log) => log.includes('onRecordingToggle invoked'));
329+
const statusLogs = capturedLogs.filter((log) => log.includes(expectedStatus));
330+
const lastRecordingLog = recordingLogs[recordingLogs.length - 1];
331+
332+
if (recordingLogs.length === 0) {
333+
throw new Error(
334+
`No 'onRecordingToggle invoked' logs found. Expected logs for isRecording: ${expectedIsRecording}. Captured logs: ${JSON.stringify(capturedLogs)}`
335+
);
336+
}
307337

308-
const lastRecordingLog = recordingLogs[recordingLogs.length - 1];
309-
if (!lastRecordingLog.includes(`isRecording: ${expectedIsRecording}`)) {
310-
throw new Error(`Expected 'isRecording: ${expectedIsRecording}' in log but found: ${lastRecordingLog}`);
338+
if (statusLogs.length === 0) {
339+
throw new Error(`No '${expectedStatus}' logs found. Captured logs: ${JSON.stringify(capturedLogs)}`);
340+
}
341+
342+
if (!lastRecordingLog?.includes(`isRecording: ${expectedIsRecording}`)) {
343+
throw new Error(`Expected 'isRecording: ${expectedIsRecording}' in log but found: ${lastRecordingLog}`);
344+
}
345+
346+
throw new Error(
347+
`Timed out validating recording logs for isRecording: ${expectedIsRecording}. Captured logs: ${JSON.stringify(capturedLogs)}`
348+
);
311349
}
312350
}
313351

playwright/tests/basic-task-controls-test.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export default function createCallTaskControlsTests() {
104104
await testManager.agent1Page.waitForTimeout(3000); // Allow time for hold to take effect
105105

106106
// Verify hold callback logs
107-
verifyHoldLogs({expectedIsHeld: true});
107+
await verifyHoldLogs({expectedIsHeld: true});
108108

109109
// Verify hold button icon changed to play icon (when call is on hold)
110110
await verifyHoldButtonIcon(testManager.agent1Page, {expectedIsHeld: true});
@@ -123,7 +123,7 @@ export default function createCallTaskControlsTests() {
123123
await testManager.agent1Page.waitForTimeout(2000);
124124

125125
// Verify resume callback logs
126-
verifyHoldLogs({expectedIsHeld: false});
126+
await verifyHoldLogs({expectedIsHeld: false});
127127

128128
// Verify hold button icon changed back to pause icon (when call is active)
129129
await verifyHoldButtonIcon(testManager.agent1Page, {expectedIsHeld: false});
@@ -149,7 +149,7 @@ export default function createCallTaskControlsTests() {
149149
await testManager.agent1Page.waitForTimeout(2000);
150150

151151
// Verify pause recording callback logs
152-
verifyRecordingLogs({expectedIsRecording: false});
152+
await verifyRecordingLogs({expectedIsRecording: false});
153153

154154
// Verify record button icon changed to record icon (when recording is paused)
155155
await verifyRecordButtonIcon(testManager.agent1Page, {expectedIsRecording: false});
@@ -161,7 +161,7 @@ export default function createCallTaskControlsTests() {
161161
await testManager.agent1Page.waitForTimeout(2000);
162162

163163
// Verify resume recording callback logs
164-
verifyRecordingLogs({expectedIsRecording: true});
164+
await verifyRecordingLogs({expectedIsRecording: true});
165165

166166
// Verify record button icon changed back to pause icon (when recording is active)
167167
await verifyRecordButtonIcon(testManager.agent1Page, {expectedIsRecording: true});

0 commit comments

Comments
 (0)