/home/runner/work/chrme/chrme/_build/test/cover/eunit/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
:-(
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
:-(
Ref = make_ref(),
43
:-(
CallbackName = {chrme_network, register_request_will_be_sent_handler, Name, Ref},
44
:-(
CallbackFun = fun
45
:-(
(stop) -> false;
46 (_Msg = #{<<"method">> := <<"Network.requestWillBeSent">>, <<"params">> := Params}) ->
47
:-(
Fun(Params),
48
:-(
true;
49
:-(
(_) -> false
50 end,
51
:-(
chrme_ws_apic:add_callback(Name, {CallbackName, CallbackFun}),
52
:-(
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
:-(
CallbackName = {chrme_network, register_request_will_be_sent_handler, Name, Ref},
58
:-(
chrme_ws_apic:remove_callback(Name, CallbackName),
59
:-(
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
:-(
Start = erlang:monotonic_time(millisecond),
79
:-(
Poll = fun This() ->
80
:-(
case get_response_body(Name, ReqId) of
81 {ok, _Body, _Enc} = Success ->
82
:-(
Success;
83 _ ->
84
:-(
Now = erlang:monotonic_time(millisecond),
85
:-(
case Now - Start >= Timeout of
86
:-(
true -> {error, timeout};
87 false ->
88
:-(
timer:sleep(100),
89
:-(
This()
90 end
91 end
92 end,
93
:-(
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
:-(
case chrme_cdp:call(Name, <<"Network.getResponseBody">>, #{requestId => RequestId}) of
114 {ok, #{<<"body">> := Body, <<"base64Encoded">> := Encoded}} ->
115
:-(
{ok, Body, Encoded};
116 Other ->
117
:-(
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
:-(
Ref = make_ref(),
129
:-(
CallbackName = {chrme_network, register_event_handler, Name, Ref},
130
:-(
CallbackFun = fun
131 (stop) ->
132
:-(
false;
133 (Msg = #{<<"method">> := Method}) ->
134
:-(
case Method of
135 <<"Network.", _/binary>> ->
136
:-(
Fun(Msg),
137
:-(
true;
138 _ ->
139
:-(
false
140 end;
141 (_) ->
142
:-(
false
143 end,
144
:-(
chrme_ws_apic:add_callback(Name, {CallbackName, CallbackFun}),
145
:-(
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
:-(
CallbackName = {chrme_network, register_event_handler, Name, Ref},
151
:-(
chrme_ws_apic:remove_callback(Name, CallbackName),
152
:-(
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
:-(
Ref = make_ref(),
163
:-(
CbName = {chrme_network, response_received, Name, Ref},
164
:-(
CbFun = fun
165
:-(
(stop) -> false;
166 (#{<<"method">> := <<"Network.responseReceived">>, <<"params">> := Params}) ->
167
:-(
Fun(Params),
168
:-(
true;
169
:-(
(_) -> false
170 end,
171
:-(
chrme_ws_apic:add_callback(Name, {CbName, CbFun}),
172
:-(
Ref.
173
174 -spec unregister_response_received_handler(chrme_session:name(), reference()) -> ok.
175 unregister_response_received_handler(Name, Ref) ->
176
:-(
CbName = {chrme_network, response_received, Name, Ref},
177
:-(
chrme_ws_apic:remove_callback(Name, CbName),
178
:-(
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
:-(
Ref = make_ref(),
185
:-(
CbName = {chrme_network, loading_finished, Name, Ref},
186
:-(
CbFun = fun
187
:-(
(stop) -> false;
188 (#{<<"method">> := <<"Network.loadingFinished">>, <<"params">> := Params}) ->
189
:-(
Fun(Params),
190
:-(
true;
191
:-(
(_) -> false
192 end,
193
:-(
chrme_ws_apic:add_callback(Name, {CbName, CbFun}),
194
:-(
Ref.
195
196 -spec unregister_loading_finished_handler(chrme_session:name(), reference()) -> ok.
197 unregister_loading_finished_handler(Name, Ref) ->
198
:-(
CbName = {chrme_network, loading_finished, Name, Ref},
199
:-(
chrme_ws_apic:remove_callback(Name, CbName),
200
:-(
ok.
Line Hits Source