选择 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
属性。
Grafana UI 元素的 Playwright 定位器
由 @grafana/plugin-e2e
定义的所有 页面 都公开了一个 getByGrafanaSelector
方法。 此方法返回一个 Playwright locator,它使用元素上定义的适当 HTML 属性解析为一个或多个元素。 无论何时您想要基于 grafana/e2e-selectors 解析 Playwright 定位器,您都应该始终使用此方法。
panelEditPage.getByGrafanaSelector(selectors.components.CodeEditor.container).click();
选择器 fixture
在 @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 组件进行交互。 InlineField
和 Field
组件可以互换使用。
输入字段
您可以使用 InlineField
组件与 UI 交互。
<InlineField label="Auth key">
<Input value={value} onChange={handleOnChange} id="config-auth-key" />
</InlineField>
await page.getByRole('textbox', { name: 'Auth key' }).fill('..');
选择字段
与许多其他需要您传递 id
属性才能将标签与表单元素关联的组件不同,select
组件需要您传递 inputId
属性。 您可以在此处找到有关测试 select
组件的更多信息。
<InlineField label="Auth type">
<Select inputId="config-auth-type" value={value} options={options} onChange={handleOnChange} />
</InlineField>
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 交互。
<InlineField label="TLS Enabled">
<Checkbox id="config-tls-enabled" value={value} onChange={handleOnChange} />
</InlineField>
在 Checkbox
组件中,输入元素不可点击,因此您需要通过设置 force: true
来绕过 Playwright 的可操作性检查。
await page.getByRole('checkbox', { name: 'TLS Enabled' }).uncheck({ force: true });
await expect(page.getByRole('checkbox', { name: 'TLS Enabled' })).not.toBeChecked();
InlineSwitch 字段
您可以使用 InlineSwitch
组件与 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 的可操作性检查。
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 版本中运行,您需要通过以下方式访问该字段
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');
}