@@ -5,6 +5,8 @@ const chai = require("chai"),
55
66const capabilityHelper = require ( "../../../../bin/helpers/capabilityHelper" ) ,
77 Constants = require ( "../../../../bin/helpers/constants" ) ,
8+ testhubUtils = require ( "../../../../bin/testhub/utils" ) ,
9+ o11yHelper = require ( "../../../../bin/testObservability/helper/helper" ) ,
810 logger = require ( "../../../../bin/helpers/logger" ) . winstonLogger ;
911
1012chai . use ( chaiAsPromised ) ;
@@ -562,6 +564,151 @@ describe("capabilityHelper.js", () => {
562564 } ) ;
563565 } ) ;
564566 } ) ;
567+
568+ context ( "testhub build attribution" , ( ) => {
569+ const bsConfig = {
570+ auth : {
571+ username : "random" ,
572+ access_key : "random" ,
573+ } ,
574+ browsers : [
575+ {
576+ browser : "chrome" ,
577+ os : "Windows 10" ,
578+ versions : [ "78" ] ,
579+ } ,
580+ ] ,
581+ run_settings : { } ,
582+ } ;
583+ const productMap = {
584+ observability : true ,
585+ accessibility : false ,
586+ percy : false ,
587+ automate : true ,
588+ app_automate : false ,
589+ } ;
590+ let productMapStub ;
591+ let originalTesthubUuid ;
592+
593+ beforeEach ( ( ) => {
594+ originalTesthubUuid = process . env . BROWSERSTACK_TESTHUB_UUID ;
595+ productMapStub = sinon . stub ( testhubUtils , "getProductMap" ) . returns ( productMap ) ;
596+ } ) ;
597+
598+ afterEach ( ( ) => {
599+ productMapStub . restore ( ) ;
600+ if ( originalTesthubUuid === undefined ) {
601+ delete process . env . BROWSERSTACK_TESTHUB_UUID ;
602+ } else {
603+ process . env . BROWSERSTACK_TESTHUB_UUID = originalTesthubUuid ;
604+ }
605+ } ) ;
606+
607+ it ( "stamps the testhub build uuid and the product map on the caps" , ( ) => {
608+ process . env . BROWSERSTACK_TESTHUB_UUID = "some-testhub-build-uuid" ;
609+ return capabilityHelper
610+ . caps ( bsConfig , { zip_url : "bs://<random>" } )
611+ . then ( function ( data ) {
612+ let parsed_data = JSON . parse ( data ) ;
613+ chai . assert . equal ( parsed_data . testhubBuildUuid , "some-testhub-build-uuid" ) ;
614+ chai . assert . deepEqual ( parsed_data . buildProductMap , productMap ) ;
615+ sinon . assert . calledWith ( productMapStub , bsConfig ) ;
616+ } ) ;
617+ } ) ;
618+
619+ it ( "stamps an empty testhub build uuid when build start produced none" , ( ) => {
620+ delete process . env . BROWSERSTACK_TESTHUB_UUID ;
621+ return capabilityHelper
622+ . caps ( bsConfig , { zip_url : "bs://<random>" } )
623+ . then ( function ( data ) {
624+ let parsed_data = JSON . parse ( data ) ;
625+ chai . assert . equal ( parsed_data . testhubBuildUuid , "" ) ;
626+ chai . assert . isTrue ( Object . prototype . hasOwnProperty . call ( parsed_data , "testhubBuildUuid" ) ) ;
627+ chai . assert . deepEqual ( parsed_data . buildProductMap , productMap ) ;
628+ } ) ;
629+ } ) ;
630+ } ) ;
631+
632+ // These exercise the REAL getProductMap rather than a stub, because the thing under test is
633+ // what the map SAYS, not that it is attached.
634+ context ( "testhub build attribution — product map reflects reality" , ( ) => {
635+ const ENV = [ "BROWSERSTACK_TEST_OBSERVABILITY" , "BROWSERSTACK_TESTHUB_UUID" ,
636+ "BROWSERSTACK_TEST_ACCESSIBILITY" , "BROWSERSTACK_AUTOMATION" ] ;
637+ let saved ;
638+
639+ const bsConfigFor = ( testObservability ) => ( {
640+ auth : { username : "random" , access_key : "random" } ,
641+ browsers : [ { browser : "chrome" , os : "Windows 10" , versions : [ "78" ] } ] ,
642+ run_settings : { cypress_config_file : "./cypress.config.js" } ,
643+ testObservability,
644+ } ) ;
645+
646+ beforeEach ( ( ) => {
647+ saved = { } ;
648+ ENV . forEach ( ( k ) => { saved [ k ] = process . env [ k ] ; } ) ;
649+ delete process . env . BROWSERSTACK_TEST_OBSERVABILITY ;
650+ process . env . BROWSERSTACK_TEST_ACCESSIBILITY = "false" ;
651+ process . env . BROWSERSTACK_AUTOMATION = "true" ;
652+ } ) ;
653+
654+ afterEach ( ( ) => {
655+ ENV . forEach ( ( k ) => {
656+ if ( saved [ k ] === undefined ) delete process . env [ k ] ;
657+ else process . env [ k ] = saved [ k ] ;
658+ } ) ;
659+ } ) ;
660+
661+ it ( "carries observability:false when the user explicitly disabled it in config" , ( ) => {
662+ const bsConfig = bsConfigFor ( false ) ;
663+ o11yHelper . setTestObservabilityFlags ( bsConfig ) ;
664+ chai . assert . equal ( process . env . BROWSERSTACK_TEST_OBSERVABILITY , "false" , "precondition" ) ;
665+
666+ return capabilityHelper
667+ . caps ( bsConfig , { zip_url : "bs://<random>" } )
668+ . then ( function ( data ) {
669+ const parsed_data = JSON . parse ( data ) ;
670+ chai . assert . isFalse ( parsed_data . buildProductMap . observability ) ;
671+ chai . assert . equal ( parsed_data . testhubBuildUuid , "" ) ;
672+ } ) ;
673+ } ) ;
674+
675+ it ( "carries observability:true when the user asked for it and build start succeeded" , ( ) => {
676+ const bsConfig = bsConfigFor ( true ) ;
677+ o11yHelper . setTestObservabilityFlags ( bsConfig ) ;
678+ process . env . BROWSERSTACK_TESTHUB_UUID = "a-real-build-uuid" ;
679+
680+ return capabilityHelper
681+ . caps ( bsConfig , { zip_url : "bs://<random>" } )
682+ . then ( function ( data ) {
683+ const parsed_data = JSON . parse ( data ) ;
684+ chai . assert . isTrue ( parsed_data . buildProductMap . observability ) ;
685+ chai . assert . equal ( parsed_data . testhubBuildUuid , "a-real-build-uuid" ) ;
686+ } ) ;
687+ } ) ;
688+
689+ it ( "flips observability to false and drops the null sentinel when build start failed" , ( ) => {
690+ const bsConfig = bsConfigFor ( true ) ;
691+ o11yHelper . setTestObservabilityFlags ( bsConfig ) ;
692+ chai . assert . equal ( process . env . BROWSERSTACK_TEST_OBSERVABILITY , "true" , "precondition" ) ;
693+
694+ const errorStub = sinon . stub ( logger , "error" ) ;
695+ try {
696+ testhubUtils . handleErrorForObservability ( ) ;
697+ } finally {
698+ errorStub . restore ( ) ;
699+ }
700+ chai . assert . equal ( process . env . BROWSERSTACK_TESTHUB_UUID , "null" , "sentinel is what we guard against" ) ;
701+
702+ return capabilityHelper
703+ . caps ( bsConfig , { zip_url : "bs://<random>" } )
704+ . then ( function ( data ) {
705+ const parsed_data = JSON . parse ( data ) ;
706+ chai . assert . isFalse ( parsed_data . buildProductMap . observability ) ;
707+ chai . assert . equal ( parsed_data . testhubBuildUuid , "" ,
708+ 'the "null" sentinel must never be stamped as a uuid' ) ;
709+ } ) ;
710+ } ) ;
711+ } ) ;
565712 } ) ;
566713
567714 describe ( "addCypressZipStartLocation" , ( ) => {
0 commit comments