Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les applications canevas s’exécutent à l’intérieur d’un iframe au sein du lecteur Power Apps. Ce guide explique comment lancer une application de type canevas, développer vos sélecteurs au cadre approprié et interagir avec les contrôles à l'aide des attributs data-control-name.
Fonctionnement des tests des applications canevas
Lorsqu’une application canevas se charge en mode lecture, l’environnement d'exécution héberge l’application dans un iframe.
iframe[name="fullscreen-app-host"]
Tous les contrôles à l’intérieur de l’application ont un attribut data-control-name qui correspond au nom de contrôle que vous avez défini dans Power Apps Studio. Les éléments de la galerie ont data-control-part="gallery-item".
Vous restreignez tous les localisateurs à ce cadre avant d’interagir avec les commandes.
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
Ouvrir une application Canvas
Permet AppProvider de lancer l’application et d’obtenir l’objet CanvasAppPage :
import { test, expect } from '@playwright/test';
import {
AppProvider,
AppType,
AppLaunchMode,
buildCanvasAppUrlFromEnv,
} from 'power-platform-playwright-toolkit';
const CANVAS_APP_URL = buildCanvasAppUrlFromEnv();
test.beforeEach(async ({ page, context }) => {
const app = new AppProvider(page, context);
await app.launch({
app: 'Northwind Orders',
type: AppType.Canvas,
mode: AppLaunchMode.Play,
skipMakerPortal: true, // bypasses Power Apps navigation
directUrl: CANVAS_APP_URL,
});
});
Conseil / Astuce
Définir skipMakerPortal: true et fournir un directUrl économise 10 à 20 secondes en contournant la navigation Power Apps.
Attendez que l’application se charge
Après le lancement, attendez qu’un contrôle connu apparaisse avant d’interagir :
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
// Wait for gallery to confirm the app is loaded and data is present
await canvasFrame
.locator('[data-control-name="Gallery1"] [data-control-part="gallery-item"]')
.first()
.waitFor({ state: 'visible', timeout: 60000 });
Note
Les applications Canvas soutenues par Dataverse peuvent prendre 30 à 60 secondes pour charger des données dans une galerie. Utilisez un délai d’expiration de 60 secondes pour les sélecteurs de galerie.
Interagir avec les contrôles
Les exemples suivants montrent comment interagir avec les contrôles d'application canevas courants à l'aide de localisateurs à portée de cadre.
Cliquez sur un bouton
Recherchez un bouton par son data-control-name attribut, attendez qu’il soit visible, puis cliquez dessus.
const addButton = canvasFrame.locator('[data-control-name="icon3"]');
await addButton.waitFor({ state: 'visible', timeout: 10000 });
await addButton.click();
Remplir une entrée de texte
Utilisez la fill() méthode pour définir la valeur d’une entrée de texte, en la ciblant par son aria-label.
const orderNumberInput = canvasFrame.locator('input[aria-label="Order Number"]');
await orderNumberInput.fill('ORD-12345');
Sélectionner un élément de galerie
Filtrez les éléments de la galerie en fonction de leur contenu texte affiché pour rechercher et cliquer sur un enregistrement spécifique.
const galleryItem = canvasFrame
.locator('[data-control-part="gallery-item"]')
.filter({ has: canvasFrame.locator('[data-control-name="Title1"]').getByText('Order 001') });
await galleryItem.waitFor({ state: 'visible' });
await galleryItem.click();
Compter les éléments de la galerie
Utilisez la count() méthode pour vérifier que la galerie contient le nombre attendu d’éléments.
const galleryItems = canvasFrame.locator('[data-control-name="Gallery1"] [data-control-part="gallery-item"]');
const count = await galleryItems.count();
expect(count).toBeGreaterThan(0);
Créer un objet de page pour votre application canevas
Pour une facilité de maintenance, encapsulez les sélecteurs et les actions dans une classe Objet Page :
// pages/my-app/MyCanvasAppPage.ts
import { Page, FrameLocator } from '@playwright/test';
export class MyCanvasAppPage {
private readonly frame: FrameLocator;
constructor(private readonly page: Page) {
this.frame = page.frameLocator('iframe[name="fullscreen-app-host"]');
}
get addButton() {
return this.frame.locator('[data-control-name="AddButton"]');
}
get gallery() {
return this.frame.locator('[data-control-name="Gallery1"]');
}
async waitForLoad(): Promise<void> {
await this.gallery
.locator('[data-control-part="gallery-item"]')
.first()
.waitFor({ state: 'visible', timeout: 60000 });
}
async clickAdd(): Promise<void> {
await this.addButton.click();
}
async getItemCount(): Promise<number> {
return this.gallery.locator('[data-control-part="gallery-item"]').count();
}
}
Exemple de test CRUD complet pour les applications de canevas
Cet exemple combine le lancement de l’application, la vérification de la galerie et l’interaction de formulaire dans une suite de tests complète.
import { test, expect, FrameLocator } from '@playwright/test';
import { AppProvider, AppType, AppLaunchMode, buildCanvasAppUrlFromEnv } from 'power-platform-playwright-toolkit';
const CANVAS_APP_URL = buildCanvasAppUrlFromEnv();
test.describe('Canvas App - Orders', () => {
let canvasFrame: FrameLocator;
test.beforeEach(async ({ page, context }) => {
const app = new AppProvider(page, context);
await app.launch({
app: 'Orders App',
type: AppType.Canvas,
mode: AppLaunchMode.Play,
skipMakerPortal: true,
directUrl: CANVAS_APP_URL,
});
canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
await canvasFrame
.locator('[data-control-part="gallery-item"]')
.first()
.waitFor({ state: 'visible', timeout: 60000 });
});
test('should display orders in gallery', async () => {
const count = await canvasFrame
.locator('[data-control-part="gallery-item"]')
.count();
expect(count).toBeGreaterThan(0);
});
test('should click Add and show form', async ({ page }) => {
await canvasFrame.locator('[data-control-name="icon3"]').click();
await page.waitForTimeout(2000);
const input = canvasFrame.locator('input[type="text"]').first();
await expect(input).toBeVisible();
});
});
Découvrir les noms de contrôle dans les applications de canevas
Pour rechercher les data-control-name valeurs dans votre application :
- Ouvrez l’application en mode lecture dans un navigateur.
- Ouvrez les outils de développement du navigateur (F12).
- Utilisez l’inspecteur pour pointer sur les contrôles et rechercher
data-control-namedes attributs.
Vous pouvez également utiliser le serveur MCP playwright pour demander à un assistant IA d’inspecter le DOM et de générer des sélecteurs pour vous. Consultez les tests assistés par l’IA.
Étapes suivantes
- Tester des applications basées sur des modèles
- Tester des pages personnalisées
- Modèle d'objet de page