xbdd.report.ReportManager.java Source code

Java tutorial

Introduction

Here is the source code for xbdd.report.ReportManager.java

Source

/**
 * Copyright (C) 2015 Orion Health (Orchestral Development 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.
 */
package xbdd.report;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.codehaus.jackson.map.JsonMappingException;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import xbdd.XbddDriver;
import xbdd.utils.JerseyClientFactory;
import xbdd.utils.XBDDInstance;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.mongodb.DBObject;

public class ReportManager {

    public static String FEATURE_LIST_ID = "featureIndex";

    public static final Function<WebElement, FeatureSummary> WEB_ELEMENT_TO_FEATURE_SUMMARY = new Function<WebElement, FeatureSummary>() {
        @Override
        public FeatureSummary apply(final WebElement featureElement) {
            final FeatureSummary summary = new FeatureSummary();
            summary.setTitle(featureElement.findElement(By.cssSelector(".feature-name")).getText());
            final String result = featureElement.getAttribute("data-status");
            summary.setResult((result) != null ? result : "undefined");
            final List<WebElement> tagElements = featureElement.findElements(By.cssSelector(".feature-tag"));
            summary.setTags(Lists.transform(tagElements, new Function<WebElement, String>() {
                @Override
                public String apply(final WebElement tagElement) {
                    return tagElement.getText();
                }
            }));

            if (!featureElement.findElements(By.cssSelector(".feature-description")).isEmpty()) {
                summary.setDescription(
                        featureElement.findElement(By.cssSelector(".feature-description")).getText());
            }
            summary.setScenarios(Lists.transform(featureElement.findElements(By.cssSelector(".scenario")),
                    WEB_ELEMENT_SCENARIO_SUMMARY));
            return summary;
        }
    };

    public static final Function<WebElement, ScenarioSummary> WEB_ELEMENT_SCENARIO_SUMMARY = new Function<WebElement, ScenarioSummary>() {
        @Override
        public ScenarioSummary apply(final WebElement element) {
            final ScenarioSummary scenarioSummary = new ScenarioSummary();
            scenarioSummary.setName(element.findElement(By.cssSelector(".scenario-name")).getText());
            scenarioSummary.setDescription(element.findElement(By.cssSelector(".scenario-description")).getText());
            scenarioSummary.setResult(element.getAttribute("data-status"));
            final List<WebElement> tagElements = element.findElements(By.cssSelector(".scenario-tag"));
            scenarioSummary.setTags(Lists.transform(tagElements, new Function<WebElement, String>() {
                @Override
                public String apply(final WebElement tagElement) {
                    return tagElement.getText();
                }
            }));
            final List<WebElement> stepElements = element.findElements(By.cssSelector(".step"));
            scenarioSummary.setSteps(Lists.transform(stepElements, new Function<WebElement, StepSummary>() {
                @Override
                public StepSummary apply(final WebElement stepElement) {
                    return new StepSummary(stepElement.getText(), stepElement.getAttribute("data-status"));
                }
            }));
            scenarioSummary
                    .setTestingTips(element.findElement(By.cssSelector(".testing-tips")).getAttribute("value"));
            scenarioSummary.setEnvironment(
                    element.findElement(By.cssSelector(".environment-notes")).getAttribute("value"));
            scenarioSummary.setExecutionNotes(
                    element.findElement(By.cssSelector(".execution-notes")).getAttribute("value"));
            return scenarioSummary;
        }
    };

    public static final Function<WebElement, StepSummary> WEB_ELEMENT_TO_STEP_SUMMARY = new Function<WebElement, StepSummary>() {

        @Override
        public StepSummary apply(final WebElement element) {
            final StepSummary step = new StepSummary();
            step.setStep(element.getText());
            step.setStatus(element.getAttribute("data-status"));
            return step;
        }
    };

    private final Client client;
    private final WebDriver webDriver;
    private final XBDDInstance xbddInstance;

    /**
     * Create a new XBDDFileHelper REST service helper which provides methods for managing report
     */
    public ReportManager(final XbddDriver webDriver, final XBDDInstance xbddInstance) {
        this.xbddInstance = xbddInstance;
        this.client = JerseyClientFactory.getInstance().createAuthenticatingClient();
        this.webDriver = webDriver;
    }

    /**
     * Load a test results JSON file to xbdd and check that the response was ok
     * 
     * @param resource The path to the resource file relative to this class' classloader
     * @param rootURL The root url for the restful service call
     * @param reportContext The context of the report
     * @throws IllegalArgumentException IOException
     */
    public void loadReport(final String resource, final String rootURL, final ReportContext reportContext)
            throws IllegalArgumentException, IOException {
        try (final InputStream is = this.getClass().getClassLoader().getResourceAsStream(resource)) {
            final Response response = this.client
                    .target(rootURL + "/rest/reports/" + reportContext.getProduct() + "/"
                            + reportContext.getMajorVersion() + "." + reportContext.getMinorVersion() + "."
                            + reportContext.getServicePackVersion() + "/" + reportContext.getBuild())
                    .request().put(Entity.entity(is, MediaType.APPLICATION_JSON));

            if (response.getStatus() != 200) {
                throw new IllegalStateException("Unexpected response code loading test result file: " + response);
            }
        }
    }

    /**
     * Retrieve a feature DBObject file to xbdd
     * 
     * @param rootURL The root url for the restful service call
     * @param reportContext The context of the report
     * @param featureId The id of the feature
     * 
     * @return the feature information
     */
    public DBObject getFeature(final String rootURL, final ReportContext reportContext, final String featureId) {
        final DBObject feature = this.client
                .target(rootURL + "/rest/feature/" + reportContext.getProduct() + "/"
                        + reportContext.getMajorVersion() + "." + reportContext.getMinorVersion() + "."
                        + reportContext.getServicePackVersion() + "/" + reportContext.getBuild() + "/" + featureId)
                .request().get(DBObject.class);
        return feature;
    }

    /**
     * Update the old feature results with the new feature results, and check that the response was ok
     * 
     * @param feature The feature
     * @param rootURL The root url for the restful service call
     * @param reportContext The context of the report
     * @throws IOException
     * @throws JsonMappingException
     * @throws IllegalArgumentException IOException
     */
    public void updateFeature(final DBObject feature, final String rootURL, final ReportContext reportContext,
            final String featureId) {
        final Response response = this.client
                .target(rootURL + "/rest/feature/" + reportContext.getProduct() + "/"
                        + reportContext.getMajorVersion() + "." + reportContext.getMinorVersion() + "."
                        + reportContext.getServicePackVersion() + "/" + reportContext.getBuild() + "/" + featureId)
                .request().put(Entity.entity(feature, MediaType.APPLICATION_JSON));

        if (response.getStatus() != 200) {
            throw new IllegalStateException("Unexpected response code loading test result file: " + response);
        }
    }

    /**
     * Open a report by navigating to its page
     * 
     * @param reportContext The context of the report
     */
    public void openReport(final ReportContext reportContext) {
        this.webDriver.navigate()
                .to(this.xbddInstance.getBaseURL() + "/reports/" + reportContext.getProduct() + "/"
                        + reportContext.getMajorVersion() + "." + reportContext.getMinorVersion() + "."
                        + reportContext.getServicePackVersion() + "/" + reportContext.getBuild());
    }

    /**
     * Open a report by navigating to its page and put the feature in context
     * 
     * @param reportContext The context of the report
     * @param feature the name of the feature
     */
    public void openFeature(final ReportContext reportContext, final String feature) {
        this.webDriver.navigate()
                .to(this.xbddInstance.getBaseURL() + "/reports/" + reportContext.getProduct() + "/"
                        + reportContext.getMajorVersion() + "." + reportContext.getMinorVersion() + "."
                        + reportContext.getServicePackVersion() + "/" + reportContext.getBuild() + "/" + feature);
    }

    /**
     * Open a openScenario from a report
     * 
     * @param reportContext The context of the report
     * @param feature The name of the feature
     * @param scenarioPathParam The part of scenario id
     * @param scenarioName The name of the scenario
     * 
     * @return the summary of the scenario
     */
    public ScenarioSummary openScenario(final ReportContext reportContext, final String feature,
            final String scenarioPathParam) {
        openFeature(reportContext, feature);
        final String id = feature + "\\;" + scenarioPathParam;
        new WebDriverWait(this.webDriver, 20)
                .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#" + id + " .scenario-name")))
                .click();

        return new WebDriverWait(this.webDriver, 20).until(new Function<WebDriver, ScenarioSummary>() {
            @Override
            public ScenarioSummary apply(final WebDriver driver) {
                return WEB_ELEMENT_SCENARIO_SUMMARY.apply(driver.findElement(By.cssSelector("#" + id)));
            }
        });
    }

    /**
     * Return the list of features from a report.
     * 
     * @return a list of {@link FeatureSummary}s. Will not be empty.
     * @throws {@link TimeoutException} if no features are found within 20 seconds.
     * */
    public List<FeatureSummary> getFeatures() {
        return new WebDriverWait(this.webDriver, 20).until(new Function<WebDriver, List<FeatureSummary>>() {
            @Override
            public List<FeatureSummary> apply(final WebDriver driver) {
                final List<WebElement> featureElements = driver.findElement(By.id(FEATURE_LIST_ID))
                        .findElements(By.cssSelector(".feature-index-entry"));
                // when the test runs really fast, it sometimes gets the element but returns an empty array
                if (featureElements.isEmpty()) {
                    return null;
                }

                return Lists.transform(featureElements, WEB_ELEMENT_TO_FEATURE_SUMMARY);
            }
        });
    }

    public FeatureSummary getFeature() {
        return new WebDriverWait(this.webDriver, 20).until(new Function<WebDriver, FeatureSummary>() {
            @Override
            public FeatureSummary apply(final WebDriver driver) {
                return WEB_ELEMENT_TO_FEATURE_SUMMARY.apply(driver.findElement(By.cssSelector(".feature")));
            }
        });
    }

    public FeatureSummary getFeatureSummary(final String summaryId) {
        return new WebDriverWait(this.webDriver, 20).until(new Function<WebDriver, FeatureSummary>() {
            @Override
            public FeatureSummary apply(final WebDriver driver) {
                return WEB_ELEMENT_TO_FEATURE_SUMMARY.apply(driver.findElement(By.id(summaryId)));
            }
        });
    }

    /**
     * update a feature DBObject
     * 
     * @param feature The jaon object form of the feature
     * @param updateMap The map includes the fields needed to be updated with the new values for the feature json object
     * 
     * @return The feature DBObject
     */
    @SuppressWarnings("unchecked")
    public DBObject updateFeatureJSONObject(final DBObject feature, final Map<String, String> updateMap) {
        final String[] namesInElements = { "testing-tips", "environment-notes", "execution-notes" };
        for (final String key : updateMap.keySet()) {
            if (Arrays.asList(namesInElements).contains(key)) {
                final List<DBObject> elements = (List<DBObject>) feature.get("elements");
                for (final DBObject scenario : elements) {
                    scenario.put(key, updateMap.get(key));
                }
            }
        }
        return feature;
    }
}