跳转到主要内容

选择 UI 元素

本指南解释了选择器在 Grafana 端到端测试中的作用,以及如何使用它们在多个版本的 Grafana 中安全地与 UI 元素交互。

Grafana 端到端选择器

从 Grafana 7.0.0 版本开始,Grafana 中的端到端测试依赖于在 @grafana/e2e-selectors 包中定义的选择器来选择 Grafana UI 中的元素。

选择 Grafana UI 元素可能具有挑战性,因为选择器可能定义在 aria-label 属性或 data-testid 属性上。最初,选择器使用了 aria-label 属性,但现在大多数选择器已迁移到使用 data-testid 属性。

Playwright 定位器用于 Grafana UI 元素

@grafana/plugin-e2e 定义的 所有页面 都公开了一个 getByGrafanaSelector 方法。此方法返回一个 Playwright 定位器,该定位器解析为一个或多个元素,使用在元素上定义的适当 HTML 属性。每当您想根据 grafana/e2e-selectors 解析 Playwright 定位器时,您都应该始终使用此方法。

panelEditPage.getByGrafanaSelector(selectors.components.CodeEditor.container).click();

选择器固定装置

@grafana/e2e-selectors包中定义的选择器与特定的Grafana版本相关联。这意味着选择器可能会随着版本的更新而变化,因此在编写针对多个Grafana版本进行测试时,很难使用@grafana/e2e-selectors中定义的选择器。

为了解决这个问题,@grafana/plugin-e2e具有自己的端到端选择器副本。这些选择器是@grafana/e2e-selectors中定义的选择器的一个子集,每个选择器值都定义了一个最小Grafana版本。当你启动一个新的端到端测试会话时,@grafana/plugin-e2e会检查正在测试的Grafana版本,并解析与运行版本关联的选择器。这些选择器通过selectors fixture提供。

import { test, expect } from '@grafana/plugin-e2e';

test('annotation query should be OK when query is valid', async ({ annotationEditPage, page, selectors }) => {
await annotationEditPage.datasource.set('E2E Test Data Source');
await annotationEditPage.getByGrafanaSelector(selectors.components.CodeEditor.container).fill('SELECT * FROM users');
await expect(annotationEditPage.runQuery()).toBeOK();
});

与插件代码中定义的UI元素交互

如上所述,你应该始终在使用与端到端选择器关联的UI元素时使用getByGrafanaSelector方法。然而,许多Grafana UI元素都没有端到端选择器。如果是这种情况,我们建议在编写UI和编写测试时遵循Grafana的测试最佳实践考虑可访问性的测试指南

作用域定位器

为了使你的测试更加健壮,最好将定位器作用域限制到你的插件上下文中。以下示例可能可行,但它很脆弱,因为如果页面上其他位置添加了具有文本URL的另一个元素,它将不再工作。

page.getByText('URL').click();

有很多方法可以作用域选择器。你可以将组件包裹在一个具有data-testid的div中,并使用ID来访问元素。

page.getByTestId('plugin-url-wrapper').getByText('URL').click();

如果你正在测试数据源查询编辑器,你可以将定位器作用域限制到查询编辑器行。

explorePage.getQueryEditorRow('A').getByLabel('Query').fill('sum(*)');

表单元素示例

以下是一些示例,演示了如何与插件中常见的几个UI组件进行交互。可以互换使用InlineFieldField组件。

输入字段

你可以使用InlineField组件来与UI交互。

UI组件
<InlineField label="Auth key">
<Input value={value} onChange={handleOnChange} id="config-auth-key" />
</InlineField>
Playwright测试
await page.getByRole('textbox', { name: 'Auth key' }).fill('..');

选择字段

与许多其他需要传递id属性以将标签与表单元素关联的组件不同,select组件需要传递inputId属性。有关测试select组件的更多信息,请参阅此处

UI组件
<InlineField label="Auth type">
<Select inputId="config-auth-type" value={value} options={options} onChange={handleOnChange} />
</InlineField>
Playwright测试
test('testing select component', async ({ page, selectors }) => {
const configPage = await createDataSourceConfigPage({ type: 'test-datasource' });
await page.getByRole('combobox', { name: 'Auth type' }).click();
const option = selectors.components.Select.option;
await expect(configPage.getByGrafanaSelector(option)).toHaveText(['val1', 'val2']);
});

复选框字段

你可以使用Checkbox组件来与UI交互。

UI组件
<InlineField label="TLS Enabled">
<Checkbox id="config-tls-enabled" value={value} onChange={handleOnChange} />
</InlineField>

Checkbox组件中,输入元素不可点击,因此你需要通过设置force: true来绕过Playwright的可操作性检查。

Playwright测试
await page.getByRole('checkbox', { name: 'TLS Enabled' }).uncheck({ force: true });
await expect(page.getByRole('checkbox', { name: 'TLS Enabled' })).not.toBeChecked();

内联开关字段

你可以使用InlineSwitch组件来与UI交互。

UI组件
<InlineField label="TLS Enabled">
<InlineSwitch
// the InlineSwitch label needs to match the label of the InlineField
label="TLS Enabled"
value={value}
onChange={handleOnChange}
/>
</InlineField>

Checkbox组件类似,你需要通过设置force: true来绕过Playwright的可操作性检查。

Playwright测试
let switchLocator = page.getByLabel('TLS Enabled');
await switchLocator.uncheck({ force: true });
await expect(switchLocator).not.toBeChecked();
注意

在 Grafana 版本低于 9.3.0 的情况下,标签无法与 InlineSwitch 组件中的复选框关联。如果您想要在低于 9.3.0 版本的 Grafana 上运行测试,您需要以下方式访问字段

Playwright测试
const label = 'Inline field with switch';
let switchLocator = page.getByLabel(label);
if (semver.lt(grafanaVersion, '9.3.0')) {
switchLocator = page.locator(`[label="${label}"]`).locator('../label');
}