Plugins SDK for HTML Reporter
Reference for available dependencies, SDK components, and extension points for plugin development.
Available Dependencies
Plugins can use the following dependencies provided by HTML Reporter at runtime. These dependencies do not need to be included in the bundle — they will be passed through the wrapper function.
| Dependency | Description |
|---|---|
@gravity-ui/icons | Gravity UI Icons |
@gravity-ui/uikit | Gravity UI components |
axios | HTTP client for server requests |
classnames | Utility for working with CSS classes |
html-reporter/plugins-sdk | SDK for server part (ExtensionPointName) |
html-reporter/plugins-sdk/ui | SDK for UI components |
immer | Immutable state updates |
lodash | Data manipulation utilities |
react | React 18 |
react-dom | React DOM |
react-redux | React bindings for Redux |
react/jsx-runtime | JSX Runtime |
redux | Redux for state management |
redux-thunk | Middleware for async actions (built-in) |
reselect | Memoized selectors for Redux |
Plugins SDK UI
The html-reporter/plugins-sdk/ui module exports components and types for creating plugin UIs.
CollapsibleSection
A collapsible section integrated with the report's Redux state.
import { CollapsibleSection } from "html-reporter/plugins-sdk/ui";
interface CollapsibleSectionProps {
/** Unique section identifier */
id: string;
/** Section title */
title: string;
/** Section content */
children?: ReactNode;
/** CSS class */
className?: string;
/** Whether the section is expanded by default */
defaultExpanded?: boolean;
/** Callback when state changes */
onUpdate?: (expanded: boolean) => void;
}
Usage example:
<CollapsibleSection
id="plugins.my-plugin.section"
title="My Section"
defaultExpanded={false}
onUpdate={expanded => {
if (expanded) {
// Load data when expanded
}
}}
>
<div>Section content</div>
</CollapsibleSection>
PanelSection
Section for the settings panel.
import { PanelSection } from "html-reporter/plugins-sdk/ui";
interface PanelSectionProps {
/** Section title */
title: ReactNode;
/** Description */
description?: ReactNode;
/** Content */
children?: ReactNode;
}
State
Type of the root Redux store state.
import { State } from "html-reporter/plugins-sdk/ui";
// Use for typing selectors
const mySelector = (state: State) => state.tree.results.byId;
Features
Flags for available report features.
import { Features } from "html-reporter/plugins-sdk/ui";
const availableFeatures = useSelector(state => {
return state.app.availableFeatures;
});
if (!availableFeatures.some(feature => feature.name === Features.RunTestsFeature.name)) {
return null;
}
The pluginOptions Object
A global pluginOptions object is available in the plugin UI component:
declare const pluginOptions: {
/** Plugin name (from configuration) */
pluginName: string;
/** Plugin configuration (config field from configuration) */
pluginConfig: object;
/** Prefix for server endpoints: /plugin-routes/{pluginName}/ */
pluginServerEndpointPrefix: string;
/** Report Redux actions */
actions: object;
/** Report action names */
actionNames: object;
/** Redux Store selectors, see html-reporter/lib/static/modules/selectors */
selectors: object;
};
Extension Points
Extension points determine where in the report interface the plugin component will be placed.
| Point | Description | Component Props |
|---|---|---|
result_meta | Test result area, near meta information | result: ReporterTestResult |
settings-panel | Settings panel | — |
run-test-options | Test run options, near the run test button | — |
ExtensionPointName
Use enum to specify the extension point in the preset:
import { ExtensionPointName } from "html-reporter/plugins-sdk";
// Available values:
ExtensionPointName.ResultMeta; // "result_meta"
ExtensionPointName.MenuBar; // "menu-bar"
ExtensionPointName.Root; // "root"
Positioning
The position parameter determines the component placement relative to the extension point:
| Value | Description |
|---|---|
"before" | Before the extension point content |
"after" | After the extension point content |
"wrap" | Wrap the extension point content |
CSS and Styling
CSS Modules
It is recommended to use CSS Modules for style isolation:
.container {
padding: 16px;
}
.result {
display: flex;
gap: 8px;
}
import styles from "./Plugin.module.css";
<div className={styles.container}>
<div className={styles.result}>...</div>
</div>;
Gravity UI CSS Variables
HTML Reporter uses the Gravity UI theme. You can use CSS variables for style consistency:
.myElement {
/* Text colors */
color: var(--g-color-text-primary);
color: var(--g-color-text-secondary);
color: var(--g-color-text-brand);
color: var(--g-color-text-danger);
/* Background colors */
background: var(--g-color-base-background);
background: var(--g-color-base-brand);
/* Borders */
border-color: var(--g-color-line-generic);
/* Spacing and sizes */
padding: var(--g-spacing-2); /* 8px */
padding: var(--g-spacing-4); /* 16px */
}
CSS Injection into Bundle
Use the vite-plugin-css-injected-by-js plugin to include CSS in the JavaScript bundle:
import cssInjectedByJsPlugin from "vite-plugin-css-injected-by-js";
export default defineConfig({
plugins: [cssInjectedByJsPlugin()],
});
Typing
Extending DefaultRootState
To type the plugin state in Redux, extend DefaultRootState:
import type { State } from "html-reporter/plugins-sdk/ui";
interface MyPluginState {
data: Record<string, { status: string; value: any }>;
}
declare module "react-redux" {
export interface DefaultRootState extends State {
plugins: {
myPlugin: MyPluginState;
};
}
}
Global pluginOptions
declare global {
const pluginOptions: {
pluginConfig: MyPluginConfig;
pluginServerEndpointPrefix: string;
};
}