One of our large enterprise clients develops user-facing experiences using AEM (Adobe Experience Manager). With AEM, developers can author a page using various components (think of it as “WordPress for enterprises”). How do we test that the AEM web page is available and is performing as expected? How can we do it in an automated fashion? Writing your first AEM authoring test with Bobcat This guide uses bobcat-aem-junit template to create tests. Some concepts are the same as in first test guide and we won’t explain them here. Context We will write a test that will check the following: Login to AEM author instance We create simple test page with few components Configure text component Check if component has entered values Remove created page after test is finished. We will use AEM 6.4 instance.

Setup

We used gradle template so we have much of the job already done. We have already prepared default runmode with all required modules:

- com.cognifide.qa.bb.modules.CoreModule
- com.cognifide.qa.bb.aem.core.modules.Aem64FullModule

These two modules are required to run authoring tests for AEM 6.4.

Page Objects

We will start with creating required page objects

Create Test Page

Page Object that will be representation of our test page

package com.bobcat.test.pages;

import org.openqa.selenium.support.ui.ExpectedConditions;

import com.cognifide.qa.bb.aem.core.pages.AemAuthorPage;
import com.cognifide.qa.bb.qualifier.PageObject;
import com.cognifide.qa.bb.wait.BobcatWait;
import com.google.inject.Inject;

@PageObject
public class TestPage extends AemAuthorPage {

  @Inject
  private BobcatWait bobcatWait;

  private String title = "English";

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public boolean isDisplayed() {
    return bobcatWait.isConditionMet(ExpectedConditions.titleIs(getTitle()));
  }

  public boolean isNotAvailable() {
    return bobcatWait.isConditionMet(ExpectedConditions.titleContains("404 Resource"));
  }
}

  • AemAuthorPage is extend version of Page.class it contains method to retrieving component page object from preview mode. Thanks to this we can check if configuration was correct

Text Component

Then we will create Page Object that represents Text Component available in AEM. We will use both PageObjectInterface and PageObject

package com.bobcat.test.pageobjects;

import com.cognifide.qa.bb.qualifier.PageObjectInterface;

@PageObjectInterface
public interface TextComponent {
  String getInnerHTML();
}

package com.bobcat.test.pageobjects;

import com.cognifide.qa.bb.constants.HtmlTags.Properties;
import com.cognifide.qa.bb.qualifier.CurrentScope;
import com.cognifide.qa.bb.qualifier.PageObject;
import com.google.inject.Inject;
import org.openqa.selenium.WebElement;

@PageObject(css = ".cmp-text")
public class TextComponentImpl implements TextComponent {

  @Inject
  @CurrentScope
  private WebElement component;

  public String getInnerHTML() {
    return component.getAttribute(Properties.INNER_HTML);
  }

  public String getCssClassNameProperty() {
    return component.getAttribute(Properties.CLASS_NAME);
  }

}

Guice module

We should bind interface to implementation so we create simple guice module

ackage com.bobcat.test;

import com.bobcat.test.pageobjects.TextComponent;
import com.bobcat.test.pageobjects.TextComponentImpl;
import com.google.inject.AbstractModule;

public class ComponentModule extends AbstractModule {

  @Override
  protected void configure() {
    bind(TextComponent.class).to(TextComponentImpl.class);
  }
}

Then we should add new module to our runmode in default.yaml

There’s always the option to use Selenium WebDriver to interact with the page and couple it with some sort of unit test framework that would act as a test runner. However, let’s discuss what alternatives we might have.

AEM ships with a build-in test framework called HobbsJs. Although it’s typically a good idea to use the test framework that is shipped with a development environment, I would argue that’s not the case here. Hobbs has a number of limitations. To begin, it seems it can only be used in Developer mode, so it’s only beneficial for testing preconfigured component properties. We can’t test authoring or publishing. It’s impossible to access the navigation bar when you need to switch between different modes.

Bobcat test framework is a different story. It’s an AEM-centric product. Therefore we were pleased to find a lot of features that help to drive the page test automation. Think of it as a great combination of Selenium WebDriver plus helpers to perform AEM-specific actions.

On the authoring side, Bobcat test framework supplies methods to manage page creation, activation, and deletion. It also checks if it’s present in the sideadmin tree. Use siteadminPage instance variable for that.

Ideally you would want to create a test page before each individual scenario, use it, and destroy it at the end of the scenario regardless of whether it finished with success or failure. You can achieve this setup using before and after scenario hooks.

Given that the page is open, we can use other Bobcat helpers to interact with parsys by dragging or removing components. Once the component is on the parsys, we can edit its properties. Again all of this is done programmatically using the helpers provided (no coding necessary).

Type caption (optional)

The webdriver.properties file tester can specify settings for webdriver “capabilities” and default page timeout time. In the instances.properties files, we can provide Bobcat test framework with AEM instance URLs and login information. It’s not a great idea to hardcode the latter, so we suggest supplying it during runtime by injecting it into the system properties hashmap.

Logging into the siteadmin page is also easy. Given that credentials are supplied during runtime and stored in author.login and author.password respectively, Bobcat simply adds a cookie to the browser and we’re in. No need to actually type login information or pressing the Sign In button.

Use aemLogin.authorLogin() for that.

If you find yourself in the situation where Bobcat test framework doesn’t have a specific helper for your task, you can still use Selenium. Simply call methods on the webdriver instance variable. For example, we developed a method to exclusively deal with navigation bar and switch between user modes.

Once that was done, we were able to do the authoring part and immediately perform publisher side validation by switching to the Preview mode. Neat!

Authors of the Bobcat test framework made a good effort to provide extensive documentation of features and functionality on the Wiki page. However, we still found the material to be outdated, and the examples would not work right of the bat.

Going One Step Further with Cucumber

For our test framefork implementation we used a setup of JUnit + Cucumber + Bobcat.

Cucumber is a tool for driving scenario execution and to manage reporting. Each scenario is written in the Gerkhin language. It features usage of Given, When, Then, And keywords to start each phrase.

“Given I have this state, when I do something, then I should see something.”

That’s the general idea behind describing software behavior using this language. It’s commonly referred to as BDD or Behavior-Driven Development. Cucumber can match (using a RegEx engine) each Gherkin phrase with the respective block of code (step definition) written in any major coding language and then execute it.

Cucumber also supports tags. In fact this is one of its strongest features. Using tags you can include or exclude various scenarios and come up with custom run configurations based on your current needs. (You can learn more about Cucumber here.)

The sole purpose of using JUnit in the above setup is to kickstart Cucumber. For that we implemented this minimalistic TestRunner.java class:

Cucumber Meets Behavior-Driven Development

Personally, the main reason to use behavior-driven development (BDD) is to provide across-the-team visibility for testing scenarios. With the Cucumber framework, we are able to describe a user story in plain English. Now both technical and non-technical people can easily understand the test case simply by reading .feature files. It’s no longer exclusively a coding expert’s role to make a list of the currently automated scenarios and compare it with acceptance criteria generated during Sprint Planning meetings. In fact the these two should match by the end of the Sprint.

Using Bobcat Test Framework

Based on our experiences during client uplifts, we have concluded that it’s crucial to drive processes in each team. These processes help teams better understand the committed feature set for each sprint, as well as a methodically selected toolset. Using BDD and Bobcat test framework allowed us to not only rapidly develop AEM-centric test suites for multiple teams but also provide clarity for both technical and non-technical members.

      if(window.strchfSettings === undefined) window.strchfSettings = {};
   window.strchfSettings.stats = {url: "https://liatrio.storychief.io/bobcat-test-framework-as-an-aem-focused-ui-testing-framework?id=1940954164&type=26",title: "Bobcat Test Framework as an AEM-Focused UI Testing Framework",id: "0a85d495-2a02-4e9f-938f-9bd79cd0d390"};
           (function(d, s, id) {
     var js, sjs = d.getElementsByTagName(s)[0];
     if (d.getElementById(id)) {window.strchf.update(); return;}
     js = d.createElement(s); js.id = id;
     js.src = "https://d37oebn0w9ir6a.cloudfront.net/scripts/v0/strchf.js";
     js.async = true;
     sjs.parentNode.insertBefore(js, sjs);
   }(document, 'script', 'storychief-jssdk'))

Leave a Reply

Privacy Settings
We use cookies to enhance your experience while using our website. If you are using our Services via a browser you can restrict, block or remove cookies through your web browser settings. We also use content and scripts from third parties that may use tracking technologies. You can selectively provide your consent below to allow such third party embeds. For complete information about the cookies we use, data we collect and how we process them, please check our Privacy Policy
Youtube
Consent to display content from Youtube
Vimeo
Consent to display content from Vimeo
Google Maps
Consent to display content from Google
Spotify
Consent to display content from Spotify
Sound Cloud
Consent to display content from Sound