@@ -19,26 +19,29 @@ namespace facebook::react::jsinspector_modern {
1919
2020namespace {
2121
22- struct Params {
22+ struct NetworkReporterTestParams {
2323 bool enableNetworkEventReporting;
2424};
2525
2626} // namespace
2727
2828/* *
2929 * A test fixture for the way the internal NetworkReporter API interacts with
30- * the CDP Network domain .
30+ * the CDP Network and Tracing domains .
3131 */
32- class NetworkReporterTest : public JsiIntegrationPortableTestBase <
33- JsiIntegrationTestHermesEngineAdapter,
34- folly::QueuedImmediateExecutor>,
35- public WithParamInterface<Params> {
32+ template <typename Params>
33+ requires std::convertible_to<Params, NetworkReporterTestParams>
34+ class NetworkReporterTestBase : public JsiIntegrationPortableTestBase <
35+ JsiIntegrationTestHermesEngineAdapter,
36+ folly::QueuedImmediateExecutor>,
37+ public WithParamInterface<Params> {
3638 protected:
37- NetworkReporterTest ()
39+ NetworkReporterTestBase ()
3840 : JsiIntegrationPortableTestBase({
3941 .networkInspectionEnabled = true ,
4042 .enableNetworkEventReporting =
41- GetParam ().enableNetworkEventReporting ,
43+ WithParamInterface<Params>::GetParam ()
44+ .enableNetworkEventReporting ,
4245 }) {}
4346
4447 void SetUp () override {
@@ -65,6 +68,58 @@ class NetworkReporterTest : public JsiIntegrationPortableTestBase<
6568 urlMatcher);
6669 }
6770
71+ void startTracing () {
72+ this ->expectMessageFromPage (JsonEq (R"( {
73+ "id": 1,
74+ "result": {}
75+ })" ));
76+
77+ this ->toPage_ ->sendMessage (R"( {
78+ "id": 1,
79+ "method": "Tracing.start"
80+ })" );
81+ }
82+
83+ /* *
84+ * Helper method to end tracing and collect all trace events from potentially
85+ * multiple chunked Tracing.dataCollected messages.
86+ * \returns A vector containing all collected trace events
87+ */
88+ std::vector<folly::dynamic> endTracingAndCollectEvents () {
89+ InSequence s;
90+
91+ this ->expectMessageFromPage (JsonEq (R"( {
92+ "id": 1,
93+ "result": {}
94+ })" ));
95+
96+ std::vector<folly::dynamic> allTraceEvents;
97+
98+ EXPECT_CALL (
99+ fromPage (),
100+ onMessage (JsonParsed (AtJsonPtr (" /method" , " Tracing.dataCollected" ))))
101+ .Times (AtLeast (1 ))
102+ .WillRepeatedly (Invoke ([&allTraceEvents](const std::string& message) {
103+ auto parsedMessage = folly::parseJson (message);
104+ auto & events = parsedMessage.at (" params" ).at (" value" );
105+ allTraceEvents.insert (
106+ allTraceEvents.end (),
107+ std::make_move_iterator (events.begin ()),
108+ std::make_move_iterator (events.end ()));
109+ }));
110+
111+ this ->expectMessageFromPage (JsonParsed (AllOf (
112+ AtJsonPtr (" /method" , " Tracing.tracingComplete" ),
113+ AtJsonPtr (" /params/dataLossOccurred" , false ))));
114+
115+ this ->toPage_ ->sendMessage (R"( {
116+ "id": 1,
117+ "method": "Tracing.end"
118+ })" );
119+
120+ return allTraceEvents;
121+ }
122+
68123 private:
69124 std::optional<std::string> getScriptUrlById (const std::string& scriptId) {
70125 auto it = scriptUrlsById_.find (scriptId);
@@ -77,6 +132,8 @@ class NetworkReporterTest : public JsiIntegrationPortableTestBase<
77132 std::unordered_map<std::string, std::string> scriptUrlsById_;
78133};
79134
135+ using NetworkReporterTest = NetworkReporterTestBase<NetworkReporterTestParams>;
136+
80137TEST_P (NetworkReporterTest, testNetworkEnableDisable) {
81138 InSequence s;
82139
@@ -581,12 +638,186 @@ TEST_P(NetworkReporterTest, testCreateRequestIdWithoutNetworkDomain) {
581638 EXPECT_NE (id1, id2);
582639}
583640
584- static const auto paramValues = testing::Values(
585- Params{.enableNetworkEventReporting = true },
586- Params{
641+ struct NetworkReporterTracingTestParams {
642+ bool enableNetworkEventReporting;
643+ bool enableNetworkDomain;
644+
645+ operator NetworkReporterTestParams () const {
646+ return NetworkReporterTestParams{
647+ .enableNetworkEventReporting = enableNetworkEventReporting,
648+ };
649+ }
650+ };
651+
652+ using NetworkReporterTracingTest =
653+ NetworkReporterTestBase<NetworkReporterTracingTestParams>;
654+
655+ TEST_P (
656+ NetworkReporterTracingTest,
657+ testReportsToTracingDomainPlusNetworkDomain) {
658+ InSequence s;
659+
660+ this ->startTracing ();
661+
662+ if (GetParam ().enableNetworkDomain ) {
663+ this ->expectMessageFromPage (JsonEq (R"( {
664+ "id": 1,
665+ "result": {}
666+ })" ));
667+ this ->toPage_ ->sendMessage (R"( {
668+ "id": 1,
669+ "method": "Network.enable"
670+ })" );
671+
672+ this ->expectMessageFromPage (JsonParsed (AllOf (
673+ AtJsonPtr (" /method" , " Network.requestWillBeSent" ),
674+ AtJsonPtr (" /params/requestId" , " trace-events-request" ),
675+ AtJsonPtr (" /params/loaderId" , " " ),
676+ AtJsonPtr (" /params/documentURL" , " mobile" ),
677+ AtJsonPtr (" /params/request/url" , " https://trace.example.com/events" ),
678+ AtJsonPtr (" /params/request/method" , " GET" ),
679+ AtJsonPtr (" /params/request/headers/Accept" , " application/json" ),
680+ AtJsonPtr (" /params/timestamp" , Gt (0 )),
681+ AtJsonPtr (" /params/wallTime" , Gt (0 )),
682+ AtJsonPtr (" /params/initiator/type" , " script" ),
683+ AtJsonPtr (" /params/redirectHasExtraInfo" , false ))));
684+
685+ this ->expectMessageFromPage (JsonParsed (AllOf (
686+ AtJsonPtr (" /method" , " Network.requestWillBeSentExtraInfo" ),
687+ AtJsonPtr (" /params/requestId" , " trace-events-request" ),
688+ AtJsonPtr (" /params/associatedCookies" , " []" _json),
689+ AtJsonPtr (" /params/headers" , " {}" _json),
690+ AtJsonPtr (" /params/connectTiming/requestTime" , Gt (0 )))));
691+
692+ this ->expectMessageFromPage (JsonParsed (AllOf (
693+ AtJsonPtr (" /method" , " Network.responseReceived" ),
694+ AtJsonPtr (" /params/requestId" , " trace-events-request" ),
695+ AtJsonPtr (" /params/loaderId" , " " ),
696+ AtJsonPtr (" /params/timestamp" , Gt (0 )),
697+ AtJsonPtr (" /params/type" , " XHR" ),
698+ AtJsonPtr (" /params/response/url" , " https://trace.example.com/events" ),
699+ AtJsonPtr (" /params/response/status" , 200 ),
700+ AtJsonPtr (" /params/response/statusText" , " OK" ),
701+ AtJsonPtr (" /params/response/headers/Content-Type" , " application/json" ),
702+ AtJsonPtr (" /params/response/mimeType" , " application/json" ),
703+ AtJsonPtr (" /params/response/encodedDataLength" , 1024 ),
704+ AtJsonPtr (" /params/hasExtraInfo" , false ))));
705+
706+ this ->expectMessageFromPage (JsonParsed (AllOf (
707+ AtJsonPtr (" /method" , " Network.loadingFinished" ),
708+ AtJsonPtr (" /params/requestId" , " trace-events-request" ),
709+ AtJsonPtr (" /params/timestamp" , Gt (0 )),
710+ AtJsonPtr (" /params/encodedDataLength" , 1024 ))));
711+ }
712+
713+ NetworkReporter::getInstance ().reportRequestStart (
714+ " trace-events-request" ,
715+ {
716+ .url = " https://trace.example.com/events" ,
717+ .httpMethod = " GET" ,
718+ .headers = Headers{{" Accept" , " application/json" }},
719+ },
720+ 0 ,
721+ std::nullopt );
722+
723+ NetworkReporter::getInstance ().reportConnectionTiming (
724+ " trace-events-request" , std::nullopt );
725+
726+ NetworkReporter::getInstance ().reportResponseStart (
727+ " trace-events-request" ,
728+ {
729+ .url = " https://trace.example.com/events" ,
730+ .statusCode = 200 ,
731+ .headers = Headers{{" Content-Type" , " application/json" }},
732+ },
733+ 1024 );
734+
735+ NetworkReporter::getInstance ().reportResponseEnd (
736+ " trace-events-request" , 1024 );
737+
738+ auto allTraceEvents = endTracingAndCollectEvents ();
739+
740+ EXPECT_THAT (
741+ allTraceEvents,
742+ Contains (AllOf (
743+ AtJsonPtr (" /name" , " ResourceSendRequest" ),
744+ AtJsonPtr (" /cat" , " devtools.timeline" ),
745+ AtJsonPtr (" /ph" , " I" ),
746+ AtJsonPtr (" /s" , " t" ),
747+ AtJsonPtr (" /tid" , oscompat::getCurrentThreadId ()),
748+ AtJsonPtr (" /pid" , oscompat::getCurrentProcessId ()),
749+ AtJsonPtr (" /args/data/initiator" , " {}" _json),
750+ AtJsonPtr (" /args/data/requestId" , " trace-events-request" ),
751+ AtJsonPtr (" /args/data/url" , " https://trace.example.com/events" ),
752+ AtJsonPtr (" /args/data/requestMethod" , " GET" ),
753+ AtJsonPtr (" /args/data/priority" , " VeryHigh" ),
754+ AtJsonPtr (" /args/data/renderBlocking" , " non_blocking" ),
755+ AtJsonPtr (" /args/data/resourceType" , " Other" ))));
756+
757+ EXPECT_THAT (
758+ allTraceEvents,
759+ Contains (AllOf (
760+ AtJsonPtr (" /name" , " ResourceReceiveResponse" ),
761+ AtJsonPtr (" /cat" , " devtools.timeline" ),
762+ AtJsonPtr (" /ph" , " I" ),
763+ AtJsonPtr (" /s" , " t" ),
764+ AtJsonPtr (" /tid" , oscompat::getCurrentThreadId ()),
765+ AtJsonPtr (" /pid" , oscompat::getCurrentProcessId ()),
766+ AtJsonPtr (" /ts" , Gt (0 )),
767+ AtJsonPtr (" /args/data/requestId" , " trace-events-request" ),
768+ AtJsonPtr (" /args/data/statusCode" , 200 ),
769+ AtJsonPtr (" /args/data/mimeType" , " application/json" ),
770+ AtJsonPtr (" /args/data/protocol" , " h2" ),
771+ AtJsonPtr (" /args/data/encodedDataLength" , 1024 ),
772+ AtJsonPtr (
773+ " /args/data/headers" ,
774+ R"( [{ "name": "Content-Type", "value": "application/json" }])" _json),
775+ AtJsonPtr (
776+ " /args/data/timing" ,
777+ AllOf (
778+ AtJsonPtr (" /requestTime" , Ge (0 )),
779+ AtJsonPtr (" /sendStart" , Ge (0 )),
780+ AtJsonPtr (" /sendEnd" , Ge (0 )),
781+ AtJsonPtr (" /receiveHeadersStart" , Ge (0 )),
782+ AtJsonPtr (" /receiveHeadersEnd" , Ge (0 )))))));
783+
784+ EXPECT_THAT (
785+ allTraceEvents,
786+ Contains (AllOf (
787+ AtJsonPtr (" /name" , " ResourceFinish" ),
788+ AtJsonPtr (" /cat" , " devtools.timeline" ),
789+ AtJsonPtr (" /ph" , " I" ),
790+ AtJsonPtr (" /s" , " t" ),
791+ AtJsonPtr (" /tid" , oscompat::getCurrentThreadId ()),
792+ AtJsonPtr (" /pid" , oscompat::getCurrentProcessId ()),
793+ AtJsonPtr (" /args/data/requestId" , " trace-events-request" ),
794+ AtJsonPtr (" /args/data/encodedDataLength" , 1024 ),
795+ AtJsonPtr (" /args/data/decodedBodyLength" , 0 ),
796+ AtJsonPtr (" /args/data/didFail" , false ))));
797+ }
798+
799+ static const auto networkReporterTestParamValues = testing::Values(
800+ NetworkReporterTestParams{.enableNetworkEventReporting = true },
801+ NetworkReporterTestParams{
587802 .enableNetworkEventReporting = false ,
588803 });
589804
590- INSTANTIATE_TEST_SUITE_P (NetworkReporterTest, NetworkReporterTest, paramValues);
805+ static const auto networkReporterTracingTestParamValues = testing::Values(
806+ NetworkReporterTracingTestParams{
807+ .enableNetworkEventReporting = true ,
808+ .enableNetworkDomain = true },
809+ NetworkReporterTracingTestParams{
810+ .enableNetworkEventReporting = true ,
811+ .enableNetworkDomain = false });
812+
813+ INSTANTIATE_TEST_SUITE_P (
814+ NetworkReporterTest,
815+ NetworkReporterTest,
816+ networkReporterTestParamValues);
817+
818+ INSTANTIATE_TEST_SUITE_P (
819+ NetworkReporterTracingTest,
820+ NetworkReporterTracingTest,
821+ networkReporterTracingTestParamValues);
591822
592823} // namespace facebook::react::jsinspector_modern
0 commit comments