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

Error Module did not self-register.using helper with new Codeceptjs workers #57

Closed
Georgegriff opened this issue Dec 19, 2019 · 11 comments

Comments

@Georgegriff
Copy link

Georgegriff commented Dec 19, 2019

Using new codeceptjs workers: https://codecept.io/parallel/

This helper will not load.

Similar issue here: web3/web3.js#2723

From reading that issue i found that if i moved the require require("resemblejs") until its used it works for some of the workers, but nott all.

@Georgegriff
Copy link
Author

I think this might be timing related because if i moved the require to inside the promise just before its used some of the workers work as expected

@Georgegriff
Copy link
Author

I've worked around this locally by copying the helper and providing my own implementation that does not use resemblejs but pixelmatch instead. this loses the bounding box functionality but okay as a temp work around

@Georgegriff
Copy link
Author

Georgegriff commented Dec 20, 2019

My version of compare Images:

const fs = require('fs');
const PNG = require('pngjs').PNG;
const pixelmatch = require("pixelmatch");
const assert = require('assert');
const mkdirp = require('mkdirp');
const getDirName = require('path').dirname;
const path = require('path');
  async _compareImages(image, diffImage, options) {
    const baseImage = this.baseFolder + image;
    const actualImage = this.screenshotFolder + image;

    // check whether the base and the screenshot images are present.
    fs.access(baseImage, fs.constants.F_OK | fs.constants.W_OK, (err) => {
      if (err) {
        throw new Error(
          `${baseImage} ${err.code === 'ENOENT' ? 'base image does not exist' : 'is read-only'}`);
      }
    });

    fs.access(actualImage, fs.constants.F_OK | fs.constants.W_OK, (err) => {
      if (err) {
        throw new Error(
          `${actualImage} ${err.code === 'ENOENT' ? 'screenshot image does not exist' : 'is read-only'}`);
      }
    });

    return new Promise((resolve, reject) => {
        
      this.debug("Tolerance Level Provided " + options.tolerance);
      const tolerance = options.tolerance;
      try {
        const baseImageData = PNG.sync.read(fs.readFileSync(baseImage));
        const actualImageData = PNG.sync.read(fs.readFileSync(actualImage));
        if (baseImageData.width !== actualImageData.width || baseImageData.height !== actualImageData.height) {
            throw new Error("The base image is of " + baseImageData.height + " X " + baseImageData.width + " and actual image is of " + actualImageData.height + " X " + actualImageData.width + ". Please use images of same dimensions so as to avoid any unexpected results.")
        }
        const {width, height} = baseImageData;
        const diff = new PNG({width, height});
        const numDiffPixels = pixelmatch(baseImageData.data, actualImageData.data, diff.data, width, height, {threshold: 0});
        const totalPixels = width * height;
        const percentageDiff = (numDiffPixels / totalPixels) * 100;
        this.debug("Number of different pixels: " + numDiffPixels);
        this.debug("Diff %: " + percentageDiff);
        if (percentageDiff > tolerance) {
            mkdirp(getDirName(this.diffFolder + diffImage), (error) => {
              if (error) return reject(error);
              fs.writeFileSync(this.diffFolder + diffImage + '.png', PNG.sync.write(diff));
              const diffImagePath = path.join(process.cwd(), this.diffFolder + diffImage + '.png');
              this.debug("Diff Image File Saved to: " + diffImagePath);
              resolve({misMatchPercentage: percentageDiff});
              return;
            });
           
        } else {
            resolve({
                misMatchPercentage: percentageDiff
            });
            return;
        }
      } catch(err) {
        return reject(err);
      }
  
    });
  }

Lost ignoreBox functionality:
potential information: mapbox/pixelmatch#9
Could support ignore box some how like this

A sample snippet of how to clear pixel data in a rectangular region (x0, y0, x1, y1):

for (let y = y0; y < y1; y++) {
    for (let x = x0; x < x1; x++) {
        const k = 4 * (width * y + x);
        data[k + 0] = 0;
        data[k + 1] = 0;
        data[k + 2] = 0;
        data[k + 3] = 0;
    }
}

@Georgegriff
Copy link
Author

I was also finding i had to do this for workers:
wrap screenshot in a mkdirp for screenshotFolder, my guess is that in worker mode the output directory is lazily created or something similar? puppeteer was failing to capture screenshots

 mkdirp(this.screenshotFolder, async (error) => {
          if(error) return reject(error);
          await el.screenshot({
            path: this.screenshotFolder + name + '.png'
          });
          resolve();
        })

@Georgegriff
Copy link
Author

You'll notice in example that tolerance works differently too so i've had to do some logic to calculate a % diff, i might have screwed this up, potentially, but seems to work for my tests.

@puneet0191
Copy link
Member

@Georgegriff could we possibly make this option configurable? User can provide this as config, so if they want to use it with workers, we can use pixelmatch

@Georgegriff
Copy link
Author

That wouldn't really work because the libraries aren't 100% compatible I think it would have to be a standard alone helper

@SavitaMaurya
Copy link

Hi Team,

Any update on the issue?

@bhupendrarautela7
Copy link

bhupendrarautela7 commented Apr 26, 2021

I am also facing a similar issue.

Worker Error: Error: Could not load helper ResembleHelper from module 'codeceptjs-resemblehelper':
Error: Module did not self-register:

Please provide solution.

@lind-eduard
Copy link

Same for me...Is it supposed to be fixed, or this helper abandoned?

@stracker-phil
Copy link
Contributor

I'm running into the same issue, but it seems that the problem is a different package:

The node.canvas package does not support workers yet (the resemble-helper uses that package internally). There are some open issues in the canvas project; this one appears to be the relevant one:

Automattic/node-canvas#1394

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

6 participants