Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use import with absolute paths in Cypress tests built with ParcelJS?

I'm using imports with absolute paths in my Parcel project but these absolute paths aren't equally resolved by Cypress tests.

Difference in module resolution

Parcel: import {foo} from '/foo.js': relatively to project root

Cypress: import {foo} from '/foo.js': absolute on disk root

When Parcel's entry point is in src folder importing /foo.js anywhere in the project looks for file in path <project>/src/foo.js. (Docs: https://parceljs.org/module_resolution.html#absolute-paths)

But Cypress doesn't have any entry point and if it tries to import a file using absolute path it considers / as a filesystem root. This can happen when imported file (foo.js) internally imports another file (bar.js).

Example

cypress-test.js

import {foo} from '../../src/foo.js' // I don't care using relative paths in tests.
// tests here...

foo.js

import {bar} from '/bar.js' // Absolute path not found by Cypress
//...

How can I make Cypress to resolve absolute paths relative to some entry point as Parcel does?

like image 231
Petr K. Avatar asked Oct 16 '22 09:10

Petr K.


1 Answers

You can compile your spec files yourself, changing path resolution.

For that, you can use a Cypress' official browserify preprocessor, and adding paths browserify option, and also pathmodify browserify plugin that will take care of stripping the leading / in paths, so that the path resolution works correctly.

First, install the packages by:

npm install -D @cypress/browserify-preprocessor pathmodify

Then in your cypress/plugins/index.js:

const preprocessor = require('@cypress/browserify-preprocessor');
const pathmodify = require('pathmodify');

const browserifyOptions = preprocessor.defaultOptions.browserifyOptions;

// -----------------------------------------------------------------------------
// (1) resolve paths relative to project root
// -----------------------------------------------------------------------------

browserifyOptions.paths = [
  // the process.cwd() depends on the cypress process being started from
  //  the project root. You can also use an absolute path here.
  require('path').resolve( process.cwd() )
];

// -----------------------------------------------------------------------------
// (2) regard paths starting with `/` as project-relative paths
// -----------------------------------------------------------------------------

browserifyOptions.plugin = browserifyOptions.plugin || [];
browserifyOptions.plugin.unshift([
  pathmodify, { mods: [
    // strip leading `/` when resolving paths
    pathmodify.mod.re(/^\//, '')
  ]}
]);

// -----------------------------------------------------------------------------
// (3) compile spec files when they're run
// -----------------------------------------------------------------------------

const compileFile = preprocessor( preprocessor.defaultOptions );

module.exports = ( on ) => {
  on('file:preprocessor', file => {
    return compileFile( file );
  });
}

Learn more at https://docs.cypress.io/api/plugins/preprocessors-api.html

like image 51
dwelle Avatar answered Oct 21 '22 09:10

dwelle