testeranto 0.199.0 → 0.200.0
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.
- package/bin/test_runner +0 -0
- package/bin/testeranto +0 -0
- package/bundle.js +2 -2
- package/cmd/test_runner/main.go +65 -0
- package/cmd/testeranto/main.go +37 -0
- package/dist/common/src/PM/main.js +126 -11
- package/dist/common/src/PM/pitonoRunner.js +54 -0
- package/dist/common/src/components/pure/TestPageView.js +180 -65
- package/dist/common/src/components/stateful/TestPage.js +50 -11
- package/dist/common/src/lib/abstractBase.test/index.js +1 -0
- package/dist/common/src/run.js +48 -82
- package/dist/common/src/{build.js → testeranto.js} +107 -55
- package/dist/common/src/utils/golingvuMetafile.js +116 -0
- package/dist/common/src/utils/logFiles.js +2 -1
- package/dist/common/src/utils/pitonoMetafile.js +67 -0
- package/dist/common/src/utils.js +40 -1
- package/dist/common/testeranto.config.js +23 -21
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/module/src/PM/main.js +126 -11
- package/dist/module/src/PM/pitonoRunner.js +47 -0
- package/dist/module/src/components/pure/TestPageView.js +180 -65
- package/dist/module/src/components/stateful/TestPage.js +50 -11
- package/dist/module/src/lib/abstractBase.test/index.js +1 -0
- package/dist/module/src/run.js +49 -45
- package/dist/module/src/{build.js → testeranto.js} +107 -55
- package/dist/module/src/utils/golingvuMetafile.js +109 -0
- package/dist/module/src/utils/logFiles.js +2 -1
- package/dist/module/src/utils/pitonoMetafile.js +60 -0
- package/dist/module/src/utils.js +40 -1
- package/dist/module/testeranto.config.js +23 -21
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/prebuild/App.js +81 -17
- package/dist/types/src/PM/main.d.ts +2 -0
- package/dist/types/src/PM/pitonoRunner.d.ts +7 -0
- package/dist/types/src/Types.d.ts +1 -1
- package/dist/types/src/run.d.ts +0 -1
- package/dist/types/src/utils/golingvuMetafile.d.ts +19 -0
- package/dist/types/src/utils/logFiles.d.ts +5 -1
- package/dist/types/src/utils/pitonoMetafile.d.ts +7 -0
- package/dist/types/src/utils.d.ts +5 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/docs/index.md +13 -13
- package/example/test_example.py +106 -0
- package/go.mod +3 -0
- package/package.json +2 -2
- package/pitono/__init__.py +54 -0
- package/pitono/base_given.py +131 -0
- package/pitono/base_suite.py +95 -0
- package/pitono/base_then.py +50 -0
- package/pitono/base_when.py +52 -0
- package/pitono/core_generator.py +110 -0
- package/pitono/pitono.egg-info/PKG-INFO +17 -0
- package/pitono/pitono.egg-info/SOURCES.txt +7 -0
- package/pitono/pitono.egg-info/dependency_links.txt +1 -0
- package/pitono/pitono.egg-info/entry_points.txt +2 -0
- package/pitono/pitono.egg-info/top_level.txt +1 -0
- package/pitono/pyproject.toml +26 -0
- package/pitono/setup.py +40 -0
- package/pitono/simple_adapter.py +24 -0
- package/pitono/types.py +78 -0
- package/sampleMetafile.json +56 -0
- package/src/PM/main.ts +146 -17
- package/src/PM/pitonoRunner.ts +49 -0
- package/src/Types.ts +1 -1
- package/src/components/pure/TestPageView.tsx +175 -8
- package/src/components/stateful/TestPage.tsx +57 -16
- package/src/core/types.go +36 -0
- package/src/golingvu/README.md +3 -0
- package/src/golingvu/base_given.go +76 -0
- package/src/golingvu/base_suite.go +39 -0
- package/src/golingvu/base_suite_test.go +197 -0
- package/src/golingvu/base_then.go +21 -0
- package/src/golingvu/base_when.go +21 -0
- package/src/golingvu/golingvu.go +179 -0
- package/src/golingvu/test_adapter.go +33 -0
- package/src/golingvu/types.go +86 -0
- package/src/lib/abstractBase.test/index.ts +1 -0
- package/src/pitono/README.md +3 -0
- package/src/run.ts +48 -48
- package/src/templates/frontpage.html +26 -17
- package/src/{build.ts → testeranto.ts} +128 -58
- package/src/utils/golingvuMetafile.ts +165 -0
- package/src/utils/logFiles.ts +2 -1
- package/src/utils/pitonoMetafile.ts +68 -0
- package/src/utils.ts +38 -1
- package/testeranto/App.js +81 -17
- package/testeranto/metafiles/golang/core.json +72 -0
- package/testeranto/metafiles/node/core.json +21 -459
- package/testeranto/metafiles/pure/core.json +18 -119
- package/testeranto/metafiles/web/core.json +37 -16797
- package/testeranto/reports/core/config.json +8 -40
- package/testeranto/reports/core/src/lib/BaseSuite.test/node.test/node/lint_errors.txt +6 -0
- package/testeranto/reports/core/src/lib/BaseSuite.test/node.test/node/prompt.txt +12 -1
- package/testeranto/reports/core/src/lib/BaseSuite.test/pure.test/pure/lint_errors.txt +2 -0
- package/testeranto/reports/core/src/lib/BaseSuite.test/pure.test/pure/prompt.txt +11 -1
- package/testeranto/reports/core/src/lib/BaseSuite.test/web.test/web/lint_errors.txt +2 -0
- package/testeranto/reports/core/src/lib/BaseSuite.test/web.test/web/prompt.txt +13 -3
- package/testeranto/reports/core/summary.json +9 -45
- package/testeranto.config.ts +25 -21
- package/tsc.log +46 -7
- package/dist/common/src/lib/mocks.test.js +0 -11
- package/dist/module/src/lib/mocks.test.js +0 -11
- package/dist/prebuild/build.mjs +0 -578
- package/dist/prebuild/run.mjs +0 -2290
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/dist/types/src/lib/mocks.test.d.ts +0 -0
- package/src/lib/mocks.test.ts +0 -11
- package/testeranto/reports/core/src/Pure.test/pure/exit.log +0 -0
- package/testeranto/reports/core/src/Pure.test/pure/lint_errors.txt +0 -0
- package/testeranto/reports/core/src/Pure.test/pure/message.txt +0 -17
- package/testeranto/reports/core/src/Pure.test/pure/prompt.txt +0 -14
- package/testeranto/reports/core/src/Pure.test/pure/type_errors.txt +0 -66
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/debug.log +0 -0
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/error.log +0 -67
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/exit.log +0 -1
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/info.log +0 -2
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/lint_errors.txt +0 -0
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/message.txt +0 -17
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/prompt.txt +0 -16
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/tests.json +0 -68
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/type_errors.txt +0 -56
- package/testeranto/reports/core/src/components/pure/FeaturesReporterView.test/index/web/warn.log +0 -0
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/debug.log +0 -0
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/error.log +0 -22
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/exit.log +0 -1
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/info.log +0 -2
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/lint_errors.txt +0 -13
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/message.txt +0 -17
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/prompt.txt +0 -16
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/tests.json +0 -88
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/type_errors.txt +0 -45
- package/testeranto/reports/core/src/components/pure/ProjectPageView.test/index/web/warn.log +0 -0
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/debug.log +0 -0
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/error.log +0 -0
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/exit.log +0 -1
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/info.log +0 -2
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/lint_errors.txt +0 -47
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/message.txt +0 -17
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/prompt.txt +0 -17
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/tests.json +0 -57
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/type_errors.txt +0 -99
- package/testeranto/reports/core/src/components/pure/TestPageView.test/index/web/warn.log +0 -0
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/exit.log +0 -1
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/lint_errors.txt +0 -0
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/message.txt +0 -17
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/prompt.txt +0 -17
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/stderr.log +0 -18
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/stdout.log +0 -0
- package/testeranto/reports/core/src/lib/TipoSkripto.test/TipoSkripto/node/type_errors.txt +0 -32
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/exit.log +0 -1
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/lint_errors.txt +0 -15
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/message.txt +0 -17
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/prompt.txt +0 -17
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/stderr.log +0 -66
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/stdout.log +0 -10
- package/testeranto/reports/core/src/lib/pmProxy.test/index/node/type_errors.txt +0 -47
- /package/dist/types/src/{build.d.ts → testeranto.d.ts} +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Dict, List, Any
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
class PitonoCoreGenerator:
|
|
8
|
+
def __init__(self, test_name: str, entry_points: List[str]):
|
|
9
|
+
self.test_name = test_name
|
|
10
|
+
self.entry_points = entry_points
|
|
11
|
+
self.output_dir = Path("testeranto") / "pitono" / test_name
|
|
12
|
+
self.output_dir.mkdir(parents=True, exist_ok=True)
|
|
13
|
+
|
|
14
|
+
def generate_core_json(self) -> Dict[str, Any]:
|
|
15
|
+
"""Generate a core.json file similar to esbuild's output"""
|
|
16
|
+
return {
|
|
17
|
+
"testName": self.test_name,
|
|
18
|
+
"entryPoints": self.entry_points,
|
|
19
|
+
"outputs": self._generate_outputs(),
|
|
20
|
+
"metafile": {
|
|
21
|
+
"inputs": self._generate_inputs(),
|
|
22
|
+
"outputs": self._generate_metafile_outputs()
|
|
23
|
+
},
|
|
24
|
+
"timestamp": self._get_timestamp(),
|
|
25
|
+
"runtime": "pitono"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
def _generate_outputs(self) -> Dict[str, Any]:
|
|
29
|
+
"""Generate outputs section similar to esbuild"""
|
|
30
|
+
outputs = {}
|
|
31
|
+
for entry_point in self.entry_points:
|
|
32
|
+
# For pitono, the "output" is the test file itself
|
|
33
|
+
# Use the absolute path to the original file
|
|
34
|
+
absolute_path = os.path.abspath(entry_point)
|
|
35
|
+
outputs[absolute_path] = {
|
|
36
|
+
"imports": [],
|
|
37
|
+
"exports": [],
|
|
38
|
+
"entryPoint": entry_point,
|
|
39
|
+
"inputs": {
|
|
40
|
+
ep: {
|
|
41
|
+
"bytes": os.path.getsize(ep) if os.path.exists(ep) else 1024,
|
|
42
|
+
"imports": []
|
|
43
|
+
}
|
|
44
|
+
for ep in self.entry_points
|
|
45
|
+
},
|
|
46
|
+
"bytes": os.path.getsize(entry_point) if os.path.exists(entry_point) else 2048
|
|
47
|
+
}
|
|
48
|
+
return outputs
|
|
49
|
+
|
|
50
|
+
def _generate_inputs(self) -> Dict[str, Any]:
|
|
51
|
+
"""Generate inputs section for metafile"""
|
|
52
|
+
inputs = {}
|
|
53
|
+
for entry_point in self.entry_points:
|
|
54
|
+
# Use absolute paths
|
|
55
|
+
absolute_path = os.path.abspath(entry_point)
|
|
56
|
+
inputs[absolute_path] = {
|
|
57
|
+
"bytes": os.path.getsize(entry_point) if os.path.exists(entry_point) else 1024,
|
|
58
|
+
"imports": []
|
|
59
|
+
}
|
|
60
|
+
return inputs
|
|
61
|
+
|
|
62
|
+
def _generate_metafile_outputs(self) -> Dict[str, Any]:
|
|
63
|
+
"""Generate outputs section for metafile"""
|
|
64
|
+
outputs = {}
|
|
65
|
+
for entry_point in self.entry_points:
|
|
66
|
+
# Use the absolute path to the original file
|
|
67
|
+
absolute_path = os.path.abspath(entry_point)
|
|
68
|
+
outputs[absolute_path] = {
|
|
69
|
+
"bytes": os.path.getsize(entry_point) if os.path.exists(entry_point) else 2048,
|
|
70
|
+
"inputs": {
|
|
71
|
+
ep: {
|
|
72
|
+
"bytesInOutput": os.path.getsize(ep) if os.path.exists(ep) else 1024
|
|
73
|
+
}
|
|
74
|
+
for ep in self.entry_points
|
|
75
|
+
},
|
|
76
|
+
"exports": [],
|
|
77
|
+
"entryPoint": entry_point
|
|
78
|
+
}
|
|
79
|
+
return outputs
|
|
80
|
+
|
|
81
|
+
def _get_timestamp(self) -> int:
|
|
82
|
+
"""Get current timestamp"""
|
|
83
|
+
import time
|
|
84
|
+
return int(time.time() * 1000)
|
|
85
|
+
|
|
86
|
+
def write_core_json(self):
|
|
87
|
+
"""Write the core.json file to disk"""
|
|
88
|
+
core_data = self.generate_core_json()
|
|
89
|
+
core_file_path = self.output_dir / "core.json"
|
|
90
|
+
|
|
91
|
+
with open(core_file_path, 'w') as f:
|
|
92
|
+
json.dump(core_data, f, indent=2)
|
|
93
|
+
|
|
94
|
+
print(f"Pitono core.json written to: {core_file_path}")
|
|
95
|
+
return core_file_path
|
|
96
|
+
|
|
97
|
+
def main():
|
|
98
|
+
if len(sys.argv) < 3:
|
|
99
|
+
print("Usage: pitono-core-generator <test_name> <entry_point1> [entry_point2 ...]")
|
|
100
|
+
sys.exit(1)
|
|
101
|
+
|
|
102
|
+
test_name = sys.argv[1]
|
|
103
|
+
# Convert entry points to absolute paths
|
|
104
|
+
entry_points = [os.path.abspath(ep) for ep in sys.argv[2:]]
|
|
105
|
+
|
|
106
|
+
generator = PitonoCoreGenerator(test_name, entry_points)
|
|
107
|
+
generator.write_core_json()
|
|
108
|
+
|
|
109
|
+
if __name__ == "__main__":
|
|
110
|
+
main()
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pitono
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python implementation of Testeranto
|
|
5
|
+
Author: Testeranto Team
|
|
6
|
+
Author-email:
|
|
7
|
+
Classifier: Development Status :: 3 - Alpha
|
|
8
|
+
Classifier: Intended Audience :: Developers
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Requires-Python: >=3.7
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
Dynamic: requires-python
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "pitono"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python implementation of Testeranto"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.7"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Testeranto Team" }
|
|
13
|
+
]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.7",
|
|
20
|
+
"Programming Language :: Python :: 3.8",
|
|
21
|
+
"Programming Language :: Python :: 3.9",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
[project.scripts]
|
|
26
|
+
pitono-core-generator = "core_generator:main"
|
package/pitono/setup.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
# Get the long description from the README file
|
|
5
|
+
readme_path = os.path.join(os.path.dirname(__file__), 'README.md')
|
|
6
|
+
long_description = ''
|
|
7
|
+
if os.path.exists(readme_path):
|
|
8
|
+
with open(readme_path, 'r', encoding='utf-8') as f:
|
|
9
|
+
long_description = f.read()
|
|
10
|
+
|
|
11
|
+
setup(
|
|
12
|
+
name="pitono",
|
|
13
|
+
version="0.1.0",
|
|
14
|
+
packages=find_packages(where='.'),
|
|
15
|
+
package_dir={'': '.'},
|
|
16
|
+
entry_points={
|
|
17
|
+
'console_scripts': [
|
|
18
|
+
'pitono-core-generator=core_generator:main',
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
python_requires='>=3.7',
|
|
22
|
+
install_requires=[
|
|
23
|
+
# Add any dependencies here
|
|
24
|
+
],
|
|
25
|
+
author="Testeranto Team",
|
|
26
|
+
author_email="",
|
|
27
|
+
description="Python implementation of Testeranto",
|
|
28
|
+
long_description=long_description,
|
|
29
|
+
long_description_content_type="text/markdown",
|
|
30
|
+
classifiers=[
|
|
31
|
+
"Development Status :: 3 - Alpha",
|
|
32
|
+
"Intended Audience :: Developers",
|
|
33
|
+
"License :: OSI Approved :: MIT License",
|
|
34
|
+
"Programming Language :: Python :: 3",
|
|
35
|
+
"Programming Language :: Python :: 3.7",
|
|
36
|
+
"Programming Language :: Python :: 3.8",
|
|
37
|
+
"Programming Language :: Python :: 3.9",
|
|
38
|
+
"Programming Language :: Python :: 3.10",
|
|
39
|
+
],
|
|
40
|
+
)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
from .types import ITestAdapter, ITTestResourceConfiguration
|
|
2
|
+
|
|
3
|
+
class SimpleTestAdapter(ITestAdapter):
|
|
4
|
+
def before_all(self, input_val, tr, pm):
|
|
5
|
+
return input_val
|
|
6
|
+
|
|
7
|
+
def after_all(self, store, pm):
|
|
8
|
+
return store
|
|
9
|
+
|
|
10
|
+
def before_each(self, subject, initializer, test_resource, initial_values, pm):
|
|
11
|
+
return subject
|
|
12
|
+
|
|
13
|
+
def after_each(self, store, key, pm):
|
|
14
|
+
return store
|
|
15
|
+
|
|
16
|
+
def and_when(self, store, when_cb, test_resource, pm):
|
|
17
|
+
return store
|
|
18
|
+
|
|
19
|
+
def but_then(self, store, then_cb, test_resource, pm):
|
|
20
|
+
return store
|
|
21
|
+
|
|
22
|
+
def assert_this(self, t):
|
|
23
|
+
# Simple implementation - always return True for now
|
|
24
|
+
return True
|
package/pitono/types.py
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from typing import TypeVar, Generic, Callable, Any, Dict, List, Optional
|
|
2
|
+
|
|
3
|
+
# Type variables for BDD input/output types
|
|
4
|
+
Iinput = TypeVar('Iinput')
|
|
5
|
+
Isubject = TypeVar('Isubject')
|
|
6
|
+
Istore = TypeVar('Istore')
|
|
7
|
+
Iselection = TypeVar('Iselection')
|
|
8
|
+
Then = TypeVar('Then')
|
|
9
|
+
Given = TypeVar('Given')
|
|
10
|
+
|
|
11
|
+
# Test resource configuration
|
|
12
|
+
class ITTestResourceConfiguration:
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
name: str,
|
|
16
|
+
fs: str,
|
|
17
|
+
ports: List[int],
|
|
18
|
+
browser_ws_endpoint: Optional[str] = None,
|
|
19
|
+
timeout: Optional[int] = None,
|
|
20
|
+
retries: Optional[int] = None,
|
|
21
|
+
environment: Optional[Dict[str, str]] = None
|
|
22
|
+
):
|
|
23
|
+
self.name = name
|
|
24
|
+
self.fs = fs
|
|
25
|
+
self.ports = ports
|
|
26
|
+
self.browser_ws_endpoint = browser_ws_endpoint
|
|
27
|
+
self.timeout = timeout
|
|
28
|
+
self.retries = retries
|
|
29
|
+
self.environment = environment or {}
|
|
30
|
+
|
|
31
|
+
# Test adapter interface
|
|
32
|
+
class ITestAdapter:
|
|
33
|
+
def before_all(self, input_val: Any, tr: ITTestResourceConfiguration, pm: Any) -> Any:
|
|
34
|
+
raise NotImplementedError()
|
|
35
|
+
|
|
36
|
+
def after_all(self, store: Any, pm: Any) -> Any:
|
|
37
|
+
raise NotImplementedError()
|
|
38
|
+
|
|
39
|
+
def before_each(self, subject: Any, initializer: Any, test_resource: ITTestResourceConfiguration,
|
|
40
|
+
initial_values: Any, pm: Any) -> Any:
|
|
41
|
+
raise NotImplementedError()
|
|
42
|
+
|
|
43
|
+
def after_each(self, store: Any, key: str, pm: Any) -> Any:
|
|
44
|
+
raise NotImplementedError()
|
|
45
|
+
|
|
46
|
+
def and_when(self, store: Any, when_cb: Any, test_resource: Any, pm: Any) -> Any:
|
|
47
|
+
raise NotImplementedError()
|
|
48
|
+
|
|
49
|
+
def but_then(self, store: Any, then_cb: Any, test_resource: Any, pm: Any) -> Any:
|
|
50
|
+
raise NotImplementedError()
|
|
51
|
+
|
|
52
|
+
def assert_this(self, t: Any) -> bool:
|
|
53
|
+
raise NotImplementedError()
|
|
54
|
+
|
|
55
|
+
# Test specification function type
|
|
56
|
+
ITestSpecification = Callable[[Any, Any, Any, Any], Any]
|
|
57
|
+
|
|
58
|
+
# Test implementation structure
|
|
59
|
+
class ITestImplementation:
|
|
60
|
+
def __init__(self, suites: Dict[str, Any], givens: Dict[str, Any],
|
|
61
|
+
whens: Dict[str, Any], thens: Dict[str, Any]):
|
|
62
|
+
self.suites = suites
|
|
63
|
+
self.givens = givens
|
|
64
|
+
self.whens = whens
|
|
65
|
+
self.thens = thens
|
|
66
|
+
|
|
67
|
+
# Test resource request
|
|
68
|
+
class ITTestResourceRequest:
|
|
69
|
+
def __init__(self, ports: int):
|
|
70
|
+
self.ports = ports
|
|
71
|
+
|
|
72
|
+
# Final results
|
|
73
|
+
class IFinalResults:
|
|
74
|
+
def __init__(self, failed: bool, fails: int, artifacts: List[Any], features: List[str]):
|
|
75
|
+
self.failed = failed
|
|
76
|
+
self.fails = fails
|
|
77
|
+
self.artifacts = artifacts
|
|
78
|
+
self.features = features
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"errors": [],
|
|
3
|
+
"warnings": [],
|
|
4
|
+
"metafile": {
|
|
5
|
+
"outputs": {
|
|
6
|
+
"testeranto/bundles/node/core/src/lib/BaseSuite.test/node.test.mjs": {
|
|
7
|
+
"entryPoint": "src/lib/BaseSuite.test/node.test.ts",
|
|
8
|
+
"inputs": {
|
|
9
|
+
"dist/cjs-shim.js": {
|
|
10
|
+
"bytesInOutput": 167
|
|
11
|
+
},
|
|
12
|
+
"src/lib/index.ts": {
|
|
13
|
+
"bytesInOutput": 672
|
|
14
|
+
},
|
|
15
|
+
"src/PM/node.ts": {
|
|
16
|
+
"bytesInOutput": 5315
|
|
17
|
+
},
|
|
18
|
+
"src/PM/index.ts": {
|
|
19
|
+
"bytesInOutput": 20
|
|
20
|
+
},
|
|
21
|
+
"src/lib/pmProxy.ts": {
|
|
22
|
+
"bytesInOutput": 6590
|
|
23
|
+
},
|
|
24
|
+
"src/lib/BaseGiven.ts": {
|
|
25
|
+
"bytesInOutput": 2911
|
|
26
|
+
},
|
|
27
|
+
"src/lib/BaseWhen.ts": {
|
|
28
|
+
"bytesInOutput": 1127
|
|
29
|
+
},
|
|
30
|
+
"src/lib/BaseThen.ts": {
|
|
31
|
+
"bytesInOutput": 1581
|
|
32
|
+
},
|
|
33
|
+
"src/lib/BaseSuite.ts": {
|
|
34
|
+
"bytesInOutput": 2451
|
|
35
|
+
},
|
|
36
|
+
"src/lib/Tiposkripto.ts": {
|
|
37
|
+
"bytesInOutput": 5299
|
|
38
|
+
},
|
|
39
|
+
"src/Node.ts": {
|
|
40
|
+
"bytesInOutput": 1203
|
|
41
|
+
},
|
|
42
|
+
"src/lib/BaseSuite.test/mock.ts": {
|
|
43
|
+
"bytesInOutput": 1481
|
|
44
|
+
},
|
|
45
|
+
"src/lib/BaseSuite.test/test.ts": {
|
|
46
|
+
"bytesInOutput": 7643
|
|
47
|
+
},
|
|
48
|
+
"src/lib/BaseSuite.test/node.test.ts": {
|
|
49
|
+
"bytesInOutput": 103
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"bytes": 37067
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/PM/main.ts
CHANGED
|
@@ -83,6 +83,12 @@ function runtimeLogs(
|
|
|
83
83
|
return {
|
|
84
84
|
exit: fs.createWriteStream(`${safeDest}/exit.log`),
|
|
85
85
|
};
|
|
86
|
+
} else if (runtime === "pitono") {
|
|
87
|
+
return {
|
|
88
|
+
stdout: fs.createWriteStream(`${safeDest}/stdout.log`),
|
|
89
|
+
stderr: fs.createWriteStream(`${safeDest}/stderr.log`),
|
|
90
|
+
exit: fs.createWriteStream(`${safeDest}/exit.log`),
|
|
91
|
+
};
|
|
86
92
|
} else {
|
|
87
93
|
throw `unknown runtime: ${runtime}`;
|
|
88
94
|
}
|
|
@@ -239,6 +245,7 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
239
245
|
webMetafileWatcher: fs.FSWatcher;
|
|
240
246
|
nodeMetafileWatcher: fs.FSWatcher;
|
|
241
247
|
importMetafileWatcher: fs.FSWatcher;
|
|
248
|
+
pitonoMetafileWatcher: fs.FSWatcher;
|
|
242
249
|
pureSidecars: Record<number, Sidecar>;
|
|
243
250
|
nodeSidecars: Record<number, ChildProcess>;
|
|
244
251
|
webSidecars: Record<number, Page>;
|
|
@@ -641,7 +648,7 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
641
648
|
);
|
|
642
649
|
}
|
|
643
650
|
|
|
644
|
-
const { nodeEntryPoints, webEntryPoints, pureEntryPoints } =
|
|
651
|
+
const { nodeEntryPoints, webEntryPoints, pureEntryPoints, pitonoEntryPoints } =
|
|
645
652
|
this.getRunnables(this.configs.tests, this.name);
|
|
646
653
|
|
|
647
654
|
[
|
|
@@ -669,6 +676,14 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
669
676
|
this.importMetafileWatcher = w;
|
|
670
677
|
},
|
|
671
678
|
],
|
|
679
|
+
[
|
|
680
|
+
pitonoEntryPoints,
|
|
681
|
+
this.launchPitono,
|
|
682
|
+
"pitono",
|
|
683
|
+
(w) => {
|
|
684
|
+
this.pitonoMetafileWatcher = w;
|
|
685
|
+
},
|
|
686
|
+
],
|
|
672
687
|
].forEach(
|
|
673
688
|
async ([eps, launcher, runtime, watcher]: [
|
|
674
689
|
Record<string, string>,
|
|
@@ -676,9 +691,22 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
676
691
|
IRunTime,
|
|
677
692
|
(f: fs.FSWatcher) => void
|
|
678
693
|
]) => {
|
|
679
|
-
|
|
694
|
+
let metafile: string;
|
|
695
|
+
if (runtime === "pitono") {
|
|
696
|
+
metafile = `./testeranto/metafiles/python/core.json`;
|
|
697
|
+
// Ensure the directory exists before trying to watch
|
|
698
|
+
const metafileDir = path.dirname(metafile);
|
|
699
|
+
if (!fs.existsSync(metafileDir)) {
|
|
700
|
+
fs.mkdirSync(metafileDir, { recursive: true });
|
|
701
|
+
}
|
|
702
|
+
} else {
|
|
703
|
+
metafile = `./testeranto/metafiles/${runtime}/${this.name}.json`;
|
|
704
|
+
}
|
|
680
705
|
|
|
681
|
-
|
|
706
|
+
// Only poll for file if it's not a pitono runtime
|
|
707
|
+
if (runtime !== "pitono") {
|
|
708
|
+
await pollForFile(metafile);
|
|
709
|
+
}
|
|
682
710
|
|
|
683
711
|
Object.entries(eps).forEach(
|
|
684
712
|
async ([inputFile, outputFile]: [string, string]) => {
|
|
@@ -707,14 +735,45 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
707
735
|
|
|
708
736
|
this.metafileOutputs(runtime);
|
|
709
737
|
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
738
|
+
// For pitono, we need to wait for the file to be created
|
|
739
|
+
if (runtime === "pitono") {
|
|
740
|
+
// Use polling to wait for the file to exist
|
|
741
|
+
const checkFileExists = () => {
|
|
742
|
+
if (fs.existsSync(metafile)) {
|
|
743
|
+
console.log(
|
|
744
|
+
ansiC.green(ansiC.inverse(`Pitono metafile found: ${metafile}`))
|
|
745
|
+
);
|
|
746
|
+
// Set up the watcher once the file exists
|
|
747
|
+
watcher(
|
|
748
|
+
watch(metafile, async (e, filename) => {
|
|
749
|
+
console.log(
|
|
750
|
+
ansiC.yellow(ansiC.inverse(`< ${e} ${filename} (${runtime})`))
|
|
751
|
+
);
|
|
752
|
+
this.metafileOutputs(runtime);
|
|
753
|
+
})
|
|
754
|
+
);
|
|
755
|
+
// Read the metafile immediately
|
|
756
|
+
this.metafileOutputs(runtime);
|
|
757
|
+
} else {
|
|
758
|
+
// Check again after a delay
|
|
759
|
+
setTimeout(checkFileExists, 1000);
|
|
760
|
+
}
|
|
761
|
+
};
|
|
762
|
+
// Start checking for the file
|
|
763
|
+
checkFileExists();
|
|
764
|
+
} else {
|
|
765
|
+
// For other runtimes, only set up watcher if the file exists
|
|
766
|
+
if (fs.existsSync(metafile)) {
|
|
767
|
+
watcher(
|
|
768
|
+
watch(metafile, async (e, filename) => {
|
|
769
|
+
console.log(
|
|
770
|
+
ansiC.yellow(ansiC.inverse(`< ${e} ${filename} (${runtime})`))
|
|
771
|
+
);
|
|
772
|
+
this.metafileOutputs(runtime);
|
|
773
|
+
})
|
|
714
774
|
);
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
);
|
|
775
|
+
}
|
|
776
|
+
}
|
|
718
777
|
}
|
|
719
778
|
);
|
|
720
779
|
|
|
@@ -760,6 +819,9 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
760
819
|
this.nodeMetafileWatcher.close();
|
|
761
820
|
this.webMetafileWatcher.close();
|
|
762
821
|
this.importMetafileWatcher.close();
|
|
822
|
+
if (this.pitonoMetafileWatcher) {
|
|
823
|
+
this.pitonoMetafileWatcher.close();
|
|
824
|
+
}
|
|
763
825
|
|
|
764
826
|
// Close any remaining log streams
|
|
765
827
|
Object.values(this.logStreams || {}).forEach((logs) => logs.closeAll());
|
|
@@ -799,13 +861,44 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
799
861
|
};
|
|
800
862
|
|
|
801
863
|
async metafileOutputs(platform: IRunTime) {
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
864
|
+
let metafilePath: string;
|
|
865
|
+
if (platform === "pitono") {
|
|
866
|
+
metafilePath = `./testeranto/metafiles/python/core.json`;
|
|
867
|
+
} else {
|
|
868
|
+
metafilePath = `./testeranto/metafiles/${platform}/${this.name}.json`;
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
// Check if the file exists
|
|
872
|
+
if (!fs.existsSync(metafilePath)) {
|
|
873
|
+
if (platform === "pitono") {
|
|
874
|
+
console.log(
|
|
875
|
+
ansiC.yellow(ansiC.inverse(`Pitono metafile not found yet: ${metafilePath}`))
|
|
876
|
+
);
|
|
877
|
+
}
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
let metafile;
|
|
882
|
+
try {
|
|
883
|
+
const fileContent = fs.readFileSync(metafilePath).toString();
|
|
884
|
+
const parsedData = JSON.parse(fileContent);
|
|
885
|
+
// Handle different metafile structures
|
|
886
|
+
if (platform === "pitono") {
|
|
887
|
+
// Pitono metafile might be the entire content or have a different structure
|
|
888
|
+
metafile = parsedData.metafile || parsedData;
|
|
889
|
+
} else {
|
|
890
|
+
metafile = parsedData.metafile;
|
|
891
|
+
}
|
|
892
|
+
if (!metafile) {
|
|
893
|
+
console.log(
|
|
894
|
+
ansiC.yellow(ansiC.inverse(`No metafile found in ${metafilePath}`))
|
|
895
|
+
);
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
} catch (error) {
|
|
899
|
+
console.error(`Error reading metafile at ${metafilePath}:`, error);
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
809
902
|
|
|
810
903
|
const outputs: IOutputs = metafile.outputs;
|
|
811
904
|
|
|
@@ -1609,6 +1702,42 @@ export class PM_Main extends PM_WithEslintAndTsc {
|
|
|
1609
1702
|
// }
|
|
1610
1703
|
};
|
|
1611
1704
|
|
|
1705
|
+
launchPitono = async (src: string, dest: string) => {
|
|
1706
|
+
console.log(ansiC.green(ansiC.inverse(`pitono < ${src}`)));
|
|
1707
|
+
this.bddTestIsRunning(src);
|
|
1708
|
+
|
|
1709
|
+
const reportDest = `testeranto/reports/${this.name}/${src
|
|
1710
|
+
.split(".")
|
|
1711
|
+
.slice(0, -1)
|
|
1712
|
+
.join(".")}/pitono`;
|
|
1713
|
+
if (!fs.existsSync(reportDest)) {
|
|
1714
|
+
fs.mkdirSync(reportDest, { recursive: true });
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
const logs = createLogStreams(reportDest, "node"); // Use node-style logs for pitono
|
|
1718
|
+
|
|
1719
|
+
try {
|
|
1720
|
+
// Execute the Python test using the pitono runner
|
|
1721
|
+
const { PitonoRunner } = await import('./pitonoRunner');
|
|
1722
|
+
const runner = new PitonoRunner(this.configs, this.name);
|
|
1723
|
+
await runner.run();
|
|
1724
|
+
|
|
1725
|
+
this.bddTestIsNowDone(src, 0);
|
|
1726
|
+
statusMessagePretty(0, src, "pitono");
|
|
1727
|
+
} catch (error) {
|
|
1728
|
+
logs.writeExitCode(-1, error);
|
|
1729
|
+
console.log(
|
|
1730
|
+
ansiC.red(
|
|
1731
|
+
ansiC.inverse(
|
|
1732
|
+
`${src} errored with: ${error}. Check logs for more info`
|
|
1733
|
+
)
|
|
1734
|
+
)
|
|
1735
|
+
);
|
|
1736
|
+
this.bddTestIsNowDone(src, -1);
|
|
1737
|
+
statusMessagePretty(-1, src, "pitono");
|
|
1738
|
+
}
|
|
1739
|
+
};
|
|
1740
|
+
|
|
1612
1741
|
launchWeb = async (src: string, dest: string) => {
|
|
1613
1742
|
console.log(ansiC.green(ansiC.inverse(`web < ${src}`)));
|
|
1614
1743
|
this.bddTestIsRunning(src);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import { ITestconfig } from '../lib';
|
|
5
|
+
|
|
6
|
+
export class PitonoRunner {
|
|
7
|
+
constructor(private config: ITestconfig, private testName: string) {}
|
|
8
|
+
|
|
9
|
+
async run(): Promise<void> {
|
|
10
|
+
const coreJsonPath = path.join(process.cwd(), 'testeranto', 'pitono', this.testName, 'core.json');
|
|
11
|
+
|
|
12
|
+
// Wait for the core.json file to be created with a timeout
|
|
13
|
+
const maxWaitTime = 10000; // 10 seconds
|
|
14
|
+
const startTime = Date.now();
|
|
15
|
+
while (!fs.existsSync(coreJsonPath) && (Date.now() - startTime) < maxWaitTime) {
|
|
16
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (!fs.existsSync(coreJsonPath)) {
|
|
20
|
+
console.error(`Pitono core.json not found at: ${coreJsonPath} after waiting ${maxWaitTime}ms`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const coreData = JSON.parse(fs.readFileSync(coreJsonPath, 'utf-8'));
|
|
26
|
+
const entryPoints = coreData.entryPoints;
|
|
27
|
+
|
|
28
|
+
for (const entryPoint of entryPoints) {
|
|
29
|
+
try {
|
|
30
|
+
console.log(`Running pitono test: ${entryPoint}`);
|
|
31
|
+
// Use python to execute the test file
|
|
32
|
+
const absolutePath = path.resolve(entryPoint);
|
|
33
|
+
// Check if the file exists
|
|
34
|
+
if (!fs.existsSync(absolutePath)) {
|
|
35
|
+
console.error(`Pitono test file not found: ${absolutePath}`);
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
execSync(`python "${absolutePath}"`, { stdio: 'inherit' });
|
|
39
|
+
console.log(`Pitono test completed: ${entryPoint}`);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(`Pitono test failed: ${entryPoint}`, error);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch (error) {
|
|
46
|
+
console.error(`Error reading or parsing core.json: ${error}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
package/src/Types.ts
CHANGED
|
@@ -177,7 +177,7 @@ export type IPluginFactory = (
|
|
|
177
177
|
entrypoints?: string[]
|
|
178
178
|
) => Plugin;
|
|
179
179
|
|
|
180
|
-
export type IRunTime = `node` | `web` | "pure" | `
|
|
180
|
+
export type IRunTime = `node` | `web` | "pure" | `golang` | `python`;
|
|
181
181
|
|
|
182
182
|
export type ITestTypes = [string, IRunTime, { ports: number }, ITestTypes[]];
|
|
183
183
|
|