测试面板插件
面板插件允许您以不同方式可视化数据。本指南将向您展示如何使用 @grafana/plugin-e2e
测试您的面板插件在多个 Grafana 版本中正确渲染数据。
测试数据
为了测试您的面板插件,您需要为其提供测试数据。Grafana 自带 TestData 数据源,可用于模拟格式为时间序列、日志、跟踪、注释等的数据帧。
开始之前
要编写类似于本指南中的端到端测试,您需要通过预设配置 TestData
数据源。如果您还没有阅读关于如何设置资源的指南,请先阅读该指南。
测试面板选项
为了测试面板的行为,我们建议预设一个仪表盘,其中包含多个面板,展示面板的不同状态。这确保您的面板在各种配置下都能正常工作。通过避免依赖 Grafana 面板编辑 UI,这种方法减少了由 UI 更改导致的测试失败,使您的测试更加稳定和可靠。
在需要与面板编辑选项交互的情况下,我们提供了一组 API 来简化测试编写。这些 API 确保您的测试在不同版本的 Grafana 中都能一致地运行,而无需进行更改。
要与 Grafana 提供的任何选项组交互,请使用以下任一函数
函数名 | 返回的选项组 |
---|---|
getPanelOptions() | 面板选项 |
getStandardOptions() | 标准选项 |
getValueMappingOptions() | 值映射 |
getDataLinksOptions() | 数据链接 |
getThresholdsOptions() | 阈值 |
要与您的面板添加的自定义选项组交互,请使用 getCustomOptions('name of option group')
API。
调用这些 API 中的任何一个都会返回一个选项组对象,该对象提供了用于与该组内选项交互的 API。
函数名 | 返回选项类型 |
---|---|
getRadioGroup(label) | RadioGroup |
getSwitch(label) | Switch |
getTextInput(label) | 定位器 |
getNumberInput(label) | 定位器 |
getSliderInput(label) | 定位器 |
getSelect(label) | Select |
getMultiSelect(label) | MultiSelect |
getColorPicker(label) | ColorPicker |
getUnitPicker(label) | UnitPicker |
示例
此测试确保当用户从标准选项中选择不同的单位时,UI 中显示的单位会正确更新。
test('should change the unit when standard option is changed', async ({ panelEditPage }) => {
const standardOptions = panelEditPage.getStandardOptions();
const unitPicker = standardOptions.getUnitPicker('Unit');
const unit = page.getByTestId('unit-container');
await unitPicker.selectOption('Misc > Pixels');
await expect(unit).toContainText('px');
});
此测试验证在面板设置中选择不同的时区后,时钟面板中显示的时区会更新。
test('should change time zone when option is selected', async ({ panelEditPage, page }) => {
const timeFormatOptions = panelEditPage.getCustomOptions('Timezone');
const timeZoneSelect = timeFormatOptions.getSelect('Timezone');
const timeZone = page.getByTestId('clock-panel').getByTestId('time-zone');
await timeZoneSelect.selectOption('Europe/Stockholm');
await expect(timeZone).toContainText('Europe/Stockholm');
});
此测试验证在时钟面板中启用等宽字体选项后,面板的字体族正确更新为 "monospace"。
test('should change the font family when enabling monospace', async ({ panelEditPage, page }) => {
const clockOptions = panelEditPage.getCustomOptions('Clock');
const monospaceFont = clockOptions.getSwitch('Font monospace');
const panel = page.getByTestId('clock-panel');
await monospaceFont.check();
await expect(panel).toHaveCSS('font-family', 'monospace');
});
此测试确保在时钟面板选项中选择“倒计时”模式时,时钟以倒计时模式运行。
test('should count down time when option is selected', async ({ panelEditPage, page }) => {
const clockOptions = panelEditPage.getCustomOptions('Clock');
const clockMode = clockOptions.getRadioGroup('Mode');
const panel = page.getByTestId('clock-panel-countdown');
await clockMode.check('Countdown');
await expect(panel).toBeVisible();
});
此测试验证当在面板选项的颜色选择器中选择新颜色时,面板的背景颜色会改变。
test('should update background color based on selected option', async ({ panelEditPage, page }) => {
const color = { hex: '#73bf69', rgb: 'rgb(115, 191, 105)' };
const clockOptions = panelEditPage.getCustomOptions('Clock');
const backgroundColor = clockOptions.getColorPicker('Background color');
const panel = page.getByTestId('clock-panel');
await backgroundColor.selectOption(color.hex);
await expect(panel).toHaveCSS('background-color', color.rgb);
});
表格面板默认定义了一个名为 Show table header
的自定义面板选项。如果此开关被禁用,表格面板应从表格中移除表头。
以下测试验证了字段名(表头)默认显示,并且在未选择 Show table header
选项时会被移除。
test('should hide headers when "Show table header" is unchecked', async ({ panelEditPage, selectors }) => {
await panelEditPage.datasource.set('gdev-testdata');
await panelEditPage.setVisualization('Table');
await expect(await panelEditPage.panel.fieldNames.count()).toBeGreaterThan(0);
const showTableHeaderSwitch = panelEditPage
.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldLabel('Table Show table header'))
.getByLabel('Toggle switch');
await panelEditPage.collapseSection('Table');
await showTableHeaderSwitch.uncheck();
await expect(panelEditPage.panel.fieldNames).not.toBeVisible();
});
测试面板如何处理不同的数据类型
数据帧模型在设计上具有灵活性。其目的是允许数据源根据各种不同的数据类型返回查询响应。Grafana 框架中的数据类型定义或声明包括种类(kind)和格式(format)。
面板不必支持所有数据类型。但是,如果您的面板应该支持某种数据类型,我们建议您编写端到端测试来验证它是否按预期工作。
“无数据”场景
如果数据源返回 无数据
,那么向用户指示这一点是很好的做法。在以下代码片段中,我们测试了表格面板如何处理 无数据
场景。
test('should display "No data" in case no data response was passed to the panel', async ({ panelEditPage, page }) => {
await panelEditPage.datasource.set('gdev-testdata');
await panelEditPage.setVisualization('Table');
await page.getByLabel('Scenario').last().click();
await page.getByText('No Data Points').click();
await panelEditPage.refreshPanel();
await expect(panelEditPage.panel.locator).toContainText('No data');
});
多个数据帧
表格面板一次只能显示一个数据帧。如果向面板传递了多个数据帧,无论它们源自同一查询还是不同查询,面板都只显示第一个数据帧。
此外,面板中还会有一个下拉菜单,允许用户在不同数据帧之间切换。此行为是表格面板特有的。
以下代码片段测试了在向面板传递两个数据帧的情况下,插件是否显示包含两个值的下拉菜单。
test('should display dropdown with two values when two frames are passed to the panel', async ({
panelEditPage,
page,
selectors,
}) => {
await panelEditPage.datasource.set('gdev-testdata');
await panelEditPage.setVisualization('Table');
await panelEditPage.getQueryEditorRow('A').getByLabel('Alias').fill('a');
await page.getByText('Add query').click();
await panelEditPage.getQueryEditorRow('B').getByLabel('Alias').fill('b');
await panelEditPage.refreshPanel();
await panelEditPage.panel.locator.getByRole('combobox').click();
await expect(panelEditPage.getByTestIdOrAriaLabel(selectors.components.Select.option)).toHaveText(['a', 'b']);
});