Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 added samples/mda_imagecontrol/Images/monitor.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added samples/mda_imagecontrol/Images/ring.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
31 changes: 31 additions & 0 deletions samples/mda_imagecontrol/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Overview

This Power Apps Test Engine sample demonstrates how to assert and interact with the values of Image and Add Picture controls in a model-driven application form.

## 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 testPlan.fx.yaml**
Update the YAML file to assert expected values of the Image and Add Picture 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. |

5. **Execute the Test for Custom Page**
Change the example below to the URL of your organization:

```pwsh
cd bin\Debug\PowerAppsEngine
dotnet PowerAppsTestEngine.dll -i ..\..\..\samples\mda_imagecontrol\testPlan.fx.yaml -e 00000000-0000-0000-0000-11112223333 -t 11112222-3333-4444-5555-666677778888 -u browser -p mda -d "https://contoso.crm4.dynamics.com/main.aspx?appid=9e9c25f3-1851-ef11-bfe2-6045bd8f802c&pagetype=custom&name=cr693_imagecontrol_dbda3"
144 changes: 144 additions & 0 deletions samples/mda_imagecontrol/testPlan.fx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
testSuite:
testSuiteName: MDA Custom Page Tests - Image Control, Add Picture Control
testSuiteDescription: Verify test cases for Image Control and Add Picture Control
persona: User1
appLogicalName: NotNeeded

testCases:
# Image1 Control Test Cases
- testCaseName: Test Image Control - OnSelect Event
testCaseDescription: Verify that the ImageRotation property rotates the image correctly.
testSteps: |
Select(Image1);
Assert(Label1.Text = "Image Control Clicked", "Check if the ImageRotation property is set to 90 degrees.");

- testCaseName: Test Image Control - ImageRotation Property
testCaseDescription: Verify that the ImageRotation property rotates the image correctly.
testSteps: |
Select(ButtonCanvas1);
Assert(Image1.ImageRotation = "rotate90", "Check if the ImageRotation property is set to 90 degrees.");

- testCaseName: Test Image Control - Visibility Property
testCaseDescription: Verify that the Visible property toggles the visibility of the Image control.
testSteps: |
SetProperty(Image1.Visible, false);
Assert(Image1.Visible = false, "Check if the Image control is hidden.");
SetProperty(Image1.Visible, true);
Assert(Image1.Visible = true, "Check if the Image control is visible.");

- testCaseName: Test Image Control - Set and Retrieve Image Property
testCaseDescription: Verify that the Image property can be set and retrieved correctly.
testSteps: |
SetProperty(Image1.Image, "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg");
Wait(Image1, "Image", "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg");
Assert(Image1.Image = "https://fakestoreapi.com/img/81fPKd-2AYL._AC_SL1500_.jpg" , "Check if Image property is correctly set.");

- testCaseName: Test Image Control - Invalid Image URL
testCaseDescription: Verify the behavior when an invalid URL is set for the Image property.
testSteps: |
SetProperty(Image1.Image, "");
Assert(Image1.Image = "" , "Check if an error is returned for the invalid image URL.");

- testCaseName: Test Image Control - Tooltip Property
testCaseDescription: Verify that the Tooltip property can be set and retrieved correctly.
testSteps: |
SetProperty(Image1.Tooltip, "This is an image tooltip");
Assert(Image1.Tooltip = "This is an image tooltip", "Check if the Tooltip property is correctly set.");

# AddMediaButton1 Control Test Cases
- testCaseName: Test AddMediaButton1 - ChangePictureText Property
testCaseDescription: Verify that the ChangePictureText property updates the button text correctly.
testSteps: |
SetProperty(AddMediaButton1.ChangePictureText, "Upload a New Picture");
Assert(AddMediaButton1.ChangePictureText = "Upload a New Picture", "Check if ChangePictureText is updated correctly.");

- testCaseName: Test AddMediaButton1 - FileName Property
testCaseDescription: Verify that the FileName property displays the correct uploaded file name.
testSteps: |
SetProperty(AddMediaButton1.FileName, "ProductImageName1");
Assert(AddMediaButton1.FileName = "ProductImageName1", "Check if FileName displays the correct uploaded file name.");

- testCaseName: Test AddMediaButton1 - Select the file from local drive
testCaseDescription: Verify that the control correctly displays the selected image along with its file name.
testSteps: |
Select(AddMediaButton1, "--Physical Path of image--");
Assert(AddMediaButton1.FileName = "ring.jpg", "Check if Image displays the correct uploaded file name.");
Select(AddMediaButton1, "--Physical Path of image--");
Assert(AddMediaButton1.FileName = "monitor.jpg", "Check if Image displays the correct uploaded file name.");

- testCaseName: Test AddMediaButton1 - PlaceholderText Property
testCaseDescription: Verify that the PlaceholderText property displays correctly before uploading an image.
testSteps: |
SetProperty(AddMediaButton1.PlaceholderText, "No image uploaded");
Assert(AddMediaButton1.PlaceholderText = "No image uploaded", "Check if PlaceholderText displays correctly.");

- testCaseName: Test AddMediaButton1 - Media Property
testCaseDescription: Verify that the Media property holds the uploaded media file.
testSteps: |
SetProperty(UploadedImage1.Image, "https://fakestoreapi.com/img/61mtL65D4cL._AC_SX679_.jpg");
Assert(AddMediaButton1.Media <> Blank(), "Check if the Media property holds the uploaded file.");

- testCaseName: Test AddMediaButton1 - UseMobileCamera Property
testCaseDescription: Verify that the UseMobileCamera property opens the device camera on mobile devices.
testSteps: |
SetProperty(AddMediaButton1.UseMobileCamera, true);
Assert(AddMediaButton1.UseMobileCamera = true, "Check if the UseMobileCamera property is enabled.");

- testCaseName: Test AddMediaButton1 - Text Property
testCaseDescription: Verify that the Text property updates the button's display text.
testSteps: |
SetProperty(AddMediaButton1.Text, "Upload Photo");
Assert(AddMediaButton1.Text = "Upload Photo", "Check if the Text property updates correctly.");

- testCaseName: Test AddMediaButton1 - Tooltip Property
testCaseDescription: Verify that the Tooltip property displays the correct tooltip text on hover.
testSteps: |
SetProperty(AddMediaButton1.Tooltip, "Click to upload an image");
Assert(AddMediaButton1.Tooltip = "Click to upload an image", "Check if Tooltip displays the correct text.");

- testCaseName: Test AddMediaButton1 - Visible Property
testCaseDescription: Verify that the Visible property toggles the visibility of the AddMediaButton control.
testSteps: |
SetProperty(AddMediaButton1.Visible, false);
Assert(AddMediaButton1.Visible = false, "Check if the control is hidden.");
SetProperty(AddMediaButton1.Visible, true);
Assert(AddMediaButton1.Visible = true, "Check if the control is visible.");

# UploadedImage1 Control Test Cases
- testCaseName: Test UploadedImage1 - Image Property
testCaseDescription: Verify that the Image property displays the uploaded image correctly.
testSteps: |
SetProperty(UploadedImage1.Image, "https://fakestoreapi.com/img/81Zt42ioCgL._AC_SX679_.jpg");
Wait(UploadedImage1, "Image", "https://fakestoreapi.com/img/81Zt42ioCgL._AC_SX679_.jpg");
Assert(UploadedImage1.Image = "https://fakestoreapi.com/img/81Zt42ioCgL._AC_SX679_.jpg", "Check if the uploaded image is displayed correctly.");

- testCaseName: Test UploadedImage1 - Tooltip Property
testCaseDescription: Verify that the Tooltip property displays the correct tooltip text on hover.
testSteps: |
SetProperty(UploadedImage1.Tooltip, "Uploaded Image Preview");
Assert(UploadedImage1.Tooltip = "Uploaded Image Preview", "Check if Tooltip displays correctly.");

- testCaseName: Test UploadedImage1 - Visible Property
testCaseDescription: Verify that the Visible property toggles the visibility of the UploadedImage control.
testSteps: |
SetProperty(UploadedImage1.Visible, false);
Assert(UploadedImage1.Visible = false, "Check if the control is hidden.");
SetProperty(UploadedImage1.Visible, true);
Assert(UploadedImage1.Visible = true, "Check if the control is visible.");


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

environmentVariables:
users:
- personaName: "User1"
emailKey: "user1Email"
passwordKey: NotNeeded
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Task<Dictionary<string, ControlRecordValue>> LoadObjectModelAsync()
throw new NotImplementedException();
}}

public Task<bool> SelectControlAsync(ItemPath itemPath)
public Task<bool> SelectControlAsync(ItemPath itemPath, string filePath = null)
{{
throw new NotImplementedException();
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public void SelectFunctionThrowsOnNonPowerAppsRecordValuetTest()
[Fact]
public void SelectOneParamFunctionTest()
{
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>())).Returns(Task.FromResult(true));
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>(), null)).Returns(Task.FromResult(true));
LoggingTestHelper.SetupMock(MockLogger);
var recordType = RecordType.Empty().Add("Text", FormulaType.String);

Expand All @@ -75,7 +75,7 @@ public void SelectOneParamFunctionTest()

var result = selectFunction.Execute(recordValue);
Assert.IsType<BlankValue>(result);
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name)), Times.Once());
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name), null), Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "------------------------------\n\n" + "Executing Select function.", LogLevel.Information, Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "Successfully finished executing Select function.", LogLevel.Information, Times.Once());
Assert.Equal(1, updaterFunctionCallCount);
Expand All @@ -84,7 +84,7 @@ public void SelectOneParamFunctionTest()
[Fact]
public void SelectTwoParamFunctionTest()
{
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>())).Returns(Task.FromResult(true));
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>(), null)).Returns(Task.FromResult(true));
LoggingTestHelper.SetupMock(MockLogger);
var recordType = RecordType.Empty().Add("Gallery1", RecordType.Empty());

Expand All @@ -101,16 +101,16 @@ public void SelectTwoParamFunctionTest()

var result = selectFunction.Execute(recordValue, rowOrColumn);
Assert.IsType<BlankValue>(result);
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name)), Times.Once());
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name), null), Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "------------------------------\n\n" + "Executing Select function.", LogLevel.Information, Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "Successfully finished executing Select function.", LogLevel.Information, Times.Once());
Assert.Equal(1, updaterFunctionCallCount);
}

[Fact]
public void SelectThreeParamFunctionTest()
{
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>())).Returns(Task.FromResult(true));
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>(), null)).Returns(Task.FromResult(true));
LoggingTestHelper.SetupMock(MockLogger);
var parentRecordType = RecordType.Empty().Add("Gallery1", RecordType.Empty());
var childRecordType = RecordType.Empty().Add("Button1", RecordType.Empty());
Expand All @@ -129,7 +129,7 @@ public void SelectThreeParamFunctionTest()

var result = selectFunction.Execute(parentValue, rowOrColumn, childValue);
Assert.IsType<BlankValue>(result);
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == childValue.Name)), Times.Once());
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == childValue.Name), null), Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "------------------------------\n\n" + "Executing Select function.", LogLevel.Information, Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "Successfully finished executing Select function.", LogLevel.Information, Times.Once());
Assert.Equal(1, updaterFunctionCallCount);
Expand All @@ -139,7 +139,7 @@ public void SelectThreeParamFunctionTest()
public void SelectOneParamFunctionFailsTest()
{
LoggingTestHelper.SetupMock(MockLogger);
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>())).Returns(Task.FromResult(false));
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>(), null)).Returns(Task.FromResult(false));

var recordType = RecordType.Empty().Add("Text", FormulaType.String);

Expand All @@ -154,7 +154,7 @@ public void SelectOneParamFunctionFailsTest()
var selectFunction = new SelectOneParamFunction(MockTestWebProvider.Object, updaterFunction, MockLogger.Object);

Assert.ThrowsAny<Exception>(() => selectFunction.Execute(recordValue));
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name)), Times.Once());
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name), null), Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "------------------------------\n\n" + "Executing Select function.", LogLevel.Information, Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "Control name: Button1", LogLevel.Trace, Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "Unable to select control", LogLevel.Error, Times.Once());
Expand All @@ -164,7 +164,7 @@ public void SelectOneParamFunctionFailsTest()
[Fact]
public void SelectTwoParamFunctionFailsTest()
{
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>())).Returns(Task.FromResult(false));
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>(), null)).Returns(Task.FromResult(false));
LoggingTestHelper.SetupMock(MockLogger);
var recordType = RecordType.Empty().Add("Gallery1", RecordType.Empty());

Expand All @@ -189,7 +189,7 @@ public void SelectTwoParamFunctionFailsTest()

recordValue = new ControlRecordValue(recordType, MockTestWebProvider.Object, "Gallery1");
Assert.ThrowsAny<Exception>(() => selectFunction.Execute(recordValue, rowOrColumn));
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name)), Times.Once());
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == recordValue.Name), null), Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "------------------------------\n\n" + "Executing Select function.", LogLevel.Information, Times.AtLeastOnce());
LoggingTestHelper.VerifyLogging(MockLogger, "Control name: Gallery1", LogLevel.Trace, Times.AtLeastOnce());
LoggingTestHelper.VerifyLogging(MockLogger, "Unable to select control", LogLevel.Error, Times.AtLeastOnce());
Expand All @@ -199,7 +199,7 @@ public void SelectTwoParamFunctionFailsTest()
[Fact]
public void SelectThreeParamFunctionFailsTest()
{
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>())).Returns(Task.FromResult(false));
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>(), null)).Returns(Task.FromResult(false));
LoggingTestHelper.SetupMock(MockLogger);
var parentRecordType = RecordType.Empty().Add("Gallery1", RecordType.Empty());
var childRecordType = RecordType.Empty().Add("Button1", RecordType.Empty());
Expand Down Expand Up @@ -229,7 +229,7 @@ public void SelectThreeParamFunctionFailsTest()
parentValue = new ControlRecordValue(parentRecordType, MockTestWebProvider.Object, "Gallery1");
childValue = new ControlRecordValue(childRecordType, MockTestWebProvider.Object, "Button1");
Assert.ThrowsAny<Exception>(() => selectFunction.Execute(parentValue, rowOrColumn, childValue));
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == childValue.Name)), Times.Once());
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == childValue.Name), null), Times.Once());
LoggingTestHelper.VerifyLogging(MockLogger, "------------------------------\n\n" + "Executing Select function.", LogLevel.Information, Times.AtLeastOnce());
LoggingTestHelper.VerifyLogging(MockLogger, "Control name: Button1", LogLevel.Trace, Times.AtLeastOnce());
LoggingTestHelper.VerifyLogging(MockLogger, "Unable to select control", LogLevel.Error, Times.AtLeastOnce());
Expand All @@ -239,7 +239,7 @@ public void SelectThreeParamFunctionFailsTest()
[Fact]
public void SelectGalleryTest()
{
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>())).Returns(Task.FromResult(true));
MockTestWebProvider.Setup(x => x.SelectControlAsync(It.IsAny<ItemPath>(), null)).Returns(Task.FromResult(true));
LoggingTestHelper.SetupMock(MockLogger);
var parentRecordType = RecordType.Empty().Add("Gallery1", RecordType.Empty());
var childRecordType = RecordType.Empty().Add("Button1", RecordType.Empty());
Expand Down Expand Up @@ -285,7 +285,7 @@ public void SelectGalleryTest()
result = selectthreeParamsFunction.Execute(parentValue, rowOrColumn, childValue);
Assert.IsType<BlankValue>(result);

MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == childValue.Name)), Times.Exactly(2));
MockTestWebProvider.Verify(x => x.SelectControlAsync(It.Is<ItemPath>((item) => item.ControlName == childValue.Name), null), Times.Exactly(2));
Assert.Equal(2, updaterFunctionCallCount);
}
}
Expand Down
Loading