Langflow E2E 测试选择器目录:data-testid 命名规范与实战用法
【免费下载链接】langflowLangflow is a powerful tool for building and deploying AI-powered agents and workflows.项目地址: https://gitcode.com/GitHub_Trending/la/langflow
本文围绕 Langflow 的 E2E 选择器参考文档 selectors.md 展开,完整讲解其中定义的data-testid命名规范、分类选择器目录(画布、组件字段、动作按钮、模态框、图标、检视面板开关)以及添加新data-testid的判定标准,并结合仓库中的真实组件源码与 Playwright 测试体系,说明这些选择器在前端代码中如何落地、在测试中如何被稳定地消费。读完后,你能够为 Langflow 前端新元素规范地添加测试锚点,并能直接使用目录中的选择器编写可运行的 Playwright E2E 测试。
选择器目录在 Langflow E2E 体系中的定位
selectors.md 被明确定义为 Langflow E2E 测试中data-testid选择器的权威参考(canonical reference):任何新增的交互式元素都应当遵循其中的命名约定,并把元素登记进这个目录。它位于 e2e-testing 技能目录 的references/子目录下,与 helpers.md、fixtures.md 共同构成 E2E 技能的参考文档集。
从测试体系看,这个目录服务于一套基于 Playwright 的完整基础设施:
| 组成部分 | 位置 | 作用 |
|---|---|---|
| 测试配置 | playwright.config.ts | fullyParallel: true、5 分钟超时、2 个 worker、20s 操作超时、首次重试时抓取 trace |
| 自定义 fixtures | fixtures.ts | 自动拦截/api/响应,检测 HTTP 400/404/422/500 与流式事件中的执行错误 |
| 共享工具函数 | tests/utils/ | awaitBootstrapTest、initialGPTsetup、enableInspectPanel等 37+ 个 helper |
| 测试分层 | tests/core/(features、integrations、regression、unit)与tests/extended/ | 核心功能、模板集成、回归与扩展特性 |
选择器目录的价值在于:它把「组件侧定义的锚点」与「测试侧消费的定位器」用一份单一事实来源(single source of truth)绑定起来——测试作者不需要阅读组件源码就能定位元素,组件作者改动锚点前也知道哪些测试依赖它。
命名规范:前缀指示元素类型
文档规定所有data-testid值采用 kebab-case,并以表示元素类型的前缀开头:
| 前缀 | 元素类型 | 示例 |
|---|---|---|
input- | 文本输入框 | input-chat-playground、input-flow-name |
button-/button_ | 动作按钮 | button-send、button_run_chat output |
icon- | 图标按钮 | icon-Globe、icon-Lock、icon-ChevronLeft |
popover-anchor-input- | 组件参数字段 | popover-anchor-input-openai_api_key |
add-component-button- | 拖拽添加按钮 | add-component-button-chat-output |
card- | 流程/组件卡片 | card-my-flow-name |
title- | 画布上的节点标题 | title-OpenAI、title-Chat Output |
handle- | 连接句柄 | handle-{component}-{shownode}-{field}-{direction} |
div-chat-message | 聊天消息 | div-chat-message |
show | 字段可见性开关 | showmodel_name、showtemperature |
值得注意的是,前缀与元素类型一一对应,这本身就是可检索性的设计:仅凭 testid 前缀,测试作者即可判断该锚点指向输入框、按钮还是画布句柄,而无需打开组件实现。个别前缀(如button_run_下划线、show无前分隔符)是历史沿革,目录将它们如实登记,测试代码必须按原文匹配。
分类选择器目录
画布与导航
| 选择器 | 元素 | 说明 |
|---|---|---|
blank-flow | "New Blank Flow" 按钮 | 位于创建项目模态框 |
sidebar-search-input | 组件搜索输入框 | 侧边栏搜索栏 |
sidebar-nav-add_note | 便签按钮 | 侧边栏导航 |
sidebar-add-sticky-note-button | 添加便签(新版) | 按钮已更新命名 |
react-flow-id | ReactFlow 画布容器 | 用作拖拽目标 |
canvas_controls_dropdown | 画布控制下拉菜单 | 打开缩放/适配/检视菜单 |
fit_view | 适配视图按钮 | 画布控制菜单内 |
zoom_out | 缩小按钮 | 画布控制菜单内 |
zoom_in | 放大按钮 | 画布控制菜单内 |
inspector-toggle | 检视面板开关 | 画布控制下拉菜单内 |
其中react-flow-id与canvas_controls_dropdown可以直接在源码中确认:前者是 Flow 页面中 ReactFlow 的宿主容器,见 PageComponent/index.tsx(<div id="react-flow-id" ...>);后者位于画布控制组件 CanvasControlsDropdown.tsx。这也提示了一个细节:react-flow-id严格来说是id而非data-testid,测试中既可getByTestId也可用#react-flow-id定位。
组件参数字段
| 选择器 | 元素 | 说明 |
|---|---|---|
popover-anchor-input-{name} | 组件输入字段 | {name}与字段的name属性一致 |
popover-anchor-input-openai_api_key | OpenAI API key 字段 | 仅当未选择全局变量时可见 |
input_output{component} | 输出连接句柄区域 | 如input_outputChat Output |
这一组选择器包含整个目录中最关键的条件渲染陷阱:当字段配置为load_from_db: true且选择了全局变量时,字段渲染为badge而非<input>,此时popover-anchor-input-{name}选择器在 DOM 中根本不存在。编写针对该字段的断言前,必须先确认字段当前是输入框形态还是 badge 形态,否则测试会因为元素缺失而失败。
动作与按钮
| 选择器 | 元素 | 说明 |
|---|---|---|
button-send | 发送消息按钮 | Playground 聊天 |
button_run_{component} | 运行组件按钮 | 如button_run_chat output |
publish-button | 发布/部署流程 | 顶部工具栏 |
save-flow-button | 保存流程 | 顶部工具栏 |
edit-fields-button | 切换字段编辑器 | 检视面板——须先调用enableInspectPanel() |
playground-btn-flow-io | Playground 按钮 | 关闭时用dispatchEvent("click")而非.click() |
manage-model-providers | 模型提供商按钮 | 设置 |
这里登记了两条非显而易见的操作细节:其一,edit-fields-button在检视面板未启用时不可见,必须先执行enableInspectPanel(page);其二,playground-btn-flow-io的关闭操作需要dispatchEvent("click")才能生效,直接.click()不可靠。这类「选择器 + 正确交互方式」的成对登记,正是选择器目录相比裸 testid 列表更完整的价值所在。
模态框与面板
| 选择器 | 元素 | 说明 |
|---|---|---|
modal-title | 模态框标题 | 通用模态框标题 |
edit-button-modal | 编辑按钮(旧版) | 旧的模态框模式 |
edit-button-close | 关闭编辑模态框 | 旧的模态框模式 |
lock-flow-switch | 流程锁定开关 | 流程设置 |
input-flow-name | 流程名称输入框 | 流程设置模态框 |
input-flow-description | 流程描述输入框 | 流程设置模态框 |
session-selector | 会话选择器 | Playground 会话切换 |
save-flow-button与input-flow-name均能在源码中定位到实际使用处:前者在流程头部菜单 FlowMenu/index.tsx,后者在流程设置编辑组件 editFlowSettingsComponent/index.tsx。
图标(作为按钮)
| 选择器 | 动作 |
|---|---|
icon-Globe | 打开全局变量 |
icon-Lock | 切换流程锁定 |
icon-ChevronLeft | 返回导航 |
icon-Trash2 | 删除动作 |
icon-Plus | 添加/创建动作 |
图标按钮通常没有可访问文本,icon-前缀加图标组件名(如Globe、ChevronLeft与图标库命名一致)为它们提供了稳定锚点。
检视面板字段可见性开关
这类选择器用于切换检视面板中字段的显隐,格式为show{fieldname}(无分隔符):
| 选择器 | 字段 |
|---|---|
showmodel_name | 模型名字段 |
showtemperature | temperature 字段 |
showmax_tokens | max tokens 字段 |
showopenai_api_key | OpenAI API key 字段 |
配合 SKILL 文档中的检视面板操作模式,完整序列为:enableInspectPanel(page)→ 点击节点(如title-OpenAI)→ 点击edit-fields-button→ 点击show{fieldname}切换可见性 → 再次点击edit-fields-button关闭编辑器。跳过第一步会导致edit-fields-button不可见。
何时为新元素添加>// 正确 —— 有描述性、kebab-case <button>import { expect, test } from "../../fixtures"; // 必须从 fixtures 导入,而非 @playwright/test import { awaitBootstrapTest } from "../../utils/await-bootstrap-test"; test( "user should be able to run a flow successfully", { tag: ["@release", "@workspace"] }, // 每个测试必须带 @release 标签 async ({ page }) => { await awaitBootstrapTest(page); // Arrange: 创建空白流程(selectors.md「画布与导航」条目) await page.getByTestId("blank-flow").click(); // Act: 搜索并添加组件(selectors.md「画布与导航」条目) await page.getByTestId("sidebar-search-input").fill("Chat Output"); // ... 组装流程 ... // Assert: 验证构建结果 await expect(page.getByTestId("build-status-success")).toBeVisible({ timeout: 30000 }); }, );
几个与选择器使用强相关的约束:
- 导入来源:
test与expect必须从 fixtures.ts 导入。该自定义 fixture 会自动监视所有/api/响应,遇到 HTTP 400/404/422/500、事件流中error: true或 Python 异常即令测试失败;测试预期内出错时可调用page.allowFlowErrors()放行。 - 标签体系:每个测试必须带
@release(release 运行按此 grep),可叠加@workspace、@api、@database、@components、@starter-projects等领域标签,这六个是唯一允许的值。 - 异步等待:涉及画布构建、流程执行的断言要显式设置超时(如
timeout: 30000),避免依赖固定 sleep。
维护该目录的实践要点
综合 selectors.md 的正文与配套文档,维护选择器目录时值得遵循的实践:
- 改动
data-testid前先查目录:SKILL 文档明确将「修改组件中的data-testid属性」列为 E2E 技能的触发条件,因为锚点改名会静默破坏既有测试; - 动态渲染元素优先登记:画布节点(
title-、handle-)、组件字段(popover-anchor-input-)都是运行时生成的 DOM,缺少稳定锚点就无法可靠定位; - 条件渲染必须在「Notes」列说明:如
popover-anchor-input-openai_api_key标注「仅当未选择全局变量时可见」,badge 形态的存在与否直接影响选择器可用性; - 交互怪癖随选择器登记:
playground-btn-flow-io需要dispatchEvent("click")、edit-fields-button依赖前置的enableInspectPanel(),这些行为细节写在目录里可避免每个测试作者重复踩坑。
小结
selectors.md 的价值不只是一张 testid 清单:它通过「前缀—元素类型」的命名规范让锚点自解释,通过分类目录(画布导航、组件字段、动作按钮、模态框、图标、检视开关)覆盖 Langflow 前端的全部关键交互面,并用 Notes 列沉淀了 badge 条件渲染、事件派发方式、前置依赖等易错细节。配合 playwright.config.ts 的并行/重试配置、fixtures.ts 的 API 错误自动拦截,以及tests/utils/中的共享 helper,它构成了 Langflow 前端 E2E 测试稳定性的基础契约。为新元素添加data-testid时,只需回答三个问题——测试是否要交互、是否有 role/text 替代、是否动态渲染——再按 kebab-case 的{type}-{descriptive-name}格式命名并登记目录,即可延续这套契约。
【免费下载链接】langflowLangflow is a powerful tool for building and deploying AI-powered agents and workflows.项目地址: https://gitcode.com/GitHub_Trending/la/langflow
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考