Headless testfx in Gitlab CI

Hello, there.

I have a issue including my testfx in gitlab ci from gitpod. Any idea of what is missing or potential mistakes. The tests are running headless in gitpod, but I can’t seem to find a way to include the same test headless in gitlab ci. I believe I miss a image for including monocle to gitlab as a theory.

I am currently trying to include my frontend test to an jacoco report in Gitlab.

My project is maven build and runs headless tests in gitpod with monocle.


Hope someone can help. I appreciate all comments.


I have defined headless properties in my app.fxml and recalled this method in the tesfx

    public static void supportHeadless() {
        if (Boolean.getBoolean("headless")) {
            System.setProperty("testfx.robot", "glass");
            System.setProperty("testfx.headless", "true");
            System.setProperty("prism.order", "sw");
            System.setProperty("prism.text", "t2k");
            System.setProperty("java.awt.headless", "true");   
        }
    }

My .gitpod.Dockerfile
FROM gitpod/workspace-full-vnc

USER root

RUN add-apt-repository universe
RUN apt update
RUN apt -y install graphviz

USER gitpod

RUN bash -c ". /home/gitpod/.sdkman/bin/sdkman-init.sh \
             && sdk install java 16.0.1.hs-adpt \
             && sdk default java 16.0.1.hs-adpt"


My .gitpod.yml

image:
  file: .gitpod.Dockerfile

tasks:
  - init: sdk use java 16.0.1.hs-adpt
  - command: cd diary; mvn clean install

ports:
  # used by virtual desktop and vnc, supports JavaFX
  - port: 6080

my .gitlab-ci.yml

image: maven:latest

variables:
    MAVEN_OPTS: "-Djava.awt.headless=true -Dmaven.repo.local=$CI_PROJECT_DIR/.m2/repository"
    MAVEN_CLI_OPTS: "--batch-mode -P headless"
    MAVEN_SKIP_UI: "-DskipUiTests=True"


cache:
    paths:
        - target/

stages:
    - build
    - test
    - visualize
    - deploy

CompileCheck:
    stage: build
    script:
        - cd diary
        - mvn compile
    retry: 
        max: 2
        when:
            - always

JUnitTests:
    stage: test
    script:
        - cd diary
        - mvn clean test $MAVEN_CLI_OPTS $MAVEN_SKIP_UI
    retry: 
        max: 2
        when:
            - unknown_failure
            - api_failure
            - runner_system_failure
            - script_failure

premerge_jacoco:
    # Jacoco added based on https://docs.gitlab.com/ee/user/project/merge_requests/test_coverage_visualization.html
    stage: test
    script:
        - cd diary
        - mvn clean verify $MAVEN_CLI_OPTS $MAVEN_SKIP_UI
        - cat testing/target/site/jacoco-aggregate/index.html | grep -o '<tfoot>.*</tfoot>'
    artifacts:
        paths:
            - diary/testing/target/site/jacoco-aggregate/
    interruptible: true
    allow_failure: false
    retry:
        max: 1
    only:   
        refs:
            - merge_requests
        variables:
            - $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"

premerge_coberature:
    # Must be in a stage later than premerge_jacoco's stage.
    # The `visualize` stage does not exist by default.
    # Please define it first, or choose an existing stage like `deploy`.
    stage: visualize
    image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
    script:
        - python /opt/cover2cover.py diary/testing/target/site/jacoco-aggregate/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > diary/testing/target/site/cobertura.xml
    needs: [premerge_jacoco]
    dependencies:
        - premerge_jacoco
    artifacts:
        reports:
            cobertura: diary/testing/target/site/cobertura.xml
    interruptible: true
    retry:
        max: 1
    only:   
        refs:
            - merge_requests
        variables:
            - $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"

jacocoReport:
    # Jacoco added based on https://docs.gitlab.com/ee/user/project/merge_requests/test_coverage_visualization.html
    stage: test
    script:
        - cd diary
        - mvn $MAVEN_CLI_OPTS clean verify -DskipUiTests=true
        - cat testing/target/site/jacoco-aggregate/index.html | grep -o '<tfoot>.*</tfoot>'
    artifacts:
        paths:
            - diary/testing/target/site/jacoco-aggregate/
    interruptible: true
    allow_failure: false
    retry:
        max: 2
    only:
        - master
        - develop

coberatureReport:
    # Must be in a stage later than jacocoReport's stage.
    # The `visualize` stage does not exist by default.
    # Please define it first, or choose an existing stage like `deploy`.
    stage: visualize
    image: registry.gitlab.com/haynes/jacoco2cobertura:1.0.7
    script:
        # convert report from jacoco to cobertura, using relative project path
        - python /opt/cover2cover.py diary/testing/target/site/jacoco-aggregate/jacoco.xml $CI_PROJECT_DIR/src/main/java/ > diary/testing/target/site/cobertura.xml
    needs: [jacocoReport]
    dependencies:
        - jacocoReport
    artifacts:
        reports:
            cobertura: diary/testing/target/site/cobertura.xml
    interruptible: true
    retry:
        max: 2
    only:
        - master
        - develop

My app/ui/pom.xml
<?xml version="1.0" encoding="UTF-8" ?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>diary</groupId>
        <artifactId>parent</artifactId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <artifactId>ui</artifactId>

    <properties>
        <skipUiTests>false</skipUiTests>
    </properties>


    <dependencies>
        <dependency>
            <groupId>diary</groupId>
            <artifactId>core</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.openjfx/javafx-fxml -->
        <dependency>
            <groupId>org.openjfx</groupId>
            <artifactId>javafx-fxml</artifactId>
            <version>16</version>
        </dependency>

        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
        </dependency>

        <!-- Test with TextFX -->
		<dependency>
			<groupId>org.testfx</groupId>
		    <artifactId>testfx-core</artifactId>
		</dependency>
		<dependency>
    		<groupId>org.testfx</groupId>
			<artifactId>testfx-junit5</artifactId>
        </dependency>
    </dependencies>

    <profiles>
        <profile>
            <id>fontawesome</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.openjfx</groupId>
                        <artifactId>javafx-maven-plugin</artifactId>
                        <version>0.0.6</version>
                        <configuration>
                            <mainClass>de.jensd.fx.glyphs.fontawesome.demo.FontAwesomeIconsDemoApp</mainClass>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>DiaryApp</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>org.openjfx</groupId>
                        <artifactId>javafx-maven-plugin</artifactId>
                        <version>0.0.6</version>
                        <configuration>
                            <mainClass>diary.ui.DiaryApp</mainClass>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>

        <profile>
            <id>jpro</id>
            <pluginRepositories>
                <pluginRepository>
                    <id>jpro - sandec repository</id>
                    <url>https://sandec.bintray.com/repo</url>
                </pluginRepository>
            </pluginRepositories>
            <repositories>
                <repository>
                    <id>jpro - sandec repository</id>
                    <url>https://sandec.bintray.com/repo</url>
                </repository>
            </repositories>
            <build>
                <plugins>
                    <plugin>
                        <groupId>com.sandec.jpro</groupId>
                        <artifactId>jpro-maven-plugin</artifactId>
                        <version>2020.1.5</version>
                        <configuration>
                            <visible>false</visible>
                            <JVMArgs>
                                <!-- <JVMArg>your-args</JVMArg> -->
                            </JVMArgs>
                            <mainClassName>diary.ui.DiaryApp</mainClassName>
                            <openingPath>/</openingPath>
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
        <profile>
            <id>headless</id>
            <properties>
                <headlessTests>true</headlessTests>
            </properties>
            <dependencies>
                <!-- https://mvnrepository.com/artifact/org.testfx/openjfx-monocle -->
                <dependency>
                    <groupId>org.testfx</groupId>
                    <artifactId>openjfx-monocle</artifactId>
                    <version>jdk-12.0.1+2</version>
                    <scope>test</scope>
                </dependency>
            </dependencies>
        </profile>
    </profiles>

    <build>

        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                <configuration>
                    <skipTests>${skipUiTests}</skipTests>
                    <systemPropertyVariables>
                        <headless>${headlessTests}</headless>
                    </systemPropertyVariables>
                    <argLine>
                        @{jaCoCoArgLine}
                        --add-opens diary.ui/diary.ui=ALL-UNNAMED --add-exports javafx.graphics/com.sun.javafx.application=ALL-UNNAMED
                        --add-opens javafx.graphics/com.sun.glass.ui=ALL-UNNAMED --add-exports javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
                        --add-exports javafx.graphics/com.sun.glass.ui.delegate=ALL-UNNAMED
                    </argLine>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.openjfx</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>0.0.6</version>
                <configuration>
                    <mainClass>diary.ui.DiaryApp</mainClass>
                </configuration>
            </plugin>

            <!-- Run the checkstyle code quality tool -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>

            <!-- Run the spotbugs code quality tool -->
            <plugin>
                <groupId>com.github.spotbugs</groupId>
                <artifactId>spotbugs-maven-plugin</artifactId>
            </plugin>

            <!-- Configure jacoco code coverage -->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <configuration>
                    <propertyName>jaCoCoArgLine</propertyName>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

Hey @nazgul735! Welcome to the Gitpod community, great to have you with us. :slight_smile:

You’ll have to bear with me as I’m not very familiar with Java. But I’ll try my best to help! I’m finding it difficult to understand what the issue exactly is, so can you send either your repo for me to have a look at? Or perhaps what the error message you’re seeing is?

Hey, @Pauline. Unfortunately is the repo private.

When it goes for error messages is there non right now. I am running testfx headless. However, I can’t find a proper way to make the headless tests visible to Gitlab CI. For this to be a possibility I believe I need a library the docker image can use to make a connection between monocle and gitlab from gitpod.