@nomyx/hardhat-adminui
Version:
A comprehensive Hardhat plugin providing a web-based admin UI for deployed smart contracts with Diamond proxy support, contract interaction, event monitoring, and deployment dashboard.
130 lines (129 loc) • 4.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ScenarioEngine = void 0;
const lodash_1 = require("lodash");
class ScenarioEngine {
constructor(hre) {
this.hre = hre;
}
async runBatch(scenarios) {
const results = [];
for (const scenario of scenarios) {
const result = await this.run(scenario);
results.push(result);
}
return results;
}
async run(scenario) {
const scenarioResult = {
name: scenario.metadata.name,
status: 'running',
steps: [],
startTime: new Date().toISOString(),
};
console.log(`Running scenario: ${scenario.metadata.name}`);
await this.runSetup(scenario.setup);
for (const individualScenario of scenario.scenarios) {
const steps = await this.runSingleScenario(individualScenario);
scenarioResult.steps.push(...steps);
}
await this.runTeardown(scenario.teardown);
scenarioResult.endTime = new Date().toISOString();
scenarioResult.duration = new Date(scenarioResult.endTime).getTime() - new Date(scenarioResult.startTime).getTime();
const hasFailedStep = scenarioResult.steps.some(s => s.status === 'failed');
scenarioResult.status = hasFailedStep ? 'failed' : 'passed';
return scenarioResult;
}
async runSetup(setup) {
if (!setup)
return;
if (setup.hooks?.before) {
for (const hook of setup.hooks.before) {
await this.hre.run(hook.task, hook.params);
}
}
}
async runSingleScenario(scenario) {
console.log(`-- Running: ${scenario.name}`);
const steps = [];
for (const step of scenario.steps) {
const stepResult = await this.executeStep(step);
steps.push(stepResult);
}
return steps;
}
async executeStep(step) {
const stepResult = {
description: step.description || step.task,
status: 'running',
logs: [],
timestamp: new Date().toISOString(),
};
const templateOptions = {
interpolate: /\$\{([\s\S]+?)\}/g,
};
// TODO: Implement a state management solution
const templateContext = {};
// Safely handle params compilation
let compiledParams = {};
try {
if (step.params && typeof step.params === 'object') {
const paramsString = JSON.stringify(step.params);
const compiledParamsString = (0, lodash_1.template)(paramsString, templateOptions)(templateContext);
// Ensure we have valid JSON before parsing
if (compiledParamsString && compiledParamsString.trim()) {
compiledParams = JSON.parse(compiledParamsString);
}
else {
compiledParams = step.params; // Fallback to original params
}
}
else if (step.params) {
compiledParams = step.params;
}
}
catch (templateError) {
console.warn(`Template processing failed for step "${step.description || step.task}":`, templateError);
compiledParams = step.params || {}; // Fallback to original params
}
try {
const startTime = Date.now();
await this.hre.run(step.task, compiledParams);
stepResult.duration = Date.now() - startTime;
if (step.shouldFail) {
stepResult.status = 'failed';
stepResult.error = `Operation ${step.task} was expected to fail, but it succeeded.`;
}
else {
stepResult.status = 'passed';
}
}
catch (error) {
const startTime = Date.now();
stepResult.duration = Date.now() - startTime;
if (!step.shouldFail) {
stepResult.status = 'failed';
stepResult.error = error.message;
}
else {
if (step.expectedError && !error.message.includes(step.expectedError)) {
stepResult.status = 'failed';
stepResult.error = `Operation ${step.task} failed with an unexpected error. Expected: '${step.expectedError}', Got: '${error.message}'`;
}
else {
stepResult.status = 'passed';
stepResult.logs.push(`Operation ${step.task} failed as expected.`);
}
}
}
return stepResult;
}
async runTeardown(teardown) {
if (!teardown?.hooks)
return;
for (const hook of teardown.hooks) {
await this.hre.run(hook.task, hook.params);
}
}
}
exports.ScenarioEngine = ScenarioEngine;