HuddleEng / PhantomCSS

Visual/CSS regression testing with PhantomJS
MIT License
4.72k stars 257 forks source link

Question: How to not duplicate `phantom.init()` settings for every test suite? #107

Closed chris-dura closed 9 years ago

chris-dura commented 9 years ago

Forgive me if this is completely obvious, but I'm more designer than developer right now...

Anyway, so, I've created a few test suites using PhantomCSS to generate some image diffs. They're pretty much structured exactly like your demos. However, I noticed that I end up copy+pasting the exact same phantomcss.init() configuration over and over into each test.js. I would much rather have a shared phantomcss.init() in a single location so if we decide to change the configuration, I don't have to edit every test suite.

The one caveat is that, instead of storing all screenshots in a single directory, I want to store each test's screenshots in its own directory to organize them a little better.

Anyway, I tried using init() and update() like illustrated below, but it didn't seem to work for me. I would appreciate any guidance on how best to accomplish this.

// includes.js

var fs = require('fs'),
    phantomcss = require(fs.absolute(fs.workingDirectory + '/node_modules/phantomcss/phantomcss.js'));

phantomcss.init({
    casper:                     casper,
    libraryRoot:                fs.absolute(fs.workingDirectory + '/node_modules/phantomcss'),
    screenshotRoot:             fs.absolute(fs.workingDirectory + '/shots/screenshots'),
    comparisonResultRoot:       fs.absolute(fs.workingDirectory + '/shots/results'),
    failedComparisonsRoot:      fs.absolute(fs.workingDirectory + '/shots/failures'),
    addLabelToFailedImage:      false,
    mismatchTolerance:          0.01,
    rebase:                     casper.cli.get('rebase'),
    hideElements: '#thing.selector',
    outputSettings: {
        errorColor: {red: 255, green: 255, blue: 0},
        errorType: 'movement',
        transparency: 0.25
    }
});
// test1.js
...
casper.test.begin('Test Suite 1', function suite(test) {
    phantomcss.init({
        screenshotRoot: fs.absolute(fs.workingDirectory + '/shots/screenshots/test1')
    });
   phantomcss.screenshot('body');
});
...
// test2.js
...
casper.test.begin('Test Suite 2', function suite(test) {
    phantomcss.update({
        screenshotRoot: fs.absolute(fs.workingDirectory + '/shots/screenshots/test2')
    });
    phantomcss.screenshot('body');
});
...
jamescryer commented 9 years ago

That should work, It's not obvious to me what you might be doing wrong.

Another way to get reuse is simply to create a function

function myPhantomCssInit( rootPath ){
    phantomcss.init({
        screenshotRoot: fs.absolute(fs.workingDirectory + rootPath),
        /*
        Other stuff
       */
    });
}

casper.test.begin('Test Suite 1', function suite(test) {
   myPhantomCssInit( '/shots/screenshots/test1' );
   phantomcss.screenshot('body');
});
chris-dura commented 9 years ago

Thanks, wrapping it in my own function is more elegant than where I was headed... I got tunnel vision on trying to use CasperJS cli hooks or using a global setUp and tearDown methods. I wonder if phantomcss.init()/update() is working as expected, but just didn't look like it because I didn't define the comparisonResultRoot as well... https://github.com/Huddle/PhantomCSS/issues/110#issuecomment-90608306

asymmetric commented 9 years ago

What I did is I run phantomcss.init in a separate file, common.js, and use exports.phantomcss to make it available to the outside.

var require = patchRequire(require);
var phantomcss = require('../../vendor/components/phantomcss/phantomcss');

phantomcss.init({
  libraryRoot: 'vendor/components/phantomcss',
  screenshotRoot: 'test/visual/screenshots/baselines',
  comparisonResultRoot: 'test/visual/screenshots/results',
  failedComparisonRoot: 'test/visual/screenshots/failures',
  rebase: casper.cli.get('rebase')
});

exports.phantomcss = phantomcss;

My test files then do a var common = require('support/common'); and access phantomcss thru common.phantomcss.

Works great.

PramodDutta commented 7 years ago

@asymmetric - Can you explain more you code, How to use it further ?. I created the util file and copied the phantom.init function but when I use it in the main.js file but require('util.js). It does not work.

e.g

Configs.js

var require = patchRequire('require');
var phantomcss = require('phantomcss');
var fs = require('fs');

phantomcss.init(
    {
        rebase: casper.cli.get("rebase"),
        casper: casper,
        libraryRoot: fs.absolute(fs.workingDirectory + ''),
        screenshotRoot: fs.absolute(fs.workingDirectory + '/screenshots'),
        failedComparisonsRoot: fs.absolute(fs.workingDirectory + '/failures'),
        addLabelToFailedImage: false,
        prefixCount: true,
        mismatch : 0

    });

exports.phantomcss = phantomcss;

Main.js

var configs = require('./configs');
configs.phantomcss.screenshot(rp.rps.mainBodyHeader, rp.rps.screenshot_mainBodyHeader);

It does not work

FDiskas commented 7 years ago

@PramodDutta phantomcss is not a node module - use full path in require function. You can read about your solution here https://asymmetric.github.io/2015/04/14/phantomcss/