UNPKG

@icyphy/github-issue-junit

Version:

Read JUnit HTML output and add a comment to an open issue on GitHub.

137 lines (122 loc) 5.27 kB
/** * Grabs the summary line showing the number of JUnit tests from https://icyphy.github.io/ptII-test/reports/junit/html/overview-summary.html * * In case of error retries X times because server can response with different errors: * 1. "This page is taking way too long to load." - when page loads too long */ // Based on https://github.com/vitalets/github-trending-repos/blob/master/scripts/helpers/trends.js const axios = require('axios'); const cheerio = require('cheerio'); const config = require('../config'); const promiseRetry = require('promise-retry'); const {log, logError} = require('./logger'); const artifacts = require('./artifacts'); const util = require('util'); const RETRY_DEFAULTS = { retries: 5, minTimeout: 5000, }; // JUnit results page can take a long time to load (FIXME: Is this true?) const request = axios.create({ timeout: 30 * 1000, }); module.exports = class JUnitSummaryResults { constructor(url, retryOptions) { this._url = url; this._retryOptions = Object.assign({}, RETRY_DEFAULTS, retryOptions); this._html = null; this._$ = null; this._domRepos = null; this._repos = []; this._filename = this._url.split('/').pop(); } /** * Loads JUnit Summary HTML Results (3 retries). * * @returns {Promise<Array>} */ async getAll() { return promiseRetry((retry, attempt) => { const date = new Date(); const time = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; log(`Fetching JUnitSummaryResults (attempt #${attempt}, ${time}): ${this._url}`); return this._loadRepos().catch(e => this._retry(e, retry)); }, this._retryOptions); } async _loadRepos() { await this._loadHtml(); this._constructDom(); this._queryRepos(); // this._domRepos.each((index, repo) => this._extractRepoInfo(repo)); // FIXME: just deal with the first item. this._extractRepoInfo(this._domRepos[0]); if (this._repos.length === 0) { throw new Error(`Can't find JUnit Summary Results on page: ${this._url}`); } return this._repos; } _retry(error, retryFn) { const r = error.response; if (r) { log(`Error: ${r.status} ${r.statusText}`); this._saveHtmlToArtifacts(r.data); } else { logError(error); this._saveHtmlToArtifacts(this._html); } retryFn(error); } async _loadHtml() { this._html = ''; this._html = (await request(this._url)).data; } _constructDom() { this._$ = cheerio.load(this._html); } _queryRepos() { //this._domRepos = this._$('li', 'ol.repo-list'); this._domRepos = this._$('table'); log(`Found JUnit Summary HTML page: ${this._domRepos.length}`); } _extractRepoInfo(repo) { const $repo = this._$(repo); const repo2 = util.inspect($repo[0].parent, { showHidden: true, depth: 6 }); const repoLength = $repo.length const repoName = $repo[0].name const repoChildrenLength = $repo[0].children.length;; const repoParentLength = $repo[0].parent.children.length; const summaryRow = $repo[0].parent.children[9].children[1].children[2]; const summaryTable = util.inspect(summaryRow, {showHidden: true, depth: 3}); const tests = summaryRow.children[1].children[0].children[0].data; const failures = summaryRow.children[2].children[0].children[0].data; const errors = summaryRow.children[3].children[0].children[0].data; const skipped = summaryRow.children[4].children[0].children[0].data; const successRate = summaryRow.children[5].children[0].data; const time = summaryRow.children[6].children[0].data; // const summaryTable = util.inspect($repo[0].parent.children[3].children[1].children[0].children[2], {showHidden: true, depth: 2}); // log(`junit-summary-results.js: _extractRepoInfo(${repo}), name: ${repoName}, length: ${repoLength}, ${repoChildrenLength}, ${repoParentLength}: tests: ${tests}, failures: ${failures}, errors: ${errors}, skipped: ${skipped}, successRate: ${successRate}, time: ${time}`) // repo2: ${repo2}`); // const name = $repo.find('table').text().trim().replace(/ /g, ''); const name = $repo[0].parent.children[1].children[0].data.replace(/ /g, ''); if (!name) { throw new Error(`Can't extract repo name. Check selector 'title' on: ${this._url}`); } const info = { name, url: config.junit_url_index, description: `tests: ${tests}, failures: ${failures}, errors: ${errors}, skipped: ${skipped}, successRate: ${successRate}, time: ${time}`, }; // log(`junit-summary-results.js: _extractRepoInfo(}: ${name})`); this._repos.push(info); } _saveHtmlToArtifacts(html) { try { artifacts.save(`${this._filename}.html`, html); } catch (e) { logError('Error while saving artifact', e); } } }; function toNumber(el) { return parseInt(el.text().trim().replace(',', '') || 0); }