Skip to content

Commit aa2da2c

Browse files
authored
Merge pull request #1066 from browserstack/SDK-4928
SDK-4928: Fixed double logs for cucumber-cypress tests.
2 parents 375f60f + cfc92b9 commit aa2da2c

4 files changed

Lines changed: 345 additions & 1596 deletions

File tree

bin/testObservability/cypress/index.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ Cypress.on('log:changed', (attrs) => {
2727

2828
if (attrs.name === 'assert') {
2929
const assertMessage = (attrs.message || '')
30+
const actualLocation = (attrs.testId === attrs.hookId) ? 'test' : 'hook';
3031

3132
eventsQueue.push({
3233
task: 'test_observability_command',
@@ -36,11 +37,13 @@ Cypress.on('log:changed', (attrs) => {
3637
attributes: {
3738
id: attrs.id,
3839
name: 'assert',
40+
testId: attrs.testId,
41+
hookId: attrs.hookId,
3942
args: [assertMessage]
4043
},
4144
state: 'pending',
4245
started_at: new Date(attrs.createdAtTimestamp).toISOString(),
43-
location: testRunStarted ? 'test' : 'hook'
46+
location: actualLocation
4447
}
4548
},
4649
options: { log: false }
@@ -54,11 +57,13 @@ Cypress.on('log:changed', (attrs) => {
5457
attributes: {
5558
id: attrs.id,
5659
name: 'assert',
60+
testId: attrs.testId,
61+
hookId: attrs.hookId,
5762
args: [assertMessage]
5863
},
5964
state: attrs.state,
6065
finished_at: new Date(attrs.updatedAtTimestamp).toISOString(),
61-
location: testRunStarted ? 'test' : 'hook'
66+
location: actualLocation
6267
}
6368
},
6469
options: { log: false }

bin/testObservability/reporter/index.js

Lines changed: 56 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class MyReporter {
7777
this.hooksStarted = {};
7878
this.beforeHooks = [];
7979
this.testIdMap = {};
80+
this.internalIdMap = {};
8081
this.platformDetailsMap = {};
8182
this.runStatusMarkedHash = {};
8283
this.haveSentBuildUpdate = false;
@@ -101,6 +102,8 @@ class MyReporter {
101102
delete this.runStatusMarkedHash[hook.hookAnalyticsId];
102103
hook.hookAnalyticsId = uuidv4();
103104
}
105+
106+
if (hook.id) this.internalIdMap[hook.id] = hook.hookAnalyticsId;
104107
debugOnConsole(`[MOCHA EVENT] EVENT_HOOK_BEGIN for uuid: ${hook.hookAnalyticsId}`);
105108
hook.hook_started_at = (new Date()).toISOString();
106109
hook.started_at = (new Date()).toISOString();
@@ -132,7 +135,11 @@ class MyReporter {
132135
}
133136
})
134137

135-
.on(EVENT_SUITE_END, (suite) => {
138+
.on(EVENT_SUITE_END, (suite) => {
139+
if (suite.root) {
140+
debugOnConsole(`[MOCHA EVENT] EVENT_SUITE_END for root suite`);
141+
this.internalIdMap = {};
142+
}
136143
})
137144

138145
.on(EVENT_TEST_PASS, async (test) => {
@@ -213,12 +220,29 @@ class MyReporter {
213220
}
214221

215222
isInternalHook(hook) {
216-
if (hook && hook.body && hook.body.includes('/* browserstack internal helper hook */')) {
217-
return true;
218-
}
219-
return false;
223+
if (!hook || !hook.body) return false;
224+
225+
const body = hook.body.toString();
226+
227+
// Keep your existing check for BrowserStack internal helpers
228+
if (body.includes('/* browserstack internal helper hook */')) {
229+
return true;
220230
}
221231

232+
// Filter duplicate hooks caused by @badeball
233+
const isBadeballInternal =
234+
body.includes('beforeEachHandler.call(this, context)') ||
235+
body.includes('afterEachHandler.call(this, context)') ||
236+
body.includes('beforeHandler.call(this, context)') ||
237+
body.includes('afterHandler.call(this, context)');
238+
239+
if (isBadeballInternal) {
240+
return true;
241+
}
242+
243+
return false;
244+
}
245+
222246
async startHttpServer() {
223247
if(this.httpServer !== null) return;
224248

@@ -313,6 +337,8 @@ class MyReporter {
313337
this.current_test = test;
314338
test.retryOf = null;
315339
test.testAnalyticsId = uuidv4();
340+
if (test.id) this.internalIdMap[test.id] = test.testAnalyticsId;
341+
debugOnConsole(`[MOCHA EVENT] EVENT_TEST_BEGIN for uuid: ${test.testAnalyticsId}`);
316342
test.started_at = (new Date()).toISOString();
317343
test.test_started_at = test.started_at;
318344
if(test._currentRetry > 0 && lastTest && lastTest.title == test.title) {
@@ -332,6 +358,14 @@ class MyReporter {
332358

333359
uploadTestSteps = async (shouldClearCurrentSteps = true, cypressSteps = null) => {
334360
const currentTestSteps = cypressSteps ? cypressSteps : JSON.parse(JSON.stringify(this.currentTestSteps));
361+
362+
if(shouldClearCurrentSteps && !cypressSteps) {
363+
this.currentTestSteps = [];
364+
}
365+
366+
if (!currentTestSteps || currentTestSteps.length === 0) {
367+
return;
368+
}
335369
/* TODO - Send as test logs */
336370
const allStepsAsLogs = [];
337371
currentTestSteps.forEach(step => {
@@ -354,7 +388,6 @@ class MyReporter {
354388
event_type: 'LogCreated',
355389
logs: allStepsAsLogs
356390
});
357-
if(shouldClearCurrentSteps) this.currentTestSteps = [];
358391
}
359392

360393
sendTestRunEvent = async (test, err = undefined, customFinished=false, eventType = "TestRunFinished") => {
@@ -704,15 +737,21 @@ class MyReporter {
704737
return;
705738
}
706739

740+
const cypressTestId = command.testId || command.attributes?.testId;
741+
const cypressHookId = command.hookId || command.attributes?.hookId;
742+
707743
const currentStepObj = {
708744
id: command.attributes.id,
709745
text: 'cy.' + command.attributes.name + '(' + this.getFormattedArgs(command.attributes.args) + ')',
710746
started_at: command.started_at || new Date().toISOString(),
711747
finished_at: null,
712748
duration: null,
713749
result: 'pending',
714-
test_run_uuid: command.location === 'test' ? this.current_test?.testAnalyticsId : null,
715-
hook_run_uuid : command.location === 'hook' ? this.current_hook?.hookAnalyticsId : null
750+
test_run_uuid: command.location === 'test'
751+
? (this.internalIdMap[cypressTestId] || this.current_test?.testAnalyticsId) : null,
752+
753+
hook_run_uuid : command.location === 'hook'
754+
? (this.internalIdMap[cypressHookId] || this.current_hook?.hookAnalyticsId) : null
716755
};
717756
if(currentStepObj.hook_run_uuid && currentStepObj.test_run_uuid) delete currentStepObj.test_run_uuid;
718757
this.currentTestSteps = [
@@ -735,15 +774,22 @@ class MyReporter {
735774

736775
if(!stepUpdated) {
737776
/* COMMAND_END reported before COMMAND_START */
777+
778+
const cypressTestId = command.testId || command.attributes?.testId;
779+
const cypressHookId = command.hookId || command.attributes?.hookId;
780+
738781
const currentStepObj = {
739782
id: command.attributes.id,
740783
text: 'cy.' + command.attributes.name + '(' + this.getFormattedArgs(command.attributes.args) + ')',
741784
started_at: new Date().toISOString(),
742785
finished_at: new Date().toISOString(),
743786
duration: 0,
744787
result: command.state,
745-
test_run_uuid: command.location === 'test' ? this.current_test?.testAnalyticsId : null,
746-
hook_run_uuid : command.location === 'hook' ? this.current_hook?.hookAnalyticsId : null
788+
test_run_uuid: command.location === 'test'
789+
? (this.internalIdMap[cypressTestId] || this.current_test?.testAnalyticsId) : null,
790+
791+
hook_run_uuid : command.location === 'hook'
792+
? (this.internalIdMap[cypressHookId] || this.current_hook?.hookAnalyticsId) : null
747793
};
748794
if(currentStepObj.hook_run_uuid && currentStepObj.test_run_uuid) delete currentStepObj.test_run_uuid;
749795
this.currentTestSteps = [

0 commit comments

Comments
 (0)