├── .forestry ├── front_matter │ └── templates │ │ └── default.yml └── settings.yml ├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── gherkin-i18n-table.yml ├── .gitignore ├── .ruby-version ├── Dockerfile ├── Gemfile ├── LICENSE ├── Makefile ├── README.md ├── TODO.md ├── config.toml ├── content ├── _index.md ├── _todo │ ├── _index.md │ └── step-reuse.md ├── docs │ ├── bdd │ │ ├── _index.md │ │ ├── better-gherkin.md │ │ ├── discovery-workshop.md │ │ ├── example-mapping.md │ │ ├── examples.md │ │ ├── history.md │ │ ├── myths.md │ │ └── who-does-what.md │ ├── community │ │ ├── _index.md │ │ ├── blog-posts.md │ │ ├── blog.md │ │ ├── contributing-to-documentation.md │ │ ├── contributing.md │ │ ├── faq.md │ │ ├── get-in-touch.md │ │ ├── new-contributors.md │ │ ├── not-cucumber.md │ │ └── projects-using-cucumber.md │ ├── cucumber │ │ ├── _index.md │ │ ├── api.md │ │ ├── checking-assertions.md │ │ ├── configuration.md │ │ ├── cucumber-expressions.md │ │ ├── debugging.md │ │ ├── environment-variables.md │ │ ├── mocking-and-stubbing-with-cucumber.md │ │ ├── reporting.md │ │ ├── state.md │ │ └── step-definitions.md │ ├── gherkin │ │ ├── _index.md │ │ ├── languages.md │ │ ├── reference.md │ │ └── step-organization.md │ ├── guides │ │ ├── 10-minute-tutorial.md │ │ ├── _index.md │ │ ├── anti-patterns.md │ │ ├── api-automation.md │ │ ├── browser-automation.md │ │ ├── continuous-integration.md │ │ ├── overview.md │ │ ├── parallel-execution.md │ │ ├── testable-architecture.md │ │ └── upgrading.md │ ├── installation │ │ ├── _index.md │ │ ├── android.md │ │ ├── android.svg │ │ ├── clojure.md │ │ ├── clojure.svg │ │ ├── cplusplus.md │ │ ├── cplusplus.svg │ │ ├── cwt-cucumber.md │ │ ├── d.md │ │ ├── dotnet.svg │ │ ├── gobdd.md │ │ ├── gocuke.md │ │ ├── golang.md │ │ ├── golang.svg │ │ ├── gosu.md │ │ ├── groovy.md │ │ ├── groovy.svg │ │ ├── ios.md │ │ ├── ios.svg │ │ ├── java.md │ │ ├── java.svg │ │ ├── javascript.md │ │ ├── javascript.svg │ │ ├── jruby.md │ │ ├── jython.md │ │ ├── kotlin.md │ │ ├── kotlin.svg │ │ ├── lua.md │ │ ├── lua.svg │ │ ├── ocaml.md │ │ ├── ocaml.svg │ │ ├── perl.md │ │ ├── php.md │ │ ├── php.svg │ │ ├── python.md │ │ ├── ruby.md │ │ ├── ruby.svg │ │ ├── rust.md │ │ ├── rust.svg │ │ ├── scala.md │ │ ├── scala.svg │ │ ├── specflow.md │ │ ├── tcl.md │ │ ├── tcl.svg │ │ └── xunit-gherkin-quick.md │ ├── professional │ │ ├── _index.md │ │ ├── books.md │ │ ├── school.md │ │ └── training.md │ ├── terms │ │ ├── _index.md │ │ └── user-story.md │ └── tools │ │ ├── _index.md │ │ ├── general.md │ │ ├── java.md │ │ ├── javascript.md │ │ ├── related-tools.md │ │ └── ruby.md ├── search-index.md └── sponsors │ └── _index.md ├── data └── versions.yaml ├── docker_shell.sh ├── layouts └── shortcodes │ ├── README.md │ ├── expression-parameter.html │ ├── gherkin-i18n-table-jq.txt │ ├── gherkin-i18n-table.html │ ├── stepdef-body.html │ └── version.html ├── package.json ├── renovate.json ├── static ├── _redirects ├── admin │ ├── config.yml │ └── index.html └── img │ ├── BDD practices diagram (2 axes).png │ ├── BDD practices diagram (2 x loops).png │ ├── BDD practices diagram - habitation.png │ ├── BDD practices diagram.graffle │ ├── BDD practices diagram.png │ ├── TDD-cycle.png │ ├── bdd-kickstart-black-128.png │ ├── bdd-practices-diagram.png │ ├── book-bdd-in-action.jpg │ ├── book-cucumber-book.jpg │ ├── book-discovery.png │ ├── books.png │ ├── cucumber-school-black-128.png │ ├── cucumber-school-logo.png │ ├── cucumber-school-logo.svg │ ├── discover-formulate-automate-sketch.png │ ├── environment-variables │ └── idea │ │ ├── enter-environment-variable.png │ │ ├── environment-variables-field.png │ │ └── run-debug-configuration.png │ ├── gosu.png │ ├── grouping-step-defs-and-helpers.png │ ├── jruby.png │ ├── jython.png │ ├── mob-manifesto-v3.png │ ├── new-contributors-ensemble.jpg │ ├── parallel-timeline-report.png │ ├── perl.png │ ├── python.png │ ├── scala.png │ ├── single-source-of-truth-256x256.png │ └── three-practices-loops.png ├── themes ├── cucumber-hugo │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── archetypes │ │ └── default.md │ ├── layouts │ │ ├── 404.html │ │ ├── _default │ │ │ ├── list.html │ │ │ └── single.html │ │ ├── index.html │ │ ├── partials │ │ │ ├── doc-search.html │ │ │ ├── gtag.html │ │ │ ├── head.html │ │ │ ├── language-tabs.html │ │ │ ├── list-content.html │ │ │ ├── navbar.html │ │ │ ├── page-card.html │ │ │ ├── sidebar.html │ │ │ └── single-content.html │ │ └── shortcodes │ │ │ ├── block.html │ │ │ ├── card.html │ │ │ ├── danger.html │ │ │ ├── note.html │ │ │ ├── text.html │ │ │ ├── tip.html │ │ │ └── warn.html │ ├── package.json │ ├── static │ │ ├── css │ │ │ ├── .gitignore │ │ │ ├── cucumber.css │ │ │ ├── cucumber.sass │ │ │ └── pygments.sass │ │ ├── favicon.ico │ │ ├── img │ │ │ ├── LOGO.svg │ │ │ ├── cucumber-black-128.png │ │ │ ├── cucumber-logo.png │ │ │ └── green-gears.svg │ │ └── js │ │ │ └── site.js │ ├── theme.toml │ ├── tools │ │ └── htmlproofer │ │ │ └── htmlproofer.rb │ └── yarn.lock └── cucumber-sb │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── archetypes │ └── default.md │ ├── layouts │ ├── 404.html │ ├── _default │ │ ├── list.html │ │ └── single.html │ ├── index.html │ ├── partials │ │ ├── doc-search.html │ │ ├── footer.html │ │ ├── gtag.html │ │ ├── head.html │ │ ├── language-tabs.html │ │ ├── list-content.html │ │ ├── navbar.html │ │ ├── page-card.html │ │ ├── scripts.html │ │ ├── sidebar.html │ │ └── single-content.html │ └── shortcodes │ │ ├── block.html │ │ ├── card.html │ │ ├── danger.html │ │ ├── note.html │ │ ├── text.html │ │ ├── tip.html │ │ └── warn.html │ ├── package-lock.json │ ├── package.json │ ├── static │ ├── css │ │ ├── .gitignore │ │ ├── cucumber-sb.min.css │ │ ├── cucumber.css │ │ ├── cucumber.sass │ │ └── pygments.sass │ ├── favicon.ico │ ├── favicon.png │ ├── img │ │ ├── cucumber-black-128.png │ │ ├── cucumber-logo.png │ │ ├── favicon.ico │ │ ├── favicon.png │ │ └── hero-gears-pattern.svg │ ├── js │ │ ├── cucumber-sb.min.js │ │ └── site.js │ └── webfonts │ │ ├── fa-brands-400.eot │ │ ├── fa-brands-400.svg │ │ ├── fa-brands-400.ttf │ │ ├── fa-brands-400.woff │ │ ├── fa-brands-400.woff2 │ │ ├── fa-light-300.eot │ │ ├── fa-light-300.svg │ │ ├── fa-light-300.ttf │ │ ├── fa-light-300.woff │ │ ├── fa-light-300.woff2 │ │ ├── fa-regular-400.eot │ │ ├── fa-regular-400.svg │ │ ├── fa-regular-400.ttf │ │ ├── fa-regular-400.woff │ │ ├── fa-regular-400.woff2 │ │ ├── fa-solid-900.eot │ │ ├── fa-solid-900.svg │ │ ├── fa-solid-900.ttf │ │ ├── fa-solid-900.woff │ │ └── fa-solid-900.woff2 │ ├── theme.toml │ ├── tools │ └── htmlproofer │ │ └── htmlproofer.rb │ └── yarn.lock └── yarn.lock /.forestry/front_matter/templates/default.yml: -------------------------------------------------------------------------------- 1 | --- 2 | hide_body: false 3 | fields: [] 4 | -------------------------------------------------------------------------------- /.forestry/settings.yml: -------------------------------------------------------------------------------- 1 | --- 2 | upload_path: "/static/uploads/:year:/:month:/:day:" 3 | frontmatter_file_url_template: "/uploads/:year:/:month:/:day:" 4 | body_file_url_template: "/uploads/:year:/:month:/:day:" 5 | new_page_extension: md 6 | auto_deploy: false 7 | admin_path: 8 | webhook_url: 9 | sections: 10 | version: 0.31.1 11 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 18 | 19 | ### 🤔 What's changed? 20 | 21 | 22 | 23 | ### ⚡️ What's your motivation? 24 | 25 | 31 | 32 | ### 📋 Checklist: 33 | 34 | - [x] I agree to respect and uphold the [Cucumber Community Code of Conduct](https://cucumber.io/conduct/) 35 | -------------------------------------------------------------------------------- /.github/workflows/gherkin-i18n-table.yml: -------------------------------------------------------------------------------- 1 | name: 'Update gherkin-i18n-table' 2 | on: 3 | schedule: 4 | # https://crontab.guru/every-night-at-midnight 5 | - cron: "0 0 * * *" 6 | workflow_dispatch: 7 | 8 | permissions: 9 | contents: read 10 | 11 | jobs: 12 | table_update: 13 | permissions: 14 | contents: write # for gr2m/create-or-update-pull-request-action to push local changes 15 | pull-requests: write # for gr2m/create-or-update-pull-request-action to create a PR 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v4 19 | with: 20 | persist-credentials: false 21 | - run: yarn upgrade 22 | - run: make layouts/shortcodes/gherkin-i18n-table.html 23 | - uses: gr2m/create-or-update-pull-request-action@v1 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | with: 27 | body: > 28 | This is an automatically generated PR by the 29 | `gherkin-i18n-table.yml` GitHub Action. 30 | It has updated the `gherkin-i18n-table.html` file. 31 | commit-message: 'Update gherkin-i18n-table' 32 | title: 'Update gherkin-i18n-table' -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | public/ 2 | venv 3 | *.swp 4 | /.idea/ 5 | node_modules/ 6 | .DS_Store 7 | *.iml 8 | .idea/* 9 | .docker-* 10 | Gemfile.lock 11 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.3.6 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Builds a docker image with all the software required to build the website 2 | # 3 | FROM alpine:3.21 4 | 5 | # Install languages and build tools 6 | RUN apk add --no-cache --update --upgrade \ 7 | alpine-sdk \ 8 | bash \ 9 | build-base \ 10 | go \ 11 | libxml2 \ 12 | make \ 13 | libffi-dev \ 14 | nodejs \ 15 | python \ 16 | py-pip \ 17 | ruby \ 18 | ruby-dev \ 19 | ruby-irb \ 20 | ruby-json \ 21 | ruby-rdoc \ 22 | zlib-dev 23 | 24 | # Install Hugo 25 | RUN mkdir -p /root/go 26 | ENV GOPATH /root/go 27 | RUN mkdir -p /root/go/src/github.com/gohugoio 28 | WORKDIR /root/go/src/github.com/gohugoio 29 | RUN git clone https://github.com/gohugoio/hugo 30 | WORKDIR /root/go/src/github.com/gohugoio/hugo 31 | RUN git reset --hard v0.40 32 | RUN go get -v 33 | RUN go build -o hugo main.go 34 | ENV PATH="/root/go/src/github.com/gohugoio/hugo:${PATH}" 35 | 36 | # Install dependencies 37 | WORKDIR /app 38 | RUN pip install --upgrade pip 39 | RUN pip install Pygments 40 | RUN gem install bundler 41 | RUN gem install html-proofer -v 3.8.0 42 | 43 | EXPOSE 1313 44 | 45 | CMD hugo serve --bind 0.0.0.0 46 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'html-proofer', '5.0.9' 4 | 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Cucumber Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | DOCKER_TAG = $(shell cat Dockerfile | md5sum | cut -d ' ' -f 1) 2 | DOCKER_IMAGE = cucumber/hugo:$(DOCKER_TAG) 3 | 4 | define DOCKER_SHELL 5 | #!/bin/sh 6 | docker run -p 1313:1313 --volume $$(pwd):/app -it $(DOCKER_IMAGE) $$@ 7 | endef 8 | export DOCKER_SHELL 9 | 10 | hugo: 11 | hugo 12 | .PHONY: hugo 13 | 14 | htmlproofer: hugo 15 | ruby themes/cucumber-hugo/tools/htmlproofer/htmlproofer.rb 16 | .PHONY: htmlproofer 17 | 18 | layouts/shortcodes/gherkin-i18n-table.html: node_modules/@cucumber/gherkin/dist/src/gherkin-languages.json layouts/shortcodes/gherkin-i18n-table-jq.txt 19 | cat $< | jq --sort-keys --from-file layouts/shortcodes/gherkin-i18n-table-jq.txt --raw-output --compact-output > $@ 20 | 21 | node_modules/@cucumber/gherkin/dist/src/gherkin-languages.json: 22 | yarn 23 | 24 | .docker-$(DOCKER_TAG): Dockerfile 25 | docker build --rm --tag $(DOCKER_IMAGE) . 26 | touch $@ 27 | 28 | docker_shell.sh: .docker-$(DOCKER_TAG) Makefile 29 | @echo "$$DOCKER_SHELL" > $@ 30 | chmod +x $@ 31 | 32 | docker_push: 33 | docker push $(DOCKER_IMAGE) 34 | .PHONY: docker_push 35 | 36 | clean: 37 | rm -rf public 38 | .PHONY: clean 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![#StandWithUkraine](https://raw.githubusercontent.com/vshymanskyy/StandWithUkraine/main/badges/StandWithUkraine.svg)](https://vshymanskyy.github.io/StandWithUkraine) 2 | 3 | # Cucumber Documentation 4 | 5 | 🚨 This repository is archived. the Cucumber documentation is now at https://github.com/cucumber/website. 🚨 6 | 7 | ## Contributing Content 8 | 9 | For small edits, the recommended way to contribute is via GitHub. 10 | Each page in the documentation will have an **Edit** link for this purpose. 11 | 12 | ## Working locally 13 | 14 | For bigger modifications, the recommended workflow is to edit the documentation 15 | locally on your machine, and seeing the results in a web browser. 16 | 17 | This involves getting the source code and building the documentation yourself. 18 | 19 | # Get the source code 20 | 21 | git clone https://github.com/cucumber/docs 22 | cd docs 23 | 24 | ### View the site 25 | 26 | The website is built with several tools that are distributed as a Docker image. 27 | 28 | Install [Docker](https://docs.docker.com/install/) if you don't already have 29 | it on your machine. 30 | 31 | Build and serve the website: 32 | 33 | ./docker_shell.sh 34 | 35 | Open a browser: 36 | 37 | http://localhost:1313 38 | 39 | Changes to the contents will be automatically updated in the browser. 40 | 41 | Try editing one of the pages under `content` and see for yourself! 42 | 43 | ### Build the site and check links 44 | 45 | When you are done editing, build the site and check links: 46 | 47 | ./docker_shell.sh make clean 48 | ./docker_shell.sh make 49 | ./docker_shell.sh make htmlproofer 50 | 51 | By default, external links are only checked in CI (because it takes a while). 52 | To check external links locally: 53 | 54 | CI=true ./docker_shell.sh make htmlproofer 55 | 56 | Links that are broken should be removed or replaced, even if they are only 57 | temporarily broken. The reason for this is that broken links negatively affect 58 | search engine rankings. 59 | 60 | ### Modify theme 61 | 62 | See the [theme README](themes/cucumber-hugo/README.md) 63 | 64 | ## Architecture 65 | 66 | The site is built with [Hugo](https://gohugo.io), a fast static site generator. 67 | 68 | We have a custom-built theme for the site in `themes/cucumber-hugo`. This theme 69 | is based on [Bulma](https://bulma.io/) - a lightweight CSS framework. 70 | 71 | The online site is rebuild automatically whenever the git repository receives 72 | new commits, either via a `git push`, or by modifying contents in the CMS. 73 | 74 | The [Netlify CMS](https://www.netlifycms.org/) saves contents straight to GitHub 75 | using the GitHub API. 76 | 77 | ## Continuous Deployment 78 | 79 | GitHub will notify Netlify for every `git push` thanks to a [webhook](https://github.com/cucumber/docs.cucumber.io/settings/hooks). 80 | 81 | Netlify will then build the site and 82 | [deploy](https://app.netlify.com/sites/cucumber/deploys) it if the build is successful. 83 | 84 | The build will check for broken links and other problems. Internal and external links are checked by [HTMLProofer](https://github.com/gjtorikian/html-proofer). 85 | Occasionally, the build will fail due to external links being unavailable or giving a timeout. When that happens, please check if these external links are available and if so, 'Retry build' on Netlify. 86 | 87 | You can discuss the documentation in the [Community Discord](https://cucumber.io/community#discord). 88 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | * Front page (Aslak) 4 | * Fix left nav (scrolling bad) 5 | * Only show level 2 (not 3 and down) 6 | * Mini-toc (what's on this page) 7 | * Fix height 8 | * Code Colour scheme 9 | * Markdown fenced code block lint (error if no lang) 10 | * Markdown title lint 11 | * Snippet lint (lots of indentation) 12 | * Align design with new training CSS? 13 | 14 | 15 | ## ... 16 | 17 | * Domain name 18 | * Redirect old sources 19 | * Old docs.cucumber.io 20 | * Cloudflare/Netlifly redirect 21 | * _redirect 22 | * GitHub Wiki 23 | * Replace content with link 24 | * Makes sequential sense? 25 | * Something we can all work with 26 | * Back-porting PRs from old repos 27 | * Delete old docs 28 | * Google analytics 29 | * Search (very important, obvious weak spot) 30 | * Algolia 31 | * Lunr/Hugo 32 | * See what people search for 33 | * And don't find - great for finding weak spots 34 | * What's there, but not found 35 | -------------------------------------------------------------------------------- /config.toml: -------------------------------------------------------------------------------- 1 | baseURL = "https://cucumber.io/" 2 | languageCode = "en-us" 3 | title = "Cucumber Documentation" 4 | theme = "cucumber-sb" 5 | enableInlineShortcodes = true 6 | 7 | 8 | [sitemap] 9 | changefreq = "monthly" 10 | filename = "sitemap.xml" 11 | priority = 0.5 12 | 13 | pygmentsUseClassic = true 14 | pygmentsCodeFences = true 15 | pygmentsUseClasses = true 16 | 17 | [markup.goldmark.renderer] 18 | unsafe = true 19 | -------------------------------------------------------------------------------- /content/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber Documentation 3 | --- 4 | 5 |
6 |
7 |
8 |
9 | 10 |
11 |
12 |

Cucumber Docs

13 | 14 |

Executable Specifications 15 | Free, open source, any platform

16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
OpenAPI Specification
29 | 30 | 31 | 32 |
Our open source tool tests business-readable specifications against your code on any modern development stack. With over 30 million downloads, Cucumber Open is the world's #1 tool for Behaviour-Driven Development.
33 | 34 | 35 |
36 | 37 |
38 |
39 | 40 | 41 | 42 |
Cucumber Studio empowers Product Owners and Business Analysts to harness the power of examples, making everyone part of the conversation.
43 | 44 | 45 |
46 | 47 |
48 |
49 | 50 | 51 | 52 |
Define with all your stakeholders the feature files using behavior driven development (BDD), directly in Jira.
53 | 54 | 55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |

67 |

68 |

SmartBear is committed to Open Source development. Create more with us.

69 | 70 |

Join the SmartBear Community

71 |
72 | 73 |
74 |
75 |
76 |
77 |
78 |
79 | 80 | 81 | -------------------------------------------------------------------------------- /content/_todo/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: TODO 3 | menu: 4 | todo: 5 | parent: nothing 6 | --- 7 | -------------------------------------------------------------------------------- /content/_todo/step-reuse.md: -------------------------------------------------------------------------------- 1 | --- 2 | source: https://github.com/cucumber/cucumber/wiki/Step-Definitions/ 3 | source: https://github.com/cucumber/cucumber/wiki/Hooks/ 4 | source: https://github.com/cucumber/cucumber/wiki/Tags/ 5 | title: Cucumber Reference 6 | --- 7 | 8 | # Reusable step definitions 9 | 10 | TODO: Describe how to use output parameters to make step definitions reusable 11 | 12 | # Reusable helper methods 13 | 14 | TODO: Describe how to extract helper methods that can be used from steps 15 | -------------------------------------------------------------------------------- /content/docs/bdd/better-gherkin.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Writing better Gherkin 3 | subtitle: "Some guidelines to writing better Gherkin" 4 | --- 5 | 6 | There are several ways to make your Gherkin better. 7 | 8 | # Describe behaviour 9 | 10 | Your scenarios should describe the intended behaviour of the system, not the implementation. 11 | In other words, it should describe *what*, not *how*. 12 | 13 | For example, for an authentication Scenario, you should write: 14 | 15 | ``` 16 | When "Bob" logs in 17 | ``` 18 | 19 | instead of: 20 | 21 | ``` 22 | Given I visit "/login" 23 | When I enter "Bob" in the "user name" field 24 | And I enter "tester" in the "password" field 25 | And I press the "login" button 26 | Then I should see the "welcome" page 27 | ``` 28 | 29 | The first example, **When "Bob" logs in**, is a *functional requirement*. The second, much longer, example is a *procedural reference*. 30 | Functional requirements are features, but procedures belong in the implementation details. 31 | 32 | That way, when the implementation of a feature changes, you'll only need to change the process steps behind the scenes. 33 | The behaviour does not have to change just because the implementation does. 34 | In fact, a good question to ask yourself when writing a feature clause is: “Will this wording need to change if the implementation does?”. 35 | 36 | If the answer is “Yes”, then you should rework it avoiding implementation specific details. 37 | As a side benefit, in consequence your scenarios will be a lot shorter and much easier to follow and understand. 38 | 39 | # Consider a more declarative style 40 | 41 | One way to make scenarios easier to maintain and less brittle is to use a declarative style. Declarative style describes the behaviour of the application, rather than the implementation details. Declarative scenarios read better as "living documentation". A declarative style helps you focus on the value that the customer is getting, rather than the keystrokes they will use. 42 | 43 | Imperative tests communicate details, and in some contexts this style of test is appropriate. On the other hand, because they are so closely tied to the mechanics of the current UI, they often require more work to maintain. Any time the implementation changes, the tests need to be updated too. 44 | 45 | Here's an example of a feature in an imperative style: 46 | ``` 47 | Feature: Subscribers see different articles based on their subscription level 48 | 49 | Scenario: Free subscribers see only the free articles 50 | Given users with a free subscription can access "FreeArticle1" but not "PaidArticle1" 51 | When I type "freeFrieda@example.com" in the email field 52 | And I type "validPassword123" in the password field 53 | And I press the "Submit" button 54 | Then I see "FreeArticle1" on the home page 55 | And I do not see "PaidArticle1" on the home page 56 | 57 | Scenario: Subscriber with a paid subscription can access "FreeArticle1" and "PaidArticle1" 58 | Given I am on the login page 59 | When I type "paidPattya@example.com" in the email field 60 | And I type "validPassword123" in the password field 61 | And I press the "Submit" button 62 | Then I see "FreeArticle1" and "PaidArticle1" on the home page 63 | ``` 64 | 65 | Each step is a precise instruction. The inputs and expected results are specified exactly. But it's easy to imagine changes to the application which would require changing these tests. The available options for free versus paid subscriptions can change. Even the means of logging in could change. What if, in the future, users log in with a voice interface or a thumbprint? 66 | 67 | A more declarative style hides the details of how the application's capabilities are implemented. 68 | 69 | ``` 70 | Feature: Subscribers see different articles based on their subscription level 71 | 72 | Scenario: Free subscribers see only the free articles 73 | Given Free Frieda has a free subscription 74 | When Free Frieda logs in with her valid credentials 75 | Then she sees a Free article 76 | 77 | Scenario: Subscriber with a paid subscription can access both free and paid articles 78 | Given Paid Patty has a basic-level paid subscription 79 | When Paid Patty logs in with her valid credentials 80 | Then she sees a Free article and a Paid article 81 | ``` 82 | With a declarative style, each step communicates an idea, but the exact values aren't specified. The details of *how* the user interacts with the system, such as which specific articles are free or paid, and the subscription level of different test users, are specified in the step definitions (the automation code that interacts with the system). The subscription packages could change in the future. The business could change what content is available to subscribers on free and paid plans, without having to change this scenario and other scenarios that use the same step definitions. If another subscription level is added later, it's easy to add a scenario for that. By avoiding terms like “click a button” that suggest implementation, the scenario is more resilient to implementation details of the UI. The intent of the scenario remains the same, even if the implementation changes later. In addition, having too many implementation details in a scenario, makes it harder to understand the intended behaviour it illustrates. 83 | -------------------------------------------------------------------------------- /content/docs/bdd/discovery-workshop.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Discovery workshop 3 | subtitle: The session where you do your exploration work 4 | --- 5 | 6 | ### What is a discovery workshop? 7 | 8 | A discovery workshop is a conversation where technical and business people collaborate to explore, discover and agree as much as they can about the desired behaviour for a [User Story](/docs/terms/user-story/). 9 | 10 | ### How do you conduct a discovery workshop? 11 | 12 | There are several discovery workshop models, these are just a few: 13 | 14 | [**Example Mapping**](/docs/bdd/example-mapping/) 15 | 16 | Uses a pack of index cards in four different colours to map rules (a summary of constraints/acceptance criteria the team has agreed upon) to examples (illustrations/cases of the acceptance criteria) 17 | 18 | [**OOPSI Mapping (Outcomes, Outputs, Processes, Scenarios, Inputs)**](https://jennyjmar.com/2016/04/16/bdd-discovery-and-oopsi/) 19 | 20 | Similar to Example Mapping, uses Post-it Notes of different colours to map shared processes/relationships between outputs and scenarios. 21 | 22 | [**Feature Mapping**](https://johnfergusonsmart.com/feature-mapping-a-simpler-path-from-stories-to-executable-acceptance-criteria/) 23 | 24 | Also uses Post-it Notes of different colours.  The team picks a story from the backlog, identifies the actors involved, breaks the story down into tasks, and maps those tasks to specific examples. 25 | 26 | ### When should you hold a discovery workshop? 27 | 28 | As late as possible before development on a new User Story begins, in order to prevent details from being lost. Conducting a discovery workshop as late as possible also gives the team enough leg room to shift their plans should new details surface. 29 | 30 | ### Who should attend? 31 | 32 | A good rule-of-thumb is 3-6 people, but at a bare minimum your [Three Amigos](/docs/bdd/who-does-what/#the-three-amigos/) should be present: a product owner, a developer, and a tester.  Your product owner will identify the problem the team should be trying to solve, your developer will address how to build a solution around said problem, and your tester will address any edge cases that could arise.  33 | 34 | ### How long does a discovery workshop take? 35 | 36 | A discovery workshop should ideally only last about 25-30 minutes per story.  If you need any more time than this, it's likely the story is far too large and should be broken down, or some of the specifics are missing.  In the latter case, you should set aside the story as the team needs to do more research. 37 | 38 | ### Why bother? 39 | 40 | The purpose of a discovery workshop is to give all stakeholders, both technical and non-technical, a *shared understanding* of the work at hand.  Doing so encourages cross-functional collaboration, an increase in feedback, and covers any lost details or incorrect assumptions made. 41 | 42 | ### Conclusion 43 | 44 | A discovery workshop is a very important piece of the BDD lifecycle, among other agile development approaches.  Without it, you are sure to run into miscommunications and your team won't discover any unknowns, which could really hamper your project's success. 45 | -------------------------------------------------------------------------------- /content/docs/bdd/example-mapping.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Example Mapping 3 | subtitle: Design examples, break down requirements 4 | --- 5 | 6 | Before you pull a user story into development, it’s crucial to have a conversation to clarify and confirm the acceptance criteria. 7 | 8 | Example Mapping is a method designed to make this conversation short and very productive. 9 | 10 | # How it works 11 | 12 | Concrete examples are a great way to help us explore and understand the problem domain. They are a great basis for our acceptance tests. 13 | 14 | When discussing examples, other things might come up in the conversation that deserve to be captured too: 15 | 16 | - **rules** that summarise a set of examples, or express other constraints. 17 | 18 | - **questions** that cannot be answered during the conversation, or assumptions that are made. 19 | 20 | - new **user stories** discovered or sliced and deferred out of scope. 21 | 22 | We can capture these different types of information on index cards, and arrange them in a map: 23 | 24 | - We write the story on a **yellow** card and place it on top. 25 | 26 | - Each of the acceptance criteria, or rules, is written on a **blue** card and placed beneath the yellow story card. 27 | 28 | - Examples to illustrate these rules are written on a **green** card and placed under the relevant rule. 29 | 30 | - Questions that cannot be answered during the session are captured on a **red** card so we can move on with the conversation. 31 | 32 | We keep going until the group is satisfied that the scope of the story is clear, or we run out of time. 33 | 34 | # More information 35 | 36 | Interested in seeing a demo of example mapping with SmartBear experts using Cucumber Studio? [Click Here](https://smartbear.com/resources/webinars/get-users-stories-into-shape-with-example-mapping/?utm_medium=cucumper-doc&utm_source=referral&utm_campaign=shape-example-mapping) 37 | 38 | For more details, see Matt Wynne's blog on [Example Mapping](https://cucumber.io/blog/2015/12/08/example-mapping-introduction). 39 | 40 | To get started yourself, see Steve Tooke's blog on [Your first Example Mapping session](https://cucumber.io/blog/2018/05/23/your-first-example-mapping-session). 41 | 42 | Or have a look at the [Example Mapping Webinar](https://cucumber.io/blog/2018/02/27/example-mapping-webinar). 43 | -------------------------------------------------------------------------------- /content/docs/bdd/examples.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Examples 3 | subtitle: "Guidelines on how to use examples" 4 | --- 5 | 6 | Good BDD examples are *concrete* rather than *abstract*. They mention names of 7 | people and places, exact dates and amounts, and anything that is relevant to the 8 | problem domain of the software. 9 | 10 | Good examples don't mention technical details. 11 | 12 | {{% note "Imagine it's 1922" %}} 13 | Most software does something people could do manually (just not as efficiently). 14 | 15 | Try hard to come up with examples that don't make any assumptions about 16 | technology. Imagine it's 1922, when there were no computers. 17 | {{% /note %}} 18 | 19 | -------------------------------------------------------------------------------- /content/docs/bdd/history.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: History of BDD 3 | subtitle: Origins of BDD and Cucumber 4 | --- 5 | 6 | Behavior-driven development was pioneered by [Daniel Terhorst-North](https://dannorth.net) back in the early 00s, as he explained in a 2006 article called [Introducing BDD](http://dannorth.net/introducing-bdd/). It grew from a response to test-driven development (TDD), as a way to help programmers on new agile teams "get straight to the good stuff" of knowing how to approach testing and coding, and minimize misunderstandings. BDD has evolved into both analysis and automated testing at the acceptance level. [Liz Keogh](https://lizkeogh.com), another BDD pioneer, started writing and speaking about it extensively beginning in 2004. 7 | 8 | # Early tools supporting BDD 9 | 10 | In 2003, Daniel Terhorst-North started writing a replacement for JUnit called JBehave, using vocabulary based on "behaviour" rather than "test". Liz Keogh and Chris Matts also started contributing early on. Influenced by the idea of ubiquitous language introduced in Eric Evans' [Domain-Driven Design](https://domainlanguage.com/ddd/), and also focusing on business value, the "Given/When/Then" template was developed to capture a story's acceptance criteria in an executable form. It grew partly from the "As a..., I ..., So that..." template for writing user stories, created by [Rachel Davies](http://rachelcdavies.github.io/) at Connextra that had become a recognized standard. 11 | 12 | In 2005, the [RSpec](https://rspec.info/) project, which supported BDD in the Ruby language, was founded by [Dave Astels](http://daveastels.com/), [Steven Baker](https://stevenrbaker.com/), [Aslak Hellesøy](https://twitter.com/aslak_hellesoy) and [David Chelimsky](https://twitter.com/dchelimsky). 13 | 14 | # Origins of Cucumber 15 | 16 | As he helped improve RSpec, Aslak had a lot of ideas for improvements in areas like error messages, step definition snippets, and result reporting. RSpec was designed for programmers, whereas the RSpec Story Runner was for the whole team, including non-coding stakeholders. 17 | 18 | He started a new project, intending to make a better version of Story Runner. He initially called it _Stories_, but asked his then-fiancée for a catchier name. She thought of _Cucumber_, and it stuck. 19 | -------------------------------------------------------------------------------- /content/docs/bdd/myths.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Myths about BDD 3 | subtitle: Common misunderstandings and myths about BDD 4 | --- 5 | 6 | Let's bust some of the most common myths and misunderstandings about BDD. 7 | 8 | # Myth: You can pick and choose the practices in any order 9 | 10 | Here's [Liz Keogh's take](https://lizkeogh.com/2014/01/22/using-bdd-with-legacy-systems/) on this: 11 | 12 | > having conversations is more important than capturing conversations is more important than automating conversations. 13 | 14 | Unless you've already done effective discovery work, trying to formulate scenarios is a waste of time. 15 | 16 | Similarly, you can't automate examples when you haven't done the work to figure out the most important examples to automate, or got your business stakeholder's feedback in how to word them. 17 | 18 | # Myth: You can automate scenarios after the code is implemented 19 | 20 | Many people use Cucumber to do test automation, to check for bugs after the code has already been implemented. That's a perfectly reasonable way to do test automation, but it's not BDD. 21 | 22 | # Myth: Discovery doesn't need a conversation 23 | 24 | We see plenty of teams who try to leave the work of identifying examples and turning them into formulated scenarios to a single individual on the team. 25 | 26 | That's not BDD. Discovery work needs to be done _collaboratively_, bringing together representatives of the different specialists who all need to share understanding about what will be built. 27 | 28 | # Myth: Using Cucumber means you're doing BDD 29 | 30 | Just because you're using Cucumber, doesn't mean you're doing BDD. [There's much more to BDD than using Cucumber](/docs/bdd). 31 | -------------------------------------------------------------------------------- /content/docs/community/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Community 3 | subtitle: Get in touch with other users and contributors 4 | weight: 1180 5 | menu: main 6 | iconClass: far fa-users 7 | --- 8 | -------------------------------------------------------------------------------- /content/docs/community/blog.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber Blog / Podcast 3 | subtitle: Keep up with the latest news 4 | external_url: https://cucumber.io/blog 5 | weight: 10 6 | --- 7 | -------------------------------------------------------------------------------- /content/docs/community/contributing.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Contributing 3 | subtitle: Help us make Cucumber better 4 | polyglot: 5 | - java 6 | - javascript 7 | - ruby 8 | - kotlin 9 | weight: 30 10 | --- 11 | 12 | You want to contribute to Cucumber, great! 13 | 14 | # You have a question 15 | 16 | You can [get in touch](/docs/community/get-in-touch) or have a look on [StackOverflow](https://stackoverflow.com/questions/tagged/cucumber). Similar questions come up now and again. You might be able to find the answer yourself. 17 | 18 | # You have found a bug 19 | 20 | There are several different flavours of Cucumber for different programming languages. Try to file your issue in the repo for the Cucumber flavour you're using: 21 | 22 | * [Cucumber JVM](https://github.com/cucumber/cucumber-jvm/issues/new) 23 | * [Cucumber JS](https://github.com/cucumber/cucumber-js/issues/new) 24 | * [Cucumber Ruby](https://github.com/cucumber/cucumber-ruby/issues/new) 25 | * [Godog](https://github.com/cucumber/godog/issues/new) 26 | 27 | If you're not sure, open an issue in the [common](https://github.com/cucumber/common/issues/new/choose) repo, and we'll take it from there. 28 | 29 | # You want to update the documentation 30 | 31 | If you would like to contribute to the documentation, please see [Contributing to documentation](/docs/community/contributing-to-documentation/). 32 | 33 | # You want to contribute but don't know how 34 | 35 | If you enjoy using Cucumber, consider [sponsoring us](https://github.com/sponsors/cucumber). 36 | -------------------------------------------------------------------------------- /content/docs/community/get-in-touch.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Get in touch 3 | subtitle: Support forums, chat rooms 4 | weight: 70 5 | --- 6 | 7 | Wherever you interact with the Cucumber Open community, always remember to 8 | respect and uphold our [code of conduct](https://github.com/cucumber/cucumber/blob/master/CODE_OF_CONDUCT.md). 9 | 10 | # Github Discussions 11 | 12 | If you have questions about using Cucumber, or ideas for how we could improve 13 | it, head over to our [GitHub Discussions](https://github.com/orgs/cucumber/discussions) forum. 14 | 15 | # Discord 16 | 17 | If you're interested in becoming an 18 | [open-source contributor](https://cucumber.io/docs/community/new-contributors/), 19 | come and hang out in our Discord community. To join the Discord you 20 | [use this invite link](https://discord.gg/8YXBH8j74w). 21 | 22 | # Stack Overflow 23 | 24 | Many people use the [`cucumber`](https://stackoverflow.com/questions/tagged/cucumber) 25 | and [`bdd`](https://stackoverflow.com/questions/tagged/bdd) tags on Stack 26 | Overflow to ask or answer questions about Cucumber. 27 | -------------------------------------------------------------------------------- /content/docs/community/new-contributors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: New Contributors 3 | subtitle: Curious about contributing to Cucumber? Here's where to start. 4 | weight: 10 5 | --- 6 | 7 | Every Wednesday at [10:45 PST](https://dateful.com/convert/pst?t=1045) we host the new contributors ensemble. This is a space for people who are keen to contribute to open source to get together and support each other in making their first contributions. 🦄 8 | 9 | The Cucumber team is committed to [tackling the structural sexism and racism](https://cucumber.io/blog/open-source/tackling-structural-racism-(and-sexism)-in-open-so/) in open source, and we host these sessions to provide a welcoming environment for people who have historically been under-represented in open source. ✊🏿🏳️‍🌈🏳️‍⚧️ 10 | 11 | Sometimes, when people feel comfortable, we stream the session live over Twitch. You can watch it on https://twitch.tv/cucumberbdd or watch old sessions on our [YouTube channel](https://www.youtube.com/playlist?list=PLrQMyTCtW0DZolJHWBLELne1EF2gqMaHc). 12 | 13 | You can also read our manifesto: 14 | 15 | ![New contributors ensemble manifesto](https://cucumber.io/img/mob-manifesto-v3.png) 16 | 17 | ## Would you like to join us? 18 | 19 | Everyone is welcome! If you'd like to join in, [join the Community Discord](https://cucumber.io/community#discord) and head over to the `#committers` channel and say hello. 20 | 21 | If you're new to open source and feeling a bit nervous 😳, we understand! We recommend watching [this excellent guide](https://egghead.io/talks/git-how-to-make-your-first-open-source-contribution) to give you a grounding in some of the basic concepts. We want you to feel safe to make mistakes, and ask questions. 22 | -------------------------------------------------------------------------------- /content/docs/community/projects-using-cucumber.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Projects using Cucumber 3 | subtitle: Get some inspiration 4 | weight: 80 5 | --- 6 | 7 | Here is a list of projects using Cucumber: 8 | 9 | - [BehatMage](https://github.com/MageTest/BehatMage) 10 | - [Broth](https://github.com/fourbeansoup/broth) 11 | - [bsmi](https://github.com/BTHUNTERCN/bsmi) 12 | - [CarrierWave](https://github.com/carrierwaveuploader/carrierwave) 13 | - [Chef](https://github.com/chef/chef) 14 | - [Chits](https://github.com/mikeymckay/chits) 15 | - [Courgette](https://github.com/21croissants/courgette) 16 | - [CF FCQ](https://github.com/cufcq/cufcq) 17 | - [Diaspora](https://github.com/diaspora/diaspora) 18 | - [drush-make-ci](https://github.com/joshkoenig/drush-make-ci) 19 | - [Folioapp](https://github.com/jpatel531/folioapp) 20 | - [Jekyll](https://github.com/jekyll/jekyll) 21 | - [Jeweler](https://github.com/technicalpickles/jeweler) 22 | - [OERPScenario (linked to OpenERP)](https://github.com/camptocamp/oerpscenario) 23 | - [One Click Orgs](https://github.com/oneclickorgs/one-click-orgs) 24 | - [PHP Sasl](https://github.com/fabiang/sasl) 25 | - [RadiantCMS](https://github.com/radiant/radiant) 26 | - [Rails directory](https://github.com/engineyard/rails_dev_directory) 27 | - [Redcar](https://github.com/redcar/redcar) (see /plugins/\*/features) 28 | - [rigse](https://github.com/concord-consortium/rigse) 29 | - [rps-challenge](https://github.com/makersacademy/rps-challenge) 30 | - [TimeFliesBy](https://github.com/esambo/TimeFliesBy) 31 | - [Vdebug](https://github.com/joonty/vdebug) 32 | - [WebJam](https://github.com/webjam/webjam) 33 | - [WontoMedia](https://github.com/gleneivey/wontomedia) 34 | -------------------------------------------------------------------------------- /content/docs/cucumber/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber 3 | subtitle: Technical documentation 4 | weight: 1130 5 | menu: main 6 | iconClass: far fa-cogs 7 | --- 8 | -------------------------------------------------------------------------------- /content/docs/cucumber/cucumber-expressions.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber Expressions 3 | subtitle: Using variables in your step definitions 4 | --- 5 | 6 | The [Cucumber Expressions Docs](https://github.com/cucumber/cucumber-expressions#readme) 7 | have been moved to GitHub. 8 | -------------------------------------------------------------------------------- /content/docs/cucumber/environment-variables.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Environment Variables 3 | subtitle: How to define Environment Variables 4 | --- 5 | 6 | Cucumber uses [environment variables](https://en.wikipedia.org/wiki/Environment_variable) to enable 7 | certain features, such as publishing [Cucumber Reports](https://reports.cucumber.io). 8 | 9 | There are many different ways to define environment variables, depending on your environment. 10 | This guide describes how to define the `CUCUMBER_PUBLISH_TOKEN` environment variable with 11 | value `some-secret-token`. 12 | 13 | For security reasons you should *not* define environment variables containing secrets globally. 14 | 15 | For MacOS and Linux users this means you should *not* define them in `~/.bashrc`, 16 | `~/.bash_profile`, `~/.zshrc`, `/etc.profile` or similar. 17 | 18 | For Windows users this means you should *not* define them via System/Control Panel or `setx.exe`. 19 | 20 | ## Terminal 21 | 22 | If you are using a terminal to run Cucumber, you should define environment variables in the 23 | same terminal. 24 | 25 | This also applies to terminals embedded in an editor such as Visual Studio Code or IntelliJ IDEA. 26 | 27 | ### Windows 28 | 29 | ```shell 30 | setx /M CUCUMBER_PUBLISH_TOKEN "some-secret-token" 31 | ``` 32 | 33 | ### Bash / Zsh 34 | 35 | ```shell 36 | export CUCUMBER_PUBLISH_TOKEN=some-secret-token 37 | ``` 38 | 39 | ## Editor / IDE 40 | 41 | If you are using an editor or IDE to run Cucumber via a menu or shortcut, you should 42 | define environment variables in the editor. 43 | 44 | If you are using a terminal embedded in the IDE, see the [Terminal](#terminal) section above. 45 | 46 | ### IntelliJ IDEA / WebStorm / RubyMine 47 | 48 | Click the *Run/Debug Configuration* dropdown in the toolbar: 49 | 50 | ![Run/Debug Configuration](/img/environment-variables/idea/run-debug-configuration.png) 51 | 52 | Click on the *Environment Variables* field. 53 | 54 | ![Environment Variabled Field](/img/environment-variables/idea/environment-variables-field.png) 55 | 56 | Enter the environment variable and its value into the dialog. 57 | 58 | ![Run/Debug Configuration](/img/environment-variables/idea/enter-environment-variable.png) 59 | 60 | ### Other editors 61 | 62 | Check the documentation for your editor, or help us improving this documentation by editing this page (link at the bottom of the page). 63 | 64 | ## Continuous Integration Servers 65 | 66 | Every Continuous Integration server has a different mechanism for defining environment variables. 67 | Please consult the documentation for your CI server about how to do this. 68 | -------------------------------------------------------------------------------- /content/docs/cucumber/mocking-and-stubbing-with-cucumber.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mocking and Stubbing with Cucumber 3 | subtitle: Decoupling your scenarios from infrastructure 4 | --- 5 | 6 | Mocking is usually discouraged when using Cucumber; ideally you would exercise as much of your stack as possible. 7 | There are cases when using mocking can come in handy. For example, if your system depends on a third party. 8 | If you have a dependency on an external system, we recommend using [stubs instead of mocks](https://martinfowler.com/articles/mocksArentStubs.html). 9 | You **can** set up mocks with expectations in your [step definitions](/docs/cucumber/step-definitions). 10 | 11 | # Ruby 12 | 13 | ## RSpec 2.x 14 | 15 | Starting with Cucumber 0.8.4, you can use all of RSpec's supported mocking frameworks (RSpec, Mocha, RR, Flexmock). 16 | Use `require 'cucumber/rspec/doubles'` ([test-double](https://www.martinfowler.com/bliki/TestDouble.html) is a more generic term than mocks and stubs). 17 | 18 | Perhaps place your stub action within a block as below: 19 | 20 | ```ruby 21 | require 'cucumber/rspec/doubles' 22 | 23 | RSpec::Mocks.with_temporary_scope do 24 | stub_resp = {"city"=>"San Francisco", "state_abbreviation"=>"CA", "state"=>"California", "mailable_city"=>true} 25 | SmartyStreets.stub(:get_city_state).with("94109").and_return(stub_resp) 26 | 27 | click_button "check zip" 28 | end 29 | ``` 30 | 31 | # Java 32 | 33 | Different mocking frameworks may serve different purposes. 34 | 35 | ## Mockito 36 | 37 | [Mockito](https://site.mockito.org/) is a framework for the creation of [test doubles](https://www.martinfowler.com/bliki/TestDouble.html) in automated unit tests for the purpose of TDD or BDD. 38 | 39 | ## MockServer 40 | 41 | You can use [MockServer](https://www.mock-server.com/) for mocking any system you integrate with via HTTP or HTTPS (i.e. services, web sites, etc). 42 | 43 | ## WireMock 44 | 45 | [WireMock](http://wiremock.org/) is a simulator for HTTP-based APIs, similar to MockServer. 46 | 47 | # JavaScript 48 | 49 | If you are using cucumber-js, there are many test frameworks to choose from. 50 | Which one you use, may depend on other JavaScript frameworks your project is using and / or personal preference. 51 | -------------------------------------------------------------------------------- /content/docs/gherkin/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Gherkin Syntax 3 | subtitle: Cucumber's syntax for executable specifications 4 | weight: 1140 5 | menu: main 6 | iconClass: far fa-file-alt 7 | --- 8 | -------------------------------------------------------------------------------- /content/docs/gherkin/languages.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Localisation 3 | subtitle: "Languages in which you can write" 4 | --- 5 | In order to allow Gherkin to be written in a number of languages, the keywords have been translated into multiple languages. To improve readability and flow, some languages may have more than one translation for any given keyword. 6 | 7 | ### Overview 8 | You can find all translation of Gherkin [on GitHub](https://github.com/cucumber/gherkin). 9 | This is also the place to add or update translations. 10 | 11 | A list of the currently supported languages and their keywords can be found below. 12 | 13 | {{% gherkin-i18n-table %}} 14 | -------------------------------------------------------------------------------- /content/docs/guides/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Guides 3 | weight: 1120 4 | menu: main 5 | iconClass: far fa-graduation-cap 6 | --- 7 | -------------------------------------------------------------------------------- /content/docs/guides/anti-patterns.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Anti-patterns 3 | subtitle: Avoid common mistakes and pitfalls 4 | polyglot: 5 | - java 6 | - javascript 7 | - ruby 8 | - kotlin 9 | 10 | weight: 1600 11 | --- 12 | 13 | There are several anti-patterns, which we will describe here. We will also give you hints on how to avoid them! 14 | 15 | # Feature-coupled step definitions 16 | 17 | Feature-coupled step definitions are step definitions that **can't be reused** across features or scenarios. 18 | 19 | This may lead to an explosion of step definitions, code duplication, and high maintenance costs. 20 | 21 | **Example** 22 | 23 | An imaginary résumé application could have the following Feature and Step Definition files: 24 | 25 | ```java 26 | features/ 27 | +--edit_work_experience.feature 28 | +--edit_languages.feature 29 | +--edit_education.feature 30 | +--steps/ 31 | +--edit_work_experience_steps.java 32 | +--edit_languages_steps.java 33 | +--edit_education_steps.java 34 | ``` 35 | 36 | ```kotlin 37 | features/ 38 | +--edit_work_experience.feature 39 | +--edit_languages.feature 40 | +--edit_education.feature 41 | +--steps/ 42 | +--edit_work_experience_steps.kt 43 | +--edit_languages_steps.kt 44 | +--edit_education_steps.kt 45 | ``` 46 | 47 | ```javascript 48 | features/ 49 | +--edit_work_experience.feature 50 | +--edit_languages.feature 51 | +--edit_education.feature 52 | +--steps/ 53 | +--edit_work_experience_steps.js 54 | +--edit_languages_steps.js 55 | +--edit_education_steps.js 56 | ``` 57 | 58 | ```ruby 59 | features/ 60 | +--edit_work_experience.feature 61 | +--edit_languages.feature 62 | +--edit_education.feature 63 | +--steps/ 64 | +--edit_work_experience_steps.rb 65 | +--edit_languages_steps.rb 66 | +--edit_education_steps.rb 67 | ``` 68 | 69 | The `edit_work_experience.feature` could have the following Scenario: 70 | 71 | ``` 72 | Scenario: add description 73 | Given I have a CV and I'm on the edit description page 74 | And I fill in "Description" with "Cucumber BDD tool" 75 | When I press "Save" 76 | Then I should see "Cucumber BDD tool" under "Descriptions" 77 | ``` 78 | The{{% text "kotlin" %}}`edit_work_experience_steps.kt`{{% /text %}} 79 | {{% text "java" %}}`edit_work_experience_steps.java`{{% /text %}} 80 | {{% text "javascript" %}}`edit_work_experience_steps.js`{{% /text %}} 81 | {{% text "ruby" %}}`edit_work_experience_steps.rb`{{% /text %}}could be implemented like this: 82 | 83 | ```java 84 | @Given("I have a CV and I'm on the edit description page") 85 | public void I_have_a_CV_and_Im_on_the_edit_description_page() { 86 | Employee employee = new Employee("Sally"); 87 | employee.createCV(); 88 | } 89 | ``` 90 | 91 | ```kotlin 92 | @Given("I have a CV and I'm on the edit description page") 93 | fun I_have_a_CV_and_Im_on_the_edit_description_page() { 94 | val employee = Employee("Sally") 95 | employee.createCV() 96 | } 97 | ``` 98 | 99 | ```javascript 100 | var { Given } = require('cucumber'); 101 | 102 | Given(/^I have a CV and I'm on the edit description page$/, function () { 103 | this.employee = new Employee('Sally'); 104 | this.employee.createCV(); 105 | }); 106 | ``` 107 | 108 | ```ruby 109 | Given /I have a CV and I'm on the edit description page/ do 110 | @employee = Employee.create!(name: 'Sally') 111 | @employee.create_cv 112 | visits("/employees/#{@employee.id}/descriptions/new") 113 | end 114 | ``` 115 | 116 | ## How to decouple steps & step definitions 117 | 118 | * Organise your steps by domain concept. 119 | 120 | * Use domain-related names (rather than feature- or scenario-related names) for your step & step definition files. 121 | 122 | 123 | # Conjunction steps 124 | 125 | From the online Merriam-Webster dictionary: 126 | 127 | > **con·junc·tion**: an uninflected linguistic form that joins together sentences, clauses, phrases, or words. 128 | 129 | Don't use steps that combine a bunch of different things. This makes steps too specialised, and hard to reuse. 130 | Cucumber has built-in support for conjunctions (`And`, `But`) for a reason! 131 | 132 | **Example** 133 | 134 | ``` 135 | Given I have shades and a brand new Mustang 136 | ``` 137 | 138 | ## How to split conjunction steps 139 | 140 | ``` 141 | Given I have shades 142 | And I have a brand new Mustang 143 | ``` 144 | 145 | ## Support for conjunction steps 146 | 147 | Sometimes you may want to combine several steps into one, to make your scenarios easier to read. 148 | For instance, if you need to set up several preconditions in your `Given` state. 149 | 150 | {{% block "ruby" %}} 151 | While it is possible to call steps from step definitions in Cucumber-Ruby, this is not recommended. 152 | {{% /block %}} 153 | 154 | {{% block "java,kotlin" %}} 155 | In Cucumber-JVM calling steps from step definitions is not supported; this is *by design*. 156 | {{% /block %}} 157 | 158 | {{% block "javascript" %}} 159 | In Cucumber-js calling steps from step definitions is not supported; this is *by design*. 160 | {{% /block %}} 161 | 162 | The best way to achieve composition and reuse, is to use the features of your programming language. If you want to combine 163 | several actions into one step, extract individual (helper) methods and call these methods from your step definition. 164 | 165 | You want to strive to keep your steps atomic as much as possible. 166 | 167 | # More information 168 | For more information on anti-patterns, see [Cucumber Anti-Patterns (blog)](http://www.thinkcode.se/blog/2016/06/22/cucumber-antipatterns). 169 | -------------------------------------------------------------------------------- /content/docs/guides/api-automation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: API Automation 3 | subtitle: RestAssured, Karate and more 4 | polyglot: 5 | - java 6 | - javascript 7 | - ruby 8 | - kotlin 9 | weight: 1350 10 | --- 11 | 12 | Cucumber is not an API automation tool, but it works well with other API automation tools. 13 | 14 | Using API's for your automation, can make your tests faster and less flaky than going through the UI. 15 | In general, API's change less frequently than the UI; keeping your automation up to date for longer. 16 | 17 | # API Automation Tools for JVM 18 | 19 | ## RestAssured 20 | RestAssured is an API automation tool for Java. 21 | 22 | {{% block "java,kotlin" %}} 23 | You can use RestAssured in your step definitions to make API calls and verify responses. 24 | For more information see the [official website](http://rest-assured.io/). 25 | {{% /block %}} 26 | 27 | # API Automation Tools for JavaScript 28 | 29 | ## PactumJS 30 | [PactumJS](https://pactumjs.github.io/) is a REST API Testing Tool for all levels in a Test Pyramid. 31 | 32 | {{% block "javascript" %}} 33 | For more information see the [official docs](https://pactumjs.github.io/) and [boilerplate code](https://github.com/pactumjs/pactum-cucumber-boilerplate). 34 | {{% /block %}} 35 | 36 | # API Automation Tools for Ruby 37 | 38 | ## REST Client 39 | [REST Client](https://github.com/rest-client/rest-client) is a simple HTTP and REST client for Ruby. 40 | 41 | ## HTTParty 42 | [HTTParty](https://github.com/jnunemaker/httparty) can be used to make HTTP calls. 43 | 44 | {{% block "ruby" %}} 45 | For more information, see the [HTTParty docs](https://github.com/jnunemaker/httparty/tree/master/docs). 46 | {{% /block %}} 47 | 48 | ## Net::HTTP 49 | [Net::HTTP](https://docs.ruby-lang.org/en/2.0.0/Net/HTTP.html) is an HTTP client API for Ruby. 50 | 51 | ## Faraday 52 | [Faraday](https://github.com/lostisland/faraday) is a HTTP client library for Ruby. 53 | 54 | ## RubyMine 55 | [RubyMine](https://www.jetbrains.com/help/ruby/meet-rubymine.html) is a Ruby and Rails IDE providing a range of developer tools for Ruby. 56 | 57 | {{% block "ruby" %}} 58 | RubyMine can be used to [test RESTful Web Services](https://www.jetbrains.com/help/ruby/testing-restful-web-services.html). 59 | {{% /block %}} 60 | 61 | ## curb 62 | [curb](https://rubygems.org/gems/curb/versions/0.9.3) provides Ruby-language bindings for the libcurl(3), a fully-featured client-side URL transfer library. 63 | 64 | ## Typhoeus 65 | [Typhoeus](https://github.com/typhoeus/typhoeus) is a Ruby tool that wraps libcurl in order to make fast and reliable requests. 66 | 67 | {{% block "ruby" %}} 68 | For more information, see the [Typhoeus Ruby docs](https://www.rubydoc.info/github/typhoeus/typhoeus). 69 | {{% /block %}} 70 | -------------------------------------------------------------------------------- /content/docs/guides/continuous-integration.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Continuous Build 3 | subtitle: Running Cucumber on a build server 4 | weight: 1500 5 | --- 6 | 7 | Using Cucumber in a [Continuous Integration](https://martinfowler.com/articles/continuousIntegration.html) (CI) environment is relatively straightforward. 8 | 9 | The `cucumber` executable will exit with an [exit status](https://en.wikipedia.org/wiki/Exit_status) 10 | different from `0` if one or more scenarios are failing. This is all your CI 11 | server needs to know. 12 | 13 | First, you have to make sure your CI server executes Cucumber. 14 | Most CI setups invoke some kind of build tool. Common build tools are: 15 | 16 | * [Rake](https://github.com/ruby/rake) 17 | * [Ant](https://ant.apache.org) 18 | * [Maven](https://maven.apache.org) 19 | 20 | We recommend executing Cucumber from one of these on a CI server. 21 | 22 | # Rake 23 | 24 | If your CI server is using [Rake](/docs/tools/ruby#rake), make sure 25 | that Rake executes your Cucumber task. 26 | 27 | # Ant JUnit output 28 | 29 | Many CI servers can interpret XML files produced by the [Ant JUnit task](https://ant.apache.org/manual/Tasks/junit.html) 30 | and display them as HTML. Some can even create reports over time. 31 | 32 | If you're using such a CI server, we recommend you use Cucumber with the `JUnit` formatter. 33 | 34 | > To get started using Cucumber in [Jenkins](https://jenkins.io/), add a build step running 35 | > `cucumber -f junit --out WORKSPACE` and then check the 36 | > 'Publish JUnit test result report', and enter `\*.xml` in the 'Test report XMLs' field. 37 | > Save and run. (Later improve by using a Rake task and placing your output in a subfolder). 38 | 39 | If you're using [Ant](https://ant.apache.org/), you can run Cucumber with the [`exec`](https://ant.apache.org/manual/Tasks/exec.html) task. 40 | 41 | # Jenkins 42 | 43 | A Jenkins plugin is available that produces beautiful Cucumber reports. 44 | 45 | Follow the install instructions for [Cucumber Reports plugin](https://github.com/jenkinsci/cucumber-reports-plugin). 46 | 47 | Overview Page: 48 | 49 | ![jenkins Cucumber report](https://github.com/masterthought/jenkins-cucumber-jvm-reports-plugin-java/raw/master/.README/feature-overview.png) 50 | 51 | Report Page: 52 | 53 | ![jenkins Cucumber report](https://github.com/masterthought/jenkins-cucumber-jvm-reports-plugin-java/raw/master/.README/feature-passed.png) 54 | -------------------------------------------------------------------------------- /content/docs/guides/overview.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Introduction 3 | subtitle: New to Cucumber? Start here! 4 | weight: 1000 5 | --- 6 | Cucumber is a tool that supports [Behaviour-Driven Development(BDD)](/docs/bdd). 7 | If you're new to Behaviour-Driven Development read our [BDD introduction](/docs/bdd) 8 | first. 9 | 10 | # What is Cucumber? 11 | Ok, now that you know that BDD is about discovery, collaboration and examples 12 | (and not testing), let's take a look at Cucumber. 13 | 14 | Cucumber reads executable specifications written in plain text and validates 15 | that the software does what those specifications say. The specifications 16 | consists of multiple *examples*, or *scenarios*. For example: 17 | 18 | ```gherkin 19 | Scenario: Breaker guesses a word 20 | Given the Maker has chosen a word 21 | When the Breaker makes a guess 22 | Then the Maker is asked to score 23 | ``` 24 | 25 | Each scenario is a list of *steps* for Cucumber to work through. Cucumber 26 | verifies that the software conforms with the specification and generates a 27 | report indicating ✅ success or ❌ failure for each scenario. 28 | 29 | In order for Cucumber to understand the scenarios, they must follow some basic 30 | syntax rules, called [Gherkin](/docs/gherkin/). 31 | 32 | # What is Gherkin? 33 | 34 | Gherkin is a set of grammar rules that makes plain text structured enough for 35 | Cucumber to understand. The scenario above is written in Gherkin. 36 | 37 | Gherkin serves multiple purposes: 38 | 39 | - Unambiguous executable specification 40 | - Automated testing using Cucumber 41 | - Document how the system *actually* behaves 42 | 43 | ![Single source of Truth](/img/single-source-of-truth-256x256.png) 44 | 45 | The Cucumber grammar exists in different flavours for many [spoken languages](/docs/gherkin/reference#spoken-languages) 46 | so that your team can use the keywords in your own language. 47 | 48 | Gherkin documents are stored in `.feature` text files and are typically 49 | versioned in source control alongside the software. 50 | 51 | See the [Gherkin reference](/docs/gherkin) for more details. 52 | 53 | # What are Step Definitions? 54 | 55 | [Step definitions](/docs/cucumber/step-definitions) connect Gherkin steps to 56 | programming code. A step definition carries out the action that should be 57 | performed by the step. So step definitions hard-wire the specification to the 58 | implementation. 59 | 60 | ``` 61 | ┌────────────┐ ┌──────────────┐ ┌───────────┐ 62 | │ Steps │ │ Step │ │ │ 63 | │ in Gherkin ├──matched with──>│ Definitions ├───manipulates──>│ System │ 64 | │ │ │ │ │ │ 65 | └────────────┘ └──────────────┘ └───────────┘ 66 | ``` 67 | 68 | Step definitions can be written in many programming languages. Here is an example 69 | using JavaScript: 70 | 71 | ```javascript 72 | When("{maker} starts a game", function(maker) { 73 | maker.startGameWithWord({ word: "whale" }) 74 | }) 75 | ``` 76 | -------------------------------------------------------------------------------- /content/docs/guides/testable-architecture.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Testable Architecture 3 | subtitle: How to have fast and reliable tests 4 | weight: 1400 5 | --- 6 | 7 | Automated tests and executable specifications can only work with software that has a testable architecture. 8 | A testable architecture enables fast and reliable tests that are easy to write, execute and maintain. 9 | 10 | # Fast feedback 11 | Fast tests enable the developers to run them frequently to obtain fast feedback on what they are building, without 12 | losing focus or flow. 13 | 14 | # Testability 15 | When designing for testability, make sure that your products and services are composed of loosely-coupled, 16 | well-encapsulated components or modules. 17 | 18 | Decoupling your business logic from your infrastructure (the often slow and brittle components), 19 | makes it possible to test at different levels, with maximum confidence and minimum cost. 20 | 21 | * Ensure that you can run your tests without going through the user interface (UI). They are slow, brittle, expensive, 22 | and hard to fix. Do not depend solely on UI tests. 23 | * Running tests against a database makes tests slow. We need to make sure the database is in the expected state before 24 | each test in order to make the tests behave consistently. 25 | This will ensure that tests don't interfere with each other and can be executed in any order. 26 | 27 | We want most of our tests to use some kind of in-memory stub implementation, instead of an actual database. 28 | From the perspective of the domain logic, the behavior looks exactly the same. 29 | To make sure that the stub works in the same way as the real thing, we need to have confidence, which we can obtain using [contract tests](https://martinfowler.com/bliki/IntegrationContractTest.html). 30 | 31 | # Ports and adapters 32 | We can think of our database and our stub as two things that can be plugged into the **port**. 33 | The application containing the business logic doesn't need to know if it's talking to a stub or the actual database. This is because it's talking to this port 34 | and storing and retrieving data. We can run our tests using both the stub and the real implementation. This gives us confidence that the stub behaves like the real thing. 35 | 36 | The business logic is at the core of the application, completely decoupled 37 | from external devices and services. It doesn’t know anything about databases, message queues, 38 | or web services, because we have isolated them through these ports. Often, 39 | these ports are connected to adapters that interact with the real implementation. 40 | There will be an adapter for the database, an adapter for the queue, and an adapter for the web service. 41 | The user interface defines how we can interact with our system. It will also have an adapter, such as 42 | a web server that plugs into a port to display a UI in a browser. All the IO tends to happen outside of these ports. 43 | By testing the core business logic directly though the ports, we can eliminate a lot of slow and brittle IO. 44 | 45 | This architectural patterns is called **ports and adapters pattern** (or [hexagonal architecture](https://en.wikipedia.org/wiki/Hexagonal_architecture_(software))). 46 | It enables you to connect your scenarios and unit tests at a lower level, while the contract tests give you the confidence to do that. 47 | 48 | # Full stack 49 | You’ll want to run *some* tests that go through the whole depth of your stack, to get complete confidence. 50 | Diagnosing where the problem is in a full-stack, end-to-end test is really hard, because it can be anywhere. 51 | These tests are brittle because one change can break all of them. They are also slow, 52 | as there is IO involved when going through a browser, web service or database. 53 | 54 | # Test Pyramid 55 | Focus on having different kinds of tests: lots and lots of unit tests, 56 | a few tests that don’t go through all the heavy infrastructure components and just a few tests that go through the UI. 57 | This is called the [test pyramid](https://martinfowler.com/bliki/TestPyramid.html). 58 | 59 | # More information 60 | 61 | For an example of how to implement fast tests (in node.js), see [subsecondtdd on GitHub](https://github.com/subsecondtdd/todo-subsecond). 62 | 63 | Or have a look at Aslak's [talk at Devlin 2017](https://skillsmatter.com/skillscasts/9971-testable-software-architecture-with-aslak-hellesoy) 64 | - or the [slides](https://speakerdeck.com/aslakhellesoy/testable-architecture-devlin-2017) - about this subject. 65 | -------------------------------------------------------------------------------- /content/docs/guides/upgrading.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Upgrading 3 | subtitle: Versioning, changes per version 4 | polyglot: 5 | - java 6 | - javascript 7 | - ruby 8 | - kotlin 9 | - scala 10 | weight: 1700 11 | --- 12 | We try to add new features to Cucumber periodically. This means you may want to upgrade to a newer version to take advantage of these new features, as well as any bug fixes. 13 | 14 | # Versioning 15 | Cucumber tries to follow the [SemVer](http://semver.org/) specification for release numbers. 16 | Essentially, this means that: 17 | 18 | * If only the right-hand (patch) number in the release changes, you don't need to worry. 19 | * If the middle number (minor) number in the release changes, you don't need to worry. 20 | * If the left-hand (major) number changes, you can expect that things might break. 21 | 22 | # Changelog 23 | You can read the history file to learn about the changes in every release: 24 | 25 | {{% block "ruby" %}} 26 | [cucumber-ruby changelog](https://github.com/cucumber/cucumber-ruby/blob/master/CHANGELOG.md) 27 | {{% /block %}} 28 | 29 | {{% block "java,kotlin" %}} 30 | [cucumber-jvm changelog](https://github.com/cucumber/cucumber-jvm/blob/main/CHANGELOG.md) 31 | {{% /block %}} 32 | 33 | {{% block "scala" %}} 34 | [cucumber-jvm-scala changelog](https://github.com/cucumber/cucumber-jvm-scala/blob/main/CHANGELOG.md) 35 | {{% /block %}} 36 | 37 | {{% block "javascript" %}} 38 | [cucumber-js changelog](https://github.com/cucumber/cucumber-js/blob/master/CHANGELOG.md) 39 | {{% /block %}} 40 | 41 | # Migration guides 42 | We don't have any migration guides at the moment, but blog posts announcing new versions usually contain an overview of the changes made in that particular version. 43 | This includes information about any breaking changes when a new major version is released. 44 | 45 | {{% block "java,kotlin" %}} 46 | The following blog posts describe the changes made per release: 47 | 48 | * [Announcing Cucumber-JVM 2.0.0](https://cucumber.io/blog/2017/08/29/announcing-cucumber-jvm-2-0-0) 49 | 50 | * [Announcing Cucumber-JVM 2.2.0](https://cucumber.io/blog/2017/12/05/announcing-cucumber-jvm-2-2-0) 51 | 52 | * [Announcing Cucumber-JVM 2.3.0](https://cucumber.io/blog/2017/12/11/announcing-cucumber-jvm-2-3-0) 53 | 54 | * [Announcing Cucumber-JVM 3.0.0](https://cucumber.io/blog/2018/05/19/announcing-cucumber-jvm-3-0-0) 55 | 56 | * [Announcing Cucumber-JVM 4.0.0](https://cucumber.io/blog/2018/09/24/announcing-cucumber-jvm-4-0-0) 57 | 58 | * [Announcing Cucumber-JVM 4.2.0](https://cucumber.io/blog/2018/10/31/announcing-cucumber-jvm-4-2-0) 59 | 60 | Details can be found in the [cucumber-jvm changelog](https://github.com/cucumber/cucumber-jvm/blob/main/CHANGELOG.md). 61 | {{% /block %}} 62 | -------------------------------------------------------------------------------- /content/docs/installation/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Installation 3 | weight: 1110 4 | menu: main 5 | iconClass: far fa-download 6 | collapseChildren: true 7 | --- 8 | 9 | Cucumber is available for most mainstream programming languages. 10 | We recommend choosing an implementation for the same platform or 11 | programming language as the production code. 12 | 13 | * official implementations are hosted under [cucumber](https://github.com/cucumber). 14 | * semi-official implementations are hosted elsewhere, but use components from [cucumber](https://github.com/cucumber). 15 | * unofficial implementations are hosted elsewhere and don't use any components from [cucumber](https://github.com/cucumber). 16 | * unmaintained implementations are official, but unmaintained and in need of new maintainers. 17 | -------------------------------------------------------------------------------- /content/docs/installation/android.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Android™ 3 | subtitle: Java 4 | svg: installation/android.svg 5 | implementation: official 6 | weight: 1140 7 | --- 8 | 9 | Please see the [Cucumber-Android project on GitHub](https://github.com/cucumber/cucumber-android). 10 | -------------------------------------------------------------------------------- /content/docs/installation/android.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /content/docs/installation/clojure.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Clojure 3 | subtitle: Clojure 4 | svg: installation/clojure.svg 5 | implementation: unmaintained 6 | weight: 1300 7 | --- 8 | 9 | **This package is currently in need of new maintainers.** 10 | 11 | Please see [Cucumber-Clojure](https://github.com/cucumber/cucumber-jvm-clojure). 12 | -------------------------------------------------------------------------------- /content/docs/installation/clojure.svg: -------------------------------------------------------------------------------- 1 | 10 | 12 | 13 | 15 | image/svg+xml 16 | 18 | 19 | 20 | 21 | 22 | 24 | 28 | 32 | 36 | 40 | 44 | 48 | 49 | -------------------------------------------------------------------------------- /content/docs/installation/cplusplus.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber.cpp 3 | subtitle: C++ 4 | svg: installation/cplusplus.svg 5 | implementation: official 6 | weight: 1130 7 | --- 8 | 9 | Please see the [Cucumber.cpp website](https://github.com/cucumber/cucumber-cpp). 10 | -------------------------------------------------------------------------------- /content/docs/installation/cplusplus.svg: -------------------------------------------------------------------------------- 1 | 3 | 5 | 7 | 9 | 10 | 13 | 14 | 15 | 17 | 18 | 19 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /content/docs/installation/cwt-cucumber.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: cwt-cucumber 3 | subtitle: C++ 4 | svg: installation/cplusplus.svg 5 | implementation: unofficial 6 | weight: 1313 7 | --- 8 | 9 | Please see the [CWT Cucumber on GitHub](https://github.com/ThoSe1990/cwt-cucumber). 10 | -------------------------------------------------------------------------------- /content/docs/installation/d.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: unencumbered 3 | subtitle: D 4 | svg: 5 | implementation: unofficial 6 | weight: 1200 7 | --- 8 | 9 | Please see the [unencumbered website](https://github.com/atilaneves/unencumbered). 10 | -------------------------------------------------------------------------------- /content/docs/installation/dotnet.svg: -------------------------------------------------------------------------------- 1 | logo_NET 2 | -------------------------------------------------------------------------------- /content/docs/installation/gobdd.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: GoBDD 3 | subtitle: Go 4 | svg: installation/golang.svg 5 | implementation: unofficial 6 | weight: 1200 7 | --- 8 | 9 | Please see the [gobdd repo](https://github.com/go-bdd/gobdd). 10 | -------------------------------------------------------------------------------- /content/docs/installation/gocuke.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: gocuke 3 | subtitle: Go 4 | svg: installation/golang.svg 5 | implementation: semi-official 6 | weight: 1195 7 | --- 8 | 9 | Please see the [gocuke repo](https://github.com/regen-network/gocuke). 10 | -------------------------------------------------------------------------------- /content/docs/installation/golang.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Godog 3 | subtitle: Go 4 | svg: installation/golang.svg 5 | implementation: official 6 | weight: 1160 7 | --- 8 | 9 | Please see the [godog repo](https://github.com/cucumber/godog). 10 | -------------------------------------------------------------------------------- /content/docs/installation/gosu.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Gosu 3 | subtitle: Gosu 4 | img: /img/gosu.png 5 | implementation: unmaintained 6 | weight: 1305 7 | --- 8 | 9 | **This package is currently in need of new maintainers.** 10 | 11 | Please see [Cucumber-Gosu](https://github.com/cucumber/cucumber-jvm-gosu). 12 | -------------------------------------------------------------------------------- /content/docs/installation/groovy.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Groovy 3 | subtitle: Groovy 4 | svg: installation/groovy.svg 5 | implementation: unmaintained 6 | weight: 1310 7 | --- 8 | 9 | **This package is currently in need of new maintainers.** 10 | 11 | Please see [Cucumber-Groovy](https://github.com/cucumber/cucumber-jvm-groovy). 12 | -------------------------------------------------------------------------------- /content/docs/installation/ios.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumberish 3 | subtitle: iOS, Swift, ObjC 4 | svg: installation/ios.svg 5 | implementation: semi-official 6 | weight: 1190 7 | --- 8 | 9 | Please see the [Cucumberish website](https://github.com/Ahmed-Ali/Cucumberish). 10 | -------------------------------------------------------------------------------- /content/docs/installation/java.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-JVM 3 | subtitle: Java 4 | svg: installation/java.svg 5 | implementation: official 6 | weight: 1110 7 | --- 8 | 9 | ---- 10 | ![Cucumber School Logo](/img/cucumber-school-logo.png) 11 | 12 | Watch the Cucumber School video lesson on installing Cucumber for JVM languages [here](https://school.cucumber.io/courses/take/bdd-with-cucumber-java/lessons/9588454-install-cucumber). 13 | 14 | ---- 15 | 16 | Cucumber-JVM is published in the central Maven repository. 17 | You can install it by adding dependencies to your project. 18 | 19 | {{% note "Dependencies"%}} 20 | Make sure the Cucumber version is the same for all Cucumber dependencies. 21 | {{% /note %}} 22 | 23 | # Maven 24 | 25 | Add the following dependency to your `pom.xml`: 26 | 27 | ```xml 28 | 29 | io.cucumber 30 | cucumber-java 31 | {{% version "cucumberjvm" %}} 32 | test 33 | 34 | ``` 35 | 36 | You can now run Cucumber [from the command line](/docs/cucumber/api/#from-the-command-line) or [run Cucumber with Maven](/docs/tools/java#maven). 37 | 38 | # Gradle 39 | 40 | If you are using Gradle **4.10.3 or older** add the following dependencies to `build.gradle`: 41 | 42 | ``` 43 | dependencies { 44 | testCompile 'io.cucumber:cucumber-java:{{% version "cucumberjvm" %}}' 45 | testCompile 'io.cucumber:cucumber-junit:{{% version "cucumberjvm" %}}' 46 | } 47 | 48 | repositories { 49 | mavenCentral() 50 | } 51 | ``` 52 | 53 | Similarly, if you want to use Gradle **5.0 or more recent** add the following dependencies to `build.gradle`: 54 | 55 | ``` 56 | dependencies { 57 | testImplementation 'io.cucumber:cucumber-java:{{% version "cucumberjvm" %}}' 58 | testImplementation 'io.cucumber:cucumber-junit:{{% version "cucumberjvm" %}}' 59 | } 60 | 61 | repositories { 62 | mavenCentral() 63 | } 64 | ``` 65 | 66 | You can now run Cucumber [from the command line](/docs/cucumber/api/#from-the-command-line) to execute by [adding a cucumber task](/docs/tools/java#gradle) to `build.gradle`. 67 | 68 | # JUnit 5 integration 69 | 70 | It is also possible to use [cucumber-junit-platform-engine](https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-junit-platform-engine) to run your Cucumber test suite. 71 | 72 | # JUnit 4 integration 73 | 74 | It is also possible to use [cucumber-junit](/docs/cucumber/api/#junit) to run your Cucumber test suite. 75 | 76 | # Assertions 77 | 78 | Cucumber does not come with an assertion library. Instead, use the assertion methods 79 | from a [unit testing tool](/docs/cucumber/checking-assertions/#java). 80 | 81 | # Dependency Injection 82 | 83 | While it's not required, we strongly recommend you include one of the 84 | [dependency injection](/docs/cucumber/state/#dependency-injection) modules as well. This allows 85 | you to share state between [step definitions](/docs/cucumber/step-definitions) 86 | without resorting to static variables (a common source of flickering scenarios). 87 | 88 | -------------------------------------------------------------------------------- /content/docs/installation/java.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /content/docs/installation/javascript.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber.js 3 | subtitle: Node.js and browsers 4 | svg: installation/javascript.svg 5 | implementation: official 6 | weight: 1115 7 | --- 8 | 9 | ---- 10 | ![Cucumber School Logo](/img/cucumber-school-logo.png) 11 | 12 | Watch the Cucumber School video lesson on installing Cucumber.js [here](https://school.cucumber.io/courses/take/bdd-with-cucumber-javascript/lessons/11261262-install-cucumber). 13 | 14 | ---- 15 | 16 | Cucumber.js is available as an [npm module](https://www.npmjs.com/package/@cucumber/cucumber). It works with both [Node.js](https://nodejs.org/en/) and browsers. 17 | 18 | # With Node.js 19 | 20 | Add `cucumber` as a development dependency: 21 | 22 | ```shell 23 | # NPM 24 | npm install --save-dev @cucumber/cucumber 25 | ``` 26 | 27 | Or, if you prefer [Yarn](https://yarnpkg.com/en/): 28 | 29 | ```shell 30 | # Yarn 31 | yarn add --dev @cucumber/cucumber 32 | ``` 33 | -------------------------------------------------------------------------------- /content/docs/installation/javascript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /content/docs/installation/jruby.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-JRuby 3 | subtitle: JRuby 4 | img: /img/jruby.png 5 | implementation: unmaintained 6 | weight: 1311 7 | --- 8 | 9 | **This package is currently in need of new maintainers.** 10 | 11 | Please see [Cucumber-JRuby](https://github.com/cucumber/cucumber-jvm-jruby). 12 | -------------------------------------------------------------------------------- /content/docs/installation/jython.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Jython 3 | subtitle: Jython 4 | img: /img/jython.png 5 | implementation: unmaintained 6 | weight: 1312 7 | --- 8 | 9 | **This package is currently in need of new maintainers.** 10 | 11 | Please see [Cucumber-Jython](https://github.com/cucumber/cucumber-jvm-jython). 12 | -------------------------------------------------------------------------------- /content/docs/installation/kotlin.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Kotlin 3 | subtitle: Cucumber-JVM with Kotlin 4 | svg: installation/kotlin.svg 5 | implementation: official 6 | weight: 1145 7 | --- 8 | 9 | There is no native Kotlin implementation of Cucumber, but you can use [Cucumber-JVM](/docs/installation/java) to write Cucumber tests in Kotlin. 10 | 11 | For examples, please see the [kotlin-java8](https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-kotlin-java8) examples on GitHub. 12 | 13 | To get started, have a look at this [blog](https://medium.com/@mlvandijk/kukumber-getting-started-with-cucumber-in-kotlin-e55112e7309b). 14 | -------------------------------------------------------------------------------- /content/docs/installation/kotlin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /content/docs/installation/lua.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Lua 3 | subtitle: Lua 4 | svg: installation/lua.svg 5 | implementation: official 6 | weight: 1135 7 | --- 8 | 9 | Please see the [Cucumber-Lua website](https://github.com/cucumber/cucumber-lua). 10 | -------------------------------------------------------------------------------- /content/docs/installation/lua.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | 6 | 8 | 10 | 11 | 12 | 14 | 19 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /content/docs/installation/ocaml.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber.ml 3 | subtitle: OCaml 4 | svg: installation/ocaml.svg 5 | implementation: official 6 | weight: 1125 7 | --- 8 | 9 | [Cucumber.ml](https://github.com/cucumber/cucumber.ml) is an 10 | implementation written in and useful for 11 | [OCaml](https://ocaml.org/) projects. 12 | 13 | # Prerequisites 14 | 15 | There are a few prerequisites before you can use 16 | Cucumber.ml: 17 | 18 | * Compile and install 19 | [gherkin-c](https://github.com/cucumber/cucumber/tree/master/gherkin/c) 20 | as a shared object on your system 21 | * Install [Opam package manager](https://opam.ocaml.org/) for OCaml 22 | * Install [Dune build system](https://github.com/ocaml/dune) via Opam 23 | 24 | Cucumber.ml delegates its Gherkin parsing to the 25 | [gherkin-c](https://github.com/cucumber/cucumber/tree/master/gherkin/c) 26 | implementation using OCaml's foreign function interface. This means 27 | that, before you can use Cucumber.ml, you will need to compile and 28 | install gherkin-c as a shared library with its header files on your 29 | system. 30 | 31 | Next, check out the 32 | [Cucumber.ml project](https://github.com/cucumber/cucumber.ml) and do the following: 33 | 34 | ```shell 35 | dune build && dune install 36 | ``` 37 | 38 | This will install the `cucumber` Opam package into your local Opam 39 | repository. For more information, please read the 40 | [README file](https://github.com/cucumber/cucumber.ml/blob/master/README.md). 41 | 42 | **Note:** Cucumber.ml assumes that 43 | once you start executing your step definitions it will control 44 | the command line arguments. This can be surprising, so please be aware 45 | of it. Basically, the executable created by the compilation process is 46 | the Cucumber runner and it is that executable which will run your step 47 | definitions. 48 | 49 | Please see the [Cucumber OCaml 50 | website](https://github.com/cucumber/cucumber.ml) for more information 51 | and usage instructions. 52 | -------------------------------------------------------------------------------- /content/docs/installation/perl.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Test::BDD-Cucumber 3 | subtitle: Perl 4 | img: /img/perl.png 5 | implementation: semi-official 6 | weight: 1190 7 | --- 8 | 9 | Please see the [Cucumber-Perl website](https://github.com/pherkin/test-bdd-cucumber-perl). 10 | -------------------------------------------------------------------------------- /content/docs/installation/php.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Behat 3 | subtitle: PHP 4 | svg: installation/php.svg 5 | implementation: semi-official 6 | weight: 1165 7 | --- 8 | 9 | Please see the [Behat website](https://behat.org/). 10 | -------------------------------------------------------------------------------- /content/docs/installation/python.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Behave 3 | subtitle: Python 4 | img: /img/python.png 5 | implementation: semi-official 6 | weight: 1170 7 | --- 8 | 9 | Please see the [Behave website](http://behave.readthedocs.io/). 10 | -------------------------------------------------------------------------------- /content/docs/installation/ruby.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber.rb 3 | subtitle: Ruby, Ruby on Rails 4 | svg: installation/ruby.svg 5 | implementation: official 6 | weight: 1120 7 | --- 8 | 9 | ---- 10 | ![Cucumber School Logo](/img/cucumber-school-logo.png) 11 | 12 | Watch the Cucumber School video lesson on installing Cucumber for Ruby [here](https://school.cucumber.io/courses/take/bdd-with-cucumber-ruby/lessons/11303803-install-cucumber). 13 | 14 | ---- 15 | 16 | Cucumber for Ruby is a Ruby gem. Depending on your project structure there are several ways to install it: 17 | 18 | # Rubygems 19 | 20 | Install from the command line: 21 | 22 | ```shell 23 | gem install cucumber 24 | ``` 25 | 26 | # Bundler (without Rails) 27 | 28 | Add `cucumber` to your `Gemfile`: 29 | 30 | ```ruby 31 | gem 'cucumber' 32 | ``` 33 | 34 | Install the gem: 35 | 36 | ```shell 37 | bundle 38 | ``` 39 | 40 | Try it out: 41 | 42 | ```shell 43 | cucumber --help 44 | ``` 45 | 46 | Then, initialize a `features/` directory: 47 | 48 | ```shell 49 | cucumber --init 50 | ``` 51 | 52 | [Bundler](https://bundler.io/) is a utility gem that manages project specific RubyGem dependencies such that each 53 | Rails project is unaffected by the gem requirements of another. 54 | If you use Bundler to support multiple gem versions in multiple Rails projects on a single development host then you must 55 | run Cucumber using the preface `bundle exec`. For example: `bundle exec cucumber -pnone features`. 56 | 57 | ## Ruby on Rails 58 | 59 | [Cucumber-Rails](https://github.com/cucumber/cucumber-rails) is a gem that Rails projects can use to install cucumber and create its configuration. 60 | 61 | Add `cucumber-rails` to your `Gemfile`: 62 | (*Note*: you do not need to add Cucumber) 63 | 64 | ```ruby 65 | group :test do 66 | gem 'cucumber-rails', require: false 67 | # database_cleaner is not mandatory, but highly recommended 68 | gem 'database_cleaner' 69 | end 70 | ``` 71 | 72 | Install the gem: 73 | 74 | ```shell 75 | bundle 76 | ``` 77 | 78 | Learn about the various options: 79 | 80 | ```shell 81 | rails generate cucumber:install --help 82 | ``` 83 | 84 | Run the generator: 85 | 86 | ```shell 87 | rails generate cucumber:install 88 | ``` 89 | 90 | Cucumber-Rails will detect whether the RSpec gems are installed. If so, then the rails generator builds the environment files to suit. 91 | If not, it ignores RSpec and configures for test-unit instead. 92 | -------------------------------------------------------------------------------- /content/docs/installation/ruby.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /content/docs/installation/rust.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Rust 3 | subtitle: Rust 4 | svg: installation/rust.svg 5 | implementation: unofficial 6 | weight: 1200 7 | --- 8 | 9 | Please see the [Cucumber-Rust website](https://github.com/bbqsrc/cucumber-rust). 10 | -------------------------------------------------------------------------------- /content/docs/installation/rust.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /content/docs/installation/scala.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Scala 3 | subtitle: Scala 4 | svg: installation/scala.svg 5 | implementation: official 6 | weight: 1146 7 | --- 8 | 9 | Cucumber-Scala is published in the central Maven repository. 10 | You can install it by adding dependencies to your project. 11 | 12 | {{% note "Dependencies"%}} 13 | Make sure the Cucumber version is the same for all Cucumber dependencies. 14 | {{% /note %}} 15 | 16 | # Maven 17 | 18 | ```xml 19 | 20 | io.cucumber 21 | cucumber-scala_2.13 22 | {{% version "cucumberscala" %}} 23 | test 24 | 25 | ``` 26 | 27 | You can now run Cucumber [from the command line](/docs/cucumber/api/#from-the-command-line) or [run Cucumber with Maven](/docs/tools/java#maven). 28 | 29 | # Sbt 30 | 31 | ```scala 32 | libraryDependencies += "io.cucumber" %% "cucumber-scala" % "{{% version "cucumberscala" %}}" % Test 33 | ``` 34 | # JUnit 5 integration 35 | 36 | It is also possible to use [cucumber-junit-platform-engine](https://github.com/cucumber/cucumber-jvm/tree/main/cucumber-junit-platform-engine) to run your Cucumber test suite. 37 | 38 | # JUnit 4 integration 39 | 40 | It is also possible to use [cucumber-junit](/docs/cucumber/api/#junit) to run your Cucumber test suite. 41 | 42 | # Assertions 43 | 44 | Cucumber does not come with an assertion library. Instead, use the assertion methods 45 | from a [unit testing tool](/docs/cucumber/checking-assertions/#java). 46 | 47 | -------------------------------------------------------------------------------- /content/docs/installation/scala.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /content/docs/installation/specflow.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: SpecFlow 3 | subtitle: C#, F#, VB.NET 4 | svg: installation/dotnet.svg 5 | implementation: semi-official 6 | weight: 1180 7 | --- 8 | 9 | Please see the [SpecFlow website](https://specflow.org/). 10 | -------------------------------------------------------------------------------- /content/docs/installation/tcl.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Cucumber-Tcl 3 | subtitle: Tcl 4 | svg: installation/tcl.svg 5 | implementation: unmaintained 6 | weight: 1150 7 | --- 8 | 9 | Please see the [Cucumber-Tcl website](https://github.com/cucumber/cucumber-ruby-tcl). 10 | -------------------------------------------------------------------------------- /content/docs/installation/tcl.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /content/docs/installation/xunit-gherkin-quick.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Xunit.Gherkin.Quick 3 | subtitle: C#, F#, VB with .NET Core 4 | svg: installation/dotnet.svg 5 | implementation: semi-official 6 | weight: 1161 7 | --- 8 | 9 | Please see the [Xunit.Gherkin.Quick website](https://github.com/ttutisani/Xunit.Gherkin.Quick). 10 | -------------------------------------------------------------------------------- /content/docs/professional/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Professional Services 3 | subtitle: Training, videos and books 4 | weight: 1122 5 | menu: main 6 | iconClass: far fa-comments-dollar 7 | --- 8 | -------------------------------------------------------------------------------- /content/docs/professional/books.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Books 3 | subtitle: About BDD and Cucumber 4 | card_image: /img/books.png 5 | weight: 10 6 | --- 7 | 8 | We like these Books 9 | 10 |
11 |
12 | {{% card 13 | title="Discovery" 14 | image="/img/book-discovery.png" 15 | link="https://bddbooks.com/" 16 | %}} 17 | This practical guide by Gáspár Nagy and Seb Rose explains good collaboration techniques, illustrated by concrete examples. 18 | {{% /card %}} 19 |
20 |
21 | {{% card 22 | title="The Cucumber Book" 23 | image="/img/book-cucumber-book.jpg" 24 | link="https://www.amazon.com/Cucumber-Book-2e-Matt-Wynne/dp/1680502387" 25 | %}} 26 | Matt Wynne and Aslak Hellesøy show you how to express your customers’ wild ideas as a set of clear, executable specifications that everyone on the team can read. 27 | {{% /card %}} 28 |
29 |
30 | {{% card 31 | title="BDD in Action" 32 | image="/img/book-bdd-in-action.jpg" 33 | link="https://www.manning.com/books/bdd-in-action" 34 | %}} 35 | BDD in Action by John Ferguson Smart teaches you Behavior-Driven Development and shows you how to integrate it into your existing development process. 36 | {{% /card %}} 37 |
38 |
39 | -------------------------------------------------------------------------------- /content/docs/professional/school.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Online training 3 | subtitle: Become a Cucumber expert at your own pace with Cucumber School 4 | card_image: /img/cucumber-school-black-128.png 5 | external_url: https://cucumber.io/school 6 | weight: 6 7 | --- 8 | 9 | -------------------------------------------------------------------------------- /content/docs/professional/training.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Classroom training 3 | subtitle: Attend our popular BDD Kickstart courses 4 | card_image: /img/bdd-kickstart-black-128.png 5 | weight: 4 6 | --- 7 | Cucumber Ltd run private and public Behaviour-Driven Development training and coaching services around the world. To make an on-site enquiry or to see a list of upcoming public course dates, head to our [training page](https://cucumber.io/training). 8 | 9 | 10 | -------------------------------------------------------------------------------- /content/docs/terms/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Terminology 3 | menu: main 4 | collapseChildren: true 5 | iconClass: far fa-book 6 | --- 7 | 8 | There's loads of new terminology and jargon to learn as you learn about Cucumber and BDD. Here you'll find definitions of the common terms. 9 | -------------------------------------------------------------------------------- /content/docs/terms/user-story.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User stories 3 | subtitle: Small increments of value used in planning agile developent work 4 | --- 5 | 6 | A *User Story* is a small piece of valuable functionality used for planning and prioritising work on an agile team. 7 | 8 | A good *User Story* should: 9 | 10 | - Deliver a demonstrable piece of functionality 11 | - Have testable acceptance criteria 12 | 13 | and be 14 | 15 | - **I**ndependent 16 | - **N**egotiable 17 | - **V**aluable 18 | - **E**stimatible 19 | - **S**mall 20 | - **T**estable 21 | 22 | ## Story Format 23 | 24 | A good *User Story* should describe the **Who** (``), **What** (``) and **Why** (``). 25 | 26 | As an 27 | I want a 28 | So that 29 | 30 | Example: 31 | 32 | As an mobile bank customer 33 | I want to see balance on my accounts 34 | So that I can make better informed decisions about my spending 35 | 36 | ## Acceptance Criteria using Cucumber language 37 | 38 | Acceptance Criteria are conditions that a (software) product must satisfy to be accepted by a user, customer or other stakeholder. 39 | 40 | These are best written using the Cucumber language and [Gherkin syntax](https://cucumber.io/docs/gherkin/). 41 | 42 | ```gherkin 43 | Feature: Some important feature 44 | 45 | Scenario: Get something 46 | Given I have something 47 | When I do something 48 | Then I get something else 49 | 50 | Scenario: Get something different 51 | Given I have something 52 | And I have also some other thing 53 | When I do something different 54 | Then I get something different 55 | ``` 56 | 57 | … etc., with more scenarios as required. 58 | 59 | Example: 60 | 61 | ```gherkin 62 | Feature: Some important feature 63 | 64 | Scenario: Do not show balance if not logged in 65 | Given I am not logged on to the mobile banking app 66 | When I open the mobile banking app 67 | Then I can see a login page 68 | And I do not see account balance 69 | 70 | Scenario: Show balance on the accounts page after logging in 71 | Given I have just logged on to the mobile banking app 72 | When I load the accounts page 73 | Then I can see account balance for each of my accounts 74 | ``` 75 | 76 | ## Futher reading 77 | 78 | - 79 | - 80 | -------------------------------------------------------------------------------- /content/docs/tools/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tools 3 | subtitle: Simplify your work with Cucumber power tools 4 | weight: 1180 5 | menu: main 6 | iconClass: far fa-tools 7 | --- 8 | -------------------------------------------------------------------------------- /content/docs/tools/general.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tools 3 | subtitle: "Editors, IDEs and build tools" 4 | weight: 1000 5 | --- 6 | 7 | Using Cucumber in your project is more manageable with the right tools. 8 | 9 | # Editors 10 | 11 | Most popular text editors support Gherkin syntax highlighting. 12 | 13 | Some IDEs also have advanced support for Cucumber, such as running Cucumber 14 | from within the IDE, displaying results, navigating between Gherkin steps and 15 | step definitions and so on. 16 | 17 | ## Atom 18 | 19 | [Atom](https://github.com/atom/atom) is a text editor for macOS, Windows or Linux. 20 | 21 | It offers several [packages](https://atom.io/packages/search?q=cucumber) you can use with Cucumber. 22 | 23 | ## TextMate 24 | 25 | [TextMate](https://macromates.com/) is a text editor for macOS. 26 | See the [`Cucumber.tmbundle`](https://github.com/cucumber/cucumber-tmbundle) documentation. 27 | 28 | ## Visual Studio Code 29 | [Visual Studio Code](https://code.visualstudio.com/) is a code editor for Windows, Linux, or macOS. 30 | 31 | You can use it with a [Cucumber (Gherkin) plugin](https://marketplace.visualstudio.com/items?itemName=alexkrechik.cucumberautocomplete). 32 | 33 | ## Nova 34 | 35 | [Nova](https://nova.app) is a text editor for macOS. 36 | 37 | See the [Cucumber extension](https://extensions.panic.com/extensions/com.rpowell/com.rpowell.Cucumber/) for Gherkin language support. 38 | 39 | # IDEs 40 | 41 | * [Java IDEs](/docs/tools/java#ides) 42 | * [Ruby IDEs](/docs/tools/ruby#ides) 43 | * [CukeTest](http://cuketest.com) is a Gherkin editor and Cucumber.js development tool. 44 | * [testjam.io](https://testjam.io) is an online IDE for running and sharing Cucumber.js snippets. 45 | 46 | # Build Tools 47 | You can run Cucumber using build tools, rather than from the command line. 48 | 49 | * [Java build tools](/docs/tools/java#build-tools) 50 | * [Ruby build tools](/docs/tools/ruby#build-tools) 51 | -------------------------------------------------------------------------------- /content/docs/tools/java.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Java Tools 3 | weight: 1100 4 | --- 5 | 6 | This page describes tools commonly used with Java. 7 | 8 | # IDEs 9 | 10 | ## IntelliJ IDEA 11 | 12 | - [IntelliJ IDEA](https://www.jetbrains.com/idea/) has the [IntelliJ IDEA Cucumber for Java plugin](https://plugins.jetbrains.com/plugin/7212-cucumber-for-java) 13 | 14 | You can find more information on using Cucumber with IntelliJ IDEA in the [IntelliJ IDEA Cucumber help pages](https://www.jetbrains.com/idea/help/cucumber.html) 15 | 16 | ## Eclipse 17 | 18 | - [Eclipse](https://www.eclipse.org/) has the [Cucumber Eclipse plugin](https://cucumber.github.io/cucumber-eclipse/) 19 | 20 | # Build tools 21 | The most widely used build tools for Java are [Maven](#maven) and [Gradle](#gradle). 22 | 23 | ## Maven 24 | 25 | To run Cucumber with [Maven](https://maven.apache.org/), make sure that: 26 | 27 | - Maven is installed 28 | - The environment variable `MAVEN_HOME` is correctly configured 29 | - The IDE is configured with the latest Maven installation 30 | 31 | Clone the [cucumber-java-skeleton](https://github.com/cucumber/cucumber-java-skeleton) to get started. 32 | 33 | ## Gradle 34 | 35 | To run Cucumber with [Gradle](https://gradle.org/), make sure that: 36 | 37 | - Gradle is installed 38 | - The environment variable `GRADLE_HOME` is correctly configured 39 | - The IDE is configured with the latest Gradle installation 40 | 41 | Clone the [cucumber-java-skeleton](https://github.com/cucumber/cucumber-java-skeleton) to get started. 42 | -------------------------------------------------------------------------------- /content/docs/tools/javascript.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JavaScript Tools 3 | weight: 1200 4 | --- 5 | 6 | This page describes tools commonly used with JavaScript. 7 | 8 | # Build tools 9 | The most widely used build tools for JavaScript are [npm](#npm) and [Yarn](#yarn). 10 | 11 | ## npm 12 | To use Cucumber with [npm](https://www.npmjs.com/), make sure that: 13 | 14 | - npm is installed 15 | 16 | Cucumber.js is available as an npm module. 17 | 18 | Add `cucumber` as a development dependency: 19 | 20 | ```shell 21 | # NPM 22 | npm install --save-dev @cucumber/cucumber 23 | ``` 24 | 25 | ## Yarn 26 | 27 | To run Cucumber with [Yarn](https://yarnpkg.com/en/), make sure that: 28 | 29 | - Yarn is installed 30 | 31 | Add `cucumber` as a development dependency: 32 | 33 | ```shell 34 | # Yarn 35 | yarn add --dev @cucumber/cucumber 36 | ``` 37 | -------------------------------------------------------------------------------- /content/docs/tools/ruby.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ruby Tools 3 | weight: 1300 4 | --- 5 | 6 | This page describes tools for a Ruby or Ruby on Rails environment. 7 | 8 | # IDEs 9 | 10 | 11 | ## RubyMine 12 | [RubyMine](https://www.jetbrains.com/help/ruby/meet-rubymine.html) is a Ruby and Rails IDE. 13 | 14 | # Build tools 15 | 16 | Cucumber can be run in several ways. 17 | Be aware that `rake cucumber`, `cucumber features`, and `autotest` with `ENV AUTOFEATURE=true` do not necessarily produce 18 | the same results given the same features and step definitions. 19 | 20 | ## Rake 21 | 22 | Running `rake cucumber` from the command line provides the simplest method to run Cucumber tests. 23 | 24 | Using Rake requires a `Rakefile` with a `features` task definition. For example: 25 | 26 | ```ruby 27 | require 'rubygems' 28 | require 'cucumber' 29 | require 'cucumber/rake/task' 30 | 31 | Cucumber::Rake::Task.new(:features) do |t| 32 | t.cucumber_opts = "--format pretty" # Any valid command line option can go here. 33 | end 34 | ``` 35 | 36 | This will run all the Features with the pretty formatter. 37 | 38 | Note, how we use the `cucumber_opts` accessor to define our arguments passed to Cucumber. 39 | 40 | If you are using [Ruby on Rails](#ruby-on-rails), this task is defined for you already. 41 | 42 | Now you can run Cucumber with Rake: 43 | 44 | ```shell 45 | rake features 46 | ``` 47 | 48 | The rake script provided with Cucumber performs much of the background magic required to get the test database and requisite 49 | libraries properly loaded. 50 | In fact, an important habit to acquire is to run Cucumber as a `rake` task immediately after performing a migration. 51 | This ensures that the test database schema is kept in sync with the development database schema. 52 | You can achieve the same effect by running `rake db:test:prepare` before your first Cucumber run following a migration 53 | but developing the habit of running `rake cucumber` or `rake cucumber:wip` is probably the better course. 54 | 55 | The Cucumber Rake task recognises the `@wip` Tag, so `rake cucumber:wip` will run only those scenarios tagged with **@wip**. 56 | 57 | For example, given a feature file containing: 58 | 59 | ``` 60 | Feature: . . . 61 | 62 | Scenario: A 63 | 64 | @wip 65 | Scenario: B 66 | 67 | Scenario: C 68 | ``` 69 | 70 | Then running the command `rake cucumber:wip` will run the Steps contained inside Scenario B only, 71 | while running `rake cucumber:ok` will run the Steps within all Scenarios other than B. 72 | 73 | ### Using Profiles in Rake Tasks 74 | 75 | For complex Feature runs that are tested often, it is nice to save the command line arguments as [Cucumber profiles](/docs/cucumber/configuration#profiles). 76 | 77 | Once you have some profiles defined, you can use them in your Rake tasks, like so: 78 | 79 | ```ruby 80 | require 'rubygems' 81 | require 'cucumber' 82 | require 'cucumber/rake/task' 83 | 84 | namespace :features do 85 | Cucumber::Rake::Task.new(:non_js) do |t| 86 | t.profile = "webrat" 87 | end 88 | 89 | Cucumber::Rake::Task.new(:selenium) do |t| 90 | t.profile = "selenium" 91 | end 92 | end 93 | ``` 94 | 95 | ### Guarding Your production machines From Cucumber 96 | 97 | Since Rake tasks are used on development and productions systems, it is generally a good idea to place a guard around your Cucumber task so your productions boxes don't need to install Cucumber. 98 | 99 | Below is an example of how to do this. This example is the Rake task that Cucumber generates for Rails projects, but the same idea applies to any project using Cucumber and Rake: 100 | 101 | ```ruby 102 | require 'rubygems' 103 | 104 | begin 105 | require 'cucumber' 106 | require 'cucumber/rake/task' 107 | 108 | Cucumber::Rake::Task.new(:features) do |t| 109 | t.cucumber_opts = "--format pretty" 110 | end 111 | 112 | task features: 'db:test:prepare' 113 | rescue LoadError 114 | desc 'Cucumber rake task not available' 115 | task :features do 116 | abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin' 117 | end 118 | end 119 | ``` 120 | 121 | ## Ruby on Rails 122 | 123 | ### cucumber-rails 124 | 125 | [cucumber-rails](https://github.com/cucumber/cucumber-rails) is a RubyGem which 126 | brings Ruby on Rails Generators for Cucumber with special support for Capybara 127 | and DatabaseCleaner. 128 | 129 | #### Installing 130 | 131 | The `cucumber:install` generator sets up Cucumber in your Rails project. It 132 | generates the necessary files in the `features/` directory. After 133 | running this generator you will also get a new rake task called `cucumber`. 134 | 135 | For more details, see `rails generate cucumber:install --help`. 136 | 137 | #### Usage 138 | 139 | By default, `cucumber-rails` runs `DatabaseCleaner.start` and 140 | `DatabaseCleaner.clean` before and after your Cucumber scenarios. This default 141 | behavior can be disabled. See the 142 | [cucumber-rails README](https://github.com/cucumber/cucumber-rails) for details. 143 | 144 | #### Resources 145 | 146 | To learn more of the tools being integrated and assisted by `cucumber-rails`, 147 | see the READMEs of 148 | [DatabaseCleaner](https://github.com/DatabaseCleaner/database_cleaner) and 149 | [Capybara](https://github.com/teamcapybara/capybara). 150 | -------------------------------------------------------------------------------- /content/search-index.md: -------------------------------------------------------------------------------- 1 | --- 2 | type: "search-index" 3 | url: "index.json" 4 | --- 5 | -------------------------------------------------------------------------------- /content/sponsors/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sponsors 3 | subtitle: Financial supporters of the Cucumber contributors 4 | weight: 1180 5 | menu: main 6 | iconClass: fas fa-money-bill-alt 7 | --- 8 | 9 | 10 | -------------------------------------------------------------------------------- /data/versions.yaml: -------------------------------------------------------------------------------- 1 | # This file contains version numbers for Cucumber 2 | # 3 | # They can be referred to with the custom Hugo shortcode, e.g. {{% version "cucumberjvm" %}} 4 | # 5 | # The "renovate:" comments help Renovate understand what we are talking about and keep the versions up to date. 6 | # See https://docs.renovatebot.com/modules/manager/regex/ 7 | 8 | cucumberjvm: "7.20.1" # renovate: datasource=maven depName=io.cucumber:cucumber-jvm 9 | cucumberscala: "6.10.4" # renovate: datasource=maven depName=io.cucumber:cucumber-jvm-scala 10 | cucumberjs: "11.1.1" # renovate: datasource=npm depName=@cucumber/cucumber 11 | cucumberruby: "9.2.0" # renovate: datasource=rubygems depName=cucumber 12 | rspec: "3.13.0" # renovate: datasource=rubygems depName=rspec 13 | testng: "7.10.2" # renovate: datasource=maven depName=org.testng:testng 14 | junit: "5.11.4" # renovate: datasource=maven depName=org.junit:junit-bom 15 | -------------------------------------------------------------------------------- /docker_shell.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | docker run -p 1313:1313 -e "CI=${CI:-false}" --volume $(pwd):/app -it cucumber/hugo:1e65815e43ac30f7d52080356fd0893a $@ 3 | -------------------------------------------------------------------------------- /layouts/shortcodes/README.md: -------------------------------------------------------------------------------- 1 | # Gherkin Internationalization Table 2 | 3 | The table can be updated automatically using make *from the root folder of 4 | the repo*: 5 | 6 | ```sh 7 | yarn upgrade 8 | make layouts/shortcodes/gherkin-i18n-table.html 9 | ``` 10 | 11 | `yarn upgrade` will upgrade `@cucumber/gherkin` to get back the last version 12 | of the file `gherkin-languages.json`. 13 | 14 | `make layouts/shortcodes/gherkin-i18n-table.html` will automatically update 15 | `gherkin-i18n-table.html` based on `gherkin-languages.json`. 16 | -------------------------------------------------------------------------------- /layouts/shortcodes/expression-parameter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /layouts/shortcodes/gherkin-i18n-table-jq.txt: -------------------------------------------------------------------------------- 1 | . as $root 2 | | ( 3 | [ 4 | to_entries | sort_by(.value.name)[] 5 | | [ 6 | " \n", (.value.name|@html), " (", (.key|@html), ")", "\n", 7 | "
\n", 8 | " \n", 9 | " \n", 10 | " \n", 11 | " \n", 12 | " \n", 13 | " \n", 14 | " \n", 15 | " \n" 16 | ] + ( 17 | [ .value 18 | | {"feature","background","scenario","scenarioOutline","examples","given","when","then","and","but","rule"} 19 | | to_entries[] 20 | | " \n", 21 | " \n", 23 | " \n" 24 | ] 25 | ) + [ 26 | " \n", 27 | "
English Keyword", (.value.name|@html), " equivalent(s)
", ([ .key ] | add), "\n", 22 | " ", ([ .value[] | "", @html, "
"] | add), "
\n", 28 | "
\n" 29 | ] 30 | | add 31 | ] 32 | | add 33 | ) 34 | | "
\n" 35 | + . 36 | + "
\n" -------------------------------------------------------------------------------- /layouts/shortcodes/stepdef-body.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layouts/shortcodes/version.html: -------------------------------------------------------------------------------- 1 | {{ index .Site.Data.versions (.Get 0) }} -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs.cucumber.io", 3 | "version": "1.0.0", 4 | "description": "docs.cucumber.io", 5 | "main": "index.js", 6 | "repository": "git@github.com:cucumber/docs.cucumber.io.git", 7 | "author": "Cucumber Ltd ", 8 | "license": "MIT", 9 | "private": true, 10 | "scripts": { 11 | "algolia": "atomic-algolia" 12 | }, 13 | "dependencies": { 14 | "@cucumber/gherkin": "30.0.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "github>cucumber/renovate-config" 5 | ], 6 | "regexManagers": [ 7 | { 8 | "fileMatch": [ 9 | "^data/versions.yaml" 10 | ], 11 | "matchStrings": [ 12 | ".*?:\\s+\"(?.*)\"\\s+#\\s+renovate: datasource=(?.+?) depName=(?.+?)\\n" 13 | ], 14 | "versioningTemplate": "{{#if versioning}}{{{versioning}}}{{else}}semver{{/if}}" 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /static/_redirects: -------------------------------------------------------------------------------- 1 | # General Category Redirects 2 | /gherkin/* https://cucumber.io/docs/gherkin/:splat 3 | /guides/* https://cucumber.io/docs/guides/:splat 4 | /training/* https://cucumber.io/school/ 5 | /cucumber/api/* https://cucumber.io/docs/cucumber/api/:splat 6 | /installation/* https://cucumber.io/docs/installation/:splat 7 | /cucumber/* https://cucumber.io/docs/cucumber/:splat 8 | /community/faq/ https://cucumber.io/docs/community/faq/ 9 | -------------------------------------------------------------------------------- /static/admin/config.yml: -------------------------------------------------------------------------------- 1 | backend: 2 | name: github 3 | repo: cucumber/docs.cucumber.io # Path to your Github repository 4 | branch: master # Branch to update (master by default) 5 | 6 | media_folder: "img/uploads" # Folder where user uploaded files should go 7 | 8 | collections: # A list of collections the CMS should be able to edit 9 | - name: "reference" # Used in routes, ie.: /admin/collections/:slug/edit 10 | label: "Reference Doc" # Used in the UI, ie.: "New Post" 11 | folder: "content/reference" # The path to the folder where the documents are stored 12 | create: true # Allow users to create new documents in this collection 13 | fields: # The fields each document in this collection have 14 | - {label: "Title", name: "title", widget: "string", tagname: "h1"} 15 | - {label: "Body", name: "body", widget: "markdown"} 16 | - {label: "Menu", name: "menu", widget: "hidden", default: "main"} 17 | - name: "tutorial" 18 | label: "Tutorial" 19 | folder: "content/tutorial" 20 | create: true 21 | fields: 22 | - {label: "Title", name: "title", widget: "string", tagname: "h1"} 23 | - {label: "Body", name: "body", widget: "markdown"} 24 | - {label: "Menu", name: "menu", widget: "hidden", default: "main"} 25 | -------------------------------------------------------------------------------- /static/admin/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Content Manager 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /static/img/BDD practices diagram (2 axes).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/BDD practices diagram (2 axes).png -------------------------------------------------------------------------------- /static/img/BDD practices diagram (2 x loops).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/BDD practices diagram (2 x loops).png -------------------------------------------------------------------------------- /static/img/BDD practices diagram - habitation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/BDD practices diagram - habitation.png -------------------------------------------------------------------------------- /static/img/BDD practices diagram.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/BDD practices diagram.graffle -------------------------------------------------------------------------------- /static/img/BDD practices diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/BDD practices diagram.png -------------------------------------------------------------------------------- /static/img/TDD-cycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/TDD-cycle.png -------------------------------------------------------------------------------- /static/img/bdd-kickstart-black-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/bdd-kickstart-black-128.png -------------------------------------------------------------------------------- /static/img/bdd-practices-diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/bdd-practices-diagram.png -------------------------------------------------------------------------------- /static/img/book-bdd-in-action.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/book-bdd-in-action.jpg -------------------------------------------------------------------------------- /static/img/book-cucumber-book.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/book-cucumber-book.jpg -------------------------------------------------------------------------------- /static/img/book-discovery.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/book-discovery.png -------------------------------------------------------------------------------- /static/img/books.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/books.png -------------------------------------------------------------------------------- /static/img/cucumber-school-black-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/cucumber-school-black-128.png -------------------------------------------------------------------------------- /static/img/cucumber-school-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/cucumber-school-logo.png -------------------------------------------------------------------------------- /static/img/discover-formulate-automate-sketch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/discover-formulate-automate-sketch.png -------------------------------------------------------------------------------- /static/img/environment-variables/idea/enter-environment-variable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/environment-variables/idea/enter-environment-variable.png -------------------------------------------------------------------------------- /static/img/environment-variables/idea/environment-variables-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/environment-variables/idea/environment-variables-field.png -------------------------------------------------------------------------------- /static/img/environment-variables/idea/run-debug-configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/environment-variables/idea/run-debug-configuration.png -------------------------------------------------------------------------------- /static/img/gosu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/gosu.png -------------------------------------------------------------------------------- /static/img/grouping-step-defs-and-helpers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/grouping-step-defs-and-helpers.png -------------------------------------------------------------------------------- /static/img/jruby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/jruby.png -------------------------------------------------------------------------------- /static/img/jython.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/jython.png -------------------------------------------------------------------------------- /static/img/mob-manifesto-v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/mob-manifesto-v3.png -------------------------------------------------------------------------------- /static/img/new-contributors-ensemble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/new-contributors-ensemble.jpg -------------------------------------------------------------------------------- /static/img/parallel-timeline-report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/parallel-timeline-report.png -------------------------------------------------------------------------------- /static/img/perl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/perl.png -------------------------------------------------------------------------------- /static/img/python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/python.png -------------------------------------------------------------------------------- /static/img/scala.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/scala.png -------------------------------------------------------------------------------- /static/img/single-source-of-truth-256x256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/single-source-of-truth-256x256.png -------------------------------------------------------------------------------- /static/img/three-practices-loops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/static/img/three-practices-loops.png -------------------------------------------------------------------------------- /themes/cucumber-hugo/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Cucumber Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/README.md: -------------------------------------------------------------------------------- 1 | 2 | Changes to the CSS should be made in `static/css/cucumber.sass`. 3 | 4 | If you make changes to the `sass`, it will be rebuilt if you run the following: 5 | 6 | yarn # install dependencies 7 | yarn build # rebuild cucumber.css 8 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/archetypes/default.md: -------------------------------------------------------------------------------- 1 | +++ 2 | +++ 3 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 |

404 - Page not found

6 |

7 | dancing dill 8 |
9 | Return Home 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 | {{ partial "navbar.html" . }} 6 | {{ partial "list-content.html" . }} 7 | 8 | 9 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 | {{ partial "navbar.html" . }} 6 | {{ partial "single-content.html" . }} 7 | 8 | 9 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 | {{- with .Content -}} 6 |
7 | {{ . | replaceRE "()" `${1} 🔗︎ ${3}` | safeHTML }} 8 |
9 | {{- end -}} 10 | 11 | 12 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/doc-search.html: -------------------------------------------------------------------------------- 1 |

2 | 3 | 4 | 5 | 6 |

7 | 8 | 15 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/gtag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/head.html: -------------------------------------------------------------------------------- 1 | 2 | {{ partial "gtag.html" . }} 3 | 4 | 5 | 6 | {{.Hugo.Generator}} 7 | {{ if .Title }} {{ .Title }} :{{ end }} Cucumber 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/language-tabs.html: -------------------------------------------------------------------------------- 1 |
2 | 13 |
14 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/list-content.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{ partial "sidebar.html" . }} 4 |
5 |
6 |
7 |

{{ .Title }}

8 |
9 | {{ .Content }} 10 |
11 | 12 |
13 | {{ range $index, $page := .Pages.ByWeight }} 14 | {{ if eq (mod (sub $index 3) 3) 0 }} 15 |
16 |
17 | {{ end }} 18 |
19 | {{ partial "page-card.html" $page }} 20 |
21 | {{ end }} 22 |
23 |
24 |
25 |
26 |

27 | You can help us improve this documentation. 28 | Edit this page. 29 |

30 |
31 |
32 |
33 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/navbar.html: -------------------------------------------------------------------------------- 1 | 41 | 42 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/page-card.html: -------------------------------------------------------------------------------- 1 | {{if ne .Dir "team/"}} 2 | 3 | {{end}} 4 | {{if .Params.external_url}} 5 | 6 | {{end}} 7 |
8 |
9 |
10 | {{if .Params.img}} 11 |
12 |
13 | Logo 14 |
15 |
16 | {{end}} 17 | {{if .Params.svg}} 18 |
19 |
20 | {{ readFile (printf "/docs/%s" .Params.svg) | safeHTML }} 21 |
22 |
23 | {{end}} 24 | {{if eq .Dir "team/"}} 25 |
26 | {{.File.BaseFileName}} 27 |
28 | {{end}} 29 |
30 |

{{.Title}}

31 | {{ if .Params.subtitle }} 32 |

{{.Params.subtitle}}

33 | {{end}} 34 | {{ if (or (.Params.twitter) (.Params.linkedin)) }} 35 |
36 | {{if eq .Dir "team/"}} 37 |

38 | {{.File.BaseFileName}} 39 |

40 | {{end}} 41 | {{ if .Params.twitter }} 42 |

43 | @{{.Params.twitter}} 44 |

45 | {{end}} 46 | {{ if .Params.linkedin }} 47 |

48 | {{.Params.linkedin}} 49 |

50 | {{end}} 51 |
52 | {{end}} 53 | {{ if .Params.implementation }} 54 |

55 | {{ if eq .Params.implementation "official"}} 56 | official 57 | {{end}} 58 | {{ if eq .Params.implementation "semi-official"}} 59 | semi-official 60 | {{end}} 61 | {{ if eq .Params.implementation "unofficial"}} 62 | unofficial 63 | {{end}} 64 | {{ if eq .Params.implementation "unmaintained"}} 65 | unmaintained 66 | {{end}} 67 |

68 | {{end}} 69 |
70 |
71 | {{if eq .Dir "team/"}} 72 |
73 | {{.Content}} 74 |
75 | {{end}} 76 |
77 | {{if .Params.card_image}} 78 |
79 |
80 | Logo 81 |
82 |
83 | {{end}} 84 |
85 | {{if .Params.external_url}} 86 | 87 | {{end}} 88 | {{if ne .Dir "team/"}} 89 | 90 | {{end}} 91 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 43 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/partials/single-content.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{ partial "sidebar.html" . }} 4 |
5 |
6 |
7 |

{{ .Title }}

8 | {{ if .Page.Params.polyglot }} 9 | {{ partial "language-tabs.html" . }} 10 | {{ end }} 11 |
12 | {{- with .Content -}}{{ . | replaceRE "()" `${1} 🔗︎${3}` | safeHTML }} 13 |
14 | {{- end -}} 15 |
16 |
17 |
18 |

19 | You can help us improve this documentation. 20 | Edit this page. 21 |

22 |
23 |
24 |
25 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/shortcodes/block.html: -------------------------------------------------------------------------------- 1 | {{ $languages := split (.Get 0) ","}} 2 | {{ $inner := .Inner }} 3 | {{ range $languages }} 4 | 5 | {{ end }} 6 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/shortcodes/card.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |

{{ .Get "title" }}

7 |
8 |
9 |
10 | {{ .Inner }} 11 |
12 |
13 |
14 |
15 | {{ .Get 16 |
17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/shortcodes/danger.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/shortcodes/note.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/shortcodes/text.html: -------------------------------------------------------------------------------- 1 | {{ $languages := split (.Get 0) ","}} 2 | {{ $inner := .Inner }} 3 | {{ range $languages }} 4 | 5 | {{ end }} 6 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/shortcodes/tip.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/layouts/shortcodes/warn.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cucumber-hugo", 3 | "description": "Hugo theme for *.cucumber.io", 4 | "author": "Cucumber Ltd", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "autoprefixer": "10.4.20", 8 | "bulma": "1.0.2", 9 | "concurrently": "9.1.0", 10 | "node-sass": "9.0.0", 11 | "postcss-cli": "11.0.0", 12 | "rimraf": "6.0.1" 13 | }, 14 | "scripts": { 15 | "build": "yarn build-clean && yarn build-sass && yarn build-autoprefix", 16 | "build-clean": "rimraf static/css/cucumber.css*", 17 | "build-sass": "node-sass --output-style expanded static/css/cucumber.sass static/css/cucumber.css.tmp", 18 | "build-autoprefix": "postcss --use autoprefixer --output static/css/cucumber.css static/css/cucumber.css.tmp", 19 | "watch": "concurrently --kill-others \"yarn build-sass --watch\" \"yarn build-autoprefix --watch\"" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/static/css/.gitignore: -------------------------------------------------------------------------------- 1 | cucumber.css.tmp 2 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/static/css/cucumber.sass: -------------------------------------------------------------------------------- 1 | @import "../../node_modules/bulma/sass/utilities/initial-variables" 2 | 3 | // Brand colours: https://github.com/cucumber-ltd/brand/blob/master/Cucumber_Brand_V1.0.pdf 4 | 5 | // Non-bulma variables 6 | $cucumber-grey-lighter: #efefef 7 | 8 | // Bulma variable overrides 9 | $blue: #004fff 10 | $orange: #ff7f00 11 | $red: #ff1245 12 | $green: #00a818 13 | $purple: #3e10af 14 | $black: #1b1d1e 15 | $grey: #65696b 16 | 17 | $primary: $green 18 | // This sets the code snippet background colour 19 | $pre-background: $cucumber-grey-lighter 20 | $code: $black !default 21 | 22 | @import "../../node_modules/bulma/bulma" 23 | @import "./pygments" 24 | 25 | .is-huge 26 | height: 128px 27 | max-height: 128px 28 | max-width: 128px 29 | min-height: 128px 30 | min-width: 128px 31 | width: 128px 32 | 33 | .algolia-autocomplete 34 | width: 100% 35 | 36 | // Override Bulma's minireset.sass so the TOC is indented 37 | li 38 | padding-left: 8px 39 | 40 | // Bulma doesn't expect these elements to have children, so we need to the default

margin 41 | .message-header, 42 | .message-body 43 | p:last-child 44 | margin-bottom: 0 45 | 46 | // give some nearly-opaque background to the language tabs 47 | .tabs 48 | li[data-language] 49 | background-color: rgba(255, 255, 255, 0.9) 50 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/static/css/pygments.sass: -------------------------------------------------------------------------------- 1 | .highlight 2 | margin-bottom: 0 !important 3 | 4 | pre 5 | margin-bottom: 1.5rem 6 | padding: 0px 7 | code 8 | padding: 0.75em 1em 9 | display: inline-block 10 | min-width: 100% 11 | 12 | .n 13 | color: $black 14 | 15 | .c, .cm, .c1 16 | color: $grey 17 | 18 | .k, .kd, .kr, .nb 19 | color: $green 20 | 21 | .kt, .mf, .mi 22 | color: $blue 23 | 24 | .nt 25 | color: $orange 26 | 27 | code.language-java 28 | .s 29 | color: $green 30 | 31 | code.language-gherkin 32 | .s 33 | color: $blue 34 | 35 | .s1 36 | color: $red 37 | 38 | code.language-xml 39 | .nt 40 | color: $blue 41 | 42 | code.language-shell 43 | background-color: $black 44 | color: $cucumber-grey-lighter 45 | 46 | .c1 47 | color: $orange 48 | 49 | .nb 50 | color: $cucumber-grey-lighter 51 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-hugo/static/favicon.ico -------------------------------------------------------------------------------- /themes/cucumber-hugo/static/img/cucumber-black-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-hugo/static/img/cucumber-black-128.png -------------------------------------------------------------------------------- /themes/cucumber-hugo/static/img/cucumber-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-hugo/static/img/cucumber-logo.png -------------------------------------------------------------------------------- /themes/cucumber-hugo/static/js/site.js: -------------------------------------------------------------------------------- 1 | ////// DOM UTILS - see http://youmightnotneedjquery.com/ 2 | 3 | function ready(fn) { 4 | if (document.readyState != 'loading'){ 5 | fn(); 6 | } else { 7 | document.addEventListener('DOMContentLoaded', fn); 8 | } 9 | } 10 | 11 | function each(parent, selector, fn) { 12 | var elements = document.querySelectorAll(selector) 13 | Array.prototype.forEach.call(elements, fn) 14 | } 15 | 16 | function addClass(el, className) { 17 | if (el.classList) 18 | el.classList.add(className); 19 | else 20 | el.className += ' ' + className; 21 | } 22 | 23 | function removeClass(el, className) { 24 | if (el.classList) 25 | el.classList.remove(className); 26 | else 27 | el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); 28 | } 29 | 30 | function hasClass(el, className) { 31 | if (el.classList) 32 | return el.classList.contains(className); 33 | else 34 | return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); 35 | } 36 | 37 | function toggleClass(el, className) { 38 | if(el.classList.toggle) { 39 | el.classList.toggle(className) 40 | } else if(hasClass(el, className)) { 41 | removeClass(el, className) 42 | } else { 43 | addClass(el, className) 44 | } 45 | } 46 | 47 | ////// Show/hide polyglot content 48 | 49 | var showHideSelectors = [ 50 | '.language-dotnet', 51 | '.text-dotnet', 52 | '.language-java', 53 | '.text-java', 54 | '.language-javascript', 55 | '.text-javascript', 56 | '.language-kotlin', 57 | '.text-kotlin', 58 | '.language-scala', 59 | '.text-scala', 60 | '.language-ruby', 61 | '.text-ruby', 62 | '.language-golang', 63 | '.text-golang', 64 | ] 65 | 66 | function showOnly(language) { 67 | // Remember 68 | localStorage.setItem('language', language) 69 | 70 | // Activate tab for language 71 | each(document, '.tabs li', function(a) { removeClass(a, 'is-active') }) 72 | var tab = document.querySelector('[data-language="' + language + '"]') 73 | addClass(tab, 'is-active') 74 | 75 | // Hide all code elements 76 | for(var i=0; i a', function(a) { 105 | var targetSelector = a.getAttribute('data-target'); 106 | a.addEventListener('click', function() { 107 | var el = document.querySelector(targetSelector); 108 | el.classList.toggle('collapsed'); 109 | }) 110 | }) 111 | 112 | var firstLi = document.querySelector('.tabs li') 113 | if(firstLi) { 114 | var language = localStorage.getItem('language') || firstLi.getAttribute('data-language') 115 | showOnly(language) 116 | } 117 | 118 | // Toggle navbar menu 119 | var burger = document.querySelector('.navbar-burger') 120 | if(burger) { 121 | burger.addEventListener('click', function() { 122 | var navbarMenu = document.getElementById(burger.dataset.target) 123 | 124 | toggleClass(burger, 'is-active') 125 | toggleClass(navbarMenu, 'is-active') 126 | }) 127 | } 128 | }) 129 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/theme.toml: -------------------------------------------------------------------------------- 1 | # theme.toml template for a Hugo theme 2 | # See https://github.com/spf13/hugoThemes#themetoml for an example 3 | 4 | name = "Cucumber Hugo" 5 | license = "MIT" 6 | licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE.md" 7 | description = "" 8 | homepage = "http://siteforthistheme.com/" 9 | tags = [] 10 | features = [] 11 | min_version = "0.20.7" 12 | 13 | [author] 14 | name = "" 15 | homepage = "" 16 | 17 | # If porting an existing theme 18 | [original] 19 | name = "" 20 | homepage = "" 21 | repo = "" 22 | -------------------------------------------------------------------------------- /themes/cucumber-hugo/tools/htmlproofer/htmlproofer.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'html-proofer' 3 | 4 | # TODO: Check that depth increases by only 1 for each header, 5 | # And that we always start with h1 (ignore the title h1) 6 | class HeaderCheck < HTMLProofer::Check 7 | IGNORE_PATHS = [ 8 | 'public/admin/index.html', 9 | 'public/index.html' 10 | ] 11 | 12 | def run 13 | return if IGNORE_PATHS.include?(@path) 14 | 15 | depth = 0 16 | count = 0 17 | @html.css('h1,h2,h3,h4,h5').each do |node| 18 | check_not_hidden(node) 19 | 20 | css_class = node.attributes['class'].value rescue nil 21 | if css_class == 'title is-1' 22 | # Ignore

generated from front matter 23 | next 24 | end 25 | node_depth = node.name.match(/h(\d)/)[1].to_i 26 | if (node_depth - depth) > 1 27 | # First header was h2, or we went from h1 to h3 without a h2, etc 28 | if depth == 0 29 | return add_issue("First header must be a h1, but it was #{node}") 30 | else 31 | return add_issue("Can't go from h#{depth} to #{node}") 32 | end 33 | end 34 | depth = node_depth 35 | end 36 | end 37 | 38 | def check_not_hidden(node) 39 | p = node 40 | while p 41 | css_class = p.attributes['class'].value rescue '' 42 | 43 | if css_class =~ /is-hidden text-(\w+)/ 44 | lang = $1 45 | add_issue("Headers are not allowed inside {{% block \"#{lang}\" %}}. Header: #{node}") 46 | break 47 | end 48 | p = p.respond_to?(:parent) ? p.parent : nil 49 | end 50 | end 51 | end 52 | 53 | $pages = [] 54 | $linked_pages = [] 55 | 56 | at_exit do 57 | orphans = $pages - $linked_pages 58 | puts "=== Orphaned pages ===" 59 | puts orphans 60 | end 61 | 62 | class OrphanCheck < HTMLProofer::Check 63 | def run 64 | if @path === 'public/documentation/index.html' 65 | $linked_pages = @html.css('a').map do |node| 66 | create_element(node).file_path 67 | end 68 | else 69 | $pages << @path 70 | end 71 | end 72 | end 73 | 74 | # To speed up local development, external links are only checked in CI: 75 | # https://app.netlify.com/sites/cucumber/settings/deploys 76 | # To enable link checks locally, define CI=true 77 | external_link_check = ENV['CI'] != 'false' 78 | options = { 79 | disable_external: !external_link_check, 80 | # https://stackoverflow.com/questions/27231113/999-error-code-on-head-request-to-linkedin 81 | http_status_ignore: [999], 82 | url_ignore: [ 83 | # Amazon often returns 503 even when a page is available. Ignore. 84 | /https:\/\/www\.amazon\.com/, 85 | # Something is not right on that site - not sure what... 86 | /https:\/\/testng\.org/, 87 | # Pull requests with new pages will link to 'edit' on master (which doesn't exist yet). Ignore! 88 | /https:\/\/github.com\/cucumber\/docs\.cucumber\.io\/edit/ 89 | ] 90 | } 91 | path = ARGV[0] || 'public' 92 | if File.file?(path) 93 | HTMLProofer.check_file(path, options).run 94 | elsif File.directory?(path) 95 | HTMLProofer.check_directory(path, options).run 96 | else 97 | raise "No such file or directory: #{path}" 98 | end 99 | -------------------------------------------------------------------------------- /themes/cucumber-sb/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /themes/cucumber-sb/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Cucumber Ltd 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /themes/cucumber-sb/README.md: -------------------------------------------------------------------------------- 1 | 2 | Changes to the CSS should be made in `static/css/cucumber.sass`. 3 | 4 | If you make changes to the `sass`, it will be rebuilt if you run the following: 5 | 6 | yarn # install dependencies 7 | yarn build # rebuild cucumber.css 8 | -------------------------------------------------------------------------------- /themes/cucumber-sb/archetypes/default.md: -------------------------------------------------------------------------------- 1 | +++ 2 | +++ 3 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 |

404 - Page not found

6 |

7 | dancing dill 8 |
9 | Return Home 10 |

11 | 12 | 13 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/_default/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 | {{ partial "navbar.html" . }} 6 | {{ partial "list-content.html" . }} 7 | {{ partial "footer.html" . }} 8 | {{ partial "scripts.html" . }} 9 | 10 | 11 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/_default/single.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 | {{ partial "navbar.html" . }} 6 | {{ partial "single-content.html" . }} 7 | {{ partial "footer.html" . }} 8 | {{ partial "scripts.html" . }} 9 | 10 | 11 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{ partial "head.html" . }} 4 | 5 | {{ partial "navbar.html" . }} 6 | 7 | {{- with .Content -}} 8 | 9 | {{ . | replaceRE "()" `${1} ${3}` | safeHTML }} 10 | 11 | {{- end -}} 12 | 13 | {{ partial "footer.html" .}} 14 | {{ partial "scripts.html" . }} 15 | 16 | 17 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/doc-search.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/gtag.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{.Hugo.Generator}} 6 | {{ if .Title }} {{ .Title }} - {{ end }}Cucumber Documentation 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 35 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/language-tabs.html: -------------------------------------------------------------------------------- 1 |
2 | 13 |
14 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/list-content.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{ partial "sidebar.html" . }} 4 |
5 |
6 |
7 | 10 |
11 | {{ .Content }} 12 |
13 | 14 |
15 |
16 | {{ range $index, $page := .Pages.ByWeight }} 17 | {{ if eq (mod (sub $index 3) 3) 0 }} 18 |
19 |
20 | {{ end }} 21 |
22 | {{ partial "page-card.html" $page }} 23 |
24 | {{ end }} 25 |
26 |
27 |
28 | 29 |
30 |

31 | You can help us improve this documentation. 32 | Edit this page. 33 |

34 |
35 |
36 |
37 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/page-card.html: -------------------------------------------------------------------------------- 1 | {{if ne .Dir "team/"}} 2 | 3 | {{end}} 4 | {{if .Params.external_url}} 5 | 6 | {{end}} 7 |
8 |
9 |
10 | {{if .Params.img}} 11 |
12 |
13 | Logo 14 |
15 |
16 | {{end}} 17 | {{if .Params.svg}} 18 |
19 |
20 | {{ readFile (printf "/docs/%s" .Params.svg) | safeHTML }} 21 |
22 |
23 | {{end}} 24 | {{if eq .Dir "team/"}} 25 |
26 | {{.File.BaseFileName}} 27 |
28 | {{end}} 29 |
30 |

{{.Title}}

31 | {{ if .Params.subtitle }} 32 |

{{.Params.subtitle}}

33 | {{end}} 34 | {{ if (or (.Params.twitter) (.Params.linkedin)) }} 35 |
36 | {{if eq .Dir "team/"}} 37 |

38 | {{.File.BaseFileName}} 39 |

40 | {{end}} 41 | {{ if .Params.twitter }} 42 |

43 | @{{.Params.twitter}} 44 |

45 | {{end}} 46 | {{ if .Params.linkedin }} 47 |

48 | {{.Params.linkedin}} 49 |

50 | {{end}} 51 |
52 | {{end}} 53 | {{ if .Params.implementation }} 54 |

55 | {{ if eq .Params.implementation "official"}} 56 | official 57 | {{end}} 58 | {{ if eq .Params.implementation "semi-official"}} 59 | semi-official 60 | {{end}} 61 | {{ if eq .Params.implementation "unofficial"}} 62 | unofficial 63 | {{end}} 64 | {{ if eq .Params.implementation "unmaintained"}} 65 | unmaintained 66 | {{end}} 67 |

68 | {{end}} 69 |
70 |
71 | {{if eq .Dir "team/"}} 72 |
73 | {{.Content}} 74 |
75 | {{end}} 76 |
77 | {{if .Params.card_image}} 78 |
79 |
80 | Logo 81 |
82 |
83 | {{end}} 84 |
85 | {{if .Params.external_url}} 86 | 87 | {{end}} 88 | {{if ne .Dir "team/"}} 89 | 90 | {{end}} 91 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/scripts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/sidebar.html: -------------------------------------------------------------------------------- 1 | 2 | 70 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/partials/single-content.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {{ partial "sidebar.html" . }} 4 |
5 |
6 |
7 | 13 |
14 | {{- with .Content -}}{{ . | replaceRE "()" `${1}${3}` | safeHTML }} 15 |
16 | {{- end -}} 17 |
18 | 19 |
20 |

21 | You can help us improve this documentation. 22 | Edit this page. 23 |

24 |
25 |
26 |
27 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/shortcodes/block.html: -------------------------------------------------------------------------------- 1 | {{ $languages := split (.Get 0) ","}} 2 | {{ $inner := .Inner }} 3 | {{ range $languages }} 4 | 5 | {{ end }} 6 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/shortcodes/card.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |

{{ .Get "title" }}

7 |
8 |
9 |
10 | {{ .Inner }} 11 |
12 |
13 |
14 |
15 | {{ .Get 16 |
17 |
18 |
19 |
20 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/shortcodes/danger.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/shortcodes/note.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/shortcodes/text.html: -------------------------------------------------------------------------------- 1 | {{ $languages := split (.Get 0) ","}}{{ $inner := .Inner }}{{ range $languages }}{{ end }} -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/shortcodes/tip.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-sb/layouts/shortcodes/warn.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

{{ .Get 0 }}

4 |
5 |
6 | {{ .Inner }} 7 |
8 |
9 | -------------------------------------------------------------------------------- /themes/cucumber-sb/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cucumber-hugo", 3 | "description": "Hugo theme for *.cucumber.io", 4 | "author": "Cucumber Ltd", 5 | "license": "MIT", 6 | "devDependencies": { 7 | "autoprefixer": "10.4.20", 8 | "bulma": "1.0.2", 9 | "concurrently": "9.1.0", 10 | "node-sass": "9.0.0", 11 | "postcss-cli": "11.0.0", 12 | "rimraf": "6.0.1", 13 | "yarn": "1.22.22" 14 | }, 15 | "scripts": { 16 | "build": "yarn build-clean && yarn build-sass && yarn build-autoprefix", 17 | "build-clean": "rimraf static/css/cucumber.css*", 18 | "build-sass": "node-sass --output-style expanded static/css/cucumber.sass static/css/cucumber.css", 19 | "build-autoprefix": "postcss --use autoprefixer --output static/css/cucumber.css static/css/cucumber.css", 20 | "watch": "concurrently --kill-others \"yarn build-sass --watch\" \"yarn build-autoprefix --watch\"" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /themes/cucumber-sb/static/css/.gitignore: -------------------------------------------------------------------------------- 1 | cucumber.css.tmp 2 | -------------------------------------------------------------------------------- /themes/cucumber-sb/static/css/cucumber.sass: -------------------------------------------------------------------------------- 1 | @import "../../node_modules/bulma/sass/utilities/initial-variables" 2 | 3 | // Brand colours: https://github.com/cucumber-ltd/brand/blob/master/Cucumber_Brand_V1.0.pdf 4 | 5 | // Non-bulma variables 6 | $cucumber-grey-lighter: #efefef 7 | 8 | // Bulma variable overrides 9 | $blue: #004fff 10 | $orange: #ff7f00 11 | $red: #ff1245 12 | $green: #00a818 13 | $purple: #3e10af 14 | $black: #1b1d1e 15 | $grey: #65696b 16 | 17 | $primary: $green 18 | // This sets the code snippet background colour 19 | $pre-background: $cucumber-grey-lighter 20 | $code: $black !default 21 | 22 | @import "../../node_modules/bulma/bulma" 23 | @import "./pygments" 24 | 25 | .is-huge 26 | height: 128px 27 | max-height: 128px 28 | max-width: 128px 29 | min-height: 128px 30 | min-width: 128px 31 | width: 128px 32 | 33 | .algolia-autocomplete 34 | width: 100% 35 | 36 | // Override Bulma's minireset.sass so the TOC is indented 37 | li 38 | padding-left: 8px 39 | 40 | // Bulma doesn't expect these elements to have children, so we need to the default

margin 41 | .message-header, 42 | .message-body 43 | p:last-child 44 | margin-bottom: 0 45 | 46 | // give some nearly-opaque background to the language tabs 47 | .tabs 48 | li[data-language] 49 | background-color: rgba(255, 255, 255, 0.9) 50 | -------------------------------------------------------------------------------- /themes/cucumber-sb/static/css/pygments.sass: -------------------------------------------------------------------------------- 1 | .highlight 2 | margin-bottom: 0 !important 3 | 4 | pre 5 | margin-bottom: 1.5rem 6 | padding: 0px 7 | code 8 | padding: 0.75em 1em 9 | display: inline-block 10 | min-width: 100% 11 | 12 | .n 13 | color: $black 14 | 15 | .c, .cm, .c1 16 | color: $grey 17 | 18 | .k, .kd, .kr, .nb 19 | color: $green 20 | 21 | .kt, .mf, .mi 22 | color: $blue 23 | 24 | .nt 25 | color: $orange 26 | 27 | code.language-java 28 | .s 29 | color: $green 30 | 31 | code.language-gherkin 32 | .s 33 | color: $blue 34 | 35 | .s1 36 | color: $red 37 | 38 | code.language-xml 39 | .nt 40 | color: $blue 41 | 42 | code.language-shell 43 | background-color: $black 44 | color: $cucumber-grey-lighter 45 | 46 | .c1 47 | color: $orange 48 | 49 | .nb 50 | color: $cucumber-grey-lighter 51 | -------------------------------------------------------------------------------- /themes/cucumber-sb/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/favicon.ico -------------------------------------------------------------------------------- /themes/cucumber-sb/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/favicon.png -------------------------------------------------------------------------------- /themes/cucumber-sb/static/img/cucumber-black-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/img/cucumber-black-128.png -------------------------------------------------------------------------------- /themes/cucumber-sb/static/img/cucumber-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/img/cucumber-logo.png -------------------------------------------------------------------------------- /themes/cucumber-sb/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/img/favicon.ico -------------------------------------------------------------------------------- /themes/cucumber-sb/static/img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/img/favicon.png -------------------------------------------------------------------------------- /themes/cucumber-sb/static/js/site.js: -------------------------------------------------------------------------------- 1 | ////// DOM UTILS - see http://youmightnotneedjquery.com/ 2 | 3 | function ready(fn) { 4 | if (document.readyState != 'loading'){ 5 | fn(); 6 | } else { 7 | document.addEventListener('DOMContentLoaded', fn); 8 | } 9 | } 10 | 11 | function each(parent, selector, fn) { 12 | var elements = document.querySelectorAll(selector) 13 | Array.prototype.forEach.call(elements, fn) 14 | } 15 | 16 | function addClass(el, className) { 17 | if (el.classList) 18 | el.classList.add(className); 19 | else 20 | el.className += ' ' + className; 21 | } 22 | 23 | function removeClass(el, className) { 24 | if (el.classList) 25 | el.classList.remove(className); 26 | else 27 | el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); 28 | } 29 | 30 | function hasClass(el, className) { 31 | if (el.classList) 32 | return el.classList.contains(className); 33 | else 34 | return new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); 35 | } 36 | 37 | function toggleClass(el, className) { 38 | if(el.classList.toggle) { 39 | el.classList.toggle(className) 40 | } else if(hasClass(el, className)) { 41 | removeClass(el, className) 42 | } else { 43 | addClass(el, className) 44 | } 45 | } 46 | 47 | ////// Show/hide polyglot content 48 | 49 | var showHideSelectors = [ 50 | '.language-dotnet', 51 | '.text-dotnet', 52 | '.language-java', 53 | '.text-java', 54 | '.language-javascript', 55 | '.text-javascript', 56 | '.language-kotlin', 57 | '.text-kotlin', 58 | '.language-scala', 59 | '.text-scala', 60 | '.language-ruby', 61 | '.text-ruby', 62 | '.language-golang', 63 | '.text-golang', 64 | ] 65 | 66 | function showOnly(language) { 67 | // Remember 68 | localStorage.setItem('language', language) 69 | 70 | // Activate tab for language 71 | each(document, '.tabs li', function(a) { removeClass(a, 'is-active') }) 72 | var tab = document.querySelector('[data-language="' + language + '"]') 73 | addClass(tab, 'is-active') 74 | 75 | // Hide all code elements 76 | for(var i=0; i li.getAttribute('data-language')) 111 | 112 | if (supportedLanguages.length >= 1) { 113 | const defaultLanguage = supportedLanguages[0] 114 | const localLanguage = localStorage.getItem('language'); 115 | const selectedLanguage = url.searchParams.get('lang'); 116 | 117 | if (supportedLanguages.includes(selectedLanguage)) { 118 | updateQueryParam(url, selectedLanguage) 119 | showOnly(selectedLanguage) 120 | } else if (supportedLanguages.includes(localLanguage)) { 121 | updateQueryParam(url, localLanguage) 122 | showOnly(localLanguage) 123 | } else { 124 | updateQueryParam(url, defaultLanguage) 125 | showOnly(defaultLanguage) 126 | } 127 | 128 | each(document, '.tabs li', function(li) { 129 | var language = li.getAttribute('data-language') 130 | li.addEventListener('click', function () { 131 | updateQueryParam(url, language) 132 | showOnly(language) 133 | }) 134 | }) 135 | } 136 | 137 | 138 | each(document, '.panel.collapsible > a', function(a) { 139 | var targetSelector = a.getAttribute('data-target'); 140 | a.addEventListener('click', function() { 141 | var el = document.querySelector(targetSelector); 142 | el.classList.toggle('collapsed'); 143 | }) 144 | }) 145 | 146 | // Toggle navbar menu 147 | var burger = document.querySelector('.navbar-burger') 148 | if(burger) { 149 | burger.addEventListener('click', function() { 150 | var navbarMenu = document.getElementById(burger.dataset.target) 151 | 152 | toggleClass(burger, 'is-active') 153 | toggleClass(navbarMenu, 'is-active') 154 | }) 155 | } 156 | }) 157 | -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-brands-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-brands-400.eot -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-brands-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-brands-400.ttf -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-brands-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-brands-400.woff -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-brands-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-brands-400.woff2 -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-light-300.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-light-300.eot -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-light-300.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-light-300.ttf -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-light-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-light-300.woff -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-light-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-light-300.woff2 -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-regular-400.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-regular-400.eot -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-regular-400.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-regular-400.ttf -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-regular-400.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-regular-400.woff -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-regular-400.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-regular-400.woff2 -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-solid-900.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-solid-900.eot -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-solid-900.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-solid-900.ttf -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-solid-900.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-solid-900.woff -------------------------------------------------------------------------------- /themes/cucumber-sb/static/webfonts/fa-solid-900.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cucumber/docs/3c93e6cee4c6164f40ed69dfe84ac440c2983120/themes/cucumber-sb/static/webfonts/fa-solid-900.woff2 -------------------------------------------------------------------------------- /themes/cucumber-sb/theme.toml: -------------------------------------------------------------------------------- 1 | # theme.toml template for a Hugo theme 2 | # See https://github.com/spf13/hugoThemes#themetoml for an example 3 | 4 | name = "Cucumber Hugo" 5 | license = "MIT" 6 | licenselink = "https://github.com/yourname/yourtheme/blob/master/LICENSE.md" 7 | description = "" 8 | homepage = "http://siteforthistheme.com/" 9 | tags = [] 10 | features = [] 11 | min_version = "0.20.7" 12 | 13 | [author] 14 | name = "" 15 | homepage = "" 16 | 17 | # If porting an existing theme 18 | [original] 19 | name = "" 20 | homepage = "" 21 | repo = "" 22 | -------------------------------------------------------------------------------- /themes/cucumber-sb/tools/htmlproofer/htmlproofer.rb: -------------------------------------------------------------------------------- 1 | require 'bundler/setup' 2 | require 'html-proofer' 3 | 4 | # TODO: Check that depth increases by only 1 for each header, 5 | # And that we always start with h1 (ignore the title h1) 6 | class HeaderCheck < HTMLProofer::Check 7 | IGNORE_PATHS = [ 8 | 'public/admin/index.html', 9 | 'public/index.html' 10 | ] 11 | 12 | def run 13 | return if IGNORE_PATHS.include?(@path) 14 | 15 | depth = 0 16 | count = 0 17 | @html.css('h1,h2,h3,h4,h5').each do |node| 18 | check_not_hidden(node) 19 | 20 | css_class = node.attributes['class'].value rescue nil 21 | if css_class == 'title is-1' 22 | # Ignore

generated from front matter 23 | next 24 | end 25 | node_depth = node.name.match(/h(\d)/)[1].to_i 26 | if (node_depth - depth) > 1 27 | # First header was h2, or we went from h1 to h3 without a h2, etc 28 | if depth == 0 29 | return add_issue("First header must be a h1, but it was #{node}") 30 | else 31 | return add_issue("Can't go from h#{depth} to #{node}") 32 | end 33 | end 34 | depth = node_depth 35 | end 36 | end 37 | 38 | def check_not_hidden(node) 39 | p = node 40 | while p 41 | css_class = p.attributes['class'].value rescue '' 42 | 43 | if css_class =~ /is-hidden text-(\w+)/ 44 | lang = $1 45 | add_issue("Headers are not allowed inside {{% block \"#{lang}\" %}}. Header: #{node}") 46 | break 47 | end 48 | p = p.respond_to?(:parent) ? p.parent : nil 49 | end 50 | end 51 | end 52 | 53 | $pages = [] 54 | $linked_pages = [] 55 | 56 | at_exit do 57 | orphans = $pages - $linked_pages 58 | puts "=== Orphaned pages ===" 59 | puts orphans 60 | end 61 | 62 | class OrphanCheck < HTMLProofer::Check 63 | def run 64 | if @path === 'public/documentation/index.html' 65 | $linked_pages = @html.css('a').map do |node| 66 | create_element(node).file_path 67 | end 68 | else 69 | $pages << @path 70 | end 71 | end 72 | end 73 | 74 | # To speed up local development, external links are only checked in CI: 75 | # https://app.netlify.com/sites/cucumber/settings/deploys 76 | # To enable link checks locally, define CI=true 77 | external_link_check = ENV['CI'] != 'false' 78 | options = { 79 | disable_external: !external_link_check, 80 | # https://stackoverflow.com/questions/27231113/999-error-code-on-head-request-to-linkedin 81 | http_status_ignore: [999], 82 | url_ignore: [ 83 | # Amazon often returns 503 even when a page is available. Ignore. 84 | /https:\/\/www\.amazon\.com/, 85 | # Something is not right on that site - not sure what... 86 | /https:\/\/testng\.org/, 87 | # Pull requests with new pages will link to 'edit' on master (which doesn't exist yet). Ignore! 88 | /https:\/\/github.com\/cucumber\/docs\.cucumber\.io\/edit/ 89 | ] 90 | } 91 | path = ARGV[0] || 'public' 92 | if File.file?(path) 93 | HTMLProofer.check_file(path, options).run 94 | elsif File.directory?(path) 95 | HTMLProofer.check_directory(path, options).run 96 | else 97 | raise "No such file or directory: #{path}" 98 | end 99 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@cucumber/gherkin@30.0.4": 6 | version "30.0.4" 7 | resolved "https://registry.yarnpkg.com/@cucumber/gherkin/-/gherkin-30.0.4.tgz#047071b3122a9fb25e073aabdbc0132e98db4ee4" 8 | integrity sha512-pb7lmAJqweZRADTTsgnC3F5zbTh3nwOB1M83Q9ZPbUKMb3P76PzK6cTcPTJBHWy3l7isbigIv+BkDjaca6C8/g== 9 | dependencies: 10 | "@cucumber/messages" ">=19.1.4 <=26" 11 | 12 | "@cucumber/messages@>=19.1.4 <=26": 13 | version "26.0.1" 14 | resolved "https://registry.yarnpkg.com/@cucumber/messages/-/messages-26.0.1.tgz#18765481cf2580066977cbe26af111458e05c424" 15 | integrity sha512-DIxSg+ZGariumO+Lq6bn4kOUIUET83A4umrnWmidjGFl8XxkBieUZtsmNbLYgH/gnsmP07EfxxdTr0hOchV1Sg== 16 | dependencies: 17 | "@types/uuid" "10.0.0" 18 | class-transformer "0.5.1" 19 | reflect-metadata "0.2.2" 20 | uuid "10.0.0" 21 | 22 | "@types/uuid@10.0.0": 23 | version "10.0.0" 24 | resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d" 25 | integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ== 26 | 27 | class-transformer@0.5.1: 28 | version "0.5.1" 29 | resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" 30 | integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== 31 | 32 | reflect-metadata@0.2.2: 33 | version "0.2.2" 34 | resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.2.2.tgz#400c845b6cba87a21f2c65c4aeb158f4fa4d9c5b" 35 | integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== 36 | 37 | uuid@10.0.0: 38 | version "10.0.0" 39 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294" 40 | integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ== 41 | --------------------------------------------------------------------------------