Usage Patterns
This page explains when and how to use each pattern in the toolkit.
Tip: Not sure which pattern to use? Check the Decision Tree at the bottom of this page.
Pattern 1: AppProvider for Testing (Recommended)
Best for: Testing existing apps by ID or name
Code Example
import { AppProvider, AppType, AppLaunchMode } from 'playwright-power-platform-toolkit';
test('Test with AppProvider', async ({ page }) => {
const provider = new AppProvider(page);
// Launch app by ID (fastest)
await provider.launch({
app: { id: 'app-id' },
type: AppType.Canvas,
mode: AppLaunchMode.Play
});
// Interact with controls
await provider.click({ name: 'Submit' });
await provider.fill({ name: 'Email' }, 'test@example.com');
// Assert results
await provider.assertVisible({ name: 'Success' });
await provider.assertText({ name: 'Status' }, 'Submitted');
// Clean up
await provider.close();
});When to Use
- Testing existing apps
- You have the app ID or name
- You want the simplest API
- Running tests in CI/CD
Advantages
- Simplest API
- Automatic factory management
- State tracking for multiple apps
- Built-in assertions
Pattern 2: Factory for Advanced Scenarios
Best for: Custom launcher logic and advanced control
Code Example
import { AppLauncherFactory, AppType, AppLaunchMode } from 'playwright-power-platform-toolkit';
test('Test with Factory', async ({ page }) => {
// Get launcher directly
const launcher = AppLauncherFactory.getCanvasLauncher(page);
// Launch app
await launcher.launchById('app-id', 'https://make.powerapps.com', AppLaunchMode.Play);
// Direct control interactions
await launcher.clickControl({ name: 'Submit' });
await launcher.fillControl({ name: 'Email' }, 'test@example.com');
// Check state
const isReady = launcher.isAppReady();
const appId = launcher.getAppId();
// Clean up
await launcher.closeApp();
});When to Use
- Need direct launcher access
- Custom wrapper around launcher
- Advanced caching scenarios
- Performance-critical operations
Advantages
- Direct launcher access
- Manual cache control
- Lower-level control
- Reusable launcher instances
Pattern 3: PowerAppsPage for App Creation
Best for: Creating new apps and studio operations
Code Example
import { PowerAppsPage } from 'playwright-power-platform-toolkit';
test('Create and test app', async ({ page }) => {
const powerApps = new PowerAppsPage(page);
// Navigate to apps page
await powerApps.navigateToApps();
// Create Canvas app
await powerApps.canvas.createBlankCanvasApp('TestApp');
await powerApps.canvas.addButton();
await powerApps.canvas.saveApp();
await powerApps.canvas.publishApp();
// Create Model-Driven app
await powerApps.modelDriven.createBlankModelDrivenApp('SalesApp');
await powerApps.modelDriven.addNavigationGroup('Sales');
await powerApps.modelDriven.publishApp();
});When to Use
- Creating new apps
- Studio operations
- App management (delete, publish)
- Navigation and search
Advantages
- App creation capabilities
- Studio automation
- Navigation helpers
- Unified Power Apps Portal access
Component Interaction Matrix
State Management
AppProvider State Lifecycle
Launcher Caching Flow
Decision Tree
Need help choosing? Follow this decision tree to find the right pattern.
Quick Decision Guide
Need to test existing app by ID? → Use AppProvider ✅
Need to test existing app by name? → Use AppProvider ✅
Need to create new app? → Use PowerAppsPage ✅
Need custom launcher logic? → Use AppLauncherFactory ✅
Need maximum control? → Use Page Objects directly ✅Next Steps
- Sequence Diagrams - See detailed interaction flows
- Core Components - Understand the class structure
- Extending the Toolkit - Add new app types
- Quick Reference - Quick reference card