Skip to content

Commit

Permalink
[DNM] React 19 (#12374)
Browse files Browse the repository at this point in the history
* Testing

* cache

* cache

* Update `@types/react`

* Update dependabot.yml

* Update Emotion to support React 19 types

* run yarn dedupe

* Type fixes

* viewRef updates

* more viewRef fixes

* more viewRef updates

* Try `React.JSX` namespace for type declaration files

* Update bundleSizeConfig.js

* Update index.jsx

* cache

* cache

* Syntax and test fixes

* Update index.tsx

* Update component.test.jsx.snap

* Disable AMP boilerplate test temporarily

* Update client.js

* Update client.js

* Try retries for Chartbeat timeouts

* Revert "Try retries for Chartbeat timeouts"

This reverts commit eb78848.

* Force reload of window for Chartbeat script tests

* Test with retries on Chartbeat e2e

* Remove eslint ignores for `imagesrcset` and `imageSizes`

* AMP boilerplate test refactor

* Missed file

* Remove `fetchpriority` from eslint ignore

* Update bundleSizeConfig.js
  • Loading branch information
amoore108 authored Feb 10, 2025
1 parent d6b705d commit 7529531
Show file tree
Hide file tree
Showing 104 changed files with 410 additions and 416 deletions.
3 changes: 0 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,6 @@ module.exports = {
'custom-element',
'custom-template',
'fallback',
'fetchpriority',
'imagesizes',
'imagesrcset',
],
},
],
Expand Down
9 changes: 0 additions & 9 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,6 @@ updates:
- dependency-name: 'react-router'
# https://jira.dev.bbc.co.uk/browse/NEWSWORLDSERVICE-2099: Delete path-to-regexp dependency
- dependency-name: 'path-to-regexp'
# https://jira.dev.bbc.co.uk/browse/NEWSWORLDSERVICE-2187: Latest major version of react has breaking changes
- dependency-name: 'react'
update-types: ['version-update:semver-major']
- dependency-name: 'react-dom'
update-types: ['version-update:semver-major']
- dependency-name: '@types/react'
update-types: ['version-update:semver-major']
- dependency-name: '@types/react-dom'
update-types: ['version-update:semver-major']
labels:
- 'dependencies'
groups:
Expand Down
2 changes: 1 addition & 1 deletion .storybook/DocsDecorator/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { type JSX } from 'react';
import {
DocsContainer,
DocsContextProps,
Expand Down
2 changes: 1 addition & 1 deletion .storybook/withServicesDecorator/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React from 'react';
import React, { type JSX } from 'react';
import { Helmet } from 'react-helmet';
import { StoryProps } from '#app/models/types/storybook';
import { Services, Variants } from '#app/models/types/global';
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added .yarn/cache/fsevents-patch-6b67494872-10.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
2 changes: 1 addition & 1 deletion cypress/e2e/pages/articles/testsForCanonicalOnly.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const serviceHasCaption = service => service === 'news';
export default ({ service, pageType, variant = 'default' }) =>
describe(`Canonical Tests for ${service} ${pageType}`, () => {
if (appToggles.chartbeatAnalytics.enabled) {
describe('Chartbeat', () => {
describe('Chartbeat', { retries: 3 }, () => {
if (envConfig.chartbeatEnabled) {
it('should have a script with src value set to chartbeat source', () => {
cy.hasScriptWithChartbeatSrc();
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/homePage/testsForCanonicalOnly.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export default ({ service }) => {
runAdsTests({ service });
}

describe(`Chartbeat analytics`, () => {
describe(`Chartbeat analytics`, { retries: 3 }, () => {
it('should have a script with src value set to chartbeat source', () => {
cy.hasScriptWithChartbeatSrc();
});
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/liveRadio/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export default ({ service, pageType }) =>
},
);

describe('Chartbeat', () => {
describe('Chartbeat', { retries: 3 }, () => {
if (envConfig.chartbeatEnabled) {
it('should have a script with src value set to chartbeat source', () => {
cy.hasScriptWithChartbeatSrc();
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/mediaAssetPage/testsForCanonicalOnly.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const testsThatFollowSmokeTestConfigForCanonicalOnly = ({
}) => {
describe(`testsThatFollowSmokeTestConfigForCanonicalOnly for ${service} ${pageType}`, () => {
if (appToggles.chartbeatAnalytics.enabled && envConfig.chartbeatEnabled) {
describe('Chartbeat', () => {
describe('Chartbeat', { retries: 3 }, () => {
it('should have a script with correct src', () => {
cy.hasScriptWithChartbeatSrc();
});
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/mostReadPage/testsForCanonicalOnly.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import envConfig from '../../../support/config/envs';

export default ({ service, pageType, variant }) => {
describe(`testsForCanonicalOnly for ${service} ${pageType} ${variant}`, () => {
describe('Chartbeat', () => {
describe('Chartbeat', { retries: 3 }, () => {
if (envConfig.chartbeatEnabled) {
it('should have a script with src value set to chartbeat source', () => {
cy.hasScriptWithChartbeatSrc();
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/onDemandAudio/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export default ({ service, pageType, variant }) => {
});
});
});
describe('Chartbeat', () => {
describe('Chartbeat', { retries: 3 }, () => {
if (envConfig.chartbeatEnabled) {
it('should have a script with src value set to chartbeat source', () => {
cy.hasScriptWithChartbeatSrc();
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/onDemandTV/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default ({ service, pageType, variant }) => {
});
});
},
describe('Chartbeat', () => {
describe('Chartbeat', { retries: 3 }, () => {
if (envConfig.chartbeatEnabled) {
it('should have a script with src value set to chartbeat source', () => {
cy.hasScriptWithChartbeatSrc();
Expand Down
2 changes: 2 additions & 0 deletions cypress/support/commands/analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ Cypress.Commands.add('hasNoscriptImgAtiUrl', atiUrl => {

// Should be moved into integration/pages/index.js once all pages have Chartbeat
Cypress.Commands.add('hasScriptWithChartbeatSrc', () => {
cy.reload(true);
cy.get(`script[src="//static.chartbeat.com/js/chartbeat.js"]`).should(
'exist',
);
});

// Should be moved into integration/pages/index.js once all pages have Chartbeat
Cypress.Commands.add('hasGlobalChartbeatConfig', () => {
cy.reload(true);
cy.window().should('have.property', '_sf_async_config');
});
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"@optimizely/js-sdk-utils": "0.4.0",
"uuid": "3.4.0",
"[email protected]": "patch:winston@npm:3.8.2#.yarn/patches/winston-npm-3.8.2-2035e9cac4.patch",
"cookie": "0.7.1"
"cookie": "0.7.1",
"react-is": "19.0.0"
},
"workspaces": {
"packages": [
Expand Down Expand Up @@ -120,8 +121,8 @@
"morgan": "1.10.0",
"polyfill-crypto.getrandomvalues": "1.0.0",
"ramda": "0.30.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-helmet": "6.1.0",
"react-lazyload": "3.2.1",
"react-router-config": "5.1.1",
Expand Down Expand Up @@ -185,8 +186,8 @@
"@types/jsdom": "21.1.7",
"@types/loadable__component": "5.13.9",
"@types/ramda": "0.30.2",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.1",
"@types/react": "19.0.8",
"@types/react-dom": "19.0.3",
"@types/react-helmet": "6.1.11",
"@types/react-lazyload": "^3.2.0",
"@types/react-router-dom": "5.3.3",
Expand Down
4 changes: 2 additions & 2 deletions scripts/bundleSize/bundleSizeConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
* We are allowing a variance of -5 on `MIN_SIZE` and +5 on `MAX_SIZE` to avoid the need for frequent changes, as bundle sizes can fluctuate
*/

export const MIN_SIZE = 640 - 5;
export const MAX_SIZE = 1174 + 5;
export const MIN_SIZE = 680 - 5;
export const MAX_SIZE = 1207 + 5;
2 changes: 1 addition & 1 deletion src/app/components/ATIAnalytics/amp/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare namespace JSX {
declare namespace React.JSX {
/*
* AMP currently doesn't have built-in types for TypeScript, but it's in their roadmap (https://github.com/ampproject/amphtml/issues/13791).
* As a workaround you can manually create custom types (https://stackoverflow.com/a/50601125).
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Ad/Amp/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare namespace JSX {
declare namespace React.JSX {
/*
* AMP currently doesn't have built-in types for TypeScript, but it's in their roadmap (https://github.com/ampproject/amphtml/issues/13791).
* As a workaround you can manually create custom types (https://stackoverflow.com/a/50601125).
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/AmpExperiment/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare namespace JSX {
declare namespace React.JSX {
interface IntrinsicElements {
'amp-experiment': React.PropsWithChildren<
ScriptHTMLAttributes<HTMLScriptElement>
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/AmpIframe/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const AmpIframe = ({
Show more
</button>
</div>
<amp-img layout="fill" src={image} placeholder />
<amp-img layout="fill" src={image} placeholder="true" />
</AmpIframeElement>
</GridItemMedium>
</>
Expand Down
4 changes: 2 additions & 2 deletions src/app/components/Billboard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @jsx jsx */
/* @jsxFrag React.Fragment */
import { forwardRef } from 'react';
import { ForwardedRef, forwardRef } from 'react';
import { jsx } from '@emotion/react';
import useViewTracker from '#app/hooks/useViewTracker';
import useClickTrackerHandler from '#app/hooks/useClickTrackerHandler';
Expand Down Expand Up @@ -35,7 +35,7 @@ const Billboard = forwardRef(
eventTrackingData,
showLiveLabel,
}: BillboardProps,
viewRef,
viewRef: ForwardedRef<HTMLDivElement>,
) => {
const clickTrackerHandler = useClickTrackerHandler(eventTrackingData);

Expand Down
2 changes: 1 addition & 1 deletion src/app/components/ChartbeatAnalytics/amp/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare namespace JSX {
declare namespace React.JSX {
/*
* AMP currently doesn't have built-in types for TypeScript, but it's in their roadmap (https://github.com/ampproject/amphtml/issues/13791).
* As a workaround you can manually create custom types (https://stackoverflow.com/a/50601125).
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/ChartbeatAnalytics/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ describe('Charbeats Analytics Container', () => {
{
chartbeatConfig: expectedConfig,
},
{},
undefined,
);
expect(testUtils.getConfig).toHaveBeenCalledTimes(1);
expect(container.firstChild).not.toBeNull();
Expand Down
21 changes: 14 additions & 7 deletions src/app/components/Curation/CurationPromo/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,20 @@ const CurationPromo = ({

return (
<Promo>
<Promo.Image src={imageUrl} alt={imageAlt} lazyLoad={lazy} isAmp={isAmp}>
{isMedia && (
<Promo.MediaIcon type={type}>
{showDuration ? mediaDuration : ''}
</Promo.MediaIcon>
)}
</Promo.Image>
{imageUrl && (
<Promo.Image
src={imageUrl}
alt={imageAlt}
lazyLoad={lazy}
isAmp={isAmp}
>
{isMedia && (
<Promo.MediaIcon type={type}>
{showDuration ? mediaDuration : ''}
</Promo.MediaIcon>
)}
</Promo.Image>
)}
<Promo.Heading as={`h${headingLevel}`}>
{isMedia ? (
<Promo.A href={link} aria-labelledby={id}>
Expand Down
20 changes: 13 additions & 7 deletions src/app/components/Curation/HierarchicalGrid/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ describe('Hierarchical Grid Curation', () => {

it('should render the last published date', async () => {
const { getByText } = render(
<HierarchicalGrid summaries={mediaFixture} />,
<HierarchicalGrid headingLevel={headingLevel} summaries={mediaFixture} />,
{
service: 'mundo',
},
Expand All @@ -109,16 +109,22 @@ describe('Hierarchical Grid Curation', () => {
});

it('should display LiveLabel on a Live Promo', () => {
const container = render(<HierarchicalGrid summaries={mediaFixture} />, {
service: 'mundo',
});
const container = render(
<HierarchicalGrid headingLevel={headingLevel} summaries={mediaFixture} />,
{
service: 'mundo',
},
);
expect(container.getByText('EN VIVO')).toBeInTheDocument();
});

it('should not display a timestamp on a Live Promo', () => {
const container = render(<HierarchicalGrid summaries={liveFixtures} />, {
service: 'mundo',
});
const container = render(
<HierarchicalGrid headingLevel={headingLevel} summaries={liveFixtures} />,
{
service: 'mundo',
},
);
expect(container.queryByText('13 noviembre 2022')).not.toBeInTheDocument();
});
});
12 changes: 7 additions & 5 deletions src/app/components/Curation/HierarchicalGrid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ const HiearchicalGrid = ({
<Promo>
<Promo.Image
useLargeImages={useLargeImages}
src={promo.imageUrl || ''}
src={promo.imageUrl || null}
alt={promo.imageAlt}
lazyLoad={lazyLoadImages}
fetchpriority={fetchpriority}
fetchPriority={fetchpriority}
isAmp={isAmp}
>
{isMedia && (
Expand Down Expand Up @@ -124,9 +124,11 @@ const HiearchicalGrid = ({
<Promo.A href={promo.link}>
{isLive ? (
<LiveLabel
{...(isFirstPromo && {
className: 'first-promo',
})}
{...(isFirstPromo
? {
className: 'first-promo',
}
: undefined)}
>
{promo.title}
</LiveLabel>
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/EmbedConsentBanner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, PropsWithChildren } from 'react';
import React, { useState, PropsWithChildren, type JSX } from 'react';
import ConsentBanner from './ConsentBanner';

import { SocialEmbedProviders } from '../../models/types/global';
Expand Down
1 change: 1 addition & 0 deletions src/app/components/FrostedGlassPromo/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { JSX } from 'react';
import { EventTrackingBlock } from '../../models/types/eventTracking';

export type ImageProps = {
Expand Down
12 changes: 6 additions & 6 deletions src/app/components/Image/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ type Props = {
sizes?: string;
src: string;
width?: number;
fetchpriority?: 'high';
fetchPriority?: 'high';
hasCaption?: boolean;
};

Expand Down Expand Up @@ -59,7 +59,7 @@ const Image = ({
src,
width,
children,
fetchpriority,
fetchPriority,
hasCaption,
}: PropsWithChildren<Props>) => {
const { pageType, isLite } = useContext(RequestContext);
Expand Down Expand Up @@ -109,8 +109,8 @@ const Image = ({
rel="preload"
as="image"
href={src}
imagesrcset={srcSet}
imagesizes={sizes}
imageSrcSet={srcSet}
imageSizes={sizes}
/>
</Helmet>
)}
Expand Down Expand Up @@ -159,7 +159,7 @@ const Image = ({
attribution={attribution}
{...(srcSet && { srcSet: imgSrcSet })}
{...(imgSizes && { sizes: imgSizes })}
{...(preload && { 'data-hero': true })}
{...(preload && { 'data-hero': 'true' })}
/>
</>
) : (
Expand Down Expand Up @@ -190,7 +190,7 @@ const Image = ({
? styles.imageFixedAspectRatio
: styles.imageResponsiveRatio,
]}
fetchpriority={fetchpriority}
fetchPriority={fetchPriority}
style={{
aspectRatio: hasFixedAspectRatio
? `${aspectRatioX} / ${aspectRatioY}`
Expand Down
15 changes: 4 additions & 11 deletions src/app/components/Image/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
declare namespace JSX {
declare namespace React.JSX {
/*
* AMP currently doesn't have built-in types for TypeScript, but it's in their roadmap (https://github.com/ampproject/amphtml/issues/13791).
* As a workaround you can manually create custom types (https://stackoverflow.com/a/50601125).
Expand All @@ -15,21 +15,14 @@ declare namespace JSX {
src?: string;
srcSet?: string;
width?: number;
placeholder?: boolean;
}
/*
* Overrides type for link with missing imagesrcset and imagesizes attributes
*/
interface LinkProps extends React.LinkHTMLAttributes<HTMLLinkElement> {
imagesrcset?: string;
imagesizes?: string;
placeholder?: string | boolean;
}

interface ImageProps extends React.ImgHTMLAttributes<HTMLImageElement> {
fetchpriority?: string;
fetchPriority?: string;
}
interface IntrinsicElements {
'amp-img': AmpImgProps;
link: LinkProps;
img: ImageProps;
}
}
Loading

0 comments on commit 7529531

Please sign in to comment.