cucumber / cucumber-js

Cucumber for JavaScript
https://cucumber.io
MIT License
5.02k stars 1.09k forks source link

Playwright typescript cucumber-js stepdefinitions undefined but can navigate to stepdefinations from feature file #2340

Closed grf1986 closed 8 months ago

grf1986 commented 9 months ago

Hi all i am having the same issue i did all there has been done here my setup:

project: setup playwright with typescript and cucumber in VScode issue: i can navigate to stepdefinitions from feature file but when running test with npx cucumber-js src\tests\features i get:

1 scenario (1 undefined)
4 steps (4 undefined)
0m00.000s

running test without cucumber work fine

.vscode/settings.json:

{
    "cucumberautocomplete.steps": [
        "**/*.steps.ts",
    ],
    "cucumberautocomplete.syncfeatures": "**/.*feature .ts",
    "cucumberautocomplete.strictGherkinCompletion": true,
    "cucumberautocomplete.strictGherkinValidation": true,
    "cucumberautocomplete.smartSnippets": true,
    "cucumberautocomplete.stepsInvariants": true,
    "cucumberautocomplete.customParameters": [
        {
            "parameter": "{ab}",
            "value": "(a|b)"
        },
    ],
    "cucumberautocomplete.pages": {
        "users": "features/*.ts",
        "pathes": "features/*.ts",
        "main": "features/*.ts",
    },
    "cucumberautocomplete.skipDocStringsFormat": true,
    "cucumberautocomplete.formatConfOverride": {
        "And": 3,
        "But": "relative",
    },
    "cucumberautocomplete.onTypeFormat": true,
    "editor.quickSuggestions": {
        "comments": false,
        "strings": true,
        "other": true
    },
    "cucumberautocomplete.gherkinDefinitionPart": "(Given|When|Then)\\(",
    "cucumberautocomplete.stepRegExSymbol": "'"
}

feature file:

Feature:Check user is on the right page

  as a user
  I want to log in to the AppFactoryApp application
  and navigate to the aanvragen app
  so i can check if i am on the right page

  Scenario:Check if user is on the right page
    Given Go to AppFactoryApp app page
    When Login to AppFactoryApp test env
    When Click on aanvragen app
    Then Check that user is on the right page

glue code aka steps.definations:

import { Given, When, Then } from "@cucumber/cucumber";
import { test } from "../pageObjects";
import { expect } from "@playwright/test";
import { GoToApp } from "../helpers/goToApp";
import { baseURL } from "../generic/utils/environment.properties";

const gotoApp = new GoToApp();

test.describe.parallel('Navigate to aanvragen app from Appfactory', async () => {
    test('check if user is on the right page', async ({ AppFactory, page, context }) => {

        Given('Go to AppFactoryApp app page', async () => {
            await gotoApp.AppFactoryAppsUrl(page);

        });

        When('Login to AppFactoryApp test env', async () => {
            await AppFactory.loginPage.LoginToAppFactory('rgga', 'rggdrg!');
        });

        When('Click on aanvragen app', async () => {
            await AppFactory.selectAppPage.ClickOnAanvragenApp();
        });

        Then('Check that user is on the right page', async () => {
            const pages = context.pages();
            if (pages.length >= 2) {
                const aanvragenapp = pages[1];
                expect(aanvragenapp.url()).toContain(baseURL.AanvragenApp);
            }
        });

    })

});

Package.json:

{
  "name": "playwright",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "cucumber-js test"
  },
  "keywords": [],
  "author": "XXXXXX",
  "license": "ISC",
  "devDependencies": {
    "@cucumber/cucumber": "^10.0.0",
    "@cucumber/messages": "^22.0.0",
    "@playwright/test": "^1.39.0",
    "@types/jquery": "^3.5.22",
    "@types/node": "^20.8.0",
    "cucumber": "^1.3.3",
    "playwright-cucumber": "^1.0.15",
    "ts-node": "^10.9.1",
    "typescript": "^5.2.2",
    "winston": "^3.8.2"
  },
  "dependencies": {
    "playwright": "^1.39.0"
  }
}

i am using VSCode plugins see screenshots:

VS code plugins

project structure:

project structure

please help me i have stayed 48 hours on this issue :(

Originally posted by @grf1986 in https://github.com/cucumber/cucumber-js/issues/718#issuecomment-1763425778

davidjgoss commented 9 months ago

Thanks for all the detail @grf1986

The problem you have here is that both Cucumber and @playwright/test are test runners, and you can only really use one test runner at a time. In your step definitions file, the only top-level calls are to test that is imported from your other file. It's not clear what that function does, but I suspect it doesn't just run whatever function you passed in, meaning the step definitions won't be registered with Cucumber. Conversely, if you run @playwright/test, perhaps your calls to test cause a test suite/case to run, but since Cucumber is not actually running at that point, the calls to Given etc won't do anything.

I would suggest you want to use Cucumber as your test runner but still use Playwright as your browser automation tool - this is fine. Try to remove the test wrappers and just have your calls to Given etc at the root of your step definitions file. If you then run Cucumber it should at least match and run the steps. Be careful using expect from Playwright, as I think it is a kind of soft assertion and doesn't throw directly (which Cucumber would need in order to recognise a failure).

i can navigate to stepdefinitions from feature file but when running test

In case you're wondering why this works, the various editor plugins tend not to hook into Cucumber directly but use a fairly loose algorithm of looking for calls to functions called Given etc, so they show up even when mixing frameworks etc.

grf1986 commented 9 months ago

can you please give me a example i am new to this

grf1986 commented 9 months ago

i did the following:

`import { Given, When, Then } from "@cucumber/cucumber"; import { test } from "../pageObjects"; import { expect } from "@playwright/test"; import { GoToApp } from "../helpers/goToApp"; import { baseURL } from "../generic/utils/environment.properties";

import { TestCase } from "@cucumber/messages";

Given('Navigate to aanvragen app from Appfactory', async function () { Given('Check if user is on the right page', async function ({ AppFactory, page, context }) { const gotoApp = new GoToApp(page);

    Given('Go to AppFactoryApp app page', async function () {
        await gotoApp.AppFactoryAppsUrl(page);

    });

    When('Login to AppFactoryApp test env', async () => {
        await AppFactory.loginPage.LoginToAppFactory('XXXXX', 'XXXXX');
    });

    When('Click on aanvragen app', async () => {
        await AppFactory.selectAppPage.ClickOnAanvragenApp();
    });

    Then('Check that user is on the right page', async () => {
        const pages = context.pages();
        if (pages.length >= 2) {
            const aanvragenapp = pages[1];
            expect(aanvragenapp.url()).toContain(baseURL.AanvragenApp);
        }
    });

})

});`

Is this what you mean?

output:

`Warnings:

1) Scenario: Check if user is on the right page # src\tests\features\login.feature:8 ? Given Navigate to aanvragen app from Appfactory Undefined. Implement with the following snippet:

     Given('Navigate to aanvragen app from Appfactory', function () {
       // Write code here that turns the phrase above into concrete actions
       return 'pending';
     });

? Given Check if user is on the right page Undefined. Implement with the following snippet:

     Given('Check if user is on the right page', function () {
       // Write code here that turns the phrase above into concrete actions
       return 'pending';
     });

? Given Go to AppFactoryApp app page Undefined. Implement with the following snippet:

     Given('Go to AppFactoryApp app page', function () {
       // Write code here that turns the phrase above into concrete actions
       return 'pending';
     });

? When Login to AppFactoryApp test env Undefined. Implement with the following snippet:

     When('Login to AppFactoryApp test env', function () {
       // Write code here that turns the phrase above into concrete actions
       return 'pending';
     });

? When Click on aanvragen app Undefined. Implement with the following snippet:

     When('Click on aanvragen app', function () {
       // Write code here that turns the phrase above into concrete actions
       return 'pending';
     });

? Then Check that user is on the right page Undefined. Implement with the following snippet:

     Then('Check that user is on the right page', function () {
       // Write code here that turns the phrase above into concrete actions
       return 'pending';
     });

1 scenario (1 undefined) 6 steps (6 undefined) 0m00.000s`

pk commented 9 months ago

That means that Cucumber does not see your step definitions. Most likely you need amend configuration of the Cucumber and tell it where to look for the support code and your steps.

You have Feature files and Step definition files. Cucumber needs to know locations of both and you do that using configuration file.

All is well documented here: https://github.com/cucumber/cucumber-js/blob/main/docs/configuration.md

davidjgoss commented 9 months ago

You can also try enabling debug mode so you get some feedback about your config and what it finds (or doesn't find) https://github.com/cucumber/cucumber-js/blob/main/docs/debugging.md

davidjgoss commented 8 months ago

Closing as not an issue with Cucumber.