2

I am trying to build a cypress BDD framework. I've think I've created the feature and step definition file correctly. When I run the the test with npx cypress run --spec cypress/integration/examples/shoppingCart.feature --headed --browser chrome, I get the following result here in this video , the vid is about 20sec long.

I wasn't sure what to think so I did another video that was a process of elimination and looking at the BDD set up. I'm still unsure (this one is about 8 mins long).

I will add the feature file, step definition file and error message.

I am totally puzzled.

Error message

`1) End to End shopping cart
       User can purchase items and have them delivered to shipping address:
     Error: Step implementation missing for: I am on the Ecommerce page
      at Context.resolveAndRunStepDefinition (http://localhost:54824/__cypress/tests?p=cypress/integration/examples/shoppingCart.feature:12277:11)
      at Context.eval (http://localhost:54824/__cypress/tests?p=cypress/integration/examples/shoppingCart.feature:11603:35)
`

Feature file

Scenario: User can purchase items and have them delivered to shipping address

Given I am on the Ecommerce page
When I add the mobile handsets to the shopping cart
And I verify the total price of shopping cart
Then I select the checkout button
When I will select my shipping location
And I agree to the terms and conditions checkbox
When I select the Purchase button
Then I will see an alert stating my order was successful, plus an ETA delivery

Step Definition file

/// <reference types="Cypress" />

import { Given,When,Then,And } from "cypress-cucumber-preprocessor/steps";
import Homepage from "../../../support/pageObjects/Homepage";
import orderSummaryPage from "../../../support/pageObjects/orderSummaryPage";
import completeOrderPage from "../../../support/pageObjects/completeOrderPage";
 
const homepage = new Homepage()
const StartCheckout = new orderSummaryPage()
const CompleteOrder = new completeOrderPage()
 
Given ( 'I am on the Ecommerce page', () => {
 
    cy.visit(Cypress.env('url')+"/angularpractice/")
    
    })
 
When('I add the mobile handsets to the shopping cart',function () {
 
        homepage.getShopTab().click() 
    
        this.data.mobileHandset.forEach(function(element) {// this custom commad will add items to your cart
    
              cy.AddToCart(element)  
            }); 
    
    
    StartCheckout.getBasketCheckoutButton().click()
    
    } )//end of step 
 
And('I verify the total price of shopping cart',() => {
 
    //calculate shopping cart here
    let sum=0
       
    CompleteOrder.getProductCost().each(($e1, index, $list) =>{
    
      const unitCost=$e1.text()  
      let res= unitCost.split(" ") 
      res= res[1].trim() 
      sum=Number(sum)+Number(res)
      
    }).then(function() 
    {
      cy.log(sum)
    
    })
    
    CompleteOrder.getBasketTotalCost().then(function(element)
    {
      const shopCartTotal=element.text()  
      var res= shopCartTotal.split(" ") 
      var total= res[1].trim() 
      expect(Number(total)).to.equal(sum)
    
    })
    
    
    } )//end of step
 
Then('I select the checkout button',() => {
 
    StartCheckout.getStartCheckoutButton().click()
 
} )//end of step
 
When('I will select my shipping location',() => {
 
    CompleteOrder.getShippingCountry().type('United Kingdom')
    CompleteOrder.getShippingCountryConfirm().click()
 
} )//end of step
 
And('I agree to the terms and conditions checkbox',()=> {
 
    CompleteOrder.getTermsConditionsCheckbox().click({force: true})
 
})//end of step 
 
When('I select the Purchase button',()=> {
 
    CompleteOrder.getPurchaseButton().click()
 
})
 
Then('I will see an alert stating my order was successful, plus an ETA delivery',()=> {
 
    CompleteOrder.getPurchaseAlert().then(function(element){
 
      
        const actualText= element.text()
       expect(actualText.includes('Success')).to.be.true
    
      }) 
 
})

I'm sure I even created the BDD framework in the right place.

enter image description here

Update:

I was just asked about the non global step definitions in my package.json (I only copied from the 'script' section onwards).
Taking a quick look I don't even see it.

 "scripts": {
    "open": "cypress open",
    "scripts": "cypress run",
    "headTest": "cypress run --headed ",
    "chromeTest": "cypress run --browser chrome",
    "firefoxTest": "cypress run --browser firefox",
    "edgeTest": "cypress run --browser edge",
    "testDashboard": "cypress run --record --key 1642c226-ca7f-49c3-b513-da4ee9222ca8 --parallel",
    "clean:reports": "rm -R -f cypress/reports && mkdir cypress/reports && mkdir cypress/reports/mochareports",
    "pretest": "npm run clean:reports",
    "combine-reports": "mochawesome-merge ./cypress/reports/mocha/*.json > cypress/reports/mochareports/report.json",
    "generate-report": "marge cypress/reports/mochareports/report.json -f report -o cypress/reports/mochareports",
    "posttest": "npm run combine-reports && npm run generate-report",
    "test": "npm run scripts || npm run posttest"
  },
  "cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": true
  },
  
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "cypress": "^7.4.0",
    "cypress-cucumber-preprocessor": "^4.1.3"
  },
  "dependencies": {
    "cypress-multi-reporters": "^1.5.0",
    "mocha": "^9.0.0",
    "mochawesome": "^6.2.2",
    "mochawesome-merge": "^4.2.0",
    "mochawesome-report-generator": "^5.2.0",
    "start-server-and-test": "^1.12.5"
  }
}
Zoe
  • 27,060
  • 21
  • 118
  • 148
fypnlp
  • 1,372
  • 4
  • 18
  • 41
  • What is your `"nonGlobalStepDefinitions"` flag set to in your `cypress.json` ? – Alapan Das Jul 05 '21 at 08:45
  • @AlapanDas Here is is the `nonGlobalStepDefinitions` I've added them to my original question. Taking a quick look, I don't see anything that jumps out at me that indicates I have them. – fypnlp Jul 05 '21 at 08:54
  • I am sorry my bad, what I meant was can you check your `package.json` whether `nonGlobalStepDefinitions` is mentioned there? is it true or false ? – Alapan Das Jul 05 '21 at 08:56
  • @AlapanDas No problem :0) . Let me update my question with this information – fypnlp Jul 05 '21 at 08:57
  • @AlapanDas Just added the package.json information as requested. – fypnlp Jul 05 '21 at 09:04

7 Answers7

3

Add the stepDefinitions option to the configuration,

"cypress-cucumber-preprocessor": {
  "nonGlobalStepDefinitions": true,
  "stepDefinitions": "cypress/integration/examples/BDD"
},
2

I set up your files and debugged through the source code.

Where should the step files be?

Basically, in loader.js this line

const stepDefinitionsToRequire = getStepDefinitionsPaths(filePath)
  .map((sdPath) => `require('${sdPath}')`); 

returns an empty array with your setup.

Digging into getStepDefinitionsPaths, and ignoring common steps for the moment, this line

let nonGlobalPath = getStepDefinitionPathsFrom(filePath);

is responsible for deciding where the steps files come from (filePath is the feature file full path).

and getStepDefinitionPathsFrom.js is just

return filePath.replace(path.extname(filePath), "")

which just removes the extension from

.../cypress/integration/examples/BDD/shoppingCart.feature

to give

.../cypress/integration/examples/BDD/shoppingCart

Then on this line nonGlobalPath is turned into a glob pattern to get all files of type .js, .ts, or .tsx

const nonGlobalPattern = `${nonGlobalPath}/**/*.+(js|ts|tsx)`;

which gives

.../cypress/integration/examples/BDD/shoppingCart/**/*.+(js|ts|tsx)

Conclusion: the step files must be in a folder with the same name as the feature file (in your case cypress/integration/examples/BDD/shoppingCart/) - except if you modify the commonPath setting (see below).

The step definition files can be named anything, as long as they have the correct extension. All files in that folder get searched for step definitions.

There is no need to move files up into the integration folder.

Fix #1

Create a new folder cypress/integration/examples/BDD/shoppingCart/ and move shoppingCartStepDef.js into it.


Config setting

  • stepDefinitions by itself has no effect on the steps location, but clearly it should from the documentation. This looks like a bug introduced by some change.

  • nonGlobalStepBaseDir affects the common steps path (which contains steps used across many features, e.g login), but not the path specific to the shoppingCart feature. Again, a bug due to the above problem.

  • commonPath seems to work as long as it points directly to the step definitions. The glob pattern **/*.+(js|ts|tsx) usage also has a bug - the pattern omits a trailing / which means the ** part (indicating any subfolder) is ineffective (See the difference between line 28 and the preceding line 26)

Fix #2

Set the commonPath config option to the folder containing the step definitions

"commonPath": "cypress/integration/examples/BDD/"

and you tests will work.

  • Wow! Thanks for the response. So are you saying this I am having this problem because it looks like my feature and step definition file appear to be in different locations to the the plugin? However, both feature and step definition files are in the same folder. I so am confused why it can't see them. I'm totally puzzled. Excuse my ignorance a number of things went over my head, can you tell me in the simplest terms possible 'how do I fix this?' – fypnlp Jul 06 '21 at 13:36
  • Yeah, sorry about the length of it. I'll make some mods. –  Jul 06 '21 at 21:16
  • A side note, because this plugin uses a file preprocessor you will need to restart the Cypress runner between changes to config. –  Jul 06 '21 at 22:28
  • 1
    Also there's a [pull request](https://github.com/TheBrainFamily/cypress-cucumber-preprocessor/pull/578) that looks like it will fix the bugs in configuration paths. –  Jul 06 '21 at 22:35
  • So basically the bug isn't with my coding. It's actually with this version of the plugin - I've uncovered a bug. Is that right? So, your doing fix and when I restart my VS studio and run the BDD code again, it should work this time. This that right? – fypnlp Jul 07 '21 at 14:54
  • Sorry I misunderstood. So basically, download the updated version of the with the fix and run my test again and it should work. Is the right? – fypnlp Jul 08 '21 at 10:03
2

I was able to resolve this issue by doing the following:

I raised a ticket with the Developer as I noticed a NUMBER of people were all experiencing the same issue. The developer found they had a bug, fixed it and released a new version.

I had another issue after the new release and was able to fix that by:

I created a new folder under BDD called shopping cart. so it integrations/BDD/shoppingCart

Then I added the following to the package.json

 },
  "cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": false,
    "stepDefinitions": "cypress/integration/BDD"
  },
fypnlp
  • 1,372
  • 4
  • 18
  • 41
2

According to TheBrainFamily/cypress-cucumber-preprocessor/issues/596, use a folder matching the feature file

enter image description here

  • thank you. It's reading the step definition file. So I can finally move on from this issue.!! – fypnlp Jul 14 '21 at 19:16
1

I think these changes will help. From your error I can tell is that the Feature file is not able to find your step definitions.

  1. Change the name of the integration/examples to integration. Because of what I see from the cypress pre-processor plugins page, the tests are being searched under cypress/integration.

  2. Again referring to the cypress pre-processor plugins page, the recommended way of writing a step definition file is that the steps definitions are searched from a directory with the same name as your .feature file.

So in your case, your .feature file is at cypress/integration/BDD/shoppingCart.feature. Now create a folder by the same name as the feature file inside the BDD folder cypress/integration/BDD/shoppingCart and inside that place your step definitions file there.

Alapan Das
  • 17,144
  • 3
  • 29
  • 52
  • both files have the same name, and are written exactly the same. However, I will double check just to be sure. Thank you I really appreciate you. – fypnlp Jul 05 '21 at 09:43
  • your `shoppingCartStepDef.js` file should be under `cypress/integration/BDD/shoppingCart`. – Alapan Das Jul 05 '21 at 09:45
0

If the feature file is unable to read the .js script file then try to add the following in the package.json file.

When you define correct folder hierarchy then it will be able to detect and run the the script in the test runner of cypress. Like i have new folder with name "Drayxchange" so i added it like this below:

"cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": false,
    "stepDefinitions": "cypress/integration/Drayxchange"
  }, 
0

Add below code into the package.json file:

"cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": false,
    "stepDefinitions": "filepath"
  }, 
Jeremy Caney
  • 7,102
  • 69
  • 48
  • 77
  • Thank you for contributing to the Stack Overflow community. This may be a correct answer, but it’d be really useful to provide additional explanation of your code so developers can understand your reasoning. This is especially useful for new developers who aren’t as familiar with the syntax or struggling to understand the concepts. **Would you kindly [edit] your answer to include additional details for the benefit of the community?** – Jeremy Caney May 09 '23 at 00:38
  • It looks like there are already two of this answer posted! – Giacomo May 09 '23 at 00:42