Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Las aplicaciones de lienzo se ejecutan dentro de un iframe dentro del reproductor de Power Apps. En esta guía se explica cómo iniciar una aplicación canvas, definir el ámbito de los selectores al marco correcto e interactuar con los controles utilizando atributos de data-control-name.
Cómo funcionan las pruebas de aplicaciones canvas
Cuando una aplicación de lienzo se carga en modo de reproducción, el tiempo de ejecución hospeda la aplicación dentro de un iframe.
iframe[name="fullscreen-app-host"]
Todos los controles dentro de la aplicación tienen un atributo data-control-name que coincide con el nombre de control establecido en Power Apps Studio. Los elementos de la galería tienen data-control-part="gallery-item".
Antes de interactuar con los controles, limite todos los localizadores a este marco:
const canvasFrame = page.frameLocator('iframe[name="fullscreen-app-host"]');
Lanzar una aplicación de lienzo
Use AppProvider para iniciar la aplicación y obtener el CanvasAppPage objeto :
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,
});
});
Sugerencia
Al establecer skipMakerPortal: true y proporcionar una directUrl, se ahorran de 10 a 20 segundos por prueba al omitir la navegación de Power Apps.
Espere a que la aplicación se cargue.
Después del inicio, espere a que aparezca un control conocido antes de interactuar:
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 });
Nota:
Las aplicaciones de lienzo respaldadas por Dataverse pueden tardar entre 30 y 60 segundos en cargar datos en una galería. Use un tiempo de espera de 60 segundos para los selectores de galería.
Interacción con controles
En los ejemplos siguientes se muestra cómo interactuar con controles comunes de la aplicación de tipo canvas mediante localizadores con alcance de marco.
Haga clic en un botón
Busque un botón por su data-control-name atributo, espere a que esté visible y, a continuación, haga clic en él.
const addButton = canvasFrame.locator('[data-control-name="icon3"]');
await addButton.waitFor({ state: 'visible', timeout: 10000 });
await addButton.click();
Rellenar una entrada de texto
Utiliza el fill() método para establecer el valor de una entrada de texto dirigiéndolo por su aria-label.
const orderNumberInput = canvasFrame.locator('input[aria-label="Order Number"]');
await orderNumberInput.fill('ORD-12345');
Selección de un elemento de la galería
Filtre los elementos de la galería por su contenido de texto mostrado para buscar y hacer clic en un registro específico.
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();
Recuento de elementos de la galería
Use el count() método para comprobar que la galería contiene el número esperado de elementos.
const galleryItems = canvasFrame.locator('[data-control-name="Gallery1"] [data-control-part="gallery-item"]');
const count = await galleryItems.count();
expect(count).toBeGreaterThan(0);
Creación de un objeto de página para la aplicación de lienzo
Para mantener el mantenimiento, encapsula selectores y acciones en una clase Page Object:
// 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();
}
}
Ejemplo completo de prueba CRUD para apps de canvas
En este ejemplo se combina el inicio de la aplicación, la comprobación de la galería y la interacción de formularios en un conjunto de pruebas completo.
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();
});
});
Detección de nombres de control en aplicaciones de lienzo
Para buscar los data-control-name valores en la aplicación:
- Abra la aplicación en modo de reproducción en un explorador.
- Abra las herramientas de desarrollo del explorador (F12).
- Utiliza el Inspector para pasar el cursor por encima de los controles y para buscar atributos
data-control-name.
Como alternativa, use el servidor MCP de Playwright para pedir a un asistente de IA que inspeccione el DOM y genere selectores automáticamente. Consulte Pruebas asistidas por IA.
Pasos siguientes
- Probar aplicaciones controladas por modelos
- Prueba de páginas personalizadas
- Modelo de objetos de página