PR #45 on Protractor Flake added the ability to specify custom parsers. On my project we’re sharding (running multiple instances of) Protractor and using the following parser to re-run only the failing spec files.
You’ll want to replace the /test/functional/specs/
and the browser name (chrome
) below with your actual values.
const _ = require('lodash'); // If only one spec file fails, on the next re-run, we don't get the filename on the output. So // if it fails again, we need re-use the filename from the previous run let previousSpecFileNames = []; module.exports = { parse: function (protractorTestOutput) { if (previousSpecFileNames.length === 1) { return previousSpecFileNames; } const lines = protractorTestOutput.split(`\n`); // At the end of the output there's a summary of which shards failed const failedLines = lines.filter(line => line.startsWith('[launcher] chrome') && line.includes('failed') && line.includes('test(s)')); // regex matches #number and #number-number (ie #1 or #1-1, #1-2, #1-3...) const testNumberRegExp = new RegExp(/#[0-9](-[0-9]+)?/); const failedSpecsLines = failedLines.map(failedLine => { const match = testNumberRegExp.exec(failedLine); if (match) { // Lines with "#number-number ]" (space followed by closing bracket) and "Specs: " return lines.filter(line => line.includes(`${match[0]}] `) && line.includes('Specs: ')); } return null; }).reduce(function (a, b) { // Flatten the array return a.concat(b); }, []); const specFileNames = _.compact(failedSpecsLines).map(line => { const startingPathPosition = line.indexOf('/test/functional/specs/'); return line.substr(startingPathPosition + 1); }); previousSpecFileNames = specFileNames; return specFileNames; }, name: 'Your custom parser name', };