FormComponent.execute() メソッドは、Xrm API に対して直接、Dynamics 365 フォーム コンテキスト内で任意の JavaScript を実行します。 このアプローチにより、ハイブリッド テストアプローチが可能になります。 Playwright を使用してレコードに移動し、 execute() を使用してデータをプログラムで検証または操作します。 この方法は、低速または信頼性の低い UI 操作を置き換えます。
どのように機能するのか
ブラウザーでモデル駆動型アプリ レコードを開くと、 window.Xrmで Xrm オブジェクトを使用できます。
execute() メソッドは、Playwright Node.js コンテキストとブラウザー ページ コンテキストをブリッジします。 関数がブラウザーに挿入され、結果が返されます。
const result = await modelDrivenApp.form.execute(async (formContext) => {
// This code runs inside the browser, with access to the full Xrm API
return formContext.getAttribute('nwind_ordernumber')?.getValue();
});
console.log(`Order number from Xrm: ${result}`);
formContext は、標準の Dynamics 365 Xrm.Form.FormContext オブジェクトです。 任意の Xrm クライアント API メソッドを使用できます。
Xrm を使用してフィールド値を読み取る
execute()を使用して、DOM セレクターに依存せずにフィールド値を読み取ります。
// Read a text field
const orderNumber = await mda.form.execute(
(ctx) => ctx.getAttribute('nwind_ordernumber')?.getValue()
);
// Read a lookup field
const customer = await mda.form.execute((ctx) => {
const lookup = ctx.getAttribute('nwind_customerid')?.getValue();
return lookup?.[0]?.name ?? null;
});
// Read a choice/option set
const statusCode = await mda.form.execute(
(ctx) => ctx.getAttribute('nwind_orderstatusid')?.getValue()
);
ヒント
Xrm API を使用した読み取りは、DOM 入力値を読み取るよりも信頼性が高くなります。 Xrm API は、フィールドのレンダリング方法に関係なく、内部型指定された値を返します。
Xrm を使用してフィールド値を書き込む
入力要素を入力せずに、プログラムでフィールド値を設定します。
await mda.form.execute((ctx) => {
ctx.getAttribute('nwind_ordernumber')?.setValue('ORD-API-001');
ctx.getAttribute('nwind_notes')?.setValue('Updated via Xrm API');
});
注
execute()を使用して値を設定すると、ブラウザーの入力イベントがバイパスされます。
onChangeビジネス ルールを持つフィールドの場合、このアプローチはプラグインまたはスクリプトが実行する方法と同じです。 ブラウザーの入力フォーカスまたはぼかしイベントに依存するフィールドの場合は、ui パスをトリガーする mda.form.setAttribute()を使用します。
ビジネス ロジック ルールを検証する
フィールド レベルまたはフォーム レベルのビジネス ルールが正しく起動することをテストします。
// Open a record
await mda.grid.openRecord({ rowNumber: 0 });
// Trigger a field change
await mda.form.setAttribute('nwind_orderstatusid', 'Shipped');
// Validate that a business rule made the tracking field required
const requiredLevel = await mda.form.execute(
(ctx) => ctx.getAttribute('nwind_trackingnumber')?.getRequiredLevel()
);
expect(requiredLevel).toBe('required');
フォームの有効性と変更された状態を確認する
isDirty()、isValid()、およびsave()メソッドを使用して、フォームの変更が正しく追跡され、保存の前後に検証に合格することを確認します。
// After making changes, verify the form is dirty
const isDirty = await mda.form.isDirty();
expect(isDirty).toBe(true);
// Save and verify no validation errors
await mda.form.save();
expect(await mda.form.isValid()).toBe(true);
expect(await mda.form.isDirty()).toBe(false);
Xrm WebApi 呼び出しを実行する
完全な Xrm.WebApi は、 execute()内で使用できます。 これを使用して、Dataverse レコードのクエリまたは変更を直接行います。
// Query Dataverse records without navigating the grid
const result = await mda.form.execute(async (formContext) => {
const response = await (window as any).Xrm.WebApi.retrieveMultipleRecords(
'nwind_orders',
'?$filter=nwind_orderstatus eq 1&$select=nwind_ordernumber&$top=5'
);
return response.entities.map((e: any) => e.nwind_ordernumber);
});
expect(result.length).toBeGreaterThan(0);
Important
Xrm.WebApi 呼び出しはブラウザー コンテキストで実行され、Dataverse API の制限とテスト ユーザーのセキュリティ ロールの対象となります。 これらは、API 呼び出しクォータに対してカウントされます。
プラグインの副作用をテストする
レコードを保存した後、 execute() を使用して、プラグインが関連フィールドを正しく更新したことを確認します。
// Create a new order via UI
await mda.navigateToFormView('nwind_orders');
await page.locator('input[data-id="nwind_ordernumber.fieldControl-text-box-text"]').fill('ORD-PLUGIN-TEST');
await mda.form.save();
// Wait for plugin async processing
await page.waitForTimeout(3000);
// Verify the plugin set the calculated total
const calculatedTotal = await mda.form.execute(
(ctx) => ctx.getAttribute('nwind_calculatedtotal')?.getValue()
);
expect(calculatedTotal).toBeGreaterThan(0);
UI ナビゲーションと API アサーションを組み合わせる
一般的なパターンは、UI を介してナビゲーションを実行し、API を使用して状態を検証することです。 次の例では、グリッドから注文を開き、[ 注文の送信 ] コマンド バー ボタンをクリックし、Xrm API を使用して注文の状態が 保留中に更新されたことをアサートします。
test('submit order sets status to Pending', async ({ page, context }) => {
const app = new AppProvider(page, context);
await app.launch({ ... });
const mda = app.getModelDrivenAppPage();
// Navigate to the order via the grid (UI path)
await mda.navigateToGridView('nwind_orders');
await mda.grid.filterByKeyword('ORD-001');
await mda.grid.waitForGridLoad();
await mda.grid.openRecord({ rowNumber: 0 });
// Click Submit via the command bar (UI path)
await mda.commanding.clickButton('Submit Order');
await page.waitForTimeout(2000);
// Validate the status via Xrm API (API assertion)
const status = await mda.form.execute(
(ctx) => ctx.getAttribute('nwind_orderstatusid')?.getValue()
);
expect(status).toBe(100000001); // Pending option set value
});
フォーム コンテキスト API リファレンス
execute() コールバックは、標準の Dynamics 365 form コンテキスト オブジェクトを受け取ります。 主なメソッド:
| メソッド | 説明 |
|---|---|
getAttribute(name) |
スキーマ名でフォーム属性を取得する |
getAttribute(name).getValue() |
現在のフィールド値を読み取る |
getAttribute(name).setValue(v) |
フィールド値を設定する |
getAttribute(name).getRequiredLevel() |
'none'、'recommended'、または'required'を読み取り |
getAttribute(name).setRequiredLevel(level) |
必要なレベルを設定する |
getControl(name).setVisible(bool) |
フィールドの表示と非表示を切り替える |
getControl(name).setDisabled(bool) |
フィールドを有効または無効にする |
ui.tabs.get(name).setVisible(bool) |
タブの表示/非表示を切り替える |
data.entity.getId() |
現在のレコード GUID を取得する |
data.entity.getEntityName() |
論理エンティティ名を取得する |
data.save() |
プログラムでフォームを保存する |
完全な Xrm クライアント API リファレンスについては、Microsoft Dataverse クライアント API リファレンスを参照してください。