When you run AET you have many out-of-the-box modifiers at your disposition (to name a few resolution sets the browser viewport size, click simulates clicking some element). AET uses modifiers to achieve certain conditions before collecting the data. Modifiers are a special case of collectors which use Selenium WebDriver to perform some actions, they just do not collect any data.

Now, let's imagine that you have some very special case (e.g. two-factor authentication) that can't be covered using JavaScript. To solve that problem, you need to implement and deploy a custom AET modifier that will use WebDriver to perform actions you want to be done. In this tutorial, you will build a custom modifier, run a local AET instance using Docker and, last but not least, deploy the modifier and run the test that uses it.

Context

AET core modules (runner, workers, WEB API) live on the OSGi container (Apache Karaf). The way to allow a piece of functionality (with an independent lifecycle) to be managed in an OSGi environment is by wrapping it in an OSGi bundle (a jar file with a manifest file). And that's exactly what your modifier will be - a bundle that will be deployed to an AET instance. It's worth mentioning, bundles can be loaded and unloaded while the system is still working.

Implementation

Ok, it is time for some coding!

Navigate to the AET Modifier template repository and simply download the ZIP or use that repository as a template and clone it.

Now it is time to choose between Java and Kotlin implementation. In the src there are two very simple implementations. Pick the language you prefer. Removing the other one is optional. You can keep both, as Java and Kotlin implementations can coexist in a single repository.

For this tutorial we will use Kotlin.

In the src/kotlin directory you can see a com.github.aet.modifier package. It contains two files: modifier and factory.

Factory and config

Let's start with the factory. Its main purpose is to deliver a modifier instance when requested and configure it. AET Modifier template comes with sample AnotherModifierFactory that implements CollectorFactory.

There are two important methods to implement:

  • getName that returns the name that modifier will be registered and identified by AET. That name will be also used in the AET suite configuration to invoke this modifier. It must be unique.
  • createInstance which creates a new instance of AnotherModifier. It can also provide properties passed via test configuration to the modifier (in this case color can be set).

Together with this class, you can see an annotation with the configuration model. This is not required by all modifiers, but this is a way to set up some default values (e.g. default color) for the modifier.

Modifier

As we mentioned above AnotherModifier implements CollectorJob (that is a common interface for both modifiers and collectors).

Besides setParameters method that was invoked by the factory, we have to implement collect method, that contains the logic of the modifier. In this example case, the logic is fairly simple. Using WebDriver as a JavascriptExecutor a simple JavaScript snippet is invoked to change the page body background color. And here is the true power of AET - you have direct access to the Selenium WebDriver and you can do anything it supports.

Build

After the logic of your modifier is ready, it's time to build it into the bundle (jar file).

Since you are building a Kotlin version, an additional plugin must be applied for the build - kotlin-dsl (it is already set in the AET Modifier template repo). Additionally, you will need kotlin-osgi-bundle installed at the Apache Karaf for the runtime. We will make use of the Karaf provisioning and ask the instance to download and install it for us using "Features". In the repo, you can see the features directory that contains a simple XML file. That file contains the following instruction:

<feature name="aet-kotlin" version="0.6.0" description="AET kotlin" install="auto">
  <bundle>mvn:org.jetbrains.kotlin/kotlin-osgi-bundle/1.3.70</bundle>
</feature>

These few simple lines, when deployed to the Karaf instance, will trigger downloading and installing kotlin-osgi-bundle. Neat, right?

Now, from the root of the repository, run ./gradelew build. After a couple of seconds, if everything goes ok, you should see the BUILD SUCCESSFUL message. Navigate to the build/libs directory. You should see a jar file (it contains the OSGi manifest).

Additionally, you will find two ZIP files in the build/distributions. They are packaged configs and features.

Set up a local AET instance and deploy the modifier

Now, let's set up an AET instance using Docker Swarm. For more information about the dockerized application please visit the AET Docker repository. In the AET Modifier template repository, you will find setup.sh. Execute it. Following things will happen:

  • try-me directory will be created
  • latest AET Docker Example Swarm will be downloaded and extracted to try-me/instance
  • sample AET Suite (from misc) will be copied to the try-me/tests directory and additionally AET bash client will be downloaded there

Navigate to the try-me/instance. Please check if you have the following prerequisites fulfilled, then run docker stack deploy -c aet-swarm.yml aet to start the AET instance. Wait a couple of minutes until all services are running and healthy.

Next, deploy your custom modifier, you can use deploy.sh (in the root repo directory). Executed script:

  • copies bundle (JAR file) to try-me/instance/bundles
  • copies feature (XML file) to try-me/instance/features
  • copies configs (CFG files) to try-me/instance/configs

AET should automatically discover the changes. You may check the logs by running docker service logs -f aet_karaf and look for a message saying your modifier is ready to use Binding collector: another.

Run the test

The last remaining step is to execute the tests.

Navigate to the try-me/tests. Open the suite.xml file - that's AET suite definition (you can read more about it here). The version form the repository contains two tests, one uses the example modifier (the one written in Java) and the second uses another modifier (the one written in Kotlin). Adjust the test appropriately to the changes you made in your modifier (e.g. remove the first test if you removed example modifier from the codebase).

You can run this sample test:

  <test name="changing-background-with-kotlin">
    <collect>
      <open/>
      <wait-for-page-loaded />
      <sleep duration="1000"/>

      <another /> <!-- this is the modifier you deployed -->

      <resolution width="1280" height="1024"/>
      <sleep duration="2000"/>
      <screen name="desktop"/>
    </collect>
    <compare>
      <screen comparator="layout"/>
    </compare>
    <urls>
      <url href="https://www.google.com"/>
    </urls>
  </test>

Using <another /> without specifying a color attribute value will cause the default color (red) to be used, as defined in the OSGi config at configs/com.github.aet.modifier.AnotherModifier.cfg.

When the suite is ready, execute it with ./aet.sh http://localhost.

You should see the information Suite started with correlation id: {some-id} and the progress. Once the processing is finished, you will see the report URL. Open it in your browser.

AET report with another modifier

Congratulations - you just executed your custom AET modifier!

Summary

In this post, you learned a bit about AET. You should know how to develop a custom AET modifier, how to set up a local AET instance using Docker and finally how to deploy a custom modifier to the local AET instance.