ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Prowler UI 邀请管理 E2E 测试深度指南:INVITATION-E2E 套件实战解析

Prowler UI 邀请管理 E2E 测试深度指南:INVITATION-E2E 套件实战解析 Prowler UI 邀请管理 E2E 测试深度指南INVITATION-E2E 套件实战解析【免费下载链接】prowlerProwler is the world’s most widely used open-source cloud security platform that automates security and compliance across any cloud environment.项目地址: https://gitcode.com/GitHub_Trending/pr/prowler导读本文以 Prowler 前端仓库中的端到端测试文档 ui/tests/invitations/invitations.md 为骨架深入拆解「用户邀请User Invitations」功能的 E2E 测试设计与实现。你将看到该套件如何覆盖从管理员发送邀请、被邀请人通过邀请链接完成注册、登录再到验证组织归属的完整闭环并对照 invitations.spec.ts、invitations-page.ts 等真实源码理解 Page Object 模式、认证状态隔离与测试数据唯一化等工程实践。读完本文你可以直接照搬这套方法论为自己的应用编写同等级别的用户邀请 E2E 测试。一、套件概览INVITATION-E2E 是什么INVITATION-E2E是 Prowler UI基于 Next.js Playwright中专门覆盖用户邀请User Invitations功能的端到端测试套件其元信息定义如下Suite IDINVITATION-E2EFeatureUser Invitations测试用例INVITATION-E2E-001- Invite New User and Complete Sign-Up邀请新用户并完成注册优先级critical该用例的核心目标Description/Objective是验证一条完整的业务链路管理员会话发起邀请 → 被邀请人消费邀请链接 → 以被邀请人身份完成注册 → 认证登录 → 校验该用户被正确关联到预期组织。从源码结构看这个套件由三个文件组成位于 ui/tests/invitations/文件职责invitations.md测试用例的规格化文档行为契约invitations.spec.tsPlaywright 测试实现可执行验证invitations-page.tsInvitationsPage 页面对象UI 交互封装这种「文档 测试 页面对象」三件套的组织方式保证了行为契约、可执行代码与 UI 定位器三者可互相追溯。二、测试前置条件与运行环境在运行INVITATION-E2E-001之前必须满足以下前置条件对应原文档 Preconditions 节管理员认证状态文件可用playwright/.auth/admin_user.json该文件由admin.auth.setup项目生成见 ui/tests/setups/admin.auth.setup.ts。测试通过test.use({ storageState: playwright/.auth/admin_user.json })注入管理员登录态见 invitations.spec.ts。环境变量已配置E2E_NEW_USER_PASSWORD被邀请用户的密码E2E_ORGANIZATION_ID用于组织归属校验的预期组织 ID。应用已启动且 UI/API 端点可访问Playwright 配置中默认以http://localhost:3000作为baseURL可通过AUTH_URL覆盖并在 CI 模式下由webServer自动拉起pnpm run start本地开发为pnpm run dev详见 ui/playwright.config.ts。注意E2E_NEW_USER_PASSWORD与E2E_ORGANIZATION_ID必须在执行前显式设置否则测试实现会在运行时直接抛出异常。参见 invitations.spec.ts。此外测试实现中还读取了E2E_ADMIN_USER/E2E_ADMIN_PASSWORD默认e2eprowler.com/Thisisapassword123可被环境变量覆盖它们用于admin.auth.setup阶段完成管理员登录相关默认值可在 ui/playwright.config.ts 中确认。三、INVITATION-E2E-001 完整流程拆解原文档将该用例标注为critical并给出了 12 步流程。下面逐条展开并标注每一步在源码中的对应实现。3.1 流程步骤一览步骤操作源码对应1导航到邀请列表页invitationsPage.goto()→/invitations2点击 Send Invitation 按钮clickInviteButton()链接跳转/invitations/new3填写唯一邮箱地址fillEmail(uniqueEmail)4选择角色e2e_adminselectRole(admin)见下方说明5点击 Send Invitation 生成邀请clickSendInviteButton()6从邀请详情读取分享 URLgetShareUrl()7打开无 Cookie 的全新浏览器上下文访问分享 URLbrowser.newContext({ storageState: { cookies: [], origins: [] } })8使用给定密码完成注册并同意条款signUpPage.signup({...})9验证注册无错误并跳转登录页verifyNoErrors()verifyRedirectToLogin()10在新上下文中使用新账号登录signInPage.login({...})11验证登录成功verifySuccessfulLogin()12进入个人资料页校验organizationIduserProfilePage.verifyOrganizationId(organizationId)3.2 关于角色选择的两点说明原文档第 4 步写明选择角色e2e_admin并强调「该角色必须在环境中存在」。而当前仓库的测试实现 invitations.spec.ts 传入的是admin。需要说明的是Page Object 的selectRole方法实际使用正则匹配角色下拉选项new RegExp(role, i)见 invitations-page.ts因此该方法可以匹配任意以传入字符串为子串的角色名——具体应传哪个角色以测试环境的真实角色数据为准。角色数据来源于服务端getRoles接口参见发送邀请页 ui/app/(prowler)/invitations/(send-invite)/new/page.tsx/invitations/(send-invite)/new/page.tsx) 中的SSRSendInvitation组件无角色时回退默认角色admin并禁用选择器。3.3 预期结果与关键验证点原文档明确给出如下预期结果邀请创建成功并提供有效的分享 URL被邀请用户可凭借邀请链接成功注册注册完成后跳转到登录页OSS 流程使用新凭据登录成功用户资料页显示其属于预期的组织。对应到测试实现中的关键验证点Key verification points邀请列表页加载并显示标题verifyPageLoaded断言heading Invitations可见发送邀请表单可见邮箱输入框 角色选择器verifyInvitePageLoaded邀请详情页显示分享 URLverifyInviteDataPageLoaded断言 Review Invitation Details 按钮可见邀请链接可打开注册页且提交无错误注册后跳转登录页toHaveURL(/\/sign-in/)新账号登录成功登录后首页加载成功verifySuccessfulLogin内部委托 HomePage 断言资料页显示预期组织 IDpage.getByText(organizationId)可见。四、源码视角Page Object 与测试实现精读4.1 InvitationsPage 页面对象ui/tests/invitations/invitations-page.ts 基于 ui/tests/base-page.ts 中的BasePage抽象类扩展而来。BasePage提供了通用能力统一goto导航、标题/加载态断言、表单填充、错误收集getFormErrors/verifyNoErrors、元素等待与截图方法等。InvitationsPage的核心定位器设计非常值得借鉴// 页面标题 this.pageHeadingInvitations page.getByRole(heading, { name: Invitations }); this.pageHeadingSendInvitation page.getByRole(heading, { name: Send Invitation }); // 邀请入口链接与提交按钮按钮区分对待 this.inviteButton page.getByRole(link, { name: Send Invitation, exact: true }); this.sendInviteButton page.getByRole(button, { name: Send Invitation, exact: true }); // 表单元素 this.emailInput page.getByRole(textbox, { name: Email }); // Radix Select 渲染为 button rolecombobox带 aria-label this.roleSelect page.getByRole(combobox, { name: /Select a role/i }); // 分享 URL 的多策略兜底定位 this.shareUrl page .locator( a[href*/sign-up?invitation_token], [data-testidshare-url], .share-url, code, pre, ) .first();几个工程要点同名元素按语义link / button分开定位页面上同时存在跳转链接和提交按钮二者名称相同但语义不同用getByRole(link)与getByRole(button)精确区分避免误点。尊重第三方组件渲染方式角色选择器由 Radix Select 渲染为rolecombobox的按钮因此用getByRole(combobox)定位且selectRole在点击后还会断言选择器不再显示占位文本Select a role确保选中生效invitations-page.ts。分享 URL 的多策略兜底同时匹配带invitation_token查询参数的锚点、data-testidshare-url、.share-url类名、code/pre元素增强对 UI 改版的鲁棒性invitations-page.ts。4.2 测试实现精读ui/tests/invitations/invitations.spec.ts 中实际包含两个测试测试一「should send an invitation successfully」tagINVITATION-E2E-001生成唯一邮箱e2e${suffix}prowler.com其中suffix makeSuffix(10)完成「进入列表页 → 进入发送页 → 填邮箱 → 选角色 → 提交 → 详情页出现」的链路验证邀请创建成功。测试二「should invite a new user and verify signup and login」tagINVITATION-E2E-002开头执行test.skip(!isCloudEnv, Requires email-verification flow (Cloud only))即完整注册登录闭环依赖 Cloud 环境的邮箱验证流程仅在isCloud()为真时运行invitations.spec.ts从环境变量读取密码与组织 ID缺失即抛错使用browser.newContext()创建无任何 Cookie 的全新上下文承载被邀请人会话从根本上杜绝管理员 Cookie 泄漏到被邀请人一侧invitations.spec.ts依次调用SignUpPage.signup、verifyNoErrors、verifyRedirectToLogin、SignInPage.login、verifySuccessfulLogin、UserProfilePage.verifyOrganizationId最后inviteContext.close()清理上下文。其中makeSuffix来自 ui/tests/helpers.ts通过Math.random().toString(36)生成指定长度的 base36 随机后缀用于保证每轮测试的邮箱唯一避免历史数据冲突——这正是原文档 Notes 中「Email should be unique per run」的实现方式。4.3 会话隔离的两种技巧认证状态复用test.use({ storageState })让同一套件所有用例共享管理员登录态文件避免每个用例重复登录拖慢执行被邀请人全新上下文对注册/登录环节创建storageState: { cookies: [], origins: [] }的全新 context确保中间件middleware以未认证状态重新执行模拟真实陌生访客访问邀请链接的场景BasePage.gotoFresh中注释明确说明「clearing cookies to ensure middleware runs fresh」见 ui/tests/base-page.ts。五、应用侧邀请功能的真实实现呼应E2E 测试验证的并不是空壳页面而是真实的业务实现。邀请功能在前端的对应实现如下邀请列表页ui/app/(prowler)/invitations/page.tsx/invitations/page.tsx)服务端组件通过getInvitations拉取邀请列表、getRoles拉取角色支持page/sort/pageSize/filter[search]等服务端过滤参数渲染DataTable表格右上角「Send Invitation」按钮即测试步骤 2 点击的入口Link href/invitations/new。发送邀请页ui/app/(prowler)/invitations/(send-invite)/new/page.tsx/invitations/(send-invite)/new/page.tsx)同样为服务端组件SSR 阶段获取角色列表并注入SendInvitationForm无角色可用时回退默认角色admin并禁用选择器——这也解释了测试中角色下拉框的来源。邀请接受流程位于 ui/app/(auth)/invitation//invitation/)包含accept页面与邀请错误处理逻辑invitation-errors.ts对应测试步骤 7-9 中「打开分享 URL → 完成注册 → 跳转登录」的服务端路由支撑分享 URL 中携带的invitation_token查询参数与invitations-page.ts中a[href*/sign-up?invitation_token]的定位器完全对应。从这些实现可以推断邀请数据与角色数据均来自后端 APIUI_API_BASE_URL默认指向http://localhost:8080/api/v1见 ui/playwright.config.ts前端 E2E 测试链路是「UI 操作 真实 API 调用」的全栈验证而非 mock 桩测试。六、如何运行该套件6.1 Playwright 项目配置ui/playwright.config.ts 中为邀请套件定义了独立 project{ name: invitations, testMatch: invitations.spec.ts, dependencies: [admin.auth.setup], }这意味着运行invitations项目时Playwright 会先自动执行admin.auth.setup生成管理员认证状态再运行邀请测试。配置中的关键全局参数fullyParallel: true、CI 下retries: 2且workers: 1、expect.timeout: 20000。6.2 运行命令# 1. 先准备环境变量 export E2E_ADMIN_USERe2eprowler.com export E2E_ADMIN_PASSWORDYourAdminPassword export E2E_NEW_USER_PASSWORDPasswordForInvitedUser export E2E_ORGANIZATION_IDyour-org-id # 2. 启动应用本地开发模式由 webServer 自动拉起 pnpm run dev # 3. 仅运行邀请套件 pnpm exec playwright test --projectinvitations # 4. 指定运行单个用例按标签过滤 pnpm exec playwright test --projectinvitations --grep INVITATION-E2E-001说明E2E_ADMIN_USER/E2E_ADMIN_PASSWORD在admin.auth.setup阶段使用见 ui/tests/setups/admin.auth.setup.ts本地未设置时回退到配置中的默认值。完整注册登录闭环用例INVITATION-E2E-002仅在 Cloud 环境isCloud()为真下运行。七、设计模式与最佳实践小结从INVITATION-E2E套件中可以提炼出以下可复用的 E2E 测试设计经验文档先行用例编号化每个用例有稳定 IDINVITATION-E2E-001、优先级critical与标签体系e2e、invitations、INVITATION-E2E-001便于 CI 筛选、失败归因与需求追溯。Page Object 分层BasePage通用能力→ 业务 Page Object页面专属定位器与动作→ spec场景编排UI 变更时只改定位层业务断言稳定。认证状态注入与隔离并用管理员走storageState复用被邀请人走全新 context双向保证会话数据互不污染。测试数据唯一化用makeSuffix生成随机后缀构造每次运行都唯一的邮箱规避重复数据导致的幂等性失败。环境差异显式声明通过isCloud()条件跳过与E2E_*环境变量门禁把环境能力差异写进测试逻辑而非隐式假设。多策略定位兜底对分享 URL 这类可能随 UI 改版变化的元素提供属性、class、语义标签多重匹配降低维护成本。这套「规格文档 页面对象 场景化 spec 认证 setup」的工程组合覆盖了邀请功能从发起到落地的完整用户旅程是 Prowler UI 中critical级核心链路 E2E 验证的典型范本可直接迁移到任何具备多租户邀请注册机制的 Web 应用中。【免费下载链接】prowlerProwler is the world’s most widely used open-source cloud security platform that automates security and compliance across any cloud environment.项目地址: https://gitcode.com/GitHub_Trending/pr/prowler创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表