/home/runner/work/chrme/chrme/_build/test/cover/aggregate/chrme_network.html

1 -module(chrme_network).
2
3 -export_type([request_id/0]).
4
5 -type request_id() :: klsn:binstr().
6 -export([enable/1, disable/1, set_request_interception/2,
7 continue_intercepted_request/2, emulate_network_conditions/2,
8 register_request_will_be_sent_handler/2, unregister_request_will_be_sent_handler/2,
9 register_event_handler/2, unregister_event_handler/2,
10 register_response_received_handler/2, unregister_response_received_handler/2,
11 register_loading_finished_handler/2, unregister_loading_finished_handler/2,
12 get_response_body/2, await_response_body/3, await_response_body/2]).
13
14 %% Enable network tracking
15 -spec enable(Name :: chrme_session:name()) -> {ok, map()} | {error, term()}.
16 enable(Name) ->
17 4 chrme_cdp:call(Name, <<"Network.enable">>, #{}).
18
19 %% Disable network tracking
20 -spec disable(Name :: chrme_session:name()) -> {ok, map()} | {error, term()}.
21 disable(Name) ->
22
:-(
chrme_cdp:call(Name, <<"Network.disable">>, #{}).
23
24 %% Set patterns for request interception
25 -spec set_request_interception(Name :: chrme_session:name(), Patterns :: term()) -> {ok, map()} | {error, term()}.
26 set_request_interception(Name, Patterns) ->
27
:-(
chrme_cdp:call(Name, <<"Network.setRequestInterception">>, #{patterns => Patterns}).
28
29 %% Continue an intercepted request
30 -spec continue_intercepted_request(Name :: chrme_session:name(), RequestId :: request_id()) -> {ok, map()} | {error, term()}.
31 continue_intercepted_request(Name, RequestId) ->
32
:-(
chrme_cdp:call(Name, <<"Network.continueInterceptedRequest">>, #{requestId => RequestId}).
33
34 %% Emulate network conditions (offline, latency, throughput)
35 -spec emulate_network_conditions(Name :: chrme_session:name(), Conditions :: term()) -> {ok, map()} | {error, term()}.
36 emulate_network_conditions(Name, Conditions) ->
37
:-(
chrme_cdp:call(Name, <<"Network.emulateNetworkConditions">>, Conditions).
38
39 %% Subscribe to requestWillBeSent events
40 -spec register_request_will_be_sent_handler(Name :: chrme_session:name(), Fun :: fun((map()) -> any())) -> reference().
41 register_request_will_be_sent_handler(Name, Fun) ->
42 2 Ref = make_ref(),
43 2 CallbackName = {chrme_network, register_request_will_be_sent_handler, Name, Ref},
44 2 CallbackFun = fun
45
:-(
(stop) -> false;
46 (_Msg = #{<<"method">> := <<"Network.requestWillBeSent">>, <<"params">> := Params}) ->
47 3 Fun(Params),
48 3 true;
49 5 (_) -> false
50 end,
51 2 chrme_ws_apic:add_callback(Name, {CallbackName, CallbackFun}),
52 2 Ref.
53
54 %% Unsubscribe from requestWillBeSent
55 -spec unregister_request_will_be_sent_handler(Name :: chrme_session:name(), Ref :: reference()) -> ok.
56 unregister_request_will_be_sent_handler(Name, Ref) ->
57 2 CallbackName = {chrme_network, register_request_will_be_sent_handler, Name, Ref},
58 2 chrme_ws_apic:remove_callback(Name, CallbackName),
59 2 ok.
60
61 %% ------------------------------------------------------------------
62 %% Await response body helper
63 %% ------------------------------------------------------------------
64
65 -spec await_response_body(chrme_session:name(), request_id(), infinity | non_neg_integer()) ->
66 {ok, binary(), boolean()} | {error, timeout | term()}.
67 await_response_body(Name, ReqId, infinity) ->
68 %% Infinite wait: keep polling until success.
69
:-(
case get_response_body(Name, ReqId) of
70 {ok, _Body, _Enc} = Success ->
71
:-(
Success;
72 _ ->
73
:-(
timer:sleep(100),
74
:-(
await_response_body(Name, ReqId, infinity)
75 end;
76
77 await_response_body(Name, ReqId, Timeout) when is_integer(Timeout), Timeout >= 0 ->
78 1 Start = erlang:monotonic_time(millisecond),
79 1 Poll = fun This() ->
80 2 case get_response_body(Name, ReqId) of
81 {ok, _Body, _Enc} = Success ->
82 1 Success;
83 _ ->
84 1 Now = erlang:monotonic_time(millisecond),
85 1 case Now - Start >= Timeout of
86
:-(
true -> {error, timeout};
87 false ->
88 1 timer:sleep(100),
89 1 This()
90 end
91 end
92 end,
93 1 Poll().
94
95 -spec await_response_body(chrme_session:name(), request_id()) ->
96 {ok, binary(), boolean()} | {error, timeout | term()}.
97 await_response_body(Name, ReqId) ->
98
:-(
await_response_body(Name, ReqId, infinity).
99
100 %% ------------------------------------------------------------------
101 %% Convenience: fetch response body for a completed request.
102 %% Wraps the CDP method Network.getResponseBody
103 %% ------------------------------------------------------------------
104
105 %% Return the response body (potentially base64-encoded) for the given
106 %% requestId. The tuple is {ok, BodyBin, IsBase64Encoded} so the caller
107 %% can decide whether to decode.
108
109 -spec get_response_body(Name :: chrme_session:name(),
110 RequestId :: request_id()) ->
111 {ok, binary(), boolean()} | {error, term()}.
112 get_response_body(Name, RequestId) ->
113 3 case chrme_cdp:call(Name, <<"Network.getResponseBody">>, #{requestId => RequestId}) of
114 {ok, #{<<"body">> := Body, <<"base64Encoded">> := Encoded}} ->
115 2 {ok, Body, Encoded};
116 Other ->
117 1 Other
118 end.
119
120 %% ------------------------------------------------------------------
121 %% New convenience: listen to *all* Network domain events.
122 %% ------------------------------------------------------------------
123
124 %% Subscribe to every "Network.*" event.
125 -spec register_event_handler(Name :: chrme_session:name(),
126 Fun :: fun((map()) -> any())) -> reference().
127 register_event_handler(Name, Fun) ->
128 1 Ref = make_ref(),
129 1 CallbackName = {chrme_network, register_event_handler, Name, Ref},
130 1 CallbackFun = fun
131 (stop) ->
132
:-(
false;
133 (Msg = #{<<"method">> := Method}) ->
134 2 case Method of
135 <<"Network.", _/binary>> ->
136 2 Fun(Msg),
137 2 true;
138 _ ->
139
:-(
false
140 end;
141 (_) ->
142
:-(
false
143 end,
144 1 chrme_ws_apic:add_callback(Name, {CallbackName, CallbackFun}),
145 1 Ref.
146
147 %% Unsubscribe from all Network.* events.
148 -spec unregister_event_handler(Name :: chrme_session:name(), Ref :: reference()) -> ok.
149 unregister_event_handler(Name, Ref) ->
150 1 CallbackName = {chrme_network, register_event_handler, Name, Ref},
151 1 chrme_ws_apic:remove_callback(Name, CallbackName),
152 1 ok.
153
154 %% ------------------------------------------------------------------
155 %% One-off helpers for other common Network events
156 %% ------------------------------------------------------------------
157
158 %% responseReceived --------------------------------------------------
159
160 -spec register_response_received_handler(chrme_session:name(), fun((map()) -> any())) -> reference().
161 register_response_received_handler(Name, Fun) ->
162 2 Ref = make_ref(),
163 2 CbName = {chrme_network, response_received, Name, Ref},
164 2 CbFun = fun
165
:-(
(stop) -> false;
166 (#{<<"method">> := <<"Network.responseReceived">>, <<"params">> := Params}) ->
167 3 Fun(Params),
168 3 true;
169 18 (_) -> false
170 end,
171 2 chrme_ws_apic:add_callback(Name, {CbName, CbFun}),
172 2 Ref.
173
174 -spec unregister_response_received_handler(chrme_session:name(), reference()) -> ok.
175 unregister_response_received_handler(Name, Ref) ->
176 2 CbName = {chrme_network, response_received, Name, Ref},
177 2 chrme_ws_apic:remove_callback(Name, CbName),
178 2 ok.
179
180 %% loadingFinished ---------------------------------------------------
181
182 -spec register_loading_finished_handler(chrme_session:name(), fun((map()) -> any())) -> reference().
183 register_loading_finished_handler(Name, Fun) ->
184 1 Ref = make_ref(),
185 1 CbName = {chrme_network, loading_finished, Name, Ref},
186 1 CbFun = fun
187
:-(
(stop) -> false;
188 (#{<<"method">> := <<"Network.loadingFinished">>, <<"params">> := Params}) ->
189 1 Fun(Params),
190 1 true;
191 8 (_) -> false
192 end,
193 1 chrme_ws_apic:add_callback(Name, {CbName, CbFun}),
194 1 Ref.
195
196 -spec unregister_loading_finished_handler(chrme_session:name(), reference()) -> ok.
197 unregister_loading_finished_handler(Name, Ref) ->
198 1 CbName = {chrme_network, loading_finished, Name, Ref},
199 1 chrme_ws_apic:remove_callback(Name, CbName),
200 1 ok.
Line Hits Source