import intel from 'intel'; import get from 'lodash.get'; import { SitespeedioPlugin } from '@sitespeed.io/plugin'; import send from './send.js'; import { throwIfMissing } from '../../support/util.js'; const log = intel.getLogger('sitespeedio.plugin.matrix'); function getBrowserData(data) { return data && data.browser ? `${data.browser.name} ${data.browser.version} ${get( data, 'android.model', '' )} ${get(data, 'android.androidVersion', '')} ${get( data, 'android.id', '' )} ` : ''; } export default class MatrixPlugin extends SitespeedioPlugin { constructor(options, context, queue) { super({ name: 'matrix', options, context, queue }); } open(context, options = {}) { this.matrixOptions = options.matrix || {}; this.options = options; log.info('Starting the matrix plugin'); throwIfMissing(options.matrix, ['accessToken', 'host', 'room'], 'matrix'); this.resultUrls = context.resultUrls; this.errorTexts = ''; this.waitForUpload = false; this.alias = {}; } async processMessage(message) { const options = this.matrixOptions; switch (message.type) { case 'browsertime.browser': { this.browserData = message.data; break; } case 'gcs.setup': case 'ftp.setup': case 's3.setup': { this.waitForUpload = true; break; } case 'browsertime.alias': { this.alias[message.url] = message.data; break; } case 'sitespeedio.render': { if (this.errorTexts !== '') { const room = get(options, 'rooms.error', options.room); try { const answer = await send( options.host, room, options.accessToken, this.errorTexts ); log.debug('Got %j from the matrix server', answer); } catch { // TODO what todo? } } break; } case 'browsertime.config': { if (message.data.screenshot === true) { this.screenshotType = message.data.screenshotType; } break; } case 'error': { // We can send too many messages to Matrix and get 429 so instead // we bulk send them all one time if (options.messages.includes('error')) { this.errorTexts += `⚠️ Error from ${ message.source } testing ${message.url || ''}
${message.data}`;
}
break;
}
case 'budget.result': {
if (options.messages.includes('budget')) {
let text = '';
// We have failing URLs in the budget
if (Object.keys(message.data.failing).length > 0) {
const failingURLs = Object.keys(message.data.failing);
text += `${ get(this.options, 'name', '') + ' ' }${getBrowserData(this.browserData)}
`; for (let url of failingURLs) { text += `${message.data.error[url]}`;
}
}
if (
Object.keys(message.data.error).length === 0 &&
Object.keys(message.data.failing).length === 0
) {
text += `🎉 All (${ Object.keys(message.data.working).length }) URLs passed the budget.
`; text += `${ get(this.options, 'name', '') + ' ' }${getBrowserData(this.browserData)}
`; } if (this.waitForUpload) { this.budgetText = text; } else { const room = get(options, 'rooms.budget', options.room); await send(options.host, room, options.accessToken, text); } } break; } case 'gcs.finished': case 'scp.finished': case 'ftp.finished': case 's3.finished': { if (this.waitForUpload && options.messages.includes('budget')) { const room = get(options, 'rooms.budget', options.room); await send(options.host, room, options.accessToken, this.budgetText); } break; } } } } export function messageTypes() { return ['error', 'budget']; }