robotcode-repl-server 0.100.2__tar.gz → 0.102.0__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/PKG-INFO +3 -3
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/pyproject.toml +2 -2
- robotcode_repl_server-0.102.0/src/robotcode/repl_server/__version__.py +1 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/interpreter.py +50 -144
- robotcode_repl_server-0.100.2/src/robotcode/repl_server/__version__.py +0 -1
- robotcode_repl_server-0.100.2/src/robotcode/repl_server/html_writer.py +0 -324
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/.gitignore +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/LICENSE.txt +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/README.md +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/__init__.py +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/cli.py +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/hooks.py +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/protocol.py +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/py.typed +0 -0
- {robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/server.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: robotcode-repl-server
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.102.0
|
4
4
|
Summary: RobotCode REPL Server for Robot Framework
|
5
5
|
Project-URL: Homepage, https://robotcode.io
|
6
6
|
Project-URL: Donate, https://opencollective.com/robotcode
|
@@ -24,8 +24,8 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
24
24
|
Classifier: Topic :: Utilities
|
25
25
|
Classifier: Typing :: Typed
|
26
26
|
Requires-Python: >=3.8
|
27
|
-
Requires-Dist: robotcode-jsonrpc2==0.
|
28
|
-
Requires-Dist: robotcode-runner==0.
|
27
|
+
Requires-Dist: robotcode-jsonrpc2==0.102.0
|
28
|
+
Requires-Dist: robotcode-runner==0.102.0
|
29
29
|
Description-Content-Type: text/markdown
|
30
30
|
|
31
31
|
# robotcode-repl-server
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "0.102.0"
|
@@ -1,16 +1,17 @@
|
|
1
|
+
import textwrap
|
1
2
|
from dataclasses import dataclass, field
|
2
|
-
from datetime import datetime
|
3
|
+
from datetime import datetime, timedelta
|
3
4
|
from pathlib import Path
|
4
5
|
from threading import Event
|
5
6
|
from typing import TYPE_CHECKING, Iterator, List, Optional, Protocol, Union, runtime_checkable
|
6
|
-
from uuid import uuid4
|
7
7
|
|
8
8
|
from robot.running import Keyword
|
9
|
+
from robot.utils.markuputils import html_format
|
10
|
+
from robot.utils.robottime import elapsed_time_to_string
|
9
11
|
|
10
12
|
from robotcode.core.utils.dataclasses import as_json
|
11
13
|
from robotcode.repl.base_interpreter import BaseInterpreter, is_true
|
12
|
-
|
13
|
-
from .html_writer import Element, create_keyword_html, create_message_html
|
14
|
+
from robotcode.robot.utils import get_robot_version
|
14
15
|
|
15
16
|
if TYPE_CHECKING:
|
16
17
|
from robot import result, running
|
@@ -76,13 +77,28 @@ class KeywordResultData(ResultData):
|
|
76
77
|
message: str
|
77
78
|
start_time: Optional[str]
|
78
79
|
end_time: Optional[str]
|
79
|
-
elapsed_time: Optional[
|
80
|
+
elapsed_time: Optional[str]
|
80
81
|
|
81
82
|
items: List[ResultData] = field(default_factory=list)
|
82
83
|
|
83
84
|
node_type: str = "keyword"
|
84
85
|
|
85
86
|
|
87
|
+
if get_robot_version() < (7, 0):
|
88
|
+
|
89
|
+
def make_elapsed_time_str(elapsed_time: Union[timedelta, int, float, None]) -> Optional[str]:
|
90
|
+
if elapsed_time is None:
|
91
|
+
return None
|
92
|
+
return str(elapsed_time_to_string(elapsed_time))
|
93
|
+
|
94
|
+
else:
|
95
|
+
|
96
|
+
def make_elapsed_time_str(elapsed_time: Union[timedelta, int, float, None]) -> Optional[str]:
|
97
|
+
if elapsed_time is None:
|
98
|
+
return None
|
99
|
+
return str(elapsed_time_to_string(elapsed_time, seconds=True))
|
100
|
+
|
101
|
+
|
86
102
|
class Interpreter(BaseInterpreter):
|
87
103
|
def __init__(
|
88
104
|
self,
|
@@ -93,45 +109,24 @@ class Interpreter(BaseInterpreter):
|
|
93
109
|
self.has_input = Event()
|
94
110
|
self.executed = Event()
|
95
111
|
self._code: List[str] = []
|
96
|
-
self._html_result: Optional[Element] = None
|
97
|
-
self._result_stack: List[Element] = []
|
98
|
-
self._output_stack: List[Element] = []
|
99
|
-
self._shadow_marker: Optional[str] = None
|
100
112
|
self._success: Optional[bool] = None
|
101
113
|
self._result_data: Optional[ResultData] = None
|
102
114
|
self._result_data_stack: List[ResultData] = []
|
103
115
|
self.collect_messages: bool = False
|
104
116
|
self._has_shutdown = False
|
117
|
+
self._cell_errors: List[str] = []
|
105
118
|
|
106
119
|
def shutdown(self) -> None:
|
107
120
|
self._code = []
|
108
121
|
self._has_shutdown = True
|
109
122
|
self.has_input.set()
|
110
|
-
# self.executed.set()
|
111
123
|
|
112
124
|
def execute(self, source: str) -> ExecutionResult:
|
113
|
-
self._result_stack = []
|
114
125
|
self._result_data_stack = []
|
115
126
|
|
116
127
|
self._success = None
|
117
128
|
try:
|
118
|
-
self.
|
119
|
-
|
120
|
-
html_result = Element("div", classes=["robot-results"])
|
121
|
-
|
122
|
-
with html_result.tag(
|
123
|
-
"div", attributes={"data-shadow-marker": self._shadow_marker}, styles={"display": "none"}
|
124
|
-
):
|
125
|
-
pass
|
126
|
-
|
127
|
-
outer_test: Optional[Element] = None
|
128
|
-
with html_result.tag("div", classes=["result_body"]) as body:
|
129
|
-
with body.tag("div", classes=["test"]) as test:
|
130
|
-
with test.tag("div", classes=["children"], styles={"display": "block"}):
|
131
|
-
pass
|
132
|
-
outer_test = test
|
133
|
-
|
134
|
-
self._html_result = outer_test
|
129
|
+
self._cell_errors = []
|
135
130
|
self._result_data = RootResultData()
|
136
131
|
|
137
132
|
self.executed.clear()
|
@@ -148,12 +143,18 @@ class Interpreter(BaseInterpreter):
|
|
148
143
|
ExecutionOutput(
|
149
144
|
"x-application/robotframework-repl-log", as_json(self._result_data, compact=True)
|
150
145
|
),
|
151
|
-
|
152
|
-
"
|
146
|
+
*(
|
147
|
+
[ExecutionOutput("application/vnd.code.notebook.stderr", "\n".join(self._cell_errors))]
|
148
|
+
if self._cell_errors
|
149
|
+
else []
|
153
150
|
),
|
154
151
|
]
|
155
152
|
if self._success is not None
|
156
|
-
else
|
153
|
+
else (
|
154
|
+
[ExecutionOutput("application/vnd.code.notebook.stderr", "\n".join(self._cell_errors))]
|
155
|
+
if self._cell_errors
|
156
|
+
else []
|
157
|
+
)
|
157
158
|
),
|
158
159
|
)
|
159
160
|
except BaseException as e:
|
@@ -164,7 +165,12 @@ class Interpreter(BaseInterpreter):
|
|
164
165
|
s = self._code.pop(0)
|
165
166
|
test, errors = self.get_test_body_from_string(s)
|
166
167
|
if errors:
|
167
|
-
|
168
|
+
self._cell_errors.append(
|
169
|
+
"CellInputError: " + ("\n" + textwrap.indent("\n".join(errors), " "))
|
170
|
+
if len(errors) > 1
|
171
|
+
else errors[0]
|
172
|
+
)
|
173
|
+
# raise CellInputError(errors)
|
168
174
|
|
169
175
|
for kw in test.body:
|
170
176
|
yield kw
|
@@ -183,29 +189,6 @@ class Interpreter(BaseInterpreter):
|
|
183
189
|
)
|
184
190
|
)
|
185
191
|
|
186
|
-
if level in ("DEBUG", "TRACE"):
|
187
|
-
return
|
188
|
-
|
189
|
-
if self._html_result is None:
|
190
|
-
return
|
191
|
-
|
192
|
-
items = next(
|
193
|
-
(
|
194
|
-
i
|
195
|
-
for i in self._html_result.children
|
196
|
-
if isinstance(i, Element) and i.tag_name == "div" and i.classes is not None and "children" in i.classes
|
197
|
-
),
|
198
|
-
None,
|
199
|
-
)
|
200
|
-
if items is None:
|
201
|
-
items = Element("div", classes=["children"])
|
202
|
-
self._html_result.add_element(items)
|
203
|
-
|
204
|
-
id = f"message-{len(items.children)}"
|
205
|
-
|
206
|
-
message_data = create_message_html(id, message, level, html, timestamp, shadow_root_id=self._shadow_marker)
|
207
|
-
items.add_element(message_data)
|
208
|
-
|
209
192
|
def message(
|
210
193
|
self, message: str, level: str, html: Union[str, bool] = False, timestamp: Union[datetime, str, None] = None
|
211
194
|
) -> None:
|
@@ -232,7 +215,7 @@ class Interpreter(BaseInterpreter):
|
|
232
215
|
name=result.name if getattr(result, "name", None) else "",
|
233
216
|
owner=result.owner if getattr(result, "owner", None) else "",
|
234
217
|
source_name=result.source_name if getattr(result, "source_name", None) else "",
|
235
|
-
doc=result.doc if getattr(result, "doc", None) else "",
|
218
|
+
doc=html_format(result.doc) if getattr(result, "doc", None) else "",
|
236
219
|
args=list(result.args) if getattr(result, "args", None) else [],
|
237
220
|
assign=list(result.assign) if getattr(result, "assign", None) else [],
|
238
221
|
tags=list(result.tags) if getattr(result, "tags", None) else [],
|
@@ -242,43 +225,29 @@ class Interpreter(BaseInterpreter):
|
|
242
225
|
message=result.message,
|
243
226
|
start_time=result.starttime,
|
244
227
|
end_time=result.endtime,
|
245
|
-
elapsed_time=
|
228
|
+
elapsed_time=(
|
229
|
+
make_elapsed_time_str(result.elapsedtime)
|
230
|
+
if get_robot_version() < (7, 0)
|
231
|
+
else make_elapsed_time_str(result.elapsed_time)
|
232
|
+
),
|
246
233
|
)
|
247
234
|
if self._result_data is not None and isinstance(self._result_data, ResultDataWithChildren):
|
248
235
|
self._result_data.items.append(kw_data)
|
249
236
|
self._result_data_stack.append(self._result_data)
|
250
237
|
self._result_data = kw_data
|
251
238
|
|
252
|
-
if self._html_result is not None:
|
253
|
-
self._result_stack.append(self._html_result)
|
254
|
-
kw = self.create_keyword_html_element(result)
|
255
|
-
|
256
|
-
children = next(
|
257
|
-
(
|
258
|
-
i
|
259
|
-
for i in self._html_result.children
|
260
|
-
if isinstance(i, Element)
|
261
|
-
and i.tag_name == "div"
|
262
|
-
and i.classes is not None
|
263
|
-
and "children" in i.classes
|
264
|
-
),
|
265
|
-
None,
|
266
|
-
)
|
267
|
-
|
268
|
-
if children is None:
|
269
|
-
self._html_result.add_element(kw)
|
270
|
-
else:
|
271
|
-
children.add_element(kw)
|
272
|
-
|
273
|
-
self._html_result = kw
|
274
|
-
|
275
239
|
def end_keyword(self, data: "running.Keyword", result: "result.Keyword") -> None:
|
276
240
|
if data.type in ["IF/ELSE ROOT", "TRY/EXCEPT ROOT"]:
|
277
241
|
return
|
242
|
+
|
278
243
|
if self._result_data is not None:
|
279
244
|
if isinstance(self._result_data, KeywordResultData):
|
280
245
|
self._result_data.end_time = result.endtime
|
281
|
-
self._result_data.elapsed_time =
|
246
|
+
self._result_data.elapsed_time = (
|
247
|
+
make_elapsed_time_str(result.elapsedtime)
|
248
|
+
if get_robot_version() < (7, 0)
|
249
|
+
else make_elapsed_time_str(result.elapsed_time)
|
250
|
+
)
|
282
251
|
self._result_data.status = result.status
|
283
252
|
self._result_data.message = result.message
|
284
253
|
|
@@ -289,69 +258,6 @@ class Interpreter(BaseInterpreter):
|
|
289
258
|
elif result.status == "PASS" and self.last_result is not False:
|
290
259
|
self._success = True
|
291
260
|
|
292
|
-
if self._html_result is not None and isinstance(self._html_result, Element):
|
293
|
-
kw = self.create_keyword_html_element(result)
|
294
|
-
|
295
|
-
old_children = next(
|
296
|
-
(
|
297
|
-
i
|
298
|
-
for i in self._html_result.children
|
299
|
-
if isinstance(i, Element)
|
300
|
-
and i.tag_name == "div"
|
301
|
-
and i.classes is not None
|
302
|
-
and "children" in i.classes
|
303
|
-
),
|
304
|
-
None,
|
305
|
-
)
|
306
|
-
if old_children is not None:
|
307
|
-
new_children = next(
|
308
|
-
(
|
309
|
-
i
|
310
|
-
for i in kw.children
|
311
|
-
if isinstance(i, Element)
|
312
|
-
and i.tag_name == "div"
|
313
|
-
and i.classes is not None
|
314
|
-
and "children" in i.classes
|
315
|
-
),
|
316
|
-
None,
|
317
|
-
)
|
318
|
-
if new_children is None:
|
319
|
-
new_children = Element("div", classes=["children"])
|
320
|
-
self._html_result.add_element(new_children)
|
321
|
-
|
322
|
-
for old_child in old_children.children:
|
323
|
-
if not (
|
324
|
-
isinstance(old_child, Element)
|
325
|
-
and old_child.tag_name == "table"
|
326
|
-
and old_child.classes is not None
|
327
|
-
and "metadata" in old_child.classes
|
328
|
-
):
|
329
|
-
new_children.add_element(old_child)
|
330
|
-
|
331
|
-
self._html_result.children = kw.children
|
332
|
-
|
333
|
-
self._html_result = self._result_stack.pop()
|
334
|
-
|
335
|
-
def create_keyword_html_element(self, result: "result.Keyword") -> Element:
|
336
|
-
return create_keyword_html(
|
337
|
-
id=result.id,
|
338
|
-
name=result.name if getattr(result, "name", None) else None,
|
339
|
-
owner=result.owner if getattr(result, "owner", None) else None,
|
340
|
-
source_name=result.source_name if getattr(result, "source_name", None) else None,
|
341
|
-
doc=result.doc if getattr(result, "doc", None) else None,
|
342
|
-
args=result.args if getattr(result, "args", None) else (),
|
343
|
-
assign=result.assign if getattr(result, "assign", None) else (),
|
344
|
-
tags=result.tags if getattr(result, "tags", None) else (),
|
345
|
-
timeout=result.timeout if getattr(result, "timeout", None) else None,
|
346
|
-
type=result.type,
|
347
|
-
status=result.status,
|
348
|
-
message=result.message,
|
349
|
-
start_time=result.starttime,
|
350
|
-
end_time=result.endtime,
|
351
|
-
elapsed_time=result.elapsedtime,
|
352
|
-
shadow_root_id=self._shadow_marker,
|
353
|
-
)
|
354
|
-
|
355
261
|
def run_input(self) -> None:
|
356
262
|
self.has_input.wait()
|
357
263
|
if self._has_shutdown:
|
@@ -1 +0,0 @@
|
|
1
|
-
__version__ = "0.100.2"
|
@@ -1,324 +0,0 @@
|
|
1
|
-
from contextlib import contextmanager
|
2
|
-
from datetime import datetime, timedelta
|
3
|
-
from typing import Any, Dict, Generator, List, Optional, Sequence, TypeVar, Union
|
4
|
-
|
5
|
-
from robot.utils.robottime import elapsed_time_to_string
|
6
|
-
|
7
|
-
from robotcode.repl.base_interpreter import is_true
|
8
|
-
from robotcode.robot.utils import get_robot_version
|
9
|
-
|
10
|
-
|
11
|
-
class ElementDataBase:
|
12
|
-
def as_str(self, indent: int = 0) -> str:
|
13
|
-
raise NotImplementedError
|
14
|
-
|
15
|
-
def __str__(self) -> str:
|
16
|
-
return self.as_str(0)
|
17
|
-
|
18
|
-
|
19
|
-
_T = TypeVar("_T", bound=ElementDataBase)
|
20
|
-
|
21
|
-
|
22
|
-
class TextElement(ElementDataBase):
|
23
|
-
def __init__(self, text: str) -> None:
|
24
|
-
self.text = text
|
25
|
-
|
26
|
-
def as_str(self, indent: int = 0) -> str:
|
27
|
-
return f"{' '*indent}{self.text}"
|
28
|
-
|
29
|
-
|
30
|
-
class RawElement(ElementDataBase):
|
31
|
-
def __init__(self, text: str) -> None:
|
32
|
-
self.text = text
|
33
|
-
|
34
|
-
def as_str(self, indent: int = 0) -> str:
|
35
|
-
return f"{' '*indent}{self.text}"
|
36
|
-
|
37
|
-
|
38
|
-
class Element(ElementDataBase):
|
39
|
-
def __init__(
|
40
|
-
self,
|
41
|
-
tag_name: str,
|
42
|
-
text: Optional[str] = None,
|
43
|
-
classes: Optional[List[str]] = None,
|
44
|
-
styles: Optional[Dict[str, str]] = None,
|
45
|
-
attributes: Optional[Dict[str, str]] = None,
|
46
|
-
**kwargs: Any,
|
47
|
-
) -> None:
|
48
|
-
self.tag_name = tag_name
|
49
|
-
self.classes = classes
|
50
|
-
self.styles = styles
|
51
|
-
if attributes is None:
|
52
|
-
attributes = {}
|
53
|
-
attributes.update(kwargs)
|
54
|
-
self.attributes = attributes
|
55
|
-
self.children: List[ElementDataBase] = []
|
56
|
-
|
57
|
-
if text is not None:
|
58
|
-
self.add_element(TextElement(text))
|
59
|
-
|
60
|
-
def add_element(self, child: _T) -> _T:
|
61
|
-
self.children.append(child)
|
62
|
-
return child
|
63
|
-
|
64
|
-
@contextmanager
|
65
|
-
def tag(
|
66
|
-
self,
|
67
|
-
tag_name: str,
|
68
|
-
*,
|
69
|
-
text: Optional[str] = None,
|
70
|
-
classes: Optional[List[str]] = None,
|
71
|
-
styles: Optional[Dict[str, str]] = None,
|
72
|
-
attributes: Optional[Dict[str, str]] = None,
|
73
|
-
**kwargs: Any,
|
74
|
-
) -> Generator["Element", None, None]:
|
75
|
-
element = Element(tag_name, text=text, classes=classes, styles=styles, attributes=attributes, **kwargs)
|
76
|
-
|
77
|
-
yield element
|
78
|
-
|
79
|
-
self.add_element(element)
|
80
|
-
|
81
|
-
def add_raw(self, text: Any) -> None:
|
82
|
-
self.add_element(RawElement(str(text)))
|
83
|
-
|
84
|
-
def add_text(self, text: Any) -> None:
|
85
|
-
self.add_element(TextElement(str(text)))
|
86
|
-
|
87
|
-
def _build_attributes(self) -> str:
|
88
|
-
result = []
|
89
|
-
if self.classes:
|
90
|
-
result.append(f'class="{" ".join(s for s in self.classes if s)}"')
|
91
|
-
if self.styles:
|
92
|
-
result.append(f'style="{"; ".join(f"{k}: {v}" for k, v in self.styles.items() if v)}"')
|
93
|
-
if self.attributes:
|
94
|
-
result.extend(f'{k}="{v}"' for k, v in self.attributes.items())
|
95
|
-
|
96
|
-
return " ".join(result)
|
97
|
-
|
98
|
-
NON_BREAKABLE_TAGS = {"span", "a", "b", "i", "u", "strong", "em", "code", "pre", "tt", "samp", "kbd", "var", "td"}
|
99
|
-
|
100
|
-
def as_str(self, indent: int = 0, *, only_children: bool = False) -> str:
|
101
|
-
if not only_children:
|
102
|
-
attributes = self._build_attributes()
|
103
|
-
|
104
|
-
if attributes:
|
105
|
-
start_tag = f"<{self.tag_name} {attributes}>"
|
106
|
-
else:
|
107
|
-
start_tag = f"<{self.tag_name}>"
|
108
|
-
|
109
|
-
end_tag = f"</{self.tag_name}>"
|
110
|
-
|
111
|
-
result = " " * indent + start_tag
|
112
|
-
else:
|
113
|
-
result = ""
|
114
|
-
end_tag = None
|
115
|
-
|
116
|
-
if self.children:
|
117
|
-
result += "\n" if self.tag_name not in self.NON_BREAKABLE_TAGS else ""
|
118
|
-
for child in self.children:
|
119
|
-
result += child.as_str((indent + 1) if self.tag_name not in self.NON_BREAKABLE_TAGS else 0) + (
|
120
|
-
"\n" if self.tag_name not in self.NON_BREAKABLE_TAGS else ""
|
121
|
-
)
|
122
|
-
result += (" " * indent) if self.tag_name not in self.NON_BREAKABLE_TAGS else ""
|
123
|
-
|
124
|
-
if end_tag:
|
125
|
-
result += end_tag
|
126
|
-
|
127
|
-
return result
|
128
|
-
|
129
|
-
|
130
|
-
def create_keyword_html(
|
131
|
-
id: Optional[str] = None,
|
132
|
-
name: Optional[str] = "",
|
133
|
-
owner: Optional[str] = None,
|
134
|
-
source_name: Optional[str] = None,
|
135
|
-
doc: Optional[str] = "",
|
136
|
-
args: Sequence[str] = (),
|
137
|
-
assign: Sequence[str] = (),
|
138
|
-
tags: Sequence[str] = (),
|
139
|
-
timeout: Optional[str] = None,
|
140
|
-
type: str = "KEYWORD",
|
141
|
-
status: str = "FAIL",
|
142
|
-
message: str = "",
|
143
|
-
start_time: Union[datetime, str, None] = None,
|
144
|
-
end_time: Union[datetime, str, None] = None,
|
145
|
-
elapsed_time: Union[timedelta, int, float, None] = None,
|
146
|
-
shadow_root_id: Optional[str] = None,
|
147
|
-
) -> Element:
|
148
|
-
result = Element("div", classes=["keyword"], id=id)
|
149
|
-
|
150
|
-
elapsed_time_str = (
|
151
|
-
(
|
152
|
-
elapsed_time_to_string(elapsed_time)
|
153
|
-
if get_robot_version() < (7, 0)
|
154
|
-
else elapsed_time_to_string(elapsed_time, seconds=True)
|
155
|
-
)
|
156
|
-
if elapsed_time is not None
|
157
|
-
else ""
|
158
|
-
)
|
159
|
-
|
160
|
-
with result.tag(
|
161
|
-
"div",
|
162
|
-
classes=["element-header", "closed" if status not in ["FAIL"] else ""],
|
163
|
-
onclick=f"toggleKeyword('{id}', '{shadow_root_id}')",
|
164
|
-
) as e_element_header:
|
165
|
-
with e_element_header.tag(
|
166
|
-
"div",
|
167
|
-
classes=["element-header-left"],
|
168
|
-
title=f"{type.upper()} {owner}.{name} [{status}]",
|
169
|
-
) as e_header_left:
|
170
|
-
if elapsed_time is not None:
|
171
|
-
with e_header_left.tag("span", classes=["elapsed"]) as e_elapsed:
|
172
|
-
e_elapsed.add_text(elapsed_time_str)
|
173
|
-
with e_header_left.tag("span", classes=["label", status.lower()]) as e_label:
|
174
|
-
e_label.add_text(str(type).upper())
|
175
|
-
with e_header_left.tag("span", classes=["assign"]) as e_assign:
|
176
|
-
e_assign.add_text(" ".join(assign))
|
177
|
-
with e_header_left.tag("span", classes=["name"]) as e_name:
|
178
|
-
with e_name.tag("span", classes=["parent-name"]) as parent_name:
|
179
|
-
parent_name.add_text((owner + " . ") if owner else "")
|
180
|
-
e_name.add_text(name)
|
181
|
-
e_header_left.add_raw(" ")
|
182
|
-
with e_header_left.tag("span", classes=["arg"]) as args_tag:
|
183
|
-
args_tag.add_text(" ".join(args))
|
184
|
-
with e_element_header.tag("div", classes=["element-header-right"]) as e_header_right:
|
185
|
-
with e_header_right.tag(
|
186
|
-
"div",
|
187
|
-
classes=["expand"],
|
188
|
-
title="Expand all",
|
189
|
-
onclick=f"expandAll(event, '{id}', '{shadow_root_id}')",
|
190
|
-
):
|
191
|
-
pass
|
192
|
-
with e_header_right.tag(
|
193
|
-
"div",
|
194
|
-
classes=["collapse"],
|
195
|
-
title="Collapse all",
|
196
|
-
onclick=f"collapseAll(event, '{id}', '{shadow_root_id}')",
|
197
|
-
):
|
198
|
-
pass
|
199
|
-
with e_header_right.tag(
|
200
|
-
"div",
|
201
|
-
classes=["link"],
|
202
|
-
title="Highlight this item",
|
203
|
-
onclick=f"makeElementVisible(event, '{id}', '{shadow_root_id}')",
|
204
|
-
):
|
205
|
-
pass
|
206
|
-
with e_element_header.tag("div", classes=["element-header-toggle"], title="Toggle visibility"):
|
207
|
-
pass
|
208
|
-
|
209
|
-
with result.tag(
|
210
|
-
"div", classes=["children", "populated"], styles={"display": "none" if status not in ["FAIL"] else "block"}
|
211
|
-
) as e_children:
|
212
|
-
with e_children.tag("table", classes=["metadata", "keyword-metadata"]) as e_body:
|
213
|
-
if doc:
|
214
|
-
with e_body.tag("tr") as tr:
|
215
|
-
with tr.tag("th", text="Documentation:"):
|
216
|
-
pass
|
217
|
-
with tr.tag("td", classes=["doc"]) as td:
|
218
|
-
td.add_text(doc)
|
219
|
-
if tags:
|
220
|
-
with e_body.tag("tr") as tr:
|
221
|
-
with tr.tag("th", text="Tags:"):
|
222
|
-
pass
|
223
|
-
with tr.tag("td", classes=["tags"]) as td:
|
224
|
-
td.add_text(", ".join(tags))
|
225
|
-
if timeout:
|
226
|
-
with e_body.tag("tr") as tr:
|
227
|
-
with tr.tag("th", text="Timeout:"):
|
228
|
-
pass
|
229
|
-
with tr.tag("td", classes=["timeout"]) as td:
|
230
|
-
td.add_text(timeout)
|
231
|
-
if source_name:
|
232
|
-
with e_body.tag("tr") as tr:
|
233
|
-
with tr.tag("th", text="Source:"):
|
234
|
-
pass
|
235
|
-
with tr.tag("td", classes=["source"]) as td:
|
236
|
-
td.add_text(source_name)
|
237
|
-
with e_body.tag("tr") as tr:
|
238
|
-
with tr.tag("th", text="Start / End / Elapsed:"):
|
239
|
-
pass
|
240
|
-
with tr.tag("td", classes=["message"]) as td:
|
241
|
-
td.add_text(str(start_time) + " / " + str(end_time) + " / " + elapsed_time_str)
|
242
|
-
if message:
|
243
|
-
with e_body.tag("tr") as tr:
|
244
|
-
with tr.tag("th", text="Message:"):
|
245
|
-
pass
|
246
|
-
with tr.tag("td", classes=["message"]) as td:
|
247
|
-
td.add_text(message)
|
248
|
-
|
249
|
-
return result
|
250
|
-
|
251
|
-
|
252
|
-
def create_message_html(
|
253
|
-
id: str,
|
254
|
-
message: str,
|
255
|
-
level: str,
|
256
|
-
html: Union[str, bool] = False,
|
257
|
-
timestamp: Union[datetime, str, None] = None,
|
258
|
-
shadow_root_id: Optional[str] = None,
|
259
|
-
) -> Element:
|
260
|
-
result = Element("table", classes=["messages", f"{level.lower()}-message"], id=id)
|
261
|
-
|
262
|
-
with result.tag("tr", classes=["message-row"]) as tr:
|
263
|
-
with tr.tag("td", classes=["time"]) as td:
|
264
|
-
if isinstance(timestamp, datetime):
|
265
|
-
td.add_text(timestamp.strftime("%H:%M:%S"))
|
266
|
-
else:
|
267
|
-
td.add_text(timestamp)
|
268
|
-
with tr.tag("td", classes=["level", level.lower()]) as td:
|
269
|
-
with td.tag("span", classes=["label", level.lower()]) as sp:
|
270
|
-
sp.add_text(level.upper())
|
271
|
-
with tr.tag("td", classes=["message"]) as td:
|
272
|
-
if is_true(html):
|
273
|
-
td.add_raw(message)
|
274
|
-
else:
|
275
|
-
td.add_text(message)
|
276
|
-
with tr.tag(
|
277
|
-
"td",
|
278
|
-
classes=["select-message"],
|
279
|
-
onclick=f"selectMessage('{id}', '{shadow_root_id}')",
|
280
|
-
title="Select message text",
|
281
|
-
) as td:
|
282
|
-
with td.tag("div"):
|
283
|
-
pass
|
284
|
-
|
285
|
-
return result
|
286
|
-
|
287
|
-
|
288
|
-
if __name__ == "__main__":
|
289
|
-
# div = Element("div", id="main", classes=["test", "test2"], styles={"color": "red", "font-size": "12px"})
|
290
|
-
# p = div.add_element(Element("p", text="Hello, world!"))
|
291
|
-
# p.add_element(Element("span", text="This is a test"))
|
292
|
-
# print(div)
|
293
|
-
|
294
|
-
# body = Element("body")
|
295
|
-
# with body.tag("div", id="main", classes=["test", "test2"], styles={"color": "red"}) as div:
|
296
|
-
# with div.tag("p") as p:
|
297
|
-
# p.add_text("Hello, world!")
|
298
|
-
# with p.tag("span") as span:
|
299
|
-
# span.add_text("This is a test")
|
300
|
-
# with span.tag("br"):
|
301
|
-
# pass
|
302
|
-
# span.add_text("This is a test")
|
303
|
-
# with span.tag("br", id="test"):
|
304
|
-
# pass
|
305
|
-
# print(body)
|
306
|
-
|
307
|
-
# r = create_keyword_html(
|
308
|
-
# id="ts-1-2-3-4-5-6",
|
309
|
-
# name="Test Keyword",
|
310
|
-
# owner="Test Library",
|
311
|
-
# doc="This is a test keyword",
|
312
|
-
# args=("arg1", "arg2"),
|
313
|
-
# assign=("${var1}", "${var2}"),
|
314
|
-
# tags=("tag1", "tag2"),
|
315
|
-
# timeout="10s",
|
316
|
-
# type="KEYWORD",
|
317
|
-
# status="PASS",
|
318
|
-
# message="This is a test message",
|
319
|
-
# start_time=datetime.now(timezone.utc),
|
320
|
-
# end_time=datetime.now(timezone.utc),
|
321
|
-
# elapsed_time=timedelta(seconds=5),
|
322
|
-
# )
|
323
|
-
r = create_message_html("ts-1-2-3-4-5-6", "This is a test message", "INFO", timestamp="2021-10-10 12:00:00")
|
324
|
-
print(r)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/cli.py
RENAMED
File without changes
|
{robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/hooks.py
RENAMED
File without changes
|
File without changes
|
{robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/py.typed
RENAMED
File without changes
|
{robotcode_repl_server-0.100.2 → robotcode_repl_server-0.102.0}/src/robotcode/repl_server/server.py
RENAMED
File without changes
|