這個 Power Platform Playwright 工具包 API 參考了公開的類別、方法和類型,你可以用來自動化 canvas 和模型驅動應用程式的端對端測試。
AppProvider
啟動 Power Platform 應用程式的入口。 每次測試實例化一次,然後呼叫 launch()。
class AppProvider {
constructor(page: Page, context: BrowserContext)
launch(options: AppLaunchOptions): Promise<void>
getModelDrivenAppPage(): ModelDrivenAppPage
getCanvasAppPage(): CanvasAppPage
getGenUxPage(): GenUxPage
}
AppLaunchOptions
選項傳到 AppProvider.launch() 設定要開啟哪個應用程式以及如何開啟。
interface AppLaunchOptions {
app: string; // Display name of the app
type: AppType; // Canvas | ModelDriven
mode: AppLaunchMode; // Play | Edit
skipMakerPortal?: boolean; // true: use directUrl, skip make.powerapps.com navigation
directUrl?: string; // Full URL when skipMakerPortal is true
}
AppType
指定要啟動的 Power Platform 應用程式類型。
enum AppType {
Canvas = 'canvas',
ModelDriven = 'model-driven',
}
AppLaunchMode
決定應用程式是以播放模式還是編輯模式開啟。
enum AppLaunchMode {
Play = 'play',
Edit = 'edit',
}
ModelDrivenAppPage
回覆者 AppProvider.getModelDrivenAppPage()。 提供導航與元件存取。
class ModelDrivenAppPage {
readonly grid: GridComponent
readonly form: FormComponent
readonly commanding: CommandingComponent
navigateToGridView(entityLogicalName: string): Promise<void>
navigateToFormView(entityLogicalName: string): Promise<void>
}
GridComponent
包裹模型驅動清單視圖中使用 的 AG 網格 。 透過 ModelDrivenAppPage.grid 存取。
class GridComponent {
waitForGridLoad(): Promise<void>
filterByKeyword(keyword: string): Promise<void>
filterByColumn(columnName: string, value: string): Promise<void>
getCellValue(rowIndex: number, columnName: string): Promise<string | null>
getRowCount(): Promise<number>
isGridEmpty(): Promise<boolean>
openRecord(options: OpenRecordOptions): Promise<void>
selectRow(rowIndex: number): Promise<void>
selectRows(rowIndexes: number[]): Promise<void>
}
OpenRecordOptions
識別從網格開啟哪筆紀錄的選項。
interface OpenRecordOptions {
rowNumber?: number; // 0-based row index
columnName?: string; // column to match (display name or schema name)
columnValue?: string; // value to match in the column
}
FormComponent
會包裝 Dynamics 365 表單執行時。 透過 ModelDrivenAppPage.form 存取。
class FormComponent {
getAttribute(fieldName: string): Promise<string | null>
setAttribute(fieldName: string, value: string): Promise<void>
save(): Promise<void>
isDirty(): Promise<boolean>
isValid(): Promise<boolean>
navigateToTab(tabName: string): Promise<void>
setFieldVisibility(fieldName: string, visible: boolean): Promise<void>
setFieldDisabled(fieldName: string, disabled: boolean): Promise<void>
setFieldRequiredLevel(
fieldName: string,
level: 'none' | 'recommended' | 'required'
): Promise<void>
execute<T>(
fn: (formContext: Xrm.FormContext) => T | Promise<T>
): Promise<T>
}
FormComponent.execute()
在瀏覽器的表單上下文中執行任意程式碼,並可完全存取 Xrm 用戶端 API:
const value = await mda.form.execute(
(ctx) => ctx.getAttribute('nwind_ordernumber')?.getValue()
);
詳細使用請參考 API 測試透過表單上下文 。
CommandingComponent
會包裝模型驅動的應用程式指令列。 透過 ModelDrivenAppPage.commanding 存取。
class CommandingComponent {
clickButton(ariaLabel: string): Promise<void>
clickMoreCommands(): Promise<void>
}
CanvasAppPage
回覆者 AppProvider.getCanvasAppPage()。 提供canvas iframe框架定位器。
class CanvasAppPage {
getFrame(): FrameLocator
waitForLoad(controlName?: string): Promise<void>
}
GenUxPage
回覆者 AppProvider.getGenUxPage()。 提供與 Power Apps Maker 入口網站 GenUX AI 設計師的互動,從 AI 提示創建、生成、檢查及發布模型驅動應用程式。
class GenUxPage {
readonly previewFrame: FrameLocator // UCI Preview iframe locator
// Power Apps navigation
goToAppsPage(): Promise<void>
navigateToStartWithPageDesign(): Promise<void>
createAppWithName(appName: string): Promise<void>
addNewPage(): Promise<void>
// AI generation
waitForUCIPreviewFrameAndFillPrompt(prompt: string): Promise<void>
waitForUCIPreviewFrameAndSelectTemplate(templateText: string): Promise<void>
verifyThoughtStreaming(): Promise<void>
verifyCodeAndPreviewTabsAvailable(): Promise<void>
verifyCodeStreaming(): Promise<void>
// Inspection
clickPreviewTab(): Promise<void>
clickCodeTab(): Promise<void>
waitForGeneratedContent(): Promise<void>
waitForCodeTabContent(): Promise<void>
getPreviewTabDom(): Promise<string>
getCodeTabContent(): Promise<string>
// Publishing
publishApp(): Promise<void>
buildCanvasPlayUrl(): string
// Form interaction
submitForm(): Promise<void>
waitForSubmitSuccess(timeout?: number): Promise<void>
// App management
getAppIdFromUrl(): string
searchAndPlayApp(appName: string, context: BrowserContext): Promise<Page | null>
deleteAppsMatchingPrefix(prefix: string): Promise<void>
deleteAppFromAppListIfFound(appName: string): Promise<void>
}
GenUxPage.previewFrame
為 UCI 預覽 iframe 揭露。FrameLocator 使用此特性直接查詢產生的表單元素:
const input = genUxPage.previewFrame.getByRole('textbox', { name: 'First Name' });
await expect(input).toBeVisible();
GenUxPage.verifyThoughtStreaming()
檢查暫時性的GenUX串流指標,如思想文字、停止按鈕及代理思考。 每次檢查都是盡力而為——生成可能在所有指標出現前就完成。 唯一確定的是,串流正在進行中或 "Your page is now generated" 是可見。
GenUxPage.searchAndPlayApp()
當 Play 被關閉(應用程式尚未發布)時,會回傳 null ,而不是丟出錯誤。 回風使用test.skip()null:
const appPage = await genUxPage.searchAndPlayApp(appName, context);
if (!appPage) test.skip();
公用程式函數
獨立的輔助功能,用於常見的設定與設定任務。
buildCanvasAppUrlFromEnv
從環境中閱讀 CANVAS_APP_URL :
function buildCanvasAppUrlFromEnv(): string
getStorageStatePath
回傳該郵件的 Power Apps 儲存狀態檔案路徑:
function getStorageStatePath(email: string): string
// Returns: packages/e2e-tests/.playwright-ms-auth/state-<email>.json
ConfigHelper
提供設定輔助工具,例如檢查快取儲存狀態是否已過期。
class ConfigHelper {
static checkStorageStateExpiration(
statePath: string
): { expired: boolean; expiresOn?: number }
}
定位工具
在 iframe 中尋找 Power Apps 控制項的輔助方法。
LocatorUtils
靜態方法,用來依名稱查找 canvas 應用程式的控制項和相簿項目。
class LocatorUtils {
static getByControlName(frame: FrameLocator, controlName: string): Locator
static getGalleryItem(frame: FrameLocator, titleText: string): Locator
}
類型出口
從套件根匯出所有類型:
import {
AppProvider,
AppType,
AppLaunchMode,
AppLaunchOptions,
ModelDrivenAppPage,
GridComponent,
FormComponent,
CommandingComponent,
CanvasAppPage,
GenUxPage,
buildCanvasAppUrlFromEnv,
getStorageStatePath,
ConfigHelper,
LocatorUtils,
} from 'power-platform-playwright-toolkit';