Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/rmpestano/cukedoctor

BDD living documentation using Cucumber and Asciidoctor: https://goo.gl/Yp3NiU
https://github.com/rmpestano/cukedoctor

Last synced: about 1 month ago
JSON representation

BDD living documentation using Cucumber and Asciidoctor: https://goo.gl/Yp3NiU

Awesome Lists containing this project

README

        

= Cukedoctor
:page-layout: base
:toc: preamble
:source-language: java
:icons: font
:linkattrs:
:sectanchors:
:sectlink:
:numbered:
:imagesdir: img
:doctype: book
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:

[quote]
____
Enabling Behaviour driven documentation!
____

image:https://github.com/rmpestano/cukedoctor/actions/workflows/ci.yml/badge.svg[Build Status, link=https://github.com/rmpestano/cukedocor/actions/workflows/ci.yml]
image:https://coveralls.io/repos/rmpestano/cukedoctor/badge.svg?branch=master&service=github[Coverage, link=https://coveralls.io/r/rmpestano/cukedoctor]
image:https://maven-badges.herokuapp.com/maven-central/com.github.cukedoctor/cukedoctor/badge.svg["Maven Central",link="http://search.maven.org/#search|ga|1|cukedoctor"]
image:https://sonarcloud.io/api/project_badges/measure?project=com.github.cukedoctor:cukedoctor&metric=alert_status["Sonar", link="https://sonarcloud.io/dashboard?id=com.github.cukedoctor%3Acukedoctor"]

BDD living documentation using http://cukes.info/[Cucumber] and http://asciidoctor.org[Asciidoctor] based on Cucumber http://www.relishapp.com/cucumber/cucumber/docs/formatters/json-output-formatter[JSON execution output].

[.text-right]
https://goo.gl/Yp3NiU[Read this page in asciidoc for better reading experience]

== Narrative

[quote]
____
In order to have awesome *living documentation* +
As a bdd developer +
I want to convert my test results into http://asciidoctor.org/docs/what-is-asciidoc/[Asciidoc format^].
____

== Story

****
[big]#*GIVEN*# I execute my cucumber tests using the json formatter

[BIG]#*AND*# cucumber json output files are generated

[big]#*WHEN*# I convert the files using Cukedoctor

[big]#*THEN*# I should have awesome _living_ documentation based on asciidoc.
****

== Sample

image:cukedoctor-sample.png[]

The feature file for the above sample can be https://github.com/database-rider/database-rider/blob/master/rider-core/src/test/resources/features/seeding/seeding-database.feature#L2[found here^].

Failing steps are rendered as follows:

image:cukedoctor-sample-with-error.png[]

== Cukedoctor Living Documentation

As a proof of concept, https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-converter/src/test/java/com/github/cukedoctor/bdd/cukedoctor[Cukedoctor bdd tests^] output are rendered by _itself_:

* http://rmpestano.github.io/cukedoctor/cukedoctor-documentation.html?theme=foundation[Cukedoctor documentation html^]
* http://rmpestano.github.io/cukedoctor/cukedoctor-documentation.pdf[Cukedoctor documentation pdf^]
* http://rmpestano.github.io/cukedoctor/cukedoctor/default/cukedoctor.html[Default cucumber formatter html^]

NOTE: This documentation is published to gh-pages by travisci on each successful build.

== Other Documentation Examples

Here are some bdd documentation examples generated by Cukedoctor:

[cols="1v,1v,lv"]
|===
|Project | Living documentation

|https://github.com/database-rider/databae-rider[Database Rider^]
|https://database-rider.github.io/database-rider/latest/documentation.html?theme=foundation[html^] / https://database-rider.github.io/database-rider/latest/documentation.pdf[pdf^]

|https://github.com/asciidoctor/asciidoctor[Asciidoctor^]
|http://rmpestano.github.io/cukedoctor/asciidoctor/asciidoctor-documentation.html[html^] / http://rmpestano.github.io/cukedoctor/asciidoctor/asciidoctor-documentation.pdf[pdf^]

|https://github.com/cucumber[Cucumber (Ruby)^]
|http://rmpestano.github.io/cukedoctor/cucumber/cucumber-documentation.html[html^] / http://rmpestano.github.io/cukedoctor/cucumber/cucumber-documentation.pdf[pdf^]

|https://github.com/cucumber/cucumber-js[Cucumber JS^]
|http://rmpestano.github.io/cukedoctor/cucumber-js/cucumber-js-documentation.html[html^] / http://rmpestano.github.io/cukedoctor/cucumber-js/cucumber-js-documentation.pdf[pdf^]

|https://github.com/jekyll/jekyll[Jekyll^]
|http://rmpestano.github.io/cukedoctor/jekyll/jekyll-documentation.html[html^] / http://rmpestano.github.io/cukedoctor/jekyll/jekyll-documentation.pdf[pdf^]

|https://github.com/sdkman/sdkman-cli[Sdkman^]
|http://rmpestano.github.io/cukedoctor/sdkman/sdkman-documentation.html[html^] / http://rmpestano.github.io/cukedoctor/sdkman/sdkman-documentation.pdf[pdf^]

|===

== Cukedoctor Converter

Cukedoctor converter is the basis for other modules, it generates asciidoc files based on Cucumber json execution files.

=== Usage

Just declare the converter in your _pom.xml_:

[source, xml]
----

com.github.cukedoctor
cukedoctor-converter
3.7.0

----

=== Example

[source, java]
----
@Test
public void shouldSaveDocumentationIntoDisk(){
List pathToCucumberJsonFiles = FileUtil.findJsonFiles("target/test-classes/json-output/");
List features = FeatureParser.parse(pathToCucumberJsonFiles);
DocumentAttributes attrs = GlobalConfig.getInstance().getDocumentAttributes;
attrs.toc("left").backend("html5")
.docType("book")
.icons("font")
.sourceHighlighter("coderay")
.docTitle("Documentation Title")
.sectAnchors(true).sectLink(true);

CukedoctorConverter converter = Cukedoctor.instance(features, attrs);
converter.setFilename("target/living_documentation.adoc");

converter.saveDocumentation();
assertThat(FileUtil.loadFile("target/living_documentation.adoc")).exists();
}
----

[IMPORTANT]
======
To generate cucumber .json output files just execute your _BDD_ tests with *json* formatter, example:

[source,java]
----
@RunWith(Cucumber.class)
@CucumberOptions(plugin = {"json:target/cucumber.json"} )
----

======

=== Introduction Chapter

You can add a custom introduction chapter to your living documentations by placing a file named *cukedoctor-intro.adoc* anywhere on your classpath.

The content of the file will be placed between Documentation title and summary section. Here's an example of cukedoctor-intro.adoc:

----
= *This is a sample introduction chapter*

Introduction chapter is the place where you can insert custom content for your living documentation.

=== Sub section
Introduction chapter can have subsections
----

Here is rendered documentation:

image:cukedoctor-intro.png[]

=== Internationalization

Cukedoctor can use internationalization in two flavours:

==== Reading features

Cucumber feature languages are provided via comments in a feature file, https://github.com/cucumber/cucumber/wiki/Spoken-languages[see here^] for examples.

Another way of setting the language is by using the `@language-` tag:

.i18n.feature.tag
----
@language-fr
Fonctionnalité: Calculateur

Scénario: Addition de nombres

----

where `` can be one of the supported locales, *en*, *es*, *fr*, *ge* and *pt*.

WARNING: Please notice that the tag `@language-` is not part of Cucumber.
Meaning that you still need to setup Cucumber for i18n. the `@language-` tag is part of Cukedoctor and serves as a
convenient replacement for the `# language: ` comment, which is not supported anymore by Cucumber in JSON files.

If your feature language is *not* supported by Cukedoctor you can https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-converter/src/main/resources/i18n[contribute it here^] or use a custom bundle.

==== Custom resource bundle

Another way of internationalization is to provide a custom bundle.

If you do so Cukedoctor will ignore feature language and will use provided resource bundle.

The name of the file must be *cukedoctor.properties* and can be anywhere in your classpath.

Here are the key values you must provide to customize your documentation:

----
#sections
title.features = Features
title.summary = Summary
title.scenario = Scenario

#summary
summary.steps = Steps
summary.total = Totals
summary.duration = Duration

#result
result.passed = Passed
result.failed = Failed
result.skipped = Skipped
result.pending = Pending
result.undefined= Undefined
result.missing = Missing

----

==== Supported locales

Cukedoctor currently supports the following locales *en*, *es*, *fr*, *ge* and *pt*.

Here are the https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-converter/src/main/resources[supported locales^]

=== Skip features

In order to ignore features and not process them in generated documentation you can use `@skipDocs tag`:

.ignored.feature
----
@skipDocs
Feature: Calculator

Scenario: Adding numbers
----

=== Feature ordering

To change the order features will be rendered in living documentation you can add an `order comment` in cucumber-jvm 1.x only:

.ordered.feature.comment
----
# order: 1
Feature: Calculator

Scenario: Adding numbers

----

Or in cucumber-jvm 2.x and later, with an `order tag`:

.ordered.feature.tag
----
@order-1
Feature: Calculator

Scenario: Adding numbers

----

=== Enriching documentation

==== Asciidoc markup in comments

To enrich the documentation one can use asciidoc markup inside Cucumber feature files, consider the following feature:

.feature without enrichment
----
Feature: Calculator

Scenario: Adding numbers
You can asciidoc markup in feature description.

Given I have numbers 1 and 2
When I sum the numbers
Then I should have 3 as result
----

It will be rendered by Cukedoctor as follows:

image::no-enrich.png[]

Now if you want to enrich your _living_ documentation you can use asciidoc syntax in your feature:

.enriched feature
----
Feature: Calculator

Scenario: Adding numbers
You can use *asciidoc markup* in _feature_ #description#.

NOTE: This is a very important feature!

#{IMPORTANT: Asciidoc markup inside *steps* must be surrounded by *curly brackets*.}
Given I have numbers 1 and 2

# {NOTE: Steps comments are placed *before* each steps so this comment is for the *WHEN* step.}

When I sum the numbers

# {* this is a list of itens inside a feature step}
# {* there is no multiline comment in gherkin}
# {** second level list item}
Then I should have 3 as result
----

And it will be rendered as follows:

image::enrich.png[]

IMPORTANT: Step comments are only supported by *Cucumber-jvm 1.x*

==== Asciidoc markup in DocStrings

You can use Asciidoc markup in https://www.relishapp.com/cucumber/cucumber/docs/gherkin/doc-strings[feature DocStrings].
The Features below show the different ways of achieving this:

* Step comment `#cukedoctor-discrete` (*cucumber-jvm 1.x* only)
** Applies to all DocStrings in the commented step
* Content type `asciidoc`
** Must be applied to each DocString you wish to be enriched
* Feature tag `@asciidoc`
** Applies to all DocStrings in the tagged feature
* Scenario tag `@asciidoc`
** Applies to all DocStrings in the tagged scenario

----
Feature: Discrete class feature with step comment

Scenario: Render source code

# cukedoctor-discrete
Given the following source code
"""
[source, java]
-----
public int sum(int x, int y){
int result = x + y;
return result; <1>
}
-----
<1> We can have callouts in living documentation
"""

Scenario: Render table

# cukedoctor-discrete
Given the following table
"""
|====

| Cell in column 1, row 1 | Cell in column 2, row 1
| Cell in column 1, row 2 | Cell in column 2, row 2
| Cell in column 1, row 3 | Cell in column 2, row 3

|====
"""

Feature: Discrete class feature with content type

Scenario: Render source code

Given the following source code
"""asciidoc
[source, java]
-----
public int sum(int x, int y){
int result = x + y;
return result; <1>
}
-----
<1> We can have callouts in living documentation
"""

Scenario: Render table

Given the following table
"""asciidoc
|====

| Cell in column 1, row 1 | Cell in column 2, row 1
| Cell in column 1, row 2 | Cell in column 2, row 2
| Cell in column 1, row 3 | Cell in column 2, row 3

|====
"""

@asciidoc
Feature: Discrete class feature with feature tag

Scenario: Render source code

Given the following source code
"""
[source, java]
-----
public int sum(int x, int y){
int result = x + y;
return result; <1>
}
-----
<1> We can have callouts in living documentation
"""

Scenario: Render table

Given the following table
"""
|====

| Cell in column 1, row 1 | Cell in column 2, row 1
| Cell in column 1, row 2 | Cell in column 2, row 2
| Cell in column 1, row 3 | Cell in column 2, row 3

|====
"""

Feature: Discrete class feature with scenario tag

@asciidoc
Scenario: Render source code

Given the following source code
"""
[source, java]
-----
public int sum(int x, int y){
int result = x + y;
return result; <1>
}
-----
<1> We can have callouts in living documentation
"""

@asciidoc
Scenario: Render table

Given the following table
"""
|====

| Cell in column 1, row 1 | Cell in column 2, row 1
| Cell in column 1, row 2 | Cell in column 2, row 2
| Cell in column 1, row 3 | Cell in column 2, row 3

|====
"""
----

The docstrings will be rendered as follows:

image::discrete.png[]

IMPORTANT: By default Cukedoctor will render DocStrings as http://asciidoctor.org/docs/user-manual/\#listing-blocks[asciidoc listing^]. Use the above mechanism to enable this feature.

=== *"Stepless"* documentation

Imagine you don't want to automate a feature (because e.g you don't have time) or you simple don't like the *Given* *When* *Then* BDD way of describing features.

You still can write the hole feature documentation (`using asciidoc`) in `feature and scenario description` without writing any cucumber step.

Here is an https://github.com/database-rider/database-rider/blob/4b12ebf6303c8866101d5bc078e62f5b0855d04a/rider-core/src/test/resources/features/export/dataset-export.feature#L2[example feature^] and https://database-rider.github.io/database-rider/latest/documentation.html#DataSet-export[resulting documentation^].

NOTE: Not automated doesn't mean you didn't discussed the feature and it's scenarios.

=== Customizing your Living Documentation

There are two ways to customize Cukedoctor generated documentation. The first one is via `custom css` and `custom pdf theme`, the second one is via `Cukedoctor SPI`.

==== Custom css and pdf theme

You can provide a `custom css` by creating a file named *cukedoctor.css*, so for example you can override default style using css selectors:

.src/test/resources/cukedoctor.css
----
body #toctitle {
color: green;
}

body.book {
background: #444;
}
----

By default Cukedoctor will search (recursively) for the custom css in current directory but you can provide any path via system property named `CUKEDOCTOR_CUSTOMIZATION_DIR`.

PDF customization works the same way, if Cukedoctor finds a file named *cukedoctor-pdf.yml* it will apply the theme. By default Cukedoctor will search (recursively) for the custom pdf theme in current directory but you can provide any path via system property named `CUKEDOCTOR_CUSTOMIZATION_DIR`.

NOTE: Use https://github.com/asciidoctor/asciidoctor-pdf/blob/master/docs/theming-guide.adoc[Asciidoctor PDF theming guide^] as reference for creating your custom theme.

==== Cukedoctor SPI

Cukedoctor SPI is backed by https://docs.oracle.com/javase/tutorial/ext/basics/spi.html[Java service provider] mechanism. You just need to implement one of the interfaces in https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-converter/src/main/java/com/github/cukedoctor/spi[Cukedoctor SPI] and declare it in META-INF/services. See https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-spi-example[Cukedoctor-spi-example^] for full example code

==== Example

Given this cucumber feature:

----
Feature: Calculator

Scenario: Adding numbers

Given I have numbers 1 and 2
When I sum the numbers
Then I should have 3 as result

Scenario: Subtracting numbers
A feature with a failing step

Given I have numbers 2 and 1
When I subtract the numbers
Then I should have 0 as result

----

When we generate documentation using *default* cukedoctor renderers we got the following result:

image::calc-original-output.png[]

===== Customizing the summary section

To customize summary one have to implement https://github.com/rmpestano/cukedoctor/blob/master/cukedoctor-converter/src/main/java/com/github/cukedoctor/spi/SummaryRenderer.java[SummaryRenderer interface]. Here is an example:

[source,java]
----
public class CustomSummaryRenderer extends AbstractBaseRenderer implements SummaryRenderer {

@Override
public String renderSummary(List features) {
docBuilder.textLine(H2(bold(i18n.getMessage("title.summary"))));
docBuilder.textLine("This is a custom summary renderer").newLine();
docBuilder.textLine("Number of features: "+features.size());
docBuilder.newLine();
ScenarioTotalizations totalization = new ScenarioTotalizations(features);
docBuilder.append("Passed steps: ",totalization.getTotalPassedSteps(),newLine())
.append(newLine()).append("Failed steps: ", totalization.getTotalFailedSteps(),newLine());
return docBuilder.toString();
}
}
----

NOTE: Abstract renderer is a template class which provides implementation of helper methods.

Now Imagine we want to render features as http://asciidoctor.org/docs/user-manual/#labeled-list[Asciidoctor labeled lists] instead of sections, see prototype below:

image::custom-feature-renderer.png[]

To do that you need to implement *FeatureRenderer* and also *ScenarioRenderer*.

[source,java]
----
public class CustomFeatureRenderer extends CukedoctorFeatureRenderer {<1>

@Override
public String renderFeature(Feature feature) {
docBuilder.textLine((bold(feature.getName()))+"::").newLine();
if (hasText(feature.getDescription())) {
docBuilder.append("+").sideBarBlock(feature.getDescription().trim().replaceAll("\\n", " +" + newLine()));
}

if(feature.hasScenarios()){

ScenarioRenderer scenarioRenderer = new CustomScenarioRenderer();
for (Scenario scenario : feature.getScenarios()) {
docBuilder.append(scenarioRenderer.renderScenario(scenario,feature));<2>
}
}

return docBuilder.toString();
}
}
----

<1> You can also extend default renderers as above.
<2> Here we provide a custom ScenarioRenderer but you could embed all markup in FeatureRenderer if you want but depending on complexity things can get messy.

And finally here is the custom ScenarioRenderer:

[source,java]
----
public class CustomScenarioRenderer extends CukedoctorScenarioRenderer{

@Override
public String renderScenario(Scenario scenario, Feature feature) {
//need to clear because we will execute this method in a for loop
//and contents will be appended
docBuilder.clear();
docBuilder.append(" "+scenario.getName()+":::",newLine());
if(scenario.hasSteps()) {
//here we will reuse builtin step renderer
docBuilder.textLine("+");
StepsRenderer stepsRenderer = new CukedoctorStepsRenderer();<1>
docBuilder.append(stepsRenderer.renderSteps(scenario.getSteps()));
}
return docBuilder.toString();
}
}
----
<1> Here we leverage default StepsRenderer that comes with Cukedoctor.

Now the output of our *customized living documentation*:

image::calc-custom-output.png[]

IMPORTANT: Don't forget to register your custom implementations in https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-spi-example/src/main/resources/META-INF/services[META-INF/services] directory.

== Section Layout

An optional, alternative layout is available; the "Section" layout.
This allows you to organise your features in to Sections and Subsections.
Sections can be shown in the main body of the document, or as appendices.
You can also specify a glossary, bibliography and index.

A detailed description with examples is available in the documentation https://rmpestano.github.io/cukedoctor/#cukedoctor-with-section[here].

Feature files for the example above can be https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-section-layout/src/test/java/com/github/cukedoctor/sectionlayout[found here].

== Maven plugin

This module brings the ability to execute Cukedoctor converter through a maven plugin.

The plugin just scans *.json* cucumber execution files in _target_ dir and generates asciidoc documentation on _target/cukedoctor_ folder.

=== Usage

Just declare the plugin in your _pom.xml_:

[source, xml]
----

com.github.cukedoctor
cukedoctor-maven-plugin
3.7.0



execute

install <1>

----
<1> You need to use a phase that runs after your tests, see https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html[maven lifecycle].

[IMPORTANT]
======
To generate cucumber .json output files just execute your tests with *json* formatter, example:

[source,java]
----
@RunWith(Cucumber.class)
@CucumberOptions(plugin = {"json:target/cucumber.json"} )
----
NOTE: *plugin* option replaced *format* option which was deprecated in newer cucumber versions.

======

=== Example of configuration

[source, xml]
----

com.github.cukedoctor
cukedoctor-maven-plugin
3.7.0

documentation <1>
docs <2>
pdf <3>
left <4>
true <5>
${project.version} <6>




execute

verify

----
<1> documentation filename
<2> directory name (relative to /target) to generate documetation (default is _cukedoctor_)
<3> document format, default is html5
<4> table of content position, default is right
<5> section numbering, default is false
<6> documentation version (http://asciidoctor.org/docs/user-manual/#revision-number-date-and-remark[asciidoctor revNumber^])

[NOTE]
======
You can also execute the plugin without building the project but make sure you already have cucumber json files in build dir.

----
mvn cukedoctor:execute
----
======

=== Configuration options

.Supported plugin configuration
[cols="1m,3,1"]
|====
|Name |Description | Default

|outputFileName
|Generated documentation file name
|documentation

|outputDir
|Directory of where documentation will be saved
|${buildDir}/cukedoctor

|documentTitle
|Documentation title (first section)
|Living Documentation

|format
|Generated documetation format. Possible values: pdf, html, all
|html

|docVersion
|Documentarion version
|

|sourceHighlighter
|highlighter for source code rendering
|highlightjs (coderay is also supported)

|toc
|Table of contents position
|right

|numbered
|Section numbering
|true

|allowUriRead
|Allow include content be referenced by an URI.
|false

|featuresDir
|Directory to start searching (recursively) for cucumber json output
|project root directory

|disableFilter
|When present, this flag disables features filtering
|

|disableMinimizable
|When present, this flag disables minimizable feature sections
|

|disableTheme
|When present, this flag disables theme support
|

|hideSummarySection
|When present, this flag hides `Summary` section
|

|hideFeaturesSection
|When present, this flag hides `Features` section
|

|hideScenarioKeyword
|When present, this flag `Scenario` (and `scenario outline`) keyword which prefixes each scenario;
|

|hideStepTime
|When present, this flag hides `step time` calculation on each step;
|

|hideTags
|When present, this flag hides `tags` rendering
|

|stem
|When present, sets the asciidoc stem attribute to the specified interpreter e.g. `latexmath`
|

|dataUri
|When present, sets the AsciiDoc 'data-uri' attribute which causes all images to be embedded in HTML output as https://docs.asciidoctor.org/asciidoctor/latest/html-backend/manage-images/[data URIs]
|

|====

=== Disable extensions

You can disable https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-extension#disable-extensions[Cukedoctor extensions^] using the following configuration in maven plugin:

[source,xml]
----

documentation <1>
docs
all
left <4>
true
true
true
true

----

NOTE: The value doesn't matter, if there is something in the attribute the extension will be disabled

== Standalone jar (a.k.a *cli*)

This module brings the ability to execute cukedoctor converter as a Java main application (using command line: *java -jar*).

To use Cukedoctor as a standalone jar you can https://search.maven.org/remotecontent?filepath=com/github/cukedoctor/cukedoctor-main/3.7.0/cukedoctor-main-3.7.0.jar[download it here^].

=== Usage

This module converts generated adoc files into html and pdf, here's an example:

[source, java]
----
@Test
public void shouldRenderHtmlForOneFeature(){
CukedoctorMain main = new CukedoctorMain();
main.execute(new String[]{
"-o", "\"target/document-one\"", <1>
"-p", "\"target/test-classes/json-output/one_passing_one_failing.json\"", <2>
"-t", "Living Documentation", <3>
"-f", "html", <4>
"-toc", "left", <5>
"-numbered", <6>
"-sourceHighlighter", "coderay" <7>
});

File generatedFile = FileUtil.loadFile("target/document-one.html");
assertThat(generatedFile).exists();
}
----
<1> output file name (default is 'documentation')
<2> path to cucumber json files or directory (default is current dir - the search is recursive)
<3> Document title (default is 'Living Documentation')
<4> document format (Default is html)
<5> table of contents position (Default is right)
<6> Section numbering (Default is false). Note that for boolean values you must not pass the value, only parameter name is required
<7> Source highlighter (Default is highlightjs)

==== Command line

Using in command line, the above test should be something like:

----
java -jar cukedoctor-main.jar
-o "target/document-one"
-p "target/test-classes/json-output/one_passing_one_failing.json"
-t "Living Documentation"
-f html
-numbered
-hideSummarySection
-hideScenarioKeyword
----

[TIP]
======
you can just use:

----
java -jar cukedoctor-main.jar
----

and rely on default parameters which are:

* f: html5
* p: current directory
* t: Living Documentation
* o: Living-Documentation

======

==== Maven exec plugin

You can use maven exec plugin, see example:

----

org.codehaus.mojo
exec-maven-plugin
1.4.0

java

-classpath

com.github.cukedoctor.cukedoctorMain

----

IMPORTANT: cukedoctor-main must be on your classpath

To invoke Cukedoctor just use:

----
mvn exec:exec
----

It will run with default args. To provide arguments, in this approach, you'll have a bit more work: http://stackoverflow.com/questions/15013651/using-maven-execexec-with-arguments[see here].

=== Disable extensions

You can disable https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-extension#disable-extensions[cukedoctor extensions^] by using _-D_ option when executing Cukedoctor main at command line:

----
java -jar -Dcukedoctor.disable.filter=123 -Dcukedoctor.disable.theme=abc
cukedoctor-main-3.7.0.jar
-p cucumber-output.json
----

IMPORTANT: `-D` args must be declared *before* cukedoctor-main-3.7.0.jar otherwise they will be used as parameters for Cukedoctor and won't be recognized.

You can download Cukedoctor main https://search.maven.org/remotecontent?filepath=com/github/cukedoctor/cukedoctor-main/3.7.0/cukedoctor-main-3.7.0.jar[jar here^]

=== Layout configuration

Some pieces of documentation can be hidden via configuration.

You can hide `Features` and `Summary` sections, as well as `scenario keyword` which prefixes each scenario and hide `tags` or `step time`. To do so just specify the following arg parameters respectively:

----
java -jar -Dcukedoctor.disable.filter=123 -Dcukedoctor.disable.theme=abc
cukedoctor-main-3.7.0.jar
-p cucumber-output.json
-hideFeaturesSection <1>
-hideSummarySection <2>
-hideScenarioKeyword <3>
-hideStepTime <4>
-hideTags <5>
----
<1> Removes `Features` section so each feature is a section instead of a sub section of `Features`;
<2> Removes summary section
<3> Removes `scenario` keyword which prefixes each scenario;
<4> Removes step time calculation on each step;
<5> Removes tags rendering;

=== Custom css and pdf theme

In order to customize generated documentation you can provide <>. To do so you can provide cukedoctor.css and cukedoctor-pdf.yml in a directory, for example `/home/custom` and then pass it as system properties to cukedoctor:

----
java -jar -D CUKEDOCTOR_CUSTOMIZATION_DIR=/home/custom
cukedoctor-main-3.7.0.jar

----

NOTE: By default Cukedoctor will use current directory to search for custom css and pdf theme.

== Extension

Cukedoctor extension adds new features to generated documentation in order to let original document cleaner and make it easier to enable/disable those features.

This module extend cukedoctor generated documentation via http://asciidoctor.org/docs/asciidoctorj/#extension-api[Asciidoctor extensions mechanism^].

Cukedoctor comes with 5 extensions to enhance documentation content:

* *Filter extension* which lets features to be filtered using an input at top right of the page;

* *Minimizable extension* which lets you minimize/maximize features sections (minus/plus icon next to feature name);

* *Theme extension* to add theme support.

* *Footer* add cukedoctor footer.

* *Style* customizes Asciidoctor stylesheet.

NOTE: All extensions target html documentation.

=== Disable extensions

To disable extensions just set the following system properties:

[source,java]
----
System.setProperty("cukedoctor.disable.theme","anyValue");

System.setProperty("cukedoctor.disable.filter","anyValue");

System.setProperty("cukedoctor.disable.minmax","anyValue");

System.setProperty("cukedoctor.disable.footer","anyValue");

System.setProperty("cukedoctor.disable.style","anyValue");

----

NOTE: The value doesn't matter, if there is something in the system property the extension will be disabled.

[TIP]
====
You can re-enable the extensions by calling

[source,java]
----
System.clearProperty("cukedoctor.disable.theme");

System.clearProperty("cukedoctor.disable.filter");

System.clearProperty("cukedoctor.disable.minmax");

System.clearProperty("cukedoctor.disable.footer");

System.clearProperty("cukedoctor.disable.style");
----
====

== Jenkins plugin

Cukedoctor brings Living documentation to Jenkins via https://wiki.jenkins-ci.org/display/JENKINS/Cucumber+Living+Documentation+Plugin[Cucumber living documentation plugin^].

== Docker

You can use Cukedoctor via docker using the following command:

----
docker run -v "$PWD:/output" rmpestano/cukedoctor -f pdf -o /output/generated_doc/documentation
----

It will search features (cucumber output in json format) in current folder (`$PWD`) and generate living documentation in `/output/generated_doc`

TIP: To change features folder just change first parameter of docker volume, ex: `docker run -v "/home:/output" ...` will search for cucumber features in `/home` directory.

NOTE: For Cukedoctor parameters details, see https://github.com/rmpestano/cukedoctor#usage-2[cukedoctor-cli^]

== Distribution

Cukedoctor is available at https://bintray.com/rmpestano/cukedoctor[Bintray] and at http://search.maven.org/#search%7Cga%7C1%7Ccukedoctor[Maven central^].

*Snapshots* are available at https://oss.sonatype.org/content/repositories/snapshots/com/github/cukedoctor/[maven central^] and published on each _successful_ commit&build on travis.

You can use snapshots by adding the following snippets in pom.xml:

[source,xml]
----



snapshots
libs-snapshot
https://oss.sonatype.org/content/repositories/snapshots

----

TIP: You can download snapshots directly from Sonatype https://oss.sonatype.org/content/repositories/snapshots/com/github/cukedoctor/[here^].

== Contributing

* Found a bug? open an https://github.com/rmpestano/cukedoctor/issues[issue^] and attach your https://github.com/rmpestano/cukedoctor/tree/master/cukedoctor-converter/src/test/resources/json-output[feature json^] output to it;
* Have an idea? open an issue and lets discuss it;
* Any form of feedback is more than welcome!