pytest-dsl 0.3.1__py3-none-any.whl → 0.5.0__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.
@@ -1,4 +1,10 @@
1
1
  import allure
2
+ import time
3
+ import random
4
+ import string
5
+ import subprocess
6
+ import datetime
7
+ import logging
2
8
  from pytest_dsl.core.keyword_manager import keyword_manager
3
9
 
4
10
 
@@ -15,3 +21,323 @@ def print_content(**kwargs):
15
21
  ])
16
22
  def return_result(**kwargs):
17
23
  return kwargs.get('result')
24
+
25
+
26
+ @keyword_manager.register('等待', [
27
+ {'name': '秒数', 'mapping': 'seconds', 'description': '等待的秒数,可以是小数'}
28
+ ])
29
+ def wait_seconds(**kwargs):
30
+ """等待指定的秒数
31
+
32
+ Args:
33
+ seconds: 等待的秒数,可以是小数表示毫秒级等待
34
+ """
35
+ seconds = float(kwargs.get('seconds', 0))
36
+ with allure.step(f"等待 {seconds} 秒"):
37
+ time.sleep(seconds)
38
+ return True
39
+
40
+
41
+ @keyword_manager.register('获取当前时间', [
42
+ {'name': '格式', 'mapping': 'format', 'description': '时间格式,例如 "%Y-%m-%d %H:%M:%S",默认返回时间戳'},
43
+ {'name': '时区', 'mapping': 'timezone', 'description': '时区,例如 "Asia/Shanghai",默认为本地时区'}
44
+ ])
45
+ def get_current_time(**kwargs):
46
+ """获取当前时间
47
+
48
+ Args:
49
+ format: 时间格式,如果不提供则返回时间戳
50
+ timezone: 时区,默认为本地时区
51
+
52
+ Returns:
53
+ str: 格式化的时间字符串或时间戳
54
+ """
55
+ time_format = kwargs.get('format')
56
+ timezone = kwargs.get('timezone')
57
+
58
+ # 获取当前时间
59
+ if timezone:
60
+ import pytz
61
+ try:
62
+ tz = pytz.timezone(timezone)
63
+ current_time = datetime.datetime.now(tz)
64
+ except Exception as e:
65
+ allure.attach(
66
+ f"时区设置异常: {str(e)}",
67
+ name="时区设置异常",
68
+ attachment_type=allure.attachment_type.TEXT
69
+ )
70
+ current_time = datetime.datetime.now()
71
+ else:
72
+ current_time = datetime.datetime.now()
73
+
74
+ # 格式化时间
75
+ if time_format:
76
+ try:
77
+ result = current_time.strftime(time_format)
78
+ except Exception as e:
79
+ allure.attach(
80
+ f"时间格式化异常: {str(e)}",
81
+ name="时间格式化异常",
82
+ attachment_type=allure.attachment_type.TEXT
83
+ )
84
+ result = str(current_time)
85
+ else:
86
+ # 返回时间戳
87
+ result = str(int(current_time.timestamp()))
88
+
89
+ return result
90
+
91
+
92
+ @keyword_manager.register('生成随机字符串', [
93
+ {'name': '长度', 'mapping': 'length', 'description': '随机字符串的长度,默认为8'},
94
+ {'name': '类型', 'mapping': 'type',
95
+ 'description': '字符类型:字母(letters)、数字(digits)、字母数字(alphanumeric)、全部(all),默认为字母数字'}
96
+ ])
97
+ def generate_random_string(**kwargs):
98
+ """生成随机字符串
99
+
100
+ Args:
101
+ length: 随机字符串的长度
102
+ type: 字符类型:字母、数字、字母数字、全部
103
+
104
+ Returns:
105
+ str: 生成的随机字符串
106
+ """
107
+ length = int(kwargs.get('length', 8))
108
+ char_type = kwargs.get('type', 'alphanumeric').lower()
109
+
110
+ # 根据类型选择字符集
111
+ if char_type == 'letters':
112
+ chars = string.ascii_letters
113
+ elif char_type == 'digits':
114
+ chars = string.digits
115
+ elif char_type == 'alphanumeric':
116
+ chars = string.ascii_letters + string.digits
117
+ elif char_type == 'all':
118
+ chars = string.ascii_letters + string.digits + string.punctuation
119
+ else:
120
+ # 默认使用字母数字
121
+ chars = string.ascii_letters + string.digits
122
+
123
+ # 生成随机字符串
124
+ result = ''.join(random.choice(chars) for _ in range(length))
125
+
126
+ with allure.step(f"生成随机字符串: 长度={length}, 类型={char_type}"):
127
+ allure.attach(
128
+ f"生成的随机字符串: {result}",
129
+ name="随机字符串",
130
+ attachment_type=allure.attachment_type.TEXT
131
+ )
132
+
133
+ return result
134
+
135
+
136
+ @keyword_manager.register('生成随机数', [
137
+ {'name': '最小值', 'mapping': 'min', 'description': '随机数的最小值,默认为0'},
138
+ {'name': '最大值', 'mapping': 'max', 'description': '随机数的最大值,默认为100'},
139
+ {'name': '小数位数', 'mapping': 'decimals', 'description': '小数位数,默认为0(整数)'}
140
+ ])
141
+ def generate_random_number(**kwargs):
142
+ """生成随机数
143
+
144
+ Args:
145
+ min: 随机数的最小值
146
+ max: 随机数的最大值
147
+ decimals: 小数位数,0表示整数
148
+
149
+ Returns:
150
+ int/float: 生成的随机数
151
+ """
152
+ min_value = float(kwargs.get('min', 0))
153
+ max_value = float(kwargs.get('max', 100))
154
+ decimals = int(kwargs.get('decimals', 0))
155
+
156
+ if decimals <= 0:
157
+ # 生成整数
158
+ result = random.randint(int(min_value), int(max_value))
159
+ else:
160
+ # 生成浮点数
161
+ result = round(random.uniform(min_value, max_value), decimals)
162
+
163
+ with allure.step(f"生成随机数: 范围=[{min_value}, {max_value}], 小数位数={decimals}"):
164
+ allure.attach(
165
+ f"生成的随机数: {result}",
166
+ name="随机数",
167
+ attachment_type=allure.attachment_type.TEXT
168
+ )
169
+
170
+ return result
171
+
172
+
173
+ @keyword_manager.register('字符串操作', [
174
+ {'name': '操作', 'mapping': 'operation',
175
+ 'description': '操作类型:拼接(concat)、替换(replace)、分割(split)、大写(upper)、小写(lower)、去空格(strip)'},
176
+ {'name': '字符串', 'mapping': 'string', 'description': '要操作的字符串'},
177
+ {'name': '参数1', 'mapping': 'param1', 'description': '操作参数1,根据操作类型不同而不同'},
178
+ {'name': '参数2', 'mapping': 'param2', 'description': '操作参数2,根据操作类型不同而不同'}
179
+ ])
180
+ def string_operation(**kwargs):
181
+ """字符串操作
182
+
183
+ Args:
184
+ operation: 操作类型
185
+ string: 要操作的字符串
186
+ param1: 操作参数1
187
+ param2: 操作参数2
188
+
189
+ Returns:
190
+ str: 操作结果
191
+ """
192
+ operation = kwargs.get('operation', '').lower()
193
+ string = str(kwargs.get('string', ''))
194
+ param1 = kwargs.get('param1', '')
195
+ param2 = kwargs.get('param2', '')
196
+
197
+ result = string
198
+
199
+ if operation == 'concat':
200
+ # 拼接字符串
201
+ result = string + str(param1)
202
+ elif operation == 'replace':
203
+ # 替换字符串
204
+ result = string.replace(str(param1), str(param2))
205
+ elif operation == 'split':
206
+ # 分割字符串
207
+ result = string.split(str(param1))
208
+ if param2 and param2.isdigit():
209
+ # 如果提供了索引,返回指定位置的元素
210
+ index = int(param2)
211
+ if 0 <= index < len(result):
212
+ result = result[index]
213
+ elif operation == 'upper':
214
+ # 转大写
215
+ result = string.upper()
216
+ elif operation == 'lower':
217
+ # 转小写
218
+ result = string.lower()
219
+ elif operation == 'strip':
220
+ # 去空格
221
+ result = string.strip()
222
+ else:
223
+ # 未知操作,返回原字符串
224
+ allure.attach(
225
+ f"未知的字符串操作: {operation}",
226
+ name="字符串操作错误",
227
+ attachment_type=allure.attachment_type.TEXT
228
+ )
229
+
230
+ with allure.step(f"字符串操作: {operation}"):
231
+ allure.attach(
232
+ f"原字符串: {string}\n操作: {operation}\n参数1: {param1}\n参数2: {param2}\n结果: {result}",
233
+ name="字符串操作结果",
234
+ attachment_type=allure.attachment_type.TEXT
235
+ )
236
+
237
+ return result
238
+
239
+
240
+ @keyword_manager.register('日志', [
241
+ {'name': '级别', 'mapping': 'level',
242
+ 'description': '日志级别:DEBUG, INFO, WARNING, ERROR, CRITICAL,默认为INFO'},
243
+ {'name': '消息', 'mapping': 'message', 'description': '日志消息内容'}
244
+ ])
245
+ def log_message(**kwargs):
246
+ """记录日志
247
+
248
+ Args:
249
+ level: 日志级别
250
+ message: 日志消息内容
251
+ """
252
+ level = kwargs.get('level', 'INFO').upper()
253
+ message = kwargs.get('message', '')
254
+
255
+ # 获取日志级别
256
+ log_level = getattr(logging, level, logging.INFO)
257
+
258
+ # 记录日志
259
+ logging.log(log_level, message)
260
+
261
+ with allure.step(f"记录日志: [{level}] {message}"):
262
+ allure.attach(
263
+ f"日志级别: {level}\n日志消息: {message}",
264
+ name="日志记录",
265
+ attachment_type=allure.attachment_type.TEXT
266
+ )
267
+
268
+ return True
269
+
270
+
271
+ @keyword_manager.register('执行命令', [
272
+ {'name': '命令', 'mapping': 'command', 'description': '要执行的系统命令'},
273
+ {'name': '超时', 'mapping': 'timeout', 'description': '命令执行超时时间(秒),默认为60秒'},
274
+ {'name': '捕获输出', 'mapping': 'capture_output', 'description': '是否捕获命令输出,默认为True'}
275
+ ])
276
+ def execute_command(**kwargs):
277
+ """执行系统命令
278
+
279
+ Args:
280
+ command: 要执行的系统命令
281
+ timeout: 命令执行超时时间(秒)
282
+ capture_output: 是否捕获命令输出
283
+
284
+ Returns:
285
+ dict: 包含返回码、标准输出和标准错误的字典
286
+ """
287
+ command = kwargs.get('command', '')
288
+ timeout = float(kwargs.get('timeout', 60))
289
+ capture_output = kwargs.get('capture_output', True)
290
+
291
+ with allure.step(f"执行命令: {command}"):
292
+ try:
293
+ # 执行命令
294
+ result = subprocess.run(
295
+ command,
296
+ shell=True,
297
+ timeout=timeout,
298
+ capture_output=capture_output,
299
+ text=True
300
+ )
301
+
302
+ # 构建结果字典
303
+ command_result = {
304
+ 'returncode': result.returncode,
305
+ 'stdout': result.stdout if capture_output else '',
306
+ 'stderr': result.stderr if capture_output else ''
307
+ }
308
+
309
+ # 记录执行结果
310
+ allure.attach(
311
+ f"命令: {command}\n返回码: {result.returncode}\n"
312
+ f"标准输出: {result.stdout if capture_output else '未捕获'}\n"
313
+ f"标准错误: {result.stderr if capture_output else '未捕获'}",
314
+ name="命令执行结果",
315
+ attachment_type=allure.attachment_type.TEXT
316
+ )
317
+
318
+ return command_result
319
+
320
+ except subprocess.TimeoutExpired:
321
+ # 命令执行超时
322
+ allure.attach(
323
+ f"命令执行超时: {command} (超时: {timeout}秒)",
324
+ name="命令执行超时",
325
+ attachment_type=allure.attachment_type.TEXT
326
+ )
327
+ return {
328
+ 'returncode': -1,
329
+ 'stdout': '',
330
+ 'stderr': f'Command timed out after {timeout} seconds'
331
+ }
332
+ except Exception as e:
333
+ # 其他异常
334
+ allure.attach(
335
+ f"命令执行异常: {str(e)}",
336
+ name="命令执行异常",
337
+ attachment_type=allure.attachment_type.TEXT
338
+ )
339
+ return {
340
+ 'returncode': -1,
341
+ 'stdout': '',
342
+ 'stderr': str(e)
343
+ }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytest-dsl
3
- Version: 0.3.1
3
+ Version: 0.5.0
4
4
  Summary: A DSL testing framework based on pytest
5
5
  Author: Chen Shuanglin
6
6
  License: MIT
@@ -8,13 +8,13 @@ Project-URL: Homepage, https://github.com/felix-1991/pytest-dsl
8
8
  Project-URL: Bug Tracker, https://github.com/felix-1991/pytest-dsl/issues
9
9
  Classifier: Framework :: Pytest
10
10
  Classifier: Programming Language :: Python :: 3
11
- Classifier: Programming Language :: Python :: 3.8
12
11
  Classifier: Programming Language :: Python :: 3.9
13
12
  Classifier: Programming Language :: Python :: 3.10
14
13
  Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
15
  Classifier: License :: OSI Approved :: MIT License
16
16
  Classifier: Operating System :: OS Independent
17
- Requires-Python: >=3.8
17
+ Requires-Python: >=3.9
18
18
  Description-Content-Type: text/markdown
19
19
  License-File: LICENSE
20
20
  Requires-Dist: pytest>=7.0.0
@@ -26,6 +26,7 @@ Requires-Dist: jsonpath-ng>=1.5.0
26
26
  Requires-Dist: requests>=2.28.0
27
27
  Requires-Dist: lxml>=4.9.0
28
28
  Requires-Dist: jsonschema>=4.17.0
29
+ Requires-Dist: pytz>=2023.3
29
30
  Dynamic: license-file
30
31
 
31
32
  # pytest-dsl: 强大的关键字驱动测试自动化框架
@@ -149,11 +150,11 @@ pytest-dsl允许在DSL文件中直接定义自定义关键字,类似于编程
149
150
  @keyword 拼接字符串 (前缀, 后缀="默认后缀") do
150
151
  # 直接使用关键字参数
151
152
  [打印],内容: "拼接前缀: ${前缀} 和后缀: ${后缀}"
152
-
153
+
153
154
  # 保存到变量中
154
155
  结果变量 = "${前缀}${后缀}"
155
156
  [打印],内容: "拼接结果: ${结果变量}"
156
-
157
+
157
158
  # 返回结果
158
159
  return ${结果变量}
159
160
  end
@@ -188,11 +189,11 @@ end
188
189
  @keyword 拼接字符串 (前缀, 后缀="我是默认值哦") do
189
190
  # 直接使用关键字参数
190
191
  [打印],内容:'拼接前缀: ${前缀} 和后缀: ${后缀}'
191
-
192
+
192
193
  # 保存到变量中
193
194
  结果变量 = "${前缀}${后缀}"
194
195
  [打印],内容:'拼接结果: ${结果变量}'
195
-
196
+
196
197
  # 返回结果
197
198
  return ${结果变量}
198
199
  end
@@ -311,7 +312,7 @@ from pytest_dsl.core.auto_decorator import auto_dsl
311
312
  @auto_dsl("./api_tests") # 加载指定目录下所有的.auto或.dsl文件
312
313
  class TestAPI:
313
314
  """API测试类
314
-
315
+
315
316
  该类将自动加载api_tests目录下的所有DSL文件作为测试方法
316
317
  """
317
318
  pass
@@ -330,6 +331,31 @@ pytest test_api.py
330
331
  pytest -v --alluredir=./reports
331
332
  ```
332
333
 
334
+ ### 使用Allure生成和查看报告
335
+
336
+ pytest-dsl已与Allure报告框架集成,可以生成美观、交互式的测试报告。
337
+
338
+ ```bash
339
+ # 运行测试并生成Allure报告数据
340
+ pytest --alluredir=./allure-results
341
+
342
+ # 生成HTML报告并启动本地服务器查看
343
+ allure serve ./allure-results
344
+
345
+ # 或生成HTML报告到指定目录
346
+ allure generate ./allure-results -o ./allure-report
347
+ # 然后可以打开 ./allure-report/index.html 查看报告
348
+ ```
349
+
350
+ Allure报告会自动包含以下信息:
351
+ - 测试步骤和执行状态
352
+ - HTTP请求和响应详情
353
+ - 断言结果和失败原因
354
+ - 测试执行时间和性能数据
355
+ - 测试标签和分类信息
356
+
357
+ 通过Allure报告,您可以更直观地分析测试结果,快速定位问题。
358
+
333
359
  ## 更多功能
334
360
 
335
361
  ### 断言重试功能
@@ -386,7 +412,7 @@ def call_microservice(**kwargs):
386
412
  method = kwargs.get('method_name')
387
413
  params = kwargs.get('params', {})
388
414
  context = kwargs.get('context')
389
-
415
+
390
416
  # 实现微服务调用逻辑
391
417
  result = your_microservice_client.call(service, method, params)
392
418
  return result
@@ -427,13 +453,135 @@ def call_microservice(**kwargs):
427
453
  - **完整测试生命周期**:内置teardown、变量管理和断言机制
428
454
  - **非侵入式设计**:以"旁路模式"扩展现有pytest项目,不影响原有测试代码
429
455
 
456
+ ## 远程关键字功能
457
+
458
+ pytest-dsl支持远程关键字调用,允许您在不同的机器或服务上执行关键字,实现分布式测试。
459
+
460
+ ### 启动远程关键字服务
461
+
462
+ 安装pytest-dsl后,可以使用内置命令启动远程关键字服务:
463
+
464
+ ```bash
465
+ # 使用默认配置启动(localhost:8270)
466
+ pytest-dsl-server
467
+
468
+ # 自定义主机和端口
469
+ pytest-dsl-server --host 0.0.0.0 --port 8888
470
+
471
+ # 使用API密钥保护服务
472
+ pytest-dsl-server --api-key your_secret_key
473
+ ```
474
+
475
+ #### 分布式测试环境配置
476
+
477
+ 在分布式测试环境中,您可以在多台机器上启动远程关键字服务:
478
+
479
+ 1. **主测试机**:运行测试脚本的机器
480
+ 2. **远程执行机**:运行远程关键字服务的机器
481
+
482
+ 配置步骤:
483
+
484
+ 1. 在每台远程执行机上安装pytest-dsl:
485
+ ```bash
486
+ pip install pytest-dsl
487
+ ```
488
+
489
+ 2. 在每台远程执行机上启动远程关键字服务:
490
+ ```bash
491
+ # 确保监听所有网络接口,以便外部可访问
492
+ pytest-dsl-server --host 0.0.0.0 --port 8270
493
+ ```
494
+
495
+ 3. 在主测试机上编写测试脚本,使用`@remote`指令连接到远程服务:
496
+ ```python
497
+ # 连接到多台远程执行机
498
+ @remote: "http://machine1-ip:8270/" as machine1
499
+ @remote: "http://machine2-ip:8270/" as machine2
500
+
501
+ # 在不同机器上执行关键字
502
+ machine1|[打印],内容: "在机器1上执行"
503
+ machine2|[打印],内容: "在机器2上执行"
504
+ ```
505
+
506
+ ### 远程关键字语法
507
+
508
+ ```python
509
+ # 导入远程关键字服务器
510
+ @remote: "http://keyword-server:8270/" as machineone
511
+ @remote: "http://keyword-server2:8270/" as machinetwo
512
+
513
+ # 远程关键字调用
514
+ machineone|[打印],内容: "这是通过远程服务器执行的关键字"
515
+ 结果 = machineone|[拼接字符串],前缀: "Hello, ",后缀: "Remote World!"
516
+ ```
517
+
518
+ ### 远程关键字测试示例
519
+
520
+ ```python
521
+ @name: "远程关键字测试"
522
+ @description: "测试远程关键字的基本功能"
523
+ @tags: ["remote", "keywords"]
524
+ @author: "Felix"
525
+ @date: 2024-05-21
526
+
527
+ # 导入远程关键字服务器
528
+ @remote: "http://localhost:8270/" as machineone
529
+
530
+ # 基本打印测试
531
+ machineone|[打印],内容: "这是通过远程服务器执行的关键字"
532
+
533
+ # 随机数生成测试
534
+ 随机数 = [生成随机数],最小值: 1,最大值: 100
535
+ machineone|[打印],内容: "远程生成的随机数: ${随机数}"
536
+ ```
537
+
538
+ > **注意**:当前远程关键字模式在HTTP请求关键字上支持的不是太好,后续会优化关键字实现,提升远程关键字的功能和稳定性。
539
+
540
+ ### 远程关键字服务安全性
541
+
542
+ 在生产环境中使用远程关键字服务时,请注意以下安全建议:
543
+
544
+ 1. **使用API密钥认证**:
545
+ ```bash
546
+ pytest-dsl-server --api-key your_secure_key
547
+ ```
548
+ 然后在测试脚本中使用API密钥连接:
549
+ ```python
550
+ @remote: "http://server:8270/?api_key=your_secure_key" as secure_server
551
+ ```
552
+
553
+ 2. **限制网络访问**:
554
+ - 在内部网络或VPN中使用远程关键字服务
555
+ - 使用防火墙限制对服务端口的访问
556
+ - 考虑使用SSH隧道连接到远程服务
557
+
558
+ 3. **监控服务**:
559
+ - 定期检查服务日志
560
+ - 监控异常访问模式
561
+ - 在不需要时关闭服务
562
+
563
+ ### 远程关键字最佳实践
564
+
565
+ 1. **合理分配关键字**:
566
+ - 将计算密集型关键字放在性能更好的机器上
567
+ - 将特定环境依赖的关键字放在对应环境的机器上
568
+
569
+ 2. **错误处理**:
570
+ - 添加适当的错误处理机制,处理远程服务不可用的情况
571
+ - 使用超时设置避免长时间等待
572
+
573
+ 3. **变量传递**:
574
+ - 注意远程关键字执行后,变量会返回到本地上下文
575
+ - 大型数据应考虑使用文件或数据库共享,而不是直接通过变量传递
576
+
430
577
  ## 进阶文档
431
578
 
432
579
  - [完整DSL语法指南](./docs/自动化关键字DSL语法设计.md)
433
- - [创建自定义关键字](./pytest_dsl/docs/custom_keywords.md)
580
+ - [创建自定义关键字](./pytest_dsl/docs/custom_keywords.md)
434
581
  - [HTTP测试关键字](./docs/api.md)
435
582
  - [断言关键字详解](./docs/assertion_keywords.md)
436
583
  - [HTTP断言重试机制](./docs/http_assertion_retry.md)
584
+ - [远程关键字语法示例](./docs/remote_syntax_example.md)
437
585
 
438
586
  ## 贡献与支持
439
587
 
@@ -445,4 +593,4 @@ MIT License
445
593
 
446
594
  ---
447
595
 
448
- 开始使用pytest-dsl,释放测试自动化的无限可能!
596
+ 开始使用pytest-dsl,释放测试自动化的无限可能!
@@ -10,15 +10,15 @@ pytest_dsl/core/auto_decorator.py,sha256=uEW1t60E_saDLY5MwR2sGTK8IAtCZKruEPq-fRT
10
10
  pytest_dsl/core/auto_directory.py,sha256=UF3Xpv4vtwvw0atS1NyChnL2XrnzwLST4H2jwlFip1E,2617
11
11
  pytest_dsl/core/context.py,sha256=fXpVQon666Lz_PCexjkWMBBr-Xcd1SkDMp2vHar6eIs,664
12
12
  pytest_dsl/core/custom_keyword_manager.py,sha256=QY-wXvzON2kkFwojBSXqWcQpo_aKixKhG-rsacV8gzE,7955
13
- pytest_dsl/core/dsl_executor.py,sha256=cGVDK461qeG-bIHnTXUvIeZnNcDKwtXNOtnSM5QE9ls,20222
13
+ pytest_dsl/core/dsl_executor.py,sha256=fd-awPL1j1RCZ00fD3AeSwFcHNZzVx_dQe5IIvNe6rE,24127
14
14
  pytest_dsl/core/dsl_executor_utils.py,sha256=cFoR2p3qQ2pb-UhkoefleK-zbuFqf0aBLh2Rlp8Ebs4,2180
15
15
  pytest_dsl/core/global_context.py,sha256=NcEcS2V61MT70tgAsGsFWQq0P3mKjtHQr1rgT3yTcyY,3535
16
16
  pytest_dsl/core/http_client.py,sha256=1AHqtM_fkXf8JrM0ljMsJwUkyt-ysjR16NoyCckHfGc,15810
17
17
  pytest_dsl/core/http_request.py,sha256=yjcoCN0E49lm44WAO3H73E6Zm-5FuEm1swAIt6E3FFo,55404
18
18
  pytest_dsl/core/keyword_manager.py,sha256=FtPsXlI7PxvVQMJfDN_nQYvRhkag5twvaHXjELQsCEo,4068
19
- pytest_dsl/core/lexer.py,sha256=CkPyWrM_bTzqYjgXzfiL4r9XJVUvauOhDJKFJd861Ys,3224
20
- pytest_dsl/core/parser.py,sha256=7cpkGewAS8_uxMpEf3h4yMyguAMQnw-u4HEJzK-J5Fw,9092
21
- pytest_dsl/core/parsetab.py,sha256=9BwOWkBv-0NnaNiipnO5JqOFJ9_s9DQ2RPBqcIDnEKI,22287
19
+ pytest_dsl/core/lexer.py,sha256=nrpprs_a0-x5xQuJ9wo3gz8s03UJzYfri_WXKhTSvmw,3559
20
+ pytest_dsl/core/parser.py,sha256=vvdsFc8vi-msa6lM9Rr5eTjJAUJNjQINLnB15AhTJ5E,10039
21
+ pytest_dsl/core/parsetab.py,sha256=LSwz0uMGWmmylfrx7daID1TPFog-PhTyWlnSqM1jAXg,24049
22
22
  pytest_dsl/core/plugin_discovery.py,sha256=jqTX2UzQMCjy6lQV5h2HX63YAdkm25dyfxrLfFp6Wag,6744
23
23
  pytest_dsl/core/utils.py,sha256=INyuWAX_yhgU9JwSUxVjoB1iI1J6Gy4cVEXZsjJTAOg,4765
24
24
  pytest_dsl/core/variable_utils.py,sha256=6uY-SWtGMyVvpFb8Sw-5u8oPzNnPQKl0pt9-8mBpwac,9167
@@ -58,11 +58,11 @@ pytest_dsl/examples/quickstart/loops.auto,sha256=2UPuNhvErCoPis-nDStSLj5EY-lo1FK
58
58
  pytest_dsl/keywords/__init__.py,sha256=5aiyPU_t1UiB2MEZ6M9ffOKnV1mFT_2YHxnZvyWaBNI,372
59
59
  pytest_dsl/keywords/assertion_keywords.py,sha256=H0vNCvfG3h8R3ST6C5sVTEH8OTWj3x94cAzqSNBBRLI,22827
60
60
  pytest_dsl/keywords/global_keywords.py,sha256=RZcJ9ksfXZaRvds4247LFXu-8a0LFqTvVaD4n98GUrk,1410
61
- pytest_dsl/keywords/http_keywords.py,sha256=oGSdLYEGypYxTw6UFA1iHPaE6hRmeaoLfEoXbP_sIaI,25543
62
- pytest_dsl/keywords/system_keywords.py,sha256=3D6htXwoW2w0B3Ywtw1EBqffkGHAaUBoapG4-oJDJQQ,496
63
- pytest_dsl-0.3.1.dist-info/licenses/LICENSE,sha256=Rguy8cb9sYhK6cmrBdXvwh94rKVDh2tVZEWptsHIsVM,1071
64
- pytest_dsl-0.3.1.dist-info/METADATA,sha256=X4FcqaJTrg8r17F20OJascFP77r4ZKYZ47m-k2KILIk,11924
65
- pytest_dsl-0.3.1.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
66
- pytest_dsl-0.3.1.dist-info/entry_points.txt,sha256=BWrYOFO9UgaDUTdS_W0G6Gl9YAj490cetXJsXrcjruA,94
67
- pytest_dsl-0.3.1.dist-info/top_level.txt,sha256=4CrSx4uNqxj7NvK6k1y2JZrSrJSzi-UvPZdqpUhumWM,11
68
- pytest_dsl-0.3.1.dist-info/RECORD,,
61
+ pytest_dsl/keywords/http_keywords.py,sha256=Dxz_ebtGoy0D4Almn5LtBD9RSZnkeoHhygoGNcBSkOw,24810
62
+ pytest_dsl/keywords/system_keywords.py,sha256=n_jRrMvSv2v6Pm_amokfyLNVOLYP7CFWbBE3_dlO7h4,11299
63
+ pytest_dsl-0.5.0.dist-info/licenses/LICENSE,sha256=Rguy8cb9sYhK6cmrBdXvwh94rKVDh2tVZEWptsHIsVM,1071
64
+ pytest_dsl-0.5.0.dist-info/METADATA,sha256=jhvveN2EgoKR5TvJmmR7ONGQXyFceopAea13ZPhO8xQ,16405
65
+ pytest_dsl-0.5.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
66
+ pytest_dsl-0.5.0.dist-info/entry_points.txt,sha256=qqxFwSHQtjoae8_WWiO6w8y0N9nC4H8eFRvOnr_OipE,152
67
+ pytest_dsl-0.5.0.dist-info/top_level.txt,sha256=4CrSx4uNqxj7NvK6k1y2JZrSrJSzi-UvPZdqpUhumWM,11
68
+ pytest_dsl-0.5.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,5 +1,6 @@
1
1
  [console_scripts]
2
2
  pytest-dsl = pytest_dsl.cli:main
3
+ pytest-dsl-server = pytest_dsl.remote.keyword_server:main
3
4
 
4
5
  [pytest11]
5
6
  pytest_dsl = pytest_dsl.plugin