Skip to content

Commit 768f05b

Browse files
authored
Merge pull request #1170 from cloudbees-oss/codeceptjs
Support CodeceptJS profile
2 parents ea19257 + 4da3bdb commit 768f05b

File tree

6 files changed

+366
-36
lines changed

6 files changed

+366
-36
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import json
2+
from typing import List
3+
4+
import click
5+
6+
from ..testpath import TestPath
7+
from . import launchable
8+
9+
10+
@launchable.subset
11+
def subset(client):
12+
def handler(output: List[TestPath], rests: List[TestPath]):
13+
# The output would be something like this:
14+
# {"tests": ["test/example_test.js", "test/login_test.js"]}
15+
if client.rest:
16+
with open(client.rest, "w+", encoding="utf-8") as f:
17+
f.write(json.dumps({"tests": [client.formatter(t) for t in rests]}))
18+
if output:
19+
click.echo(json.dumps({"tests": [client.formatter(t) for t in output]}))
20+
21+
# read lines as test file names
22+
for t in client.stdin():
23+
if t.rstrip("\n"):
24+
client.test_path(t.rstrip("\n"))
25+
client.output_handler = handler
26+
27+
client.run()
28+
29+
30+
record_tests = launchable.CommonRecordTestImpls(__name__).file_profile_report_files()
31+
32+
split_subset = launchable.CommonSplitSubsetImpls(__name__).split_subset()

launchable/test_runners/file.py

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
#
22
# The most bare-bone versions of the test runner support
33
#
4-
import click
5-
from junitparser import TestCase, TestSuite # type: ignore
64

7-
from ..testpath import TestPath
85
from . import launchable
96

107

@@ -17,39 +14,7 @@ def subset(client):
1714
client.run()
1815

1916

20-
@click.argument('reports', required=True, nargs=-1)
21-
@launchable.record.tests
22-
def record_tests(client, reports):
23-
def path_builder(case: TestCase, suite: TestSuite,
24-
report_file: str) -> TestPath:
25-
"""path builder that puts the file name first, which is consistent with the subset command"""
26-
def find_filename():
27-
"""look for what looks like file names from test reports"""
28-
for e in [case, suite]:
29-
for a in ["file", "filepath"]:
30-
filepath = e._elem.attrib.get(a)
31-
if filepath:
32-
return filepath
33-
return None # failing to find a test name
34-
35-
filepath = find_filename()
36-
if not filepath:
37-
raise click.ClickException(
38-
"No file name found in %s" % report_file)
39-
40-
# default test path in `subset` expects to have this file name
41-
test_path = [client.make_file_path_component(filepath)]
42-
if suite.name:
43-
test_path.append({"type": "testsuite", "name": suite.name})
44-
if case.name:
45-
test_path.append({"type": "testcase", "name": case.name})
46-
return test_path
47-
client.path_builder = path_builder
48-
49-
for r in reports:
50-
client.report(r)
51-
client.run()
52-
17+
record_tests = launchable.CommonRecordTestImpls(__name__).file_profile_report_files()
5318

5419
split_subset = launchable.CommonSplitSubsetImpls(__name__).split_subset()
5520

launchable/test_runners/launchable.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,15 @@
44
import types
55

66
import click
7+
from junitparser import TestCase, TestSuite # type: ignore
78

89
from launchable.commands.detect_flakes import detect_flakes as detect_flakes_cmd
910
from launchable.commands.record.tests import tests as record_tests_cmd
1011
from launchable.commands.split_subset import split_subset as split_subset_cmd
1112
from launchable.commands.subset import subset as subset_cmd
1213

14+
from ..testpath import TestPath
15+
1316

1417
def cmdname(m):
1518
"""figure out the sub-command name from a test runner function"""
@@ -113,6 +116,47 @@ def record_tests(client, source_roots):
113116

114117
return wrap(record_tests, record_tests_cmd, self.cmdname)
115118

119+
def file_profile_report_files(self):
120+
"""
121+
Suitable for test runners that create a directory full of JUnit report files.
122+
123+
'record tests' expect JUnit report/XML file names.
124+
"""
125+
126+
@click.argument('source_roots', required=True, nargs=-1)
127+
def record_tests(client, source_roots):
128+
def path_builder(
129+
case: TestCase, suite: TestSuite, report_file: str
130+
) -> TestPath:
131+
def find_filename():
132+
"""look for what looks like file names from test reports"""
133+
for e in [case, suite]:
134+
for a in ["file", "filepath"]:
135+
filepath = e._elem.attrib.get(a)
136+
if filepath:
137+
return filepath
138+
return None # failing to find a test name
139+
140+
filepath = find_filename()
141+
if not filepath:
142+
raise click.ClickException("No file name found in %s" % report_file)
143+
144+
# default test path in `subset` expects to have this file name
145+
test_path = [client.make_file_path_component(filepath)]
146+
if suite.name:
147+
test_path.append({"type": "testsuite", "name": suite.name})
148+
if case.name:
149+
test_path.append({"type": "testcase", "name": case.name})
150+
return test_path
151+
152+
client.path_builder = path_builder
153+
154+
for r in source_roots:
155+
client.report(r)
156+
client.run()
157+
158+
return wrap(record_tests, record_tests_cmd, self.cmdname)
159+
116160
@classmethod
117161
def load_report_files(cls, client, source_roots, file_mask="*.xml"):
118162
# client type: RecordTests in def launchable.commands.record.tests.tests
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<testsuites name="Mocha Tests" time="0.861" tests="2" failures="1">
3+
<testsuite name="Root Suite" timestamp="2025-10-27T01:20:06" tests="0" time="0.000" failures="0">
4+
</testsuite>
5+
<testsuite name="Basic Tests" timestamp="2025-10-27T01:20:06" tests="2" file="/Users/ono-max/src/github.com/cloudbees-oss/smart-tests-integration-examples/codeceptjs/tests/website_test.js" time="0.861" failures="1">
6+
<testcase name="Basic Tests: Visit homepage" time="0.194" classname="Visit homepage">
7+
<failure message="expected web application to include &quot;Test Pagee&quot;" type="Error"><![CDATA[expected web application to include "Test Pagee"
8+
9+
+ expected - actual
10+
11+
-Test Page Welcome
12+
+Test Pagee
13+
]]></failure>
14+
</testcase>
15+
<testcase name="Basic Tests: Visit form page" time="0.127" classname="Visit form page">
16+
</testcase>
17+
</testsuite>
18+
</testsuites>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{
2+
"events": [
3+
{
4+
"type": "case",
5+
"testPath": [
6+
{
7+
"type": "file",
8+
"name": "/Users/ono-max/src/github.com/cloudbees-oss/smart-tests-integration-examples/codeceptjs/tests/website_test.js"
9+
},
10+
{
11+
"type": "testsuite",
12+
"name": "Basic Tests"
13+
},
14+
{
15+
"type": "testcase",
16+
"name": "Basic Tests: Visit homepage"
17+
}
18+
],
19+
"duration": 0.194,
20+
"status": 0,
21+
"stdout": "",
22+
"stderr": "expected web application to include \"Test Pagee\"\n\n + expected - actual\n\n -Test Page Welcome\n +Test Pagee\n ",
23+
"data": null
24+
},
25+
{
26+
"type": "case",
27+
"testPath": [
28+
{
29+
"type": "file",
30+
"name": "/Users/ono-max/src/github.com/cloudbees-oss/smart-tests-integration-examples/codeceptjs/tests/website_test.js"
31+
},
32+
{
33+
"type": "testsuite",
34+
"name": "Basic Tests"
35+
},
36+
{
37+
"type": "testcase",
38+
"name": "Basic Tests: Visit form page"
39+
}
40+
],
41+
"duration": 0.127,
42+
"status": 1,
43+
"stdout": "",
44+
"stderr": "",
45+
"data": null
46+
}
47+
],
48+
"testRunner": "codeceptjs",
49+
"group": "",
50+
"noBuild": false,
51+
"flavors": [],
52+
"testSuite": ""
53+
}

0 commit comments

Comments
 (0)