diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index c1eeec0c4b9b..2f2378305926 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -5,6 +5,7 @@ _Released 1/2/2024 (PENDING)_ **Bugfixes:** +- Now 'node_modules' will not be ignored if a project path or a provided path to spec files contains it. Fixes [#23616](https://github.com/cypress-io/cypress/issues/23616). - When generating assertions via Cypress Studio, the preview of the generated assertions now correctly displays the past tense of 'expected' instead of 'expect'. Fixed in [#28593](https://github.com/cypress-io/cypress/pull/28593). ## 13.6.2 @@ -15,6 +16,7 @@ _Released 12/26/2023_ - Fixed a regression in [`13.6.1`](https://docs.cypress.io/guides/references/changelog/13.6.1) where a malformed URI would crash Cypress. Fixes [#28521](https://github.com/cypress-io/cypress/issues/28521). - Fixed a regression in [`12.4.0`](https://docs.cypress.io/guides/references/changelog/12.4.0) where erroneous `
` tags were displaying in error messages in the Command Log making them less readable. Fixes [#28452](https://github.com/cypress-io/cypress/issues/28452). +- Now 'node_modules' will not be ignored if a project path or a provided path to spec files contains it. Fixes [#23616](https://github.com/cypress-io/cypress/issues/23616). **Performance:** diff --git a/packages/data-context/src/sources/FileDataSource.ts b/packages/data-context/src/sources/FileDataSource.ts index 52b07410e46b..7c2b1d52f6be 100644 --- a/packages/data-context/src/sources/FileDataSource.ts +++ b/packages/data-context/src/sources/FileDataSource.ts @@ -49,7 +49,9 @@ export class FileDataSource { return globPattern }) - const ignoreGlob = (globOptions.ignore ?? []).concat('**/node_modules/**') + const nodeModulesInGlobPath = ([] as string[]).concat(glob).some((globPattern) => globPattern.includes('node_modules')) + const ignoreNodeModules = !!((cwd.includes('node_modules') || nodeModulesInGlobPath)) + const ignoreGlob = (globOptions.ignore ?? []).concat(ignoreNodeModules ? [] : '**/node_modules/**') if (os.platform() === 'win32') { // globby can't work with backwards slashes diff --git a/packages/data-context/test/unit/sources/FileDataSource.spec.ts b/packages/data-context/test/unit/sources/FileDataSource.spec.ts index 98da6e245d3f..7ec85e44063f 100644 --- a/packages/data-context/test/unit/sources/FileDataSource.spec.ts +++ b/packages/data-context/test/unit/sources/FileDataSource.spec.ts @@ -100,7 +100,7 @@ describe('FileDataSource', () => { expect(files).to.have.length(3) }) - it('always ignores files within node_modules', async () => { + it('by default ignores files within node_modules', async () => { const nodeModulesPath = path.join(projectPath, 'node_modules') await fs.mkdir(nodeModulesPath) @@ -118,6 +118,40 @@ describe('FileDataSource', () => { expect(files).to.have.length(2) }) + it('does not ignores files within node_modules, if node_modules is in the glob path', async () => { + const nodeModulesPath = path.join(projectPath, 'node_modules') + + await fs.mkdir(nodeModulesPath) + await fs.writeFile(path.join(nodeModulesPath, 'module-script-1.js'), '') + await fs.writeFile(path.join(nodeModulesPath, 'module-script-2.js'), '') + const files = await fileDataSource.getFilesByGlob( + projectPath, + '**/(node_modules/)?*script-*.js', + { ignore: ['./scripts/**/*'] }, + ) + + // scripts at root (2 of them) and scripts at node_modules should be found + // and ./scripts is explicitly ignored + expect(files).to.have.length(4) + }) + + it('does not ignores files within node_modules, if node_modules is in the project path', async () => { + const nodeModulesPath = path.join(projectPath, 'node_modules') + + await fs.mkdir(nodeModulesPath) + await fs.writeFile(path.join(nodeModulesPath, 'module-script-1.js'), '') + await fs.writeFile(path.join(nodeModulesPath, 'module-script-2.js'), '') + await fs.writeFile(path.join(nodeModulesPath, 'module-script-3.js'), '') + const files = await fileDataSource.getFilesByGlob( + nodeModulesPath, + '**/*script-*.js', + { ignore: ['./scripts/**/*'] }, + ) + + // only scripts at node_modules should be found, since it is the project path + expect(files).to.have.length(3) + }) + it('converts globs to POSIX paths on windows', async () => { const windowsSeperator = '\\' @@ -254,6 +288,64 @@ describe('FileDataSource', () => { ) }) + it('does not ignore node_modules, if the working dir is located inside node_modules', async () => { + const files = await fileDataSource.getFilesByGlob( + '/node_modules/project/', + '/cypress/e2e/**.cy.js', + ) + + expect(files).to.eq(mockMatches) + expect(matchGlobsStub).to.have.been.calledWith( + ['/cypress/e2e/**.cy.js'], + { + ...defaultGlobbyOptions, + cwd: '/node_modules/project/', + ignore: [], + }, + ) + }) + + it('does not ignore node_modules, if one of glob paths contains node_modules', async () => { + const files = await fileDataSource.getFilesByGlob( + '/', + [ + '/node_modules/cypress/e2e/**.cy.js', + '/cypress/e2e/**.cy.js', + ], + ) + + expect(files).to.eq(mockMatches) + expect(matchGlobsStub).to.have.been.calledWith( + [ + 'node_modules/cypress/e2e/**.cy.js', + 'cypress/e2e/**.cy.js', + ], + { + ...defaultGlobbyOptions, + cwd: '/', + ignore: [], + }, + ) + }) + + it('uses supplied ignore options, when node_modules are not ignored', async () => { + const files = await fileDataSource.getFilesByGlob( + '/node_modules/project/', + '/node_modules/test_package/e2e/**.cy.js', + { ignore: ['ignore/foo.*', '/ignore/bar.*'] }, + ) + + expect(files).to.eq(mockMatches) + expect(matchGlobsStub).to.have.been.calledWith( + ['/node_modules/test_package/e2e/**.cy.js'], + { + ...defaultGlobbyOptions, + cwd: '/node_modules/project/', + ignore: ['ignore/foo.*', '/ignore/bar.*'], + }, + ) + }) + it('uses supplied globby options', async () => { const files = await fileDataSource.getFilesByGlob( '/',