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

Custom location of cypress.config.ts crash on spec update in component tests #26400

Closed
ghost opened this issue Apr 3, 2023 · 20 comments · Fixed by #27320
Closed

Custom location of cypress.config.ts crash on spec update in component tests #26400

ghost opened this issue Apr 3, 2023 · 20 comments · Fixed by #27320
Assignees
Labels
CT Issue related to component testing Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team.

Comments

@ghost
Copy link

ghost commented Apr 3, 2023

Current behavior

The onSpecsChange handler in the CypressCTWebpackPlugin file calculates the location of the indexHtmlFile based on the project root, not the location of the cypress.config.ts file.
If the config file is located at a location other than the project root, trying to update the spec file while it's opened in the runner results in a crash with an error provided in the logs section below (rarely it doesn't fail on the first attempt but then fails on the second one).

Desired behavior

The indexHtmlFile location is calculated based on the location of the cypress.config.ts file where it's declared. not the project root which may be a completely different path

Test code to reproduce

I cannot provide our project code, however, you can scaffold any component testing structure where the config file is not located in the project root and try to update the spec that's being run by the runner at the moment

For example, our structure is as follows

package.json,
package-lock.json
src,
test
  cypress
    specs
    cypress.config.ts
    support
      component-index.html
    ...otherFiles

and indexHtmlFile in the cypress.config.ts file is set to support/component-index.html

Cypress Version

12.9.0

Node version

v18.15.0

Operating System

macOS Ventura 13.3

Debug Logs

Error: ENOENT: no such file or directory, utime '/Users/{user}/work/{repo}/support/component-index.html'
    at utimesSync (node:fs:2061:3)
    at EventEmitter.CypressCTWebpackPlugin.onSpecsChange (/Users/{user}/Library/Caches/Cypress/12.9.0/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/webpack-dev-server/dist/CypressCTWebpackPlugin.js:70:13)
    at EventEmitter.emit (node:events:513:28)
    at EventEmitter.emit (node:domain:489:12)
    at EventEmitter. (/Users/{user}/Library/Caches/Cypress/12.9.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/child/dev-server.js:9:21)
    at EventEmitter.emit (node:events:513:28)
    at EventEmitter.emit (node:domain:489:12)
    at process. (/Users/{user}/Library/Caches/Cypress/12.9.0/Cypress.app/Contents/Resources/app/packages/server/lib/plugins/util.js:33:22)
    at process.emit (node:events:513:28)
    at process.emit (node:domain:489:12)
    at process.emit.sharedData.processEmitHook.installedValue [as emit] (/Users/{user}/Library/Caches/Cypress/12.9.0/Cypress.app/Contents/Resources/app/node_modules/@cspotcode/source-map-support/source-map-support.js:745:40)
    at emit (node:internal/child_process:937:14)
    at processTicksAndRejections (node:internal/process/task_queues:83:21)

Other

This issue was actually already reported but discussion stopped: #24398 (comment)
I did some debugging and found the issue at the path /Users/{user}/Library/Caches/Cypress/12.9.0/Cypress.app/Contents/Resources/app/node_modules/@cypress/webpack-dev-server/dist/CypressCTWebpackPlugin.js line 70 where the project root (which is always the project root folder where package.json and package-lock.json are located) and the indexHtmlFile property in our case is indexHtmlFile: support/component-index.html are concatenated and the result is /Users/{user}/work/{repo-name}/support/component-index.html which doesn't exist in our project structure
image
From what I gathered, changes done in this PR influence this

@ghost ghost changed the title Custom locations of cypress.config.ts crash on spec update in component tests Custom location of cypress.config.ts crash on spec update in component tests Apr 3, 2023
@lmiller1990
Copy link
Contributor

Uh oh - I think you are right, the fix in #25861 (fixes one issue) introduced another. We should be able to calculate the component-index.html without relying on projectRoot in the way we do today. Great debugging.

@lmiller1990 lmiller1990 added the CT Issue related to component testing label Apr 4, 2023
@astone123
Copy link
Contributor

Yep, thanks @nikolayeasygenerator, routing this to the CT team

@astone123 astone123 removed their assignment Apr 4, 2023
@nagash77 nagash77 added Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team. and removed routed-to-ct labels Apr 19, 2023
@electrofLy
Copy link

what would be a potential workaround for this?

@lmiller1990
Copy link
Contributor

Good question... ideally we'd rewrite this part to not have that issue:

utimesSync(path.join(this.projectRoot, this.indexHtmlFile), new Date(), new Date())

You can also customize the indexHtmlFile location, see here. You might be able to change that to make Cypress look in the correct place, using the correct placed relative path.

@electrofLy
Copy link

electrofLy commented Jun 16, 2023

@lmiller1990 I am using an nx workspace, where they are providing this function. It also customizes the indexHtmlFile accordingly among other stuff. Unfortunately it also sets the projectRoot so after a spec changes it joins the 2 paths where it creates a path like C:\codePath\codePath\cypress\support\component-index.html for the indexHtmlFile. For some reason the wrong path is generated only after a spec changes. Why does it work the first time? Does it set the path differently initially?

@ghost
Copy link
Author

ghost commented Jun 16, 2023

@lmiller1990 I am using an nx workspace, where they are providing this function. It also customizes the indexHtmlFile accordingly among other stuff. Unfortunately it also sets the projectRoot so after a spec changes it joins the 2 paths where it creates a path like C:\codePath\codePath\cypress\support\component-index.html for the indexHtmlFile. For some reason the wrong path is generated only after a spec changes. Why does it work the first time? Does it set the path differently initially?

For now we worked around this by creating a symlink to the config file in the root folder
Regarding the why, I don't remember exactly as I researched this issue a while ago but seems like it just doesn't use that dev server plugin during initial bundling

@lmiller1990
Copy link
Contributor

Why does it work the first time? Does it set the path differently initially?

Not sure - it might be because this code is only called on save, not initial startup.

Regarding the why, I don't remember exactly as I researched this issue a while ago but seems like it just doesn't use that dev server plugin during initial bundling

It definitely uses this plugin during initial bundling, but I suspect some part of the plugin is only called on save/hot reload, not startup. Hm...

Is this actually a bug in Cypress, or in the Nx integration? Should we be patching the Nx plugin?

@dflor003
Copy link

Getting this bug as well after upgrading to NX/Angular 16 with a dedicated NX library for component tests. It seems to be duplicating the path if we set an absolute path to the component-index.html and it only happens when you make a change in watch mode.

The error shows that it's duplicating the path to component-index.html:

Error: ENOENT: no such file or directory, utime 'C:\Projects\my-app\app\libs\testing\component-tests\C:\Projects\my-app\app\libs\testing\component-tests\cypress\support\component-index.html'
    at utimesSync (node:fs:2061:3)
    at EventEmitter.CypressCTWebpackPlugin.onSpecsChange (C:\Users\dflor\AppData\Local\Cypress\Cache\12.16.0\Cypress\resources\app\node_modules\@packages\server\node_modules\@cypress\webpack-dev-server\dist\CypressCTWebpackPlugin.js:70:13)
    at EventEmitter.emit (node:events:513:28)
    at EventEmitter.emit (node:domain:489:12)
    at EventEmitter. (C:\Users\dflor\AppData\Local\Cypress\Cache\12.16.0\Cypress\resources\app\node_modules\@packages\server\lib\plugins\child\dev-server.js:9:21)

Here's my cypress config:

import { nxComponentTestingPreset } from '@nx/angular/plugins/component-testing';
import { defineConfig } from 'cypress';
import { join } from 'path';

const base = nxComponentTestingPreset(__filename);
export default defineConfig({
  viewportWidth: 1024,
  viewportHeight: 768,
  component: {
    ...base,
    video: false,
    indexHtmlFile: join(__dirname, './cypress/support/component-index.html'),
    devServer: {
      ...base.devServer,
      options: {
        ...base.devServer.options,
        projectConfig: {
          ...base.devServer.options.projectConfig,
          buildOptions: {
            ...base.devServer.options.projectConfig.buildOptions,
            assets: [
              'apps/my-app/src/favicon.ico',
              'apps/my-app/src/robots.txt',
              'apps/my-app/src/assets',
            ],
            styles: ['apps/my-app/src/styles.scss'],
          },
        },
      },
    },
  },
});

@lmiller1990 lmiller1990 self-assigned this Jun 29, 2023
@lmiller1990
Copy link
Contributor

@dflor003 what's the minimal reproduction to make an Nx project that exhibits this error? I can spend time fixing it this week if I've got a repro.

I'm not an Nx guy yet and it's quite a lot to learn, if you can either shoot me a repo with the error or the commands to make one I can try to fix it.

@dflor003
Copy link

Let me see if I can reproduce it in an NX app from scratch.

@ghost
Copy link
Author

ghost commented Jul 12, 2023

By the way, completely forgot to mention, we use Vue in our application so this is definitely not Angular-specific

@lmiller1990
Copy link
Contributor

Great - if you can post a minimal reproduction, that'd help tremendously.

@ghost
Copy link
Author

ghost commented Jul 17, 2023

I can reproduce it following the structure from the initial issue description so it should probably do the trick

@lmiller1990
Copy link
Contributor

@lmiller1990
Copy link
Contributor

utimesSync(path.join(this.projectRoot, this.indexHtmlFile), new Date(), new Date())

This is the problem. The obvious issue is how do we know where to look? I wonder if we can create a temporary file, include it in the webpack compilation, then just touch that.

@lmiller1990
Copy link
Contributor

Actually this is NOT the problem - I tried using a temp file, but now a new issue - still cannot find indexHtml:

ERROR in   Error: Child compilation failed:
  Module not found: Error: Can't resolve '/Users/lachlanmiller/code/dump/cypress-test-tiny/cypress/cypress/support/component-index.html' in '/Users/lachlanmiller/code/dump/cypress-test-tiny/cypress'

Double cypress is the issue now:

cypress-test-tiny/cypress/cypress/support/component-index.html

@lmiller1990
Copy link
Contributor

I fixed it! #27320

@kazamov
Copy link

kazamov commented Aug 3, 2023

utimesSync(path.join(this.projectRoot, this.indexHtmlFile), new Date(), new Date())

This is the problem. The obvious issue is how do we know where to look? I wonder if we can create a temporary file, include it in the webpack compilation, then just touch that.

I have the same issue on Windows. I am using the Cypress 12.17.2. My project is an NX monorepo. I have a Cypress config in each project and the component-index.html file in the workspace's root to reuse it.

@lmiller1990
Copy link
Contributor

Next release this will be shipped! Finally.

nagash77 pushed a commit that referenced this issue Aug 4, 2023
* chore: move entry for #26400 to fix changelog

* add line break
@cypress-bot
Copy link
Contributor

cypress-bot bot commented Aug 15, 2023

Released in 12.17.4.

This comment thread has been locked. If you are still experiencing this issue after upgrading to
Cypress v12.17.4, please open a new issue.

@cypress-bot cypress-bot bot locked as resolved and limited conversation to collaborators Aug 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
CT Issue related to component testing Triaged Issue has been routed to backlog. This is not a commitment to have it prioritized by the team.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants