genpage
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePower Apps Generative Pages Builder
Power Apps生成式页面构建器
Triggers: genpage, generative page, create genpage, genux page, build genux, power apps page, model page
Keywords: power apps, generative pages, genux, model-driven, dataverse, react, fluent ui, pac cli
Aliases: /genpage, /gen-page, /genux
触发词: genpage, generative page, create genpage, genux page, build genux, power apps page, model page
关键词: power apps, generative pages, genux, model-driven, dataverse, react, fluent ui, pac cli
别名: /genpage, /gen-page, /genux
References
参考资料
- Code generation rules: genpage-rules-reference.md
- Troubleshooting: troubleshooting.md
- Sample pages: samples/
- 代码生成规则:genpage-rules-reference.md
- 故障排除:troubleshooting.md
- 示例页面:samples/
Development Standards
开发标准
- React 17 + TypeScript — all generated code
- Fluent UI V9 — exclusively (DatePicker from
@fluentui/react-components, TimePicker from@fluentui/react-datepicker-compat)@fluentui/react-timepicker-compat - Single file architecture — all components, utilities, styles in one file
.tsx - No external libraries — only React, Fluent UI V9, approved Fluent icons, D3.js for charts
- Type-safe DataAPI — use RuntimeTypes when Dataverse entities are involved
- Responsive design — flexbox, relative units, never /
100vh100vw - Accessibility — WCAG AA, ARIA labels, keyboard navigation, semantic HTML
- Complete code — no placeholders, TODOs, or ellipses in final output
- React 17 + TypeScript — 所有生成代码均采用此技术栈
- Fluent UI V9 — 仅使用(日期选择器来自
@fluentui/react-components,时间选择器来自@fluentui/react-datepicker-compat)@fluentui/react-timepicker-compat - 单文件架构 — 所有组件、工具函数、样式均放在一个文件中
.tsx - 无外部依赖库 — 仅使用React、Fluent UI V9、官方认可的Fluent图标、用于图表的D3.js
- 类型安全的DataAPI — 涉及Dataverse实体时使用RuntimeTypes
- 响应式设计 — 使用flexbox、相对单位,禁止使用/
100vh100vw - 可访问性 — 符合WCAG AA标准,包含ARIA标签、键盘导航、语义化HTML
- 完整代码 — 最终输出中无占位符、TODO或省略号
Instructions
操作步骤
Follow these steps in order for every invocation.
/genpage每次调用时,请按以下顺序执行步骤。
/genpageStep 1: Validate Prerequisites
步骤1:验证前置条件
Run these checks (first invocation per session only). Run each command separately — do not chain with :
&&powershell
node --versionpowershell
pac helppac helpdotnet tool update --global Microsoft.PowerApps.CLI.ToolIf either command fails, inform the user and provide installation instructions. Do NOT proceed until prerequisites are met. See troubleshooting.md if issues arise.
执行以下检查(每个会话仅首次调用时执行)。请单独运行每个命令——不要用串联:
&&powershell
node --versionpowershell
pac helppac helpdotnet tool update --global Microsoft.PowerApps.CLI.Tool如果任一命令执行失败,请告知用户并提供安装说明。在前置条件满足前不要继续执行。若遇到问题,请查看troubleshooting.md。
Step 2: Authenticate and Select Environment
步骤2:身份验证与环境选择
Check PAC CLI authentication:
powershell
pac auth listIf no profiles: Ask user to authenticate:
powershell
pac auth create --environment https://your-env.crm.dynamics.comWait for user to complete browser sign-in, then re-verify.
If one profile: Confirm it's active (has marker). If not, activate it:
*powershell
pac auth select --index 1If multiple profiles: Show the list, ask which environment to use, then:
powershell
pac auth select --index <user-chosen-index>Report: "Working with environment: [name]" and proceed.
检查PAC CLI的身份验证状态:
powershell
pac auth list若无配置文件: 请用户进行身份验证:
powershell
pac auth create --environment https://your-env.crm.dynamics.com等待用户完成浏览器登录,然后重新验证。
若有一个配置文件: 确认其处于激活状态(带有标记)。若未激活,执行以下命令激活:
*powershell
pac auth select --index 1若有多个配置文件: 展示列表,询问用户要使用哪个环境,然后执行:
powershell
pac auth select --index <用户选择的索引>反馈:"正在使用环境:[环境名称]",然后继续执行。
Detect Configured Languages (New Pages Only)
检测已配置语言(仅新建页面)
When creating a new page, detect configured languages after confirming the active environment. Skip this for edit flows — the existing page already has its localization set up.
powershell
pac model list-languagesNote the output. If multiple languages are configured (or any non-English language), localization will be included in the generated code. Include the detected languages when reporting the environment to the user, e.g.:
"Working with environment: [name] — Languages: English (1033), Arabic (1025), French (1036)"
创建新页面时,确认激活环境后检测已配置语言。编辑流程跳过此步骤——现有页面已完成本地化设置。
powershell
pac model list-languages记录输出结果。如果配置了多种语言(或任何非英语语言),生成的代码将包含本地化内容。向用户反馈环境信息时需包含检测到的语言,例如:
"正在使用环境:[环境名称] — 语言:英语(1033)、阿拉伯语(1025)、法语(1036)"
Step 3: Gather Requirements (Interactive)
步骤3:收集需求(交互式)
Ask these questions one at a time:
- "Create a new generative page or edit an existing one?" (use )
AskUserQuestion- If new: continue to next question
- If edit: ask for the app and page to edit, download it with , then ask what changes to make
pac model genpage download --app-id <app-id> --page-id <page-id> --output-directory ./output-dir
- "Describe the page you'd like to build" (use ) — present two example descriptions as options and let the user type their own via the "Other" option:
AskUserQuestion- Option 1: "Build a page showing Account records as a gallery of cards using modern look & feel. All cards should have fixed size and tall enough to fit 4 lines of titles. Include name, entityimage on the top and, website, email, phone number. Make the component fill 100% of the space. Make the gallery scrollable. Use data from the Account table. Make each card clickable to open the Account record in a new window. The target URL should be current location path with following query string parameters: pagetype=entityrecord&etn=[entityname]&id=[recordid] where entityname is account and id is accountid."
- Option 2: "Design a vertically scrollable checklist interface for Task records using a clean, flat layout. Each task should be a row with a left-aligned checkbox, subject in bold and right-aligned due date and priority. Use neutral tones for background and soft color tags for priority (e.g., red for High, gray for Low). Completed tasks should show a strikethrough and reduced opacity. Allow inline editing of due date with a date picker. On hover, rows should highlight with another background. Clicking a task opens the Task record in a new window using: pagetype=entityrecord&etn=[entityname]&id=[recordid] where entityname is task and id is related record id."
- Other (Recommended): User types their own description
- "Will the page use Dataverse entities or mock data?" (use )
AskUserQuestion- If entities: ask which entities and fields (use logical names — singular, lowercase)
- If mock data: confirm you'll generate realistic sample data
- "Any specific requirements?" (use ) — styling, features (search, filtering, sorting), accessibility, responsive behavior, interactions
AskUserQuestion
If the user provided a description with the command, acknowledge it and skip question 2. If the selected description already specifies a data source (e.g., Option 1 mentions Account table, Option 2 mentions Task records), skip question 3 as well.
/genpage依次询问以下问题:
- "是创建新的生成式页面还是编辑现有页面?"(使用)
AskUserQuestion- 若选择新建:继续下一个问题
- 若选择编辑:询问要编辑的应用和页面,使用下载页面,然后询问需要进行的更改
pac model genpage download --app-id <app-id> --page-id <page-id> --output-directory ./output-dir
- "描述你想要构建的页面"(使用)——提供两个示例描述作为选项,并允许用户通过"其他"选项输入自定义描述:
AskUserQuestion- 选项1: "构建一个以卡片画廊形式展示Account记录的页面,采用现代外观。所有卡片尺寸固定,高度足够容纳4行标题。包含名称、顶部实体图片,以及网站、邮箱、电话号码。让组件填满100%空间。画廊支持滚动。使用Account表的数据。每张卡片可点击,在新窗口打开Account记录。目标URL为当前路径,附加查询参数:pagetype=entityrecord&etn=[entityname]&id=[recordid],其中entityname为account,id为accountid。"
- 选项2: "为Task记录设计垂直滚动的清单界面,采用简洁的扁平化布局。每个任务为一行,包含左对齐的复选框、加粗的主题,以及右对齐的截止日期和优先级。背景使用中性色调,优先级使用柔和颜色标签(例如:红色代表高优先级,灰色代表低优先级)。已完成任务显示删除线并降低透明度。允许通过日期选择器内联编辑截止日期。鼠标悬停时,行背景高亮。点击任务在新窗口打开Task记录,使用URL:pagetype=entityrecord&etn=[entityname]&id=[recordid],其中entityname为task,id为相关记录ID。"
- 其他(推荐): 用户输入自定义描述
- "页面将使用Dataverse实体还是模拟数据?"(使用)
AskUserQuestion- 若使用实体:询问使用的实体和字段(使用逻辑名称——单数、小写)
- 若使用模拟数据:确认将生成真实的示例数据
- "是否有特定需求?"(使用)——样式、功能(搜索、筛选、排序)、可访问性、响应式表现、交互逻辑
AskUserQuestion
如果用户在调用时已提供描述,请确认并跳过问题2。如果所选描述已指定数据源(例如选项1提到Account表,选项2提到Task记录),则同样跳过问题3。
/genpageStep 4: Plan and Confirm
步骤4:规划与确认
Present a clear plan:
I'll create a [page type] with:
- Data: [entities or mock data with specifics]
- Features: [list key features]
- Components: [Fluent UI components to use]
- Layout: [responsive design approach]
- Localization: [list detected languages] (translations, RTL support if applicable, user format settings)
Does this plan look good? Any changes needed?Only include the Localization line when multiple languages were detected in Step 2, or any non-English language was configured.
Wait for confirmation before proceeding. If changes requested, revise and re-confirm.
展示清晰的规划方案:
我将创建一个[页面类型],包含:
- 数据:[实体或模拟数据详情]
- 功能:[核心功能列表]
- 组件:[将使用的Fluent UI组件]
- 布局:[响应式设计方案]
- 本地化:[检测到的语言列表](翻译、RTL支持(如适用)、用户格式设置)
此规划是否可行?是否需要调整?仅当步骤2中检测到多种语言或任何非英语语言时,才包含本地化行。
等待用户确认后再继续。若用户要求更改,修改方案后重新确认。
Step 5: Generate Schema and Verify Columns (Dataverse Pages Only)
步骤5:生成架构并验证列(仅Dataverse页面)
CRITICAL — DO THIS BEFORE WRITING ANY CODE. Column name hallucination is the #1 source of runtime errors. Never guess column names.
If the page uses Dataverse entities, generate the TypeScript schema NOW:
powershell
pac model genpage generate-types --data-sources "entity1,entity2" --output-file RuntimeTypes.tsWindows + Bash: Always use forward slashes in file paths (e.g.,). Backslashes likeD:/temp/RuntimeTypes.tsor\tare consumed as escape sequences by bash, producing wrong paths.\R
After generating, read the RuntimeTypes.ts file and:
- Identify the actual column names available on each entity
- Note which columns are readonly vs writable
- Note the enum/choice set names and values
- Use ONLY these verified column names when generating code in the next step
NEVER guess or assume column names. Custom entities (e.g.,) have unpredictable column names (e.g.,cr69c_candidatenotcr69c_fullname). The only way to know the real names is to read them from the generated schema.cr69c_name
If schema generation fails, see troubleshooting.md. Do NOT generate code with guessed column names.
For mock data pages: Skip this step.
关键步骤——编写代码前必须执行此操作。 列名称臆测是运行时错误的首要原因。切勿猜测列名称。
如果页面使用Dataverse实体,立即生成TypeScript架构:
powershell
pac model genpage generate-types --data-sources "entity1,entity2" --output-file RuntimeTypes.tsWindows + Bash:文件路径始终使用正斜杠(例如)。反斜杠如D:/temp/RuntimeTypes.ts或\t会被bash解析为转义序列,导致路径错误。\R
生成完成后,阅读RuntimeTypes.ts文件并:
- 识别每个实体可用的实际列名称
- 记录哪些列是只读的,哪些是可写的
- 记录枚举/选项集的名称和值
- 下一步生成代码时,仅使用这些已验证的列名称
切勿猜测或假设列名称。 自定义实体(例如)的列名称不可预测(例如cr69c_candidate而非cr69c_fullname)。唯一能获取真实名称的方式是读取生成的架构文件。cr69c_name
如果架构生成失败,请查看troubleshooting.md。切勿使用猜测的列名称生成代码。
模拟数据页面: 跳过此步骤。
Step 6: Read Code Generation Rules and Samples
步骤6:阅读代码生成规则与示例
Before generating code, read the comprehensive rules reference:
genpage-rules-reference.md — Full code generation rules, DataAPI types, layout patterns, common errors.
Also read a relevant sample for reference:
| Sample | Use When |
|---|---|
| 1-account-grid.tsx | DataGrid with Dataverse entities |
| 2-wizard-multi-step.tsx | Multi-step wizard flow |
| 3-poa-revocation-wizard.tsx | Complex wizard with forms |
| 4-account-crud-dataverse.tsx | Full CRUD operations |
| 5-file-upload.tsx | File upload pattern |
| 6-navigation-sidebar.tsx | Sidebar navigation layout |
| 7-comprehensive-form.tsx | Complex form with validation |
| 8-responsive-cards.tsx | Card-based responsive layout |
| 9-data-caching.tsx | Caching data across navigations |
生成代码前,请阅读完整的规则参考文档:
genpage-rules-reference.md — 完整的代码生成规则、DataAPI类型、布局模式、常见错误。
同时阅读相关示例作为参考:
| 示例 | 使用场景 |
|---|---|
| 1-account-grid.tsx | 基于Dataverse实体的数据网格 |
| 2-wizard-multi-step.tsx | 多步骤向导流程 |
| 3-poa-revocation-wizard.tsx | 带表单的复杂向导 |
| 4-account-crud-dataverse.tsx | 完整CRUD操作 |
| 5-file-upload.tsx | 文件上传模式 |
| 6-navigation-sidebar.tsx | 侧边栏导航布局 |
| 7-comprehensive-form.tsx | 带验证的复杂表单 |
| 8-responsive-cards.tsx | 基于卡片的响应式布局 |
| 9-data-caching.tsx | 跨导航的数据缓存 |
Step 7: Generate Code
步骤7:生成代码
Generate complete TypeScript following ALL rules in genpage-rules-reference.md. For Dataverse pages, use ONLY the column names verified from RuntimeTypes.ts in Step 5. Output in this format:
Agent Thoughts: Step-by-step reasoning and approach
Summary: Non-technical bulleted list of what was built
Final Code: Complete, ready-to-run TypeScript (no placeholders)
Localization: If multiple languages were detected in Step 2, the generated code must follow the Localization rules in genpage-rules-reference.md. This includes language detection boilerplate, a translations dictionary for all detected languages, a helper for all user-visible text, RTL support if any RTL languages (Arabic, Hebrew) were detected, and user formatting settings from .
translate()usersettingsSave the code to a file (e.g., ).
.tsxaccount-dashboard.tsx遵循genpage-rules-reference.md中的所有规则生成完整的TypeScript代码。对于Dataverse页面,仅使用步骤5中从RuntimeTypes.ts验证的列名称。 按以下格式输出:
Agent思路: 分步推理与实现方案
摘要: 非技术化的功能列表,说明构建内容
最终代码: 完整、可直接运行的TypeScript代码(无占位符)
本地化: 如果步骤2中检测到多种语言,生成的代码必须遵循genpage-rules-reference.md中的本地化规则。这包括语言检测模板、所有检测到语言的翻译字典、用于所有用户可见文本的辅助函数、RTL支持(如果检测到RTL语言如阿拉伯语、希伯来语),以及来自的用户格式设置。
translate()usersettings将代码保存到文件(例如)。
.tsxaccount-dashboard.tsxComponent Template
组件模板
typescript
import {useEffect, useState} from 'react';
import type {
TableRow,
DataColumnValue,
RowKeyDataColumnValue,
QueryTableOptions,
ReadableTableRow,
ExtractFields,
GeneratedComponentProps
} from "./RuntimeTypes";
// Additional imports: @fluentui/react-components, @fluentui/react-icons, d3, etc.
// Utility functions as separate top-level functions
// Sub-components as separate top-level functions
const GeneratedComponent = (props: GeneratedComponentProps) => {
const { dataApi, pageInput } = props;
// Component implementation
}
export default GeneratedComponent;typescript
import {useEffect, useState} from 'react';
import type {
TableRow,
DataColumnValue,
RowKeyDataColumnValue,
QueryTableOptions,
ReadableTableRow,
ExtractFields,
GeneratedComponentProps
} from "./RuntimeTypes";
// 额外导入:@fluentui/react-components, @fluentui/react-icons, d3等
// 工具函数作为独立的顶层函数
// 子组件作为独立的顶层函数
const GeneratedComponent = (props: GeneratedComponentProps) => {
const { dataApi, pageInput } = props;
// 组件实现
}
export default GeneratedComponent;DataAPI Quick Reference
DataAPI快速参考
typescript
// Query with pagination
const result = await dataApi.queryTable("account", {
select: ["name", "revenue"],
filter: `contains(name,'test')`,
orderBy: `name asc`,
pageSize: 50
});
// Load more rows
if (result.hasMoreRows && result.loadMoreRows) {
const nextPage = await result.loadMoreRows();
}
// Create, Update, Retrieve
await dataApi.createRow("account", { name: "New Account" });
await dataApi.updateRow("account", "record-id", { name: "Updated" });
const row = await dataApi.retrieveRow("account", { id: "record-id", select: ["name"] });
// Access formatted values (for enums, lookups, dates, etc.)
const formatted = row["status@OData.Community.Display.V1.FormattedValue"];
// Lookup fields: raw value is a GUID — use formatted value for display name
const contactGuid = row._primarycontactid_value; // GUID
const contactName = row["_primarycontactid_value@OData.Community.Display.V1.FormattedValue"]; // Display name
// Get enum choices
const choices = await dataApi.getChoices("account-statecode");DataAPI Rules:
- ONLY use when TableRegistrations are provided — never assume tables/fields exist
dataApi - NEVER guess column names — always verify from RuntimeTypes.ts generated in Step 5
- Lookup fields (e.g., ) return a GUID. Always use the
_primarycontactid_valueannotation for display@OData.Community.Display.V1.FormattedValue - Use entity logical names — singular lowercase (e.g., )
"account" - Only reference columns that exist in the generated schema
- If no types provided, use mocked sample data
- Always wrap async calls in try-catch
dataApi - DataGrid: use , enable sorting by default
createTableColumn
See genpage-rules-reference.md for full DataAPI type definitions and examples.
typescript
// 带分页的查询
const result = await dataApi.queryTable("account", {
select: ["name", "revenue"],
filter: `contains(name,'test')`,
orderBy: `name asc`,
pageSize: 50
});
// 加载更多行
if (result.hasMoreRows && result.loadMoreRows) {
const nextPage = await result.loadMoreRows();
}
// 创建、更新、检索
await dataApi.createRow("account", { name: "New Account" });
await dataApi.updateRow("account", "record-id", { name: "Updated" });
const row = await dataApi.retrieveRow("account", { id: "record-id", select: ["name"] });
// 访问格式化值(适用于枚举、查找、日期等)
const formatted = row["status@OData.Community.Display.V1.FormattedValue"];
// 查找字段:原始值为GUID — 使用格式化值显示名称
const contactGuid = row._primarycontactid_value; // GUID
const contactName = row["_primarycontactid_value@OData.Community.Display.V1.FormattedValue"]; // 显示名称
// 获取枚举选项
const choices = await dataApi.getChoices("account-statecode");DataAPI规则:
- 仅当提供TableRegistrations时使用— 切勿假设表/字段存在
dataApi - 切勿猜测列名称 — 始终从步骤5生成的RuntimeTypes.ts中验证
- 查找字段(例如)返回GUID。显示时始终使用
_primarycontactid_value注解@OData.Community.Display.V1.FormattedValue - 使用实体逻辑名称 — 单数小写(例如)
"account" - 仅引用生成架构中存在的列
- 如果未提供类型,使用模拟示例数据
- 始终将异步调用包裹在try-catch中
dataApi - 数据网格:使用,默认启用排序
createTableColumn
查看genpage-rules-reference.md获取完整的DataAPI类型定义和示例。
Step 8: Save and Deploy
步骤8:保存与部署
After showing code, ALWAYS ask:
"Would you like to publish this page to Power Apps?"
If yes, follow this deployment workflow. Copy the upload commands below exactly — , , , are all required and must use these exact flag names.
--app-id--code-file--prompt--agent-messageFor Dataverse entity pages (schema already generated in Step 5):
powershell
pac model listCRITICAL: Ask the user: "Which app would you like to publish this page to? Please provide the app-id or app name from the list above."
- NEVER choose a default app or assume an app-id
- ACCEPT BOTH app-id (GUID) or app name — if user provides an app name, run to look up the corresponding app-id
pac model list - WAIT for user response before proceeding
powershell
pac model genpage upload `
--app-id <user-provided-app-id-or-name> `
--code-file page-name.tsx `
--name "Page Display Name" `
--data-sources "entity1,entity2" `
--prompt "User's original request summary" `
--model "<current-model-id>" `
--agent-message "The agent's response message describing what was built and any relevant details" `
--add-to-sitemapFor mock data pages (skip schema generation):
powershell
pac model list展示代码后,务必询问:
"是否要将此页面发布到Power Apps?"
如果用户同意,遵循以下部署流程。请完全复制以下上传命令——、、、均为必填项,且必须使用这些确切的参数名称。
--app-id--code-file--prompt--agent-message对于Dataverse实体页面(步骤5已生成架构):
powershell
pac model list关键提示: 询问用户:"你要将此页面发布到哪个应用?请提供上述列表中的app-id或应用名称。"
- 切勿选择默认应用或假设app-id
- 同时接受app-id(GUID)或应用名称 — 如果用户提供应用名称,运行查找对应的app-id
pac model list - 等待用户回复后再继续
powershell
pac model genpage upload `
--app-id <用户提供的app-id或名称> `
--code-file page-name.tsx `
--name "页面显示名称" `
--data-sources "entity1,entity2" `
--prompt "用户原始请求摘要" `
--model "<当前模型ID>" `
--agent-message "Agent的回复消息,说明构建内容及相关细节" `
--add-to-sitemap对于模拟数据页面(跳过架构生成):
powershell
pac model listAsk user for app selection, then:
询问用户选择应用,然后执行:
pac model genpage upload
--code-file page-name.tsx
--prompt "User's original request summary"
--agent-message "The agent's response message describing what was built and any relevant details" `
--add-to-sitemap
--app-id <user-provided-app-id-or-name> --name "Page Display Name" --model "<current-model-id>"
**For updating existing pages** (use `--page-id`, omit `--add-to-sitemap`):
```powershell
pac model genpage upload `
--app-id <app-id-or-name> `
--page-id <page-id> `
--code-file page-name.tsx `
--data-sources "entity1,entity2" `
--prompt "User's original request summary" `
--model "<current-model-id>" `
--agent-message "The agent's response message describing what was built and any relevant details"pac model genpage upload
--code-file page-name.tsx
--prompt "用户原始请求摘要"
--agent-message "Agent的回复消息,说明构建内容及相关细节" `
--add-to-sitemap
--app-id <用户提供的app-id或名称> --name "页面显示名称" --model "<当前模型ID>"
**对于更新现有页面**(使用`--page-id`,省略`--add-to-sitemap`):
```powershell
pac model genpage upload `
--app-id <app-id或名称> `
--page-id <page-id> `
--code-file page-name.tsx `
--data-sources "entity1,entity2" `
--prompt "用户原始请求摘要" `
--model "<当前模型ID>" `
--agent-message "Agent的回复消息,说明构建内容及相关细节"Step 9: Verify in Browser
步骤9:浏览器验证
After successful deployment, ask the user (use ):
AskUserQuestion"Would you like to verify the page in the browser using Playwright? This will open the page and test interactive elements."
Options: Yes, verify in browser / Skip verification
If the user chooses to skip, go directly to Step 10.
If the user chooses to verify, open the page in the browser using Playwright to verify it works and interactive elements function correctly.
部署成功后,询问用户(使用):
AskUserQuestion"是否要使用Playwright在浏览器中验证此页面?这将打开页面并测试交互元素。"
选项:是,在浏览器中验证 / 跳过验证
如果用户选择跳过,直接进入步骤10。
如果用户选择验证,使用Playwright在浏览器中打开页面,验证页面正常工作且交互元素功能正常。
9.1 Navigate and Authenticate
9.1 导航与身份验证
Construct the URL from the environment base URL, app-id, and page-id returned by the upload command:
https://<env>.crm.dynamics.com/main.aspx?appid=<app-id>&pagetype=genux&id=<page-id>- Use to open the constructed URL
browser_navigate - If you get a "page closed" or "browser closed" error, retry navigation once — Playwright sessions can expire
- Use to capture the page state. Always snapshot before any clicks — stale refs cause "Ref not found" errors
browser_snapshot - If a sign-in page appears, use on the sign-in option, then
browser_clickfor the page to loadbrowser_wait_for - Use to wait for the genux page content to render (may take a few seconds)
browser_wait_for
根据环境基础URL、app-id和上传命令返回的page-id构造URL:
https://<env>.crm.dynamics.com/main.aspx?appid=<app-id>&pagetype=genux&id=<page-id>- 使用打开构造的URL
browser_navigate - 如果出现"页面已关闭"或"浏览器已关闭"错误,重试一次导航——Playwright会话可能过期
- 使用捕获页面状态。点击任何元素前务必先快照——过时的引用会导致"未找到引用"错误
browser_snapshot - 如果出现登录页面,使用点击登录选项,然后使用
browser_click等待页面加载browser_wait_for - 使用等待genux页面内容渲染(可能需要几秒)
browser_wait_for
9.2 Structural Verification
9.2 结构验证
Use to take an accessibility snapshot and verify the expected DOM elements are present based on the page type built:
browser_snapshot| Page Type | Expected Elements |
|---|---|
| Data Grid | Table/grid element with column headers and data rows |
| Form / Wizard | Form fields (inputs, dropdowns) and Next/Back buttons |
| CRUD | Data grid + action buttons (Add, Edit, Delete) |
| Dashboard | Multiple sections/panels with headings |
| Card Layout | Card containers with content |
| File Upload | File input or drop zone element |
| Navigation Sidebar | Nav element with menu items |
If expected elements are missing, note the issue for the fix step (9.5).
使用获取可访问性快照,根据构建的页面类型验证预期的DOM元素是否存在:
browser_snapshot| 页面类型 | 预期元素 |
|---|---|
| 数据网格 | 带列标题和数据行的表格/网格元素 |
| 表单/向导 | 表单字段(输入框、下拉菜单)和下一步/返回按钮 |
| CRUD | 数据网格 + 操作按钮(添加、编辑、删除) |
| 仪表板 | 多个带标题的区块/面板 |
| 卡片布局 | 包含内容的卡片容器 |
| 文件上传 | 文件输入框或拖拽区域元素 |
| 导航侧边栏 | 带菜单项的导航元素 |
如果预期元素缺失,记录问题以便修复(步骤9.5)。
9.3 Interactive Testing
9.3 交互测试
Test functional interactions based on the page type. Always take a fresh before each click to get current element refs. Move on after 2 failed attempts per interaction.
browser_snapshotAll page types:
- Verify at least one button or control responds to a click
Page-type-specific tests:
| Page Type | Test Action | Expected Result |
|---|---|---|
| Data Grid | Click a column header | Sort order changes (arrow indicator appears or flips) |
| Form / Wizard | Click Next button | Step advances to next section |
| Form / Wizard | Click Back button | Returns to previous section |
| CRUD | Click Add/New button | Form or dialog appears |
| Dashboard | Click a tab or section toggle | Content area updates |
| Card Layout | Click an action button on a card | Card responds (expand, navigate, etc.) |
| Navigation Sidebar | Click a menu item | Content area updates to show selected section |
What NOT to test (skip these):
- Dataverse data mutations (create/update/delete records) — modifies real data
- File upload dialogs — Playwright cannot interact with native OS file dialogs
- Complex form validation — fragile, requires realistic test data
- Pagination — requires actual Dataverse data to be present
根据页面类型测试功能交互。每次点击前务必获取新的以获取当前元素引用。 每个交互尝试2次失败后即停止。
browser_snapshot所有页面类型:
- 验证至少一个按钮或控件响应点击
页面类型专属测试:
| 页面类型 | 测试操作 | 预期结果 |
|---|---|---|
| 数据网格 | 点击列标题 | 排序顺序更改(箭头指示器出现或翻转) |
| 表单/向导 | 点击下一步按钮 | 步骤切换到下一部分 |
| 表单/向导 | 点击返回按钮 | 返回上一部分 |
| CRUD | 点击添加/新建按钮 | 弹出表单或对话框 |
| 仪表板 | 点击标签页或区块切换按钮 | 内容区域更新 |
| 卡片布局 | 点击卡片上的操作按钮 | 卡片响应(展开、导航等) |
| 导航侧边栏 | 点击菜单项 | 内容区域更新为选中部分 |
无需测试的内容(跳过):
- Dataverse数据变更(创建/更新/删除记录)——会修改真实数据
- 文件上传对话框——Playwright无法与原生操作系统对话框交互
- 复杂表单验证——易出错,需要真实测试数据
- 分页——需要实际Dataverse数据存在
9.4 Visual Confirmation
9.4 视觉确认
Use to capture a final screenshot for the deployment summary. This screenshot should show the page in its final verified state.
browser_take_screenshot使用捕获最终截图用于部署总结。此截图应展示页面验证后的最终状态。
browser_take_screenshot9.5 Fix and Re-deploy
9.5 修复与重新部署
If structural or interactive issues are found:
- Analyze the snapshot and screenshot for error details
- Fix the code
- Re-deploy using Step 8
- Repeat verification (Steps 9.1–9.4) until the page works correctly
Common Playwright issues:
- "Target page, context or browser has been closed" → retry the navigation
- "Ref not found" → take a fresh before clicking any element
browser_snapshot - Sign-in required → Playwright uses the system browser session; if not authenticated, the user must sign in manually first
如果发现结构或交互问题:
- 分析快照和截图获取错误详情
- 修复代码
- 使用步骤8重新部署
- 重复验证(步骤9.1–9.4)直到页面正常工作
常见Playwright问题:
- "目标页面、上下文或浏览器已关闭" → 重试导航
- "未找到引用" → 点击任何元素前获取新的
browser_snapshot - 需要登录 → Playwright使用系统浏览器会话;如果未登录,用户需手动先登录
Step 10: Final Summary
步骤10:最终总结
After deployment and verification, provide:
- Confirmation of successful upload
- Screenshot of the page (if browser verification was done)
- How to find the page in the app
- Next steps (share with team, iterate on design)
- Offer to make updates or create additional pages
部署和验证完成后,提供以下内容:
- 上传成功的确认信息
- 页面截图(如果进行了浏览器验证)
- 在应用中查找页面的方法
- 后续步骤(与团队共享、迭代设计)
- 提供更新页面或创建其他页面的服务