Skip to content

Commit

Permalink
Add additional reporter tests and improved reporter UI. Refs NimaSoro…
Browse files Browse the repository at this point in the history
  • Loading branch information
badsyntax committed Aug 21, 2017
1 parent 7001c47 commit ed6aad2
Show file tree
Hide file tree
Showing 12 changed files with 181 additions and 89 deletions.
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ docs/
.vscode/
dist/
differencify_report/
screenshots/
screenshots/
coverage/
43 changes: 32 additions & 11 deletions src/Reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import logger from './logger';
import getHtmlReport from './reportTypes/htmlReport';
import getJsonReport from './reportTypes/jsonReport';

const saveReport = (filepath, contents) => {
const saveReport = (filepath, contents) =>
fs.writeFileSync(filepath, contents);
};

const getReport = (key, results) => {
switch (key) {
Expand All @@ -18,23 +17,44 @@ const getReport = (key, results) => {
}
};

class Reporter {
const getImages = dir =>
fs
.readdirSync(dir)
.filter(file => fs.lstatSync(path.join(dir, file)).isFile());

constructor() {
const getImagePath = (files, file) =>
(files.includes(file) ? file : null);

class Reporter {
constructor(options = {}) {
this.options = options;
this.results = [];
}

addResult(outcome, fileName, message, diff) {
addResult({ outcome, testName, result }) {
this.results.push({
outcome,
fileName: path.basename(fileName),
message,
diff: diff ? path.basename(diff) : null,
testName,
result,
});
}

getResults() {
return this.results;
const { testReportPath, saveDifferencifiedImage } = this.options;
const images = getImages(testReportPath);
return this.results.map(result =>
// eslint-disable-next-line prefer-object-spread/prefer-object-spread
Object.assign(
{
referenceFileName: getImagePath(images, `${result.testName}.png`),
diffFileName:
!result.outcome && saveDifferencifiedImage
? getImagePath(images, `${result.testName}_differencified.png`)
: null,
},
result,
),
);
}

generate(types, testReportPath) {
Expand All @@ -45,10 +65,11 @@ class Reporter {
saveReport(filepath, template);
logger.log(`Generated ${type} report at ${filepath}`);
} catch (err) {
logger.error(`Unable to generate ${type} report at ${filepath}: ${err}`);
logger.error(
`Unable to generate ${type} report at ${filepath}: ${err}`,
);
}
});
return true;
}
}

Expand Down
53 changes: 35 additions & 18 deletions src/Reporter.test.js
Original file line number Diff line number Diff line change
@@ -1,53 +1,53 @@
import fs from 'fs';
import Reporter, { getHtmlReport, getJsonReport } from './Reporter';
import logger from './logger';
import { globalConfig } from './defaultConfig';

jest.mock('fs', () => ({
writeFileSync: jest.fn(),
readdirSync: jest.fn(() => []),
}));

jest.mock('./logger', () => ({
log: jest.fn(),
error: jest.fn(),
}));

const results = [
{
outcome: true,
fileName: 'image1.png',
message: 'no mismatch found',
diff: null,
testName: 'default',
result: 'no mismatch found',
},
{
outcome: true,
fileName: 'image2.png',
message: 'no mismatch found',
diff: null,
testName: 'default2',
result: 'no mismatch found',
},
{
outcome: false,
fileName: 'image2.png',
message: 'mismatch found!',
diff: 'image2_diff.png',
testName: 'default3',
result: 'mismatch found!',
},
];

describe('Generate report index', () => {
let reporter;

beforeEach(() => {
reporter = new Reporter();
reporter = new Reporter(globalConfig);
results.forEach(result =>
reporter.addResult(
result.outcome,
result.fileName,
result.message,
result.diff,
),
reporter.addResult({
outcome: result.outcome,
testName: result.testName,
result: result.result,
}),
);
});

afterEach(() => {
fs.writeFileSync.mockClear();
fs.readdirSync.mockClear();
logger.log.mockClear();
});

Expand All @@ -58,9 +58,10 @@ describe('Generate report index', () => {
},
'./example/path',
);
expect(fs.readdirSync).toHaveBeenCalledWith(globalConfig.testReportPath);
expect(fs.writeFileSync).toHaveBeenCalledWith(
'example/path/index.html',
getHtmlReport(results),
getHtmlReport(reporter.getResults()),
);
});

Expand All @@ -71,9 +72,10 @@ describe('Generate report index', () => {
},
'./example/path',
);
expect(fs.readdirSync).toHaveBeenCalledWith(globalConfig.testReportPath);
expect(fs.writeFileSync).toHaveBeenCalledWith(
'example/path/report.json',
getJsonReport(results),
getJsonReport(reporter.getResults()),
);
});

Expand All @@ -92,4 +94,19 @@ describe('Generate report index', () => {
'Generated html report at example/path/index.html',
);
});

it('logs the error', () => {
fs.writeFileSync.mockImplementation(() => {
throw new Error('write file error');
});
reporter.generate(
{
html: 'index.html',
},
'./example/path',
);
expect(logger.error).toHaveBeenCalledWith(
'Unable to generate html report at example/path/index.html: Error: write file error',
);
});
});
5 changes: 5 additions & 0 deletions src/chromyRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ const run = async (chromy, options, test, reporter) => {
const result = await compareImage(options, test.name, reporter);
prefixedLogger.log(result);
} catch (error) {
reporter.addResult({
outcome: false,
testName: test.name,
result: error.message || '',
});
prefixedLogger.error(error);
return false;
}
Expand Down
54 changes: 39 additions & 15 deletions src/chromyRunner.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { globalConfig, testConfig, configTypes } from './defaultConfig';
import actions from './actions';
import functionToString from './helpers/functionToString';
import freezeImage from './freezeImage';
import Reporter from './Reporter';

jest.mock('chromy', () => () =>
({
Expand All @@ -29,6 +30,10 @@ jest.mock('./compareImage', () => jest.fn(arg =>

jest.mock('./helpers/functionToString');

jest.mock('./Reporter', () => () => ({
addResult: jest.fn(),
}));

let loggerCalls = [];
logger.prefix = () => logger;
logger.log = (...args) => {
Expand All @@ -40,9 +45,15 @@ fs.writeFileSync = (...args) => {
writeFileSyncCalls.push(...args);
};

let mockReporter;

const chromy = new Chromy();

describe('ChromyRunner', () => {
beforeEach(() => {
mockReporter = new Reporter();
});

afterEach(() => {
loggerCalls = [];
writeFileSyncCalls = [];
Expand All @@ -55,7 +66,7 @@ describe('ChromyRunner', () => {
});
it('run update', async () => {
testConfig.type = configTypes.update;
const result = await run(chromy, globalConfig, testConfig);
const result = await run(chromy, globalConfig, testConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.screenshotDocument).toHaveBeenCalledTimes(1);
Expand All @@ -66,7 +77,7 @@ describe('ChromyRunner', () => {
});
it('run test', async () => {
testConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, testConfig);
const result = await run(chromy, globalConfig, testConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.screenshotDocument).toHaveBeenCalledTimes(1);
Expand All @@ -75,11 +86,24 @@ describe('ChromyRunner', () => {
expect(loggerCalls[2]).toEqual('screenshot saved in -> ./differencify_report/default.png');
expect(writeFileSyncCalls).toEqual(['./differencify_report/default.png', 'png file']);
});
it('run test fail', async () => {
// eslint-disable-next-line prefer-object-spread/prefer-object-spread
const failTestConfig = Object.assign({}, testConfig);
failTestConfig.steps = [{
name: 'test',
}];
// eslint-disable-next-line prefer-object-spread/prefer-object-spread
const failGlobalConfig = Object.assign({}, globalConfig);
failGlobalConfig.screenshots = null;
const result = await run(chromy, failGlobalConfig, failTestConfig, mockReporter);
expect(result).toEqual(false);
expect(mockReporter.addResult).toHaveBeenCalledWith({ outcome: false, result: '', testName: 'default' });
});
describe('Chromy runner', () => {
it('Step runner: test action', async () => {
testConfig.type = configTypes.test;
testConfig.steps.push({ name: actions.test, value: globalConfig.testReportPath });
const result = await run(chromy, globalConfig, testConfig);
const result = await run(chromy, globalConfig, testConfig, mockReporter);
testConfig.steps.pop({ name: actions.test, value: globalConfig.testReportPath });
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
Expand All @@ -91,7 +115,7 @@ describe('ChromyRunner', () => {
});
it('Step runner: update action', async () => {
testConfig.type = configTypes.update;
const result = await run(chromy, globalConfig, testConfig);
const result = await run(chromy, globalConfig, testConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.screenshotDocument).toHaveBeenCalledTimes(1);
Expand All @@ -115,7 +139,7 @@ describe('ChromyRunner', () => {
],
};
newConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.screenshot).toHaveBeenCalledTimes(1);
Expand All @@ -137,7 +161,7 @@ describe('ChromyRunner', () => {
],
};
newConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.screenshotDocument).toHaveBeenCalledTimes(1);
Expand All @@ -159,7 +183,7 @@ describe('ChromyRunner', () => {
],
};
newConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.screenshotSelector).toHaveBeenCalledTimes(1);
Expand All @@ -183,7 +207,7 @@ describe('ChromyRunner', () => {
],
};
newConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.wait).toHaveBeenCalledWith(10);
Expand All @@ -203,7 +227,7 @@ describe('ChromyRunner', () => {
],
};
newConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.wait).toHaveBeenCalledWith('selector name');
Expand All @@ -223,7 +247,7 @@ describe('ChromyRunner', () => {
],
};
newConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.wait).toHaveBeenCalledTimes(1);
Expand All @@ -243,7 +267,7 @@ describe('ChromyRunner', () => {
],
};
newConfig.type = configTypes.test;
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(false);
expect(chromy.goto).toHaveBeenCalledWith('www.example.com');
expect(chromy.wait).toHaveBeenCalledTimes(0);
Expand All @@ -263,7 +287,7 @@ describe('ChromyRunner', () => {
{ name: 'execute', value: () => {} },
],
};
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.evaluate).toHaveBeenCalledTimes(1);
expect(loggerCalls[0]).toEqual('waiting for to execute function in browser');
Expand All @@ -279,7 +303,7 @@ describe('ChromyRunner', () => {
{ name: 'execute', value: 123 },
],
};
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(false);
expect(chromy.evaluate).toHaveBeenCalledTimes(0);
expect(loggerCalls[0]).toEqual('failed to detect execute function');
Expand All @@ -299,7 +323,7 @@ describe('ChromyRunner', () => {
{ name: 'freezeImage', value: 'selector' },
],
};
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(true);
expect(chromy.evaluate).toHaveBeenCalledWith('return string function');
expect(functionToString).toHaveBeenCalledWith(freezeImage, 'selector');
Expand All @@ -318,7 +342,7 @@ describe('ChromyRunner', () => {
{ name: 'freezeImage', value: 'selector' },
],
};
const result = await run(chromy, globalConfig, newConfig);
const result = await run(chromy, globalConfig, newConfig, mockReporter);
expect(result).toEqual(false);
expect(chromy.evaluate).toHaveBeenCalledWith('return string function');
expect(functionToString).toHaveBeenCalledWith(freezeImage, 'selector');
Expand Down
Loading

0 comments on commit ed6aad2

Please sign in to comment.