Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support feature files in a sub directory #788

Closed
3 tasks done
FDIM opened this issue Aug 4, 2022 · 6 comments
Closed
3 tasks done

Support feature files in a sub directory #788

FDIM opened this issue Aug 4, 2022 · 6 comments

Comments

@FDIM
Copy link

FDIM commented Aug 4, 2022

Current behavior

In our project we have sub folders with feature files in integration folder. This used to work with previous package, but gives an error with this one.

image

This has been very fun to debug :)

In this process I actually ended up moving from webpack to esbuild files as I could not make it work with webpack v5. Now I can share a useful stack trace:

`[ERROR] [plugin feature] The "path" argument must be of type string. Received null

../node_modules/common-ancestor-path/index.js:14:4:
  14 Γöé   : parse(a).root !== parse(b).root ? null
     Γò╡     ^

at validateString (internal/validators.js:124:11)
at parse (path.js:818:5)
at commonAncestorPath (C:\ffd\abcdefget\node_modules\common-ancestor-path\index.js:14:5)
at Array.reduce (<anonymous>)
at Object.module.exports [as default] (C:\ffd\abcdefget\node_modules\common-ancestor-path\index.js:17:38)
at compile (C:\ffd\abcdefget\node_modules\@badeball\cypress-cucumber-preprocessor\lib\template.js:36:55)
at C:\ffd\abcdefget\node_modules\@badeball\cypress-cucumber-preprocessor\esbuild.js:13:60
at callback (C:\ffd\abcdefget\node_modules\esbuild\lib\main.js:993:28)
at handleRequest (C:\ffd\abcdefget\node_modules\esbuild\lib\main.js:721:30)

This error came from the "onLoad" callback registered here:

../node_modules/@badeball/cypress-cucumber-preprocessor/esbuild.js:10:18:
  10 Γöé             build.onLoad({ filter: /\.feature$/ }, async (args) => {
     Γò╡                   ~~~~~~

at setup (C:\ffd\abcdefget\node_modules\@badeball\cypress-cucumber-preprocessor\esbuild.js:10:19)
at handlePlugins (C:\ffd\abcdefget\node_modules\esbuild\lib\main.js:855:23)
at Object.buildOrServe (C:\ffd\abcdefget\node_modules\esbuild\lib\main.js:1149:7)
at C:\ffd\abcdefget\node_modules\esbuild\lib\main.js:2110:17
at new Promise (<anonymous>)
at Object.build (C:\ffd\abcdefget\node_modules\esbuild\lib\main.js:2109:14)
at Object.build (C:\ffd\abcdefget\node_modules\esbuild\lib\main.js:1956:51)
at Object.cypressESBuildFilePreprocessor [as handler] (C:\ffd\abcdefget\node_modules\@bahmutov\cypress-esbuild-preprocessor\src\index.js:68:33)
at invoke (C:\Users\abcdef\AppData\Local\Cypress\Cache\8.5.0\Cypress\resources\app\packages\server\lib\plugins\child\run_plugins.js:22:16)
at C:\Users\abcdef\AppData\Local\Cypress\Cache\8.5.0\Cypress\resources\app\packages\server\lib\plugins\util.js:45:14
at tryCatcher (C:\Users\abcdef\AppData\Local\Cypress\Cache\8.5.0\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\util.js:16:23)
at Function.Promise.attempt.Promise.try (C:\Users\abcdef\AppData\Local\Cypress\Cache\8.5.0\Cypress\resources\app\packages\server\node_modules\bluebird\js\release\method.js:39:29)
at Object.wrapChildPromise (C:\Users\abcdef\AppData\Local\Cypress\Cache\8.5.0\Cypress\resources\app\packages\server\lib\plugins\util.js:44:23)
at Object.wrap (C:\Users\abcdef\AppData\Local\Cypress\Cache\8.5.0\Cypress\resources\app\packages\server\lib\plugins\child\preprocessor.js:28:8)
at execute (C:\Users\abcdef\AppData\Local\Cypress\Cache\8.5.0\Cypress\resources\app\packages\server\lib\plugins\child\run_plugins.js:119:27)

Desired behavior

Build should work as normal and not issue a cryptic error message. Webpack version literally threw The "path" argument must be of type string. Received null with stack trace originating in internal node package!

My current workaround is to patch template.js file, specifically the place that assigns value to implicitIntegrationFolder.

{
        // workaround to support sub folders in integration folder
        file: './node_modules/@badeball/cypress-cucumber-preprocessor/lib/template.js',
        find: 'const implicitIntegrationFolder = (0, assertions_1.assertAndReturn)((0, common_ancestor_path_1.default)(...(0, cypress_configuration_1.getTestFiles)(configuration).map(path_1.default.dirname)), "Expected to find a common ancestor path");',
        replace: `const implicitIntegrationFolder = (0, assertions_1.assertAndReturn)((0, common_ancestor_path_1.default)(...(0, cypress_configuration_1.getTestFiles)(configuration).map(path_1.default.dirname).filter(p => p.endsWith('/integration'))), "Expected to find a common ancestor path");`
    }

Test code to reproduce

Simply create a sub folder in integration folder and add a feature file there to reproduce this issue.

Versions

  • Cypress version: 8.5.0
  • Preprocessor version: 12.0.0
  • Node version: 16.15.1

Checklist

  • I've read the FAQ.
  • I've read Instructions for logging issues.
  • I'm not using cypress-cucumber-preprocessor@4.3.1 (package name has changed and it is no longer the most recent version, see #689).
@badeball
Copy link
Owner

badeball commented Aug 4, 2022

I'm not able to reproduce your issue. Can you provide me an example that fails?

@gonzmed
Copy link

gonzmed commented Aug 4, 2022

Same issue, i think it is a Windows issue when using glob and common-ancestor-path.
...getTestFiles(configuration).map(path.dirname) returns
[
'C:/Foo/1',
'C:/Foo/2',
'C:/Foo/3',
'C:/Foo/4',
]
but should be
[
'C:\Foo\1',
'C:\Foo\2',
'C:\Foo\3',
'C:\Foo\4',
]

commonAncestorPath use delimiter from path which is based on OS which in windows is \ this causes parse to throw null exception

@FDIM
Copy link
Author

FDIM commented Aug 4, 2022

@badeball I tried to reproduce the issue at home and I could not :/ I forked and pushed updated example that I will test on work PC tomorrow.

Few things that I should have mentioned:

  • I'm on windows (enterprise world...)
  • we do not use cypress.config.ts, instead we start cypress programmatically together with multiple others things (mock server, sso mock server)

@kchiron
Copy link

kchiron commented Aug 8, 2022

Hello everyone,

EDIT: here an example repository to reproduce https://github.com/kchiron/cypress-preprocessor-tests

I reproduce the issue within my project. I have also needed to switch from webpack to esbuild as @FDIM did to get more information about the error :).

This is what I got :

node_modules/common-ancestor-path/index.js:17:37:
      17 │ module.exports = (...paths) => paths.reduce(commonAncestorPath)
         ╵   

followed by :

 This error came from the "onLoad" callback registered here:
    node_modules/@badeball/cypress-cucumber-preprocessor/esbuild.js:10:18:
      10 │             build.onLoad({ filter: /\.feature$/ }, async (args) => {
         ╵                   ~~~~~~

Our testing projet is organized as follow :

e2e-tests/
    features/
         feature_01/
              awesome.feature
         feature_02/
              misc/
                  lonely.feature
        great.feature
    web/
         cypress/
             integrations/
             cypress.config.ts
             package.json
    mobile/
        ... appium magic used in there ...
    sdk/
         ... dart magic used in there ...

Our tests are written in gherkin language, we use cucumber framework to bind features with sdk folder, or mobile folder or web folder (depends on where we want to run our tests). This folder organization worked fine under cypress-cucumber-preprocessor: 7.0, we are currently trying to migrate :).

Here is the content of the cypress.config.ts :

export default defineConfig({
  e2e: {
    setupNodeEvents,
    baseUrl: 'http://localhost:3000',
    chromeWebSecurity: false,
    scrollBehavior: 'center',
    videosFolder: 'cypress/reports',
    screenshotsFolder: 'cypress/reports',
    specPattern: '../features/',
    supportFile: false,
  },
})

async function setupNodeEvents(
  on: Cypress.PluginEvents,
  config: Cypress.PluginConfigOptions
): Promise<Cypress.PluginConfigOptions> {
  await addCucumberPreprocessorPlugin(on, config)

  on(
      "file:preprocessor",
      createBundler({
        plugins: [createEsbuildPlugin(config)],
      })
  );
  return config
}

I also kept this block in my package.json file :

  "cypress-cucumber-preprocessor": {
    "nonGlobalStepDefinitions": false,
    "step_definitions": "cypress/integration",
    "commonPath": "cypress/integration",
    "cucumberJson": {
      "generate": true,
      "outputFolder": "cypress/reports",
      "fileSuffix": ""
    }
  }

I tried to move all the content of the features folder into web/cypress/ but nothing changed, I still got the same error.

I run my tests within the folder web/ using this command line :

npm run tags --tags="@myTag"

which calls a npm script defined in package.json :

"tags": "cypress run -e TAGS=$npm_config_tags --browser chrome",

This is the list of all dependance I used, if it might help:

note: I kept cypress-cucumber-preprocessor: 4.0.1 because TableDefinition used in step definitions were not recognized otherwise. I use this dependance only for TableDefinition, I use @badeball/cypress-cucumber-preprocessor for everything else.

  "devDependencies": {
    "@cucumber/cucumber": "^7.1.0",
    "@cypress/webpack-preprocessor": "5.11.1",
    "@faker-js/faker": "6.3.1",
    "@testing-library/cypress": "^8.0.3",
    "@types/cypress-cucumber-preprocessor": "4.0.1",
    "@types/fs-extra": "9.0.13",
    "@types/node": "14.18.5",
    "@types/tough-cookie": "4.0.2",
    "@typescript-eslint/eslint-plugin": "5.22.0",
    "@typescript-eslint/parser": "5.22.0",
    "axios": "0.27.2",
    "cross-env": "7.0.3",
    "cypress": "10.4.0",
    "date-fns": "2.28.0",
    "eslint": "8.15.0",
    "eslint-config-prettier": "8.5.0",
    "eslint-plugin-cypress": "2.12.1",
    "eslint-plugin-prettier": "4.0.0",
    "fs-extra": "10.1.0",
    "google-libphonenumber": "3.2.27",
    "got": "11.8.5",
    "lint-staged": "10.5.4",
    "node-polyfill-webpack-plugin": "1.1.4",
    "npm-run-all": "4.1.5",
    "path": "0.12.7",
    "prettier": "2.6.2",
    "tough-cookie": "4.0.0",
    "ts-loader": "9.3.0",
    "typescript": "4.6.4",
    "webpack": "5.72.0"
  },
  "dependencies": {
    "@badeball/cypress-cucumber-preprocessor": "12.0.0",
    "@bahmutov/cypress-esbuild-preprocessor": "latest",
    "moment": "2.29.4",
    "moment-with-locales-es6": "1.0.1",
    "tsconfig-paths-webpack-plugin": "3.5.2"
  }

Have a nice day :)

@FDIM
Copy link
Author

FDIM commented Aug 8, 2022

@badeball I finally managed to reproduce the issue. For some reason if I have multiple files in a sub-folder, I'll get an error:

image

If I remove "sub copy.feature" file, then it works again.

The only code change I've done to webpack-ts example is to make it run with cypress 8.5, it's probably the same with v10.

badeball added a commit that referenced this issue Aug 8, 2022
badeball added a commit that referenced this issue Aug 8, 2022
badeball added a commit that referenced this issue Aug 8, 2022
@badeball
Copy link
Owner

badeball commented Aug 8, 2022

This has been fixed in v12.0.1.

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

No branches or pull requests

4 participants