次の方法で共有


Copilotを使用した AI テスト作成

Playwright の組み込みコード ジェネレーター (codegen) は、ブラウザーの対話を TypeScript テスト コードとして記録します。 それを AI コーディング アシスタントと組み合わせて、記録をクリーンアップし、Power Platform Playwright ツールキットの規則を適用し、セレクターを手動で記述せずに運用環境対応のテストを生成します。

ワークフローのしくみ

  1. レコード: Power Platform アプリに対して playwright codegen を実行します。 Playwright は、すべてのクリック、塗りつぶし、ナビゲーションを生のテスト コードとしてキャプチャします。
  2. 貼り付け: 記録したコードをツールキット API ドキュメントまたはカスタム手順と共に AI チャットにドロップします。
  3. 書き換え: AppProviderModelDrivenAppPageGridComponent、その他のツールキット クラスを使用して記録を書き直すように AI に依頼します。
  4. 確認: 生成されたテストの正確性、タイムアウトの調整、コミットを確認します。

このワークフローは、ツールキット API を初めて使用する場合や、なじみのないアプリを操作する場合に特に便利です。

手順 1: Playwright codegen で記録する

Playwright の codegen ツールを使用してブラウザーの対話を記録し、後の手順で調整する生のテスト コードを生成します。

Playwright ブラウザーをインストールする

記録する前に、Chromium ブラウザーが Playwright 用にインストールされていることを確認します。

cd packages/e2e-tests
npx playwright install chromium

アプリに対して codegen を実行する

Power Platform アプリの URL を指す Playwright のコード ジェネレーターを起動します。 これにより、Playwright Inspector と共にブラウザーが開き、すべての操作が TypeScript として記録されます。

npx playwright codegen --save-storage=.playwright-ms-auth/state-record.json \
  "https://apps.powerapps.com/play/<your-app-id>"

このコマンドを実行すると、ブラウザーと Playwright Inspector がサイド バイ サイドで開きます。 アプリを操作する - ボタンをクリックし、フォームに入力し、移動します。 インスペクターは、すべてのアクションを TypeScript として記録します。

ヒント

アプリで認証が必要な場合は、最初に認証を行い、ストレージの状態を渡します。

npx playwright codegen --load-storage=.playwright-ms-auth/state-<email>.json \
  "https://apps.powerapps.com/play/<your-app-id>"

生成されたコードをコピーする

完了したら、生成されたテストを Playwright Inspector からコピーします。 次のようになります。

import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('https://apps.powerapps.com/play/...');
  await page.frameLocator('iframe[name="fullscreen-app-host"]')
    .locator('[data-control-name="icon3"]').click();
  await page.frameLocator('iframe[name="fullscreen-app-host"]')
    .locator('input[aria-label="Account Name"]').fill('Contoso');
  // ...
});

手順 2: AI で書き換える

記録を AI チャットに貼り付けます。 次に、次のように質問します。

"Power Platform Playwright ツールキットを使用して、この Playwright codegen の記録を適切なテストとして書き換える。 AppProviderを使用してアプリを起動し、フレーム ロケーターのスコープを変数に設定し、対話の前に適切なwaitFor呼び出しを追加し、expectから@playwright/testアサーションを使用します。

カスタム命令ファイルが構成されている場合、AI によってプロジェクト規則が自動的に適用されます。 それ以外の場合は、 コンテキストとして canvas-application.md または model-driven-application.md から関連するコード スニペットを共有します。

例: AI で書き換えられたキャンバス テスト

次の例は、Power Platform Playwright ツールキットを使用して、生の codegen 出力がクリーンで保守可能なテストに変換される方法を示しています。

Before (codegen output):

test('test', async ({ page }) => {
  await page.goto('https://apps.powerapps.com/play/<app-id>');
  await page.frameLocator('iframe[name="fullscreen-app-host"]')
    .locator('[data-control-name="icon3"]').click();
  await page.frameLocator('iframe[name="fullscreen-app-host"]')
    .locator('input[aria-label="Account Name"]').fill('Contoso');
  await page.frameLocator('iframe[name="fullscreen-app-host"]')
    .locator('[data-control-name="IconButton_Accept1"] [role="button"]').click();
});

(AIリライト後):

import { test, expect } from '@playwright/test';
import { AppProvider, AppType, AppLaunchMode, buildCanvasAppUrlFromEnv } from 'power-platform-playwright-toolkit';

test('should add a new account', async ({ page, context }) => {
  const app = new AppProvider(page, context);
  await app.launch({
    app: 'Accounts App',
    type: AppType.Canvas,
    mode: AppLaunchMode.Play,
    skipMakerPortal: true,
    directUrl: buildCanvasAppUrlFromEnv(),
  });

  const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');

  // Wait for app to load
  await canvasFrame
    .locator('[data-control-part="gallery-item"]')
    .first()
    .waitFor({ state: 'visible', timeout: 60000 });

  // Click Add
  await canvasFrame.locator('[data-control-name="icon3"]').click();

  // Fill form
  await canvasFrame.locator('input[aria-label="Account Name"]').fill('Contoso');

  // Save
  await canvasFrame
    .locator('[data-control-name="IconButton_Accept1"] [role="button"]')
    .click();

  // Verify record appears
  const newItem = canvasFrame
    .locator('[data-control-part="gallery-item"]')
    .filter({ hasText: 'Contoso' });

  await expect(newItem).toBeVisible({ timeout: 30000 });
});

手順 3: モデル駆動型アプリのヘッド モードで codegen を使用する

モデル駆動型アプリの場合は、グリッド ナビゲーションとフォーム操作を記録します。

npx playwright codegen --load-storage=.playwright-ms-auth/state-mda-<email>.json \
  "https://<org>.crm.dynamics.com/main.aspx?appid=<app-id>"

次に、 ModelDrivenAppPage を使用して AI に書き換えを依頼します。

この codegen レコーディングを書き換えて、ModelDrivenAppPage を使用します。 生の page.locator() グリッドクリックを mda.grid.filterByKeyword()mda.grid.openRecord()mda.form.getAttribute()、および mda.form.save()に置き換えます。

テスト作成に GitHub Copilot Chatを使用する

GitHub Copilotを使用した VS Code では、codegen を使用せずにチャット パネルで直接テストを作成できます。

  1. エディターで関連するテスト ファイルを開きます。

  2. Copilot Chat (Ctrl+Shift+I) を開きます。

  3. 問い合わせ:

    "@workspaceギャラリーを開き、"Northwind Traders" というタイトルのアイテムを検索してクリックし、電話フィールドを編集して保存する tests/northwind/canvas/canvas-app-crud.test.ts でテストを記述します。"

Copilotは、既存のテスト ファイルとツールキットのインポートを読み取り、コンテキストに応じて正確なテスト コードを生成します。

最適な結果を得るには、適切に記述された参照テストを同じファイルまたはフォルダーに保持します。 Copilotは、スタイルに合わせてパターンとして使用します。

大規模なテスト スイートに Claude を使用する

Claude (Claude Code または Claude.ai を使用) では、複数の関連するテストを一度に生成できます。

このキャンバスアプリの構造 [canvas-application.md コンテンツを貼り付ける] を考慮し、次をカバーする完全なテストスイートを生成します。(1) ギャラリーに項目が読み込まれること、(2) 検索フィルターの結果、(3) 新しいレコードを作成すること、(4) 既存のレコードを編集すること、(5) レコードを削除すること。

Claude は、コンテキスト内のパターンに従って、1 つの応答で 5 つのテストすべてを生成します。

迅速なテスト生成のためのプレイライト CLI

Playwright CLI には、テスト管理のための追加のユーティリティが用意されています。

# Install
npm install -g @playwright/cli

# Generate test stubs for a URL
playwright-cli generate --url "https://apps.powerapps.com/play/<app-id>"

# List all tests in a project
playwright-cli list

# Show test tree
playwright-cli show-tree packages/e2e-tests

Playwright CLI は、Playwright テスト ランナーとは別のパッケージです。 テストの検出とスキャフォールディングのための便利なコマンドが追加されます。

AI で生成されたテストのベスト プラクティス

  • 生成されたセレクターを常に確認する: AI によって、脆弱すぎるセレクターや広すぎるセレクターが作成される可能性があります。 実際の DOM に対して data-control-name の値を確認する。
  • タイムアウトを確認する: AI はアプリの読み込み時間を認識しません。 Dataverse ベースのアプリでのギャラリー waitFor 呼び出しに 60 秒のタイムアウトを追加します。
  • 一意のテスト データを使用する: AI によって生成されたテストでは、多くの場合、ハードコードされた文字列が使用されます。 テストの実行間の競合を回避するために、 Date.now() サフィックスに置き換えます。
  • expectを使用して検証する: Codegen の記録にはアサーションがないことがよくあります。 各アクションの後に意味のある expect 呼び出しを追加するように AI に依頼します。

次のステップ

こちらも参照ください