Playwright Infrastructure in the PPUX Repository#
This chapter explores the Playwright testing infrastructure used in the Power Platform UX (PPUX) repository, providing a comprehensive understanding of enterprise-level test automation setup.
Repository Overview#
The PPUX repository uses a monorepo approach to manage multiple applications and shared packages:
power-platform-ux/
├── apps/ # Power Platform applications
│ ├── make-powerapps-com/
│ ├── admin-powerplatform-microsoft-com/
│ └── [other-power-platform-apps]/
├── packages/ # Shared npm packages
│ ├── playwright-integration-tests/ # Centralized test framework
│ └── [other-packages]/
└── package.json # Root configuration
This structure allows for:
Centralized testing infrastructure
Shared components and utilities
Independent app development with shared resources
Standardized testing approaches across teams
For a detailed breakdown of the recommended folder structure for Playwright tests, see the Folder Structure page.
Playwright Configuration#
The PPUX repository uses a comprehensive playwright.config.ts file to control test execution. This configuration provides flexibility through environment variables and utility functions. For detailed information on how the configuration works and how to customize it, see the Playwright Configuration page.
Playwright Integration Tests Package#
The playwright-integration-tests package serves as the central testing framework for all Power Platform applications. Let’s examine its structure:
playwright-integration-tests/
├── src/
│ ├── config/ # Test configurations
│ │ └── config.json
│ │
│ ├── apps/ # Custom test fixtures for different apps
│ │ └── <app_name>/ # App-specific test module
│ │ ├── pages/ # Page Object Models (POMs)
│ │ ├── tests/ # Test cases for the app
│ │ └── utils/ # App-specific utilities
│ │ ├── fixtures.ts # Fixtures like login, environment setup
│ │ └── testUtils.ts # Helpers used across tests
│ │
├── playwright.config.ts # Playwright config (projects, baseURL, tracing, etc.)
├── package.json # Dependencies and scripts
└── README.md # Setup, usage, and contribution guidelines
Key Configuration Files#
The package.json file defines essential scripts for the testing workflow:
{
"scripts": {
"record": "playwright codegen",
"login-tms": "node ./src/loginTMS.mjs",
"int-test": "playwright test",
"int-test:config": "playwright test --config=./playwright.config.ts",
"show-trace": "playwright show-trace"
}
}
These scripts enable:
Recording test interactions with Playwright Codegen
Authentication with Test Management System (TMS)
Running integration tests with different configurations
Debugging test failures with trace viewer
Core Testing Dependencies#
The package utilizes several specialized Playwright extensions:
{
"dependencies": {
"@axe-core/playwright": "4.9.1",
"@paeng/playwright-auth": "2.0.2",
"@paeng/playwright-solution": "3.3.3",
"@paeng/playwright-teams-info": "0.36.0",
"@paeng/playwright-test-reporter": "1.3.18",
"@paeng/playwright-tms": "1.4.10",
"@playwright/test": "1.52.0"
}
}
Each package serves a specific purpose:
@axe-core/playwright: Accessibility testing integration@paeng/playwright-auth: Authentication helpers for Microsoft identity@paeng/playwright-solution: Solution deployment testing utilities@paeng/playwright-teams-info: Team ownership tracking for tests@paeng/playwright-test-reporter: Custom enterprise reporting@paeng/playwright-tms: Test Management System integration
The Heart of Testing: playwright.config.ts#
The playwright.config.ts file configures the testing environment:
export default defineConfig<AuthOptions>({
name: "Playwright Integration Tests",
globalSetup: require.resolve("./src/globals/global-setup"),
globalTeardown: require.resolve("./src/globals/global-teardown"),
use: {
authDir: path.join(__dirname, "./playwright/.auth/"),
browserName: ProcessEnvironmentConfig().browserType as BrowserTypes,
baseURL: getBaseUrl(),
headless: ProcessEnvironmentConfig().headless,
viewport: { width: 1920, height: 1080 },
ignoreHTTPSErrors: true,
acceptDownloads: true,
permissions: ["clipboard-read", "clipboard-write"],
actionTimeout: TimeOut.OneMinuteTimeOut,
navigationTimeout: TimeOut.OneMinuteTimeOut,
storageState:
!isDevEnvironment() && !isTMS ? storageStatePath() : undefined,
},
testDir: ProcessEnvironmentConfig().testDirectory,
timeout: ProcessEnvironmentConfig().testTimeout,
workers: ProcessEnvironmentConfig().workers,
retries: ProcessEnvironmentConfig().retries,
});
Key configuration aspects include:
Global setup and teardown hooks for test environment preparation
Authentication directory for storing credentials
Dynamic base URL selection based on environment
Viewport standardization for consistent testing
Permission management for clipboard operations
Timeout configurations to prevent flaky tests
Storage state management for session persistence
Built-in Failure Analysis#
The configuration includes comprehensive failure analysis tools:
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure',
viewport: { width: 1920, height: 1080 },
actionTimeout: TimeOut.OneMinuteTimeOut,
navigationTimeout: TimeOut.OneMinuteTimeOut,
}
This ensures:
Screenshots capture the exact state when tests fail
Video recordings show the sequence leading to failure
Trace files provide detailed technical information for debugging
Consistent viewport dimensions eliminate responsive design issues
Adequate timeouts accommodate application performance variations
Enterprise Test Reporting#
The PPUX repository implements advanced test reporting capabilities:
reporter: [
[
"@paeng/playwright-test-reporter",
{
testRunName: ProcessEnvironmentConfig().playwrightTestRunName,
testDirectory: ProcessEnvironmentConfig().testDirectory,
sendEmail: ProcessEnvironmentConfig().sendEmailNotification,
sendFailureEmail: ProcessEnvironmentConfig().sendFailureEmailNotification,
emailHandlebarPath: handlebarPath,
pushToTelemetry: ProcessEnvironmentConfig().pushFailuresToTelemetry,
createBug: ProcessEnvironmentConfig().createBugForFailures,
fireIcm: ProcessEnvironmentConfig().fireIcmForFailures,
},
],
];
This custom reporter provides:
Email notifications for test results and failures
Telemetry data collection for performance analysis
Automatic bug creation in tracking systems
Incident Management (ICM) integration for critical failures
Customizable email templates using Handlebars
Page Object Model Implementation#
The PPUX repository follows the Page Object Model (POM) pattern to create maintainable tests:
// Example Page Object for the PowerApps studio
export class StudioPage {
readonly page: Page;
readonly headerControls: Locator;
readonly saveButton: Locator;
readonly previewButton: Locator;
constructor(page: Page) {
this.page = page;
this.headerControls = page.locator(".studio-header-controls");
this.saveButton = page.getByRole("button", { name: "Save" });
this.previewButton = page.getByRole("button", { name: "Preview" });
}
async saveApp() {
await this.saveButton.click();
await this.page.waitForSelector(".save-success-notification", {
state: "visible",
});
}
async previewApp() {
await this.previewButton.click();
await this.page.waitForLoadState("networkidle");
}
}
The POM pattern:
Encapsulates page elements and interactions
Improves test readability and maintenance
Simplifies test authoring through reusable components
Provides a clear separation between test logic and page interactions
Test Fixtures for Application State#
Custom fixtures handle complex test prerequisites:
// Custom fixture for logged-in PowerApps session
const powerAppsTest = test.extend<PowerAppsFixtures>({
appStudioPage: async ({ page }, use) => {
// Authenticate and navigate to app studio
await page.goto("/");
await login(page);
await page.goto("/studio");
await page.waitForLoadState("networkidle");
// Create a new page object and pass it to the test
const studioPage = new StudioPage(page);
await use(studioPage);
},
});
These fixtures enable:
Pre-authenticated test sessions
Standard app states for testing
Reduced test setup duplication
Consistent starting points for different test scenarios
Integration Test Wrapper#
The PPUX repository uses a custom integrationTest wrapper function to organize tests with specific configurations. This wrapper is so important that it has its own dedicated page in this book.
The wrapper function provides:
Consistent test organization
Environment-specific configurations
Team ownership tracking
Test Management System (TMS) integration
Test Tenant Management System (TMS)#
For managing complex test environments and user scenarios, the PPUX repository integrates with the Test Tenant Management System (TMS). This system is so important for enterprise testing that we’ve created a dedicated page about TMS integration.
TMS provides:
Centralized management of test environments and scenarios
User management for different testing roles
Authentication automation
Access to scenario details in tests
Test Environment Configuration#
The PPUX repository uses a robust environment configuration system to manage URLs and settings for different environments and geographical regions. This configuration is managed through the config.json file and is essential for running tests across multiple environments. Learn more in our test environments configuration guide.
Environment-Specific Configuration#
The PPUX repo uses a dynamic configuration approach:
function ProcessEnvironmentConfig() {
return {
browserType: process.env.BROWSER || "chromium",
headless: process.env.HEADLESS !== "false",
testDirectory: process.env.TEST_DIR || "./src/apps/**/*.spec.ts",
testTimeout: parseInt(process.env.TIMEOUT || "60000"),
workers: process.env.WORKERS ? parseInt(process.env.WORKERS) : undefined,
retries: process.env.CI ? 2 : 0,
environment: process.env.ENV || "dev",
// Additional environment variables...
};
}
This allows:
Dynamic configuration based on environment variables
Different settings for CI/CD versus local development
Customizable test execution based on context
Simplified command-line overrides for specific test runs
Key Takeaways#
The PPUX repository’s Playwright infrastructure demonstrates enterprise-level test automation with:
Centralized Framework: Shared testing resources across multiple applications
Structured Organization: Clear separation of page objects, tests, and utilities
Advanced Reporting: Enterprise-grade reporting with notifications and bug tracking
Comprehensive Failure Analysis: Multi-faceted approach to debugging test failures
Environment Flexibility: Dynamic configuration for different testing contexts
Authentication Management: Specialized handling of Microsoft identity services
This approach can be adapted to other enterprise testing needs by implementing similar patterns and practices.