Skip to content

Commit bcfe6c5

Browse files
author
djeang
committed
add e2e tests
1 parent daf5abe commit bcfe6c5

File tree

1 file changed

+112
-28
lines changed

1 file changed

+112
-28
lines changed

src/dev/jeka/demo/templates/SpringBootTemplateBuild.java

Lines changed: 112 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
import dev.jeka.core.api.project.JkIdeSupport;
66
import dev.jeka.core.api.project.JkIdeSupportSupplier;
77
import dev.jeka.core.api.project.JkProject;
8+
import dev.jeka.core.api.system.JkLog;
9+
import dev.jeka.core.api.testing.ApplicationTester;
10+
import dev.jeka.core.api.testing.JkTestProcessor;
11+
import dev.jeka.core.api.testing.JkTestSelection;
12+
import dev.jeka.core.api.tooling.docker.JkDocker;
13+
import dev.jeka.core.api.tooling.docker.JkDockerBuild;
14+
import dev.jeka.core.api.tooling.docker.JkDockerJvmBuild;
15+
import dev.jeka.core.api.utils.JkUtilsNet;
816
import dev.jeka.core.tool.JkDoc;
917
import dev.jeka.core.tool.JkInjectProperty;
1018
import dev.jeka.core.tool.KBean;
@@ -16,6 +24,7 @@
1624
import java.nio.file.Files;
1725
import java.nio.file.Path;
1826
import java.util.List;
27+
import java.util.Optional;
1928

2029
@JkDoc("""
2130
Builds a Spring-Boot project, optionally containing a reactjs frontend.
@@ -38,25 +47,51 @@ public class SpringBootTemplateBuild extends KBean implements JkIdeSupportSuppli
3847

3948
public static final String REACTJS_BASE_DIR = "reactjs-client";
4049

50+
static final String E2E_TEST_PATTERN = "^e2e\\..*";
51+
4152
// Do not enforce to use a specific of NodeJs. Propose latest LTS versions instead.
4253
@JkDepSuggest(versionOnly = true, hint = "20.10.0,18.19.0,16.20.2")
4354
public String nodeJsVersion = NODEJS_VERSION;
4455

45-
@JkDoc("The unique application id within the organization. By defauly values to root dir name.")
56+
@JkDoc("The unique application id within the organization. By default, it values to the root dir name.")
4657
public String appId = getBaseDir().toAbsolutePath().getFileName().toString();
4758

4859
@JkDoc("Project version injected by CI/CD tool")
4960
@JkInjectProperty("PROJECT_VERSION")
5061
private String projectVersion;
5162

63+
private JkProject project = JkProject.of();
64+
65+
@Override
66+
protected void init() {
67+
project.setModuleId(appId);
68+
project.setVersion(projectVersion);
69+
project.packaging.getManifest().addMainAttribute(JkManifest.IMPLEMENTATION_VERSION, projectVersion);
70+
project.testing.testSelection.addExcludePatterns(E2E_TEST_PATTERN);
71+
72+
// Configure project as a Spring-Boot application
73+
JkSpringbootProject.of(project).configure();
74+
75+
// Build reactJs if 'reactjs-client' dir is present.
76+
// The bundled js app is copied in 'resources/static'.
77+
if (Files.exists(reactBaseDir())) {
78+
JkNodeJs.ofVersion(nodeJsVersion).configure(
79+
project,
80+
REACTJS_BASE_DIR,
81+
"build",
82+
"static",
83+
List.of("npx yarn install ", "npm run build"),
84+
List.of());
85+
}
86+
}
87+
5288
@JkDoc("Performs a simple build, without code coverage")
5389
public void pack() {
54-
project().clean().pack();
90+
project.clean().pack();
5591
}
5692

5793
@JkDoc("Performs a build including quality static analysis.")
5894
public void packQuality() {
59-
JkProject project = project();
6095
JkJacoco.ofVersion(getRunbase().getDependencyResolver(), JACOCO_VERSION)
6196
.configureFor(project);
6297
project.clean().pack();
@@ -83,48 +118,97 @@ public void packQuality() {
83118

84119
@JkDoc("Executes the built bootable jar")
85120
public void runJar() {
86-
project().prepareRunJar(JkProject.RuntimeDeps.EXCLUDE).run();
121+
project.prepareRunJar(JkProject.RuntimeDeps.EXCLUDE).run();
87122
}
88123

89124
@JkDoc("Displays the dependency tree on the console.")
90125
public void depTree() {
91-
project().displayDependencyTree();
126+
project.displayDependencyTree();
92127
}
93128

94-
@Override
95-
public JkIdeSupport getJavaIdeSupport() {
96-
return project().getJavaIdeSupport();
129+
@JkDoc("Creates a Docker image of the application")
130+
public void buildImage() {
131+
JkDockerJvmBuild.of(project)
132+
.setExposedPorts(8080)
133+
.buildImage(imageName());
97134
}
98135

99-
private JkProject project() {
100-
JkProject project = JkProject.of();
101-
project.setModuleId(appId);
102-
project.setVersion(projectVersion);
103-
project.packaging.getManifest().addMainAttribute(JkManifest.IMPLEMENTATION_VERSION, projectVersion);
104-
105-
// Configure project as a Spring-Boot application
106-
JkSpringbootProject.of(project).configure();
136+
@JkDoc("Run the Docker image and execute E2E tests (browser based)")
137+
public void runE2e() {
138+
new DockerTester().run();
139+
}
107140

108-
// Build reactJs if 'reactjs-client' dir is present.
109-
// The bundled js app is copied in 'resources/static'.
110-
if (Files.exists(reactBaseDir())) {
111-
JkNodeJs.ofVersion(nodeJsVersion).configure(
112-
project,
113-
REACTJS_BASE_DIR,
114-
"build",
115-
"static",
116-
List.of("npx yarn install ", "npm run build"),
117-
List.of());
118-
}
119-
return project;
141+
@Override
142+
public JkIdeSupport getJavaIdeSupport() {
143+
return project.getJavaIdeSupport();
120144
}
121145

122146
private Path reactBaseDir() {
123147
return getBaseDir().resolve(REACTJS_BASE_DIR);
124148
}
125149

150+
private String imageName() {
151+
String version = Optional.ofNullable(projectVersion).orElse("latest");
152+
return "my-org/" + appId + ":" + version;
153+
}
154+
155+
126156
private JkSonarqube sonarqubeBase() {
127157
return JkSonarqube.ofVersion(getRunbase().getDependencyResolver(), SONARQUBE_VERSION);
128158
}
129159

160+
private void execSelenideTests(String baseUrl) {
161+
//project.compilation.runIfNeeded();
162+
//project.testing.compilation.runIfNeeded();
163+
JkTestSelection selection = project.testing.createDefaultTestSelection()
164+
.addIncludePatterns(E2E_TEST_PATTERN);
165+
JkTestProcessor testProcessor = project.testing.createDefaultTestProcessor().setForkingProcess(true);
166+
testProcessor.getForkingProcess()
167+
.setLogWithJekaDecorator(true)
168+
.setLogCommand(true)
169+
.addJavaOptions("-Dselenide.reportsFolder=jeka-output/test-report/selenide")
170+
.addJavaOptions("-Dselenide.downloadsFolder=jeka-output/test-report/selenide-download")
171+
.addJavaOptions("-Dselenide.headless=true")
172+
.addJavaOptions("-Dselenide.baseUrl=" + baseUrl);
173+
testProcessor.launch(project.testing.getTestClasspath(), selection).assertSuccess();
174+
}
175+
176+
class DockerTester extends ApplicationTester {
177+
178+
int port;
179+
180+
String baseUrl;
181+
182+
String containerName;
183+
184+
@Override
185+
protected void startApp() {
186+
port = findFreePort();
187+
baseUrl = "http://localhost:" + port;
188+
containerName = project.getBaseDir().toAbsolutePath().getFileName().toString() + "-" + port;
189+
JkDocker.prepareExec("run", "-d", "-p", String.format("%s:8080", port), "--name",
190+
containerName, SpringBootTemplateBuild.this.imageName())
191+
.setInheritIO(false)
192+
.setLogWithJekaDecorator(true)
193+
.exec();
194+
}
195+
196+
@Override
197+
protected boolean isApplicationReady() {
198+
return JkUtilsNet.isAvailableAndOk(baseUrl, JkLog.isDebug());
199+
}
200+
201+
@Override
202+
protected void executeTests() {
203+
execSelenideTests(baseUrl);
204+
}
205+
206+
@Override
207+
protected void stopGracefully() {
208+
JkDocker.prepareExec("rm", "-f", containerName)
209+
.setInheritIO(false).setLogWithJekaDecorator(true)
210+
.exec();
211+
}
212+
}
213+
130214
}

0 commit comments

Comments
 (0)