ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

AdminJS 的 Cypress 测试辅助模块(adminjs/cy)使用指南:为 Node.js 管理后台编写端到端测试

AdminJS 的 Cypress 测试辅助模块(adminjs/cy)使用指南:为 Node.js 管理后台编写端到端测试 后端低代码【免费下载链接】adminjsAdminJS is an admin panel for apps written in node.js项目地址https://gitcode.com/gh_mirrors/ad/adminjs点击查看免费下载导读AdminJSnode.js 应用的管理后台框架在 cy/cypress.doc.md 中提供了一套专供 Cypress 端到端E2E测试使用的辅助模块adminjs/cy。本文以该文档为主体结合仓库中四个内置命令的实现源码与类型声明完整讲解如何把该模块引入你的 Cypress 项目、如何用abLogin/abLoginAPI/abKeepLoggedIn/abGetProperty快速完成登录、会话保持与表单字段定位从而为 AdminJS 管理后台编写稳定、可复用的 E2E 测试用例。一、adminjs/cy是什么模块定位与当前状态根据 cy/cypress.doc.md 的说明cy是一个收集 Cypress 辅助工具helpers的模块用途是当你像 AdminJS 官方一样用 Cypress 对自己的 AdminJS 管理面板做 E2E 测试时可以直接复用这些现成的命令。它本身不依赖具体的数据库适配器或业务代码只关注管理后台的通用交互模式登录、会话 Cookie 维持、表单属性定位。需要特别说明的是文档明确标注了该模块的成熟度Cypress helpers project is currently in the WIP/POC phase, that is why there are not much helpers here. But you can expect that gradually we will add more.即该项目当前仍处于WIP进行中/ POC概念验证阶段目前内置命令数量不多但会逐步扩充。因此在实际项目中使用时建议把它当作可扩展的测试基座而非完备的测试框架——你仍然需要根据自己的资源模型编写大量业务断言。从仓库目录结构看模块的入口在 cy/index.js它通过四行 import 一次性注册了全部四个命令import ./commands/ab-login.js import ./commands/ab-login-api.js import ./commands/ab-keep-logged-in.js import ./commands/ab-get-property.js而 cy/index.d.ts 则提供了对应的 TypeScript 类型声明供 Cypress 项目获得完整的智能提示。二、引入模块在 Cypress 的 support 文件中注册命令Cypress 的自定义命令必须在测试运行前完成注册官方推荐的挂载点是cypress/support目录下的入口文件。文档给出的引入方式如下你可以在以下任意一个文件中写入/support/index.js/support/commands.jsrequire(adminjs/cy)引入之后四个辅助命令abLogin、abLoginAPI、abKeepLoggedIn、abGetProperty就会注册为 Cypress 链式命令可以在describe / context / it中直接以cy.abLogin(...)的形式调用。对于 TypeScript 项目为了让编辑器与 Cypress 的类型检查识别这些命令还需要在测试文件顶部添加类型引用/// reference typescypress / /// reference typesadminjs/cy /其中adminjs/cy的类型声明来自 cy/index.d.ts它通过declare namespace Cypress扩展了Chainable接口使cy.abLogin等调用具备参数类型校验。仓库中该文件的完整声明如下declare namespace Cypress { type AbLoginParams { email?: string; password?: string; loginPath?: string; } type AbKeepLoggedInParams { cookie?: string; } interface ChainableSubject { abLogin(params?: AbLoginParams): Chainableany; abLoginAPI(params?: AbLoginParams): Chainableany; abGetProperty(propertyPath: string, selector?: string): Chainableany; abKeepLoggedIn(params?: AbKeepLoggedInParams): Chainableany; } }可以看到四个命令的签名前两个接收AbLoginParams可选 email / password / loginPathabGetProperty接收属性路径与可选的内层选择器abKeepLoggedIn接收会话 Cookie 名称。三、标准测试骨架登录 会话保持 页面访问文档给出了一个完整的测试用例骨架覆盖登录 API 会话保持 访问目标页面的典型流程原样继承如下/// reference typescypress / /// reference typesadminjs/cy / context(resources/Company/actions/new, () { before(() { cy.abLoginAPI({ password: Cypress.env(ADMIN_PASSWORD), email: Cypress.env(ADMIN_EMAIL) }) }) beforeEach(() { cy.abKeepLoggedIn({ cookie: Cypress.env(COOKIE_NAME) }) cy.visit(resources/Company/actions/new) }) //... })这个骨架体现了 AdminJS E2E 测试的两个关键约定登录只需一次before阶段通过abLoginAPI直接发 HTTP 请求完成认证避免每个用例都走一次页面渲染会话在用例间保持beforeEach阶段通过abKeepLoggedIn保留会话 Cookie然后才访问目标路由如resources/Company/actions/new对应 AdminJS 的资源新增页。把环境变量如ADMIN_PASSWORD、ADMIN_EMAIL、COOKIE_NAME从代码中抽离、放进Cypress.env()是为了避免在测试源码里硬编码凭据这也是官方示例的推荐做法。四、内置命令详解4.1cy.abLogin(options)页面表单登录实现位于 cy/commands/ab-login.js。它的行为是访问登录页 → 依次填充[nameemail]与[namepassword]两个输入框 → 点击按钮提交。Cypress.Commands.add(abLogin, ({ email, password, loginPath } {}) { cy.visit(loginPath || /login) cy.get([nameemail]).type(email || Cypress.env(AB_EMAIL)) cy.get([namepassword]).type(password || Cypress.env(AB_PASSWORD)) cy.get(button).click() })参数及默认值如下参数说明默认值email登录邮箱Cypress.env(AB_EMAIL)password登录密码Cypress.env(AB_PASSWORD)loginPath登录页路由/login注意两个细节默认登录路径是/loginAdminJS 默认的登录路由选择器直接采用 AdminJS 登录表单中固定的nameemail/namepassword属性。该方法会真实渲染登录页面属于UI 驱动的登录方式适合需要验证登录页本身的用例例如对登录表单做回归测试。4.2cy.abLoginAPI(options)API 直连登录推荐实现位于 cy/commands/ab-login-api.js。文档明确对比了两者的差异与abLogin不同abLoginAPI不会渲染页面而是直接通过cy.request向登录接口发 POST 请求以设置会话 Cookie 的方式完成登录。Cypress.Commands.add(abLoginAPI, ({ email, password, loginPath } {}) ( cy.request(POST, loginPath || /login, { email: email || Cypress.env(AB_EMAIL), password: password || Cypress.env(AB_PASSWORD), }) ))参数与abLogin完全一致默认AB_EMAIL/AB_PASSWORD//login但请求体以 JSON 形式携带email与password。由于跳过了页面渲染它明显更快适合绝大多数先登录、再测业务页面的场景——文档给出的测试骨架正是用它配合abKeepLoggedIn使用。使用提示调用后需要在后续用例中配合cy.abKeepLoggedIn保留会话 Cookie否则每个it()之间的 Cookie 会被 Cypress 默认清空导致未登录。4.3cy.abKeepLoggedIn(options)跨用例保持会话实现位于 cy/commands/ab-keep-logged-in.js其核心只有一行Cypress.Commands.add(abKeepLoggedIn, ({ cookie }) { Cypress.Cookies.preserveOnce(cookie || Cypress.env(AB_COOKIE_NAME)) })它调用 Cypress 内置的Cypress.Cookies.preserveOnce把指定名称的会话 Cookie 在多个测试用例之间保留。参数cookie用于指定会话 Cookie 名默认取Cypress.env(AB_COOKIE_NAME)。文档在注释中还给出了它在beforeAll场景下的用法示例before(() { cy.abLogin() }) beforeAll(() { cy.abKeepLoggedIn({ cookie: my-session-cookie }) cy.visit(your/path) })这也解释了为什么 AdminJS 官方示例要同时使用abLoginAPIabKeepLoggedIn前者负责建立会话后者负责维持会话二者缺一不可。4.4cy.abGetProperty(propertyPath, selector?)按属性定位表单字段实现位于 cy/commands/ab-get-property.js用于定位 AdminJS 表单中某个属性对应的 DOM 节点Cypress.Commands.add(abGetProperty, (path, selector null) { let propertySelector [data-testid$-${path}] if (selector) { propertySelector [propertySelector, selector].join( ) } return cy.get(propertySelector) })它的核心机制是利用AdminJS 渲染表单时生成的data-testid属性做属性级定位基础选择器为[data-testid$-${path}]其中$表示以……结尾的属性匹配path即属性路径支持点分路径如嵌套属性第二个可选参数selector用于在该属性的包裹容器内继续选择具体元素例如input[typecheckbox]、label、option等最终组合成类似[data-testid$-isAdmin] input[typecheckbox]的选择器。文档给出的典型用法——针对一个名为isAdmin的属性在资源配置中形如properties: { isAdmin: {...} }断言其禁用与勾选状态cy.abGetProperty(isAdmin, input[typecheckbox]) .should(be.disabled) .should(not.be.checked) cy.abGetProperty(isAdmin, label) .click() .should(not.be.checked)值得说明的是data-testid的生成逻辑在前端组件中确有对应实现。例如 base-property-component.tsx 中通过data-testid{testId}输出属性级测试标记array/edit.tsx 中数组属性还额外输出了data-testid{property.path}、data-testiddelete-item与data-testid{${property.path}-add}等细粒度标记。因此abGetProperty不仅能定位普通属性也能配合数组、嵌套等复杂属性的编辑控件使用——这也与 cy/readme.md 中针对Complicated复杂资源表单的手工测试用例MRF-1所覆盖的场景相互印证。五、把环境变量集中到 Cypress 配置四个命令默认值均从Cypress.env()读取因此推荐在 Cypress 配置cypress.json/cypress.config.ts或系统环境变量中统一提供环境变量用途AB_EMAIL默认登录邮箱abLogin/abLoginAPIAB_PASSWORD默认登录密码abLogin/abLoginAPIAB_COOKIE_NAME默认会话 Cookie 名abKeepLoggedIn例如在cypress.config.ts的env字段中声明export default defineConfig({ e2e: { env: { AB_EMAIL: adminexample.com, AB_PASSWORD: change-me, AB_COOKIE_NAME: adminjs, }, }, })当然你完全可以在调用处显式传参覆盖默认值就像文档示例中那样使用Cypress.env(ADMIN_PASSWORD)、Cypress.env(ADMIN_EMAIL)、Cypress.env(COOKIE_NAME)——这些自定义变量名并不绑定模块内部逻辑只是把凭据收拢到测试配置的一种方式。六、扩展方向把手工用例逐步自动化与 cy/cypress.doc.md 同目录的 cy/readme.md 记录了三套与 AdminJS 功能强相关的手工测试用例文档LPF-1 登录页表单验证有效凭据登录成功并跳转到/admin页面——可直接用abLogin自动化MRF-1 Mongoose 复杂资源新增覆盖String Array / Authors / Parents / Item等数组与嵌套属性的增删改涉及Add New Item按钮与 bin 图标交互——正是abGetProperty 数组属性data-testid的用武之地SRF-1 Sequelize 资源过滤覆盖Name、Id、User Id下拉、Published At日期范围、Description关键字等过滤交互以及Apply changes/Reset按钮行为——可围绕 filter.ts 对应的过滤参数体系设计断言。这些用例虽未标注 Cypress 自动化实现但可以看作待自动化的测试资产清单结合本文介绍的四个命令你已经具备把它们落地为 Cypress 用例所需的基础设施。七、总结adminjs/cy用四个命令覆盖了 AdminJS 管理后台 E2E 测试最常用的三条路径UI 登录abLogin、API 登录abLoginAPI、会话保持abKeepLoggedIn与属性定位abGetProperty。文档给出的引入方式在 support 文件中require(adminjs/cy)与登录一次、会话贯穿的骨架可以直接套用而abGetProperty与前端data-testid体系参见 base-property-component.tsx、array/edit.tsx的结合让表单断言可以精确到单个属性甚至其内部控件。需要再次强调该模块仍处于 WIP/POC 阶段内置命令有限官方承诺会逐步补充。在正式项目里建议以这四个命令为起点建立自己的测试辅助层并留意该模块的后续版本更新。赞分享后端低代码【免费下载链接】adminjsAdminJS is an admin panel for apps written in node.js项目地址https://gitcode.com/gh_mirrors/ad/adminjs点击查看免费下载相关推荐Etherpad 前端测试指南使用 Cypress 编写与运行端到端测试Etherpad 前端测试指南使用 Cypress 编写与运行端到端测试 本指南基于 Etherpad 仓库中的 src/tests/frontend/cyp后端协同办公WebSocket前端富文本Akka Streams Flow.lazyInitAsync 详解延迟创建内部 Flow 的异步操作符及其迁移方案Akka Streams Flow.lazyInitAsync 详解延迟创建内部 Flow 的异步操作符及其迁移方案 Flow.lazyInitAsync 是后端并发编程异步编程Mole终极指南Brew安装与脚本安装的深度技术对比Mole终极指南Brew安装与脚本安装的深度技术对比 在macOS系统优化和磁盘清理领域Mole作为一款终端驱动的专业工具为开发者和技术决策者提供了高效的CLI开发工具运维观测上一篇用 Falco 规则检测容器逃逸Anthropic-Cybersecurity-Skills 实战工作流指南下一篇抢票总手慢这套大麦自动抢票工具帮你盯开售、挑价位、自动下单创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表