{"id":23069075,"url":"https://github.com/xanders/gherkin-steps-js","last_synced_at":"2025-04-30T04:50:18.885Z","repository":{"id":46318797,"uuid":"198093759","full_name":"Xanders/gherkin-steps-js","owner":"Xanders","description":"Write Cucumber step definitions with Gherkin syntax","archived":false,"fork":false,"pushed_at":"2022-07-18T19:56:45.000Z","size":63,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-30T04:50:04.193Z","etag":null,"topics":["bdd","cucumber","cucumber-js","cucumber-steps","gherkin","qa","tdd","test-automation","testing"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Xanders.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-07-21T18:53:26.000Z","updated_at":"2021-05-10T13:53:35.000Z","dependencies_parsed_at":"2022-08-20T13:10:26.133Z","dependency_job_id":null,"html_url":"https://github.com/Xanders/gherkin-steps-js","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xanders%2Fgherkin-steps-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xanders%2Fgherkin-steps-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xanders%2Fgherkin-steps-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xanders%2Fgherkin-steps-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xanders","download_url":"https://codeload.github.com/Xanders/gherkin-steps-js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251644827,"owners_count":21620630,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bdd","cucumber","cucumber-js","cucumber-steps","gherkin","qa","tdd","test-automation","testing"],"created_at":"2024-12-16T06:12:52.931Z","updated_at":"2025-04-30T04:50:18.867Z","avatar_url":"https://github.com/Xanders.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gherkin Steps\n\nWrite Cucumber step definitions with Gherkin – Cucumber features syntax.\n\nIt is like calling steps from steps, but Good™, not Evil™.\n\n* [Show me the code](#show-me-the-code)\n* [Why?](#why)\n* [What to do?](#what-to-do)\n* [Why not to call steps from steps?](#why-not-to-call-steps-from-steps)\n* [How to use?](#how-to-use)\n* [Reference](#reference)\n  * [Basics](#basics)\n  * [Regexp Syntax](#regexp-syntax)\n  * [Params](#params)\n  * **TODO:** [Doc Strings](#doc-strings)\n  * **TODO:** [Data Tables](#data-tables)\n  * **TODO:** [Timeouts](#timeouts)\n  * [State](#state)\n  * [Acceptance](#acceptance)\n  * **TODO:** [Iterations](#iterations)\n  * **TODO:** [Conditions](#conditions)\n  * **TODO:** [Sequences](#sequences)\n  * [Custom Helpers](#custom-helpers)\n  * [Additional Parameter Types](#additional-parameter-types)\n  * **TODO:** [Formatters](#formatters)\n  * **TODO:** [Snippets](#snippets)\n* [Changelog](https://github.com/Xanders/gherkin-steps-js/tree/master/CHANGELOG.md)\n\n## Show me the code\n\nThis is usual feature:\n\n**features/update_profile.feature**\n\n```gherkin\nFeature: User can update profile on the site\n\n  Scenario: User Alice updates her phone number\n\n    Given user Alice\n      And profile page\n     When Alice enters new phone number\n      And reloads the page\n     Then she see new phone number\n```\n\nAnd there are steps defined with Gherkin:\n\n**features/step_definitions/update_profile.steps**\n\n```gherkin\nFeature: Steps for profile updating feature\n\n  # Idea for refactoring: split to `users.steps` and `navigation.steps`\n\n  Scenario: Given user {word}\n\n    When I send request GET /\n     And click on \"Sign in\" button\n     And enter \"~param~\" into input[name=\"nickname\"]\n     And enter \"I Love Bob\" into input[name=\"password\"]\n     And click on \"Enter\" button\n\n  Scenario: Given profile page\n\n    When I send request GET /profile\n\n  Scenario: When {}enters new phone number\n\n    When I enter \"~next phone number~\" into input[name=\"phone_number\"]\n     And click on \"Update\" button\n\n  Scenario: When {}reloads the page\n\n    When I send request GET ~state $.current_url~\n\n  Scenario: Then he/she see new phone number\n\n    Then '~value from input[name=\"phone_number\"]~' should be equal to \"~last phone number~\"\n```\n\nHere:\n\n* `~param~` and `~state ...~` – built-in *step helpers*\n* `~next ...~` and `~last ...~` – sequences step helpers\n* `~value from ...~` – custom step helper, defined below\n* `should be equal to` – built-in step for acceptance\n\nGherkin Steps defined no new syntax constructions with except of step helpers.\nAlso Gherkin Steps defined a few step definitions and parameter types, described below.\n\nAnd usual basic steps:\n\n**features/step_definitions/basic_steps.js**\n\n```javascript\nconst { Given, When, Then } = require('cucumber');\n\nWhen('I send request {word} {string}', function(verb, url) {\n  // Request logic should be here, for example:\n  //   this.currect_page = engine.send(verb, url);\n  this.current_url = url;\n});\n\nWhen('(I )click on {string} button', function(label) {\n  // Click logic should be here, for example:\n  //   engine.find('button', label).click();\n});\n\nWhen('(I )enter {string} into {element}', function(value, element) {\n  // Value enter logic should be here, for example:\n  //    element.setValue(value);\n});\n```\n\nCustom step helpers may be defined in following way:\n\n**features/support/step_helpers.js**\n\n```javascript\nconst { defineHelper, callHelper } = require('gherkin-steps');\n\ndefineHelper('value from {element}', async function(element) {\n  // Get value logic should be here, for example:\n  //   return element.value();\n  return await callHelper('last phone number', this);\n});\n```\n\nAnd also usual parameter type to complete the example:\n\n**features/support/parameter_types.js**\n\n```javascript\nconst { defineParameterType } = require('cucumber');\n\ndefineParameterType({\n  name: 'element',\n  regexp: /input\\[name=\"\\w+\"\\]/, // for example: engine.PATH_REGEXP\n  transformer: path =\u003e path // for example: path =\u003e engine.find(path)\n});\n```\n\n## Why?\n\n**To write less code on underlying language, while keeping features short and readable.**\n\nThere are two common problems in my Cucumber practice:\n\n1) Programmers writes Cucumber specifications. They likes their programming language, so they writes a lot of code.\n   In the end we have beautiful **features/update_profile.feature** and huge messy imperative **features/step_definitions/thousands_of_steps.js**.\n   Team grew, QA engineers arrived, they hate programmer's language and break their heads when trying to understand step definitions.\n   Every time you say them: \"you need to write a new step\", the day of \"I want to **rewrite all the things** or lay me off\" become closer.\n\n2) QA engineers writes Cucumber specifications. On every hard step definition they call for programmers to help.\n   Programmers hates to be distracted. They write several very basic steps and say: \"You have basic blocks, you can build any feature with them\".\n   Features grew. Brave ones can read them. Nobody except for last old QA engineer can write them. Nobody can call it \"specification\".\n   In the end we have beautiful **features/step_definitions/basic_steps.js** and huge messy imperative **features/step_definitions/i_am_not_sure_what_is_this.feature**:\n\n```gherkin\nFeature: User can update profile on the site\n\n  # TODO: refactor it (2009.07.03: urgently!)\n\n  # 2014.11.27: Is this feature about users or profiles or requests or DOM elements? Anybody know?\n\n  # 2017.01.30: DO NOT CHANGE ANYTHING! DRAGONS WAS HERE!\n\n  Scenario: User Alice (maybe) updates her phone number\n\n    Given I send request with successfull response and page store GET /\n    Given I click on \"Sign in\" button with disable check\n    Given I enter \"Alice\" into input[name=\"nickname\"]\n    Given I enter \"I Love Bob\" into input[name=\"password\"]\n    Given I click on \"Enter\" button with disable check\n    Given I send request with successfull response and page store and URL store GET /profile\n     When I generate random from template \"phone_number\"\n     When I enter \"last_generated_random\" into input[name=\"phone_number\"]\n     When I click on \"Update\" button with disable check\n     When I send request with substitution from current_url with successfull response and page store GET /fake_url_see_substitution\n     Then I find element input[name=\"phone_number\"]\n     Then I check \"last_found_element\" is equal to \"last_generated_random\"\n```\n\nIn a worst case you have both problems. Good luck!\n\n## What to do?\n\n**Gherkin Steps** are here for the rescue!\n\nFeatures are still **features**: short, declarative, readable for anyone. *Specifications*.\n\nSteps are still **steps**: knowing about implementation, close to \"bare metal\".\nBut writable for both QA engineers and programmers of any language.\nBuilt from basic blocks. Debuggable.\n\n**Batteries included:**\n* [Params](#params)\n* [State](#state)\n* [Acceptance](#acceptance)\n* **TODO:** [Iterations](#iterations)\n* **TODO:** [Conditions](#conditions)\n* **TODO:** [Sequences](#sequences) powered by [faker.js](https://github.com/marak/faker.js)\n* [Custom Helpers](#custom-helpers)\n* [Additional Parameter Types](#additional-parameter-types) (like array, JSON, JSONPath, generic number)\n* **TODO:** [Formatters](#formatters) for simple debugging\n* **TODO:** [Snippets](#snippets) (someone use them?)\n\nStandard Gherkin features are also supported:\n* [Cucumber Expressions](#basics) ([what is it?](https://cucumber.io/blog/announcing-cucumber-expressions))\n* [Regexp Syntax](#regexp-syntax)\n* **TODO:** [Doc Strings](#doc-strings)\n* **TODO:** [Data Tables](#data-tables)\n* **TODO:** [Timeouts](#timeouts)\n\nIn any moment you can move Cucumber backend to any other underlying language without pain: only few steps should be re-written (and target language should support Gherkin Steps).\n\n**Note:** Gherkin Steps are only supported on JavaScript for now, sorry! But volunteers are welcome. :D\n\n## Why not to call steps from steps?\n\nBecause it is Evil™:\nhttps://cucumber.io/docs/guides/anti-patterns/#support-for-conjunction-steps\n\nAnd why not \"to use the features of your programming language\" as said in the article? See [Why?](#why) section above for an answer.\n\n## How to use?\n\nOh, you know:\n\n```bash\nnpm install --save-dev gherkin-steps\n```\n\nOr with [Yarn](https://yarnpkg.com):\n\n```bash\nyarn add gherkin-steps --dev\n```\n\nThen in `package.json` scripts:\n\n```json\n{\n  ...\n  \"scripts\": {\n    ...\n    \"test\": \"cucumber-js --require-module gherkin-steps/register --require 'features/support/world.js' --require 'features/**/*.js' --require 'features/**/*.steps'\",\n    ...\n  },\n  ...\n}\n```\n\nOr in `cucumber.js`:\n\n```javascript\nlet arguments = [\n  \"--require-module gherkin-steps/register\", // for Gherkin Steps support\n  \"--require 'features/support/world.js'\", // load World at first\n  \"--require 'features/**/*.js'\", // load basic steps and support files\n  \"--require 'features/**/*.steps'\", // load steps with Gherkin syntax\n  // formatters and other options\n].join(' ');\n\nmodule.exports = {\n  default: arguments\n};\n```\n\nThen just add some files with `.steps` extension into `step_definitions` folder.\n\nRefer to [features](https://github.com/Xanders/gherkin-steps-js/tree/master/features) folder in this repo for examples.\n\n**Important:** Requiring `gherkin-steps/register` module will add support for syntax only. In order to use additional features like [State](#state), [Acceptance](#acceptance) or [Additional Parameter Types](#additional-parameter-types), please add following line to your `features/support/world.js`:\n\n```javascript\nrequire('gherkin-steps/all');\n```\n\nYou also can include certain features only, like this:\n\n```javascript\nrequire('gherkin-steps/lib/state');\nrequire('gherkin-steps/lib/acceptance');\nrequire('gherkin-steps/lib/parameter_types');\nrequire('gherkin-steps/lib/parameter_types/json'); // or even more granular\n```\n\nMake sure to require World before other support files.\n\n**Note:** Cucumber.js `5.x.x` only supported for now. Volunteers are welcome!\n\n## Reference\n\n### Basics\n\nEvery `.steps` file should follow standard Gherkin structure:\n* `Feature` keyword on the top\n* One or more `Scenario` keywords under `Feature`\n* Any number of `Given`/`When`/`Then`/`And`/`But` keywords under each `Scenario`\n* Optional comments, started with `#`\n\nThere are some differences from the `.feature` file:\n* `Feature` description is ignored by the library\n* `Rule` keyword is ignored by the library\n* `Scenario Outline` and `Background` keywords are not allowed (please create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you have ideas how to use them)\n\n`Scenario` description should start with `Given`, `When` or `Then` keyword. Then *Cucumber Expression* (see introduction [here](https://cucumber.io/blog/announcing-cucumber-expressions) and reference [here](https://cucumber.io/docs/cucumber/cucumber-expressions)) or *Regular Expression* (see details [below](#regexp-syntax)) should follow. This expression will be used for step definition.\n\n`Scenario` description *may* have ` (X params)` postfix. It is not part of the expression. See [params](#params) section for details.\n\n`Scenario` body may consist of both steps defined with Gherkin and steps defined with basic language. So be careful:\n\n```gherkin\nFeature: This description will be ignored, so I can write silly things\n\n  Scenario: Given cucumber expression here\n\n    Given cucumber expression here\n\n    # TODO: make this recursion executed by random to make debugging funnier\n```\n\nYou can use non-English language in `.steps`, just like in the `.features`. But, unfortunately, params postfix and built-in step helpers are available only in English for now. Volunteers are welcome!\n\n### Params\n\nSteps defined with Gherkin may have arguments – `params` in this library terms.\n\nTo define params you can use same techniques as in any usual step definition: `{parameter_types}` for *Cucumber Expressions* and captured `(groups)` for *Regular Expressions*.\n\nTo use arguments in steps you should use one of step helpers:\n* `~param~` if there was only one argument in the definition\n* `~param 1~`, `~param 2~`, `~param 3~`, etc. if there was several arguments in the definition\n\n**Note 1**: For semantic purposes you cannot use `~param~` when there are several arguments and `~param 1~` when there is one argument.\n\nExample:\n\n```gherkin\n  Scenario: Given a step with {int} argument that works\n\n    Then ~param~ should be equal to 1\n\n  Scenario: Then step with {int} arguments should {word} too\n\n    Then ~param 1~ should be equal to 2\n     And \"~param 2~\" should be equal to \"work\"\n```\n\nUsage:\n\n```gherkin\n  Scenario: Try to use steps with arguments\n\n    Given a step with 1 argument that works\n     Then step with 2 arguments should work too\n```\n\nThere is no rules to use `\"~param~\"` instead of `~param~` – step helper does not know anything about quotes, they will be added to the step text \"as is\". They used in this example for semantic purposes.\n\n**Note 2**: When parser see step helper in the step text, it will just replace helper call with the call result in the text. If helper returns non-string value, it will be converted to string. At first, library searches for `toCucumberString` function – it should be sync or Promise-based async (including defined with `async` keyword), have no arguments and return string. If such function is not defined, library will just call usual `toString` function.\nSo if you want to use some Parameter Types with non-`s =\u003e s` transformer, be sure to provide `toCucumberString` function to the result of transformation to keep consistency between step calls:\n\n```javascript\nconst { defineParameterType } = require('cucumber');\n\ndefineParameterType({\n  name: 'heavy_object',\n  regexp: /heavy object (\\d+)/,\n  transformer: id =\u003e ({ id: Number(id), toCucumberString: () =\u003e `heavy object ${id}` })\n});\n```\n\nThis will work great with step:\n\n```gherkin\n  Scenario: Given a step which parse and store {heavy_object}\n\n    When I save ~param~ in the storage\n```\n\n**Note 3**: Gherkin Steps cannot always determine params number correctly. For example:\n\n```gherkin\n  Scenario: Given a very strange Cucumber Expression with {int} argument and non-escaped `{` sign\n\n  # Error \"function uses multiple asynchronous interfaces\" will be thrown\n```\n\nIn this case you can add special postfix to help library understand correct params number. Possible postfixes are:\n* ` (no params)`\n* ` (1 param)`\n* ` (X params)`, where `X` is integer \u003e= 2\n\nThis postfix will be removed from scenario description before expression parsing, so do not include it in the step call.\n\nCorrect example:\n\n```gherkin\n  Scenario: Given a very strange Cucumber Expression with {int} argument and non-escaped `{` sign (1 param)\n\n  # Works!\n```\n\n### Regexp Syntax\n\nWhile *Cucumber Expression* are recommended, you can still use old good *Regular Expressions*. Just start and end expression after `Given`, `When` or `Then` keyword in `Scenario` description with `/`:\n\n```gherkin\n  Scenario: Given /^some (great|ugly) regexp$/\n\n    Then \"~param~\" should be equal to \"great\"\n```\n\nIf you want to add ` (X params)` postfix, it should be placed *after* trailing `/`:\n\n```gherkin\n  Scenario: Given /(?!hardcore )regexp without params/ (no params)\n\n  # Note: This example won't work since lookahead/lookbehind does not supported by Cucumber\n```\n\nGherkin Steps params parser can determine number of arguments when using usual `(groups)`, named `(?\u003cname\u003egroups)` (names just ignored by Cucumber) and non-captured `(?:groups)`, but not other group kinds like lookahead/lookbehind groups, but they are not supported by Cucumber anyway. So you'll not need the postfix in most of cases. Please refer to [params](#params) section for details about this postfix.\n\n### Doc Strings\n\n**This function is under development yet.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for priority.\n\n### Data Tables\n\n**This function is under development yet.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for priority.\n\n### Timeouts\n\n**This function is under development yet.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for priority.\n\n### State\n\nMost of tests should store some state between steps and common way to do it is to use World object. Gherkin Steps have built-in instruments to manage a state in the World object.\n\nFirst of all, this library uses JSONPath [concept](https://goessner.net/articles/JsonPath) and [library](https://github.com/dchester/jsonpath) to perform any operations with a state. Please, follow given links if you're not familiar with them.\n\nThere are three ways to interact with state in Gherkin Steps:\n1) **Step** `Then {structured_type} should be stored as {}` to set new state\n2) **Parameter Types** `{jsonpath}` and `{jsonpath_array}` to pass state values into definition\n3) **Step Helpers** `~state {jsonpath}~` and `~state {jsonpath_array}~` to insert state values into step text before expression matching\n\nSee [Additional Parameter Types](#additional-parameter-types) section for details about `{structured_type}`, `{jsonpath}` and `{jsonpath_array}`.\n\nExample:\n\n```gherkin\n  Scenario: Given {word} state tests\n  # Hint: the word should be \"great\"\n\n    Then {\"some\": \"great\", \"json\": [1, 2, 3, 4]} should be stored as $.fixtures\n     And $.fixtures..[?(@ == \"~param~\")] should exists\n     And [$.fixtures.json[?(@ \u003e 3)]] should not be empty\n     And {\"an_answer\": ~state $.fixtures.json[(@.length - 1)]~~state $.fixtures.json[1]~} should be equal to {\"an_answer\": 42}\n     And [~state [$.fixtures.json[:2]]~] should be equal to [1, 2]\n```\n\nThe main difference between `{jsonpath}` and `~state {jsonpath}~` is the moment of parsing:\n* In the first case JSONPath expression included in the step text, so you should use `{jsonpath}` Parameter Type in the step definition, but also you can use step helpers like `~param X~` in the JSONPath query.\n  It is useful when you need a value itself.\n* In the second case step text will be modified before matching, so you can use final types like `{number}` or `{string}` in the step definition, but you cannot use step helpers inside step helpers.\n  It is useful when a value is the part of other object.\n\nIt is recommended to name keys in state with `underscore_notation`, not `camelCasedNotation` for two reasons:\n* Better readability for humans, which is priority for Cucumber\n* Better consistency between implementations, easier to change underlying language\n\n### Acceptance\n\nAcceptance steps allows you to check values without custom steps in underlying language at all.\n\nFollowing acceptance steps are built-in:\n\n* `Then {structured_type} should be equal to {structured_type}`\n* `Then {structured_type} should not be equal to {structured_type}`\n* `Then {jsonpath} should exists`\n* `Then {jsonpath} should not exists`\n* `Then {jsonpath_array} should be empty`\n* `Then {jsonpath_array} should not be empty`\n\nSee [Additional Parameter Types](#additional-parameter-types) section for details about `{structured_type}`, `{jsonpath}` and `{jsonpath_array}`.\n\nUse the power of JSONPath to filter out any data you want before pass to acceptance step. See examples and links to JSONPath docs in [State](#state) section.\n\nFeel free to create an [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you have any questions for existing or ideas for new acceptance steps.\n\n### Iterations\n\n**This function is under development yet.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for priority.\n\nIterations will let you control the execution flow.\n\n### Conditions\n\n**This function is under development yet.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for priority.\n\nConditions will let you control the execution flow.\n\n### Sequences\n\n**This function is under development yet.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for priority.\n\nSequences in a separated module will provide helpers to generate fake data with [faker.js](https://github.com/marak/faker.js).\n\n### Custom Helpers\n\nYou can add own helpers to use in step definitions.\nThey works only in `.steps` files, not in `.features`, and only in step body (under `Scenario` keyword), not in step title (right after `Scenario` keyword).\nUse tilde (`~`) symbol to call helper. You can escape tilde inside and outside helper with backslash (`\\`). There is no way to escape backslash before tilde, please create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you need such feature.\n\nFor example, you want to be able to sum numbers:\n\n```gherkin\n    Then ~sum of 2 and 2~ should be equal to 4\n```\n\nUse `defineHelper` function of the package to define the helper.\nIt is recommended to place such definitions into `features/support/step_helpers.js`. If you has several groups of helpers, use the `step_helpers` folder and files with `_helpers` postfix instead: `features/support/step_helpers/users_helpers.js`.\n\n`defineHelper` function receives two arguments:\n* `pattern` – can be both Cucumber Expression and regexp, just like in a step definition\n* `callback` – can be both sync or async function\n\n**Note:** Only Promise-based async functions are supported (including defined with `async` keyword). Callback-based async functions are not planned to be supported.\n\n```javascript\nconst { defineHelper } = require('gherkin-steps');\n\ndefineHelper('sum of {number} and {number}', (a, b) =\u003e a + b);\n```\n\nIn `callback` function keyword `this` will refer to current `World` unless this function was an arrow function (which does not have own `this`).\n\nIt is recommended to write the helper's pattern as close to native language as possible. Spaces are welcome, underscores are not. You can use non-English patterns too, of course.\n\nIf several patterns will match for one helper call, exception will be thrown.\n\n---\n\nThere is also public `callHelper` function in the package. It can be useful in case when you want to call one helper from another.\n\nFor example, you can make a workaround for Cucumber Expressions limitation: parameter type cannot be optional.\n\n```javascript\nconst { defineHelper } = require('gherkin-steps');\n\ndefineHelper('param( {int})', (position = 1) =\u003e ...); // =\u003e Error: Parameter types cannot be optional\n```\n\nInstead, just define two helpers:\n\n```javascript\nconst { defineHelper, callHelper } = require('gherkin-steps');\n\ndefineHelper('param {int}', position =\u003e ...);\ndefineHelper('param', () =\u003e callHelper('param 1'));\n```\n\n`callHelper` function receives two arguments:\n* `text` – to match helper pattern\n* `world` – to pass into helper callback and parameter types transformers (make no sense when they are arrow functions)\n\nThe return value is always `Promise`.\n\n### Additional Parameter Types\n\nThis library provides following built-in [parameter types](https://cucumber.io/docs/cucumber/cucumber-expressions/#parameter-types):\n* `json` to match JSON objects like `{\"some\": \"json\"}` or `[\"army\", \"of\", 2]`\n* `jsonpath` to match JSONPath queries like `$.key[0]` and return first matched value\n* `jsonpath_array` to return all matched values, use square brackets around query like this: `[$.key[*]]`\n* `number` to match human-readable forms of numbers: both integers and floats, and also some named numbers like `-5`, `3.14`, `.5`, `Two`, `zero` (which has alias `no`, for example: `Then Alice has no bytes left to encrypt`)\n* `array` to match human-readable form of arrays: `Alice and Bob`, `1, 2, 3` (numbers will be parsed with human-readable parser from `number` parameter type), `A, B and C` (or `A, B, and C` – you can use comma before \"and\" when there is three or more elements)\n* `structured_type` to match any of `jsonpath_array`, `jsonpath`, `json`, `string` (built-in Cucumber type, string with quotes), `number` or `array` types\n\n### Formatters\n\n**This is feature proposal.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for implementation.\n\nCustom formatters will help you with debugging.\n\n### Snippets\n\n**This is feature proposal.** Create [issue](https://github.com/Xanders/gherkin-steps-js/issues) if you want to help or vote for implementation.\n\nCustom snippets for code examples in case of unknown step.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxanders%2Fgherkin-steps-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxanders%2Fgherkin-steps-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxanders%2Fgherkin-steps-js/lists"}