Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: prepare html-reporter for pwt GUI integration #522

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 63 additions & 13 deletions hermione.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,89 @@
import os from 'os';
import PQueue from 'p-queue';
import path from 'path';
import Hermione, {TestResult as HermioneTestResult} from 'hermione';
import _ from 'lodash';
import PQueue from 'p-queue';
import {CommanderStatic} from '@gemini-testing/commander';

import {PluginAdapter} from './lib/plugin-adapter';
import {createWorkers, CreateWorkersRunner} from './lib/workers/create-workers';
import {FAIL, SUCCESS} from './lib/constants';
import {cliCommands} from './lib/cli-commands';
import {hasDiff} from './lib/common-utils';
import {formatTestResult} from './lib/server-utils';
import {ReporterConfig, ReporterOptions} from './lib/types';
import {parseConfig} from './lib/config';
import {FAIL, SUCCESS, ToolName} from './lib/constants';
import {HtmlReporter} from './lib/plugin-api';
import {StaticReportBuilder} from './lib/report-builder/static';
import {formatTestResult, logPathToHtmlReport, logError} from './lib/server-utils';
import {SqliteClient} from './lib/sqlite-client';
import {HermioneTestAdapter, ReporterTestResult} from './lib/test-adapter';
import {TestAttemptManager} from './lib/test-attempt-manager';
import {HtmlReporterApi, ReporterConfig, ReporterOptions} from './lib/types';
import {createWorkers, CreateWorkersRunner} from './lib/workers/create-workers';

let workers: ReturnType<typeof createWorkers>;

export = (hermione: Hermione, opts: Partial<ReporterOptions>): void => {
if (hermione.isWorker()) {
return;
}
const plugin = PluginAdapter.create(hermione, opts);

if (!plugin.isEnabled()) {
const config = parseConfig(opts);

if (!config.enabled) {
shadowusr marked this conversation as resolved.
Show resolved Hide resolved
return;
}

plugin
.addApi()
.addCliCommands()
.init(prepare);
const htmlReporter = HtmlReporter.create(config, {toolName: ToolName.Hermione});

(hermione as Hermione & HtmlReporterApi).htmlReporter = htmlReporter;

let isCliCommandLaunched = false;
let handlingTestResults: Promise<void>;

hermione.on(hermione.events.CLI, (commander: CommanderStatic) => {
_.values(cliCommands).forEach((command: string) => {
// eslint-disable-next-line @typescript-eslint/no-var-requires
require(path.resolve(__dirname, 'lib/cli-commands', command))(commander, config, hermione);

commander.prependListener(`command:${command}`, () => {
isCliCommandLaunched = true;
});
});
});

hermione.on(hermione.events.INIT, async () => {
if (isCliCommandLaunched) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

чет я не понимаю для чего это условие

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Это нужно чтобы при запуске cli команд типа gui или любых других команд html-reporter не запускался обычный прогон hermione.

Ранее это было реализовано в PluginAdapter в виде this._run = _.noop. Сейчас — этим способом.

return;
}

const dbClient = await SqliteClient.create({htmlReporter, reportPath: config.path});
const testAttemptManager = new TestAttemptManager();
const staticReportBuilder = StaticReportBuilder.create(htmlReporter, config, {dbClient, testAttemptManager});

handlingTestResults = Promise.all([
staticReportBuilder.saveStaticFiles(),
handleTestResults(hermione, staticReportBuilder, config)
]).then(async () => {
await staticReportBuilder.finalize();
}).then(async () => {
await htmlReporter.emitAsync(htmlReporter.events.REPORT_SAVED, {reportPath: config.path});
});
});

hermione.on(hermione.events.RUNNER_START, (runner) => {
workers = createWorkers(runner as unknown as CreateWorkersRunner);
});

hermione.on(hermione.events.RUNNER_END, async () => {
try {
await handlingTestResults;

logPathToHtmlReport(config);
} catch (e: unknown) {
logError(e as Error);
}
});
};

async function prepare(hermione: Hermione, reportBuilder: StaticReportBuilder, pluginConfig: ReporterConfig): Promise<void> {
async function handleTestResults(hermione: Hermione, reportBuilder: StaticReportBuilder, pluginConfig: ReporterConfig): Promise<void> {
const {path: reportPath} = pluginConfig;
const {imageHandler} = reportBuilder;

Expand Down
90 changes: 0 additions & 90 deletions lib/plugin-adapter.ts

This file was deleted.

75 changes: 47 additions & 28 deletions test/unit/hermione.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ describe('lib/hermione', () => {
let hermione;
let cacheExpectedPaths = new Map(), cacheAllImages = new Map(), cacheDiffImages = new Map();

let program;

const fs = _.clone(fsOriginal);
const originalUtils = proxyquire('lib/server-utils', {
'fs-extra': fs
Expand Down Expand Up @@ -49,19 +51,17 @@ describe('lib/hermione', () => {
'../image-handler': {ImageHandler}
});

const {PluginAdapter} = proxyquire('lib/plugin-adapter', {
'./sqlite-client': {SqliteClient},
'./server-utils': utils,
'./report-builder/static': {StaticReportBuilder},
'./plugin-api': proxyquire('lib/plugin-api', {
'./local-images-saver': proxyquire('lib/local-images-saver', {
'./server-utils': utils
})
const HtmlReporter = proxyquire('lib/plugin-api', {
'./local-images-saver': proxyquire('lib/local-images-saver', {
'./server-utils': utils
})
});
}).HtmlReporter;

const HermioneReporter = proxyquire('../../hermione', {
'./lib/plugin-adapter': {PluginAdapter}
const runHtmlReporter = proxyquire('../../hermione', {
'./lib/sqlite-client': {SqliteClient},
'./lib/server-utils': utils,
'./lib/report-builder/static': {StaticReportBuilder},
'./lib/plugin-api': {HtmlReporter}
});

const events = {
Expand Down Expand Up @@ -103,14 +103,35 @@ describe('lib/hermione', () => {
}, events, {ImageDiffError, NoRefImageError});
}

function mkCommander() {
const commander = {};
const props = [
'command',
'allowUnknownOption',
'description',
'option',
'action',
'on',
'prependListener'
];

for (const prop of props) {
commander[prop] = sinon.stub().returns(commander);
}

return commander;
}

function initReporter_(opts) {
opts = _.defaults(opts, {
enabled: true,
path: 'default-path',
baseHost: ''
});

HermioneReporter(hermione, opts);
runHtmlReporter(hermione, opts);

hermione.emit(hermione.events.CLI, program);

return hermione.emitAsync(hermione.events.INIT);
}
Expand Down Expand Up @@ -139,9 +160,9 @@ describe('lib/hermione', () => {
beforeEach(async () => {
hermione = mkHermione_();

sandbox.spy(PluginAdapter.prototype, 'addApi');
sandbox.spy(PluginAdapter.prototype, 'addCliCommands');
sandbox.spy(PluginAdapter.prototype, 'init');
program = mkCommander();

sandbox.spy(HtmlReporter, 'create');

sandbox.stub(fs, 'ensureDir').resolves();
sandbox.stub(fs, 'writeFile').resolves();
Expand Down Expand Up @@ -178,24 +199,22 @@ describe('lib/hermione', () => {
sandbox.restore();
});

it('should do nothing if plugin is disabled', () => {
return initReporter_({enabled: false}).then(() => {
assert.notCalled(PluginAdapter.prototype.addCliCommands);
});
});
it('should do nothing if plugin is disabled', async () => {
await initReporter_({enabled: false});

it('should add api', () => {
return initReporter_()
.then(() => assert.calledOnce(PluginAdapter.prototype.addCliCommands));
assert.notCalled(HtmlReporter.create);
});

it('should add cli commands', () => {
return initReporter_()
.then(() => assert.calledOnce(PluginAdapter.prototype.addCliCommands));
it('should add api', async () => {
await initReporter_();

assert.isObject(hermione.htmlReporter);
});

it('should init plugin', () => {
return initReporter_().then(() => assert.calledOnce(PluginAdapter.prototype.init));
it('should add cli commands', async () => {
await initReporter_();

assert.called(program.command);
});

it('should add skipped test to result', async () => {
Expand Down
Loading