LironEr / cypress-mochawesome-reporter

Zero config Mochawesome reporter for Cypress with screenshots and videos
MIT License
159 stars 49 forks source link

[solution] Cypress & with Yarn PnP #108

Open OleksandrKucherenko opened 1 year ago

OleksandrKucherenko commented 1 year ago

Is your feature request related to a problem? Please describe.

The cause:

Error loading the reporter: cypress-mochawesome-reporter

We searched for the reporter in these paths:

 - ~/workspace/telekom.de/hvc-csp/cypress-mochawesome-reporter
 - ~/workspace/telekom.de/hvc-csp/node_modules/cypress-mochawesome-reporter

Learn more at https://on.cypress.io/reporters

Describe the solution you'd like

Step #1: Add mocha a required yarn package, so yarn PnP can resolve it for Cypress.

yarn add --dev mocha

Step #2: create in the root of the project file cypress-mochawesome-reporter.js with content:

const path = require("node:path");
const cwd = process.cwd();

// ref: https://yarnpkg.com/advanced/pnpapi
console.log("cypress-mochawesome-reporter.js: cwd =", cwd);
console.log("cypress-mochawesome-reporter.js: PnP =", path.join(cwd, ".pnp.cjs"));

const pnp = require(path.join(cwd, ".pnp.cjs"));
pnp.setup();
console.log("cypress-mochawesome-reporter.js: pnp =", process.versions.pnp);

// NOTE: at this point require('module') will be already patched by pnp and
// will have findPnpApi method; also `require('pnpapi')` will start to work.

let instance = {};

try {
  // ref: https://yarnpkg.com/advanced/pnpapi#requiremodule
  const { createRequire, findPnpApi } = require(`module`);
  const targetModule = cwd + "/";
  console.log("cypress-mochawesome-reporter.js: targetModule =", targetModule);

  const targetPnp = findPnpApi(targetModule);
  // console.log("cypress-mochawesome-reporter.js: targetPnp =", targetPnp);

  const targetRequire = createRequire(targetModule);
  // console.log("cypress-mochawesome-reporter.js: targetRequire =", targetRequire);

  const resolved = targetPnp.resolveRequest("cypress-mochawesome-reporter", targetModule);
  console.log("cypress-mochawesome-reporter.js: resolved =", resolved);

  instance = targetRequire(resolved);

  console.log("cypress-mochawesome-reporter.js: reporter loaded");
} catch (error) {
  console.error("cypress-mochawesome-reporter.js: error =", error);
}

module.exports = instance;

Follow the original configuration steps.

Describe alternatives you've considered

Refs:

Additional context

Cypress reporter executed in "isolated" node instance that does not have enabled P'n'P logic.

OleksandrKucherenko commented 1 year ago

Cleaner version:

const path = require("node:path");
/* ref: https://yarnpkg.com/advanced/pnpapi */
require(path.join(process.cwd(), ".pnp.cjs")).setup();

const REPORTER = "cypress-mochawesome-reporter";

const resolve = () => {
  const cwd = process.cwd() + "/";

  try {
    const { createRequire, findPnpApi } = require(`module`);
    const targetPnp = findPnpApi(cwd);
    const targetRequire = createRequire(cwd);
    const resolved = targetPnp.resolveRequest(REPORTER, cwd);

    return targetRequire(resolved);
  } catch (error) {
    console.error(REPORTER + ".js: error =", error);
    throw error;
  }
};

module.exports = resolve();
vire commented 10 months ago

Cleaner version:

const path = require("node:path");
/* ref: https://yarnpkg.com/advanced/pnpapi */
require(path.join(process.cwd(), ".pnp.cjs")).setup();

const REPORTER = "cypress-mochawesome-reporter";

const resolve = () => {
  const cwd = process.cwd() + "/";

  try {
    const { createRequire, findPnpApi } = require(`module`);
    const targetPnp = findPnpApi(cwd);
    const targetRequire = createRequire(cwd);
    const resolved = targetPnp.resolveRequest(REPORTER, cwd);

    return targetRequire(resolved);
  } catch (error) {
    console.error(REPORTER + ".js: error =", error);
    throw error;
  }
};

module.exports = resolve();

This breaks with new yarn4 PNP api

LironEr commented 9 months ago

if you can open a PR and a test for that, it would be great. I'm not familiar with Yarn PnP.