mithwire 0.50.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mithwire/__init__.py +32 -0
- mithwire/cdp/README.md +4 -0
- mithwire/cdp/__init__.py +6 -0
- mithwire/cdp/accessibility.py +668 -0
- mithwire/cdp/animation.py +494 -0
- mithwire/cdp/audits.py +1995 -0
- mithwire/cdp/autofill.py +292 -0
- mithwire/cdp/background_service.py +215 -0
- mithwire/cdp/bluetooth_emulation.py +626 -0
- mithwire/cdp/browser.py +821 -0
- mithwire/cdp/cache_storage.py +311 -0
- mithwire/cdp/cast.py +172 -0
- mithwire/cdp/console.py +107 -0
- mithwire/cdp/crash_report_context.py +55 -0
- mithwire/cdp/css.py +2750 -0
- mithwire/cdp/database.py +179 -0
- mithwire/cdp/debugger.py +1405 -0
- mithwire/cdp/device_access.py +141 -0
- mithwire/cdp/device_orientation.py +45 -0
- mithwire/cdp/dom.py +2257 -0
- mithwire/cdp/dom_debugger.py +321 -0
- mithwire/cdp/dom_snapshot.py +876 -0
- mithwire/cdp/dom_storage.py +222 -0
- mithwire/cdp/emulation.py +1779 -0
- mithwire/cdp/event_breakpoints.py +56 -0
- mithwire/cdp/extensions.py +238 -0
- mithwire/cdp/fed_cm.py +283 -0
- mithwire/cdp/fetch.py +507 -0
- mithwire/cdp/file_system.py +115 -0
- mithwire/cdp/headless_experimental.py +115 -0
- mithwire/cdp/heap_profiler.py +401 -0
- mithwire/cdp/indexed_db.py +528 -0
- mithwire/cdp/input_.py +701 -0
- mithwire/cdp/inspector.py +95 -0
- mithwire/cdp/io.py +101 -0
- mithwire/cdp/layer_tree.py +464 -0
- mithwire/cdp/log.py +190 -0
- mithwire/cdp/media.py +313 -0
- mithwire/cdp/memory.py +305 -0
- mithwire/cdp/network.py +5342 -0
- mithwire/cdp/overlay.py +1468 -0
- mithwire/cdp/page.py +3972 -0
- mithwire/cdp/performance.py +124 -0
- mithwire/cdp/performance_timeline.py +200 -0
- mithwire/cdp/preload.py +575 -0
- mithwire/cdp/profiler.py +420 -0
- mithwire/cdp/pwa.py +278 -0
- mithwire/cdp/py.typed +0 -0
- mithwire/cdp/runtime.py +1589 -0
- mithwire/cdp/schema.py +50 -0
- mithwire/cdp/security.py +518 -0
- mithwire/cdp/service_worker.py +401 -0
- mithwire/cdp/smart_card_emulation.py +891 -0
- mithwire/cdp/storage.py +1573 -0
- mithwire/cdp/system_info.py +327 -0
- mithwire/cdp/target.py +829 -0
- mithwire/cdp/tethering.py +65 -0
- mithwire/cdp/tracing.py +377 -0
- mithwire/cdp/util.py +18 -0
- mithwire/cdp/web_audio.py +606 -0
- mithwire/cdp/web_authn.py +598 -0
- mithwire/cdp/web_mcp.py +293 -0
- mithwire/core/_contradict.py +142 -0
- mithwire/core/browser.py +923 -0
- mithwire/core/cf_templates/cf_dark_checkbox.png +0 -0
- mithwire/core/cf_templates/cf_light_checkbox.png +0 -0
- mithwire/core/config.py +323 -0
- mithwire/core/connection.py +564 -0
- mithwire/core/element.py +1205 -0
- mithwire/core/tab.py +2202 -0
- mithwire/core/util.py +5063 -0
- mithwire-0.50.3.dist-info/METADATA +1049 -0
- mithwire-0.50.3.dist-info/RECORD +76 -0
- mithwire-0.50.3.dist-info/WHEEL +5 -0
- mithwire-0.50.3.dist-info/licenses/LICENSE.txt +619 -0
- mithwire-0.50.3.dist-info/top_level.txt +1 -0
mithwire/cdp/profiler.py
ADDED
|
@@ -0,0 +1,420 @@
|
|
|
1
|
+
# DO NOT EDIT THIS FILE!
|
|
2
|
+
#
|
|
3
|
+
# This file is generated from the CDP specification. If you need to make
|
|
4
|
+
# changes, edit the generator and regenerate all of the modules.
|
|
5
|
+
#
|
|
6
|
+
# CDP domain: Profiler
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
import enum
|
|
10
|
+
import typing
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from .util import event_class, T_JSON_DICT
|
|
13
|
+
|
|
14
|
+
from . import debugger
|
|
15
|
+
from . import runtime
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class ProfileNode:
|
|
20
|
+
'''
|
|
21
|
+
Profile node. Holds callsite information, execution statistics and child nodes.
|
|
22
|
+
'''
|
|
23
|
+
#: Unique id of the node.
|
|
24
|
+
id_: int
|
|
25
|
+
|
|
26
|
+
#: Function location.
|
|
27
|
+
call_frame: runtime.CallFrame
|
|
28
|
+
|
|
29
|
+
#: Number of samples where this node was on top of the call stack.
|
|
30
|
+
hit_count: typing.Optional[int] = None
|
|
31
|
+
|
|
32
|
+
#: Child node ids.
|
|
33
|
+
children: typing.Optional[typing.List[int]] = None
|
|
34
|
+
|
|
35
|
+
#: The reason of being not optimized. The function may be deoptimized or marked as don't
|
|
36
|
+
#: optimize.
|
|
37
|
+
deopt_reason: typing.Optional[str] = None
|
|
38
|
+
|
|
39
|
+
#: An array of source position ticks.
|
|
40
|
+
position_ticks: typing.Optional[typing.List[PositionTickInfo]] = None
|
|
41
|
+
|
|
42
|
+
def to_json(self) -> T_JSON_DICT:
|
|
43
|
+
json: T_JSON_DICT = dict()
|
|
44
|
+
json['id'] = self.id_
|
|
45
|
+
json['callFrame'] = self.call_frame.to_json()
|
|
46
|
+
if self.hit_count is not None:
|
|
47
|
+
json['hitCount'] = self.hit_count
|
|
48
|
+
if self.children is not None:
|
|
49
|
+
json['children'] = [i for i in self.children]
|
|
50
|
+
if self.deopt_reason is not None:
|
|
51
|
+
json['deoptReason'] = self.deopt_reason
|
|
52
|
+
if self.position_ticks is not None:
|
|
53
|
+
json['positionTicks'] = [i.to_json() for i in self.position_ticks]
|
|
54
|
+
return json
|
|
55
|
+
|
|
56
|
+
@classmethod
|
|
57
|
+
def from_json(cls, json: T_JSON_DICT) -> ProfileNode:
|
|
58
|
+
return cls(
|
|
59
|
+
id_=int(json['id']),
|
|
60
|
+
call_frame=runtime.CallFrame.from_json(json['callFrame']),
|
|
61
|
+
hit_count=int(json['hitCount']) if json.get('hitCount', None) is not None else None,
|
|
62
|
+
children=[int(i) for i in json['children']] if json.get('children', None) is not None else None,
|
|
63
|
+
deopt_reason=str(json['deoptReason']) if json.get('deoptReason', None) is not None else None,
|
|
64
|
+
position_ticks=[PositionTickInfo.from_json(i) for i in json['positionTicks']] if json.get('positionTicks', None) is not None else None,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@dataclass
|
|
69
|
+
class Profile:
|
|
70
|
+
'''
|
|
71
|
+
Profile.
|
|
72
|
+
'''
|
|
73
|
+
#: The list of profile nodes. First item is the root node.
|
|
74
|
+
nodes: typing.List[ProfileNode]
|
|
75
|
+
|
|
76
|
+
#: Profiling start timestamp in microseconds.
|
|
77
|
+
start_time: float
|
|
78
|
+
|
|
79
|
+
#: Profiling end timestamp in microseconds.
|
|
80
|
+
end_time: float
|
|
81
|
+
|
|
82
|
+
#: Ids of samples top nodes.
|
|
83
|
+
samples: typing.Optional[typing.List[int]] = None
|
|
84
|
+
|
|
85
|
+
#: Time intervals between adjacent samples in microseconds. The first delta is relative to the
|
|
86
|
+
#: profile startTime.
|
|
87
|
+
time_deltas: typing.Optional[typing.List[int]] = None
|
|
88
|
+
|
|
89
|
+
def to_json(self) -> T_JSON_DICT:
|
|
90
|
+
json: T_JSON_DICT = dict()
|
|
91
|
+
json['nodes'] = [i.to_json() for i in self.nodes]
|
|
92
|
+
json['startTime'] = self.start_time
|
|
93
|
+
json['endTime'] = self.end_time
|
|
94
|
+
if self.samples is not None:
|
|
95
|
+
json['samples'] = [i for i in self.samples]
|
|
96
|
+
if self.time_deltas is not None:
|
|
97
|
+
json['timeDeltas'] = [i for i in self.time_deltas]
|
|
98
|
+
return json
|
|
99
|
+
|
|
100
|
+
@classmethod
|
|
101
|
+
def from_json(cls, json: T_JSON_DICT) -> Profile:
|
|
102
|
+
return cls(
|
|
103
|
+
nodes=[ProfileNode.from_json(i) for i in json['nodes']],
|
|
104
|
+
start_time=float(json['startTime']),
|
|
105
|
+
end_time=float(json['endTime']),
|
|
106
|
+
samples=[int(i) for i in json['samples']] if json.get('samples', None) is not None else None,
|
|
107
|
+
time_deltas=[int(i) for i in json['timeDeltas']] if json.get('timeDeltas', None) is not None else None,
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
@dataclass
|
|
112
|
+
class PositionTickInfo:
|
|
113
|
+
'''
|
|
114
|
+
Specifies a number of samples attributed to a certain source position.
|
|
115
|
+
'''
|
|
116
|
+
#: Source line number (1-based).
|
|
117
|
+
line: int
|
|
118
|
+
|
|
119
|
+
#: Number of samples attributed to the source line.
|
|
120
|
+
ticks: int
|
|
121
|
+
|
|
122
|
+
def to_json(self) -> T_JSON_DICT:
|
|
123
|
+
json: T_JSON_DICT = dict()
|
|
124
|
+
json['line'] = self.line
|
|
125
|
+
json['ticks'] = self.ticks
|
|
126
|
+
return json
|
|
127
|
+
|
|
128
|
+
@classmethod
|
|
129
|
+
def from_json(cls, json: T_JSON_DICT) -> PositionTickInfo:
|
|
130
|
+
return cls(
|
|
131
|
+
line=int(json['line']),
|
|
132
|
+
ticks=int(json['ticks']),
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
@dataclass
|
|
137
|
+
class CoverageRange:
|
|
138
|
+
'''
|
|
139
|
+
Coverage data for a source range.
|
|
140
|
+
'''
|
|
141
|
+
#: JavaScript script source offset for the range start.
|
|
142
|
+
start_offset: int
|
|
143
|
+
|
|
144
|
+
#: JavaScript script source offset for the range end.
|
|
145
|
+
end_offset: int
|
|
146
|
+
|
|
147
|
+
#: Collected execution count of the source range.
|
|
148
|
+
count: int
|
|
149
|
+
|
|
150
|
+
def to_json(self) -> T_JSON_DICT:
|
|
151
|
+
json: T_JSON_DICT = dict()
|
|
152
|
+
json['startOffset'] = self.start_offset
|
|
153
|
+
json['endOffset'] = self.end_offset
|
|
154
|
+
json['count'] = self.count
|
|
155
|
+
return json
|
|
156
|
+
|
|
157
|
+
@classmethod
|
|
158
|
+
def from_json(cls, json: T_JSON_DICT) -> CoverageRange:
|
|
159
|
+
return cls(
|
|
160
|
+
start_offset=int(json['startOffset']),
|
|
161
|
+
end_offset=int(json['endOffset']),
|
|
162
|
+
count=int(json['count']),
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
@dataclass
|
|
167
|
+
class FunctionCoverage:
|
|
168
|
+
'''
|
|
169
|
+
Coverage data for a JavaScript function.
|
|
170
|
+
'''
|
|
171
|
+
#: JavaScript function name.
|
|
172
|
+
function_name: str
|
|
173
|
+
|
|
174
|
+
#: Source ranges inside the function with coverage data.
|
|
175
|
+
ranges: typing.List[CoverageRange]
|
|
176
|
+
|
|
177
|
+
#: Whether coverage data for this function has block granularity.
|
|
178
|
+
is_block_coverage: bool
|
|
179
|
+
|
|
180
|
+
def to_json(self) -> T_JSON_DICT:
|
|
181
|
+
json: T_JSON_DICT = dict()
|
|
182
|
+
json['functionName'] = self.function_name
|
|
183
|
+
json['ranges'] = [i.to_json() for i in self.ranges]
|
|
184
|
+
json['isBlockCoverage'] = self.is_block_coverage
|
|
185
|
+
return json
|
|
186
|
+
|
|
187
|
+
@classmethod
|
|
188
|
+
def from_json(cls, json: T_JSON_DICT) -> FunctionCoverage:
|
|
189
|
+
return cls(
|
|
190
|
+
function_name=str(json['functionName']),
|
|
191
|
+
ranges=[CoverageRange.from_json(i) for i in json['ranges']],
|
|
192
|
+
is_block_coverage=bool(json['isBlockCoverage']),
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
@dataclass
|
|
197
|
+
class ScriptCoverage:
|
|
198
|
+
'''
|
|
199
|
+
Coverage data for a JavaScript script.
|
|
200
|
+
'''
|
|
201
|
+
#: JavaScript script id.
|
|
202
|
+
script_id: runtime.ScriptId
|
|
203
|
+
|
|
204
|
+
#: JavaScript script name or url.
|
|
205
|
+
url: str
|
|
206
|
+
|
|
207
|
+
#: Functions contained in the script that has coverage data.
|
|
208
|
+
functions: typing.List[FunctionCoverage]
|
|
209
|
+
|
|
210
|
+
def to_json(self) -> T_JSON_DICT:
|
|
211
|
+
json: T_JSON_DICT = dict()
|
|
212
|
+
json['scriptId'] = self.script_id.to_json()
|
|
213
|
+
json['url'] = self.url
|
|
214
|
+
json['functions'] = [i.to_json() for i in self.functions]
|
|
215
|
+
return json
|
|
216
|
+
|
|
217
|
+
@classmethod
|
|
218
|
+
def from_json(cls, json: T_JSON_DICT) -> ScriptCoverage:
|
|
219
|
+
return cls(
|
|
220
|
+
script_id=runtime.ScriptId.from_json(json['scriptId']),
|
|
221
|
+
url=str(json['url']),
|
|
222
|
+
functions=[FunctionCoverage.from_json(i) for i in json['functions']],
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
227
|
+
|
|
228
|
+
cmd_dict: T_JSON_DICT = {
|
|
229
|
+
'method': 'Profiler.disable',
|
|
230
|
+
}
|
|
231
|
+
json = yield cmd_dict
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
235
|
+
|
|
236
|
+
cmd_dict: T_JSON_DICT = {
|
|
237
|
+
'method': 'Profiler.enable',
|
|
238
|
+
}
|
|
239
|
+
json = yield cmd_dict
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def get_best_effort_coverage() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[ScriptCoverage]]:
|
|
243
|
+
'''
|
|
244
|
+
Collect coverage data for the current isolate. The coverage data may be incomplete due to
|
|
245
|
+
garbage collection.
|
|
246
|
+
|
|
247
|
+
:returns: Coverage data for the current isolate.
|
|
248
|
+
'''
|
|
249
|
+
cmd_dict: T_JSON_DICT = {
|
|
250
|
+
'method': 'Profiler.getBestEffortCoverage',
|
|
251
|
+
}
|
|
252
|
+
json = yield cmd_dict
|
|
253
|
+
return [ScriptCoverage.from_json(i) for i in json['result']]
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
def set_sampling_interval(
|
|
257
|
+
interval: int
|
|
258
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
259
|
+
'''
|
|
260
|
+
Changes CPU profiler sampling interval. Must be called before CPU profiles recording started.
|
|
261
|
+
|
|
262
|
+
:param interval: New sampling interval in microseconds.
|
|
263
|
+
'''
|
|
264
|
+
params: T_JSON_DICT = dict()
|
|
265
|
+
params['interval'] = interval
|
|
266
|
+
cmd_dict: T_JSON_DICT = {
|
|
267
|
+
'method': 'Profiler.setSamplingInterval',
|
|
268
|
+
'params': params,
|
|
269
|
+
}
|
|
270
|
+
json = yield cmd_dict
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
def start() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
274
|
+
|
|
275
|
+
cmd_dict: T_JSON_DICT = {
|
|
276
|
+
'method': 'Profiler.start',
|
|
277
|
+
}
|
|
278
|
+
json = yield cmd_dict
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
def start_precise_coverage(
|
|
282
|
+
call_count: typing.Optional[bool] = None,
|
|
283
|
+
detailed: typing.Optional[bool] = None,
|
|
284
|
+
allow_triggered_updates: typing.Optional[bool] = None
|
|
285
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,float]:
|
|
286
|
+
'''
|
|
287
|
+
Enable precise code coverage. Coverage data for JavaScript executed before enabling precise code
|
|
288
|
+
coverage may be incomplete. Enabling prevents running optimized code and resets execution
|
|
289
|
+
counters.
|
|
290
|
+
|
|
291
|
+
:param call_count: *(Optional)* Collect accurate call counts beyond simple 'covered' or 'not covered'.
|
|
292
|
+
:param detailed: *(Optional)* Collect block-based coverage.
|
|
293
|
+
:param allow_triggered_updates: *(Optional)* Allow the backend to send updates on its own initiative
|
|
294
|
+
:returns: Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
|
|
295
|
+
'''
|
|
296
|
+
params: T_JSON_DICT = dict()
|
|
297
|
+
if call_count is not None:
|
|
298
|
+
params['callCount'] = call_count
|
|
299
|
+
if detailed is not None:
|
|
300
|
+
params['detailed'] = detailed
|
|
301
|
+
if allow_triggered_updates is not None:
|
|
302
|
+
params['allowTriggeredUpdates'] = allow_triggered_updates
|
|
303
|
+
cmd_dict: T_JSON_DICT = {
|
|
304
|
+
'method': 'Profiler.startPreciseCoverage',
|
|
305
|
+
'params': params,
|
|
306
|
+
}
|
|
307
|
+
json = yield cmd_dict
|
|
308
|
+
return float(json['timestamp'])
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
def stop() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,Profile]:
|
|
312
|
+
'''
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
:returns: Recorded profile.
|
|
316
|
+
'''
|
|
317
|
+
cmd_dict: T_JSON_DICT = {
|
|
318
|
+
'method': 'Profiler.stop',
|
|
319
|
+
}
|
|
320
|
+
json = yield cmd_dict
|
|
321
|
+
return Profile.from_json(json['profile'])
|
|
322
|
+
|
|
323
|
+
|
|
324
|
+
def stop_precise_coverage() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
325
|
+
'''
|
|
326
|
+
Disable precise code coverage. Disabling releases unnecessary execution count records and allows
|
|
327
|
+
executing optimized code.
|
|
328
|
+
'''
|
|
329
|
+
cmd_dict: T_JSON_DICT = {
|
|
330
|
+
'method': 'Profiler.stopPreciseCoverage',
|
|
331
|
+
}
|
|
332
|
+
json = yield cmd_dict
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def take_precise_coverage() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[typing.List[ScriptCoverage], float]]:
|
|
336
|
+
'''
|
|
337
|
+
Collect coverage data for the current isolate, and resets execution counters. Precise code
|
|
338
|
+
coverage needs to have started.
|
|
339
|
+
|
|
340
|
+
:returns: A tuple with the following items:
|
|
341
|
+
|
|
342
|
+
0. **result** - Coverage data for the current isolate.
|
|
343
|
+
1. **timestamp** - Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
|
|
344
|
+
'''
|
|
345
|
+
cmd_dict: T_JSON_DICT = {
|
|
346
|
+
'method': 'Profiler.takePreciseCoverage',
|
|
347
|
+
}
|
|
348
|
+
json = yield cmd_dict
|
|
349
|
+
return (
|
|
350
|
+
[ScriptCoverage.from_json(i) for i in json['result']],
|
|
351
|
+
float(json['timestamp'])
|
|
352
|
+
)
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
@event_class('Profiler.consoleProfileFinished')
|
|
356
|
+
@dataclass
|
|
357
|
+
class ConsoleProfileFinished:
|
|
358
|
+
id_: str
|
|
359
|
+
#: Location of console.profileEnd().
|
|
360
|
+
location: debugger.Location
|
|
361
|
+
profile: Profile
|
|
362
|
+
#: Profile title passed as an argument to console.profile().
|
|
363
|
+
title: typing.Optional[str]
|
|
364
|
+
|
|
365
|
+
@classmethod
|
|
366
|
+
def from_json(cls, json: T_JSON_DICT) -> ConsoleProfileFinished:
|
|
367
|
+
return cls(
|
|
368
|
+
id_=str(json['id']),
|
|
369
|
+
location=debugger.Location.from_json(json['location']),
|
|
370
|
+
profile=Profile.from_json(json['profile']),
|
|
371
|
+
title=str(json['title']) if json.get('title', None) is not None else None
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
@event_class('Profiler.consoleProfileStarted')
|
|
376
|
+
@dataclass
|
|
377
|
+
class ConsoleProfileStarted:
|
|
378
|
+
'''
|
|
379
|
+
Sent when new profile recording is started using console.profile() call.
|
|
380
|
+
'''
|
|
381
|
+
id_: str
|
|
382
|
+
#: Location of console.profile().
|
|
383
|
+
location: debugger.Location
|
|
384
|
+
#: Profile title passed as an argument to console.profile().
|
|
385
|
+
title: typing.Optional[str]
|
|
386
|
+
|
|
387
|
+
@classmethod
|
|
388
|
+
def from_json(cls, json: T_JSON_DICT) -> ConsoleProfileStarted:
|
|
389
|
+
return cls(
|
|
390
|
+
id_=str(json['id']),
|
|
391
|
+
location=debugger.Location.from_json(json['location']),
|
|
392
|
+
title=str(json['title']) if json.get('title', None) is not None else None
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
@event_class('Profiler.preciseCoverageDeltaUpdate')
|
|
397
|
+
@dataclass
|
|
398
|
+
class PreciseCoverageDeltaUpdate:
|
|
399
|
+
'''
|
|
400
|
+
**EXPERIMENTAL**
|
|
401
|
+
|
|
402
|
+
Reports coverage delta since the last poll (either from an event like this, or from
|
|
403
|
+
``takePreciseCoverage`` for the current isolate. May only be sent if precise code
|
|
404
|
+
coverage has been started. This event can be trigged by the embedder to, for example,
|
|
405
|
+
trigger collection of coverage data immediately at a certain point in time.
|
|
406
|
+
'''
|
|
407
|
+
#: Monotonically increasing time (in seconds) when the coverage update was taken in the backend.
|
|
408
|
+
timestamp: float
|
|
409
|
+
#: Identifier for distinguishing coverage events.
|
|
410
|
+
occasion: str
|
|
411
|
+
#: Coverage data for the current isolate.
|
|
412
|
+
result: typing.List[ScriptCoverage]
|
|
413
|
+
|
|
414
|
+
@classmethod
|
|
415
|
+
def from_json(cls, json: T_JSON_DICT) -> PreciseCoverageDeltaUpdate:
|
|
416
|
+
return cls(
|
|
417
|
+
timestamp=float(json['timestamp']),
|
|
418
|
+
occasion=str(json['occasion']),
|
|
419
|
+
result=[ScriptCoverage.from_json(i) for i in json['result']]
|
|
420
|
+
)
|
mithwire/cdp/pwa.py
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# DO NOT EDIT THIS FILE!
|
|
2
|
+
#
|
|
3
|
+
# This file is generated from the CDP specification. If you need to make
|
|
4
|
+
# changes, edit the generator and regenerate all of the modules.
|
|
5
|
+
#
|
|
6
|
+
# CDP domain: PWA (experimental)
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
import enum
|
|
10
|
+
import typing
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from .util import event_class, T_JSON_DICT
|
|
13
|
+
|
|
14
|
+
from . import target
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class FileHandlerAccept:
|
|
19
|
+
'''
|
|
20
|
+
The following types are the replica of
|
|
21
|
+
https://crsrc.org/c/chrome/browser/web_applications/proto/web_app_os_integration_state.proto;drc=9910d3be894c8f142c977ba1023f30a656bc13fc;l=67
|
|
22
|
+
'''
|
|
23
|
+
#: New name of the mimetype according to
|
|
24
|
+
#: https://www.iana.org/assignments/media-types/media-types.xhtml
|
|
25
|
+
media_type: str
|
|
26
|
+
|
|
27
|
+
file_extensions: typing.List[str]
|
|
28
|
+
|
|
29
|
+
def to_json(self) -> T_JSON_DICT:
|
|
30
|
+
json: T_JSON_DICT = dict()
|
|
31
|
+
json['mediaType'] = self.media_type
|
|
32
|
+
json['fileExtensions'] = [i for i in self.file_extensions]
|
|
33
|
+
return json
|
|
34
|
+
|
|
35
|
+
@classmethod
|
|
36
|
+
def from_json(cls, json: T_JSON_DICT) -> FileHandlerAccept:
|
|
37
|
+
return cls(
|
|
38
|
+
media_type=str(json['mediaType']),
|
|
39
|
+
file_extensions=[str(i) for i in json['fileExtensions']],
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@dataclass
|
|
44
|
+
class FileHandler:
|
|
45
|
+
action: str
|
|
46
|
+
|
|
47
|
+
accepts: typing.List[FileHandlerAccept]
|
|
48
|
+
|
|
49
|
+
display_name: str
|
|
50
|
+
|
|
51
|
+
def to_json(self) -> T_JSON_DICT:
|
|
52
|
+
json: T_JSON_DICT = dict()
|
|
53
|
+
json['action'] = self.action
|
|
54
|
+
json['accepts'] = [i.to_json() for i in self.accepts]
|
|
55
|
+
json['displayName'] = self.display_name
|
|
56
|
+
return json
|
|
57
|
+
|
|
58
|
+
@classmethod
|
|
59
|
+
def from_json(cls, json: T_JSON_DICT) -> FileHandler:
|
|
60
|
+
return cls(
|
|
61
|
+
action=str(json['action']),
|
|
62
|
+
accepts=[FileHandlerAccept.from_json(i) for i in json['accepts']],
|
|
63
|
+
display_name=str(json['displayName']),
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
class DisplayMode(enum.Enum):
|
|
68
|
+
'''
|
|
69
|
+
If user prefers opening the app in browser or an app window.
|
|
70
|
+
'''
|
|
71
|
+
STANDALONE = "standalone"
|
|
72
|
+
BROWSER = "browser"
|
|
73
|
+
|
|
74
|
+
def to_json(self) -> str:
|
|
75
|
+
return self.value
|
|
76
|
+
|
|
77
|
+
@classmethod
|
|
78
|
+
def from_json(cls, json: str) -> DisplayMode:
|
|
79
|
+
return cls(json)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def get_os_app_state(
|
|
83
|
+
manifest_id: str
|
|
84
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[int, typing.List[FileHandler]]]:
|
|
85
|
+
'''
|
|
86
|
+
Returns the following OS state for the given manifest id.
|
|
87
|
+
|
|
88
|
+
:param manifest_id: The id from the webapp's manifest file, commonly it's the url of the site installing the webapp. See https://web.dev/learn/pwa/web-app-manifest.
|
|
89
|
+
:returns: A tuple with the following items:
|
|
90
|
+
|
|
91
|
+
0. **badgeCount** -
|
|
92
|
+
1. **fileHandlers** -
|
|
93
|
+
'''
|
|
94
|
+
params: T_JSON_DICT = dict()
|
|
95
|
+
params['manifestId'] = manifest_id
|
|
96
|
+
cmd_dict: T_JSON_DICT = {
|
|
97
|
+
'method': 'PWA.getOsAppState',
|
|
98
|
+
'params': params,
|
|
99
|
+
}
|
|
100
|
+
json = yield cmd_dict
|
|
101
|
+
return (
|
|
102
|
+
int(json['badgeCount']),
|
|
103
|
+
[FileHandler.from_json(i) for i in json['fileHandlers']]
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def install(
|
|
108
|
+
manifest_id: str,
|
|
109
|
+
install_url_or_bundle_url: typing.Optional[str] = None
|
|
110
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
111
|
+
'''
|
|
112
|
+
Installs the given manifest identity, optionally using the given installUrlOrBundleUrl
|
|
113
|
+
|
|
114
|
+
IWA-specific install description:
|
|
115
|
+
manifestId corresponds to isolated-app:// + web_package::SignedWebBundleId
|
|
116
|
+
|
|
117
|
+
File installation mode:
|
|
118
|
+
The installUrlOrBundleUrl can be either file:// or http(s):// pointing
|
|
119
|
+
to a signed web bundle (.swbn). In this case SignedWebBundleId must correspond to
|
|
120
|
+
The .swbn file's signing key.
|
|
121
|
+
|
|
122
|
+
Dev proxy installation mode:
|
|
123
|
+
installUrlOrBundleUrl must be http(s):// that serves dev mode IWA.
|
|
124
|
+
web_package::SignedWebBundleId must be of type dev proxy.
|
|
125
|
+
|
|
126
|
+
The advantage of dev proxy mode is that all changes to IWA
|
|
127
|
+
automatically will be reflected in the running app without
|
|
128
|
+
reinstallation.
|
|
129
|
+
|
|
130
|
+
To generate bundle id for proxy mode:
|
|
131
|
+
1. Generate 32 random bytes.
|
|
132
|
+
2. Add a specific suffix at the end following the documentation
|
|
133
|
+
https://github.com/WICG/isolated-web-apps/blob/main/Scheme.md#suffix
|
|
134
|
+
3. Encode the entire sequence using Base32 without padding.
|
|
135
|
+
|
|
136
|
+
If Chrome is not in IWA dev
|
|
137
|
+
mode, the installation will fail, regardless of the state of the allowlist.
|
|
138
|
+
|
|
139
|
+
:param manifest_id:
|
|
140
|
+
:param install_url_or_bundle_url: *(Optional)* The location of the app or bundle overriding the one derived from the manifestId.
|
|
141
|
+
'''
|
|
142
|
+
params: T_JSON_DICT = dict()
|
|
143
|
+
params['manifestId'] = manifest_id
|
|
144
|
+
if install_url_or_bundle_url is not None:
|
|
145
|
+
params['installUrlOrBundleUrl'] = install_url_or_bundle_url
|
|
146
|
+
cmd_dict: T_JSON_DICT = {
|
|
147
|
+
'method': 'PWA.install',
|
|
148
|
+
'params': params,
|
|
149
|
+
}
|
|
150
|
+
json = yield cmd_dict
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def uninstall(
|
|
154
|
+
manifest_id: str
|
|
155
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
156
|
+
'''
|
|
157
|
+
Uninstalls the given manifest_id and closes any opened app windows.
|
|
158
|
+
|
|
159
|
+
:param manifest_id:
|
|
160
|
+
'''
|
|
161
|
+
params: T_JSON_DICT = dict()
|
|
162
|
+
params['manifestId'] = manifest_id
|
|
163
|
+
cmd_dict: T_JSON_DICT = {
|
|
164
|
+
'method': 'PWA.uninstall',
|
|
165
|
+
'params': params,
|
|
166
|
+
}
|
|
167
|
+
json = yield cmd_dict
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def launch(
|
|
171
|
+
manifest_id: str,
|
|
172
|
+
url: typing.Optional[str] = None
|
|
173
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,target.TargetID]:
|
|
174
|
+
'''
|
|
175
|
+
Launches the installed web app, or an url in the same web app instead of the
|
|
176
|
+
default start url if it is provided. Returns a page Target.TargetID which
|
|
177
|
+
can be used to attach to via Target.attachToTarget or similar APIs.
|
|
178
|
+
|
|
179
|
+
:param manifest_id:
|
|
180
|
+
:param url: *(Optional)*
|
|
181
|
+
:returns: ID of the tab target created as a result.
|
|
182
|
+
'''
|
|
183
|
+
params: T_JSON_DICT = dict()
|
|
184
|
+
params['manifestId'] = manifest_id
|
|
185
|
+
if url is not None:
|
|
186
|
+
params['url'] = url
|
|
187
|
+
cmd_dict: T_JSON_DICT = {
|
|
188
|
+
'method': 'PWA.launch',
|
|
189
|
+
'params': params,
|
|
190
|
+
}
|
|
191
|
+
json = yield cmd_dict
|
|
192
|
+
return target.TargetID.from_json(json['targetId'])
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
def launch_files_in_app(
|
|
196
|
+
manifest_id: str,
|
|
197
|
+
files: typing.List[str]
|
|
198
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[target.TargetID]]:
|
|
199
|
+
'''
|
|
200
|
+
Opens one or more local files from an installed web app identified by its
|
|
201
|
+
manifestId. The web app needs to have file handlers registered to process
|
|
202
|
+
the files. The API returns one or more page Target.TargetIDs which can be
|
|
203
|
+
used to attach to via Target.attachToTarget or similar APIs.
|
|
204
|
+
If some files in the parameters cannot be handled by the web app, they will
|
|
205
|
+
be ignored. If none of the files can be handled, this API returns an error.
|
|
206
|
+
If no files are provided as the parameter, this API also returns an error.
|
|
207
|
+
|
|
208
|
+
According to the definition of the file handlers in the manifest file, one
|
|
209
|
+
Target.TargetID may represent a page handling one or more files. The order
|
|
210
|
+
of the returned Target.TargetIDs is not guaranteed.
|
|
211
|
+
|
|
212
|
+
TODO(crbug.com/339454034): Check the existences of the input files.
|
|
213
|
+
|
|
214
|
+
:param manifest_id:
|
|
215
|
+
:param files:
|
|
216
|
+
:returns: IDs of the tab targets created as the result.
|
|
217
|
+
'''
|
|
218
|
+
params: T_JSON_DICT = dict()
|
|
219
|
+
params['manifestId'] = manifest_id
|
|
220
|
+
params['files'] = [i for i in files]
|
|
221
|
+
cmd_dict: T_JSON_DICT = {
|
|
222
|
+
'method': 'PWA.launchFilesInApp',
|
|
223
|
+
'params': params,
|
|
224
|
+
}
|
|
225
|
+
json = yield cmd_dict
|
|
226
|
+
return [target.TargetID.from_json(i) for i in json['targetIds']]
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def open_current_page_in_app(
|
|
230
|
+
manifest_id: str
|
|
231
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
232
|
+
'''
|
|
233
|
+
Opens the current page in its web app identified by the manifest id, needs
|
|
234
|
+
to be called on a page target. This function returns immediately without
|
|
235
|
+
waiting for the app to finish loading.
|
|
236
|
+
|
|
237
|
+
:param manifest_id:
|
|
238
|
+
'''
|
|
239
|
+
params: T_JSON_DICT = dict()
|
|
240
|
+
params['manifestId'] = manifest_id
|
|
241
|
+
cmd_dict: T_JSON_DICT = {
|
|
242
|
+
'method': 'PWA.openCurrentPageInApp',
|
|
243
|
+
'params': params,
|
|
244
|
+
}
|
|
245
|
+
json = yield cmd_dict
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
def change_app_user_settings(
|
|
249
|
+
manifest_id: str,
|
|
250
|
+
link_capturing: typing.Optional[bool] = None,
|
|
251
|
+
display_mode: typing.Optional[DisplayMode] = None
|
|
252
|
+
) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
|
|
253
|
+
'''
|
|
254
|
+
Changes user settings of the web app identified by its manifestId. If the
|
|
255
|
+
app was not installed, this command returns an error. Unset parameters will
|
|
256
|
+
be ignored; unrecognized values will cause an error.
|
|
257
|
+
|
|
258
|
+
Unlike the ones defined in the manifest files of the web apps, these
|
|
259
|
+
settings are provided by the browser and controlled by the users, they
|
|
260
|
+
impact the way the browser handling the web apps.
|
|
261
|
+
|
|
262
|
+
See the comment of each parameter.
|
|
263
|
+
|
|
264
|
+
:param manifest_id:
|
|
265
|
+
:param link_capturing: *(Optional)* If user allows the links clicked on by the user in the app's scope, or extended scope if the manifest has scope extensions and the flags ```DesktopPWAsLinkCapturingWithScopeExtensions```` and ````WebAppEnableScopeExtensions``` are enabled. Note, the API does not support resetting the linkCapturing to the initial value, uninstalling and installing the web app again will reset it. TODO(crbug.com/339453269): Setting this value on ChromeOS is not supported yet.
|
|
266
|
+
:param display_mode: *(Optional)*
|
|
267
|
+
'''
|
|
268
|
+
params: T_JSON_DICT = dict()
|
|
269
|
+
params['manifestId'] = manifest_id
|
|
270
|
+
if link_capturing is not None:
|
|
271
|
+
params['linkCapturing'] = link_capturing
|
|
272
|
+
if display_mode is not None:
|
|
273
|
+
params['displayMode'] = display_mode.to_json()
|
|
274
|
+
cmd_dict: T_JSON_DICT = {
|
|
275
|
+
'method': 'PWA.changeAppUserSettings',
|
|
276
|
+
'params': params,
|
|
277
|
+
}
|
|
278
|
+
json = yield cmd_dict
|
mithwire/cdp/py.typed
ADDED
|
File without changes
|