diff --git a/build/azure-pipelines.yml b/build/azure-pipelines.yml index 60c7a70e47..d798e0de48 100644 --- a/build/azure-pipelines.yml +++ b/build/azure-pipelines.yml @@ -99,6 +99,208 @@ stages: inputs: command: test projects: '**\Umbraco.Tests.Integration.csproj' + - stage: Acceptance_Tests + displayName: Acceptance Tests + dependsOn: [] + variables: + - name: Umbraco__CMS__Unattended__InstallUnattended + value: true + - name: Umbraco__CMS__Unattended__UnattendedUserName + value: Cypress Test + - name: Umbraco__CMS__Unattended__UnattendedUserEmail + value: cypress@umbraco.com + - name: Umbraco__CMS__Unattended__UnattendedUserPassword + value: UmbracoAcceptance123! + jobs: + - job: Windows_Acceptance_tests + variables: + - name: UmbracoDatabaseServer + value: (LocalDB)\MSSQLLocalDB + - name: UmbracoDatabaseName + value: Cypress + - name: ConnectionStrings__umbracoDbDSN + value: Server=$(UmbracoDatabaseServer);Database=$(UmbracoDatabaseName);Integrated Security=true; + displayName: Windows + pool: + vmImage: windows-latest + steps: + - task: UseDotNet@2 + displayName: Use .Net Core sdk 5.x + inputs: + version: 5.x + + - powershell: sqllocaldb start mssqllocaldb + displayName: Start MSSQL LocalDb + - powershell: Invoke-Sqlcmd -Query "CREATE DATABASE $env:UmbracoDatabaseName" -ServerInstance $env:UmbracoDatabaseServer + displayName: Create database +# - task: DotNetCoreCLI@2 +# displayName: dotnet build (Netcore) +# inputs: +# command: build +# projects: '**/Umbraco.Web.UI.Netcore.csproj' + - task: NodeTool@0 + displayName: Use Node 11.x + inputs: + versionSpec: 11.x + - task: Npm@1 + displayName: npm install (Client) + inputs: + workingDir: src\Umbraco.Web.UI.Client + verbose: false + - task: gulp@0 + displayName: gulp build + inputs: + gulpFile: src\Umbraco.Web.UI.Client\gulpfile.js + targets: build + workingDirectory: src\Umbraco.Web.UI.Client + - powershell: Start-Process -FilePath "dotnet" -ArgumentList "run", "-p", "src\Umbraco.Web.UI.Netcore\Umbraco.Web.UI.Netcore.csproj" + displayName: dotnet run (Netcore) +# - powershell: dotnet run --no-build -p .\src\Umbraco.Web.UI.NetCore\Umbraco.Web.UI.NetCore.csproj +# displayName: dotnet run (Netcore) + - task: PowerShell@1 + displayName: Generate Cypress.env.json + inputs: + scriptType: inlineScript + inlineScript: > + @{ username = $env:Umbraco__CMS__Unattended__UnattendedUserEmail; password = $env:Umbraco__CMS__Unattended__UnattendedUserPassword } | ConvertTo-Json | Set-Content -Path "src\Umbraco.Tests.AcceptanceTest\cypress.env.json" + - task: Npm@1 + name: PrepareTask + displayName: npm install (AcceptanceTest) + inputs: + workingDir: 'src\Umbraco.Tests.AcceptanceTest' + - task: Npm@1 + displayName: Run Cypress (Desktop) + condition: always() + continueOnError: true + inputs: + workingDir: src\Umbraco.Tests.AcceptanceTest + command: 'custom' + customCommand: 'run test -- --reporter junit --reporter-options "mochaFile=results/test-output-D-[hash].xml,toConsole=true" --config="viewportHeight=1600,viewportWidth=2560,screenshotsFolder=cypress/artifacts/desktop/screenshots,videosFolder=cypress/artifacts/desktop/videos,videoUploadOnPasses=false"' + + - task: PublishTestResults@2 + condition: always() + inputs: + testResultsFormat: 'JUnit' + testResultsFiles: 'src/Umbraco.Tests.AcceptanceTest/results/test-output-D-*.xml' + mergeTestResults: true + testRunTitle: "Test results Desktop" +# - task: Npm@1 +# displayName: Run Cypress (Tablet portrait) +# condition: always() +# inputs: +# workingDir: src\Umbraco.Tests.AcceptanceTest +# command: 'custom' +# customCommand: 'run test -- --config="viewportHeight=1366,viewportWidth=1024,screenshotsFolder=cypress/artifacts/tablet/screenshots,videosFolder=cypress/artifacts/tablet/videos,videoUploadOnPasses=false"' +# +# - task: Npm@1 +# displayName: Run Cypress (Mobile protrait) +# condition: always() +# inputs: +# workingDir: src\Umbraco.Tests.AcceptanceTest +# command: 'custom' +# customCommand: 'run test -- --config="viewportHeight=812,viewportWidth=375,screenshotsFolder=cypress/artifacts/mobile/screenshots,videosFolder=cypress/artifacts/mobile/videos,videoUploadOnPasses=false"' + - task: PublishPipelineArtifact@1 + displayName: "Publish test artifacts" + condition: failed() + inputs: + targetPath: '$(Build.SourcesDirectory)/src/Umbraco.Tests.AcceptanceTest/cypress/artifacts' + artifact: 'Test artifacts - Windows' + - job: Linux_Acceptance_tests + displayName: Linux + variables: + - name: UmbracoDatabaseServer + value: localhost + - name: UmbracoDatabaseName + value: Cypress + - name: ConnectionStrings__umbracoDbDSN + value: Server=localhost,1433;Database=$(UmbracoDatabaseName);User Id=sa;Password=$(SA_PASSWORD); + services: + mssql: mssql + pool: + vmImage: ubuntu-latest + steps: + - task: UseDotNet@2 + displayName: Use .Net Core sdk 5.x + inputs: + version: 5.x + - task: Bash@3 + displayName: Create database + inputs: + targetType: 'inline' + script: 'sqlcmd -S . -U sa -P $SA_PASSWORD -Q "CREATE DATABASE $DBNAME"' + env: + DBNAME: $(UmbracoDatabaseName) + SA_PASSWORD: $(SA_PASSWORD) + - task: NodeTool@0 + displayName: Use Node 11.x + inputs: + versionSpec: 11.x + - task: Npm@1 + displayName: npm install (Client) + inputs: + workingDir: src/Umbraco.Web.UI.Client + verbose: false + - task: gulp@0 + displayName: gulp build + inputs: + gulpFile: src/Umbraco.Web.UI.Client/gulpfile.js + targets: build + workingDirectory: src/Umbraco.Web.UI.Client + - task: Bash@3 + displayName: dotnet run (Netcore) + inputs: + targetType: 'inline' + script: 'nohup dotnet run -p ./src/Umbraco.Web.UI.NetCore/Umbraco.Web.UI.NetCore.csproj &' + - task: Bash@3 + displayName: Generate Cypress.env.json + inputs: + targetType: 'inline' + script: 'echo "{ \"username\": \"$USERNAME\", \"password\": \"$PASSWORD\" }" > "src/Umbraco.Tests.AcceptanceTest/cypress.env.json"' + env: + USERNAME: $(Umbraco__CMS__Unattended__UnattendedUserEmail) + PASSWORD: $(Umbraco__CMS__Unattended__UnattendedUserPassword) + - task: Npm@1 + name: PrepareTask + displayName: npm install (AcceptanceTest) + inputs: + workingDir: 'src/Umbraco.Tests.AcceptanceTest' + - task: Npm@1 + displayName: Run Cypress (Desktop) + condition: always() + continueOnError: true + inputs: + workingDir: src/Umbraco.Tests.AcceptanceTest + command: 'custom' + customCommand: 'run test -- --reporter junit --reporter-options "mochaFile=results/test-output-D-[hash].xml,toConsole=true" --config="viewportHeight=1600,viewportWidth=2560,screenshotsFolder=cypress/artifacts/desktop/screenshots,videosFolder=cypress/artifacts/desktop/videos,videoUploadOnPasses=false"' + + - task: PublishTestResults@2 + condition: always() + inputs: + testResultsFormat: 'JUnit' + testResultsFiles: 'src/Umbraco.Tests.AcceptanceTest/results/test-output-D-*.xml' + mergeTestResults: true + testRunTitle: "Test results Desktop" + # - task: Npm@1 + # displayName: Run Cypress (Tablet portrait) + # condition: always() + # inputs: + # workingDir: src/Umbraco.Tests.AcceptanceTest + # command: 'custom' + # customCommand: 'run test -- --config="viewportHeight=1366,viewportWidth=1024,screenshotsFolder=cypress/artifacts/tablet/screenshots,videosFolder=cypress/artifacts/tablet/videos,videoUploadOnPasses=false"' + # + # - task: Npm@1 + # displayName: Run Cypress (Mobile protrait) + # condition: always() + # inputs: + # workingDir: src/Umbraco.Tests.AcceptanceTest + # command: 'custom' + # customCommand: 'run test -- --config="viewportHeight=812,viewportWidth=375,screenshotsFolder=cypress/artifacts/mobile/screenshots,videosFolder=cypress/artifacts/mobile/videos,videoUploadOnPasses=false"' + - task: PublishPipelineArtifact@1 + displayName: "Publish test artifacts" + condition: failed() + inputs: + targetPath: '$(Build.SourcesDirectory)/src/Umbraco.Tests.AcceptanceTest/cypress/artifacts' + artifact: 'Test artifacts - Linux' - stage: Artifacts dependsOn: [] jobs: diff --git a/src/Umbraco.Tests.AcceptanceTest/cypress.json b/src/Umbraco.Tests.AcceptanceTest/cypress.json index 33978211ed..340eede2a0 100644 --- a/src/Umbraco.Tests.AcceptanceTest/cypress.json +++ b/src/Umbraco.Tests.AcceptanceTest/cypress.json @@ -7,5 +7,9 @@ "password": "" }, "supportFile": "cypress/support/index.ts", - "videoUploadOnPasses" : false + "videoUploadOnPasses" : false, + "retries": { + "runMode": 5, + "openMode": 1 + } } diff --git a/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/languages.ts b/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/languages.ts index 541c6d213d..43f32a0821 100644 --- a/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/languages.ts +++ b/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/languages.ts @@ -6,7 +6,10 @@ context('Languages', () => { }); it('Add language', () => { - const name = "Afrikaans"; // Must be an option in the select box + // For some reason the languages to chose fom seems to be translated differently than normal, as an example: + // My system is set to EN (US), but most languages are translated into Danish for some reason + // Aghem seems untranslated though? + const name = "Aghem"; // Must be an option in the select box cy.umbracoEnsureLanguageNameNotExists(name); diff --git a/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/templates.ts b/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/templates.ts index 3122c3ebf7..8e0eed9154 100644 --- a/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/templates.ts +++ b/src/Umbraco.Tests.AcceptanceTest/cypress/integration/Settings/templates.ts @@ -23,6 +23,9 @@ context('Templates', () => { cy.umbracoEnsureTemplateNameNotExists(name); createTemplate(); + // We have to wait for the ace editor to load, because when the editor is loading it will "steal" the focus briefly, + // which causes the save event to fire if we've added something to the header field, causing errors. + cy.wait(500); //Type name cy.umbracoEditorHeaderName(name); // Save diff --git a/src/Umbraco.Tests.AcceptanceTest/cypress/plugins/index.js b/src/Umbraco.Tests.AcceptanceTest/cypress/plugins/index.js index 59283feec5..51b79a1fef 100644 --- a/src/Umbraco.Tests.AcceptanceTest/cypress/plugins/index.js +++ b/src/Umbraco.Tests.AcceptanceTest/cypress/plugins/index.js @@ -11,6 +11,7 @@ // This function is called when a project is opened or re-opened (e.g. due to // the project's config changing) +const del = require('del') /** * @type {Cypress.PluginConfig} @@ -24,5 +25,13 @@ module.exports = (on, config) => { config.baseUrl = baseUrl; } + on('after:spec', (spec, results) => { + if(results.stats.failures === 0 && results.video) { + // `del()` returns a promise, so it's important to return it to ensure + // deleting the video is finished before moving + return del(results.video) + } + }) + return config; } diff --git a/src/Umbraco.Tests.AcceptanceTest/package.json b/src/Umbraco.Tests.AcceptanceTest/package.json index 378fe719fc..b443390d1e 100644 --- a/src/Umbraco.Tests.AcceptanceTest/package.json +++ b/src/Umbraco.Tests.AcceptanceTest/package.json @@ -7,7 +7,8 @@ }, "devDependencies": { "cross-env": "^7.0.2", - "cypress": "^6.0.1", + "cypress": "^6.7.0", + "del": "^6.0.0", "ncp": "^2.0.0", "prompt": "^1.0.0", "umbraco-cypress-testhelpers": "^1.0.0-beta-52" diff --git a/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json b/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json index b16945dcb0..4edb56f7fa 100644 --- a/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json +++ b/src/Umbraco.Web.UI.NetCore/Properties/launchSettings.json @@ -20,7 +20,7 @@ "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "applicationUrl": "https://localhost:44354;http://localhost:9000" + "applicationUrl": "https://localhost:44331;http://localhost:9000" } } }