Skip to content
This repository has been archived by the owner on Nov 23, 2021. It is now read-only.

Using Aem Content Tree

kkarolk edited this page Jul 22, 2016 · 2 revisions

Using Aem Content Tree

An AemContentTree class can be used whenever a path should be selected from some content tree - for example on the Siteadmin page or in the component configuration dialog window. Let's take a closer look at these two examples

Siteadmin content tree

The SiteadminPage class has designated method for obtaining a content tree from it - #getContentTree(). For example to select a page from the SiteAdmin content tree, we could do something like this:

siteAdminPage.getContentTree().selectPath("Summer Blockbuster Hits and Misses");

This statement will select the Summer Blockbuster Hits and Misses page in the SiteAdmin context and allow to perform further actions on it, however there is designated method for that - SiteAdminGrid#openPageByTitle which should be used in this case. Now let's take a look at more useful example - using content tree in configuration dialogs.

Pathfield content tree

Let's try to configure Search Component on the Search Page. At first we we will need the Search Component itself - so let's implement it!

@PageObject
public class SearchComponent {

  @Inject
  private AemDialog dialog;

  public AemDialog getDialog() {
    return dialog;
  }
}

This simple object keeps just the AemDialog field only. We need to control the path field element on the dialog to select some location under which search will be performed.

Search Component dialog window

As we can see, the path field on the dialog has "Path to search in" label. We can use it in our SearchComponent class. We need to add proper declaration and getter:

import com.cognifide.qa.bb.aem.dialog.classic.field.lookup.AemLookupField;
import com.cognifide.qa.bb.aem.qualifier.DialogField;
import com.cognifide.qa.bb.aem.ui.AemDialog;
import com.cognifide.qa.bb.qualifier.PageObject;
import com.google.inject.Inject;

@PageObject
public class SearchComponent {

  @Inject
  private AemDialog dialog;

  @DialogField(label = "Path to search in")
  private AemLookupField lookupField;

  public AemDialog getDialog() {
    return dialog;
  }

  public AemLookupField getLookupField() {
    return lookupField;
  }
}

We've used out of the box AemLookupField class here which handles such dialog fields. Now - when we've got the component, we should implement the page which contains it! But at first - let's find a css class under which this component is located to add proper @FindBy annotation:

Search component

As we can see at the image above, the component is located under div with cq-element-par_470004 class on it. Let's use it to implement Page Object of our page:

import com.cognifide.qa.bb.aem.AbstractPage;
import com.cognifide.qa.bb.qualifier.Frame;
import com.cognifide.qa.bb.qualifier.PageObject;

import org.openqa.selenium.support.FindBy;

@PageObject
@Frame("$cq")
public class GeoSearchPage extends AbstractPage {

  private static final String PAGE_TITLE = "Search";

  private static final String PAGE_URL = "/cf#/content/geometrixx/en/toolbar/search.html";

  @FindBy(css = ".cq-element-par_470004")
  private SearchComponent searchComponent;

  public SearchComponent getSearchComponent() {
    return searchComponent;
  }

  @Override
  public String getContentPath() {
    return PAGE_URL;
  }

  @Override
  public String getPageTitle() {
    return PAGE_TITLE;
  }

}

This is all we need to implement our test:

import com.cognifide.qa.bb.aem.AemLogin;
import com.cognifide.qa.bb.aem.dialog.classic.field.lookup.AemLookupField;
import com.cognifide.qa.bb.aem.dialog.classic.field.lookup.AemPathWindow;
import com.cognifide.qa.bb.aem.ui.AemDialog;
import com.cognifide.qa.bb.constants.Timeouts;
import com.cognifide.qa.bb.junit.Modules;
import com.cognifide.qa.bb.junit.TestRunner;
import com.cognifide.qa.bb.provider.selenium.BobcatWait;
import com.cognifide.test.GuiceModule;
import com.google.inject.Inject;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(TestRunner.class)
@Modules(GuiceModule.class)
public class SearchComponentTest {

private static final int OPENING_PAGE_TIMEOUT_IN_SECONDS = 200;

  @Inject
  private SearchPage searchPage;

  @Inject
  private AemLogin aemLogin;

  @Inject
  private BobcatWait wait;

  private AemLookupField lookupField;

  @Before
  public void before() {
    aemLogin.authorLogin();
    boolean loaded = searchPage.openPageWithRefresh(OPENING_PAGE_TIMEOUT_IN_SECONDS);
    assertTrue("page should be opened", loaded);
    lookupField = getLookupField();
  }

  @Test
  public void testSelectByPathWindowBlankPath() {
    wait.withTimeout(Timeouts.MINIMAL).until(input -> {
      AemPathWindow pathWindow = lookupField.openPathWindow();
      pathWindow.getContentTree().selectPath("Community Sites");
      return pathWindow.clickOk();
    });
  }

  private AemLookupField getLookupField() {
    SearchComponent searchComponent = searchPage.getSearchComponent();
    AemDialog dialog = searchComponent.getDialog();
    dialog.open();
    AemLookupField lookup = searchComponent.getLookupField();
    lookup.clear();
    return lookup;
  }
}

The #getLookupField() method is just collecting and returning the AemLookupField which will be a subject to configure in our test. In the test method we are selecting the "Geometrixx Gov" catalog. Why this is not a full path? Bobcat sees only what the end user can see so we need to click on something visible in the dialog window:

Pathfield Dialog

However, we can select some nested location also - "Geometrixx Media/English" will also work. If everything will go smooth the test will pass. You can extend it with your own logic if you want.

Getting started with Bobcat

  1. Getting started

AEM Related Features

  1. Authoring tutorial - Classic
  1. AEM Classic Authoring Advanced usage
  1. Authoring tutorial - Touch UI
Clone this wiki locally