testeranto 0.125.3 → 0.129.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/README.md +248 -6
- package/dist/common/src/Node.js +5 -0
- package/dist/common/src/PM/base.js +6 -0
- package/dist/common/src/PM/index.js +0 -1
- package/dist/common/src/PM/main.js +84 -22
- package/dist/common/src/PM/web.js +1 -1
- package/dist/common/src/ReportServer.js +39 -2
- package/dist/common/src/build.js +41 -6
- package/dist/common/src/lib/abstractBase.js +22 -107
- package/dist/common/src/lib/basebuilder.js +20 -21
- package/dist/common/src/lib/classBuilder.js +12 -1
- package/dist/common/src/lib/core.js +1 -8
- package/dist/common/src/lib/index.js +2 -5
- package/dist/common/src/lib/pmProxy.js +294 -0
- package/dist/common/testeranto.config.js +43 -34
- package/dist/common/tsconfig.common.tsbuildinfo +1 -1
- package/dist/module/src/Node.js +5 -0
- package/dist/module/src/PM/base.js +6 -0
- package/dist/module/src/PM/index.js +0 -1
- package/dist/module/src/PM/main.js +84 -22
- package/dist/module/src/PM/web.js +1 -1
- package/dist/module/src/Project.js +6 -6
- package/dist/module/src/ReportClient.js +3 -3
- package/dist/module/src/ReportServer.js +39 -2
- package/dist/module/src/build.js +41 -6
- package/dist/module/src/lib/abstractBase.js +22 -107
- package/dist/module/src/lib/basebuilder.js +20 -21
- package/dist/module/src/lib/classBuilder.js +12 -1
- package/dist/module/src/lib/core.js +1 -8
- package/dist/module/src/lib/index.js +2 -5
- package/dist/module/src/lib/pmProxy.js +285 -0
- package/dist/module/testeranto.config.js +40 -34
- package/dist/module/tsconfig.module.tsbuildinfo +1 -1
- package/dist/prebuild/Project.css +1 -26
- package/dist/prebuild/Project.js +4 -4
- package/dist/prebuild/ReportClient.css +1 -26
- package/dist/prebuild/ReportClient.js +3 -3
- package/dist/prebuild/ReportServer.mjs +1 -2
- package/dist/prebuild/TestReport.css +1 -26
- package/dist/prebuild/build.mjs +42 -7
- package/dist/prebuild/run.mjs +95 -20
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/src/PM/web.d.ts +1 -1
- package/dist/types/src/Types.d.ts +2 -1
- package/dist/types/src/lib/abstractBase.d.ts +4 -6
- package/dist/types/src/lib/index.d.ts +1 -1
- package/dist/types/src/lib/pmProxy.d.ts +7 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +14 -7
- package/src/Init.ts +1 -0
- package/src/Node.ts +6 -0
- package/src/PM/base.ts +8 -0
- package/src/PM/index.ts +2 -7
- package/src/PM/main.ts +128 -26
- package/src/PM/web.ts +3 -3
- package/src/Project.tsx +6 -6
- package/src/ReportClient.tsx +3 -3
- package/src/ReportServer.ts +43 -2
- package/src/Types.ts +3 -2
- package/src/build.ts +47 -6
- package/src/lib/abstractBase.ts +45 -184
- package/src/lib/basebuilder.ts +25 -28
- package/src/lib/classBuilder.ts +13 -2
- package/src/lib/core.ts +10 -14
- package/src/lib/index.ts +6 -29
- package/src/lib/pmProxy.ts +366 -0
- package/testeranto/bundles/node/{react → redux}/metafile.json +186 -254
- package/testeranto/bundles/pure/redux/metafile.json +554 -0
- package/testeranto/bundles/web/redux/metafile.json +504 -0
- package/testeranto/bundles/web/{react/src/SubPackages/react-test-renderer/component → redux}/test/web.html +1 -1
- package/testeranto/index.html +1 -1
- package/testeranto/reports/{react → redux}/config.json +26 -10
- package/testeranto/reports/{react → redux}/index.html +5 -5
- package/testeranto/reports/redux/summary.json +20 -0
- package/testeranto.config.ts +46 -34
- package/tsc.log +3 -1
- package/testeranto/bundles/node/react/src/SubPackages/react-test-renderer/component/test/node.mjs +0 -24687
- package/testeranto/bundles/pure/react/metafile.json +0 -8
- package/testeranto/bundles/pure/react/src/SubPackages/react-test-renderer/component/test/pure.mjs +0 -24625
- package/testeranto/bundles/web/react/metafile.json +0 -8
- package/testeranto/bundles/web/react/src/SubPackages/react-test-renderer/component/test/web.mjs +0 -21290
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/node/node/console_log.txt +0 -0
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/bdd_errors.txt +0 -1
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/featurePrompt.txt +0 -0
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/lint_errors.json +0 -3381
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/littleBoard.html +0 -20
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/log.txt +0 -40
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/prompt.txt +0 -24
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/tests.json +0 -132
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/pure/pure/type_errors.txt +0 -17
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/bdd_errors.txt +0 -1
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/console_log.txt +0 -1
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/lint_errors.json +0 -2947
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/littleBoard.html +0 -20
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/log.txt +0 -40
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/prompt.txt +0 -23
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/tests.json +0 -132
- package/testeranto/reports/react/src/SubPackages/react-test-renderer/component/test/web/web/type_errors.txt +0 -18
- package/testeranto/reports/react/summary.json +0 -8
package/README.md
CHANGED
|
@@ -16,13 +16,16 @@ example test report: [chromapdx.github.io/kokomoBay](https://chromapdx.github.io
|
|
|
16
16
|
|
|
17
17
|
example repo: [kokomo bay](https://github.com/ChromaPDX/kokomoBay)
|
|
18
18
|
|
|
19
|
+
example repo V2: [testeranto-starter](https://github.com/adamwong246/testeranto-starter)
|
|
20
|
+
|
|
19
21
|
## What is testeranto?
|
|
20
22
|
|
|
21
23
|
- Testeranto produces test results which can be fed to Aider.ai to automatically fix failing tests.
|
|
22
24
|
- Testeranto tests are specified in a strongly-typed gherkin-like syntax. Rather than testing your code directly, Testeranto requires you wrap your code with a semantic interface which is based on TS type signatures.
|
|
23
25
|
- Testeranto can be run in the frontend or the backend, or both.
|
|
24
26
|
- Testeranto can be used to test anything that can be bundled with esbuild.
|
|
25
|
-
- Testeranto
|
|
27
|
+
- Testeranto connects "features" to "tests". This allows the AI to read feature documentation from external systems, like Jira.
|
|
28
|
+
- Testeranto generates test results into static a website which can be deployed to github pages easily.
|
|
26
29
|
|
|
27
30
|
## tech of note
|
|
28
31
|
|
|
@@ -31,16 +34,255 @@ example repo: [kokomo bay](https://github.com/ChromaPDX/kokomoBay)
|
|
|
31
34
|
- puppeteer - provides access to both node and chrome runtimes
|
|
32
35
|
- esbuild - used to quickly generate test bundles
|
|
33
36
|
- aider - AI to automatically fix broken tests
|
|
37
|
+
- eslint - runs upon the input files to generate a file of static analysis errors
|
|
38
|
+
- tsc - runs upon the input files to generate a file of type errors
|
|
39
|
+
- markdown - Markdown is used record feature files
|
|
40
|
+
|
|
41
|
+
## scripts
|
|
42
|
+
|
|
43
|
+
`yarn t-init`: startup a new testeranto project
|
|
44
|
+
|
|
45
|
+
`yarn t-build <someTest> <once|dev>`: build the "someTest" project once, or continuously
|
|
46
|
+
|
|
47
|
+
`yarn t-run <someTest> <once|dev>`: run the "someTest" project once, or continuously
|
|
48
|
+
|
|
49
|
+
`yarn t-report` Run the report server
|
|
50
|
+
|
|
51
|
+
`yarn t-aider PATH_TO_PROMPT_FILE`: Execute a generated prompt file to fix broken tests.
|
|
34
52
|
|
|
35
|
-
##
|
|
53
|
+
## AI
|
|
36
54
|
|
|
37
|
-
|
|
55
|
+
Testeranto generates a "prompt" alongside test results. This prompt is passed to aider as input.
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
// input src files which can be edited by aider
|
|
59
|
+
/add test/node.ts
|
|
60
|
+
|
|
61
|
+
// test report files that inform aider but should not be edited
|
|
62
|
+
/read testeranto/reports/allTests/node/test/node/tests.json
|
|
63
|
+
/read testeranto/reports/allTests/test/node/node/lint_errors.json
|
|
64
|
+
/read testeranto/reports/allTests/test/node/node/type_errors.txt
|
|
65
|
+
|
|
66
|
+
// A list of features which can inform aider.
|
|
67
|
+
/load testeranto/reports/allTests/node/test/node/featurePrompt.txt
|
|
68
|
+
|
|
69
|
+
// tell the AI what to do
|
|
70
|
+
/code Fix the failing tests described in testeranto/reports/allTests/node/test/node/tests.json. Correct any type signature errors described in the files testeranto/reports/allTests/test/node/node/type_errors.txt. Implement any method which throws "Function not implemented. Resolve the lint errors described in testeranto/reports/allTests/test/node/node/lint_errors.json"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## "Features"
|
|
74
|
+
|
|
75
|
+
Testeranto connects "features" to tests. The features may be simple strings, but they can also take the form of local markdown files, or remote URLs to external feature tracking systems. For instance, this could be a jira ticket or a github issue. These features are used to inform the AI context.
|
|
38
76
|
|
|
39
77
|
## Platforms
|
|
40
78
|
|
|
41
|
-
Testeranto runs tests in multiple runtimes. You can run the same test (more or less) in multiple contexts
|
|
79
|
+
Testeranto runs tests in multiple runtimes. You can run the same test (more or less) in multiple contexts, but depending on your test subject, not all may be applicable. For instance, if you are testing an http node server, you'll can't use the web runtime. If your code references `document` or `window`, you must use the web style. And if you wish to capture console.logs in a node context, you should use the `pure` runtime.
|
|
42
80
|
|
|
43
81
|
1. Node - the test is run in node v8 via fork.
|
|
44
|
-
2. Web - the test is run in chrome, in a page.
|
|
82
|
+
2. Web - the test is run in chrome, in a page.
|
|
45
83
|
3. Pure - the test is dynamically imported into the main thread. It will not have access to IO (console.log, etc) but it is more performant.
|
|
46
|
-
|
|
84
|
+
|
|
85
|
+
## Concepts
|
|
86
|
+
|
|
87
|
+
Testeranto tests take some piece of javascript as input, and wraps it in testing apparatus, and then executes that test on the given platform. You must provide this apparatus in the following form:
|
|
88
|
+
|
|
89
|
+
```js
|
|
90
|
+
export default async <I extends IT, O extends OT, M>(
|
|
91
|
+
|
|
92
|
+
// the thing that is being tested.
|
|
93
|
+
input: I["iinput"],
|
|
94
|
+
|
|
95
|
+
testSpecification: ITestSpecification<I, O>,
|
|
96
|
+
testImplementation: ITestImplementation<I, O, M>,
|
|
97
|
+
testInterface: Partial<IWebTestInterface<I>>,
|
|
98
|
+
testResourceRequirement: ITTestResourceRequest = defaultTestResourceRequirement
|
|
99
|
+
) => {
|
|
100
|
+
|
|
101
|
+
// or WebTesteranto<I, O, M> or PureTesteranto<I, O, M>
|
|
102
|
+
return new NodeTesteranto<I, O, M>(
|
|
103
|
+
input,
|
|
104
|
+
testSpecification,
|
|
105
|
+
testImplementation,
|
|
106
|
+
testResourceRequirement,
|
|
107
|
+
testInterface
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Practically speaking, for each thing you test, you will need to implement 3 types and 4 objects.
|
|
114
|
+
|
|
115
|
+
### type I
|
|
116
|
+
|
|
117
|
+
this type describes the shape of the BDD test
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
export type I = Ibdd_in<
|
|
121
|
+
null,
|
|
122
|
+
null,
|
|
123
|
+
Rectangle,
|
|
124
|
+
Rectangle,
|
|
125
|
+
Rectangle,
|
|
126
|
+
(...x) => (rectangle: Rectangle, utils: IPM) => Rectangle,
|
|
127
|
+
(rectangle: Rectangle, utils: IPM) => Rectangle
|
|
128
|
+
>;
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### type O
|
|
132
|
+
|
|
133
|
+
this type describes the shape of the "interface"
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
export type O = Ibdd_out<
|
|
137
|
+
// Suite
|
|
138
|
+
{
|
|
139
|
+
Default: [string];
|
|
140
|
+
},
|
|
141
|
+
// "Given" are initial states
|
|
142
|
+
{
|
|
143
|
+
Default;
|
|
144
|
+
WidthOfOneAndHeightOfOne;
|
|
145
|
+
WidthAndHeightOf: [number, number];
|
|
146
|
+
},
|
|
147
|
+
// "Whens" are steps which change the state of the test subject
|
|
148
|
+
{
|
|
149
|
+
HeightIsPubliclySetTo: [number];
|
|
150
|
+
WidthIsPubliclySetTo: [number];
|
|
151
|
+
setWidth: [number];
|
|
152
|
+
setHeight: [number];
|
|
153
|
+
},
|
|
154
|
+
// "Thens" are steps which make assertions of the test subject
|
|
155
|
+
{
|
|
156
|
+
AreaPlusCircumference: [number];
|
|
157
|
+
circumference: [number];
|
|
158
|
+
getWidth: [number];
|
|
159
|
+
getHeight: [number];
|
|
160
|
+
area: [number];
|
|
161
|
+
prototype: [];
|
|
162
|
+
},
|
|
163
|
+
// "Checks" are similar to "Givens"
|
|
164
|
+
{
|
|
165
|
+
Default;
|
|
166
|
+
WidthOfOneAndHeightOfOne;
|
|
167
|
+
WidthAndHeightOf: [number, number];
|
|
168
|
+
}
|
|
169
|
+
>;
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### type M (optional)
|
|
173
|
+
|
|
174
|
+
this type describes the modifications to the shape of the "specification". It can be used to make your BDD tests DRYer but is not necessary
|
|
175
|
+
|
|
176
|
+
```ts
|
|
177
|
+
export type M = {
|
|
178
|
+
givens: {
|
|
179
|
+
[K in keyof O["givens"]]: (...Iw: O["givens"][K]) => Rectangle;
|
|
180
|
+
};
|
|
181
|
+
whens: {
|
|
182
|
+
[K in keyof O["whens"]]: (
|
|
183
|
+
...Iw: O["whens"][K]
|
|
184
|
+
) => (rectangle: Rectangle, utils: PM) => Rectangle;
|
|
185
|
+
};
|
|
186
|
+
thens: {
|
|
187
|
+
[K in keyof O["thens"]]: (
|
|
188
|
+
...Iw: O["thens"][K]
|
|
189
|
+
) => (rectangle: Rectangle, utils: PM) => Rectangle;
|
|
190
|
+
};
|
|
191
|
+
};
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### the "specification" aka ITestSpecification<I, O>
|
|
195
|
+
|
|
196
|
+
The test specification is the BDD tests logic. The specification implements BDD directives "Given", "When", and Then"
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
export const RectangleTesterantoBaseTestSpecification: ITestSpecification<
|
|
200
|
+
I,
|
|
201
|
+
O
|
|
202
|
+
> = (Suite, Given, When, Then, Check) => {
|
|
203
|
+
return [
|
|
204
|
+
Suite.Default(
|
|
205
|
+
"Testing the Rectangle class",
|
|
206
|
+
{
|
|
207
|
+
// A "given" is a strict BDD test. It starts with an initial state, then executes the "whens" which update the test subject, and then executes the "thens" as a assertions.
|
|
208
|
+
test0: Given.Default(
|
|
209
|
+
// a list of features
|
|
210
|
+
["https://api.github.com/repos/adamwong246/testeranto/issues/8"],
|
|
211
|
+
// a list of "whens"
|
|
212
|
+
[When.setWidth(4), When.setHeight(19)],
|
|
213
|
+
// a list of "thens"
|
|
214
|
+
[Then.getWidth(4), Then.getHeight(19)]
|
|
215
|
+
),
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
[
|
|
219
|
+
// a "check" is a less strict style of test. Instead of lists of whens and thens, you get a function callback.
|
|
220
|
+
Check.Default("imperative style?!", [], async (rectangle) => {
|
|
221
|
+
Then.getWidth(2).thenCB(rectangle);
|
|
222
|
+
Then.getHeight(2).thenCB(rectangle);
|
|
223
|
+
When.setHeight(22).whenCB(rectangle);
|
|
224
|
+
Then.getHeight(232).thenCB(rectangle);
|
|
225
|
+
}),
|
|
226
|
+
]
|
|
227
|
+
),
|
|
228
|
+
];
|
|
229
|
+
};
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### the "interface" aka testInterface: Partial<IWebTestInterface<I>>
|
|
233
|
+
|
|
234
|
+
The test interface is code which is NOT BDD steps. The interface implements "before all", "after all", "before each", and "after each", all of which are optional. f
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
export const RectangleTesterantoBaseInterface: IPartialInterface<I> = {
|
|
238
|
+
beforeEach: async (subject, i) => {
|
|
239
|
+
return i();
|
|
240
|
+
},
|
|
241
|
+
andWhen: async function (s, whenCB, tr, utils) {
|
|
242
|
+
return whenCB(s)(s, utils);
|
|
243
|
+
},
|
|
244
|
+
butThen: async (s, t, tr, pm) => {
|
|
245
|
+
return t(s, pm);
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
## the "test resource requirement" aka ITTestResourceRequest (optional)
|
|
251
|
+
|
|
252
|
+
The test resource requirement describes things that the test needs to run, namely network ports. It is optional, but you should add this argument if your test needs to rely upon network ports
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
// TODO add example of test resource requirement
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Sidecars (COMING SOON)
|
|
259
|
+
|
|
260
|
+
Along side your test, you can include a number of "sidecars" which are other bundled javascript assets upon which your test depends. For example, suppose you have an app with a frontend and backend component. You could run a react test in the web and include the node http server as a sidecar.
|
|
261
|
+
|
|
262
|
+
## `eslint` and `tsc`
|
|
263
|
+
|
|
264
|
+
Alongside the bdd tests, testeranto runs eslint and tsc upon the input files to generate a list of static analysis errors and a list of type errors, respectively.
|
|
265
|
+
|
|
266
|
+
## Subprojects
|
|
267
|
+
|
|
268
|
+
Testeranto has a core repo, but there are also subprojects which implement tests by type and by technology
|
|
269
|
+
|
|
270
|
+
### testeranto-solidity
|
|
271
|
+
|
|
272
|
+
Test a solidity contract. Also included is an example of deploying a contrct to a ganache server.
|
|
273
|
+
|
|
274
|
+
### testeranto-reduxtoolkit
|
|
275
|
+
|
|
276
|
+
Test a redux store.
|
|
277
|
+
|
|
278
|
+
### testeranto-http
|
|
279
|
+
|
|
280
|
+
Test a node http server.
|
|
281
|
+
|
|
282
|
+
### testeranto-react (COMING SOON)
|
|
283
|
+
|
|
284
|
+
Test a react component. You can choose from a variety of types (jsx functions, class style, etc) and you can test with `react`, `react-dom`, or `react-test-renderer`
|
|
285
|
+
|
|
286
|
+
### testeranto-express (COMING SOON)
|
|
287
|
+
|
|
288
|
+
### testeranto-xstate (COMING SOON)
|
package/dist/common/src/Node.js
CHANGED
|
@@ -26,7 +26,12 @@ class NodeTesteranto extends core_js_1.default {
|
|
|
26
26
|
exports.NodeTesteranto = NodeTesteranto;
|
|
27
27
|
const testeranto = async (input, testSpecification, testImplementation, testInterface, testResourceRequirement = index_js_1.defaultTestResourceRequirement) => {
|
|
28
28
|
const t = new NodeTesteranto(input, testSpecification, testImplementation, testResourceRequirement, testInterface);
|
|
29
|
+
process.on("unhandledRejection", (reason, promise) => {
|
|
30
|
+
console.error("Unhandled Rejection at:", promise, "reason:", reason);
|
|
31
|
+
// Optionally, terminate the process or perform cleanup
|
|
32
|
+
});
|
|
29
33
|
try {
|
|
34
|
+
console.log(process.argv);
|
|
30
35
|
const f = await t.receiveTestResourceConfig(process.argv[2]);
|
|
31
36
|
console.error("goodbye node error", f.fails);
|
|
32
37
|
process.exit(f.fails);
|
|
@@ -129,7 +129,13 @@ class PM_Base {
|
|
|
129
129
|
});
|
|
130
130
|
}
|
|
131
131
|
async createWriteStream(filepath, testName) {
|
|
132
|
+
const folder = filepath.split("/").slice(0, -1).join("/");
|
|
132
133
|
return new Promise((res) => {
|
|
134
|
+
if (!fs_1.default.existsSync(folder)) {
|
|
135
|
+
return fs_1.default.mkdirSync(folder, {
|
|
136
|
+
recursive: true,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
133
139
|
const f = fs_1.default.createWriteStream(filepath);
|
|
134
140
|
fileStreams3.push(f);
|
|
135
141
|
if (!files[testName]) {
|
|
@@ -73,7 +73,7 @@ async function fileHash(filePath, algorithm = "md5") {
|
|
|
73
73
|
}
|
|
74
74
|
const statusMessagePretty = (failures, test) => {
|
|
75
75
|
if (failures === 0) {
|
|
76
|
-
console.log(ansi_colors_1.default.green(ansi_colors_1.default.inverse(`> ${test} completed successfully
|
|
76
|
+
console.log(ansi_colors_1.default.green(ansi_colors_1.default.inverse(`> ${test} completed successfully?!?`)));
|
|
77
77
|
}
|
|
78
78
|
else {
|
|
79
79
|
console.log(ansi_colors_1.default.red(ansi_colors_1.default.inverse(`> ${test} failed ${failures} times`)));
|
|
@@ -135,7 +135,6 @@ class PM_Main extends base_js_1.PM_Base {
|
|
|
135
135
|
basePath: process.cwd(), // always required, used for relative paths
|
|
136
136
|
configFilePath: "tsconfig.json", // config to inherit from (optional)
|
|
137
137
|
compilerOptions: {
|
|
138
|
-
rootDir: "src",
|
|
139
138
|
outDir: (0, utils_1.tscPather)(entrypoint, platform, this.name),
|
|
140
139
|
// declaration: true,
|
|
141
140
|
// skipLibCheck: true,
|
|
@@ -345,24 +344,40 @@ ${addableFiles
|
|
|
345
344
|
// }
|
|
346
345
|
// })
|
|
347
346
|
// );
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
.
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
347
|
+
try {
|
|
348
|
+
await Promise.resolve(`${`${builtfile}?cacheBust=${Date.now()}`}`).then(s => __importStar(require(s))).then((module) => {
|
|
349
|
+
return module.default
|
|
350
|
+
.then((defaultModule) => {
|
|
351
|
+
defaultModule
|
|
352
|
+
.receiveTestResourceConfig(argz)
|
|
353
|
+
.then(async (results) => {
|
|
354
|
+
this.receiveFeatures(results.features, destFolder, src, "pure");
|
|
355
|
+
statusMessagePretty(results.fails, src);
|
|
356
|
+
this.bddTestIsNowDone(src, results.fails);
|
|
357
|
+
})
|
|
358
|
+
.catch((e) => {
|
|
359
|
+
console.log(ansi_colors_1.default.red(ansi_colors_1.default.inverse(`${src} errored with: ${e}`)));
|
|
360
|
+
this.bddTestIsNowDone(src, -1);
|
|
361
|
+
})
|
|
362
|
+
.finally(() => {
|
|
363
|
+
webSideCares.forEach((webSideCar) => webSideCar.close());
|
|
364
|
+
});
|
|
356
365
|
})
|
|
357
366
|
.catch((e) => {
|
|
358
|
-
console.log(ansi_colors_1.default.red(ansi_colors_1.default.inverse(`${src} errored with: ${e}`)));
|
|
367
|
+
console.log(ansi_colors_1.default.red(ansi_colors_1.default.inverse(`${src} errored with: ${e}. Check ${reportDest}/error.txt for more info`)));
|
|
368
|
+
this.writeFileSync(`${reportDest}/error.txt`, e.stack, src);
|
|
359
369
|
this.bddTestIsNowDone(src, -1);
|
|
360
|
-
|
|
361
|
-
.
|
|
362
|
-
webSideCares.forEach((webSideCar) => webSideCar.close());
|
|
370
|
+
statusMessagePretty(-1, src);
|
|
371
|
+
// console.error(e);
|
|
363
372
|
});
|
|
364
373
|
});
|
|
365
|
-
}
|
|
374
|
+
}
|
|
375
|
+
catch (e) {
|
|
376
|
+
console.log(ansi_colors_1.default.red(ansi_colors_1.default.inverse(`${src} errored with: ${e}. Check ${reportDest}/error.txt for more info`)));
|
|
377
|
+
this.writeFileSync(`${reportDest}/error.txt`, e.stack, src);
|
|
378
|
+
this.bddTestIsNowDone(src, -1);
|
|
379
|
+
statusMessagePretty(-1, src);
|
|
380
|
+
}
|
|
366
381
|
// console.log("portsToUse", portsToUse);
|
|
367
382
|
for (let i = 0; i <= portsToUse.length; i++) {
|
|
368
383
|
if (portsToUse[i]) {
|
|
@@ -386,7 +401,7 @@ ${addableFiles
|
|
|
386
401
|
return t[0] === src;
|
|
387
402
|
});
|
|
388
403
|
if (!testConfig) {
|
|
389
|
-
console.log(ansi_colors_1.default.inverse(
|
|
404
|
+
console.log(ansi_colors_1.default.inverse(`missing test config! Exiting ungracefully for '${src}'`));
|
|
390
405
|
process.exit(-1);
|
|
391
406
|
}
|
|
392
407
|
const testConfigResource = testConfig[2];
|
|
@@ -488,11 +503,32 @@ ${addableFiles
|
|
|
488
503
|
});
|
|
489
504
|
});
|
|
490
505
|
const oStream = fs_1.default.createWriteStream(`${reportDest}/console_log.txt`);
|
|
491
|
-
const child = (0, node_child_process_1.spawn)("node", [builtfile, testResources], {
|
|
506
|
+
const child = (0, node_child_process_1.spawn)("node", [builtfile, testResources, "--trace-warnings"], {
|
|
492
507
|
stdio: ["pipe", "pipe", "pipe", "ipc"],
|
|
493
508
|
// silent: true
|
|
494
509
|
});
|
|
495
|
-
const p = destFolder + "/
|
|
510
|
+
const p = destFolder + "/tpipe";
|
|
511
|
+
// exec(`lsof`, (ec, out, err) => {
|
|
512
|
+
// console.log(ec, out, err);
|
|
513
|
+
// });
|
|
514
|
+
// if (fs.existsSync(p)) {
|
|
515
|
+
// fs.rmSync(p);
|
|
516
|
+
// }
|
|
517
|
+
const errFile = `${reportDest}/error.txt`;
|
|
518
|
+
if (fs_1.default.existsSync(errFile)) {
|
|
519
|
+
fs_1.default.rmSync(errFile);
|
|
520
|
+
}
|
|
521
|
+
// server.on("error", (e) => {
|
|
522
|
+
// if (e.code === "EADDRINUSE") {
|
|
523
|
+
// console.error(e);
|
|
524
|
+
// process.exit(-1);
|
|
525
|
+
// // console.error("Address in use, retrying...");
|
|
526
|
+
// // setTimeout(() => {
|
|
527
|
+
// // server.close();
|
|
528
|
+
// // server.listen(p);
|
|
529
|
+
// // }, 1000);
|
|
530
|
+
// }
|
|
531
|
+
// });
|
|
496
532
|
server.listen(p, () => {
|
|
497
533
|
var _a, _b;
|
|
498
534
|
(_a = child.stderr) === null || _a === void 0 ? void 0 : _a.on("data", (data) => {
|
|
@@ -502,6 +538,11 @@ ${addableFiles
|
|
|
502
538
|
oStream.write(`stdout data ${data}`);
|
|
503
539
|
});
|
|
504
540
|
child.on("close", (code) => {
|
|
541
|
+
console.log("close");
|
|
542
|
+
console.log("deleting", p);
|
|
543
|
+
if (fs_1.default.existsSync(p)) {
|
|
544
|
+
fs_1.default.rmSync(p);
|
|
545
|
+
}
|
|
505
546
|
oStream.close();
|
|
506
547
|
server.close();
|
|
507
548
|
if (code === null) {
|
|
@@ -516,9 +557,30 @@ ${addableFiles
|
|
|
516
557
|
this.bddTestIsNowDone(src, code);
|
|
517
558
|
statusMessagePretty(code, src);
|
|
518
559
|
}
|
|
519
|
-
|
|
560
|
+
haltReturns = true;
|
|
561
|
+
});
|
|
562
|
+
child.on("exit", (code) => {
|
|
563
|
+
console.log("exit");
|
|
564
|
+
console.log("deleting", p);
|
|
565
|
+
if (fs_1.default.existsSync(p)) {
|
|
566
|
+
fs_1.default.rmSync(p);
|
|
567
|
+
}
|
|
568
|
+
haltReturns = true;
|
|
569
|
+
});
|
|
570
|
+
child.on("error", (e) => {
|
|
571
|
+
console.log("error");
|
|
572
|
+
console.log("deleting", p);
|
|
573
|
+
if (fs_1.default.existsSync(p)) {
|
|
574
|
+
fs_1.default.rmSync(p);
|
|
575
|
+
}
|
|
576
|
+
haltReturns = true;
|
|
577
|
+
console.log(ansi_colors_1.default.red(ansi_colors_1.default.inverse(`${src} errored with: ${e.name}. Check ${errFile}for more info`)));
|
|
578
|
+
this.writeFileSync(`${reportDest}/error.txt`, e.toString(), src);
|
|
579
|
+
this.bddTestIsNowDone(src, -1);
|
|
580
|
+
statusMessagePretty(-1, src);
|
|
581
|
+
// this.bddTestIsNowDone(src, -1);
|
|
582
|
+
// statusMessagePretty(-1, src);
|
|
520
583
|
});
|
|
521
|
-
child.on("exit", (code) => { });
|
|
522
584
|
});
|
|
523
585
|
child.send({ path: p });
|
|
524
586
|
for (let i = 0; i <= portsToUse.length; i++) {
|
|
@@ -960,7 +1022,7 @@ ${addableFiles
|
|
|
960
1022
|
const hash = await fileHash(outputFile);
|
|
961
1023
|
if (fileHashes[k] !== hash) {
|
|
962
1024
|
fileHashes[k] = hash;
|
|
963
|
-
console.log(ansi_colors_1.default.
|
|
1025
|
+
console.log(ansi_colors_1.default.yellow(ansi_colors_1.default.inverse(`< ${e} ${filename}`)));
|
|
964
1026
|
launcher(k, outputFile);
|
|
965
1027
|
}
|
|
966
1028
|
});
|
|
@@ -971,7 +1033,7 @@ ${addableFiles
|
|
|
971
1033
|
});
|
|
972
1034
|
this.metafileOutputs(runtime);
|
|
973
1035
|
watcher((0, fs_1.watch)(metafile, async (e, filename) => {
|
|
974
|
-
console.log(ansi_colors_1.default.
|
|
1036
|
+
console.log(ansi_colors_1.default.yellow(ansi_colors_1.default.inverse(`< ${e} ${filename} (${runtime})`)));
|
|
975
1037
|
this.metafileOutputs(runtime);
|
|
976
1038
|
}));
|
|
977
1039
|
});
|
|
@@ -36,7 +36,7 @@ class PM_Web {
|
|
|
36
36
|
return window["isDisabled"](selector);
|
|
37
37
|
}
|
|
38
38
|
getAttribute(selector, attribute) {
|
|
39
|
-
return window["
|
|
39
|
+
return window["getAttribute"](selector, attribute);
|
|
40
40
|
}
|
|
41
41
|
getValue(selector) {
|
|
42
42
|
return window["getValue"](selector);
|
|
@@ -5,9 +5,46 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const node_static_1 = __importDefault(require("node-static"));
|
|
7
7
|
const http_1 = __importDefault(require("http"));
|
|
8
|
+
// import esbuild from "esbuild";
|
|
8
9
|
const main = async () => {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
// esbuild
|
|
11
|
+
// .context(configer(config, Object.keys(entryPoints), testName))
|
|
12
|
+
// .then(async (ctx) => {
|
|
13
|
+
// if (mode === "dev") {
|
|
14
|
+
// await ctx.watch().then((v) => {
|
|
15
|
+
// done();
|
|
16
|
+
// });
|
|
17
|
+
// } else {
|
|
18
|
+
// ctx.rebuild().then((v) => {
|
|
19
|
+
// done();
|
|
20
|
+
// });
|
|
21
|
+
// }
|
|
22
|
+
// return ctx;
|
|
23
|
+
// });
|
|
24
|
+
// }),
|
|
25
|
+
// await esbuild
|
|
26
|
+
// .context({
|
|
27
|
+
// entryPoints: [
|
|
28
|
+
// "node_modules/testeranto/src/ReportClient.tsx",
|
|
29
|
+
// "node_modules/testeranto/src/TestReport.tsx",
|
|
30
|
+
// "node_modules/testeranto/src/Project.tsx",
|
|
31
|
+
// ],
|
|
32
|
+
// bundle: true,
|
|
33
|
+
// format: "iife",
|
|
34
|
+
// platform: "browser",
|
|
35
|
+
// outdir: "./testeranto",
|
|
36
|
+
// define: {
|
|
37
|
+
// REPORT_ROOT: "localhost:8765",
|
|
38
|
+
// },
|
|
39
|
+
// })
|
|
40
|
+
// .then(async (ctx) => {
|
|
41
|
+
// await ctx.watch();
|
|
42
|
+
// let { host, port } = await ctx.serve({
|
|
43
|
+
// servedir: ".",
|
|
44
|
+
// });
|
|
45
|
+
// });
|
|
46
|
+
// process.chdir("../"); // Navigate one level up
|
|
47
|
+
const fileServer = new node_static_1.default.Server("./testeranto", {});
|
|
11
48
|
http_1.default
|
|
12
49
|
.createServer(function (request, response) {
|
|
13
50
|
request
|
package/dist/common/src/build.js
CHANGED
|
@@ -57,6 +57,7 @@ if (mode !== "once" && mode !== "dev") {
|
|
|
57
57
|
}
|
|
58
58
|
console.log("testeranto is building", testName, mode);
|
|
59
59
|
Promise.resolve(`${process.cwd() + "/" + "testeranto.config.ts"}`).then(s => __importStar(require(s))).then(async (module) => {
|
|
60
|
+
const pckge = (await Promise.resolve(`${`${process.cwd()}/package.json`}`).then(s => __importStar(require(s)))).default;
|
|
60
61
|
const bigConfig = module.default;
|
|
61
62
|
const project = bigConfig.projects[testName];
|
|
62
63
|
if (!project) {
|
|
@@ -130,12 +131,12 @@ Promise.resolve(`${process.cwd() + "/" + "testeranto.config.ts"}`).then(s => __i
|
|
|
130
131
|
<head>
|
|
131
132
|
<meta name="description" content="Webpage description goes here" />
|
|
132
133
|
<meta charset="utf-8" />
|
|
133
|
-
<title
|
|
134
|
+
<title>${pckge.name} - testeranto</title>
|
|
134
135
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
135
136
|
<meta name="author" content="" />
|
|
136
137
|
|
|
137
|
-
<link rel="stylesheet" href="
|
|
138
|
-
<script type="module" src="
|
|
138
|
+
<link rel="stylesheet" href="../ReportClient.css" />
|
|
139
|
+
<script type="module" src="../ReportClient.js"></script>
|
|
139
140
|
|
|
140
141
|
</head>
|
|
141
142
|
|
|
@@ -155,7 +156,7 @@ Promise.resolve(`${process.cwd() + "/" + "testeranto.config.ts"}`).then(s => __i
|
|
|
155
156
|
<head>
|
|
156
157
|
<meta name="description" content="Webpage description goes here" />
|
|
157
158
|
<meta charset="utf-8" />
|
|
158
|
-
<title
|
|
159
|
+
<title>${pckge.name} - testeranto</title>
|
|
159
160
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
160
161
|
<meta name="author" content="" />
|
|
161
162
|
|
|
@@ -163,8 +164,8 @@ Promise.resolve(`${process.cwd() + "/" + "testeranto.config.ts"}`).then(s => __i
|
|
|
163
164
|
${JSON.stringify(Object.keys(bigConfig.projects))}
|
|
164
165
|
</script>
|
|
165
166
|
|
|
166
|
-
<link rel="stylesheet" href="
|
|
167
|
-
<script type="module" src="
|
|
167
|
+
<link rel="stylesheet" href="Project.css" />
|
|
168
|
+
<script type="module" src="Project.js"></script>
|
|
168
169
|
|
|
169
170
|
</head>
|
|
170
171
|
|
|
@@ -197,6 +198,40 @@ Promise.resolve(`${process.cwd() + "/" + "testeranto.config.ts"}`).then(s => __i
|
|
|
197
198
|
// fs.unlinkSync(chunk);
|
|
198
199
|
// });
|
|
199
200
|
// });
|
|
201
|
+
const x = [
|
|
202
|
+
["pure", Object.keys(importEntryPoints)],
|
|
203
|
+
["node", Object.keys(nodeEntryPoints)],
|
|
204
|
+
["web", Object.keys(webEntryPoints)],
|
|
205
|
+
];
|
|
206
|
+
x.forEach(async ([runtime, keys]) => {
|
|
207
|
+
keys.forEach(async (k) => {
|
|
208
|
+
const folder = `testeranto/reports/${testName}/${k
|
|
209
|
+
.split(".")
|
|
210
|
+
.slice(0, -1)
|
|
211
|
+
.join(".")}/${runtime}`;
|
|
212
|
+
await fs_1.default.mkdirSync(folder, { recursive: true });
|
|
213
|
+
fs_1.default.writeFileSync(`${folder}/index.html`, `
|
|
214
|
+
<!DOCTYPE html>
|
|
215
|
+
<html lang="en">
|
|
216
|
+
|
|
217
|
+
<head>
|
|
218
|
+
<meta name="description" content="Webpage description goes here" />
|
|
219
|
+
<meta charset="utf-8" />
|
|
220
|
+
<title>${testName} - testeranto</title>
|
|
221
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
222
|
+
<meta name="author" content="" />
|
|
223
|
+
|
|
224
|
+
<link rel="stylesheet" href="../../../../../TestReport.css" />
|
|
225
|
+
<script src="../../../../../TestReport.js"></script>
|
|
226
|
+
|
|
227
|
+
</head>
|
|
228
|
+
|
|
229
|
+
<body>
|
|
230
|
+
<div id="root"/>
|
|
231
|
+
</body>
|
|
232
|
+
`);
|
|
233
|
+
});
|
|
234
|
+
});
|
|
200
235
|
await Promise.all([
|
|
201
236
|
...[
|
|
202
237
|
[pure_js_1.default, importEntryPoints, onImportDone],
|