Package com.crawljax.core.plugin

Source Code of com.crawljax.core.plugin.PluginsWithCrawlerTest

package com.crawljax.core.plugin;

import static org.hamcrest.core.Is.is;
import static org.hamcrest.object.IsCompatibleType.typeCompatibleWith;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import org.apache.html.dom.HTMLAnchorElementImpl;
import org.eclipse.jetty.util.BlockingArrayQueue;
import org.hamcrest.core.IsCollectionContaining;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.rules.ErrorCollector;

import com.crawljax.browser.EmbeddedBrowser;
import com.crawljax.condition.NotRegexCondition;
import com.crawljax.condition.invariant.Invariant;
import com.crawljax.core.CandidateElement;
import com.crawljax.core.CrawlSession;
import com.crawljax.core.CrawlerContext;
import com.crawljax.core.CrawljaxRunner;
import com.crawljax.core.ExitNotifier.ExitStatus;
import com.crawljax.core.configuration.CrawljaxConfiguration;
import com.crawljax.core.configuration.CrawljaxConfiguration.CrawljaxConfigurationBuilder;
import com.crawljax.core.state.Eventable;
import com.crawljax.core.state.StateVertex;
import com.crawljax.test.BrowserTest;
import com.crawljax.test.RunWithWebServer;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

/**
* Test cases to test the running and correct functioning of the plugins. Used to address issue #26
*/
@Category(BrowserTest.class)
public class PluginsWithCrawlerTest {

  private static CrawljaxRunner controller;
  private static CrawljaxConfiguration config;
  private static String listAsString;

  private static List<Class<? extends Plugin>> plugins = new BlockingArrayQueue<>();

  @ClassRule
  public static final RunWithWebServer SERVER = new RunWithWebServer("/site");

  @ClassRule
  public static final ErrorCollector ERRORS = new ErrorCollector();

  private static CrawlSession session;

  @BeforeClass
  public static void setup() {
    CrawljaxConfigurationBuilder builder = SERVER.newConfigBuilder("/crawler/");

    builder.crawlRules().clickDefaultElements();

    /**
     * Add a sample Invariant for testing the OnInvariantViolation plugin
     */
    builder.crawlRules().addInvariant("Never contain Final state S8",
            new NotRegexCondition("Final state S2"));

    builder.addPlugin(new PreCrawlingPlugin() {

      @Override
      public void preCrawling(CrawljaxConfiguration config) {
        plugins.add(PreCrawlingPlugin.class);

      }
    });

    builder.addPlugin(new OnNewStatePlugin() {
      @Override
      public void onNewState(CrawlerContext context, StateVertex state) {
        plugins.add(OnNewStatePlugin.class);

        if (!state.getName().equals("index")) {
          assertTrue("currentState and indexState are never the same",
                  !state.equals(context.getSession().getInitialState()));
        }
      }
    });

    builder.addPlugin(new DomChangeNotifierPlugin() {

      @Override
      public boolean isDomChanged(CrawlerContext context, String domBefore, Eventable e,
              String domAfter) {

        plugins.add(DomChangeNotifierPlugin.class);
        return !domAfter.equals(domBefore);

      }

    });

    builder.addPlugin(new OnBrowserCreatedPlugin() {

      @Override
      public void onBrowserCreated(EmbeddedBrowser newBrowser) {
        plugins.add(OnBrowserCreatedPlugin.class);
        assertNotNull(newBrowser);
      }
    });

    builder.addPlugin(new OnInvariantViolationPlugin() {

      @Override
      public void onInvariantViolation(Invariant invariant, CrawlerContext context) {
        plugins.add(OnInvariantViolationPlugin.class);

        assertNotNull(invariant);

      }
    });

    builder.addPlugin(new OnUrlLoadPlugin() {

      @Override
      public void onUrlLoad(CrawlerContext browser) {
        plugins.add(OnUrlLoadPlugin.class);
        assertNotNull(browser);
      }
    });

    builder.addPlugin(new PostCrawlingPlugin() {

      @Override
      public void postCrawling(CrawlSession session, ExitStatus status) {
        plugins.add(PostCrawlingPlugin.class);

      }
    });

    builder.addPlugin(new PreStateCrawlingPlugin() {

      @Override
      public void preStateCrawling(CrawlerContext session,
              ImmutableList<CandidateElement> candidateElements, StateVertex state) {
        plugins.add(PreStateCrawlingPlugin.class);
        try {
          assertNotNull(candidateElements);

        } catch (AssertionError e) {
          ERRORS.addError(e);
        }

        if (state.getName().equals("state8")) {
          /**
           * Add to miss invocation for the OnFireEventFaild plugin.
           */
          // This is a bit ugly; but hey it works, and is checked above..
          CandidateElement candidate = candidateElements.get(0);
          HTMLAnchorElementImpl impl = (HTMLAnchorElementImpl) candidate.getElement();
          impl.setName("fail");
          impl.setId("eventually");
          impl.setHref("will");
          impl.setTextContent("This");
          candidate.getIdentification().setValue("/HTML[1]/BODY[1]/FAILED[1]/A[1]");
        }
      }

    });

    builder.addPlugin(new OnRevisitStatePlugin() {

      @Override
      public void onRevisitState(CrawlerContext session, StateVertex currentState) {
        plugins.add(OnRevisitStatePlugin.class);

        assertNotNull(currentState);
      }
    });

    config = builder.build();
    controller = new CrawljaxRunner(config);
    session = controller.call();

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < plugins.size(); i++) {
      Class<? extends Plugin> plugin = plugins.get(i);
      sb.append('\n').append(i).append(' ').append(plugin.getSimpleName());
    }
    listAsString = sb.toString();
  }

  @Test
  public void whenCrawlStartsInitialPluginsAreRun() {
    assertThat(plugins.get(0), typeCompatibleWith(PreCrawlingPlugin.class));
    assertThat(plugins.get(1), typeCompatibleWith(OnBrowserCreatedPlugin.class));
    assertThat(plugins.get(2), typeCompatibleWith(OnUrlLoadPlugin.class));
  }

  @Test
  public void whenCrawlFinishesTheLastPluginIsTheOverviewPlugin() {
    assertThat(plugins.get(plugins.size() - 1), typeCompatibleWith(PostCrawlingPlugin.class));
  }

  @Test
  public void verifyOnUrlLoadFollowers() {
    afterFirstPluginsIsFollowedBy(OnUrlLoadPlugin.class, ImmutableSet.of(
            OnInvariantViolationPlugin.class, OnNewStatePlugin.class,
            DomChangeNotifierPlugin.class, OnRevisitStatePlugin.class,
            PostCrawlingPlugin.class));
  }

  private void afterFirstPluginsIsFollowedBy(Class<OnUrlLoadPlugin> suspect,
          Iterable<Class<? extends Plugin>> followedBy) {
    List<Integer> indexes = indexesOf(suspect);
    if (indexes.size() > 0) {
      indexes.remove(0);
    }
    for (int index : indexes) {
      Class<? extends Plugin> follower = plugins.get(index + 1);
      assertThat(suspect + " @index=" + index + " was followed by " + follower
              + listAsString, followedBy, IsCollectionContaining.hasItem(follower));
    }
  }

  public void pluginsIsFollowedBy(Class<? extends Plugin> suspect,
          Iterable<Class<? extends Plugin>> followedBy) {
    for (int index : indexesOf(suspect)) {
      Class<? extends Plugin> follower = plugins.get(index + 1);
      assertThat(suspect + " @index=" + index + " was followed by " + follower
              + listAsString, followedBy, IsCollectionContaining.hasItem(follower));
    }
  }

  private List<Integer> indexesOf(Class<? extends Plugin> clasz) {
    List<Integer> indexes = new ArrayList<>();
    for (int i = 0; i < plugins.size(); i++) {
      if (plugins.get(i).isAssignableFrom(clasz)) {
        indexes.add(i);
      }
    }
    return indexes;
  }

  @Test
  public void verifyOnNewStateFollowers() {
    pluginsIsFollowedBy(OnNewStatePlugin.class,
            ImmutableSet.of(PreStateCrawlingPlugin.class, OnUrlLoadPlugin.class,
                    PostCrawlingPlugin.class));
  }

  @Test
  public void verifyPreStateCrawlingFollowers() {
    pluginsIsFollowedBy(PreStateCrawlingPlugin.class,
            ImmutableSet.of(DomChangeNotifierPlugin.class, OnFireEventFailedPlugin.class,
                    OnInvariantViolationPlugin.class, OnNewStatePlugin.class,
                    OnUrlLoadPlugin.class));
  }

  @Test
  public void onRevisitStatesFollowers() {
    pluginsIsFollowedBy(OnRevisitStatePlugin.class, ImmutableSet.of(
            OnFireEventFailedPlugin.class, DomChangeNotifierPlugin.class,
            OnInvariantViolationPlugin.class, OnNewStatePlugin.class));
  }

  @Test
  public void verifyOnDomChangedFollowers() {
    pluginsIsFollowedBy(DomChangeNotifierPlugin.class, ImmutableSet.of(
            OnFireEventFailedPlugin.class, DomChangeNotifierPlugin.class,
            OnInvariantViolationPlugin.class, OnNewStatePlugin.class,
            PostCrawlingPlugin.class));
  }

  @Test
  public void startAndEndPluginsAreOnlyRunOnce() {
    // assertThat(orrurencesOf(ProxyServerPlugin.class), is(1));
    assertThat(orrurencesOf(PreCrawlingPlugin.class), is(1));
    assertThat(orrurencesOf(PostCrawlingPlugin.class), is(1));
  }

  @Test
  public void domStatesChangesAreEqualToNumberOfStatesAfterIndex() {
    int numberOfStates = session.getStateFlowGraph().getAllStates().size();
    int newStatesAfterIndexPage = numberOfStates - 1;
    assertThat(orrurencesOf(DomChangeNotifierPlugin.class), is(newStatesAfterIndexPage));
  }

  @Test
  public void newStatePluginCallsAreEqualToNumberOfStates() {
    int numberOfStates = session.getStateFlowGraph().getAllStates().size();
    assertThat(orrurencesOf(OnNewStatePlugin.class), is(numberOfStates));
  }

  private int orrurencesOf(Class<? extends Plugin> clasz) {
    int count = 0;
    for (Class<? extends Plugin> plugin : plugins) {
      if (plugin.isAssignableFrom(clasz)) {
        count++;
      }
    }
    return count;
  }
}
TOP

Related Classes of com.crawljax.core.plugin.PluginsWithCrawlerTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.