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

Cuypress can't managed to load the support file when using cypress as custom module #26710

Closed
idanElitzur opened this issue May 10, 2023 · 6 comments

Comments

@idanElitzur
Copy link

idanElitzur commented May 10, 2023

Current behavior

Hey, i've packed and bundled Cypress with some extras and custom abilities to be scalable in multiple projects in my organization.
Now Cypress packed as isolated module inside the structure below -

| main project
 - src
 - test-files
 - node_modules
     - @org-custome_modules
        - scalable_cy
            - cypress
               - support
                  e2e.ts
            cypress.config.ts
            tsconfig.json
            webpack.config.json
   tsconfig.json

but the support file can't managed to load but actually everything works ok when I'm turning the flag for support file to "false".

But i really need the support file for some handlers like catching console errors during the test execution and for the html reporter configuration.

The I got regarding the support file when i running cypress is below -

  cypress:config:project:utils validate that there is no breaking config options before setupNodeEvents +2ms
  cypress:lifecycle:ProjectConfigManager catch setupNodeEvents Error: Your supportFile is missing or invalid: cypress/support/e2e.ts The supportFile must be a .js, .ts, .coffee file or be supported by your preprocessor plugin (if configured). Fix your support file, or set supportFile to false if a support file is not necessary for your project. If you have just renamed the extension of your supportFile, restart Cypress. https://on.cypress.io/support-file-missing-or-invalid 

Desired behavior

No response

Test code to reproduce

Technical info:

cypress.config.file -

// cypress.config.ts
/// <reference types="cypress" />
/**
 * @type {Cypress.PluginConfig}
 */

import { defineConfig } from 'cypress';
import { cypressBrowserPermissionsPlugin } from 'cypress-browser-permissions';
// @ts-ignore
import { send, nodemailer } from './cypress/support/mailer/mailer-send';
// @ts-ignore
import mailer from './cypress/support/mailer/mailer-server';

const { initPlugin } = require('cypress-plugin-snapshots/plugin');
const fs = require('fs');
const ansi = require('ansi-colors');
const webpackPreprocessor = require('@cypress/webpack-preprocessor');
const options = {
	webpackOptions: require('./webpack.config'),
	watchOptions: {},
};
require('dotenv').config({ path: '.env', override: true });
import * as mailListener from './cypress/support/mailer/mail-listener-config';

export default defineConfig({
	env: {
		'cypress-plugin-snapshots': {
			autoCleanUp: false,
			autopassNewSnapshots: true,
			diffLines: 3,
			excludeFields: [],
			ignoreExtraArrayItems: false,
			ignoreExtraFields: false,
			normalizeJson: true,
			prettier: true,
			imageConfig: {
				createDiffImage: true,
				resizeDevicePixelRatio: true,
				threshold: 0.25,
				thresholdType: 'percent',
			},
			screenshotConfig: {
				blackout: [],
				capture: 'fullPage',
				clip: null,
				disableTimersAndAnimations: true,
				log: false,
				scale: false,
				timeout: 30000,
			},
			serverEnabled: false,
			serverHost: 'localhost',
			serverPort: 2121,
			updateSnapshots: false,
			backgroundBlend: 'difference',
		},
		browserPermissions: {
			notifications: 'allow',
			geolocation: 'allow',
		},
		uploadsFolder: './cypress/uploads',
		ignoreTestFiles: ['**/__snapshots__/*', '**/__image_snapshots__/*'],
		gmail_user: process.env.GMAIL_USER,
		gmail_password: process.env.GMAIL_PASSWORD,
		gmail_host: process.env.GMAIL_HOST,
		gmail_port: process.env.GMAIL_PORT,
		gmail_tls: process.env.GMAIL_TLS,
		googleRefreshToken: process.env.GOOGLE_REFRESH_TOKEN,
		googleClientId: process.env.GOOGLE_CLIENT_ID,
		googleClientSecret: process.env.GOOGLE_CLIENT_SECRET,
		SMTP_HOST: process.env.SMTP_HOST,
		AUTHENTICATION_STAGING: process.env.AUTHENTICATION_STAGING,
	},
	e2e: {
		supportFile: 'cypress/support/e2e.ts',
		downloadsFolder: 'cypress/downloads',
		chromeWebSecurity: false,
		experimentalWebKitSupport: true,
		experimentalModifyObstructiveThirdPartyCode: true,
		modifyObstructiveCode: false,
		numTestsKeptInMemory: 0,
		defaultCommandTimeout: 30000,
		requestTimeout: 30000,
		responseTimeout: 45000,
		testIsolation: false,
		taskTimeout: 45000,
		pageLoadTimeout: 30000,
		screenshotsFolder: 'mochawesome-report/assets',
		screenshotOnRunFailure: true,
		reporter: 'mochawesome',
		reporterOptions: {
			reportDir: 'cypress/report',
			code: false,
			charts: true,
			overwrite: false,
			html: false,
			json: true,
			embeddedScreenshots: true,
		},
		video: false,
		viewportHeight: 1080,
		viewportWidth: 1920,
		waitForAnimations: true,
		setupNodeEvents: async (on, config) => {
			//Add browser permissions for faking geo location
			config = cypressBrowserPermissionsPlugin(on, config);
			//Save local storage between test cases when running without cy.session
			require('cypress-localstorage-commands/plugin')(on, config);
			//Webpack compiling configurations
			on('file:preprocessor', webpackPreprocessor(options));
			//Turn ON visual testing support by cypress-plugin-snapshots
			initPlugin(on, config);
			//Print browser logs to terminal logs
			on('task', {
				log(message) {
					console.log(ansi.yellow(message));
					return null;
				},
			});
			on('task', {
				err(message) {
					console.log(ansi.red(message));
					return null;
				},
			});

			//Pushing configuration flags to Chrome to launch with them
			on('before:browser:launch', (browser, launchOptions) => {
				if (browser.name === 'chrome') {
					launchOptions.args.push(
						'--disable-features=CrossSiteDocumentBlockingIfIsolating,CrossSiteDocumentBlockingAlways,IsolateOrigins,site-per-process',
						'--disable-web-security',
						'--disable-dev-shm-usage',
						'--user-data-dir',
						'--disable-gpu',
						'--no-sandbox',
						'--start-maximized',
						'--enable-automation',
						'--safebrowsing-disable-auto-update',
						'--window-size=1920,1080'
					);
				}
				launchOptions.args = launchOptions.args.filter(
					(item) => item !== '--disable-dev-shm-usage'
				);
				return launchOptions;
			});

			return config;
		},
	},
});

tsconfig.json inside the packed cypress (scalable_cy) -

{
  "compilerOptions": {
    "baseUrl": ".",
    "outDir": "./dist/",
    "esModuleInterop": true,
    "declarationMap": false,
    "strict": true,
    "target": "esnext",
    "lib": ["es5", "es6", "ES2018", "dom"],
    "noImplicitAny": false,
    "allowJs": true,
    "jsx": "react",
    "types": ["cypress", "node", "cypress-localstorage-commands", "@cypress/grep", "cypress-file-upload", "detox", "jest"],
    "allowSyntheticDefaultImports": true,
    "skipLibCheck": true,
    "isolatedModules": false,
    "noEmit": false,
    "module": "es6",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "downlevelIteration": true,
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": false,
    "strictNullChecks": false
  },
  "ts-node": {
    "esm": true
  },
  "include": [
    "../../../e2e-tests/**/*.ts",
    "**/*.ts",
    "node_modules/@types/node/globals.d.ts"
  ],
  "exclude": ["node_modules", "dist", "cypress/support/index.ts", "cypress/support/commands.ts"]
}

webpack.config.js -

'use strict';
const path = require('path');
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin');

module.exports = {
	mode: 'development',
	entry: path.join(__dirname, './node_modules/@my-org-modules/scalable_cy/index.ts'),
	externals: {
		cypress: 'Cypress'
	},
	module: {
		rules: [
			{
				test: /\.(ts|tsx)$/,
				loader: 'ts-loader',
				exclude: /node_modules/,
				options: {
					configFile: path.resolve(__dirname, 'tsconfig.json'), // the path to your tsconfig.json file
					transpileOnly: true, // speed up compilation
					experimentalWatchApi: true, // speed up incremental builds
				},
			},
			{
				test:  /\.(js|jsx)$/,
				loader: 'babel-loader',
				exclude: /node_modules/,
				options: {
					presets: [['@babel/preset-env', { loose: true }]],
					configFile: path.resolve(__dirname, 'tsconfig.json'), // the path to your tsconfig.json file
				},
			},
		],
	},
	resolve: {
		extensions: ['.js', '.jsx', '.tsx', '.ts', '.json'],
	},
	plugins: [new NodePolyfillPlugin()],
	output: {
		path: path.join(__dirname, 'dist'),
		filename: 'bundle.js',
	},
};

package.json inside the packed cypress (scalable_cy) -

{
  "name": "@my-org-modules/scalable_cy",
  "version": "1.1.1",
  "description": "shared standalone testing infrastructure for end-to-end and integration tests",
  "main": "index.ts",
  "scripts": {
    "tsc": "tsc --traceResolution",
    "test": "echo \"Error: no test specified\" && exit 1",
    "rename-screenshots": "./deploy/rename-screenshots.sh",
    "merge-reports": "npx mochawesome-merge ./cypress/report/*.json -o mochawesome.json",
    "generate-report": "marge mochawesome.json",
    "merge:generate-reports": "npm run rename-screenshots && sleep 2 && npm run merge-reports && sleep 2 && npm run generate-report",
    "remove-reports": "[ -e mochawesome.json ] && rm -f mochawesome.json; rm -rf mochawesome-report/*.html cypress/report/*.json cypress/screenshots/** mochawesome-report/assets/**\n",
    "prettier-check": "npx prettier --check $PROJECT/e2e-tests --single-quote=true",
    "prettier-write": "npx prettier --write $PROJECT/e2e-tests --single-quote=true",

  },
  "author": "Idan E",
  "license": "ISC",
  "lint-staged": {
    "**/*.{ts,tsx,js,jsx}": "npm run prettier-write:testilize"
  },
  "prettier": {
    "bracketSpacing": true,
    "useTabs": true,
    "singleQuote": true,
    "semi": true,
    "parser": "babel-ts"
  },
  "babel": {
    "presets": [
      "@babel/preset-env",
      "@babel/preset-react"
    ],
    "plugins": [
      [
        "@babel/plugin-proposal-decorators",
        {
          "legacy": true
        }
      ]
    ]
  },
  "browser": {
    "fs": false,
    "path": false,
    "os": false
  },
  "dependencies": {
    "@babel/plugin-proposal-class-properties": "^7.16.7",
    "@babel/plugin-proposal-decorators": "^7.21.0",
    "@babel/preset-react": "^7.18.6",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "cypress-log-to-output": "^1.1.2",
    "cypress-plugin-snapshots": "^1.4.4",
    "detox-cli": "^20.0.0",
    "dotenv": "^16.0.0",
    "fs": "^0.0.1-security",
    "imap": "^0.8.19",
    "jest-html-reporter": "^3.5.0",
    "mail-listener6": "^2.0.3",
    "mochawesome": "^7.1.3",
    "mochawesome-report-generator": "^6.2.0",
    "mongodb": "^4.12.1",
    "mysql": "^2.18.1",
    "node-polyfill-webpack-plugin": "^2.0.0",
    "nodemailer": "^6.9.1",
    "pg": "^8.7.3",
    "playwright-webkit": "^1.26.1",
    "pnpm": "^6.0.0",
    "prettier": "^2.7.1",
    "sleep-promise": "^9.1.0",
    "smtp-tester": "^2.0.0",
    "soft-assert": "^0.2.6",
    "ts-loader": "^9.3.0",
    "tslib": "^2.4.0",
    "typescript": "^4.6.3",
    "util": "^0.12.4",
    "wait-on": "^6.0.1",
    "webpack": "^5.72.0"
  },
  "keywords": [
    "cypress",
    "cypress-plugin",
    "cypress-preprocessor",
    "code-coverage",
    "typescript"
  ],
  "devDependencies": {
    "@babel/core": "^7.18.9",
    "@babel/preset-env": "^7.18.9",
    "@babel/types": "^7.18.9",
    "@cypress/code-coverage": "^3.10.0",
    "@cypress/grep": "^3.1.3",
    "@cypress/webpack-preprocessor": "^5.12.0",
    "@istanbuljs/nyc-config-babel": "^3.0.0",
    "@istanbuljs/nyc-config-typescript": "^1.0.2",
    "@types/cypress": "^1.1.3",
    "@types/mochawesome": "^6.2.1",
    "babel-loader": "^8.2.5",
    "babel-plugin-istanbul": "^6.1.1",
    "babel-plugin-transform-class-properties": "^6.24.1",
    "cypress": "^12.11.0",
    "cypress-browser-permissions": "^1.1.0",
    "cypress-fail-on-console-error": "^3.1.0",
    "cypress-file-upload": "^5.0.8",
    "cypress-localstorage-commands": "^2.2.2",
    "cypress-map": "^1.14.1",
    "cypress-recurse": "^1.23.0",
    "detox": "^20.7.2",
    "eslint-plugin-cypress": "^2.12.1",
    "husky": "^8.0.1",
    "istanbul-lib-coverage": "^3.2.0",
    "jest": "^29.5.0",
    "jest-circus": "^29.5.0",
    "lint-staged": "^13.0.3",
    "mocha": "^9.2.2",
    "mochawesome-merge": "^4.2.1",
    "nyc": "^15.1.0",
    "source-map-support": "^0.5.21",
    "ts-node": "^10.9.1"
  },
  "nyc": {
    "extends": [
      "@istanbuljs/nyc-config-babel",
      "@istanbuljs/nyc-config-typescript"
    ],
    "all": true,
    "check-coverage": true,
    "exclude": [
      "**"
    ],
    "reporter": [
      "html",
      "lcov",
      "text",
      "text-summary"
    ],
    "report-dir": "coverage"
  },
  "repository": {
    "type": "git",
    "url": "someurl.git"
  },
}

package.json inside the main project root (only the script that run the packed cypress) -

  "scripts": {
    "e2e-test:runner": "./node_modules/@my-org-modules/scalable_cy/node_modules/.bin/cypress open --project ./node_modules/@my-org-modules/scalable_cy --config '{\"specPattern\":[\"./../../../e2e-tests/test-files/**/*.cy.ts\"], \"baseUrl\": \"https://someurl.com\", \"fixturesFolder\": \"./../../../e2e-tests/fixtures\"}' --env client=https://someurl.com,server=https://someurl.com",
  },

Cypress Version

12.11.0

Node version

14.19.1

Operating System

13.0.1 M1

Debug Logs

`
  cypress:config:project:utils validate that there is no breaking config options before setupNodeEvents +2ms
  cypress:lifecycle:ProjectConfigManager catch setupNodeEvents Error: Your supportFile is missing or invalid: cypress/support/e2e.ts The supportFile must be a .js, .ts, .coffee file or be supported by your preprocessor plugin (if configured). Fix your support file, or set supportFile to false if a support file is not necessary for your project. If you have just renamed the extension of your supportFile, restart Cypress. https://on.cypress.io/support-file-missing-or-invalid at L (<embedded>:4171:9407)     at process.processTicksAndRejections (node:internal/process/task_queues:96:5) at async D.buildBaseFullConfig (<embedded>:4384:60987) at async D.getFullInitialConfig (<embedded>:4384:62436) at async D.setupNodeEvents (<embedded>:4384:56576) { isCypressErr: true, type: 'SUPPORT_FILE_NOT_FOUND', details: undefined, messageMarkdown: 'Your `supportFile` is missing or invalid: `cypress/support/e2e.ts`\n' + '\n' + 'The supportFile must be a .js, .ts, .coffee file or be supported by your preprocessor plugin (if configured).\n' + '\n' + 'Fix your support file, or set supportFile to `false` if a support file is not necessary for your project.\n' + '\n' + 'If you have just renamed the extension of your supportFile, restart Cypress.\n' + '\n' + 'https://on.cypress.io/support-file-missing-or-invalid', originalError: undefined, stackWithoutMessage: '    at L (<embedded>:4171:9407)\n' + '    at process.processTicksAndRejections (node:internal/process/task_queues:96:5)\n' + '    at async D.buildBaseFullConfig (<embedded>:4384:60987)\n' + '    at async D.getFullInitialConfig (<embedded>:4384:62436)\n' + '    at async D.setupNodeEvents (<embedded>:4384:56576)' } +1s


### Other

Google chrome - 
Version 111.0.5563.110 (Official Build) (arm64)

Typescript - 4.6.3
@idanElitzur
Copy link
Author

@emilyrohrbough @nagash77
Please your assistance soon,
I really stuck :/

Thanks a lot! 🙏

@ocombe
Copy link

ocombe commented Jun 12, 2023

The support file doesn't work if it is in node_modules (see #23616), and that really is annoying... there should be a way to run it from there if the path of the support file points to node_modules

@idanElitzur
Copy link
Author

Any news regarding this issue guys?
i'm trying to pack cypress inside some internal private npm package and bundle it to the project
but can do it regarding the support file issue

@warrensplayer
Copy link
Contributor

@idanElitzur Looking at this issue now.

@warrensplayer
Copy link
Contributor

@idanElitzur After consideration, this isn’t a feature we are looking to develop at this time. If we decide that this is something we want to pursue in the future we will comment back on this ticket. For the time being we are going to close this issue.

@warrensplayer warrensplayer removed their assignment Jun 13, 2023
@idanElitzur
Copy link
Author

:(

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