Skip to content

Commit

Permalink
rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
[email protected] authored and [email protected] committed Jun 18, 2018
1 parent 97d9034 commit 77f4ddf
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 247 deletions.
10 changes: 6 additions & 4 deletions src/browser/connection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,13 @@ export default class BrowserConnection extends EventEmitter {
}

establish (userAgent) {
var parsedUserAgent = parseUserAgent(userAgent);

this.ready = true;
this.browserInfo.userAgent = parsedUserAgent.toString();
this.browserInfo.userAgentRaw = userAgent;

const parsedUserAgent = parseUserAgent(userAgent);

this.browserInfo.userAgent = parsedUserAgent.toString();
this.browserInfo.fullUserAgent = userAgent;
this.browserInfo.parsedUserAgent = parsedUserAgent;

this._waitForHeartbeat();
this.emit('ready');
Expand Down
7 changes: 0 additions & 7 deletions src/cli/argument-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ export default class CLIArgumentParser {
}
}


_parseSelectorTimeout () {
if (this.opts.selectorTimeout) {
assertType(is.nonNegativeNumberString, null, 'Selector timeout', this.opts.selectorTimeout);
Expand Down Expand Up @@ -187,11 +186,6 @@ export default class CLIArgumentParser {
this.opts.speed = parseFloat(this.opts.speed);
}

_parseScreenshotsPattern () {
if (!this.opts.screenshotPathPattern)
this.opts.screenshotPathPattern = '${DATE}_${TIME}/test-${TEST_INDEX}/${USERAGENT}/${TEST_INDEX}';
}

_parseConcurrency () {
if (this.opts.concurrency)
this.concurrency = parseInt(this.opts.concurrency, 10);
Expand Down Expand Up @@ -325,7 +319,6 @@ export default class CLIArgumentParser {
this._parsePorts();
this._parseBrowserList();
this._parseConcurrency();
this._parseScreenshotsPattern();

await Promise.all([
this._parseScreenshotsPath(),
Expand Down
6 changes: 2 additions & 4 deletions src/runner/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,10 @@ import { GeneralError } from '../errors/runtime';
import MESSAGE from '../errors/runtime/message';
import { assertType, is } from '../errors/runtime/type-assertions';


const DEFAULT_SELECTOR_TIMEOUT = 10000;
const DEFAULT_ASSERTION_TIMEOUT = 3000;
const DEFAULT_PAGE_LOAD_TIMEOUT = 3000;


export default class Runner extends EventEmitter {
constructor (proxy, browserConnectionGateway) {
super();
Expand All @@ -30,7 +28,7 @@ export default class Runner extends EventEmitter {
proxyBypass: null,
screenshotPath: null,
takeScreenshotsOnFails: false,
screenshotsPattern: null,
screenshotPathPattern: null,
skipJsErrors: false,
quarantineMode: false,
debugMode: false,
Expand Down Expand Up @@ -202,7 +200,7 @@ export default class Runner extends EventEmitter {
screenshots (path, takeOnFails = false, pattern) {
this.opts.takeScreenshotsOnFails = takeOnFails;
this.opts.screenshotPath = path;
this.opts.screenshotsPattern = pattern;
this.opts.screenshotPathPattern = pattern;

return this;
}
Expand Down
2 changes: 1 addition & 1 deletion src/runner/task.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default class Task extends EventEmitter {
this.running = false;
this.browserConnectionGroups = browserConnectionGroups;
this.tests = tests;
this.screenshots = new Screenshots(opts.screenshotPath, opts.screenshotsPattern);
this.screenshots = new Screenshots(opts.screenshotPath, opts.screenshotPathPattern);
this.warningLog = new WarningLog();

this.fixtureHookController = new FixtureHookController(tests, browserConnectionGroups.length);
Expand Down
69 changes: 11 additions & 58 deletions src/screenshots/capturer.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,25 @@
import { join as joinPath, dirname } from 'path';
import sanitizeFilename from 'sanitize-filename';
import { generateThumbnail } from 'testcafe-browser-tools';
import cropScreenshot from './crop';
import { ensureDir } from '../utils/promisified-functions';
import { isInQueue, addToQueue } from '../utils/async-queue';
import WARNING_MESSAGE from '../notifications/warning-message';
import * as patternParser from './pattern-parser';

const PNG_EXTENSION_RE = /(\.png)$/;
const FILENAME_EXT = '.png';
import correctFilePath from '../utils/correct-file-path';

export default class Capturer {
constructor (baseScreenshotsPath, testEntry, connection, namingOptions, warningLog) {
constructor (baseScreenshotsPath, testEntry, connection, pathPattern, warningLog) {
this.enabled = !!baseScreenshotsPath;
this.baseScreenshotsPath = baseScreenshotsPath;
this.testEntry = testEntry;
this.provider = connection.provider;
this.browserId = connection.id;
this.quarantineAttemptNum = namingOptions.quarantineAttemptNum;
this.testIndex = namingOptions.testIndex;
this.screenshotIndex = 1;
this.errorScreenshotIndex = 1;
this.warningLog = warningLog;
this.pathPattern = pathPattern;

var screenshotsPath = this.enabled ? this.baseScreenshotsPath : '';
const screenshotsPath = this.enabled ? this.baseScreenshotsPath : '';

this.screenshotsPath = screenshotsPath;
this.screenshotPathForReport = screenshotsPath;
this.screenshotsPatternName = namingOptions.patternName;

this.patternMap = namingOptions.patternMap;
this.patternOptions = namingOptions;
}

static _correctFilePath (path) {
var correctedPath = path
.replace(/\\/g, '/')
.split('/')
.map(str => sanitizeFilename(str))
.join('/');

return PNG_EXTENSION_RE.test(correctedPath) ? correctedPath : `${correctedPath}.png`;
}

static _getDimensionWithoutScrollbar (fullDimension, documentDimension, bodyDimension) {
Expand Down Expand Up @@ -80,38 +59,16 @@ export default class Capturer {
};
}

_getFileName (forError) {
let fileName = '';

if (this.screenshotsPatternName)
fileName = `${this.screenshotsPatternName}`;
else
fileName = `${forError ? this.errorScreenshotIndex : this.screenshotIndex}.png`;

if (forError)
this.errorScreenshotIndex++;
else
this.screenshotIndex++;

return fileName;
}

_parsePattern (namePattern) {
for (const pattern in this.patternMap)
namePattern = namePattern.replace(new RegExp(`\\$\\{${pattern}\\}`, 'g'), this.patternMap[pattern]);

return namePattern;
_getCustomScreenshotPath (customPath) {
return joinPath(this.baseScreenshotsPath, correctFilePath(customPath));
}

_getScreenshotPath (fileName, customPath) {
if (customPath)
return joinPath(this.baseScreenshotsPath, Capturer._correctFilePath(patternParser.parse(customPath, this.patternMap, this.patternOptions)));
_getScreenshotPath (forError) {
const parsedPath = this.pathPattern.getPath(forError);

var screenshotPath = this.quarantineAttemptNum !== null ?
joinPath(this.screenshotsPath, `run-${this.quarantineAttemptNum}`) :
this.screenshotsPath;
this.pathPattern.incrementFileIndexes(forError);

return joinPath(screenshotPath, fileName);
return joinPath(this.baseScreenshotsPath, parsedPath);
}

async _takeScreenshot (filePath, pageWidth, pageHeight) {
Expand All @@ -123,11 +80,7 @@ export default class Capturer {
if (!this.enabled)
return null;

var fileName = patternParser.parseFileIndex(this._getFileName(forError), this.screenshotIndex) + FILENAME_EXT;

fileName = forError ? joinPath('errors', fileName) : fileName;

var screenshotPath = this._getScreenshotPath(fileName, customPath);
const screenshotPath = customPath ? this._getCustomScreenshotPath(customPath) : this._getScreenshotPath(forError);

if (isInQueue(screenshotPath))
this.warningLog.addWarning(WARNING_MESSAGE.screenshotRewritingError, screenshotPath);
Expand Down
107 changes: 12 additions & 95 deletions src/screenshots/index.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,15 @@
import { find } from 'lodash';
import sanitizeFilename from 'sanitize-filename';
import moment from 'moment';
import useragent from 'useragent';
import Capturer from './capturer';
import * as patternParser from './pattern-parser';
import PathPattern from './path-pattern';

export default class Screenshots {
constructor (path, pattern) {
const now = moment(Date.now());

this.enabled = !!path;
this.screenshotsPath = path;
this.screenshotsPattern = pattern;
this.testEntries = [];
this.userAgentNames = [];
this.now = now;
this.currentDate = now.format('YYYY-MM-DD');
this.currentTime = now.format('HH-mm-ss');
}

static _escapeUserAgent (userAgent) {
return sanitizeFilename(userAgent.toString()).replace(/\s+/g, '_');
}

_getUsedUserAgent (name, testIndex, quarantineAttemptNum) {
var userAgent = null;

for (var i = 0; i < this.userAgentNames.length; i++) {
userAgent = this.userAgentNames[i];

if (userAgent.name === name && userAgent.testIndex === testIndex &&
userAgent.quarantineAttemptNum === quarantineAttemptNum)
return userAgent;
}

return null;
}

_getUserAgentName (userAgent, testIndex, quarantineAttemptNum) {
var userAgentString = userAgent.toString();
var userAgentName = Screenshots._escapeUserAgent(userAgentString);
var usedUserAgent = this._getUsedUserAgent(userAgentName, testIndex, quarantineAttemptNum);

if (usedUserAgent) {
usedUserAgent.index++;
return `${userAgentName}_${usedUserAgent.index}`;
}

this.userAgentNames.push({ name: userAgentName, index: 0, testIndex, quarantineAttemptNum });

return {
full: userAgentName,
browser: userAgent.family,
browserVersion: userAgent.toVersion(),
os: userAgent.os.family,
osVersion: userAgent.os.toVersion()
};
this.now = moment();
}

_addTestEntry (test) {
Expand All @@ -82,58 +36,21 @@ export default class Screenshots {
return this._getTestEntry(test).path;
}

_parsePattern (namePattern, options) {
if (!namePattern) return '';

var spaceRegex = new RegExp(' ', 'g');

this.patternMap = Object.assign(this.patternMap, {
FIXTURE: options.fixture.replace(spaceRegex, '-'),
TEST: options.test.replace(spaceRegex, '-'),
TEST_INDEX: options.testIndex,
DATE: this.currentDate,
TIME: this.currentTime,
USERAGENT: options.userAgent.full,
BROWSER: options.userAgent.browser.replace(spaceRegex, '_'),
BROWSER_VERSION: options.userAgent.browserVersion,
OS: options.userAgent.os.replace(spaceRegex, '_'),
OS_VERSION: options.userAgent.osVersion,
QUARANTINE_ATTEMPT: options.quarantineAttempt
});

for (const pattern in this.patternMap)
namePattern = namePattern.replace(new RegExp(`\\$\\{${pattern}\\}`, 'g'), this.patternMap[pattern]);

return namePattern;
}

createCapturerFor (test, testIndex, quarantineAttemptNum, connection, warningLog) {
var userAgent = useragent.parse(connection.browserInfo.userAgentRaw);
var testEntry = this._getTestEntry(test);
createCapturerFor (test, testIndex, quarantineAttempt, connection, warningLog) {
let testEntry = this._getTestEntry(test);

if (!testEntry)
testEntry = this._addTestEntry(test);

const patternOptions = {
testIndex: testIndex,
fixture: test.fixture.name,
test: test.name,
quarantineAttempt: quarantineAttemptNum ? quarantineAttemptNum : 1,
userAgent: this._getUserAgentName(userAgent, testIndex, quarantineAttemptNum),
currentTime: this.currentTime,
currentDate: this.currentDate
};

const patternMap = patternParser.generatePatternMap(patternOptions);

var namingOptions = {
const pathPattern = new PathPattern(this.screenshotsPattern, {
testIndex,
quarantineAttemptNum,
patternMap,
now: this.now,
patternName: patternParser.parse(this.screenshotsPattern, patternMap, patternOptions)
};
quarantineAttempt,
now: this.now,
fixture: test.fixture.name,
test: test.name,
parsedUserAgent: connection.browserInfo.parsedUserAgent,
});

return new Capturer(this.screenshotsPath, testEntry, connection, namingOptions, warningLog);
return new Capturer(this.screenshotsPath, testEntry, connection, pathPattern, warningLog);
}
}
Loading

0 comments on commit 77f4ddf

Please sign in to comment.