diff --git a/cypress/e2e/specialFeatures/scriptSwitching/helpers/index.js b/cypress/e2e/specialFeatures/scriptSwitching/helpers/index.js
index 88b68b0f5df..c26a4b327b6 100644
--- a/cypress/e2e/specialFeatures/scriptSwitching/helpers/index.js
+++ b/cypress/e2e/specialFeatures/scriptSwitching/helpers/index.js
@@ -1,7 +1,7 @@
import { MEDIA_ASSET_PAGE } from '../../../../../src/app/routes/utils/pageTypes';
-const clickFirstArticleLink = () => {
- cy.get('a[href*="articles"]').first().click();
+const clickFirstLink = () => {
+ cy.get('a').first().click();
};
const clickFirstMapLink = () => {
@@ -12,11 +12,11 @@ const clickFirstMapLink = () => {
.parentsUntil('[data-testid="topic-promos"]')
.first()
.within(() => {
- cy.get('a').first().click();
+ clickFirstLink();
});
} else {
// If a MAP item isn't found on the home page, click the first promo item.
- clickFirstArticleLink();
+ clickFirstLink();
}
});
};
@@ -41,7 +41,7 @@ export const clickPromoLinkOnHomePage = pageType => {
.first()
.within(() => {
// If it isn't a MAP page being tested, click the first promo item
- clickFirstArticleLink();
+ clickFirstLink();
});
}
};
diff --git a/src/app/components/CollapsibleNavigation/index.styles.ts b/src/app/components/CollapsibleNavigation/index.styles.ts
index dd0e6f40ce1..ade3828d305 100644
--- a/src/app/components/CollapsibleNavigation/index.styles.ts
+++ b/src/app/components/CollapsibleNavigation/index.styles.ts
@@ -47,7 +47,7 @@ const styles = {
height: `${pixelsToRem(20)}rem`,
backgroundColor: palette.GREY_10,
},
- '&:nth-last-child(2)::after': {
+ '&:last-of-type::after': {
background: 'none',
},
}),
@@ -222,9 +222,6 @@ const styles = {
backgroundColor: palette.WHITE,
},
}),
- collapsed: css({
- display: 'none',
- }),
};
export default styles;
diff --git a/src/app/components/CollapsibleNavigation/index.test.tsx b/src/app/components/CollapsibleNavigation/index.test.tsx
index 68dd9145697..cd17d13238d 100644
--- a/src/app/components/CollapsibleNavigation/index.test.tsx
+++ b/src/app/components/CollapsibleNavigation/index.test.tsx
@@ -32,70 +32,67 @@ describe('LanguageNavigation', () => {
render();
sections.forEach(section => {
- const element = section.href
- ? screen.getByRole('link', { name: section.title })
- : screen.getByRole('button', { name: section.title });
- expect(element).toBeInTheDocument();
+ expect(screen.getByText(section.title)).toBeInTheDocument();
});
});
test('clicking a section toggles dropdown', () => {
render();
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
sections[0].links?.forEach(link => {
- expect(screen.getAllByText(link.label)[0]).toBeInTheDocument();
+ expect(screen.getByText(link.label)).toBeInTheDocument();
});
});
test('clicking the same section again closes the dropdown', () => {
render();
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
- expect(screen.getAllByText('Link 1')[0]).toBeVisible();
- expect(screen.getAllByText('Link 2')[0]).toBeVisible();
+ expect(screen.getByText('Link 1')).toBeInTheDocument();
+ expect(screen.getByText('Link 2')).toBeInTheDocument();
fireEvent.click(sectionTitle);
- expect(screen.getAllByText('Link 1')[0]).not.toBeVisible();
- expect(screen.getAllByText('Link 2')[0]).not.toBeVisible();
+ expect(screen.queryByText('Link 1')).not.toBeInTheDocument();
+ expect(screen.queryByText('Link 2')).not.toBeInTheDocument();
});
test('clicking close button closes the dropdown', () => {
render();
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
- expect(screen.getAllByText('Link 1')[0]).toBeInTheDocument();
- expect(screen.getAllByText('Link 2')[0]).toBeInTheDocument();
+ expect(screen.getByText('Link 1')).toBeInTheDocument();
+ expect(screen.getByText('Link 2')).toBeInTheDocument();
const closeButton = screen.getByRole('button', {
name: 'Close Section 1 submenu',
});
fireEvent.click(closeButton);
- expect(closeButton).not.toBeVisible();
- expect(screen.queryAllByText('Link 1')[0]).not.toBeVisible();
- expect(screen.queryAllByText('Link 2')[0]).not.toBeVisible();
+ expect(closeButton).not.toBeInTheDocument();
+ expect(screen.queryByText('Link 1')).not.toBeInTheDocument();
+ expect(screen.queryByText('Link 2')).not.toBeInTheDocument();
});
test('renders links correctly when section is active', () => {
render();
- const sectionTitle = screen.getByRole('button', { name: 'Section 2' });
+ const sectionTitle = screen.getByText('Section 2');
fireEvent.click(sectionTitle);
sections[1].links?.forEach(link => {
- expect(screen.getAllByText(link.label)[0]).toBeInTheDocument();
+ expect(screen.getByText(link.label)).toBeInTheDocument();
});
});
@@ -108,13 +105,13 @@ describe('LanguageNavigation', () => {
fireEvent.click(sectionLink);
- expect(screen.queryAllByText('Link 1')[0]).not.toBeVisible();
+ expect(screen.queryByText('Link 1')).not.toBeInTheDocument();
});
test('applies lang attribute to links when provided', () => {
render();
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
const link1 = screen.getByRole('link', { name: 'Link 1' });
@@ -154,7 +151,7 @@ describe('LanguageNavigation', () => {
/>,
);
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
const link1 = screen.getByRole('link', {
@@ -187,7 +184,7 @@ describe('LanguageNavigation', () => {
,
);
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
const link1 = screen.getByRole('link', {
@@ -216,7 +213,7 @@ describe('LanguageNavigation', () => {
render();
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
const link1 = screen.getByRole('link', { name: 'Link 1' });
@@ -247,7 +244,7 @@ describe('LanguageNavigation', () => {
/>,
);
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
const link1 = screen.getByRole('link', { name: 'Link 1' });
@@ -275,7 +272,7 @@ describe('LanguageNavigation', () => {
render();
- const sectionTitle = screen.getByRole('button', { name: 'Section 1' });
+ const sectionTitle = screen.getByText('Section 1');
fireEvent.click(sectionTitle);
const link1 = screen.getByRole('link', { name: 'Link 1' });
diff --git a/src/app/components/CollapsibleNavigation/index.tsx b/src/app/components/CollapsibleNavigation/index.tsx
index 6a23ab140d0..c201afe5f94 100644
--- a/src/app/components/CollapsibleNavigation/index.tsx
+++ b/src/app/components/CollapsibleNavigation/index.tsx
@@ -86,6 +86,7 @@ const CollapsibleNavigation = ({
{navigationSections.map(section => {
const isActive = Boolean(openSection === section.id);
+ const shouldShowSubNav = isHydrated ? isActive : true;
const isLink = section.href;
const navigationLinkId = `nav-${section.id}`;
@@ -112,14 +113,10 @@ const CollapsibleNavigation = ({
- {section.links && (
+ {section.links && shouldShowSubNav && (
- {
return true;
};
-type ExperimentControlProps = {
- experimentVariant: string;
-};
-
-// Control group - fire the control group pixel
-const PWAPromotionalBannerControl = ({
- experimentVariant,
-}: ExperimentControlProps) => {
- const { isInstallable } = usePWAInstallPrompt({ deferPrompt: false });
- const viewTracker = useViewTracker({
- componentName: 'pwa-promotional-banner',
- experimentName: PWA_PROMOTIONAL_BANNER_EXPERIMENT_NAME,
- experimentVariant,
- alwaysInView: true,
- });
-
- if (!isInstallable) {
- return null;
- }
-
- return ;
-};
-
-// Treatment group - actual PWA banner
-const PWAPromotionalBannerTreatment = ({
- experimentVariant,
-}: ExperimentControlProps) => {
+const PWAPromotionalBanner = () => {
const { promotionalBanner } = use(ServiceContext);
+ const { isLite, isAmp } = use(RequestContext);
const [isVisible, setIsVisible] = useState(() => isBannerVisible());
// EXPERIMENT: PWA Promotional Banner
+ const pwaPromoBannerExperimentName = 'newswb_ws_pwa_promo_prompt';
+ const pwaPromoBannerVariant = useOptimizelyVariation({
+ experimentName: pwaPromoBannerExperimentName,
+ experimentType: ExperimentType.SERVER_SIDE,
+ });
+
+ const isPwaPromoExperimentEnabled = pwaPromoBannerVariant === 'on';
+ const isAndroid = useAndroidDetection();
+
const optimizelyExperimentData = {
- experimentName: PWA_PROMOTIONAL_BANNER_EXPERIMENT_NAME,
- experimentVariant,
+ experimentName: pwaPromoBannerExperimentName,
+ experimentVariant: pwaPromoBannerVariant || 'off',
};
-
const viewTracker = useViewTracker({
componentName: 'pwa-promotional-banner',
...optimizelyExperimentData,
@@ -121,7 +101,6 @@ const PWAPromotionalBannerTreatment = ({
},
[onSecondaryClickTrack, handleBannerDismiss],
);
-
const { promptInstall, isInstallable } = usePWAInstallPrompt({
onAccepted: () => {
setIsVisible(false);
@@ -143,7 +122,15 @@ const PWAPromotionalBannerTreatment = ({
[onPrimaryClickTrack, promptInstall],
);
- if (!isVisible || !isInstallable || !promotionalBanner) {
+ if (
+ isLite ||
+ isAmp ||
+ !isAndroid ||
+ !isPwaPromoExperimentEnabled ||
+ !isVisible ||
+ !isInstallable ||
+ !promotionalBanner
+ ) {
return null;
}
@@ -173,37 +160,4 @@ const PWAPromotionalBannerTreatment = ({
);
};
-
-const PWAPromotionalBanner = () => {
- const { isLite, isAmp } = use(RequestContext);
- const isPWA = useIsPWA();
- const isAndroid = useAndroidDetection();
-
- const pwaPromoBannerExperimentName = PWA_PROMOTIONAL_BANNER_EXPERIMENT_NAME;
- const pwaPromoBannerVariant = useOptimizelyVariation({
- experimentName: pwaPromoBannerExperimentName,
- experimentType: ExperimentType.SERVER_SIDE,
- });
-
- if (isLite || isAmp || isPWA || !isAndroid) {
- return null;
- }
-
- if (pwaPromoBannerVariant === 'control') {
- return (
-
- );
- }
-
- if (pwaPromoBannerVariant === 'on') {
- return (
-
- );
- }
-
- return null;
-};
-
export default PWAPromotionalBanner;
diff --git a/src/app/hooks/usePWAInstallPrompt/index.ts b/src/app/hooks/usePWAInstallPrompt/index.ts
index 088e85cfaf0..9a2e8a13de3 100644
--- a/src/app/hooks/usePWAInstallPrompt/index.ts
+++ b/src/app/hooks/usePWAInstallPrompt/index.ts
@@ -11,7 +11,6 @@ interface UsePWAInstallPromptCallbacks {
onDismissed?: () => void;
onError?: (error: unknown) => void;
onPromptShown?: () => void;
- deferPrompt?: boolean;
}
const usePWAInstallPrompt = ({
@@ -19,7 +18,6 @@ const usePWAInstallPrompt = ({
onDismissed,
onError,
onPromptShown,
- deferPrompt = true,
}: UsePWAInstallPromptCallbacks = {}) => {
const deferredPrompt = useRef(null);
const [isInstallable, setIsInstallable] = useState(false);
@@ -32,10 +30,8 @@ const usePWAInstallPrompt = ({
return undefined;
}
const handleBeforeInstallPrompt = (event: Event) => {
- if (deferPrompt) {
- event?.preventDefault();
- deferredPrompt.current = event as BeforeInstallPromptEvent;
- }
+ if (typeof event.preventDefault === 'function') event.preventDefault();
+ deferredPrompt.current = event as BeforeInstallPromptEvent;
setIsInstallable(true);
};
window.addEventListener(
@@ -51,7 +47,7 @@ const usePWAInstallPrompt = ({
handleBeforeInstallPrompt as EventListener,
);
};
- }, [deferPrompt, isPWA]);
+ }, [isPWA]);
const promptInstall = async () => {
if (!deferredPrompt.current) return;
diff --git a/src/app/pages/ArticlePage/ArticlePage.tsx b/src/app/pages/ArticlePage/ArticlePage.tsx
index 7b76b76ca68..1fff9caeb9a 100644
--- a/src/app/pages/ArticlePage/ArticlePage.tsx
+++ b/src/app/pages/ArticlePage/ArticlePage.tsx
@@ -365,8 +365,15 @@ const ArticlePage = ({ pageData }: { pageData: Article }) => {
) : null;
// EXPERIMENT: PWA Promotional Banner
+ // EXPERIMENT: PWA Promotional Banner
+ const pwaPromoBannerExperimentName = 'newswb_ws_pwa_promo_prompt';
+ const pwaPromoBannerVariant = useOptimizelyVariation({
+ experimentName: pwaPromoBannerExperimentName,
+ experimentType: ExperimentType.SERVER_SIDE,
+ });
const shouldRenderPWAPromotionalBanner =
- !pageData?.secondaryColumn?.topStories?.length;
+ !pageData?.secondaryColumn?.topStories?.length &&
+ pwaPromoBannerVariant === 'on';
return (
diff --git a/src/app/pages/HomePage/HomePage.tsx b/src/app/pages/HomePage/HomePage.tsx
index 822245d3a09..a104c0b6ee3 100644
--- a/src/app/pages/HomePage/HomePage.tsx
+++ b/src/app/pages/HomePage/HomePage.tsx
@@ -76,6 +76,7 @@ const HomePage = ({ pageData }: HomePageProps) => {
experimentName: pwaPromoBannerExperimentName,
experimentType: ExperimentType.SERVER_SIDE,
});
+ const shouldRenderPWAPromotionalBanner = pwaPromoBannerVariant === 'on';
// if variant is set to 'homepage_time_of_day_a' or 'homepage_time_of_day_b' then reorder curations
if (
@@ -93,7 +94,7 @@ const HomePage = ({ pageData }: HomePageProps) => {
return (
<>
{/* EXPERIMENT: PWA Promotional Banner */}
-
+ {shouldRenderPWAPromotionalBanner &&
}
{
- const serviceID = (config[service]?.name || service) as Services;
-
- if (!MOST_READ_EXCLUDED_SERVICES.includes(serviceID)) {
+ if (!MOST_READ_EXCLUDED_SERVICES.includes(service)) {
const {
mostRead: { hasMostRead, numberOfItems },
- } = appConfig[serviceID][variant];
+ } = appConfig[service][variant];
if (hasMostRead) {
describe('Most Read Component', () => {
beforeEach(() => {
- cy.getToggles(serviceID);
+ cy.getToggles(service);
});
it(`should render ${numberOfItems} items`, () => {
- cy.fixture(`toggles/${serviceID}.json`).then(toggles => {
+ cy.fixture(`toggles/${service}.json`).then(toggles => {
if (toggles.mostRead?.enabled) {
cy.get('[data-e2e="most-read"]').scrollIntoView();
cy.get('[data-e2e="most-read"] li').should(
@@ -39,9 +35,9 @@ export const crossPlatform = ({
});
it(`should show correct numerals`, () => {
- cy.fixture(`toggles/${serviceID}.json`).then(toggles => {
+ cy.fixture(`toggles/${service}.json`).then(toggles => {
if (toggles.mostRead?.enabled) {
- const expectedMostReadRank = serviceNumerals(serviceID);
+ const expectedMostReadRank = serviceNumerals(service);
cy.get('[data-e2e="most-read"]').scrollIntoView();
cy.get('[data-e2e="most-read"]')
.find('li span')
@@ -53,7 +49,7 @@ export const crossPlatform = ({
});
it(`should have links with href and title`, () => {
- cy.fixture(`toggles/${serviceID}.json`).then(toggles => {
+ cy.fixture(`toggles/${service}.json`).then(toggles => {
if (toggles.mostRead?.enabled) {
cy.get('[data-e2e="most-read"]').scrollIntoView();
cy.get('[data-e2e="most-read"]').within(() => {
@@ -76,20 +72,18 @@ export const ampOnly = ({
service,
variant = 'default',
}: ServiceParametersType) => {
- const serviceID = (config[service]?.name || service) as Services;
-
- if (!MOST_READ_EXCLUDED_SERVICES.includes(serviceID)) {
+ if (!MOST_READ_EXCLUDED_SERVICES.includes(service)) {
const {
mostRead: { hasMostRead },
- } = appConfig[serviceID][variant];
+ } = appConfig[service][variant];
if (hasMostRead) {
describe('Most Read Component', () => {
beforeEach(() => {
- cy.getToggles(serviceID);
+ cy.getToggles(service);
});
it('should not render when data fetch fails', () => {
const mostReadPath = getMostReadEndpoint({
- service: serviceID,
+ service,
variant: variant !== 'default' && variant,
isBff: getAppEnv() !== 'local',
});
@@ -101,7 +95,7 @@ export const ampOnly = ({
{ statusCode: 404 },
);
cy.reload();
- cy.fixture(`toggles/${serviceID}.json`).then(toggles => {
+ cy.fixture(`toggles/${service}.json`).then(toggles => {
if (toggles.mostRead?.enabled) {
cy.get('[data-e2e="most-read"]').scrollIntoView();
cy.get('[data-e2e="most-read"] li').should('not.exist');
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/articleLiteSiteLink.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/articleLiteSiteLink.ts
index 6d4694ed31c..c28cbcbd466 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/articleLiteSiteLink.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/articleLiteSiteLink.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { ARTICLE_LITE_SITE_LINK } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/continueReadingButton.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/continueReadingButton.ts
index fcaa7d4576e..197f36c43cf 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/continueReadingButton.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/continueReadingButton.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { CONTINUE_READING_BUTTON } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/featuresAnalysis.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/featuresAnalysis.ts
index 5661514ef68..c7c5212425e 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/featuresAnalysis.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/featuresAnalysis.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { FEATURES } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/index.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/index.ts
new file mode 100644
index 00000000000..1f66d441597
--- /dev/null
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/index.ts
@@ -0,0 +1,350 @@
+import { eea, gbOrUnknown } from '#app/lib/utilities/cookieCountries';
+import {
+ VIEW_EVENT,
+ VIEWABILITY_CLICK_EVENT,
+} from '#app/lib/analyticsUtils/analytics.const';
+import {
+ ATI_PAGE_VIEW,
+ ATI_PAGE_VIEW_REVERB,
+ // ATI_USER_ID_COOKIE,
+ getATIParamsFromURL,
+ interceptATIAnalyticsBeacons,
+ getExpectedAtiDestination,
+} from '../helpers';
+import environment from '../../../../support/helpers/getAppEnv';
+
+const usesReverbViewabilityModel = applicationType =>
+ applicationType !== 'lite';
+
+const getAppName = service => {
+ if (service === 'ws') {
+ return '[news]';
+ }
+
+ return ['archive', 'news', 'newsround', 'scotland', 'sport'].includes(service)
+ ? `[${service}]`
+ : `[news-${service}]`;
+};
+
+const assertATIPageViewEventParamsExist = ({
+ params,
+ contentType,
+ applicationType,
+}) => {
+ expect(params).to.have.property('s'); // destination
+ expect(params).to.have.property('s2'); // Level 2 Site / Producer ID
+ expect(params).to.have.property('p'); // page identifier
+ expect(params).to.have.property('x2'); // application type
+ expect(params).to.have.property('x3'); // application name
+ expect(params).to.have.property('x4'); // language
+ expect(params).to.have.property('x7'); // content type
+ expect(params).to.have.property('x8'); // library version
+ expect(params).to.have.property('x9'); // page title
+
+ if (['responsive', 'amp'].includes(applicationType)) {
+ expect(params).to.have.property('r'); // screen resolution & colour depth
+ expect(params).to.have.property('re'); // browser/viewport resolution
+ expect(params).to.have.property('hl'); // timestamp
+ expect(params).to.have.property('lng'); // device language
+ expect(params).to.have.property('x5'); // url
+ }
+
+ if (['responsive', 'lite'].includes(applicationType)) {
+ expect(params).to.have.property('idclient');
+ }
+
+ if (!['list-datadriven', 'static'].includes(contentType)) {
+ expect(params).to.have.property('x1'); // content ID
+ }
+
+ if (contentType === 'article') {
+ expect(params).to.have.property('x11'); // first published
+ expect(params).to.have.property('x12'); // last published
+ expect(params).to.have.property('x13'); // ldp things
+ expect(params).to.have.property('x17'); // category
+ }
+};
+
+const assertLocationSpecificPianoDestinationExists = ({ service }) => {
+ cy.get(
+ 'head script[src*="https://cdn.ampproject.org/v0/amp-geo-0.1.js"]',
+ ).should('exist');
+
+ cy.get('amp-geo script[type="application/json"]').should(script => {
+ const ampGeoContent = JSON.parse(script.text());
+
+ expect(ampGeoContent).to.eql({
+ AmpBind: true,
+ ISOCountryGroups: {
+ eea,
+ gbOrUnknown,
+ },
+ });
+ });
+
+ cy.get(
+ '[data-e2e="ati-amp-analytics"] script[type="application/json"]',
+ ).should(script => {
+ const ampAnalyticsContent = script.text();
+
+ expect(ampAnalyticsContent).to.contain(
+ `s=${getExpectedAtiDestination({ service, applicationEnv: environment() })}`,
+ );
+ });
+};
+
+const assertReverbViewabilityComponentEventParamsExist = ({ params }) => {
+ expect(params).to.have.property('s'); // destination
+ expect(params).to.have.property('events'); // event details
+ expect(params).to.have.property('context');
+
+ const eventContext = JSON.parse(params.context);
+
+ expect(eventContext[0].data.page).to.have.property('$');
+ expect(eventContext[0].data.site).to.have.property('level2_id');
+};
+
+const fieldIsValidString = field =>
+ typeof field === 'string' && field.trim().length > 0;
+
+const validateViewabilityEventDetails = ({ payload, actionType }) => {
+ const arr = JSON.parse(payload);
+
+ return arr.some(event => {
+ if (event.name !== `viewability.${actionType}`) return false;
+
+ const group = event.data?.group ?? {};
+ const ev = event.data?.event ?? {};
+ const item = event.data?.item ?? {};
+
+ // strict checks
+ if (ev.category !== 'viewability' || ev.action !== actionType) return false;
+
+ // required fields in Group
+ const groupNameOk = fieldIsValidString(group.name);
+
+ const groupTypeOk = fieldIsValidString(group.type);
+
+ // optional fields in Group
+ const groupLinkOk = !group.link || fieldIsValidString(group.link);
+
+ const groupItemCountOk =
+ !group.item_count || Number.isInteger(group.item_count);
+
+ const groupResourceOk =
+ !group.resource_id || fieldIsValidString(group.resource_id);
+
+ const groupPositionOk = !group.position || Number.isInteger(group.position);
+
+ // required fields in Item
+ const itemNameOk = fieldIsValidString(item.name);
+
+ // optional fields in Item
+ const itemLinkOk = !item.link || fieldIsValidString(item.link);
+
+ const itemAdvertiserIdOk =
+ !item.advertiser_id || fieldIsValidString(item.advertiser_id);
+
+ const itemTypeOk = !item.type || fieldIsValidString(item.type);
+
+ const itemTextOk = !item.text || fieldIsValidString(item.text);
+
+ const itemPositionOk = !item.position || Number.isInteger(item.position);
+
+ const itemDurationOk = !item.duration || Number.isInteger(item.duration);
+
+ const itemMediaTypeOk =
+ !item.media_type || fieldIsValidString(item.media_type);
+
+ const itemLabelOk = !item.label || fieldIsValidString(item.label);
+
+ const itemResourceIdOk =
+ !item.resource_id || fieldIsValidString(item.resource_id);
+
+ return (
+ groupNameOk &&
+ groupTypeOk &&
+ groupLinkOk &&
+ groupItemCountOk &&
+ groupResourceOk &&
+ groupPositionOk &&
+ itemNameOk &&
+ itemLinkOk &&
+ itemAdvertiserIdOk &&
+ itemTypeOk &&
+ itemTextOk &&
+ itemPositionOk &&
+ itemDurationOk &&
+ itemMediaTypeOk &&
+ itemLabelOk &&
+ itemResourceIdOk
+ );
+ });
+};
+
+export const assertPageView = ({
+ useReverb,
+ pageIdentifier,
+ applicationType,
+ contentType,
+ service,
+ path,
+ siteId,
+}) => {
+ it(`should send a page view event with service = ${service}, page identifier = ${pageIdentifier}, site ID = ${siteId}, application type = ${applicationType} and content type = ${contentType}`, () => {
+ interceptATIAnalyticsBeacons();
+ cy.visit(path, { retryOnStatusCodeFailure: true });
+
+ const useViewabilty = usesReverbViewabilityModel(applicationType);
+ const atiPageViewAlias =
+ useReverb && useViewabilty && applicationType !== 'amp'
+ ? ATI_PAGE_VIEW_REVERB
+ : ATI_PAGE_VIEW;
+
+ cy.wait(`@${atiPageViewAlias}`).then(({ request }) => {
+ const params = getATIParamsFromURL(request.url);
+
+ assertATIPageViewEventParamsExist({
+ params,
+ contentType,
+ applicationType,
+ });
+
+ // TODO: Commenting out temporarily until old ATI code is removed - https://bbc.atlassian.net/browse/WS-222
+ // if (['responsive', 'lite'].includes(applicationType)) {
+ // expect(params.idclient).to.equal(
+ // ATI_USER_ID_COOKIE,
+ // 'params.idclient (atuserid cookie value)',
+ // );
+ // }
+
+ expect(params.p).to.equal(pageIdentifier, 'params.p (page identifier)');
+ expect(parseInt(params.s2, 10)).to.equal(
+ siteId,
+ 'params.s2 (Level 2 site / Producer ID)',
+ );
+ expect(params.x2).to.equal(
+ `[${applicationType}]`,
+ 'params.x2 (application type)',
+ );
+ expect(params.x3).to.equal(
+ getAppName(service),
+ 'params.x3 (application name)',
+ );
+ expect(params.x7).to.equal(
+ `[${contentType}]`,
+ 'params.x7 (content type)',
+ );
+ });
+
+ if (applicationType === 'amp') {
+ assertLocationSpecificPianoDestinationExists({ service });
+ }
+ });
+};
+
+const assertViewabilityModelViewEvent = ({
+ pageIdentifier,
+ params,
+ // applicationType,
+ siteId,
+}) => {
+ const eventContext = JSON.parse(params.context);
+
+ assertReverbViewabilityComponentEventParamsExist({ params });
+
+ // TODO: Commenting out temporarily until old ATI code is removed - https://bbc.atlassian.net/browse/WS-222
+ // if (['responsive', 'lite'].includes(applicationType)) {
+ // expect(params.idclient).to.equal(
+ // ATI_USER_ID_COOKIE,
+ // 'params.idclient (atuserid cookie value)',
+ // );
+ // }
+
+ expect(params.events).to.satisfy(
+ payload =>
+ validateViewabilityEventDetails({ payload, actionType: VIEW_EVENT }),
+ 'params.events (publisher impression)',
+ );
+
+ expect(eventContext[0].data.page.$).to.equal(pageIdentifier);
+ expect(parseInt(eventContext[0].data.site.level2_id, 10)).to.equal(siteId);
+};
+
+export const assertATIComponentViewEvent = ({
+ component,
+ pageIdentifier,
+ contentType,
+ siteId,
+}) => {
+ const requestAlias = `@${component}-viewability-view`;
+
+ cy.wait(requestAlias)
+ .its('request.url')
+ .then(url => {
+ const params = getATIParamsFromURL(url);
+
+ assertViewabilityModelViewEvent({
+ component,
+ pageIdentifier,
+ contentType,
+ params,
+ siteId,
+ });
+ });
+};
+
+const assertViewabilityModelClickEvent = ({
+ pageIdentifier,
+ params,
+ // applicationType,
+ siteId,
+}) => {
+ const eventContext = JSON.parse(params.context);
+
+ assertReverbViewabilityComponentEventParamsExist({
+ params,
+ });
+
+ // TODO: Commenting out temporarily until old ATI code is removed - https://bbc.atlassian.net/browse/WS-222
+ // if (['responsive', 'lite'].includes(applicationType)) {
+ // expect(params.idclient).to.equal(
+ // ATI_USER_ID_COOKIE,
+ // 'params.idclient (atuserid cookie value)',
+ // );
+ // }
+
+ expect(params.events).to.satisfy(
+ payload =>
+ validateViewabilityEventDetails({
+ payload,
+ actionType: VIEWABILITY_CLICK_EVENT,
+ }),
+ 'params.events (publisher click)',
+ );
+
+ expect(eventContext[0].data.page.$).to.equal(pageIdentifier);
+ expect(parseInt(eventContext[0].data.site.level2_id, 10)).to.equal(siteId);
+};
+
+export const assertATIComponentClickEvent = ({
+ component,
+ contentType,
+ pageIdentifier,
+ siteId,
+}) => {
+ const requestAlias = `@${component}-viewability-click`;
+
+ cy.wait(requestAlias)
+ .its('request.url')
+ .then(url => {
+ const params = getATIParamsFromURL(url);
+ assertViewabilityModelClickEvent({
+ component,
+ contentType,
+ pageIdentifier,
+ params,
+ siteId,
+ });
+ });
+};
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/latestMedia.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/latestMedia.ts
index 1e146ae27ef..5294b3df78f 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/latestMedia.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/latestMedia.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { LATEST_MEDIA } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/mostRead.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/mostRead.ts
index 7d41e4ea47e..d3e499daf0d 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/mostRead.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/mostRead.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
import runIfToggleEnabled from '../../../../support/helpers/runIfToggleEnabled';
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/navigation.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/navigation.ts
index d16f89d878c..5ba2820f656 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/navigation.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/navigation.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { SCROLLABLE_NAVIGATION, DROPDOWN_NAVIGATION } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/podcastPromo.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/podcastPromo.ts
index 8b7c8b98141..e14962bfa33 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/podcastPromo.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/podcastPromo.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { PODCAST_PROMO } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/recommendations.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/recommendations.ts
index bbd3cc9de52..cb6e2c9b7a4 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/recommendations.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/recommendations.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { RECOMMENDATIONS } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedContent.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedContent.ts
index 10360b7d3e4..783248cd963 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedContent.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedContent.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { RELATED_CONTENT } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedTopics.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedTopics.ts
index 30375524890..f1df5089c26 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedTopics.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/relatedTopics.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { RELATED_TOPICS } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/scrollablePromo.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/scrollablePromo.ts
index f8e6a8f259c..c59d73a847b 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/scrollablePromo.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/scrollablePromo.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { SCROLLABLE_PROMO } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/socialEmbed.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/socialEmbed.ts
index 26a308e566e..f57eff74e6b 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/socialEmbed.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/socialEmbed.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { SOCIAL_EMBED } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topBarOjs.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topBarOjs.ts
index 5ee6c57376a..fab0f32990a 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topBarOjs.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topBarOjs.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { TOP_BAR_OJ } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topStories.ts b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topStories.ts
index ebeac4ca5fb..d2cb306856d 100644
--- a/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topStories.ts
+++ b/ws-nextjs-app/cypress/e2e/specialFeatures/atiAnalytics/assertions/topStories.ts
@@ -1,9 +1,6 @@
/* eslint-disable import/no-relative-packages */
import { interceptATIAnalyticsBeacons, COMPONENTS } from '../helpers';
-import {
- assertATIComponentClickEvent,
- assertATIComponentViewEvent,
-} from '../../../../../../cypress/e2e/specialFeatures/atiAnalytics/assertions';
+import { assertATIComponentClickEvent, assertATIComponentViewEvent } from '.';
import { AtiAssertionFnProps } from './type';
const { TOP_STORIES } = COMPONENTS;
diff --git a/ws-nextjs-app/cypress/e2e/testsForAllAMPPages.ts b/ws-nextjs-app/cypress/e2e/testsForAllAMPPages.ts
index 20ec08b0236..861dddcc53e 100644
--- a/ws-nextjs-app/cypress/e2e/testsForAllAMPPages.ts
+++ b/ws-nextjs-app/cypress/e2e/testsForAllAMPPages.ts
@@ -1,15 +1,12 @@
/* eslint-disable import/prefer-default-export */
-import config from '../support/config/services';
import { ServiceParametersType } from '../types';
// For testing features that may differ across services but share a common logic e.g. translated strings.
export default ({ service, pageType }: ServiceParametersType) => {
describe(`testsThatFollowSmokeTestConfigForAllAMPPages to run for ${service} ${pageType}`, () => {
describe('Header Tests', () => {
- const serviceName = config[service]?.name || service;
// limit number of tests to 2 services for navigation toggling
- const testMobileNav =
- serviceName === 'ukchina' || serviceName === 'persian';
+ const testMobileNav = service === 'ukchina' || service === 'persian';
if (testMobileNav) {
it('should show dropdown menu and hide scrollable menu when menu button is clicked', () => {
cy.viewport(320, 480);
diff --git a/ws-nextjs-app/cypress/e2e/testsForAllCanonicalPages.ts b/ws-nextjs-app/cypress/e2e/testsForAllCanonicalPages.ts
index dec1cae3b37..17c356f13c7 100644
--- a/ws-nextjs-app/cypress/e2e/testsForAllCanonicalPages.ts
+++ b/ws-nextjs-app/cypress/e2e/testsForAllCanonicalPages.ts
@@ -1,6 +1,5 @@
/* eslint-disable import/prefer-default-export */
import envConfig, { EnvironmentConfigType } from '../support/config/envs';
-import config from '../support/config/services';
import { ServiceParametersType } from '../types';
// For testing features that may differ across services but share a common logic e.g. translated strings.
@@ -26,7 +25,7 @@ export default ({ service, pageType }: ServiceParametersType) => {
}
describe('Header Tests', () => {
- const serviceName = config[service]?.name || service;
+ const serviceName = service;
// limit number of tests to 2 services for navigation toggling
const testMobileNav =
serviceName === 'ukchina' || serviceName === 'persian';
diff --git a/ws-nextjs-app/cypress/support/config/services.ts b/ws-nextjs-app/cypress/support/config/services.ts
deleted file mode 100644
index 74581bc6de4..00000000000
--- a/ws-nextjs-app/cypress/support/config/services.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Services } from '#app/models/types/global';
-import allServices from './settings';
-
-// Allow runs to be limited to a single service via the CYPRESS_ONLY_SERVICE env var
-const runOnlyService = Cypress.env('ONLY_SERVICE');
-
-export default (() => {
- if (runOnlyService && Object.keys(allServices).includes(runOnlyService)) {
- return {
- [runOnlyService]: allServices[runOnlyService as Services],
- };
- }
-
- return allServices;
-})();
diff --git a/ws-nextjs-app/cypress/support/config/settings.ts b/ws-nextjs-app/cypress/support/config/settings.ts
deleted file mode 100644
index 73039098bf0..00000000000
--- a/ws-nextjs-app/cypress/support/config/settings.ts
+++ /dev/null
@@ -1,379 +0,0 @@
-import { Services } from '#app/models/types/global';
-
-export type ServiceConfigDataType = {
- name: string;
- font?: string;
- isWorldService?: boolean;
- variant: string;
- pageTypes: Record;
-};
-
-export default {
- afaanoromoo: {
- name: 'afaanoromoo',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- afrique: {
- name: 'afrique',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- amharic: {
- name: 'amharic',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- arabic: {
- name: 'arabic',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- azeri: {
- name: 'azeri',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- bengali: {
- name: 'bengali',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- burmese: {
- name: 'burmese',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- cymrufyw: {
- name: 'cymrufyw',
- font: 'Reith',
- isWorldService: false,
- variant: 'default',
- pageTypes: {},
- },
- gahuza: {
- name: 'gahuza',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- gujarati: {
- name: 'gujarati',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- hausa: {
- name: 'hausa',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- hindi: {
- name: 'hindi',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- igbo: {
- name: 'igbo',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- indonesia: {
- name: 'indonesia',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- japanese: {
- name: 'japanese',
- font: undefined,
- isWorldService: false,
- variant: 'default',
- pageTypes: {},
- },
- korean: {
- name: 'korean',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- kyrgyz: {
- name: 'kyrgyz',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- marathi: {
- name: 'marathi',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- mundo: {
- name: 'mundo',
- font: 'Reith',
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- naidheachdan: {
- name: 'naidheachdan',
- font: 'Reith',
- isWorldService: false,
- variant: 'default',
- pageTypes: {},
- },
- nepali: {
- name: 'nepali',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- news: {
- name: 'news',
- font: 'Reith',
- isWorldService: false,
- variant: 'default',
- pageTypes: {},
- },
- newsround: {
- name: 'newsround',
- font: undefined,
- variant: 'default',
- pageTypes: {},
- },
- pashto: {
- name: 'pashto',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- persian: {
- name: 'persian',
- font: 'Nassim',
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- pidgin: {
- name: 'pidgin',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- portuguese: {
- name: 'portuguese',
- font: 'Reith',
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- punjabi: {
- name: 'punjabi',
- font: undefined,
- variant: 'default',
- pageTypes: {},
- },
- russian: {
- name: 'russian',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- scotland: {
- name: 'scotland',
- font: undefined,
- isWorldService: false,
- variant: 'default',
- pageTypes: {},
- },
- serbianCyr: {
- name: 'serbian',
- font: undefined,
- isWorldService: true,
- variant: 'cyr',
- pageTypes: {},
- },
- serbianLat: {
- name: 'serbian',
- font: undefined,
- isWorldService: true,
- variant: 'lat',
- pageTypes: {},
- },
- sinhala: {
- name: 'sinhala',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- somali: {
- name: 'somali',
- font: undefined,
- variant: 'default',
- pageTypes: {},
- },
- sport: {
- name: 'sport',
- font: undefined,
- variant: 'default',
- pageTypes: {},
- },
- swahili: {
- name: 'swahili',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- tamil: {
- name: 'tamil',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- telugu: {
- name: 'telugu',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- thai: {
- name: 'thai',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- tigrinya: {
- name: 'tigrinya',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- turkce: {
- name: 'turkce',
- font: 'Reith',
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- ukchinaSimp: {
- name: 'ukchina',
- font: undefined,
- isWorldService: true,
- variant: 'simp',
- pageTypes: {},
- },
- ukchinaTrad: {
- name: 'ukchina',
- font: undefined,
- isWorldService: true,
- variant: 'trad',
- pageTypes: {},
- },
- ukrainianRu: {
- name: 'ukrainian',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- ukrainian: {
- name: 'ukrainian',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- urdu: {
- name: 'urdu',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- uzbek: {
- name: 'uzbek',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- uzbekCyr: {
- name: 'uzbek',
- font: undefined,
- isWorldService: true,
- variant: 'cyr',
- pageTypes: {},
- },
- uzbekLat: {
- name: 'uzbek',
- font: undefined,
- isWorldService: true,
- variant: 'lat',
- pageTypes: {},
- },
- vietnamese: {
- name: 'vietnamese',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- yoruba: {
- name: 'yoruba',
- font: undefined,
- isWorldService: true,
- variant: 'default',
- pageTypes: {},
- },
- zhongwenSimp: {
- name: 'zhongwen',
- font: undefined,
- isWorldService: true,
- variant: 'simp',
- pageTypes: {},
- },
- zhongwenTrad: {
- name: 'zhongwen',
- font: undefined,
- isWorldService: true,
- variant: 'trad',
- pageTypes: {},
- },
-} as Partial>;
diff --git a/ws-nextjs-app/cypress/support/helpers/adsTests/testsForAMPOnly.ts b/ws-nextjs-app/cypress/support/helpers/adsTests/testsForAMPOnly.ts
index 248f98bc399..fd376a99550 100644
--- a/ws-nextjs-app/cypress/support/helpers/adsTests/testsForAMPOnly.ts
+++ b/ws-nextjs-app/cypress/support/helpers/adsTests/testsForAMPOnly.ts
@@ -1,16 +1,11 @@
import path from 'ramda/src/path';
-import serviceConfig from '../../config/services';
import { ServiceParametersType } from '../../../types';
-import { ServiceConfigDataType } from '../../config/settings';
export default ({ service }: ServiceParametersType) => {
describe(`AMP Ads`, () => {
it('should be displayed based on whether ads toggle is enabled/disabled', () => {
- const config = serviceConfig[service] as ServiceConfigDataType;
- const serviceName = config.name;
-
- cy.getToggles(serviceName).then(() => {
- cy.fixture(`toggles/${serviceName}.json`).then(toggles => {
+ cy.getToggles(service).then(() => {
+ cy.fixture(`toggles/${service}.json`).then(toggles => {
const adsEnabled = path(['ads', 'enabled'], toggles);
if (adsEnabled) {
diff --git a/ws-nextjs-app/cypress/support/helpers/adsTests/testsForCanonicalOnly.ts b/ws-nextjs-app/cypress/support/helpers/adsTests/testsForCanonicalOnly.ts
index 8d6f1a53ae1..4077a237c49 100644
--- a/ws-nextjs-app/cypress/support/helpers/adsTests/testsForCanonicalOnly.ts
+++ b/ws-nextjs-app/cypress/support/helpers/adsTests/testsForCanonicalOnly.ts
@@ -1,18 +1,10 @@
-import serviceConfig from '../../config/services';
import { ServiceParametersType } from '../../../types';
-import { ServiceConfigDataType } from '../../config/settings';
export default ({ service }: ServiceParametersType) => {
describe(`Canonical Ads`, () => {
it('should be displayed based on whether ads toggle is enabled/disabled', () => {
- let serviceName = service as string;
- if (Object.keys(serviceConfig).includes(service)) {
- const config = serviceConfig[service] as ServiceConfigDataType;
- serviceName = config.name;
- }
-
- cy.getToggles(serviceName).then(() => {
- cy.fixture(`toggles/${serviceName}.json`).then(toggles => {
+ cy.getToggles(service).then(() => {
+ cy.fixture(`toggles/${service}.json`).then(toggles => {
const adsEnabled = toggles.ads?.enabled;
if (adsEnabled) {