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

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

ワークフローのしくみ

  1. レコード: Power Platform アプリに対して playwright codegen を実行します。 Playwright は、すべてのクリック、塗りつぶし、ナビゲーションを生のテスト コードとしてキャプチャします。
  2. 貼り付け: 記録したコードをツールキット API ドキュメントまたはカスタム手順と共に AI チャットにドロップします。
  3. 書き換え: AppProvider、 ModelDrivenAppPage、 GridComponent、その他のツールキット クラスを使用して記録を書き直すように 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 として記録します。

Tip

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

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 出力がクリーンで保守可能なテストに変換される方法を示しています。

以前 (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は、既存のテスト ファイルとツールキットのインポートを読み取り、コンテキストに応じて正確なテスト コードを生成します。

Note

最適な結果を得るには、適切に記述された参照テストを同じファイルまたはフォルダーに保持します。 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

Note

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

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

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

次のステップ

こちらも参照ください