nx icon indicating copy to clipboard operation
nx copied to clipboard

@nx/[email protected] does not exit after tests complete when dev server target is not static

Open antischematic opened this issue 2 years ago • 4 comments

Current Behavior

I have a module federated React app which consists of one shell app and one remote app.

shell
shell-e2e
remote
remote-e2e

When I run the e2e test command the tests pass but the process doesn't exit.

npx nx e2e shell-e2e

The last working version was @nx/[email protected].

Expected Behavior

The shell-e2e:e2e target should exit when tests are complete.

GitHub Repo

No response

Steps to Reproduce

The shell-e2e target is configured to start the webpack dev server before running tests. The shell-e2e project.json is as follows:

{
  "name": "shell-e2e",
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "sourceRoot": "apps/shell-e2e/src",
  "projectType": "application",
  "targets": {
    "e2e": {
      "executor": "@nx/cypress:cypress",
      "options": {
        "cypressConfig": "apps/shell-e2e/cypress.config.ts",
        "devServerTarget": "shell:serve:development",
        "testingType": "e2e",
        "baseUrl": "http://localhost:4200"
      },
      "configurations": {
        "production": {
          "devServerTarget": "shell:serve:production"
        },
        "ci": {
          "devServerTarget": "shell:serve"
        }
      }
    },
    "lint": {
      "executor": "@nx/linter:eslint",
      "outputs": ["{options.outputFile}"],
      "options": {
        "lintFilePatterns": ["apps/shell-e2e/**/*.{js,ts}"]
      }
    }
  },
  "tags": [],
  "implicitDependencies": ["shell"]
}

The shell:serve target is configured as follows:

{
    "serve": {
      "executor": "@nx/react:module-federation-dev-server",
      "defaultConfiguration": "development",
      "options": {
        "buildTarget": "shell:build",
        "hmr": true,
        "port": 4200
      },
      "configurations": {
        "development": {
          "buildTarget": "shell:build:development"
        },
        "production": {
          "buildTarget": "shell:build:production",
          "hmr": false
        }
      }
    }
}

Nx Report

Node   : 18.16.0
   OS     : darwin-x64
   npm    : 9.5.1

   nx                 : 16.4.0
   @nx/js             : 16.4.0
   @nx/jest           : 16.4.0
   @nx/linter         : 16.4.0
   @nx/workspace      : 16.4.0
   @nx/cypress        : 16.4.0
   @nx/devkit         : 16.4.0
   @nx/eslint-plugin  : 16.4.0
   @nx/nest           : 16.4.0
   @nx/node           : 16.4.0
   @nx/react          : 16.4.0
   @nrwl/tao          : 16.4.0
   @nx/web            : 16.4.0
   @nx/webpack        : 16.4.0
   typescript         : 5.1.3
   ---------------------------------------
   Community plugins:
   @jscutlery/semver : 3.0.0

Failure Logs

There are no observable errors.

Operating System

  • [ ] macOS
  • [ ] Linux
  • [ ] Windows
  • [ ] Other (Please specify)

Additional Information

As a workaround downgrading to @nx/[email protected] fixes the problem.

antischematic avatar Jun 29 '23 01:06 antischematic

Any resolution on cypress not ending or exiting?

ojemuyiwa avatar Oct 09 '23 12:10 ojemuyiwa

Not sure if this helps anyone but I used a hacky workaround using concurrently to serve-static the remote app and e2e test concurrently and by skipping the remotes in the serve command for the shell app

SavageCabbagee avatar Oct 11 '23 13:10 SavageCabbagee

  • So I found a Ctrl C when it hangs works. But what is really going on is node SSR server process doesn't terminate. I tried using npm find-process https://www.npmjs.com/package/find-process which worked a charm locally but not in ci-cd due to sudo needed to query the network for the appropriate port. Also tried giving the SSR process a title which changed the process name and other things under the hood. After a few all nighters decided to:
  • save the process pid in a text file
  • read the text file and get the pid in cypress event
  • kill the ssr node process

In server.ts import fs at the top

import { writeFile } from 'node:fs';

// Synchronous Write pid to file
if (env.NX_CYPRESS_TARGET_CONFIGURATION === 'ci') {
  console.log('writing file');
  writeFile('pid.txt', `${process.pid}`, 'utf8', (err)=> {
    if(err){
      console.error('error writing pid file:', err);
    }
  }); 
}

Then in cypress.config.ts in the setupNodeEvents(on, config)

import { env, kill, nextTick, ppid } from 'node:process';


 // exec in ci configuration mode in project.json
        on('after:run', async (results: any) => {
          if (results || env.NX_CYPRESS_TARGET_CONFIGURATION === 'ci') {
            let SSRID: number;

            readFile('../pid.txt', 'utf8', (err, data) => {
              if (err) console.error('Error reading pid.txt:', err);

              if (!isNaN(Number(data))) {
                nextTick(() => {
                  SSRID = Number(data);

                  console.log(`SSR proccess ID ${SSRID}`);
                  kill(SSRID, 'SIGINT'); // SIGTERM
                });
              } else {
                setTimeout(() => {
                  console.log('sending ctrl + c to this signal');

                  kill(ppid, 'SIGINT');
                }, 250);
              }
            });
          }
        });

ojemuyiwa avatar Oct 12 '23 08:10 ojemuyiwa

This issue has been automatically marked as stale because it hasn't had any recent activity. It will be closed in 14 days if no further activity occurs. If we missed this issue please reply to keep it active. Thanks for being a part of the Nx community! 🙏

github-actions[bot] avatar May 01 '24 00:05 github-actions[bot]