diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml index bbce0fcd6..bbeb800c1 100644 --- a/.github/workflows/dev.yml +++ b/.github/workflows/dev.yml @@ -90,10 +90,15 @@ jobs: - name: Load Image run: docker load < squidex-tmp.tar.gz - - name: Replace Image Name + - name: Replace Image Name1 uses: mikefarah/yq@v4.9.1 with: - cmd: yq e '.services.squidex.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex1.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + + - name: Replace Image Name2 + uses: mikefarah/yq@v4.9.1 + with: + cmd: yq e '.services.squidex2.image = "squidex-tmp"' -i backend/tests/docker-compose.yml - name: Start Test run: docker-compose up -d @@ -102,12 +107,24 @@ jobs: - name: RUN TEST uses: kohlerdominik/docker-run-action@v1.0.0 with: - image: mcr.microsoft.com/dotnet/sdk:6.0 + image: squidex/build environment: | CONFIG__WAIT=60 CONFIG__SERVER__URL=http://localhost:8080 default_network: host - options: --name test + options: --name test1 + volumes: ${{ github.workspace }}:/src + run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated + + - name: RUN TEST on path + uses: kohlerdominik/docker-run-action@v1.0.0 + with: + image: squidex/build + environment: | + CONFIG__WAIT=60 + CONFIG__SERVER__URL=http://localhost:8081/squidex + default_network: host + options: --name test2 volumes: ${{ github.workspace }}:/src run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5072f5b41..5642a6ef4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -73,10 +73,15 @@ jobs: - name: Load Image run: docker load < squidex-tmp.tar.gz - - name: Replace Image Name + - name: Replace Image Name1 uses: mikefarah/yq@v4.9.1 with: - cmd: yq e '.services.squidex.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + cmd: yq e '.services.squidex1.image = "squidex-tmp"' -i backend/tests/docker-compose.yml + + - name: Replace Image Name2 + uses: mikefarah/yq@v4.9.1 + with: + cmd: yq e '.services.squidex2.image = "squidex-tmp"' -i backend/tests/docker-compose.yml - name: Start Test run: docker-compose up -d @@ -85,12 +90,24 @@ jobs: - name: RUN TEST uses: kohlerdominik/docker-run-action@v1.0.0 with: - image: mcr.microsoft.com/dotnet/sdk:6.0 + image: squidex/build environment: | CONFIG__WAIT=60 CONFIG__SERVER__URL=http://localhost:8080 default_network: host - options: --name test + options: --name test1 + volumes: ${{ github.workspace }}:/src + run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated + + - name: RUN TEST on path + uses: kohlerdominik/docker-run-action@v1.0.0 + with: + image: squidex/build + environment: | + CONFIG__WAIT=60 + CONFIG__SERVER__URL=http://localhost:8081/squidex + default_network: host + options: --name test2 volumes: ${{ github.workspace }}:/src run: dotnet test /src/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj --filter Category!=NotAutomated diff --git a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj index eb77d918a..a20ab3725 100644 --- a/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj +++ b/backend/src/Squidex.Domain.Apps.Entities.MongoDb/Squidex.Domain.Apps.Entities.MongoDb.csproj @@ -23,7 +23,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj b/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj index 1a8830906..6fa338409 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj +++ b/backend/src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj @@ -34,7 +34,7 @@ - + diff --git a/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj b/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj index 2ba42f114..27c55ccf7 100644 --- a/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj +++ b/backend/src/Squidex.Domain.Users.MongoDb/Squidex.Domain.Users.MongoDb.csproj @@ -24,7 +24,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj b/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj index 760ec1614..0b55c8a73 100644 --- a/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj +++ b/backend/src/Squidex.Infrastructure.MongoDb/Squidex.Infrastructure.MongoDb.csproj @@ -18,8 +18,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj index 35f849641..1f56c70a3 100644 --- a/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj +++ b/backend/src/Squidex.Infrastructure/Squidex.Infrastructure.csproj @@ -31,7 +31,7 @@ - + diff --git a/backend/src/Squidex.Web/Pipeline/SetupMiddleware.cs b/backend/src/Squidex.Web/Pipeline/SetupMiddleware.cs index 99a364ff3..8f7fa3e83 100644 --- a/backend/src/Squidex.Web/Pipeline/SetupMiddleware.cs +++ b/backend/src/Squidex.Web/Pipeline/SetupMiddleware.cs @@ -22,6 +22,12 @@ namespace Squidex.Web.Pipeline public async Task InvokeAsync(HttpContext context, IUserService userService) { + if (context.Request.Query.ContainsKey("skip-setup")) + { + await next(context); + return; + } + if (!isUserFound && await userService.IsEmptyAsync(context.RequestAborted)) { var url = context.Request.PathBase.Add("/identity-server/setup"); diff --git a/backend/src/Squidex/Areas/IdentityServer/Views/Account/AccessDenied.cshtml b/backend/src/Squidex/Areas/IdentityServer/Views/Account/AccessDenied.cshtml index 519cc0630..567bf786d 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Views/Account/AccessDenied.cshtml +++ b/backend/src/Squidex/Areas/IdentityServer/Views/Account/AccessDenied.cshtml @@ -2,7 +2,7 @@ ViewBag.Title = T.Get("users.accessDenied.title"); } - +

@T.Get("users.accessDenied.title")

@@ -11,5 +11,5 @@

- @T.Get("common.logout") + @T.Get("common.logout")

\ No newline at end of file diff --git a/backend/src/Squidex/Areas/IdentityServer/Views/Account/LockedOut.cshtml b/backend/src/Squidex/Areas/IdentityServer/Views/Account/LockedOut.cshtml index d11e8d3c0..04d9f25e7 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Views/Account/LockedOut.cshtml +++ b/backend/src/Squidex/Areas/IdentityServer/Views/Account/LockedOut.cshtml @@ -2,7 +2,7 @@ ViewBag.Title = T.Get("users.lockedOutTitle"); } - +

@T.Get("users.lockedOutTitle")

diff --git a/backend/src/Squidex/Areas/IdentityServer/Views/Account/LogoutCompleted.cshtml b/backend/src/Squidex/Areas/IdentityServer/Views/Account/LogoutCompleted.cshtml index f7f882186..a7ef6f664 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Views/Account/LogoutCompleted.cshtml +++ b/backend/src/Squidex/Areas/IdentityServer/Views/Account/LogoutCompleted.cshtml @@ -2,7 +2,7 @@ ViewBag.Title = T.Get("users.logout.title"); } - +

@T.Get("users.logout.headline")

diff --git a/backend/src/Squidex/Areas/IdentityServer/Views/Error/Error.cshtml b/backend/src/Squidex/Areas/IdentityServer/Views/Error/Error.cshtml index 1804080db..60b248f2c 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Views/Error/Error.cshtml +++ b/backend/src/Squidex/Areas/IdentityServer/Views/Error/Error.cshtml @@ -4,7 +4,7 @@ ViewBag.Title = T.Get("users.error.title"); } - +

@T.Get("users.error.headline")

diff --git a/backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml b/backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml index 5a4c3a478..dae4db68e 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml +++ b/backend/src/Squidex/Areas/IdentityServer/Views/Profile/Profile.cshtml @@ -34,7 +34,7 @@
- +
diff --git a/backend/src/Squidex/Areas/IdentityServer/Views/Setup/Setup.cshtml b/backend/src/Squidex/Areas/IdentityServer/Views/Setup/Setup.cshtml index cde4a5774..76725468f 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Views/Setup/Setup.cshtml +++ b/backend/src/Squidex/Areas/IdentityServer/Views/Setup/Setup.cshtml @@ -67,7 +67,7 @@

@T.Get("setup.headline")

- +
@T.Get("setup.hint") diff --git a/backend/src/Squidex/Areas/IdentityServer/Views/_Layout.cshtml b/backend/src/Squidex/Areas/IdentityServer/Views/_Layout.cshtml index 724596e5d..132fd9814 100644 --- a/backend/src/Squidex/Areas/IdentityServer/Views/_Layout.cshtml +++ b/backend/src/Squidex/Areas/IdentityServer/Views/_Layout.cshtml @@ -8,7 +8,7 @@ @ViewBag.Title - @T.Get("common.product") - + @if (IsSectionDefined("header")) { @@ -16,13 +16,13 @@ } - - + +
- +
diff --git a/backend/src/Squidex/Squidex.csproj b/backend/src/Squidex/Squidex.csproj index 127746983..0103363e5 100644 --- a/backend/src/Squidex/Squidex.csproj +++ b/backend/src/Squidex/Squidex.csproj @@ -60,7 +60,7 @@ - + @@ -74,16 +74,16 @@ - - - - - - - - + + + + + + + + - + diff --git a/backend/tests/docker-compose.yml b/backend/tests/docker-compose.yml index 2ddce960c..17e652353 100644 --- a/backend/tests/docker-compose.yml +++ b/backend/tests/docker-compose.yml @@ -3,18 +3,17 @@ services: mongo: image: mongo:latest ports: - - "27018:27017" + - "27019:27017" networks: - internal - squidex: + squidex1: image: squidex - ports: - - "8080:80" environment: - URLS__BASEURL=http://localhost:8080 - ASSETS__RESIZERURL=http://resizer - EVENTSTORE__MONGODB__CONFIGURATION=mongodb://mongo + - EVENTSTORE__MONGODB__DATABASE=squidex1 - GRAPHQL__CACHEDURATION=0 - IDENTITY__ADMINCLIENTID=root - IDENTITY__ADMINCLIENTSECRET=xeLd6jFxqbXJrfmNLlO2j1apagGGGSyZJhFnIuHp4I0= @@ -22,8 +21,36 @@ services: - SCRIPTING__TIMEOUTEXECUTION=00:00:10 - SCRIPTING__TIMEOUTSCRIPT=00:00:10 - STORE__MONGODB__CONFIGURATION=mongodb://mongo + - STORE__MONGODB__DATABASE=squidex1 + - STORE__MONGODB__CONTENTDATABASE=squidex1_content - STORE__TYPE=MongoDB - - TEMPLATES__LOCALURL=http://localhost:80 + - TEMPLATES__LOCALURL=http://localhost:5000 + - ASPNETCORE_URLS=http://+:5000 + networks: + - internal + depends_on: + - mongo + + squidex2: + image: squidex + environment: + - URLS__BASEURL=http://localhost:8081/squidex/ + - URLS__BASEPATH=squidex/ + - ASSETS__RESIZERURL=http://resizer + - EVENTSTORE__MONGODB__CONFIGURATION=mongodb://mongo + - EVENTSTORE__MONGODB__DATABASE=squidex2 + - GRAPHQL__CACHEDURATION=0 + - IDENTITY__ADMINCLIENTID=root + - IDENTITY__ADMINCLIENTSECRET=xeLd6jFxqbXJrfmNLlO2j1apagGGGSyZJhFnIuHp4I0= + - IDENTITY__MULTIPLEDOMAINS=true + - SCRIPTING__TIMEOUTEXECUTION=00:00:10 + - SCRIPTING__TIMEOUTSCRIPT=00:00:10 + - STORE__MONGODB__CONFIGURATION=mongodb://mongo + - STORE__MONGODB__DATABASE=squidex2 + - STORE__MONGODB__CONTENTDATABASE=squidex2_content + - STORE__TYPE=MongoDB + - TEMPLATES__LOCALURL=http://localhost:5000 + - ASPNETCORE_URLS=http://+:5000 networks: - internal depends_on: @@ -31,12 +58,38 @@ services: resizer: image: squidex/resizer:dev-40 - ports: - - "8081:80" networks: - internal depends_on: - mongo + + squidex_proxy1: + image: squidex/caddy-proxy + ports: + - "8080:8080" + environment: + - SITE_ADDRESS=http://localhost:8080 + - SITE_PATH=* + - SITE_SERVER="squidex1:5000" + depends_on: + - squidex1 + networks: + - internal + restart: unless-stopped + + squidex_proxy2: + image: squidex/caddy-proxy-path + ports: + - "8081:8081" + environment: + - SITE_ADDRESS=http://localhost:8081 + - SITE_PATH=/squidex/* + - SITE_SERVER="squidex2:5000" + depends_on: + - squidex2 + networks: + - internal + restart: unless-stopped networks: internal: diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/AssetFixture.cs b/backend/tools/TestSuite/TestSuite.ApiTests/AssetFixture.cs index f709a6d15..ffc6fecfe 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/AssetFixture.cs +++ b/backend/tools/TestSuite/TestSuite.ApiTests/AssetFixture.cs @@ -20,7 +20,7 @@ namespace TestSuite.ApiTests { client.BaseAddress = new Uri(ServerUrl); - var url = asset._links["content"].Href; + var url = asset._links["content"].Href[1..]; if (version > 0) { diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/Assets/Frontend_Home.jpg b/backend/tools/TestSuite/TestSuite.ApiTests/Assets/Frontend_Home.jpg new file mode 100644 index 000000000..2676c4fb6 Binary files /dev/null and b/backend/tools/TestSuite/TestSuite.ApiTests/Assets/Frontend_Home.jpg differ diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/Assets/Frontend_Login.jpg b/backend/tools/TestSuite/TestSuite.ApiTests/Assets/Frontend_Login.jpg new file mode 100644 index 000000000..380a3bb16 Binary files /dev/null and b/backend/tools/TestSuite/TestSuite.ApiTests/Assets/Frontend_Login.jpg differ diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/FrontendTests.cs b/backend/tools/TestSuite/TestSuite.ApiTests/FrontendTests.cs new file mode 100644 index 000000000..4acaa138c --- /dev/null +++ b/backend/tools/TestSuite/TestSuite.ApiTests/FrontendTests.cs @@ -0,0 +1,62 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using Codeuctivity.ImageSharpCompare; +using PuppeteerSharp; +using TestSuite.Fixtures; +using Xunit; + +#pragma warning disable SA1300 // Element should begin with upper-case letter + +namespace TestSuite.ApiTests +{ + public sealed class FrontendTests : IClassFixture + { + public ClientFixture _ { get; } + + public FrontendTests(ClientFixture fixture) + { + _ = fixture; + } + + [Theory] + [InlineData("Frontend_Home", "")] + [InlineData("Frontend_Login", "identity-server/account/login")] + public async Task Should_render_properly(string name, string url) + { + using (var browserFetcher = new BrowserFetcher()) + { + await browserFetcher.DownloadAsync(); + } + + await using var browser = await Puppeteer.LaunchAsync(new LaunchOptions + { + Headless = true, + DefaultViewport = new ViewPortOptions + { + Height = 800, + IsLandscape = true, + IsMobile = false, + Width = 1000 + }, + Args = new string[] + { + "--no-sandbox" + } + }); + + await using var page = await browser.NewPageAsync(); + + await page.GoToAsync(_.ClientManager.Options.Url + url + "?skip-setup"); + await page.ScreenshotAsync($"__{name}.jpg"); + + var diff = ImageSharpCompare.CalcDiff($"__{name}.jpg", $"Assets/{name}.jpg"); + + Assert.InRange(diff.MeanError, 0, 10); + } + } +} diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs b/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs index 5358d23a3..615efa372 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs +++ b/backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs @@ -105,6 +105,14 @@ namespace TestSuite.ApiTests try { await CreateSchemasAsync(); + } + catch + { + // Do nothing + } + + try + { await CreateContentsAsync(); } catch diff --git a/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj b/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj index 0a7612c2a..92d0429ed 100644 --- a/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj +++ b/backend/tools/TestSuite/TestSuite.ApiTests/TestSuite.ApiTests.csproj @@ -14,12 +14,14 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive + @@ -35,6 +37,12 @@ + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj b/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj index 7d3009b94..9be865dad 100644 --- a/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj +++ b/backend/tools/TestSuite/TestSuite.Shared/TestSuite.Shared.csproj @@ -16,7 +16,7 @@ - +