From adaf03e777c23c76a2b1f9101d25de23f67d23c7 Mon Sep 17 00:00:00 2001 From: Freddy Kristiansen Date: Wed, 2 Aug 2023 11:18:24 +0200 Subject: [PATCH] E2E test (#635) - End 2 End test covering special characters (on Windows and Linux) - Support for running End 2 End tests locally on new single repo AL-Go Development setup Fails with this: ![image](https://github.com/microsoft/AL-Go/assets/10775043/ed7c1838-300e-4483-8718-ead2192dab57) when run on preview today. Running on main, the test passes and produces output like: ![image](https://github.com/microsoft/AL-Go/assets/10775043/23c9ae23-be97-46ab-a87a-86f3901bcd23) --------- Co-authored-by: freddydk Co-authored-by: Maria Zhelezova <43066499+mazhelez@users.noreply.github.com> --- Scenarios/Contribute.md | 18 ++-- e2eTests/Test-AL-Go.ps1 | 2 +- .../Workflows/Run-UpdateAlGoSystemFiles.ps1 | 2 +- e2eTests/e2eTestHelper.psm1 | 41 ++++++- .../scenarios/SpecialCharacters/runtest.ps1 | 102 ++++++++++++++++++ .../UseProjectDependencies/runtest.ps1 | 2 +- 6 files changed, 153 insertions(+), 14 deletions(-) create mode 100644 e2eTests/scenarios/SpecialCharacters/runtest.ps1 diff --git a/Scenarios/Contribute.md b/Scenarios/Contribute.md index 107857e02..1d6bb38b2 100644 --- a/Scenarios/Contribute.md +++ b/Scenarios/Contribute.md @@ -66,14 +66,16 @@ End to end testing will create a lot of repositories called tmpXYZ, where XYZ is You can run the *Cleanup after failed E2E* workflow to cleanup these repositories. You can also run the end to end tests directly from VS Code, by providing the following global variables: -- $global:E2EgitHubOwner -- $global:SecureE2EPAT -- $global:SecureAdminCenterApiToken -- $global:SecureLicenseFileUrl -- $global:SecureInsiderSasToken - -Where E2EgitHubOwner is of type string and the other global variables is of type SecureString. -Running end to end tests in VS Code will use your 3 deployed template repositories for running the tests. + +|Variable|Type|Description| +|---|---|---| +|$global:E2EgitHubOwner| String | The GitHub owner of the test repositories (like `freddydk` or `microsoft`) | +|$global:SecureE2EPAT| SecureString | A personal access token with workflow permissions | +|$global:SecureAdminCenterApiToken| SecureString | Admin Center API Credentials | +|$global:SecureLicenseFileUrl| SecureString | Direct download URL to a license file | +|$global:SecureInsiderSasToken | SecureString | The Insider SAS Token from https://aka.ms/collaborate | +|$global:pteTemplate| String | URL for your PTE template (like `freddyk/AL-Go-PTE@main` or `freddydk/AL-Go@main\|Templates/Per Tenant Extension` for direct AL-Go development) | +|$global:appSourceTemplate| String | URL for your PTE template (like `freddyk/AL-Go-AppSource@main` or `freddydk/AL-Go@main\|Templates/AppSource App` for direct AL-Go development) | --- [back](../README.md) diff --git a/e2eTests/Test-AL-Go.ps1 b/e2eTests/Test-AL-Go.ps1 index 24ec7dcba..88dfc570c 100644 --- a/e2eTests/Test-AL-Go.ps1 +++ b/e2eTests/Test-AL-Go.ps1 @@ -96,7 +96,7 @@ else { $projectSettingsFiles = @(".AL-Go\settings.json") } -$template = "https://github.com/$($template)@main" +$template = "https://github.com/$template" # Login SetTokenAndRepository -github:$github -githubOwner $githubOwner -token $token -repository $repository diff --git a/e2eTests/Workflows/Run-UpdateAlGoSystemFiles.ps1 b/e2eTests/Workflows/Run-UpdateAlGoSystemFiles.ps1 index 180a094a8..af3890c4d 100644 --- a/e2eTests/Workflows/Run-UpdateAlGoSystemFiles.ps1 +++ b/e2eTests/Workflows/Run-UpdateAlGoSystemFiles.ps1 @@ -13,7 +13,7 @@ } $workflowName = 'Update AL-Go System Files' $parameters = @{ - "templateUrl" = $templateUrl + "templateUrl" = $templateUrl.Split('|')[0] "directCommit" = @("Y","N")[!$directCommit] } RunWorkflow -name $workflowName -parameters $parameters -wait:$wait -branch $branch -repository $repository diff --git a/e2eTests/e2eTestHelper.psm1 b/e2eTests/e2eTestHelper.psm1 index 2041f3a20..54ef5ee1c 100644 --- a/e2eTests/e2eTestHelper.psm1 +++ b/e2eTests/e2eTestHelper.psm1 @@ -301,7 +301,7 @@ function CreateNewAppInFolder { ) $al = @( - "pageextension $objID CustListExt$name extends ""Customer List""" + "pageextension $objID ""CustListExt$name"" extends ""Customer List""" "{" " trigger OnOpenPage();" " begin" @@ -343,6 +343,16 @@ function CreateAlGoRepository { if (!$repository) { $repository = $defaultRepository } + $waitMinutes = Get-Random -Minimum 0 -Maximum 4 + $templateFolder = '' + if ($template.Contains('|')) { + # In order to run tests on the direct AL-Go Development branch, specify the folder in which the template is located after a | character in template + # example: "https://github.com/freddydk/AL-Go@branch|Templates/Per Tenant Extension" + $templateFolder = $template.Split('|')[1] + $templateOwner = $template.Split('/')[3] + $template = $template.Split('|')[0] + $waitMinutes = 0 # Do not wait when running tests on direct AL-Go Development branch + } if (!$template.Contains('@')) { $template += '@main' } @@ -353,6 +363,10 @@ function CreateAlGoRepository { $path = Join-Path $tempPath ([GUID]::NewGuid().ToString()) New-Item $path -ItemType Directory | Out-Null Set-Location $path + if ($waitMinutes) { + Write-Host "Waiting $waitMinutes minutes" + Start-Sleep -seconds ($waitMinutes*60) + } if ($private) { Write-Host -ForegroundColor Yellow "`nCreating private repository $repository (based on $template)" invoke-gh repo create $repository --private --clone @@ -371,9 +385,30 @@ function CreateAlGoRepository { $tempRepoPath = Join-Path $tempPath ([GUID]::NewGuid().ToString()) Expand-Archive -Path $zipFileName -DestinationPath $tempRepoPath - Copy-Item (Join-Path (Get-Item "$tempRepoPath\*").FullName '*') -Destination . -Recurse -Force + Copy-Item (Join-Path (Get-Item "$tempRepoPath/*/$templateFolder").FullName '*') -Destination . -Recurse -Force Remove-Item -Path $tempRepoPath -Force -Recurse Remove-Item -Path $zipFileName -Force + if ($templateFolder) { + # This is a direct AL-Go development repository + # Replace URL's + references to microsoft/AL-Go-Actions with $templateOwner/AL-Go/Actions + Get-ChildItem -Path . -File -Recurse | ForEach-Object { + $file = $_.FullName + $lines = Get-Content -Encoding UTF8 -path $file + + # Replace URL's to actions repository first + $regex = "^(.*)https:\/\/raw\.githubusercontent\.com\/microsoft\/AL-Go-Actions\/main(.*)$" + $replace = "`$1https://raw.githubusercontent.com/$($templateOwner)/AL-Go/$($templateBranch)/Actions`$2" + $lines = $lines | ForEach-Object { $_ -replace $regex, $replace } + + # Replace AL-Go-Action references + $regex = "^(.*)microsoft\/AL-Go-Actions(.*)main(.*)$" + $replace = "`$1$($templateOwner)/AL-Go/Actions`$2$($templateBranch)`$3" + $lines = $lines | ForEach-Object { $_ -replace $regex, $replace } + + [System.IO.File]::WriteAllText($file, "$($lines -join "`n")`n") + } + } + if ($projects) { # Make Repo multi-project $projects | ForEach-Object { @@ -523,7 +558,7 @@ function RemoveRepository { @((invoke-gh api -H "Accept: application/vnd.github+json" /orgs/$owner/packages?package_type=nuget -silent -returnvalue -ErrorAction SilentlyContinue | ConvertFrom-Json)) | Where-Object { $_.PSObject.Properties.Name -eq 'repository' } | Where-Object { $_.repository.full_name -eq $repository } | ForEach-Object { Write-Host "+ package $($_.name)" # Pipe empty string into GH API --METHOD DELETE due to https://github.com/cli/cli/issues/3937 - '' | invoke-gh api --method DELETE -H "Accept: application/vnd.github+json" /orgs/$owner/packages/nuget/$($_.name) --input - + '' | invoke-gh api --method DELETE -H "Accept: application/vnd.github+json" /orgs/$owner/packages/nuget/$($_.name) --input } } catch { diff --git a/e2eTests/scenarios/SpecialCharacters/runtest.ps1 b/e2eTests/scenarios/SpecialCharacters/runtest.ps1 new file mode 100644 index 000000000..e13739150 --- /dev/null +++ b/e2eTests/scenarios/SpecialCharacters/runtest.ps1 @@ -0,0 +1,102 @@ +Param( + [switch] $github, + [string] $githubOwner = $global:E2EgithubOwner, + [string] $repoName = [System.IO.Path]::GetFileNameWithoutExtension([System.IO.Path]::GetTempFileName()), + [string] $token = ($Global:SecureE2EPAT | Get-PlainText), + [string] $pteTemplate = $global:pteTemplate, + [string] $appSourceTemplate = $global:appSourceTemplate, + [string] $adminCenterApiToken = ($global:SecureAdminCenterApiToken | Get-PlainText), + [string] $licenseFileUrl = ($global:SecureLicenseFileUrl | Get-PlainText), + [string] $insiderSasToken = ($global:SecureInsiderSasToken | Get-PlainText) +) + +Write-Host -ForegroundColor Yellow @' +# _____ _ _ _____ _ _ +# / ____| (_) | | / ____| | | | +# | (___ _ __ ___ ___ _ __ _| | | | | |__ __ _ _ __ __ _ ___| |_ ___ _ __ ___ +# \___ \| '_ \ / _ \/ __| |/ _` | | | | | '_ \ / _` | '__/ _` |/ __| __/ _ \ '__/ __| +# ____) | |_) | __/ (__| | (_| | | | |____| | | | (_| | | | (_| | (__| || __/ | \__ \ +# |_____/| .__/ \___|\___|_|\__,_|_| \_____|_| |_|\__,_|_| \__,_|\___|\__\___|_| |___/ +# | | +# |_| +# This test tests the following scenario: +# +# - Create a new repository based on the PTE template with 1 app +# - Æøå-app with publisher Süß +# - Set RepoName to Privé +# - Run the "CI/CD" workflow +# - Check artifacts generated +# - Set runs-on to ubuntu-latest (and use CompilerFolder) +# - Run the "CI/CD" workflow again +# - Check artifacts generated +# - Cleanup repositories +# +'@ + +$errorActionPreference = "Stop"; $ProgressPreference = "SilentlyContinue"; Set-StrictMode -Version 2.0 +$prevLocation = Get-Location + +Remove-Module e2eTestHelper -ErrorAction SilentlyContinue +Import-Module (Join-Path $PSScriptRoot "..\..\e2eTestHelper.psm1") -DisableNameChecking + +$repository = "$githubOwner/$repoName" +$branch = "main" + +$template = "https://github.com/$pteTemplate" + +# Login +SetTokenAndRepository -github:$github -githubOwner $githubOwner -token $token -repository $repository + +$appName = 'Æøå-app' +$publisherName = 'Süß' +$RepoName = 'Privé' + +# Create repository1 +CreateAlGoRepository ` + -github:$github ` + -template $template ` + -repository $repository ` + -branch $branch ` + -contentScript { + Param([string] $path) + $global:id = CreateNewAppInFolder -folder $path -name $appName -publisher $publisherName + Add-PropertiesToJsonFile -path (Join-Path $path '.github/AL-Go-Settings.json') -properties @{ "RepoName" = $repoName } + } + +$repoPath = (Get-Location).Path +$run = Run-CICD -repository $repository -branch $branch + +# Wait for CI/CD workflow of repository1 to finish +WaitWorkflow -repository $repository -runid $run.id + +# test artifacts generated in repository1 +Test-ArtifactsFromRun -runid $run.id -folder 'artifacts' -expectedArtifacts @{"Apps"=1;"TestApps"=0;"Dependencies"=0} -repoVersion '1.0' -appVersion '1.0' +Push-Location "artifacts/$repoName-main-Apps-1.0*" +Get-Item -Path "$($publisherName)_$($appName)_1.0*" | Should -Not -BeNullOrEmpty +Pop-Location + +# Remove downloaded artifacts +Remove-Item -Path 'artifacts' -Recurse -Force + +Pull + +# Set GitHubRunner and runs-on to ubuntu-latest (and use CompilerFolder) +Add-PropertiesToJsonFile -path '.github/AL-Go-Settings.json' -properties @{ "runs-on" = "ubuntu-latest"; "gitHubRunner" = "ubuntu-latest"; "UseCompilerFolder" = $true; "doNotPublishApps" = $true } + +# Push +CommitAndPush -commitMessage 'Shift to Linux' + +# Upgrade AL-Go System Files +Run-UpdateAlGoSystemFiles -directCommit -commitMessage 'Update system files' -wait -templateUrl $template + +$run = Run-CICD -repository $repository -branch $branch -wait + +# test artifacts generated in repository1 +Test-ArtifactsFromRun -runid $run.id -folder 'artifacts' -expectedArtifacts @{"Apps"=1;"TestApps"=0;"Dependencies"=0} -repoVersion '1.0' -appVersion '1.0' +Push-Location "artifacts/$repoName-main-Apps-1.0*" +Get-Item -Path "$($publisherName)_$($appName)_1.0*" | Should -Not -BeNullOrEmpty +Pop-Location + +Set-Location $prevLocation + +RemoveRepository -repository $repository -path $repoPath diff --git a/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 b/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 index 435863e4d..b8b121451 100644 --- a/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 +++ b/e2eTests/scenarios/UseProjectDependencies/runtest.ps1 @@ -49,7 +49,7 @@ Import-Module (Join-Path $PSScriptRoot "..\..\e2eTestHelper.psm1") -DisableNameC $repository = "$githubOwner/$repoName" $branch = "main" -$template = "https://github.com/$($pteTemplate)@main" +$template = "https://github.com/$pteTemplate" # Login SetTokenAndRepository -github:$github -githubOwner $githubOwner -token $token -repository $repository