Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
df7436d
Refactor transaction processing mobile flows
StuartFerguson Aug 20, 2026
5a6262f
Remove redundant Docker setup from Android E2E workflow
StuartFerguson Aug 20, 2026
43b3b38
Merge branch 'main' into task/redesign_ui_tests
StuartFerguson Aug 20, 2026
27e297b
Configure Android UI tests with built APK path
StuartFerguson Aug 20, 2026
6dc3933
Merge branch 'task/redesign_ui_tests' of https://github.com/Transacti…
StuartFerguson Aug 20, 2026
831df22
Configure Android UI tests for built APKs and reuse Appium servers
StuartFerguson Aug 20, 2026
67d0e77
Remove obsolete training mode login step
StuartFerguson Aug 20, 2026
ff1ad1f
Fix training mode state detection and setup
StuartFerguson Aug 20, 2026
3461189
Fix Windows UI test workflows
StuartFerguson Aug 20, 2026
c175299
Configure Windows CI builds for win-x64
StuartFerguson Aug 20, 2026
27f2487
Simplify Windows workflow restore steps
StuartFerguson Aug 20, 2026
3f58c43
Resolve Windows app ID dynamically for UI tests
StuartFerguson Aug 20, 2026
3a5a84e
Improve Windows UI test app package discovery
StuartFerguson Aug 20, 2026
02af303
Fix PowerShell attempt logging in Windows test workflows
StuartFerguson Aug 20, 2026
4502d30
Add Windows fallback handling for profile button lookup
StuartFerguson Aug 20, 2026
4123e24
Improve UI test element lookup and assertions
StuartFerguson Aug 20, 2026
375d165
Improve profile option tile handling in UI tests
StuartFerguson Aug 20, 2026
d9ac63f
Update profile page traits to match display names
StuartFerguson Aug 20, 2026
a63668a
Add Windows UI element fallbacks for mobile tests
StuartFerguson Aug 21, 2026
0a01e4c
Handle platform-specific operator and product page traits
StuartFerguson Aug 21, 2026
9ebd376
Normalize UI test page trait names
StuartFerguson Aug 21, 2026
ca4936e
Normalize operator and product automation IDs in UI tests
StuartFerguson Aug 21, 2026
ff6d2b5
Support Windows accessibility traits in bill payment UI tests
StuartFerguson Aug 21, 2026
44ac1ca
Improve UI page assertion diagnostics
StuartFerguson Aug 21, 2026
e3a20ac
Skip Upload Logs interaction on Windows UI tests
StuartFerguson Aug 21, 2026
1e5ffef
Support platform-specific UI test page traits
StuartFerguson Aug 21, 2026
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
58 changes: 44 additions & 14 deletions .github/workflows/android_e2e_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,27 +135,57 @@ jobs:
run: |
nohup appium --log appium.log &

- name: Set up Docker (Ubuntu)
if: runner.os == 'Linux'
run: |
# Check Docker version to ensure it's installed properly
docker --version
docker info

# Allow current user to access Docker without sudo (optional, for convenience)
sudo usermod -aG docker $USER

# Restart Docker service to apply changes
sudo systemctl restart docker

- name: Restore MAUI App for Android
run: dotnet restore TransactionProcessor.Mobile.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json

- name: Build Code
run: dotnet build TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj -f net10.0-android -c Release --no-restore

- name: Locate Android APK
id: android_apk
run: |
apk_path=$(find "$GITHUB_WORKSPACE/TransactionProcessor.Mobile/bin/Release/net10.0-android" -type f -name '*-Signed.apk' | head -n 1)
if [ -z "$apk_path" ]; then
echo "Unable to find a signed APK under TransactionProcessor.Mobile/bin/Release/net10.0-android."
find "$GITHUB_WORKSPACE/TransactionProcessor.Mobile/bin/Release/net10.0-android" -type f -name '*.apk' -print
exit 1
fi

echo "UITEST_ANDROID_APP_PATH=$apk_path" >> "$GITHUB_ENV"
echo "apk_path=$apk_path" >> "$GITHUB_OUTPUT"

- name: Prepare Android UI test settings
id: android_settings
run: |
settings_path="$RUNNER_TEMP/android-ui-tests.runsettings"
cp TransactionProcessor.Mobile.UITests.Android.runsettings "$settings_path"

python3 - "$settings_path" "${{ steps.android_apk.outputs.apk_path }}" <<'PY'
from pathlib import Path
import re
import sys

settings_file = Path(sys.argv[1])
apk_path = sys.argv[2]
content = settings_file.read_text()
updated_content, replacements = re.subn(
r"<UITEST_ANDROID_APP_PATH>.*?</UITEST_ANDROID_APP_PATH>",
f"<UITEST_ANDROID_APP_PATH>{apk_path}</UITEST_ANDROID_APP_PATH>",
content,
count=1,
flags=re.DOTALL,
)

if replacements != 1:
raise SystemExit("Expected exactly one UITEST_ANDROID_APP_PATH entry in the runsettings template.")

settings_file.write_text(updated_content)
PY

echo "runsettings_path=$settings_path" >> "$GITHUB_OUTPUT"

- name: Run Android Navigation Tests
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "(Category=PRTest)&(Category=Android)" --no-restore
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "(Category=PRTest)&(Category=Android)" --no-restore --settings "${{ steps.android_settings.outputs.runsettings_path }}"

- name: Upload Logs on Failure
if: always()
Expand Down
90 changes: 88 additions & 2 deletions .github/workflows/android_navigation_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,51 @@ jobs:
- name: Build Code
run: dotnet build TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj -f net10.0-android -c Release --no-restore

- name: Locate Android APK
id: android_apk
run: |
apk_path=$(find "$GITHUB_WORKSPACE/TransactionProcessor.Mobile/bin/Release/net10.0-android" -type f -name '*-Signed.apk' | head -n 1)
if [ -z "$apk_path" ]; then
echo "Unable to find a signed APK under TransactionProcessor.Mobile/bin/Release/net10.0-android."
find "$GITHUB_WORKSPACE/TransactionProcessor.Mobile/bin/Release/net10.0-android" -type f -name '*.apk' -print
exit 1
fi

echo "UITEST_ANDROID_APP_PATH=$apk_path" >> "$GITHUB_ENV"
echo "apk_path=$apk_path" >> "$GITHUB_OUTPUT"

- name: Prepare Android UI test settings
id: android_settings
run: |
settings_path="$RUNNER_TEMP/android-ui-tests.runsettings"
cp TransactionProcessor.Mobile.UITests.Android.runsettings "$settings_path"

python3 - "$settings_path" "${{ steps.android_apk.outputs.apk_path }}" <<'PY'
from pathlib import Path
import re
import sys

settings_file = Path(sys.argv[1])
apk_path = sys.argv[2]
content = settings_file.read_text()
updated_content, replacements = re.subn(
r"<UITEST_ANDROID_APP_PATH>.*?</UITEST_ANDROID_APP_PATH>",
f"<UITEST_ANDROID_APP_PATH>{apk_path}</UITEST_ANDROID_APP_PATH>",
content,
count=1,
flags=re.DOTALL,
)

if replacements != 1:
raise SystemExit("Expected exactly one UITEST_ANDROID_APP_PATH entry in the runsettings template.")

settings_file.write_text(updated_content)
PY

echo "runsettings_path=$settings_path" >> "$GITHUB_OUTPUT"

- name: Run Android Navigation Tests
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "(Category=PRNavTest)&(Category=Android)" --no-restore
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "(Category=PRNavTest)&(Category=Android)" --no-restore --settings "${{ steps.android_settings.outputs.runsettings_path }}"

- name: Upload Appium Logs on Failure
if: always()
Expand Down Expand Up @@ -286,8 +329,51 @@ jobs:
- name: Build Code
run: dotnet build TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj -f net10.0-android -c Release --no-restore

- name: Locate Android APK
id: android_apk
run: |
apk_path=$(find "$GITHUB_WORKSPACE/TransactionProcessor.Mobile/bin/Release/net10.0-android" -type f -name '*-Signed.apk' | head -n 1)
if [ -z "$apk_path" ]; then
echo "Unable to find a signed APK under TransactionProcessor.Mobile/bin/Release/net10.0-android."
find "$GITHUB_WORKSPACE/TransactionProcessor.Mobile/bin/Release/net10.0-android" -type f -name '*.apk' -print
exit 1
fi

echo "UITEST_ANDROID_APP_PATH=$apk_path" >> "$GITHUB_ENV"
echo "apk_path=$apk_path" >> "$GITHUB_OUTPUT"

- name: Prepare Android UI test settings
id: android_settings
run: |
settings_path="$RUNNER_TEMP/android-ui-tests.runsettings"
cp TransactionProcessor.Mobile.UITests.Android.runsettings "$settings_path"

python3 - "$settings_path" "${{ steps.android_apk.outputs.apk_path }}" <<'PY'
from pathlib import Path
import re
import sys

settings_file = Path(sys.argv[1])
apk_path = sys.argv[2]
content = settings_file.read_text()
updated_content, replacements = re.subn(
r"<UITEST_ANDROID_APP_PATH>.*?</UITEST_ANDROID_APP_PATH>",
f"<UITEST_ANDROID_APP_PATH>{apk_path}</UITEST_ANDROID_APP_PATH>",
content,
count=1,
flags=re.DOTALL,
)

if replacements != 1:
raise SystemExit("Expected exactly one UITEST_ANDROID_APP_PATH entry in the runsettings template.")

settings_file.write_text(updated_content)
PY

echo "runsettings_path=$settings_path" >> "$GITHUB_OUTPUT"

- name: Run Android Navigation Tests
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "(Category=PRHWNavTest)&(Category=Android)" --no-restore
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "(Category=PRHWNavTest)&(Category=Android)" --no-restore --settings "${{ steps.android_settings.outputs.runsettings_path }}"

- name: Upload Appium Logs on Failure
if: always()
Expand Down
54 changes: 50 additions & 4 deletions .github/workflows/windows_e2e_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,6 @@ jobs:
- name: Restore MAUI App for Windows
run: dotnet restore TransactionProcessor.Mobile.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json

- name: Build Code
run: dotnet build TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj -f net10.0-android -c Release --no-restore

- name: Decrypt PFX File
run: |
echo "${{ secrets.WINDOWSSIGNINGCERT }}" > cert.pfx.asc
Expand Down Expand Up @@ -71,8 +68,57 @@ jobs:
Add-AppxPackage -Path $msixPackage.FullName -ForceApplicationShutdown
}

- name: Resolve Windows UI test app id
id: windows_app
shell: powershell
run: |
$package = $null
for ($attempt = 1; $attempt -le 12 -and $null -eq $package; $attempt++) {
$package = Get-AppxPackage -AllUsers |
Where-Object {
$_.Name -like '*TransactionMobile*' -or
$_.Name -like '*TransactionProcessor.Mobile*' -or
$_.PackageFamilyName -like '*TransactionMobile*' -or
$_.PackageFamilyName -like '*TransactionProcessor.Mobile*' -or
$_.InstallLocation -like '*TransactionProcessor.Mobile*'
} |
Sort-Object InstallDate -Descending |
Select-Object -First 1

if ($null -eq $package) {
Write-Host ("Attempt {0}: installed app not visible yet, waiting 5 seconds." -f $attempt)
Start-Sleep -Seconds 5
}
}

if ($null -eq $package) {
Write-Error "Unable to find the installed TransactionProcessor.Mobile package."
Get-AppxPackage -AllUsers | Sort-Object Name | Select-Object Name, PackageFamilyName, InstallLocation | Format-Table -AutoSize
exit 1
}

$windowsAppId = "$($package.PackageFamilyName)!App"
Write-Host "Resolved Windows app id: $windowsAppId"
"windows_app_id=$windowsAppId" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8

- name: Prepare Windows UI test settings
id: windows_settings
shell: powershell
run: |
$settingsPath = Join-Path $env:RUNNER_TEMP "windows-ui-tests.runsettings"
Copy-Item -Path "TransactionProcessor.Mobile.UITests.Windows.runsettings" -Destination $settingsPath -Force
[xml]$settingsXml = Get-Content -Raw $settingsPath
$nodes = $settingsXml.SelectNodes("//EnvironmentVariables/UITEST_WINDOWS_APP_ID")
if ($nodes.Count -ne 1) {
throw "Expected exactly one UITEST_WINDOWS_APP_ID entry in the runsettings template."
}

$nodes.Item(0).InnerText = "${{ steps.windows_app.outputs.windows_app_id }}"
$settingsXml.Save($settingsPath)
"runsettings_path=$settingsPath" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8

- name: Run Windows End To End Tests
run: dotnet test TransactionProcessor.Mobile.UiTests/TransactionProcessor.Mobile.UiTests.csproj --filter "Category=PRTest&Category=Windows" --no-restore
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "Category=PRTest&Category=Windows" --no-restore --settings "${{ steps.windows_settings.outputs.runsettings_path }}"
#run: dotnet test TransactionProcessor.Mobile.UiTests/TransactionProcessor.Mobile.UiTests.csproj --list-tests -v:d

- name: Upload Logs on Failure
Expand Down
56 changes: 51 additions & 5 deletions .github/workflows/windows_navigation_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@ jobs:
nohup appium --log appium.log &

- name: Restore MAUI App for Windows
run: dotnet restore TransactionProcessor.Mobile.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json

- name: Build Code
run: dotnet build TransactionProcessor.Mobile/TransactionProcessor.Mobile.csproj -f net10.0-android -c Release --no-restore
run: dotnet restore TransactionProcessor.Mobile.sln --source ${{ secrets.PUBLICFEEDURL }} --source ${{ secrets.PRIVATEFEED_URL }} --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json

- name: Decrypt PFX File
run: |
Expand Down Expand Up @@ -86,8 +83,57 @@ jobs:
Add-AppxPackage -Path $msixPackage.FullName -ForceApplicationShutdown
}

- name: Resolve Windows UI test app id
id: windows_app
shell: powershell
run: |
$package = $null
for ($attempt = 1; $attempt -le 12 -and $null -eq $package; $attempt++) {
$package = Get-AppxPackage -AllUsers |
Where-Object {
$_.Name -like '*TransactionMobile*' -or
$_.Name -like '*TransactionProcessor.Mobile*' -or
$_.PackageFamilyName -like '*TransactionMobile*' -or
$_.PackageFamilyName -like '*TransactionProcessor.Mobile*' -or
$_.InstallLocation -like '*TransactionProcessor.Mobile*'
} |
Sort-Object InstallDate -Descending |
Select-Object -First 1

if ($null -eq $package) {
Write-Host ("Attempt {0}: installed app not visible yet, waiting 5 seconds." -f $attempt)
Start-Sleep -Seconds 5
}
}

if ($null -eq $package) {
Write-Error "Unable to find the installed TransactionProcessor.Mobile package."
Get-AppxPackage -AllUsers | Sort-Object Name | Select-Object Name, PackageFamilyName, InstallLocation | Format-Table -AutoSize
exit 1
}

$windowsAppId = "$($package.PackageFamilyName)!App"
Write-Host "Resolved Windows app id: $windowsAppId"
"windows_app_id=$windowsAppId" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8

- name: Prepare Windows UI test settings
id: windows_settings
shell: powershell
run: |
$settingsPath = Join-Path $env:RUNNER_TEMP "windows-ui-tests.runsettings"
Copy-Item -Path "TransactionProcessor.Mobile.UITests.Windows.runsettings" -Destination $settingsPath -Force
[xml]$settingsXml = Get-Content -Raw $settingsPath
$nodes = $settingsXml.SelectNodes("//EnvironmentVariables/UITEST_WINDOWS_APP_ID")
if ($nodes.Count -ne 1) {
throw "Expected exactly one UITEST_WINDOWS_APP_ID entry in the runsettings template."
}

$nodes.Item(0).InnerText = "${{ steps.windows_app.outputs.windows_app_id }}"
$settingsXml.Save($settingsPath)
"runsettings_path=$settingsPath" | Out-File -FilePath $env:GITHUB_OUTPUT -Append -Encoding utf8

- name: Run Windows Navigation Tests
run: dotnet test TransactionProcessor.Mobile.UiTests/TransactionProcessor.Mobile.UiTests.csproj --filter "(Category=PRNavTest)&(Category=Windows)" --no-restore
run: dotnet test TransactionProcessor.Mobile.UITests/TransactionProcessor.Mobile.UITests.csproj --filter "(Category=PRNavTest)&(Category=Windows)" --no-restore --settings "${{ steps.windows_settings.outputs.runsettings_path }}"

- name: Upload Appium Logs on Failure
if: always()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using SecurityService.Client;
using SecurityService.Client;
using SecurityService.DataTransferObjects;
using Shared.Results;
using SimpleResults;
Expand Down Expand Up @@ -105,4 +105,4 @@ public async Task<Result<TokenResponseModel>> RefreshAccessToken(String refreshT
}
}
}
}
}
10 changes: 10 additions & 0 deletions TransactionProcessor.Mobile.UITests.Android.runsettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<EnvironmentVariables>
<UITEST_PLATFORM>Android</UITEST_PLATFORM>
<UITEST_ANDROID_APP_PATH>G:\Git\TransactionProcessing\TransactionMobile\TransactionProcessor.Mobile\bin\Debug\net10.0-android\com.transactionprocessor.mobile-Signed.apk</UITEST_ANDROID_APP_PATH>
<UITEST_APPIUM_STARTUP_TIMEOUT_SECONDS>180</UITEST_APPIUM_STARTUP_TIMEOUT_SECONDS>
</EnvironmentVariables>
</RunConfiguration>
</RunSettings>
10 changes: 10 additions & 0 deletions TransactionProcessor.Mobile.UITests.Windows.runsettings
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
<RunConfiguration>
<EnvironmentVariables>
<UITEST_PLATFORM>Windows</UITEST_PLATFORM>
<UITEST_WINDOWS_APP_ID>TransactionMobile_zct748q4xfh0m!App</UITEST_WINDOWS_APP_ID>
<UITEST_APPIUM_STARTUP_TIMEOUT_SECONDS>180</UITEST_APPIUM_STARTUP_TIMEOUT_SECONDS>
</EnvironmentVariables>
</RunConfiguration>
</RunSettings>
Loading
Loading