AI コーディング アシスタントはコンテキストから学習します。 プロジェクトの規則を記述するカスタム命令ファイルを指定すると、AI は自分のスタイルに一致するテスト コードを生成し、適切なツールキット API を使用し、一般的なミスを回避します。すべてのセッションで同じパターンを説明する必要はありません。
この記事では、さまざまな AI アシスタント用のカスタム命令ファイルを記述する方法と、Power Platform Playwright テストに含める内容について説明します。
カスタム命令が重要な理由
カスタム命令がない場合、AI アシスタントは次の場合があります。
- グリッドメソッドやフォーム メソッドの代わりに生の
page.locator()ModelDrivenAppPage使用する - ロケーターのスコープ設定を忘れてしまう
iframe[name="fullscreen-app-host"] - Dataverse に基づくギャラリーで失敗しやすい短いタイムアウトを設定する
-
nth-child属性ではなく、脆弱な[row-index]セレクターを生成する - 実行間の競合を引き起こすハードコードされたテスト データを使用する
カスタム手順では、ツールキットの API とパターンに対して常に使用可能な参照を AI に提供することで、この問題を解決します。
クロード (アントロピック) 用の CLAUDE.md
Claude Code は、リポジトリ ルート (およびサブディレクトリ) で CLAUDE.md ファイルを読み取ります。
packages/e2e-tests/CLAUDE.mdを作成します。
# Power Platform Playwright Tests
## Project structure
- Toolkit: `power-platform-playwright-toolkit` (local package)
- Tests: `packages/e2e-tests/tests/`
- Page objects: `packages/e2e-tests/pages/`
- Auth state: `packages/e2e-tests/.playwright-ms-auth/`
## Key conventions
### Always use AppProvider to launch apps
```typescript
const app = new AppProvider(page, context);
await app.launch({
app: 'App Name',
type: AppType.Canvas, // or AppType.ModelDriven
mode: AppLaunchMode.Play,
skipMakerPortal: true,
directUrl: process.env.CANVAS_APP_URL!,
});
キャンバス アプリ: 常に iframe にスコープを設定する
キャンバス アプリは入れ子になった iframe 内でレンダリングされるため、コントロールを確実に見つけるには、すべてのロケーター クエリをそのフレームにスコープする必要があります。
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
キャンバス アプリ: ギャラリー waitFor に 60 秒のタイムアウトを使用する
キャンバス アプリのギャラリー コントロールはレンダリングに時間がかかる可能性があるため、ギャラリー項目が表示されるのを待つ間は 60 秒のタイムアウトを使用します。
await canvasFrame.locator('[data-control-part="gallery-item"]').first()
.waitFor({ state: 'visible', timeout: 60000 });
モデル駆動型アプリ: GridComponent と FormComponent を使用する
モデル駆動型アプリは、ヘルパー ページ オブジェクトを介して直接操作できる組み込みのグリッドコンポーネントとフォーム コンポーネントを公開します。
const mda = app.getModelDrivenAppPage();
await mda.grid.filterByKeyword('ORD-001');
await mda.grid.waitForGridLoad();
await mda.grid.openRecord({ rowNumber: 0 });
await mda.form.getAttribute('nwind_ordernumber');
await mda.form.save();
競合を回避するために一意のテスト データを使用する
並列テストの実行が互いに競合しないように、テスト データにタイムスタンプまたは一意識別子を追加します。
const accountName = `Test Account ${Date.now()}`;
モデル駆動型アプリ グリッド: nth-child ではなく [行インデックス] を使用する
GridComponentはこれを内部で処理します。nth-childセレクターを直接記述しないでください。
Auth: storageState に getStorageStatePath を使用する
import { getStorageStatePath } from 'power-platform-playwright-toolkit';
test.use({ storageState: getStorageStatePath(process.env.MS_AUTH_EMAIL!) });
インポート
常にツールキット パッケージからインポートします。
import {
AppProvider,
AppType,
AppLaunchMode,
buildCanvasAppUrlFromEnv,
getStorageStatePath,
} from 'power-platform-playwright-toolkit';
高度な Claude Code の構成
セッションごとのコンテキストの場合は、 /init スラッシュ コマンドを使用してプロジェクト コンテキストを読み込むか、リポジトリ ルートの .claude/ の下にエージェント レベルのメモリを追加します。
.claude/
settings.json # MCP server config, permissions
commands/ # Custom slash commands
.claude/settings.json例:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp"]
}
},
"permissions": {
"allow": [
"Bash(npx playwright *)",
"Bash(npm run auth*)"
]
}
}
.github/copilot-instructions.md for GitHub Copilot
GitHub Copilotはリポジトリの.github/copilot-instructions.mdを読み取ります。 次のファイルを作成します。
# Copilot instructions for Power Platform Playwright tests
## Tech stack
- Playwright test runner with TypeScript
- Custom toolkit: `power-platform-playwright-toolkit`
- Rush monorepo (use `node common/scripts/install-run-rush.js build` not `npm run build`)
## Test file conventions
- Tests live in `packages/e2e-tests/tests/`
- Page objects live in `packages/e2e-tests/pages/`
- Import from `'power-platform-playwright-toolkit'`, not from relative paths
## App launch
Always use [`AppProvider`](api-reference.md#appprovider) with `skipMakerPortal: true` and `directUrl`.
## Canvas apps
- Scope all locators to `page.frameLocator('iframe[name="fullscreen-app-host"]')`
- Use 60 second timeouts for gallery `waitFor` calls
- Identify controls via `data-control-name` attribute (inspect in DevTools)
## Model-driven apps
- Use `app.getModelDrivenAppPage()` to get [`ModelDrivenAppPage`](api-reference.md#modeldrivenapppage)
- Use `mda.grid.*` for grid interactions, `mda.form.*` for form interactions
- After `filterByKeyword`, always call `mda.grid.waitForGridLoad()`
## Test data
- Always use unique names: `\`Test ${Date.now()}\``
- Never hardcode strings that could clash across parallel test runs
カーソルとウィンドサーフの「agents.md」
カーソルは .cursorrules を読み取り、ウィンドサーフィンはリポジトリのルートで .windsurfrules を読み取ります。 同じ内容のファイルを作成します。
# Power Platform Playwright test conventions
You are helping write end-to-end tests for Power Platform apps using Playwright and a custom toolkit.
## Framework
- Test runner: Playwright (`@playwright/test`)
- Toolkit: `power-platform-playwright-toolkit` (workspace package)
- App types: Canvas, ModelDriven, CustomPage (canvas embedded in MDA)
## Critical rules
1. **Canvas apps always use an iframe**
- Frame: `page.frameLocator('iframe[name="fullscreen-app-host"]')`
- All canvas locators must be scoped to this frame
2. **Gallery timeouts must be 60 seconds**
- Dataverse galleries take 30–60s to load
- Use `waitFor({ state: 'visible', timeout: 60000 })`
3. **Model-driven grids use GridComponent**
- Never use raw `page.locator('[role="row"]')` for grid rows
- Use `mda.grid.filterByKeyword()`, `mda.grid.getCellValue()`, `mda.grid.openRecord()`
4. **Always use unique test data**
- Pattern: `` `Test Name ${Date.now()}` ``
5. **Import only from the toolkit**
- `import { AppProvider, AppType, AppLaunchMode } from 'power-platform-playwright-toolkit'`
プレイライト テスト エージェント
プレイライト テスト エージェント は、テストを自律的に実行および修正できる、実行時間の長い AI プロセスです。 カスタム命令をシステム コンテキストとして渡して、ツールキットを理解するようにエージェントを構成します。
// playwright.config.ts
import { defineConfig } from '@playwright/test';
export default defineConfig({
// ...
use: {
// Agent context: pass custom instructions to the test agent
agentContext: {
systemPrompt: `
You are testing Power Platform apps using the power-platform-playwright-toolkit.
Canvas apps render in iframe[name="fullscreen-app-host"].
Always scope canvas locators to the frame.
Gallery waitFor timeouts should be 60000ms.
Use mda.grid.* and mda.form.* for model-driven apps.
`,
},
},
});
注
プレイライト テスト エージェントは、Playwright 1.50 以降で利用できます。 この機能は試験段階です。 最新の API については 、playwright.dev/docs/test-agents を参照してください。
カスタム手順に含める内容
このプロジェクトの適切なカスタム命令ファイルには、次の内容が含まれます。
| トピック | ドキュメントの内容 |
|---|---|
| プロジェクト構造 | テストのライブ場所、ページ オブジェクトのライブ場所 |
| アプリの起動 |
AppProvider
skipMakerPortalとdirectUrlのパターン |
| キャンバス アプリ | Iframe セレクター、コントロール名の検出、ギャラリーのタイムアウト |
| モデル駆動型アプリ |
ModelDrivenAppPage 、 GridComponent 、 FormComponent メソッド |
| Auth | ストレージ状態ファイルの名前付けと getStorageStatePath |
| テスト データ | 一意性規則 (Date.now()) |
| インポート | ツールキット パッケージ名、インポートする内容 |
| 避ける | 未加工の n 番目の子セレクター、ハードコーディングされたテストデータ、waitFor がありません |
手順を検証する
AI に次の操作を依頼して、カスタム手順をテストします。
- キャンバス ギャラリーのテストを作成する: iframe と 60s のタイムアウトを使用しているかどうかを確認する
-
モデル駆動型 CRUD テストを記述する:
GridComponentメソッドを使用して検証する -
コード生成の記録を書き換える:
AppProviderを使用していることを確認する
AI がツールキット コードではなく生の Playwright コードを生成する場合は、命令ファイルにさらに明示的な規則を追加します。