UI Testing

UI tests are Selenium-based tests packaged in a Docker image in order to allow a wide choice in language and frameworks (such as Java and Maven, Node and WebDriver.io, or any other framework and technology built upon Selenium). The Docker image can be created with standard tooling, but it must respect certain conventions during its execution. When running the Docker image, a Selenium server is automatically provisioned. The runtime conventions described below allow your test code to access both the Selenium server and the AEM instances under test.

NOTE

Stage and production pipelines created before February 10, 2021 need to be updated in order to use the UI tests as described on this page.
See Configuring your CI-CD Pipeline for information about pipeline configuration.

Building UI Tests

UI tests are built out of a Docker build context generated by a Maven project. Cloud Manager uses the Docker build context to generate a Docker image that contains the actual UI tests. In summary, a Maven project generates a Docker build context, and the Docker build context describes how to create a Docker image containing the UI tests.

This section goes through the steps needed to add a UI Tests project to your repository. If you are in a hurry or don’t have special requirements for the programming language, the AEM Project Archetype can generate a UI Tests project for you.

Generate a Docker build context

In order to generate a Docker build context, you need a Maven module that:

  • Produces an archive that contains a Dockerfile and every other file necessary to build the Docker image with your tests.
  • Tags the archive with the ui-test-docker-context classifier.

The simplest way to achieve this is to configure the Maven Assembly Plugin to create the Docker build context archive and assign the right classifier to it.

You can build UI tests with different technologies and frameworks, but this section assumes that your project is laid out in a way similar to the following.

├── Dockerfile
├── assembly-ui-test-docker-context.xml
├── pom.xml
├── test-module
│   ├── package.json
│   ├── index.js
│   └── wdio.conf.js
└── wait-for-grid.sh

The pom.xml file takes care of the Maven build. Add an execution to the Maven Assembly Plugin similar to the following.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-assembly-plugin</artifactId>
    <configuration>
        <descriptors>
            <descriptor>${project.basedir}/assembly-ui-test-docker-context.xml</descriptor>
        </descriptors>
        <tarLongFileMode>gnu</tarLongFileMode>
    </configuration>
    <executions>
        <execution>
            <id>make-assembly</id>
            <phase>package</phase>
            <goals>
                <goal>single</goal>
            </goals>
        </execution>
    </executions>
</plugin>

This execution instructs the Maven Assembly Plugin to create an archive based on the instructions contained in assembly-ui-test-docker-context.xml, called an “assembly descriptor” in the plugin’s jargon. The assembly descriptor lists all the files that must be part of the archive.

<assembly>
    <id>ui-test-docker-context</id>
    <includeBaseDirectory>false</includeBaseDirectory>
    <formats>
        <format>tar.gz</format>
    </formats>
    <fileSets>
        <fileSet>
            <directory>${basedir}</directory>
            <includes>
                <include>Dockerfile</include>
                <include>wait-for-grid.sh</include>
            </includes>
        </fileSet>
        <fileSet>
            <directory>${basedir}/test-module</directory>
            <excludes>
                <exclude>node/**</exclude>
                <exclude>node_modules/**</exclude>
                <exclude>reports/**</exclude>
            </excludes>
        </fileSet>
    </fileSets>
</assembly>

The assembly descriptor instructs the plugin to create an archive of type .tar.gz and assigns the ui-test-docker-context classifier to it. Moreover, it lists the files that must be included in the archive:

  • A Dockerfile, mandatory for building the Docker image.
  • The wait-for-grid.sh script, whose purposes are described below.
  • The actual UI tests, implemented by a Node.js project in the test-module folder.

The assembly descriptor also excludes some files that might be generated while running the UI tests locally. This guarantees a smaller archive and faster builds.

The archive containing the Docker build context is automatically picked up by Cloud Manager, that will build the Docker image containing your tests during its deployment pipelines. Eventually, Cloud Manager will run the Docker image to execute the UI tests against your application.

Writing UI Tests

This section describes the conventions that the Docker image containing your UI tests must follow. The Docker image is built out of the Docker build context described in the previous section.

Environment variables

The following environment variables will be passed to your Docker image at run time.

Variable Examples Description
SELENIUM_BASE_URL http://my-ip:4444 The URL of the Selenium server
SELENIUM_BROWSER chrome, firefox The browser implementation used by the Selenium Server
AEM_AUTHOR_URL http://my-ip:4502/context-path The URL of the AEM author instance
AEM_AUTHOR_USERNAME admin The username to login to the AEM author instance
AEM_AUTHOR_PASSWORD admin The password to login to the AEM author instance
AEM_PUBLISH_URL http://my-ip:4503/context-path The URL of the AEM publish instance
AEM_PUBLISH_USERNAME admin The username to login to the AEM publish instance
AEM_PUBLISH_PASSWORD admin The password to login to the AEM publish instance
REPORTS_PATH /usr/src/app/reports The path where the XML report of the test results must be saved
UPLOAD_URL http://upload-host:9090/upload The URL where file must be uploaded to in order to make them accessible to Selenium

Waiting for Selenium to be ready

Before the tests start, it’s the responsibility of the Docker image to ensure that the Selenium server is up and running. Waiting for the Selenium service is a two-steps process:

  1. Read the URL of the Selenium service from the SELENIUM_BASE_URL environment variable.
  2. Poll at regular interval to the status endpoint exposed by the Selenium API.

Once the Selenium’s status endpoint answers with a positive response, the tests can finally start.

Generate the test reports

The Docker image must generate test reports in the JUnit XML format and save them in the path specified by the environment variable REPORTS_PATH. The JUnit XML format is a widespread format for reporting the results of tests. If the Docker image uses Java and Maven, both the Maven Surefire Plugin and the Maven Failsafe Plugin. If the Docker image is implemented with other programming languages or test runners, check the documentation for the chosen tools to know how to generate JUnit XML reports.

Upload files (#upload-files)

Tests sometimes must upload files to the application under test. In order to maintain keep the deployment of Selenium relative to your tests flexible, it is not possible to directly upload an asset directly to Selenium. Instead, uploading a file goes through some intermediate steps:

  1. Upload the file at the URL specified by the UPLOAD_URL environment variable. The upload must be performed in one POST request with a multipart form. The multipart form must have a single file field. This is equivalent to curl -X POST ${UPLOAD_URL} -F "data=@file.txt". Consult the documentation and libraries of the programming language used in the Docker image to know how to perform such an HTTP request.
  2. If the upload is successful, the request returns a 200 OK response of type text/plain. The content of the response is an opaque file handle. You can use this handle in place of a file path in an <input> element to test file uploads in your application.

On this page