Skip to content

Conversation

@fijijavis
Copy link
Contributor

@fijijavis fijijavis commented Feb 9, 2026

Motivation/Description of the PR

Problem

BDD step definitions require explicit await on all I.* method calls, even when the return value isn't needed. Without await, actions execute out of order because the step function completes before queued recorder actions finish.

This contradicts the documented behavior and differs from how regular CodeceptJS scenarios work, where the recorder handles promise chaining automatically.

Minimal Reproducible Example

Feature File

Feature: BDD Promise Chain Bug Demo
  Demonstrates that I.say() output appears out of order without await

  Scenario: Output appears in wrong order
    Given I am on the CodeceptJS homepage
    When I click on the Quickstart link
    Then I should see the Quickstart page
    And I verify the page title

Stepdef

const { I } = inject();

Given('I am on the CodeceptJS homepage', () => {
  I.amOnPage('https://codecept.io');
  I.say('Step 1: Navigated to homepage');
});

When('I click on the Quickstart link', () => {
  I.click('Quickstart');
  I.say('Step 2: Clicked Quickstart');
});

Then('I should see the Quickstart page', () => {
  I.see('Quickstart');
  I.say('Step 3: Verified Quickstart visible');
});

Then('I verify the page title', () => {
  I.seeInTitle('CodeceptJS');
  I.say('Step 4: Verified title');
});

Actual Output (npx codeceptjs run --features --steps)

> npx codeceptjs run --steps --features

CodeceptJS v3.7.6 #StandWithUkraine
Using test root "/Users/******/repos/codecept-sandbox"

BDD Promise Chain Bug Demo --
/Users/******/repos/codecept-sandbox/features/codecept.feature
    Demonstrates that I.say() output appears out of order without await
  Output appears in wrong order
  Scenario()
   Given I am on the CodeceptJS homepage ""
   When I click on the Quickstart link ""
   Then I should see the Quickstart page ""
   And I verify the page title ""
   Step 1: Navigated to homepage
   Step 2: Clicked Quickstart
   Step 3: Verified Quickstart visible
   Step 4: Verified title
  ✔ OK in 3218ms

Expected Output

> npx codeceptjs run --steps --features 

CodeceptJS v3.7.6 #StandWithUkraine
Using test root "/Users/******/repos/codecept-sandbox"

BDD Promise Chain Bug Demo --
/Users/******/repos/codecept-sandbox/features/codecept.feature
    Demonstrates that I.say() output appears out of order without await
  Output appears in wrong order
  Scenario()
   Given I am on the CodeceptJS homepage ""
   Step 1: Navigated to homepage
   When I click on the Quickstart link ""
   Step 2: Clicked Quickstart
   Then I should see the Quickstart page ""
   Step 3: Verified Quickstart visible
   And I verify the page title ""
   Step 4: Verified title
  ✔ OK in 10297ms

Root Cause

In gherkin.js function awaits the step function but doesn't wait for the recorder promise chain to complete:

await fn(...fn.params)
// Recorder actions are still queued and executing...
step.status = 'passed'  // Step marked complete too early

Solution

After awaiting the step function, also await recorder.promise() to ensure all queued actions complete before the step finishes. This aligns BDD step execution with how hooks in asyncWrapper.js already handle the recorder (see injectHook which returns recorder.promise()).

After this fix:

  • await is only needed when you need the return value (e.g., await I.grabTextFrom())
  • Actions without return values work correctly without await
  • Output appears in the correct order
  • Behavior matches the documentation examples which don't use await

Related Documentation

From https://codecept.io/bdd/#step-definitions - the examples show step definitions without await

Given(/I have product with \$(\d+) price/, (price) => {
  I.amOnPage('/products');
  productPage.create({ price });
  I.click('Add to cart');
});

Applicable helpers: None

Applicable plugins: None

Type of change

  • 🔥 Breaking changes
  • 🚀 New functionality
  • 🐛 Bug fix
  • 🧹 Chore
  • 📋 Documentation changes/updates
  • ♨️ Hot fix
  • 🔨 Markdown files fix - not related to source code
  • 💅 Polish code

Checklist:

  • Tests have been added
  • Documentation has been added (Run npm run docs)
  • Lint checking (Run npm run lint)
  • Local tests are passed (Run npm test)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant