diff --git a/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Cache/MemoryCacheAttributeTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Cache/MemoryCacheAttributeTests.cs index 117aa246fe..70dba70e34 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Cache/MemoryCacheAttributeTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Cache/MemoryCacheAttributeTests.cs @@ -10,6 +10,7 @@ using Moq; using NCrontab; using Xunit; +using static GovUk.Education.ExploreEducationStatistics.Common.Cache.CronSchedules; using static GovUk.Education.ExploreEducationStatistics.Common.Services.CollectionUtils; using static GovUk.Education.ExploreEducationStatistics.Common.Tests.Utils.MockUtils; @@ -18,9 +19,6 @@ namespace GovUk.Education.ExploreEducationStatistics.Common.Tests.Cache; [Collection(CacheTestFixture.CollectionName)] public class MemoryCacheAttributeTests : IClassFixture, IDisposable { - private const string HourlyExpirySchedule = "0 * * * *"; - private const string HalfHourlyExpirySchedule = "*/30 * * * *"; - private readonly Mock _memoryCacheService = new(MockBehavior.Strict); public MemoryCacheAttributeTests() diff --git a/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Services/MemoryCacheServiceTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Services/MemoryCacheServiceTests.cs index 490bf8ba1f..7e9e67593d 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Services/MemoryCacheServiceTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Common.Tests/Services/MemoryCacheServiceTests.cs @@ -11,6 +11,7 @@ using NCrontab; using Xunit; using static System.Globalization.DateTimeStyles; +using static GovUk.Education.ExploreEducationStatistics.Common.Cache.CronSchedules; using static GovUk.Education.ExploreEducationStatistics.Common.Tests.Utils.MockUtils; using static Moq.MockBehavior; @@ -18,8 +19,8 @@ namespace GovUk.Education.ExploreEducationStatistics.Common.Tests.Services; public class MemoryCacheServiceTests { - private readonly CrontabSchedule _hourlyExpirySchedule = CrontabSchedule.Parse("0 * * * *"); - private readonly CrontabSchedule _halfHourlyExpirySchedule = CrontabSchedule.Parse("*/30 * * * *"); + private readonly CrontabSchedule _hourlyExpirySchedule = CrontabSchedule.Parse(HourlyExpirySchedule); + private readonly CrontabSchedule _halfHourlyExpirySchedule = CrontabSchedule.Parse(HalfHourlyExpirySchedule); private record SampleClassSuperclass; diff --git a/src/GovUk.Education.ExploreEducationStatistics.Common/Cache/CronSchedules.cs b/src/GovUk.Education.ExploreEducationStatistics.Common/Cache/CronSchedules.cs new file mode 100644 index 0000000000..50c6027ef0 --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Common/Cache/CronSchedules.cs @@ -0,0 +1,7 @@ +namespace GovUk.Education.ExploreEducationStatistics.Common.Cache; + +public static class CronSchedules +{ + public const string HourlyExpirySchedule = "0 * * * *"; + public const string HalfHourlyExpirySchedule = "*/30 * * * *"; +} \ No newline at end of file diff --git a/src/GovUk.Education.ExploreEducationStatistics.Common/ViewModels/PaginatedListViewModel.cs b/src/GovUk.Education.ExploreEducationStatistics.Common/ViewModels/PaginatedListViewModel.cs index f7832eef94..a4f9645903 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Common/ViewModels/PaginatedListViewModel.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Common/ViewModels/PaginatedListViewModel.cs @@ -4,6 +4,7 @@ using System.Linq; using GovUk.Education.ExploreEducationStatistics.Common.Model; using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; namespace GovUk.Education.ExploreEducationStatistics.Common.ViewModels; @@ -19,6 +20,13 @@ public PaginatedListViewModel(List results, int totalResults, int page, int p Paging = new PagingViewModel(page: page, pageSize: pageSize, totalResults: totalResults); } + [JsonConstructor] + public PaginatedListViewModel(List results, PagingViewModel paging) + { + Results = results; + Paging = paging; + } + /// /// Paginate some results (in memory) that have not been paginated yet. /// diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/PublicationControllerCachingTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/PublicationControllerCachingTests.cs new file mode 100644 index 0000000000..7cb2850596 --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/PublicationControllerCachingTests.cs @@ -0,0 +1,130 @@ +#nullable enable +using System; +using System.Threading.Tasks; +using GovUk.Education.ExploreEducationStatistics.Common.Cache; +using GovUk.Education.ExploreEducationStatistics.Common.Model; +using GovUk.Education.ExploreEducationStatistics.Common.Tests.Extensions; +using GovUk.Education.ExploreEducationStatistics.Common.Tests.Fixtures; +using GovUk.Education.ExploreEducationStatistics.Common.ViewModels; +using GovUk.Education.ExploreEducationStatistics.Content.Api.Cache; +using GovUk.Education.ExploreEducationStatistics.Content.Api.Controllers; +using GovUk.Education.ExploreEducationStatistics.Content.Api.Requests; +using GovUk.Education.ExploreEducationStatistics.Content.Model; +using GovUk.Education.ExploreEducationStatistics.Content.Services.Interfaces; +using GovUk.Education.ExploreEducationStatistics.Content.Services.Interfaces.Cache; +using GovUk.Education.ExploreEducationStatistics.Content.Services.ViewModels; +using Moq; +using NCrontab; +using Xunit; +using static GovUk.Education.ExploreEducationStatistics.Common.Cache.CronSchedules; +using static GovUk.Education.ExploreEducationStatistics.Common.Services.CollectionUtils; +using static GovUk.Education.ExploreEducationStatistics.Common.Tests.Utils.MockUtils; +using static Moq.MockBehavior; +using static Newtonsoft.Json.JsonConvert; + +namespace GovUk.Education.ExploreEducationStatistics.Content.Api.Tests.Controllers; + +[Collection(CacheServiceTests)] +public class PublicationControllerCachingTests : CacheServiceTestFixture +{ + private readonly PublicationsListRequest _query = new( + ReleaseType.ExperimentalStatistics, + ThemeId: Guid.Empty, + Search: "", + IPublicationService.PublicationsSortBy.Published, + SortOrder.Asc, + Page: 1, + PageSize: 10 + ); + + private readonly PaginatedListViewModel _publications = new( + ListOf(new PublicationSearchResultViewModel + { + Id = Guid.NewGuid(), + Published = DateTime.UtcNow, + Rank = 4, + Slug = "slug", + Summary = "summary", + Theme = "theme", + Title = "title", + Type = ReleaseType.ExperimentalStatistics + }), 5, 1, 10); + + [Fact] + public async Task ListPublications_NoCachedEntryExists() + { + var publicationService = new Mock(Strict); + + MemoryCacheService + .Setup(s => s.GetItem( + new GetPublicationListCacheKey(_query), + typeof(PaginatedListViewModel))) + .Returns(null); + + var expectedCacheConfiguration = new MemoryCacheConfiguration( + 10, CrontabSchedule.Parse(HalfHourlyExpirySchedule)); + + MemoryCacheService + .Setup(s => s.SetItem( + new GetPublicationListCacheKey(_query), + _publications, + ItIs.DeepEqualTo(expectedCacheConfiguration), + null)); + + publicationService + .Setup(s => s.ListPublications( + _query.ReleaseType, + _query.ThemeId, + _query.Search, + _query.Sort, + _query.Order, + _query.Page, + _query.PageSize)) + .ReturnsAsync(_publications); + + var controller = BuildController(publicationService.Object); + + var result = await controller.ListPublications(_query); + + VerifyAllMocks(MemoryCacheService, publicationService); + + result.AssertOkResult(_publications); + } + + [Fact] + public async Task ListPublications_CachedEntryExists() + { + MemoryCacheService + .Setup(s => s.GetItem( + new GetPublicationListCacheKey(_query), + typeof(PaginatedListViewModel))) + .Returns(_publications); + + var controller = BuildController(); + + var result = await controller.ListPublications(_query); + + VerifyAllMocks(MemoryCacheService); + + result.AssertOkResult(_publications); + } + + [Fact] + public void PublicationSearchResults_SerializeAndDeserialize() + { + var converted = DeserializeObject>( + SerializeObject(_publications)); + + converted.AssertDeepEqualTo(_publications); + } + + private static PublicationController BuildController( + IPublicationService? publicationService = null + ) + { + return new( + Mock.Of(Strict), + publicationService ?? Mock.Of(Strict) + ); + } +} diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/ReleaseControllerCachingTests.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/ReleaseControllerCachingTests.cs index 0343952236..ea4e17b06e 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/ReleaseControllerCachingTests.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api.Tests/Controllers/ReleaseControllerCachingTests.cs @@ -13,6 +13,7 @@ using Moq; using NCrontab; using Xunit; +using static GovUk.Education.ExploreEducationStatistics.Common.Cache.CronSchedules; using static GovUk.Education.ExploreEducationStatistics.Common.Tests.Utils.MockUtils; using static Moq.MockBehavior; @@ -21,8 +22,6 @@ namespace GovUk.Education.ExploreEducationStatistics.Content.Api.Tests.Controlle [Collection(CacheServiceTests)] public class ReleaseControllerCachingTests : CacheServiceTestFixture { - private const string HalfHourlyExpirySchedule = "*/30 * * * *"; - private const string PublicationSlug = "publication-a"; private const string ReleaseSlug = "200"; diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Cache/GetPublicationListCacheKey.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Cache/GetPublicationListCacheKey.cs new file mode 100644 index 0000000000..3632bb84e8 --- /dev/null +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Cache/GetPublicationListCacheKey.cs @@ -0,0 +1,9 @@ +using GovUk.Education.ExploreEducationStatistics.Common.Cache.Interfaces; +using GovUk.Education.ExploreEducationStatistics.Content.Api.Requests; + +namespace GovUk.Education.ExploreEducationStatistics.Content.Api.Cache; + +public record GetPublicationListCacheKey(PublicationsListRequest PublicationQuery) : IMemoryCacheKey +{ + public string Key => $"{GetType().Name}:{PublicationQuery}"; +} \ No newline at end of file diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/PublicationController.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/PublicationController.cs index df7b765e1f..65cbb6bf18 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/PublicationController.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/PublicationController.cs @@ -2,15 +2,18 @@ using System.Collections.Generic; using System.Net.Mime; using System.Threading.Tasks; +using GovUk.Education.ExploreEducationStatistics.Common.Cache; using GovUk.Education.ExploreEducationStatistics.Common.Extensions; using GovUk.Education.ExploreEducationStatistics.Common.Model; using GovUk.Education.ExploreEducationStatistics.Common.ViewModels; +using GovUk.Education.ExploreEducationStatistics.Content.Api.Cache; using GovUk.Education.ExploreEducationStatistics.Content.Api.Requests; using GovUk.Education.ExploreEducationStatistics.Content.Services.Interfaces; using GovUk.Education.ExploreEducationStatistics.Content.Services.Interfaces.Cache; using GovUk.Education.ExploreEducationStatistics.Content.Services.Requests; using GovUk.Education.ExploreEducationStatistics.Content.Services.ViewModels; using Microsoft.AspNetCore.Mvc; +using static GovUk.Education.ExploreEducationStatistics.Common.Cache.CronSchedules; namespace GovUk.Education.ExploreEducationStatistics.Content.Api.Controllers { @@ -45,6 +48,7 @@ public async Task>> GetPublica .HandleFailuresOrOk(); } + [MemoryCache(typeof(GetPublicationListCacheKey), durationInSeconds: 10, expiryScheduleCron: HalfHourlyExpirySchedule)] [HttpGet("publications")] public async Task>> ListPublications( [FromQuery] PublicationsListRequest request) diff --git a/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/ReleaseController.cs b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/ReleaseController.cs index ce5a285ce2..ad5f219513 100644 --- a/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/ReleaseController.cs +++ b/src/GovUk.Education.ExploreEducationStatistics.Content.Api/Controllers/ReleaseController.cs @@ -11,6 +11,7 @@ using GovUk.Education.ExploreEducationStatistics.Content.Services.Interfaces.Cache; using GovUk.Education.ExploreEducationStatistics.Content.Services.ViewModels; using Microsoft.AspNetCore.Mvc; +using static GovUk.Education.ExploreEducationStatistics.Common.Cache.CronSchedules; namespace GovUk.Education.ExploreEducationStatistics.Content.Api.Controllers { @@ -18,8 +19,6 @@ namespace GovUk.Education.ExploreEducationStatistics.Content.Api.Controllers [Produces(MediaTypeNames.Application.Json)] public class ReleaseController : ControllerBase { - private const string HalfHourlyExpirySchedule = "*/30 * * * *"; - private readonly IMethodologyCacheService _methodologyCacheService; private readonly IPublicationCacheService _publicationCacheService; private readonly IReleaseCacheService _releaseCacheService; diff --git a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartReferenceLinesConfiguration.tsx b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartReferenceLinesConfiguration.tsx index 3b4945367d..adf2a46d71 100644 --- a/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartReferenceLinesConfiguration.tsx +++ b/src/explore-education-statistics-admin/src/pages/release/datablocks/components/chart/ChartReferenceLinesConfiguration.tsx @@ -6,7 +6,6 @@ import FormFieldSelect from '@common/components/form/FormFieldSelect'; import FormFieldTextInput from '@common/components/form/FormFieldTextInput'; import FormSelect, { SelectOption } from '@common/components/form/FormSelect'; import Tooltip from '@common/components/Tooltip'; -import VisuallyHidden from '@common/components/VisuallyHidden'; import { AxisType, ChartDefinitionAxis, diff --git a/src/explore-education-statistics-frontend/.env b/src/explore-education-statistics-frontend/.env index c8c4685026..4362a4ceae 100644 --- a/src/explore-education-statistics-frontend/.env +++ b/src/explore-education-statistics-frontend/.env @@ -2,4 +2,5 @@ CONTENT_API_BASE_URL=http://localhost:5010/api DATA_API_BASE_URL=http://localhost:5000/api NOTIFICATION_API_BASE_URL=http://localhost:7073/api GA_TRACKING_ID= -PUBLIC_URL=http://localhost:3000/ \ No newline at end of file +PUBLIC_URL=http://localhost:3000/ +APP_ENV=Local diff --git a/src/explore-education-statistics-frontend/server.js b/src/explore-education-statistics-frontend/server.js index 03994c4ec6..771af7b6d2 100644 --- a/src/explore-education-statistics-frontend/server.js +++ b/src/explore-education-statistics-frontend/server.js @@ -13,6 +13,7 @@ if (process.env.APPINSIGHTS_INSTRUMENTATIONKEY) { .setAutoCollectDependencies(true) .setAutoCollectConsole(true) .setUseDiskRetryCaching(true) + .setSendLiveMetrics(true) .start(); } diff --git a/src/explore-education-statistics-frontend/src/modules/find-statistics/PublicationReleasePage.tsx b/src/explore-education-statistics-frontend/src/modules/find-statistics/PublicationReleasePage.tsx index 088fe592c9..51069abe59 100644 --- a/src/explore-education-statistics-frontend/src/modules/find-statistics/PublicationReleasePage.tsx +++ b/src/explore-education-statistics-frontend/src/modules/find-statistics/PublicationReleasePage.tsx @@ -29,7 +29,7 @@ import { logEvent } from '@frontend/services/googleAnalyticsService'; import glossaryService from '@frontend/services/glossaryService'; import classNames from 'classnames'; import orderBy from 'lodash/orderBy'; -import { GetServerSideProps, NextPage } from 'next'; +import { GetStaticPaths, GetStaticProps, NextPage } from 'next'; import React from 'react'; import VisuallyHidden from '@common/components/VisuallyHidden'; import ScrollableContainer from '@common/components/ScrollableContainer'; @@ -571,13 +571,11 @@ const PublicationReleasePage: NextPage = ({ release }) => { ); }; -export const getServerSideProps: GetServerSideProps = async ({ - query, -}) => { +export const getStaticProps: GetStaticProps = async ({ params }) => { const { publication: publicationSlug, release: releaseSlug, - } = query as Dictionary; + } = params as Dictionary; const release = await (releaseSlug ? publicationService.getPublicationRelease(publicationSlug, releaseSlug) @@ -587,6 +585,14 @@ export const getServerSideProps: GetServerSideProps = async ({ props: { release, }, + revalidate: process.env.APP_ENV === 'Local' ? 2 : 10, + }; +}; + +export const getStaticPaths: GetStaticPaths = async () => { + return { + paths: [], + fallback: 'blocking', }; }; diff --git a/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication].tsx b/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication].tsx index 3d14684600..7b230dcf8c 100644 --- a/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication].tsx +++ b/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication].tsx @@ -1,4 +1,5 @@ export { default, - getServerSideProps, + getStaticProps, + getStaticPaths, } from '@frontend/modules/find-statistics/PublicationReleasePage'; diff --git a/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication]/[release].tsx b/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication]/[release].tsx index 3d14684600..7b230dcf8c 100644 --- a/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication]/[release].tsx +++ b/src/explore-education-statistics-frontend/src/pages/find-statistics/[publication]/[release].tsx @@ -1,4 +1,5 @@ export { default, - getServerSideProps, + getStaticProps, + getStaticPaths, } from '@frontend/modules/find-statistics/PublicationReleasePage'; diff --git a/src/explore-education-statistics-frontend/src/types/env.d.ts b/src/explore-education-statistics-frontend/src/types/env.d.ts index c6ad994112..6c6503f0e7 100644 --- a/src/explore-education-statistics-frontend/src/types/env.d.ts +++ b/src/explore-education-statistics-frontend/src/types/env.d.ts @@ -1,6 +1,6 @@ declare namespace NodeJS { interface ProcessEnv { - APP_ENV: 'Production' | 'Pre-Production' | 'Test' | 'Development'; + APP_ENV: 'Production' | 'Pre-Production' | 'Test' | 'Development' | 'Local'; APPINSIGHTS_INSTRUMENTATIONKEY: string; BUILD_NUMBER: string; GA_TRACKING_ID: string; diff --git a/tests/robot-tests/.env.example b/tests/robot-tests/.env.example index b979a9deda..e2550e5e7b 100644 --- a/tests/robot-tests/.env.example +++ b/tests/robot-tests/.env.example @@ -11,7 +11,8 @@ ANALYST_PASSWORD=ANALYST_PASSWORD # Analyst1 user password EXPIRED_INVITE_USER_EMAIL= # Expired Invite user email EXPIRED_INVITE_USER_PASSWORD= # Expired Invite user password RELEASE_COMPLETE_WAIT=120 # Time to wait for a release to publish (in seconds) -WAIT_MEMORY_CACHE_EXPIRY=2 # Time to wait for the memory cache to expire (in minutes. Local = 2, Dev = 10) +WAIT_CACHE_EXPIRY=2 # Time to wait for the environment's various caches to expire (in seconds. Local = 2, Dev = 10) +WAIT_NEXT_ISR=5 # Time for Next.js to perform Incremental Static Regeneration (generate a new version of a stale page in the background) WAIT_MEDIUM=120 # Variable used throughout tests (in seconds) WAIT_SMALL=45 # Variable used throughout tests (in seconds) WAIT_LONG=180 # Variable used throughout tests (in seconds) diff --git a/tests/robot-tests/run_tests.py b/tests/robot-tests/run_tests.py index 9e559f3484..e88f5dd4f1 100755 --- a/tests/robot-tests/run_tests.py +++ b/tests/robot-tests/run_tests.py @@ -178,7 +178,8 @@ "WAIT_SMALL", "FAIL_TEST_SUITES_FAST", "IDENTITY_PROVIDER", - "WAIT_MEMORY_CACHE_EXPIRY", + "WAIT_CACHE_EXPIRY", + "WAIT_NEXT_ISR", "EXPIRED_INVITE_USER_EMAIL", "PUBLISHER_FUNCTIONS_URL", ] diff --git a/tests/robot-tests/tests/admin_and_public/bau/archive_publication.robot b/tests/robot-tests/tests/admin_and_public/bau/archive_publication.robot index 99d5164bf7..b6b89e8e31 100644 --- a/tests/robot-tests/tests/admin_and_public/bau/archive_publication.robot +++ b/tests/robot-tests/tests/admin_and_public/bau/archive_publication.robot @@ -209,8 +209,14 @@ Check public superseding-publication release page displays correctly user waits until page contains This is the latest data Check public archive-publication release page displays correctly + user waits for caches to expire + user navigates to public frontend ${PUBLICATION_ARCHIVE_URL} user waits until h1 is visible ${PUBLICATION_NAME_ARCHIVE} %{WAIT_MEDIUM} + + user reloads the stale cached page + user waits until h1 is visible ${PUBLICATION_NAME_ARCHIVE} %{WAIT_MEDIUM} + user checks page does not contain This is the latest data Check public archive-publication release page displays superseded warning @@ -386,7 +392,7 @@ Set archive-publication to be no longer be superseded user clicks button Confirm ${modal} user waits until modal is not visible Confirm publication changes - sleep %{WAIT_MEMORY_CACHE_EXPIRY} + user waits for caches to expire Check can create a release for archive-publication which is no longer archived [Documentation] Failing due to https://dfedigital.atlassian.net/browse/EES-4269 diff --git a/tests/robot-tests/tests/admin_and_public/bau/legacy_releases.robot b/tests/robot-tests/tests/admin_and_public/bau/legacy_releases.robot index 8bc8759ed2..8373487c92 100644 --- a/tests/robot-tests/tests/admin_and_public/bau/legacy_releases.robot +++ b/tests/robot-tests/tests/admin_and_public/bau/legacy_releases.robot @@ -1,4 +1,5 @@ *** Settings *** +Resource ../../libs/public-common.robot Resource ../../libs/admin-common.robot Resource ../../libs/admin/manage-content-common.robot Library ../../libs/admin_api.py @@ -88,7 +89,6 @@ Update legacy release user enters text into element id:legacyReleaseForm-description ${UPDATED_DESCRIPTION} user enters text into element id:legacyReleaseForm-url http://test2.com user clicks button Save legacy release - sleep %{WAIT_MEMORY_CACHE_EXPIRY} Validate updated legacy release user waits until h2 is visible Legacy releases @@ -98,7 +98,13 @@ Validate updated legacy release user checks table cell contains 1 3 http://test2.com Validate public frontend shows changes made to legacy release after saving publication + user waits for caches to expire + user navigates to public frontend ${PUBLIC_RELEASE_LINK} + user waits until h1 is visible ${PUBLICATION_NAME} %{WAIT_MEDIUM} + + user reloads the stale cached page + user waits until h1 is visible ${PUBLICATION_NAME} %{WAIT_MEDIUM} user opens details dropdown View releases (1) diff --git a/tests/robot-tests/tests/admin_and_public/bau/publish_data.robot b/tests/robot-tests/tests/admin_and_public/bau/publish_data.robot index ecbc0bca85..4630a742e7 100644 --- a/tests/robot-tests/tests/admin_and_public/bau/publish_data.robot +++ b/tests/robot-tests/tests/admin_and_public/bau/publish_data.robot @@ -505,6 +505,8 @@ Approve release user approves original release for immediate publication Verify newly published release is on Find Statistics page + user waits for caches to expire + user checks publication is on find statistics page ${PUBLICATION_NAME} Navigate to published release page diff --git a/tests/robot-tests/tests/admin_and_public_2/bau/publish_release_and_amend.robot b/tests/robot-tests/tests/admin_and_public_2/bau/publish_release_and_amend.robot index 95ac9238e7..43949b6db1 100644 --- a/tests/robot-tests/tests/admin_and_public_2/bau/publish_release_and_amend.robot +++ b/tests/robot-tests/tests/admin_and_public_2/bau/publish_release_and_amend.robot @@ -730,11 +730,16 @@ Approve amendment for scheduled release set suite variable ${EXPECTED_PUBLISHED_DATE} Verify amendment is on Find Statistics page again + user waits for caches to expire user checks publication is on find statistics page ${PUBLICATION_NAME} Navigate to amendment release page user clicks link ${PUBLICATION_NAME} user waits until h1 is visible ${PUBLICATION_NAME} %{WAIT_MEDIUM} + + user reloads the stale cached page + user waits until h1 is visible ${PUBLICATION_NAME} %{WAIT_MEDIUM} + user waits until page contains title caption ${RELEASE_NAME} user checks url contains %{PUBLIC_URL}/find-statistics/ui-tests-publish-release-and-amend-%{RUN_IDENTIFIER} @@ -948,8 +953,12 @@ Verify published date on publication page has been updated user checks element contains ${row} ${EXPECTED_PUBLISHED_DATE} Navigate to amended public release + user waits for caches to expire user navigates to public frontend ${PUBLIC_RELEASE_LINK} - user waits until h1 is visible ${PUBLICATION_NAME} + user waits until h1 is visible ${PUBLICATION_NAME} %{WAIT_MEDIUM} + + user reloads the stale cached page + user waits until h1 is visible ${PUBLICATION_NAME} %{WAIT_MEDIUM} Verify public published date has been updated user checks summary list contains Published ${EXPECTED_PUBLISHED_DATE} diff --git a/tests/robot-tests/tests/libs/common.robot b/tests/robot-tests/tests/libs/common.robot index faf4a81d74..ef07af17d6 100644 --- a/tests/robot-tests/tests/libs/common.robot +++ b/tests/robot-tests/tests/libs/common.robot @@ -982,3 +982,6 @@ user takes html snapshot of element ${element}= lookup or return webelement ${selector_or_webelement} ${filepath}= take html snapshot of element ${element} ${filename} [Return] ${filepath} + +user waits for caches to expire + sleep %{WAIT_CACHE_EXPIRY} diff --git a/tests/robot-tests/tests/libs/public-common.robot b/tests/robot-tests/tests/libs/public-common.robot index 6ae304615d..6b27e0c610 100644 --- a/tests/robot-tests/tests/libs/public-common.robot +++ b/tests/robot-tests/tests/libs/public-common.robot @@ -60,3 +60,9 @@ user checks methodology note [Arguments] ${number} ${displayDate} ${content} user waits until element contains css:#methodologyNotes li:nth-of-type(${number}) time ${displayDate} user waits until element contains css:#methodologyNotes li:nth-of-type(${number}) p ${content} + +user reloads the stale cached page + # Next.js will have returned a stale cached page for the last request and will have created a new cached page in + # the background in the meantime using Incremental Static Regeneration, so request the page again. + sleep %{WAIT_NEXT_ISR} + user reloads page