Skip to content

Commit 97c5409

Browse files
committed
Run a webserver to serve test content rather than loading from file://
1 parent ff36284 commit 97c5409

2 files changed

Lines changed: 78 additions & 23 deletions

File tree

pom.xml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@
4545

4646
<!-- Test goal -->
4747
<selenium.version>3.141.59</selenium.version>
48-
<selenium.htmlunit.version>2.36.0</selenium.htmlunit.version>
48+
<selenium.htmlunit.version>2.41.0</selenium.htmlunit.version>
4949
<jsoup.version>1.12.1</jsoup.version>
50+
<jetty.version>9.4.26.v20200117</jetty.version>
5051

5152
<!-- Required core j2cl dependencies -->
5253
<vertispan.jsinterop.base.version>1.0.0-SNAPSHOT</vertispan.jsinterop.base.version>
@@ -204,6 +205,20 @@
204205
</exclusions>
205206
</dependency>
206207

208+
<!-- allow test goal to start a simple server -->
209+
<dependency>
210+
<groupId>org.eclipse.jetty</groupId>
211+
<artifactId>jetty-server</artifactId>
212+
<version>${jetty.version}</version>
213+
</dependency>
214+
215+
<!-- specified to help htmlunit-driver and selenium-server have consistent dependencies -->
216+
<dependency>
217+
<groupId>org.eclipse.jetty.websocket</groupId>
218+
<artifactId>websocket-client</artifactId>
219+
<version>${jetty.version}</version>
220+
</dependency>
221+
207222
<dependency>
208223
<groupId>org.slf4j</groupId>
209224
<artifactId>slf4j-api</artifactId>
@@ -342,6 +357,10 @@
342357
<artifactId>jsoup</artifactId>
343358
<version>${jsoup.version}</version>
344359
</dependency>
360+
<dependency>
361+
<groupId>org.eclipse.jetty</groupId>
362+
<artifactId>jetty-server</artifactId>
363+
</dependency>
345364

346365
<!-- Test -->
347366
<dependency>

src/main/java/net/cardosi/mojo/TestMojo.java

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import java.io.*;
77
import java.nio.charset.StandardCharsets;
8+
import java.util.concurrent.CountDownLatch;
89
import java.util.logging.Level;
910

1011
import com.google.gson.GsonBuilder;
@@ -22,6 +23,12 @@
2223
import org.apache.maven.project.DefaultProjectBuildingRequest;
2324
import org.apache.maven.project.ProjectBuildingException;
2425
import org.apache.maven.project.ProjectBuildingRequest;
26+
import org.eclipse.jetty.server.Server;
27+
import org.eclipse.jetty.server.ServerConnector;
28+
import org.eclipse.jetty.server.handler.ResourceHandler;
29+
import org.eclipse.jetty.util.component.AbstractLifeCycle;
30+
import org.eclipse.jetty.util.component.LifeCycle;
31+
import org.eclipse.jetty.util.resource.Resource;
2532
import org.openqa.selenium.JavascriptExecutor;
2633
import org.openqa.selenium.WebDriver;
2734
import org.openqa.selenium.chrome.ChromeDriver;
@@ -224,7 +231,6 @@ public void execute() throws MojoExecutionException, MojoFailureException {
224231
String testClass = testFilePathWithoutSuffix.replaceAll("/", ".");
225232

226233
// Synthesize a new project which only depends on the last one, and only contains the named test's .testsuite content, remade into a one-off JS file
227-
228234
ArrayList<CachedProject> finalChildren = new ArrayList<>(e.getChildren());
229235
finalChildren.add(e);
230236
CachedProject t = new CachedProject(diskCache, project.getArtifact(), project, finalChildren, Collections.singletonList(tmp.toString()), Collections.emptyList());
@@ -241,56 +247,86 @@ public void execute() throws MojoExecutionException, MojoFailureException {
241247
// write a simple html file to that output dir
242248
//TODO parallelize this - run once each is done, possibly concurrently
243249
//TODO don't fail on the first test that doesn't work
244-
String startupHtmlFile;
250+
Path startupHtmlFile;
245251
try {
252+
Path webappDirPath = Paths.get(webappDirectory);
253+
Path outputJsPath = webappDirPath.resolve(config.getInitialScriptFilename());
246254
File outputJs = new File(new File(webappDirectory), config.getInitialScriptFilename());
247-
Path junitStartupFile = Paths.get(outputJs.getParent(), outputJs.getName().substring(0, outputJs.getName().length() - 2) + "html");
248-
Files.createDirectories(junitStartupFile.getParent());
255+
Path junitStartupPath = outputJsPath.resolveSibling(outputJsPath.getFileName().toString().substring(0, outputJs.getName().length() - 2) + "html");
256+
Files.createDirectories(junitStartupPath.getParent());
249257
String fileContents = CharStreams.toString(new InputStreamReader(TestMojo.class.getResourceAsStream("/junit.html")));
250258
fileContents = fileContents.replace("<TEST_SCRIPT>", outputJs.getName());
251259

252-
Files.write(junitStartupFile, fileContents.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
253-
startupHtmlFile = junitStartupFile.toAbsolutePath().toString();
260+
Files.write(junitStartupPath, fileContents.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
261+
startupHtmlFile = webappDirPath.relativize(junitStartupPath);
254262
} catch (IOException ex) {
255263
throw new UncheckedIOException(ex);
256264
}
257-
// assuming that was successful, start htmlunit to run the test
265+
266+
// Start a webserver TODO start just once for all tests
267+
Server server = new Server(0);
268+
269+
// Tell jetty how to serve our compiled content
270+
ResourceHandler resourceHandler = new ResourceHandler();
271+
resourceHandler.setDirectoriesListed(true);//enabled for easier debugging, if we introduce a "manual" mode
272+
resourceHandler.setBaseResource(Resource.newResource(webappDirectory));
273+
274+
server.setHandler(resourceHandler);
275+
server.start();
276+
277+
// With the server started, start a browser too so they work in parallel
258278
WebDriver driver = createBrowser();
279+
280+
// Wait until server is ready
281+
if (!server.isStarted()) {
282+
CountDownLatch started = new CountDownLatch(1);
283+
server.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener() {
284+
@Override
285+
public void lifeCycleStarted(LifeCycle event) {
286+
started.countDown();
287+
}
288+
});
289+
started.await();
290+
}
291+
int port = ((ServerConnector) server.getConnectors()[0]).getLocalPort();
292+
259293
try {
260-
driver.get("file://" + startupHtmlFile);
261-
// loop and poll if tests are done
294+
String url = "http://localhost:" + port + "/" + startupHtmlFile.toString();
295+
System.out.println("fetching " + url);
296+
driver.get(url);
297+
298+
// Loop and poll if tests are done
262299
new FluentWait<>(driver)
263300
.withTimeout(Duration.ofMinutes(1))
264-
.withMessage("Tests failed to finish in timeout")
301+
.withMessage("Tests failed to finish before timeout")
265302
.pollingEvery(Duration.ofMillis(100))
266303
.until(d -> isFinished(d));
267-
// check for success
304+
// Check for success
268305
if (!isSuccess(driver)) {
269-
// print the content of the browser console to the log
306+
// Print the content of the browser console to the log
270307
this.analyzeLog(driver);
271-
failedTests.put(config.getTest(), startupHtmlFile);
308+
failedTests.put(config.getTest(), generatedTest);
272309
getLog().error("Test failed!");
273310
} else {
274311
getLog().info("Test passed!");
275312
}
276313
} catch (Exception ex) {
277-
failedTests.put(config.getTest(), startupHtmlFile);
278-
if (!Objects.isNull(driver)) {
279-
this.analyzeLog(driver);
280-
}
314+
failedTests.put(config.getTest(), generatedTest);
315+
this.analyzeLog(driver);
281316
getLog().error("Test failed!");
282-
getLog().error(cleanForMavenLog(String.format(ex.getMessage())));
317+
getLog().error(cleanForMavenLog(ex.getMessage()));
283318
} finally {
284-
if (driver != null) {
285-
driver.quit();
286-
}
319+
driver.quit();
287320
}
288321
}
289322
} catch (ProjectBuildingException | IOException e) {
290323
throw new MojoExecutionException("Failed to build project structure", e);
324+
} catch (Exception e) {
325+
//TODO refine this, possibly remove
326+
throw new MojoExecutionException("Failed on test server start", e);
291327
}
292328

293-
if(failedTests.isEmpty()) {
329+
if (failedTests.isEmpty()) {
294330
getLog().info("All tests were passed successfully!");
295331
} else {
296332
failedTests.forEach((name, startupHtmlFile) -> getLog().error(String.format("Test %s failed, please try manually %s", name, startupHtmlFile)));

0 commit comments

Comments
 (0)