cypress-io / cypress

Fast, easy and reliable testing for anything that runs in a browser.
https://cypress.io
MIT License
47.17k stars 3.19k forks source link

The "paths[1]" argument must be of type string #28997

Open petergaal91 opened 9 months ago

petergaal91 commented 9 months ago

Current behavior

Since angular 17 if we use an application builder the output folder will be "dist/path/browser". If you want to build into the "dist/path" folder - like in the previous version with browser builder - you need to update the outputPath to:

{
...
"architect": {
  "build": {
    "builder": "@angular-devkit/build-angular:application",
    "options": {
      "outputPath": {
        "base": "dist/path",
        "browser": ""
      }
      "index": "src/index.html",
      "browser": "src/main.ts"
    }
  }
}      
...
}

If I do this I get the following error at angular component test config initialization step:

TypeError [ERR_INVALID_ARG_TYPE]: The "paths[1]" argument must be of type string. Received an instance of Object
    at new NodeError (node:internal/errors:406:5)
    at validateString (node:internal/validators:162:11)
    at Object.resolve (node:path:1101:7)
    at getCommonConfig (/Users/xyz/project/node_modules/@angular-devkit/build-angular/src/tools/webpack/configs/common.js:275:24)
    at async Promise.all (index 0)
    at async generateWebpackConfig (/Users/xyz/project/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:60:22)
    at async generateBrowserWebpackConfigFromContext (/Users/xyz/project/node_modules/@angular-devkit/build-angular/src/utils/webpack-browser-config.js:117:20)
    at async getAngularCliWebpackConfig (/Users/xyz/Library/Caches/Cypress/13.6.4/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/webpack-dev-server/dist/helpers/angularHandler.js:165:24)
    at async angularHandler (/Users/xyz/Library/Caches/Cypress/13.6.4/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/webpack-dev-server/dist/helpers/angularHandler.js:205:27)
    at async getPreset (/Users/xyz/Library/Caches/Cypress/13.6.4/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/webpack-dev-server/dist/devServer.js:94:20)
    at async Function.devServer.create (/Users/xyz/Library/Caches/Cypress/13.6.4/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/webpack-dev-server/dist/devServer.js:111:61)
    at async /Users/xyz/Library/Caches/Cypress/13.6.4/Cypress.app/Contents/Resources/app/packages/server/node_modules/@cypress/webpack-dev-server/dist/devServer.js:26:24

I think outputPath as an object not handled correctly in this case.

Desired behavior

No response

Test code to reproduce

  1. Generate a fresh angular 17 project
  2. Update the angular.json build target outputPath to the following:
    "outputPath": {
    "base": "dist/path",
    "browser": ""
    }
  3. Configure angular component test in angular.json and use the updated build target:
    "component-test": {
      "executor": "@nx/cypress:cypress",
      "options": {
        "cypressConfig": "./cypress.config.ts",
        "devServerTarget": "project:build",
        "testingType": "component"
        "skipServe": true
      }
    }

Cypress Version

13.6.4

Node version

20.9.0

Operating System

macOS 14.3.1

Debug Logs

No response

Other

No response

bauerbua commented 8 months ago

What you can do as a workaround for now is to manually define the outputPath in devServer config in cypress.config.ts

devServer: {
    framework: 'angular',
    bundler: 'webpack',
    options: {
        projectConfig: {
            root: './',
            sourceRoot: 'src',
            buildOptions: {
              outputPath: 'dist/browser',
             /** other options **/
         }
    }
}
poveu commented 6 months ago

It's worth noting that those "other options" @bauerbua mentioned, are usually options from angular.json projects.*whatever*.architect.build.options (that could be automatically retrieved and appended to the buildOptions). In my case it's:

import { defineConfig } from 'cypress';
import * as fs from 'node:fs';

const angularConfig = fs.readFileSync('angular.json', 'utf8');
const angularJson = JSON.parse(angularConfig);
const buildOptions = angularJson.projects.ui.architect.build.options;

export default defineConfig({
    e2e: {
        projectId: 'ui',
        baseUrl: 'http://localhost:4200',
    },
    component: {
        devServer: {
            framework: 'angular',
            bundler: 'webpack',
            options: {
                projectConfig: {
                    root: '',
                    sourceRoot: 'src',
                    buildOptions: {
                        ...buildOptions,
                        outputPath: 'dist/ui',
                    },
                },
            },
        },
    },
});
cypress-app-bot commented 1 week ago

This issue has not had any activity in 180 days. Cypress evolves quickly and the reported behavior should be tested on the latest version of Cypress to verify the behavior is still occurring. It will be closed in 14 days if no updates are provided.