com.cognifide.qa.bb.aem.touch.pageobjects.pages.AuthorPage.java Source code

Java tutorial

Introduction

Here is the source code for com.cognifide.qa.bb.aem.touch.pageobjects.pages.AuthorPage.java

Source

/*-
 * #%L
 * Bobcat
 * %%
 * Copyright (C) 2016 Cognifide Ltd.
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */
package com.cognifide.qa.bb.aem.touch.pageobjects.pages;

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

import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.cognifide.qa.bb.qualifier.FindPageObject;
import javax.annotation.Nullable;

import org.apache.commons.lang3.StringUtils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.cognifide.qa.bb.aem.touch.data.componentconfigs.ComponentConfigs;
import com.cognifide.qa.bb.aem.touch.data.componentconfigs.ComponentConfiguration;
import com.cognifide.qa.bb.aem.touch.data.components.Components;
import com.cognifide.qa.bb.aem.touch.pageobjects.touchui.GlobalBar;
import com.cognifide.qa.bb.aem.touch.pageobjects.touchui.Parsys;
import com.cognifide.qa.bb.aem.touch.util.Conditions;
import com.cognifide.qa.bb.aem.touch.util.DataPathUtil;
import com.cognifide.qa.bb.constants.HtmlTags;
import com.cognifide.qa.bb.constants.Timeouts;
import com.cognifide.qa.bb.frame.FrameSwitcher;
import com.cognifide.qa.bb.qualifier.PageObject;
import com.cognifide.qa.bb.utils.PageObjectInjector;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.google.inject.assistedinject.AssistedInject;
import com.google.inject.name.Named;

/**
 * Represents author page.
 */
@PageObject
public class AuthorPage {

    private static final Logger LOG = LoggerFactory.getLogger(AuthorPage.class);

    private static final String EDITOR_HTML = "/editor.html";

    private static final String IS_HIDDEN = "is-hidden";

    private static final String CONTENT_FRAME = "ContentFrame";

    private final String path;

    @Inject
    private WebDriver driver;

    @Inject
    private PageObjectInjector pageObjectInjector;

    @Inject
    private FrameSwitcher frameSwitcher;

    @Inject
    private Conditions conditions;

    @Inject
    private ComponentConfigs componentConfigs;

    @Inject
    private Components components;

    @Inject
    @Named("author.url")
    private String domain;

    @Inject
    private GlobalBar globalBar;

    @FindPageObject
    private List<Parsys> parsyses;

    @FindBy(css = "#OverlayWrapper")
    private WebElement authoringOverlay;

    /**
     * Constructs AuthorPage. Sets 'path' field value. Don't call it manually. Use the factory.
     *
     * @param path path of the page.
     */
    @AssistedInject
    public AuthorPage(@Assisted String path) {
        this.path = path;
    }

    /**
     * Opens page in web driver.
     */
    public void open() {
        driver.get(domain + EDITOR_HTML + path);
    }

    /**
     * @return true if page is loaded.
     */
    public boolean isLoaded() {
        boolean isLoaded = isLoadedCondition();
        if (!isLoaded) {
            retryLoad();
        }
        return isLoaded;
    }

    /**
     * Looks for parsys by data path. If parsys is not found then throws runtime exception
     * {@link IllegalStateException}.
     *
     * @param dataPath data path of parsys.
     * @return Parsys object.
     */
    public Parsys getParsys(String dataPath) {
        String componentDataPath = DataPathUtil.normalize(dataPath);
        return parsyses.stream() //
                .filter(parsys -> StringUtils.contains(parsys.getDataPath(), componentDataPath)) //
                .findFirst() //
                .orElseThrow(() -> new IllegalStateException("Parsys not found"));
    }

    /**
     * Looks for css class of given component class and return its content.
     *
     * @param component component class.
     * @return content of component.
     */
    public <T> T getContent(Class<T> component) {
        Objects.requireNonNull(component, "clazz property was not specified in YAML config");
        globalBar.switchToPreviewMode();
        frameSwitcher.switchTo(CONTENT_FRAME);
        WebElement scope = null;
        try {
            String selector = (String) component.getField("CSS").get(null);
            scope = driver.findElement(By.cssSelector(selector));
        } catch (IllegalAccessException e) {
            LOG.error("CSS was not accessible, injecting with default scope", e);
        } catch (NoSuchFieldException e) {
            LOG.error("CSS field was not present in the page object, injecting with default scope", e);
        }
        frameSwitcher.switchBack();
        return scope == null ? pageObjectInjector.inject(component, CONTENT_FRAME)
                : pageObjectInjector.inject(component, scope, CONTENT_FRAME);
    }

    /**
     * Adds component of given name to parsys of given name on the page. Verifies if parsys is rendered.
     *
     * @param parsys name of parsys on the page.
     * @param componentName name of component.
     */
    public void addComponent(String parsys, String componentName) {
        getParsys(parsys).insertComponent(componentName);
        verifyParsysRerendered(parsys);
    }

    /**
     * Configures component in parsys with specific configuration. Verifies if parsys is rendered.
     *
     * @param parsys parsys name.
     * @param componentName component name.
     * @param configName configuration name.
     * @return Map with component configuration.
     */
    public ComponentConfiguration configureComponent(String parsys, String componentName, String configName) {
        ComponentConfiguration data = componentConfigs.getConfigs(componentName).get(configName.toLowerCase());
        if (data == null) {
            throw new IllegalArgumentException("Config does not exist: " + configName);
        }
        getParsys(parsys).configureComponent(componentName, data);
        verifyParsysRerendered(parsys);
        return data;
    }

    /**
     * Deletes component from parsys. Verifies if parsys is rendered.
     *
     * @param parsys parsys name.
     * @param componentName component name.
     */
    public void deleteComponent(String parsys, String componentName) {
        globalBar.switchToEditMode();
        getParsys(parsys).deleteComponent(componentName);
        verifyParsysRerendered(parsys);
    }

    /**
     * Remove all components with name.
     *
     * @param parsys parsys name
     * @param componentName name of the component
     */
    public void clearParsys(String parsys, String componentName) {
        globalBar.switchToEditMode();
        while (getParsys(parsys).isComponentPresent(componentName)) {
            deleteComponent(parsys, componentName);
        }
    }

    private void verifyParsysRerendered(String parsys) {
        conditions.verifyPostAjax(object -> getParsys(parsys).isNotStale());
    }

    private void retryLoad() {
        conditions.verify(new ExpectedCondition<Object>() {
            @Nullable
            @Override
            public Object apply(WebDriver driver) {
                LOG.debug("Retrying page open");
                driver.navigate().refresh();
                return isLoadedCondition();
            }
        }, Timeouts.MEDIUM);
    }

    private boolean isLoadedCondition() {
        return conditions.isConditionMet(not(ignored -> StringUtils
                .contains(authoringOverlay.getAttribute(HtmlTags.Attributes.CLASS), IS_HIDDEN)));
    }
}