Skip to content

User/grant archibald ms/report 594 #631

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 8 commits into
base: main
Choose a base branch
from

Conversation

Grant-Archibald-MS
Copy link
Contributor

@Grant-Archibald-MS Grant-Archibald-MS commented Jun 4, 2025

Pull Request Template

Description

Add new test summary option to Test Engine. This feature provides the following:

  • New --run-name that allows a common test run name to be applied to multiple test execution sessions.
  • New --output-file that allows the name of the HTL summary report to be specified
$env:user1Email = "test@contoso.onmicrosoft.com"
dotnet PowerAppsTestEngine -i test.te.yaml -p mda -e $envId -t $tenantId -d $testPage --run-name "Sample"
dotnet PowerAppsTestEngine -i test2.te.yaml -p mda -e $envId -t $tenantId -d $testPage --run-name "Sample"

$folderPath = "$env:USERPROFILE\AppData\Local\Temp\Microsoft\TestEngine\TestOutput"
$reportPath = [System.IO.Path]::Combine($folderPath, "test_summary_$runName.html")

dotnet PowerAppsTestEngine  --run-name "Sample" --output-file $reportPath

Checklist

  • The code change is covered by unit tests. I have added tests that prove my fix is effective or that my feature works
  • I have performed end-to-end test locally.
  • New and existing unit tests pass locally with my changes
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I used clear names for everything
  • I have performed a self-review of my own code

@Grant-Archibald-MS Grant-Archibald-MS requested a review from a team as a code owner June 4, 2025 17:53
container.style.display = 'none';
const relatedBtn = testRow.querySelector(`.toggle-video[data-video-id="${container.id}"]`);
if (relatedBtn) {
relatedBtn.innerHTML = `<i class="fas fa-play-circle"></i> ${relatedBtn.textContent.trim().replace('Pause Video', '').trim() || 'Play Video'}`;

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI about 1 month ago

To fix the issue, the text retrieved from relatedBtn.textContent should be properly escaped before being interpolated into the HTML string. Escaping ensures that any meta-characters in the text are treated as literal text rather than HTML. A utility function or library like DOMPurify can be used for this purpose, or a simple manual escaping function can be implemented.

Steps to fix:

  1. Introduce a function to escape HTML meta-characters (e.g., <, >, &, ").
  2. Use this function to sanitize relatedBtn.textContent before interpolating it into the HTML string.
  3. Replace the vulnerable line with the sanitized version.

Suggested changeset 1
src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html b/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html
--- a/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html
+++ b/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html
@@ -1229,2 +1229,11 @@
               // Event listeners for video toggle
+            // Utility function to escape HTML meta-characters
+            function escapeHtml(text) {
+                return text.replace(/&/g, '&amp;')
+                           .replace(/</g, '&lt;')
+                           .replace(/>/g, '&gt;')
+                           .replace(/"/g, '&quot;')
+                           .replace(/'/g, '&#039;');
+            }
+            
             document.body.addEventListener('click', function(e) {
@@ -1258,3 +1267,4 @@
                                 if (relatedBtn) {
-                                    relatedBtn.innerHTML = `<i class="fas fa-play-circle"></i> ${relatedBtn.textContent.trim().replace('Pause Video', '').trim() || 'Play Video'}`;
+                                    const sanitizedText = escapeHtml(relatedBtn.textContent.trim().replace('Pause Video', '').trim() || 'Play Video');
+                                    relatedBtn.innerHTML = `<i class="fas fa-play-circle"></i> ${sanitizedText}`;
                                     relatedBtn.classList.remove('btn-secondary');
EOF
@@ -1229,2 +1229,11 @@
// Event listeners for video toggle
// Utility function to escape HTML meta-characters
function escapeHtml(text) {
return text.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#039;');
}

document.body.addEventListener('click', function(e) {
@@ -1258,3 +1267,4 @@
if (relatedBtn) {
relatedBtn.innerHTML = `<i class="fas fa-play-circle"></i> ${relatedBtn.textContent.trim().replace('Pause Video', '').trim() || 'Play Video'}`;
const sanitizedText = escapeHtml(relatedBtn.textContent.trim().replace('Pause Video', '').trim() || 'Play Video');
relatedBtn.innerHTML = `<i class="fas fa-play-circle"></i> ${sanitizedText}`;
relatedBtn.classList.remove('btn-secondary');
Copilot is powered by AI and may make mistakes. Always verify output.
// Set source if not already set
const sourceElement = videoElement.querySelector('source');
if (sourceElement && !sourceElement.src && videoSrc) {
sourceElement.src = videoSrc;

Check warning

Code scanning / CodeQL

DOM text reinterpreted as HTML Medium

DOM text
is reinterpreted as HTML without escaping meta-characters.

Copilot Autofix

AI about 1 month ago

To fix the issue, the value of videoSrc should be validated or sanitized before being assigned to the src property of the <source> element. A simple and effective approach is to ensure that videoSrc is a valid and safe URL. This can be achieved using the URL constructor, which throws an error if the input is not a valid URL. Additionally, you can restrict the allowed protocols (e.g., http and https) to prevent malicious payloads.

The fix involves:

  1. Wrapping the assignment of videoSrc in a validation step.
  2. Using the URL constructor to validate the URL and checking its protocol.
  3. Logging an error and skipping the assignment if the validation fails.

Suggested changeset 1
src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html b/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html
--- a/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html
+++ b/src/Microsoft.PowerApps.TestEngine/Reporting/Templates/TestRunSummaryTemplate.html
@@ -1278,4 +1278,13 @@
                             if (sourceElement && !sourceElement.src && videoSrc) {
-                                sourceElement.src = videoSrc;
-                                videoElement.load();
+                                try {
+                                    const validatedUrl = new URL(videoSrc, window.location.origin);
+                                    if (validatedUrl.protocol === 'http:' || validatedUrl.protocol === 'https:') {
+                                        sourceElement.src = validatedUrl.href;
+                                        videoElement.load();
+                                    } else {
+                                        console.error('Invalid video source protocol:', validatedUrl.protocol);
+                                    }
+                                } catch (err) {
+                                    console.error('Invalid video source URL:', videoSrc, err);
+                                }
                             }
EOF
@@ -1278,4 +1278,13 @@
if (sourceElement && !sourceElement.src && videoSrc) {
sourceElement.src = videoSrc;
videoElement.load();
try {
const validatedUrl = new URL(videoSrc, window.location.origin);
if (validatedUrl.protocol === 'http:' || validatedUrl.protocol === 'https:') {
sourceElement.src = validatedUrl.href;
videoElement.load();
} else {
console.error('Invalid video source protocol:', validatedUrl.protocol);
}
} catch (err) {
console.error('Invalid video source URL:', videoSrc, err);
}
}
Copilot is powered by AI and may make mistakes. Always verify output.
@Grant-Archibald-MS
Copy link
Contributor Author

Extended the Copilot Studio Kit sample to include the following

  • validate.ps1 - To validate that dependencies for source code version of Test Engine are configured as expected and ready to run the sample
  • RunTests.ps1 to run a set of tests with pac test run or from the source code version

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant