Categories
GWT Java Maven

HTMLUnit and GWT

After developing on an other aspect of a project, I realized later that all my GWT testcases didn’t work anymore. I got the following strange Exception:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
java.lang.NoSuchFieldError: FIREFOX_17
	at com.google.gwt.junit.RunStyleHtmlUnit.<clinit>(RunStyleHtmlUnit.java:200)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at com.google.gwt.junit.JUnitShell.createRunStyle(JUnitShell.java:1181)
	at com.google.gwt.junit.JUnitShell.doStartup(JUnitShell.java:942)
	at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:982)
	at com.google.gwt.junit.JUnitShell.getUnitTestShell(JUnitShell.java:698)
	at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:672)
	at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:421)
	at junit.framework.TestCase.runBare(TestCase.java:141)
	at junit.framework.TestResult$1.protect(TestResult.java:122)
	at junit.framework.TestResult.runProtected(TestResult.java:142)
	at junit.framework.TestResult.run(TestResult.java:125)
	at junit.framework.TestCase.run(TestCase.java:129)
	at com.google.gwt.junit.client.GWTTestCase.run(GWTTestCase.java:247)
	at junit.framework.TestSuite.runTest(TestSuite.java:255)
	at junit.framework.TestSuite.run(TestSuite.java:250)
	at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
</clinit>

The exception also occurred via Maven and not only in IntelliJ, so I knew it has something to do with my Maven-Project.

After checking the dependencies of my project with mvn dependency:tree, I found a new transitive dependency of a new added dependency. Because I didn’t need the htmlunit-part of this component I excluded the htmlunit-dependency with the following directive in my pom.xml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<dependencies>
....
    <dependency>
        <groupdid>my.dependency
        <artifactid>mydependency
        <exclusions>
            <exclusion>
                <groupid>net.sourceforge.htmlunit</groupid>
                <artifactid>htmlunit</artifactid>
            </exclusion>
        </exclusions>
    </artifactid></groupdid></dependency>
....
</dependencies>

A deeper analysis of the problem shows, that the transitive dependency was too new, because the field FIREFOX_17 is not available any more, but the newer one like FIREFOX_38.

Categories
GWT Java Javascript Maven

GWT-Hidden-Feature: code coverage

In July 2012 a until now rarely documented feature was added to GWT (related Git-Commit). It’s code coverage on the client side.

How it works

You can activate it via the System-Property “gwt.coverage”. The property-value must contain either all named Java source files separated by comma, or it must point to a text file containing all Java source files; one per line. Now the GWT compiler will instrument the corresponding JavaScript which is based on the named Java source files. Additionally the compiler registers an onUnLoad-Event, which stores the code coverage into LocalStorage of the browser.

Maven-Example

I have a simple GWT-Project which is build via Maven. In the main source (src/main/java/org/jajax/gwt/test/client/MyEntryPoint.java) I have the following file:

1
2
3
4
5
6
7
8
9
10
11
12
package org.jajax.gwt.test.client;
 
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Window;
 
public class MyEntryPoint implements EntryPoint {
 
   @Override
   public void onModuleLoad() {
       Window.alert("Hello world");
   }
}

Additionally I created a Textfile (target/gwt-coverage-sources.txt) with the following content:

1
org/jajax/gwt/test/client/MyEntryPoint.java

Now only the configuration of GWT is missing. You have to add the Parameter gwt.coverage=target/gwt-coverage-sources.txt.

1
2
3
4
5
6
7
8
<plugin>
    <groupid>org.codehaus.mojo</groupid>
    <artifactid>gwt-maven-plugin</artifactid>
    <version>2.7.0</version>
    <configuration>
        <extrajvmargs>-Dgwt.coverage=target/gwt-coverage-sources.txt</extrajvmargs>
    </configuration>
</plugin>

Now if you run you application, you can access the code coverage via JavaScript

?View Code JAVASCRIPT
1
localStorge.getItem("gwt_coverage");

You will get a JSON with the following content:

1
{"org/jajax/gwt/test/client/MyEntryPoint.java":{"6":1,"10":1}}

The inner object has for every line as key a value of 0 for a missing coverage or 1 for covered code.

Conclusion

This feature is very interesting, because the alternatives are very rare. The old option to use Emma / Jacoco is not functional anymore with the current versions of Java (1.8), GWT (2.7.0 / 2.8.0-SNAPSHOT), etc. So this feature seems to be a good alternative. Unfortunately there is no tool to extract the code coverage of Unit-Tests or Integration-Tests, but I will release a Tool, which connects the GWT code coverage with Jacoco Reports. So stay tuned!

Categories
HTML/CSS Javascript Polymer/Webcomponents

position:fixed and translate3d

Actually, I thought I understood position:fixed in HTML/CSS, but then I had some trouble in combination with transform:translate3d.  Generally position:fixed of an element means, you will have this element relative to the viewport (the browser window) fixed positioned, regardless any scroll-position.

For example the following HTML-Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<div style="position:absolute; left: 20px; top: 20px; width: 150px;  background-color: #7FDBFF">
<h1>positioned Box</h1>
<p>
Lorem ipsum ...
</p>
<div style="position:fixed; background-color:#FF851B; left: 50px; top:50px;width:100px;height: 30px;">
Fixed Box
</div>
</div>
<div style="position:absolute; left: 250px; top: 20px; width: 150px;  background-color: #2ECC40">
<h1>translated Box</h1>
<p>
Lorem ipsum...</p>
<div style="position:fixed; background-color:#FF4136; left: 50px; top:90px;width:100px;height: 30px;">
Fixed Box
</div>
</div>

You will see two absolute positioned boxes (an aqua and a green one) and two fixed boxes (orange and red), which are children of the absolute positioned boxes.

boxes1

The CSS-transform API gives now the possibility to use translate3d as a fast left/top replacement. So we can rewrite the green box to:

1
2
3
4
5
6
7
8
<div style="position:absolute; transform: translate3d(250px, 20px, 0px); width: 150px;  background-color: #2ECC40">
<h1>translated Box</h1>
<p>
Lorem ipsum...</p>
<div style="position:fixed; background-color:#FF4136; left: 50px; top:90px;width:100px;height: 30px;">
Fixed Box
</div>
</div>

We would expect the same result, but got a different one:

boxes2

You see that the red box is jumped to the right. The reason for this result is due to the fact, that translate3d moves the virtual viewport and so the root of the fixed position-relation. Unfortunately the common function getClientBoundingRect, which gives you the rectangle in the viewport, did not respect the translate3d transformation, so that common elements like Polymers iron-dropdown did not work properly anymore.

Until now I have no common solution for that problem, comments are welcome!

You can see, and play around, with my example on JSFiddle.

And also the polymer example shows the problem.