Skip to content

Enable PowerApps MDA Gallery Controls for Custom Pages #610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 56 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
6fd265f
Initial commit of sample
Grant-Archibald-MS Mar 6, 2025
0fecf39
Merge remote-tracking branch upstream/integration
Grant-Archibald-MS Mar 6, 2025
b2f2314
Update to preview
Grant-Archibald-MS Mar 6, 2025
1c229cd
Update to include different page types
Grant-Archibald-MS Mar 7, 2025
a658b6b
Documentation update
Grant-Archibald-MS Mar 8, 2025
473d3c1
Branch update
Grant-Archibald-MS Mar 8, 2025
be5272c
script reference update
Grant-Archibald-MS Mar 13, 2025
173ad1e
Redierct update
Grant-Archibald-MS Mar 13, 2025
06195e4
Link update
Grant-Archibald-MS Mar 13, 2025
7352ad1
Validation update
Grant-Archibald-MS Mar 13, 2025
3dc8d1f
Update Preview namespace
Grant-Archibald-MS Mar 13, 2025
e7dc0fa
Remove mermaid
Grant-Archibald-MS Mar 14, 2025
4b28f05
Initial template
Grant-Archibald-MS Mar 14, 2025
ffa38a4
Merge integration' visualcompare-568
Grant-Archibald-MS Mar 14, 2025
4b456ed
WIP implementation
Grant-Archibald-MS Mar 15, 2025
bcb2f59
Review edit
Grant-Archibald-MS Mar 15, 2025
0ffb58e
Merge branch copilotstudio-560
Grant-Archibald-MS Mar 15, 2025
6c8071e
Merge branch grant-archibald-ms/visualcompare-568
Grant-Archibald-MS Mar 15, 2025
5bff8cb
Merge branch 'grant-archibald-ms/new-docs'
Grant-Archibald-MS Mar 16, 2025
1ccb88d
Update VisualCompare
Grant-Archibald-MS Mar 17, 2025
eb30405
Dcos update
Grant-Archibald-MS Mar 17, 2025
943d496
Adding dataverse integration tests
Grant-Archibald-MS Mar 23, 2025
1875fdd
WIP Test Settings
Grant-Archibald-MS Mar 24, 2025
8b61929
Update for Preview.AIEvaluate
Grant-Archibald-MS Mar 26, 2025
a33c759
Package update
Grant-Archibald-MS Mar 26, 2025
07ae485
package update
Grant-Archibald-MS Mar 27, 2025
d57047b
Ading Second AI user case
Grant-Archibald-MS Mar 27, 2025
6726882
Adding Power Fx function
Grant-Archibald-MS Mar 30, 2025
83da9e4
Adding Power Fx test functions and UDT
Grant-Archibald-MS Apr 1, 2025
075154d
Merge branch 'integration'
Grant-Archibald-MS Apr 1, 2025
4f0f039
Date tests
Grant-Archibald-MS Apr 1, 2025
c27f405
Sample update
Grant-Archibald-MS Apr 2, 2025
b5d9ff2
Merge changes
Grant-Archibald-MS Apr 2, 2025
6b4c18c
Update for multi page test
Grant-Archibald-MS Apr 3, 2025
69206b2
Test Set data
Grant-Archibald-MS Apr 3, 2025
6fcad26
Adding test agent setup
Grant-Archibald-MS Apr 4, 2025
714a8a7
Review edit and report
Grant-Archibald-MS Apr 4, 2025
0949ee3
Update to msedge
Grant-Archibald-MS Apr 4, 2025
bea4326
Review edits
Grant-Archibald-MS Apr 4, 2025
714b463
Review edits
Grant-Archibald-MS Apr 4, 2025
bd6c0cb
Static context example
Grant-Archibald-MS Apr 4, 2025
e1b1591
Get appId from WebApi
Grant-Archibald-MS Apr 4, 2025
b857488
Security note update
Grant-Archibald-MS Apr 4, 2025
0e5a17a
Report update
Grant-Archibald-MS Apr 5, 2025
d915ed5
Work in progress agent details tests
Grant-Archibald-MS Apr 7, 2025
1cfa018
Review edit
Grant-Archibald-MS Apr 7, 2025
bb962d5
Review edit
Grant-Archibald-MS Apr 7, 2025
9efdf23
New tests
Grant-Archibald-MS Apr 7, 2025
c1bbb5c
Initial Changes for Gallery and Classic Gallery controls
v-nabalasubr Apr 8, 2025
b20284f
Review update
Grant-Archibald-MS Apr 9, 2025
e55a91e
Addded changes for handling child control inside gallery
v-nabalasubr Apr 16, 2025
7578d0f
merging main into Gallery changes
v-nabalasubr May 8, 2025
d09c423
Remove Unnecessary Gallery Changes and adding ReadMe document
v-nabalasubr May 8, 2025
4a4f675
Fixing whitespace issue
v-nabalasubr May 8, 2025
ba58e27
Added changes for fixing Unit test case failure
v-nabalasubr May 16, 2025
ad605ec
Fixing white space issue
v-nabalasubr May 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
58 changes: 58 additions & 0 deletions samples/mdagallerycontrols/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Overview

This Power Apps Test Engine sample illustrates how to assert and interact with both modern and classic gallery controls in a model-driven application form. It covers Horizontal, Vertical, and Flexible height Gallery controls.

## Usage

1. **Build the Test Engine Solution**
Ensure the Power Apps Test Engine solution is built and ready to be executed.

2. **Get the URL of the Model-Driven Application Form**
Acquire the URL of the specific model-driven application form that you want to test.

3. **Modify the verticalgallery_testPlan.fx**
Update the YAML file to assert expected values of the Horizontal, Vertical and Flexible height gallery controls.

> **Note:** The controls are referenced using the [logical name](https://learn.microsoft.com/power-apps/developer/data-platform/entity-metadata#table-names).
4. **Update the Domain URL for Your Model-Driven Application**

| URL Part | Description |
| ---------------------------------------------- | ------------------------------------------------------- |
| `appid=a1234567-cccc-44444-9999-a123456789123` | The unique identifier of your model-driven application. |
| `etn=` | The name of the entity being validated. |
| `id=26bafa27-ca7d-ee11-8179-0022482a91f4` | The unique identifier of the record being edited. |
| `pagetype=custom` | The type of page to open. |
| `UserAuth=storagestate` | The type of user authentication to use. |
| `UseStaticContext=True` | A flag indicating the use of a static context. |

5. **Execute the Test for Custom Page**
Please replace the example URLs with your organization's URL.

**Command for Modern Vertical Gallery Control:**
```pwsh
cd bin\Debug\PowerAppsEngine
dotnet PowerAppsTestEngine.dll -i ..\..\..\samples\mdagallerycontrols\formtablecontroltestplan.fx.yaml -e 00000000-0000-0000-0000-11112223333 -t 11112222-3333-4444-5555-666677778888 -u browser -p mda -d "https://orgfc708206.crm.dynamics.com/main.aspx?appid=65cdcc8e-54bc-ef11-a72f-000d3a12b0cb&pagetype=custom&name=cr693_mdagallerycontrol_846d9"
Copy link
Contributor

@snamilikonda snamilikonda Aug 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

replace -p with full name for all instances in all files

```

**Command for Modern Horizontal Gallery Control:**
```pwsh
cd bin\Debug\PowerAppsEngine
dotnet PowerAppsTestEngine.dll -i ..\..\..\samples\mdagallerycontrols\horizontalgallery_testPlan.fx.yaml -e 00000000-0000-0000-0000-11112223333 -t 11112222-3333-4444-5555-666677778888 -u browser -p mda -d "https://orgfc708206.crm.dynamics.com/main.aspx?appid=65cdcc8e-54bc-ef11-a72f-000d3a12b0cb&pagetype=custom&name=cr7d6_productdetails_6f49a"
```

**Command for Modern Flexible Height Gallery Control:**
```pwsh
cd bin\Debug\PowerAppsEngine
dotnet PowerAppsTestEngine.dll -i ..\..\..\samples\mdagallerycontrols\flexiblegallery_testPlan.fx.yaml -e 00000000-0000-0000-0000-11112223333 -t 11112222-3333-4444-5555-666677778888 -u browser -p mda -d "https://orgfc708206.crm.dynamics.com/main.aspx?appid=65cdcc8e-54bc-ef11-a72f-000d3a12b0cb&pagetype=custom&name=cr693_flexiblegallery_f5374"
```

**Command for Classic - Blank Horizontal and Flexible Height Gallery Control:**
```pwsh
cd bin\Debug\PowerAppsEngine
dotnet PowerAppsTestEngine.dll -i ..\..\..\samples\mdagallerycontrols\blankgallery_testPlan.fx.yaml -e 00000000-0000-0000-0000-11112223333 -t 11112222-3333-4444-5555-666677778888 -u browser -p mda -d "https://orgfc708206.crm.dynamics.com/main.aspx?appid=65cdcc8e-54bc-ef11-a72f-000d3a12b0cb&pagetype=custom&name=cr7d6_blankhorizontalgallery_311c9"
```

**Command for Classic - Blank Vertical Gallery Control:**
```pwsh
cd bin\Debug\PowerAppsEngine
dotnet PowerAppsTestEngine.dll -i ..\..\..\samples\mdagallerycontrols\blankverticalgallery_testPlan.fx.yaml -e 00000000-0000-0000-0000-11112223333 -t 11112222-3333-4444-5555-666677778888 -u browser -p mda -d "https://orgfc708206.crm.dynamics.com/main.aspx?appid=65cdcc8e-54bc-ef11-a72f-000d3a12b0cb&pagetype=custom&name=cr7d6_blankverticalgallery_a4937"
33 changes: 33 additions & 0 deletions samples/mdagallerycontrols/RunTests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# Get current directory so we can reset back to it after running the tests
$currentDirectory = Get-Location

$config = Get-Content -Path .\config.json -Raw | ConvertFrom-Json
$tenantId = $config.tenantId
$environmentId = $config.environmentId
$user1Email = $config.user1Email

if ([string]::IsNullOrEmpty($environmentId)) {
Write-Error "Environment not configured. Please update config.json"
return
}

# Build the latest debug version of Test Engine from source
Set-Location ..\..\src
dotnet build

if ($config.installPlaywright) {
Start-Process -FilePath "pwsh" -ArgumentList "-Command `"..\bin\Debug\PowerAppsTestEngine\playwright.ps1 install`"" -Wait
} else {
Write-Host "Skipped playwright install"
}

Set-Location ..\bin\Debug\PowerAppsTestEngine
$env:user1Email = $user1Email
# Run the tests for each user in the configuration file.
dotnet PowerAppsTestEngine.dll -u "storagestate" -p "mda" -a "none" -i "$currentDirectory\mdagallerycontrols_testPlan.fx.yaml" -t $tenantId -e $environmentId

# Reset the location back to the original directory.
Set-Location $currentDirectory
105 changes: 105 additions & 0 deletions samples/mdagallerycontrols/blankgallery_testPlan.fx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# yaml-embedded-languages: powerfx
testSuite:
testSuiteName: MDA Custom Page tests - Gallery Controls
testSuiteDescription: Verify test cases for MDA Gallery Controls
persona: User1
appLogicalName: NotNeeded
testCases:
- testCaseName: Test Gallery Control - Validate Selection by Row Number
testCaseDescription: Ensure that selecting an item in the Gallery control by specifying the row number updates the selected record accurately.
testSteps: |
Select(Gallery1, 3);
Assert(Index(Gallery1.AllItems, 3).Label1.Text = "Action Figure", "Verify the selected record's Title value is 'Action Figure'");
Assert(Index(Gallery1.AllItems, 3).Label3.Text = "24.99", "Verify the selected record's Price value is '24.99'");
Select(Gallery2, 3);
Assert(Index(Gallery2.AllItems, 3).Label6.Text = "Action Figure", "Verify the selected record's Title value is 'Action Figure'");
Assert(Index(Gallery2.AllItems, 3).Label8.Text = "24.99", "Verify the selected record's Price value is '24.99'");

- testCaseName: Test Gallery Control - Validate Selection via Icon
testCaseDescription: Ensure that selecting an item in the Gallery control using an icon updates the selected record accurately.
testSteps: |
Select(Gallery1, 5, Icon1);
Assert(Index(Gallery1.AllItems, 5).Label1.Text = "Laptop", "Verify the selected record's Title value is 'Laptop'");
Assert(Index(Gallery1.AllItems, 5).Label3.Text = "999.99", "Verify the selected record's Price value is '999.99'");
Select(Gallery2, 5, Icon2);
Assert(Index(Gallery2.AllItems, 5).Label6.Text = "Laptop", "Verify the selected record's Title value is 'Laptop'");
Assert(Index(Gallery2.AllItems, 5).Label8.Text = "999.99", "Verify the selected record's Price value is '999.99'");

- testCaseName: Populate gallery with data
testCaseDescription: Populate gallery with data and validate with count
testSteps: |
=
Assert(CountRows(Gallery1.Items) = 10, "Checking the Items count of the Horizontal Gallery control");
Assert(CountRows(Gallery2.Items) = 10, "Checking the Items count of the Flexible Gallery control");

- testCaseName: Test Gallery Control - Search and Validate Result Count
testCaseDescription: Verify that searching the Gallery control using input from the text box updates the displayed items correctly.
testSteps: |
SetProperty(txtSearchInput.Value, "Jeans");
Select(icnSearch);
Wait(Gallery1,"AllItemsCount", 1);
Wait(Gallery2,"AllItemsCount", 1);
Assert(Gallery1.AllItemsCount = 1, "Checking if the Horizontal Gallery displays the correct number of items after search");
Assert(Gallery2.AllItemsCount = 1, "Checking if the Flexible Gallery displays the correct number of items after search");
SetProperty(txtSearchInput.Value, "");
SetProperty(txtSearchInput.Value, "e");
Select(icnSearch);
Wait(Gallery1,"AllItemsCount", 7);
Wait(Gallery2,"AllItemsCount", 7);
Assert(Gallery1.AllItemsCount = 7, "Checking if the Horizontal Gallery displays the correct number of items after search");
Assert(Gallery2.AllItemsCount = 7, "Checking if the Flexible Gallery displays the correct number of items after search");


- testCaseName: Test Gallery Control - Validate ShowNavigation Property
testCaseDescription: Verify that the ShowNavigation property of the Gallery control is set and validated correctly.
testSteps: |
SetProperty(txtSearchInput.Value, "");
SetProperty(Gallery1.ShowNavigation, false);
SetProperty(Gallery2.ShowNavigation, false);
Assert(Gallery1.ShowNavigation = false, "Verify the ShowNavigation property is set to false");
Assert(Gallery2.ShowNavigation = false, "Verify the ShowNavigation property is set to false");
SetProperty(Gallery1.ShowNavigation, true);
SetProperty(Gallery2.ShowNavigation, true);
Assert(Gallery1.ShowNavigation = true, "Verify the ShowNavigation property is set to true");
Assert(Gallery2.ShowNavigation = true, "Verify the ShowNavigation property is set to true");

- testCaseName: Test Gallery Control - Validate Selectable Property
testCaseDescription: Verify that the Selectable property of the Gallery control is set and validated correctly.
testSteps: |
SetProperty(Gallery1.Selectable, true);
SetProperty(Gallery2.Selectable, true);
Assert(Gallery1.Selectable = true, "Verify the Selectable property is set to true");
Assert(Gallery2.Selectable = true, "Verify the Selectable property is set to true");
SetProperty(Gallery1.Selectable, false);
SetProperty(Gallery2.Selectable, false);
Assert(Gallery1.Selectable = false, "Verify the Selectable property is set to false");
Assert(Gallery2.Selectable = false, "Verify the Selectable property is set to false");

- testCaseName: Test Gallery Control - Filter and Validate Single Item
testCaseDescription: Ensure that filtering the Gallery control by a specific title updates the displayed items correctly and validates the item count.
testSteps: |
SetProperty(Gallery1.Items, Filter(Gallery1.Items, 'cr7d6_title'="Coffee Maker"));
SetProperty(Gallery2.Items, Filter(Gallery2.Items, 'cr7d6_title'="Coffee Maker"));
Select(Gallery1, 1);
Select(Gallery2, 1);
Assert(Label1.Text = "Coffee Maker", "Checking the Items count of the Gallery control");
Assert(Label6.Text = "Coffee Maker", "Checking the Items count of the Gallery control");

# Both examples provided below are effective.
# SetProperty(Gallery1.Items, Search(Gallery1.Items, "Action Figure", 'cr7d6_title'));
# SetProperty(Gallery1.Items, Filter(Gallery1.Items, Title6.Text="SmartPhone"));
testSettings:
headless: false
locale: "en-US"
recordVideo: true
extensionModules:
enable: true
browserConfigurations:
- browser: Chromium
channel: msedge

environmentVariables:
users:
- personaName: User1
emailKey: user1Email
passwordKey: NotNeeded
111 changes: 111 additions & 0 deletions samples/mdagallerycontrols/blankverticalgallery_testPlan.fx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# yaml-embedded-languages: powerfx
testSuite:
testSuiteName: MDA Custom Page tests - Gallery Controls
testSuiteDescription: Verify test cases for MDA Gallery Controls
persona: User1
appLogicalName: NotNeeded
testCases:
- testCaseName: Test Gallery Control - Validate Selection by Row Number
testCaseDescription: Ensure that selecting an item in the Gallery control by specifying the row number updates the selected record accurately.
testSteps: |
Select(Gallery1, 3);
Assert(Index(Gallery1.AllItems, 3).TextInputCanvas2.Value = "Action Figure", "Verify the selected record's Title value is 'Action Figure'");
Assert(Index(Gallery1.AllItems, 3).TextInputCanvas4.Value = "24.99", "Verify the selected record's Price value is '24.99'");

- testCaseName: Test Gallery Control - Validate Selection via Icon
testCaseDescription: Ensure that selecting an item in the Gallery control using an icon updates the selected record accurately.
testSteps: |
Select(Gallery1, 5, Icon1);
Assert(Index(Gallery1.AllItems, 5).TextInputCanvas2.Value = "Laptop", "Verify the selected record's Title value is 'Laptop'");
Assert(Index(Gallery1.AllItems, 5).TextInputCanvas4.Value = "999.99", "Verify the selected record's Price value is '999.99'");
Select(Gallery1, 5, Icon2);

- testCaseName: Test Gallery Control - Select the row and edit the fieds value
testCaseDescription: Ensure that selecting an item in the Gallery control using an icon updates the selected record accurately.
testSteps: |
Select(Gallery1, 5, Icon1);
SetProperty(Index(Gallery1.AllItems, 5).TextInputCanvas2.Value, "Laptop1");
SetProperty(Index(Gallery1.AllItems, 5).TextInputCanvas4.Value, "1000.00");
SetProperty(Index(Gallery1.AllItems, 5).ComboboxCanvas1.DefaultSelectedItems, Table({Id:472770002,Value:"Home"}));
Assert(Index(Gallery1.AllItems, 5).TextInputCanvas2.Value = "Laptop1", "Verify the selected record's Title value is 'Laptop1'");
Assert(Index(Gallery1.AllItems, 5).TextInputCanvas4.Value = "1000.00", "Verify the selected record's Price value is '1000.00'");
Select(Gallery1, 5, Icon2);

- testCaseName: Test Gallery Control - Validate Selection and Assertions
testCaseDescription: Ensure that selecting an item in the Gallery control using an icon updates the selected record accurately and validates its values.
testSteps: |
Select(Gallery1, 5, Icon1);
Assert((Gallery1.Selected).TextInputCanvas2.Value = "Laptop1", "Verify the selected record's Title value is 'Laptop1'");
Assert((Gallery1.Selected).TextInputCanvas4.Value = "1000.00", "Verify the selected record's Price value is '1000.00'");
Select(Gallery1, 5, Icon2);

- testCaseName: Populate gallery with data
testCaseDescription: Populate gallery with data and validate with count
testSteps: |
=
Assert(CountRows(Gallery1.Items) = 10, "Checking the Items count of the Gallery control");
Assert(CountRows(Gallery1.AllItems) = 10, "Verify the AllItemsCount property returns the correct number of items");

- testCaseName: Test Gallery Control - Search and Validate Result Count
testCaseDescription: Verify that searching the Gallery control using input from the text box updates the displayed items correctly.
testSteps: |
SetProperty(txtSearchInput.Value, "Jeans");
Select(icnSearch);
Wait(Gallery1,"AllItemsCount", 1);
Assert(Gallery1.AllItemsCount = 1, "Checking if the Gallery displays the correct number of items after search");
SetProperty(txtSearchInput.Value, "");
SetProperty(txtSearchInput.Value, "e");
Select(icnSearch);
Wait(Gallery1,"AllItemsCount", 7);
Assert(Gallery1.AllItemsCount = 7, "Checking if the Gallery displays the correct number of items after search");


- testCaseName: Test Gallery Control - Validate ShowNavigation Property
testCaseDescription: Verify that the ShowNavigation property of the Gallery control is set and validated correctly.
testSteps: |
SetProperty(txtSearchInput.Value, "");
SetProperty(Gallery1.ShowNavigation, false);
Assert(Gallery1.ShowNavigation = false, "Verify the ShowNavigation property is set to false");
SetProperty(Gallery1.ShowNavigation, true);
Assert(Gallery1.ShowNavigation = true, "Verify the ShowNavigation property is set to true");

- testCaseName: Test Gallery Control - Validate Selectable Property
testCaseDescription: Verify that the Selectable property of the Gallery control is set and validated correctly.
testSteps: |
SetProperty(Gallery1.Selectable, true);
Assert(Gallery1.Selectable = true, "Verify the Selectable property is set to true");
SetProperty(Gallery1.Selectable, false);
Assert(Gallery1.Selectable = false, "Verify the Selectable property is set to false");

- testCaseName: Test Gallery Control - Validate Default Property
testCaseDescription: Verify that the Default property of the Gallery control is set and validated correctly.
testSteps: |
SetProperty(Gallery1.Default, Last(Gallery1.Items));
Assert((Gallery1.Selected).TextInputCanvas2.Value = "Cookbook", "Verify the Default property is set to the first item");

- testCaseName: Test Gallery Control - Filter and Validate Single Item
testCaseDescription: Ensure that filtering the Gallery control by a specific title updates the displayed items correctly and validates the item count.
testSteps: |
SetProperty(Gallery1.Items, Filter(Gallery1.Items, 'cr7d6_title'="Coffee Maker"));
Select(Gallery1, 1);
Assert(TextInputCanvas2.Value = "Coffee Maker", "Checking the Items count of the Gallery control");

# Both examples provided below are effective.
# SetProperty(Gallery1.Items, Search(Gallery1.Items, "Action Figure", 'cr7d6_title'));
# SetProperty(Gallery1.Items, Filter(Gallery1.Items, Title6.Text="SmartPhone"));

testSettings:
headless: false
locale: "en-US"
recordVideo: true
extensionModules:
enable: true
browserConfigurations:
- browser: Chromium
channel: msedge

environmentVariables:
users:
- personaName: User1
emailKey: user1Email
passwordKey: NotNeeded
Loading