Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hack for fact that comments are no longer included in cucumber json output #132

Open
msche opened this issue Dec 2, 2019 · 2 comments
Open

Comments

@msche
Copy link

msche commented Dec 2, 2019

Due to the fact that comments are no longer included in the cucumber json output the cukedoctor-discrete functionality doesn't seem to work anymore.

As a hack to solve this I abused the content-type of docstring so that i can include input and output snippets. To do this I added contentType to the DocString entity:

@JsonIgnoreProperties(ignoreUnknown = true)
public class DocString {

  private final String DISCRETE_CONTENT_TYPE = "cukedoctor-discrete";
  public final String UNKNOWN_CONTENT_TYPE = "unknown";

  private String value;

  @JsonProperty("content_type")
  private String contentType = UNKNOWN_CONTENT_TYPE;

  public String getContentType() {
    return contentType;
  }

  public String getValue() {
     return value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  public boolean discreteContent() {
    return  DISCRETE_CONTENT_TYPE.equalsIgnoreCase(getContentType());
  }
  @Override
  public String toString() {
    return value;
  }
}

and within the method renderSteps of CukedoctorStepsRenderer I added an additional check to see whether the content of docstring is discrete:

            if (notNull(step.getDocString()) && hasText(step.getDocString().getValue())) {
                if(step.hasDiscreteComment() || step.getDocString().discreteContent()){
                    //discrete comment/content renders inside a sidebar block and has [discrete] class on every line
                    renderDiscreteSidebarBlock(step.getDocString());

                } else{
                    renderListingBlock(step.getDocString());
                }
               
            }

Defining discrete content within a cucumber feature file would now become something like this:

    And 3 Deliveries `PROCESSING`
    When retrieving Provisioner overview
    """cukedoctor-discrete
include::provisioner/overview/get/http-request.adoc[Request Snippet]
    """
@tisoft
Copy link

tisoft commented Apr 8, 2020

I had the same problem, but I'm using a different solution. I have created a custom JSON formatter for cucumber, that contans the comments as before:

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import io.cucumber.core.plugin.JSONFormatter;
import io.cucumber.plugin.EventListener;
import io.cucumber.plugin.event.EventPublisher;
import io.cucumber.plugin.event.PickleStepTestStep;
import io.cucumber.plugin.event.TestSourceRead;
import io.cucumber.plugin.event.TestStepFinished;

public class CustomJSONFormatter implements EventListener {

   private final JSONFormatter jsonFormatter;

   private final Map <URI, List <String>> lines = new HashMap <> ();

   public CustomJSONFormatter (Appendable out) {
      jsonFormatter = new JSONFormatter (out);
   }

   @Override
   public void setEventPublisher (EventPublisher publisher) {
      jsonFormatter.setEventPublisher (publisher);
      publisher.registerHandlerFor (TestSourceRead.class, event -> lines.put (event.getUri (), Arrays.asList (event.getSource ().split ("\n"))));
      publisher.registerHandlerFor (TestStepFinished.class, event -> {
         if (event.getTestStep () instanceof PickleStepTestStep) {
            PickleStepTestStep testStep = (PickleStepTestStep) event.getTestStep ();
            List <Map <String, Object>> comments = new LinkedList <> ();
            for (int lineNumber = testStep.getStep ().getLine () - 1 - 1; lineNumber >= 0; lineNumber--) {
               String line = lines.get (testStep.getUri ()).get (lineNumber).trim ();
               if (line.startsWith ("#")) {
                  HashMap <String, Object> comment = new HashMap <> ();
                  comment.put ("value", line);
                  comment.put ("line", lineNumber);
                  comments.add (0, comment);
               } else if ( ! line.isEmpty ()) {
                  // no comment, we are finished
                  break;
               }
            }
            if ( ! comments.isEmpty ()) {
               getCurrentStepOrHookMap ().put ("comments", comments);
            }
         }
      });
   }

   @SuppressWarnings ("unchecked")
   private Map <String, Object> getCurrentStepOrHookMap () {
      try {
         Field currentStepOrHookMap = JSONFormatter.class.getDeclaredField ("currentStepOrHookMap");
         currentStepOrHookMap.setAccessible (true);
         return (Map <String, Object>) currentStepOrHookMap.get (jsonFormatter);
      } catch (NoSuchFieldException | IllegalAccessException e) {
         throw new IllegalStateException (e);
      }
   }
}

Tested against cucumber 5.6.0.

@rmpestano
Copy link
Owner

Ow nice, liked this formatter solution!

I need to retake this project and at least fix cucumber 2.x support issue

Thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants