A Cucumber dictionary from the infrastructure is a ready-made set of Cucumber steps for automating and verifying your application, so you can write feature files without writing any step definitions yourself.
Each dictionary targets a different testing surface — for example, the Web Dictionary automates and verifies web pages with Selenium.
This page explains how to use an already-implemented dictionary. To implement a new dictionary using the framework's interfaces, see Integrating and Extending Cucumber Base Dictionary with Infrastructure instead.
Setup
Before you can use any dictionary in a project, two one-time steps are required, regardless of which dictionary (or dictionaries) you use:
1. Register the dictionary's Spring bean. Declare a @Bean method under the matching @Profile, directly in your project's Spring configuration class — one such method per dictionary you plan to use. This is written by hand for every dictionary; see the concrete example for the Web Dictionary below.
2. Declare a Cucumber-Spring context configuration class. Cucumber's Spring integration needs a class annotated @CucumberContextConfiguration that points at your Spring configuration class, so it can find the bean(s) from step 1. This step is identical for every project regardless of which dictionary you use:
@CucumberContextConfiguration
@ContextConfiguration(classes = YourSpringConfig.class)
public class CucumberSpringConfiguration {}
Once both steps are done, use the dictionary as described below.
Using it in a test
There are two ways to select which dictionary a test uses:
Per test — pass it explicitly as an argument to executeTest(...), using the @Profile name from step 1 above.
Project-wide default — set the profile name once via the dictionary.implementation.profile key in application.properties; every executeTest(...) call that doesn't pass a Dictionary argument will use it automatically.
Both forms are shown concretely for the Web Dictionary below.
Mixing multiple technologies in one scenario. Pass a comma-separated profile list to activate more than one dictionary at once, e.g. new Dictionary("web,desktop").
Note: if a call to executeTest(...) doesn't pass a FeatureFile either, it defaults to the JUnit test class name with the trailing Test stripped — without lowercasing (e.g. class TransferTest looks for a feature file named Transfer.feature, not transfer.feature).
Example: the Web Dictionary
The Web Dictionary is available from framework version 4.0.7 onward. Here are the two setup/selection steps above, concretely:
1 — Spring bean:
@Bean
@Profile("web")
public WebDictionary webDictionary() {
return new WebDictionaryImpl();
}
Per-test selection:
executeTest(
new Scenario("My scenario"),
new FeatureFile("myFeature"),
new Dictionary("web")
);
Project-wide default:
dictionary.implementation.profile=web
executeTest(
new Scenario("My scenario"),
new FeatureFile("myFeature")
);
Then write your scenario in the feature file using the Web Dictionary's sentences.
Defining Locators (UI Dictionaries)
An element identifier in a sentence tells the dictionary which element to act on. Choose it in this order:
- Visible text (recommended) — write the element's exact visible text, e.g.
"Login". No setup is needed, and the feature file reads like the screen. - Object Repository — only when there is no suitable visible text (an icon-only button, an unlabeled field, a text that repeats on the page), register the element in the Object Repository and use its key, e.g.
"loginButton". - A new sentence — when neither fits, extend the dictionary with a sentence of your own (see Adding a sentence to a dictionary below).
At run time, an identifier registered as a key in the Object Repository uses the registered locator; any other identifier is matched by exact visible text. If neither matches, the step fails.
ℹ️ Info: Desktop Dictionary: visible text is not supported — only the Object Repository applies. An unregistered identifier fails the step.
Locators with values
A locator may hold numbered placeholders — {0}, {1} — so one entry covers a family of elements. Add the values in parentheses after the key, separated by |.
# Registered in the Object Repository
When user clicks button "loginButton"
# Not registered - found by its visible text
When user clicks button "Login"
# Registered, with values for {0} and {1}
Then user sees element "gridCell(Row 3|Total)" is on page
For how to create and format the Object Repository, see: Using the Objects Repository
Adding a sentence to a dictionary
To add a sentence, extend the dictionary instead of changing it. All of its built-in sentences keep working.
1 — Extend the implementation and add the action. The subclass inherits getDriver(), getTimeout() and resolveElementLocator(...).
public class MyWebDictionaryImpl extends WebDictionaryImpl {
public void clickDeleteIconInRow(String rowText) {
By locator = By.xpath("//tr[td[normalize-space()='" + rowText + "']]//button[@aria-label='Delete']");
Waits.elementToBeClickable(getDriver(), getTimeout(), locator).click();
}
}
2 — Register the subclass as the dictionary bean, in place of the original and under the same profile:
@Bean
@Profile("web")
public MyWebDictionaryImpl webDictionary() {
return new MyWebDictionaryImpl();
}
3 — Add the sentence in a step-definitions class in your own package:
package com.myproject.steps;
public class MyWebStepDefinitions {
private final MyWebDictionaryImpl myWebDictionary;
private final ParameterProcessor parameterProcessor = new ParameterProcessor();
@Autowired
public MyWebStepDefinitions(MyWebDictionaryImpl myWebDictionary) {
this.myWebDictionary = myWebDictionary;
}
@When("user clicks delete icon in row {string}")
public void clickDeleteIconInRow(String rowText) {
if (!StepConditionHelper.canProceed()) {
return;
}
rowText = parameterProcessor.transformString(rowText);
myWebDictionary.clickDeleteIconInRow(rowText);
}
}
StepConditionHelper.canProceed() and ParameterProcessor make the new sentence behave like the built-in ones: it respects conditional steps and supports {{...}} placeholders.
4 — Pass your package to the test. It is scanned in addition to the framework's own sentences:
executeTest(
new Scenario("Delete order"),
new FeatureFile("Orders"),
new Dictionary("web"),
new PackageName("com.myproject.steps")
);
The new sentence's text must not match an existing sentence, or Cucumber fails with an ambiguous step. For Desktop, do the same with DesktopDictionaryImpl.
Dynamic values in any sentence
Any value inside quotes, in any sentence of any dictionary, can hold a placeholder that is filled in when the step runs.
Store values — {{name}}. Anything a step saved in the Store during the run:
| Saved by | Then used as |
|---|---|
user defines variable from field "orderIdField" as name "orderId" |
user enters value "{{orderId}}" in field "searchField" |
Generated values — {{$...}}:
| Placeholder | Result |
|---|---|
{{$guid}} |
A unique identifier |
{{$randomInt}} |
A random whole number |
{{$randomString}} |
8 random characters |
{{$timestamp}} |
The current time, in seconds |
Dates — {{$format}}, optionally plus or minus time from today:
| Placeholder | Result |
|---|---|
{{$dd/MM/yyyy}} |
Today |
{{$dd/MM/yyyy+5d}} |
Today plus 5 days |
{{$dd/MM/yyyy-3M}} |
Today minus 3 months |
{{$yyyy-MM-dd+1y}} |
Today plus a year, in a different format |
The format is written the way Java writes dates: dd day, MM month, yyyy year. The unit is d days, M months, y years — note the capital M, because a small m means minutes. Offsets always count from today; for a fixed date, simply write it.
Then user defines variable from field "orderIdField" as name "orderId"
When user enters value "{{orderId}}" in field "searchField"
When user selects date "{{$dd/MM/yyyy+5d}}" in field "dateField"
When user selects date "15/10/2025" in field "dateField"
Cucumber Dictionaries Currently Available
Each dictionary has its own reference page with its full sentence list, the framework version it's available from, and any dictionary-specific notes: