From 4ebbbdb21ed6328695b958650c140cb22a63511d Mon Sep 17 00:00:00 2001 From: Mohamed Fall Date: Sun, 4 Jan 2026 18:03:51 +0000 Subject: [PATCH 1/4] fix(LoginPage): allow brand props passthrough and fix brand appearing without props Signed-off-by: Mohamed Fall --- packages/react-core/src/components/LoginPage/LoginPage.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/react-core/src/components/LoginPage/LoginPage.tsx b/packages/react-core/src/components/LoginPage/LoginPage.tsx index e0fa868a096..5ebba9325eb 100644 --- a/packages/react-core/src/components/LoginPage/LoginPage.tsx +++ b/packages/react-core/src/components/LoginPage/LoginPage.tsx @@ -2,7 +2,7 @@ import { Fragment } from 'react'; import { css } from '@patternfly/react-styles'; import { BackgroundImage } from '../BackgroundImage'; -import { Brand } from '../Brand'; +import { Brand, BrandProps } from '../Brand'; import { List, ListVariant } from '../List'; import { Login } from './Login'; @@ -21,6 +21,8 @@ export interface LoginPageProps extends React.HTMLProps { brandImgSrc?: string; /** Attribute that specifies the alt text of the brand image for the login page */ brandImgAlt?: string; + /** Additional props for the brand image for the login page */ + brandImgProps?: BrandProps; /** Attribute that specifies the URL of the background image for the login page */ backgroundImgSrc?: string; /** Content rendered inside of the text component of the login page */ @@ -50,6 +52,7 @@ export const LoginPage: React.FunctionComponent = ({ className = '', brandImgSrc = '', brandImgAlt = '', + brandImgProps, backgroundImgSrc = '', footerListItems = null, textContent = '', @@ -65,7 +68,7 @@ export const LoginPage: React.FunctionComponent = ({ }: LoginPageProps) => { const HeaderBrand = ( - + {(brandImgSrc || brandImgProps?.src) && } ); const Header = ; From 9df125d437ce0fb81b3cff5366d1b03e717b548e Mon Sep 17 00:00:00 2001 From: Mohamed Fall Date: Sat, 10 Jan 2026 06:51:45 +0000 Subject: [PATCH 2/4] test(LoginPage): add tests for brand image rendering scenarios Signed-off-by: Mohamed Fall --- .../LoginPage/__tests__/LoginPage.test.tsx | 17 +++ .../__snapshots__/LoginPage.test.tsx.snap | 141 ++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx b/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx index e76f7589645..d126d82ea42 100644 --- a/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx +++ b/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx @@ -26,3 +26,20 @@ test('check loginpage example against snapshot', () => { ); expect(asFragment()).toMatchSnapshot(); }); + +test('brand is absent without brandImgSrc and brandImgProps.src', () => { + const { asFragment } = render(); + expect(asFragment()).toMatchSnapshot(); +}); + +test('brand is present with brandImgSrc prop', () => { + const { asFragment } = render(); + expect(asFragment()).toMatchSnapshot(); +}); + +test('brandImgProps successfully renders brand with props', () => { + const { asFragment } = render( + + ); + expect(asFragment()).toMatchSnapshot(); +}); diff --git a/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap b/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap index 2ff29357dc3..452e58d96c8 100644 --- a/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap +++ b/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap @@ -1,5 +1,146 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`brand is absent without brandImgSrc and brandImgProps.src 1`] = ` + + + +`; + +exports[`brand is present with brandImgSrc prop 1`] = ` + + + +`; + +exports[`brandImgProps successfully renders brand with props 1`] = ` + + + +`; + exports[`check loginpage example against snapshot 1`] = `
Date: Sat, 10 Jan 2026 07:08:48 +0000 Subject: [PATCH 3/4] test(LoginPage): enhance brand image tests with aria-label and className attributes Signed-off-by: Mohamed Fall --- .../LoginPage/__tests__/LoginPage.test.tsx | 28 +++++++++-- .../__snapshots__/LoginPage.test.tsx.snap | 49 ------------------- 2 files changed, 24 insertions(+), 53 deletions(-) diff --git a/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx b/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx index d126d82ea42..479cd14bfb0 100644 --- a/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx +++ b/packages/react-core/src/components/LoginPage/__tests__/LoginPage.test.tsx @@ -1,5 +1,5 @@ import { Fragment } from 'react'; -import { render } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; import { LoginPage } from '../LoginPage'; import { ListVariant } from '../../List'; @@ -38,8 +38,28 @@ test('brand is present with brandImgSrc prop', () => { }); test('brandImgProps successfully renders brand with props', () => { - const { asFragment } = render( - + render( + ); - expect(asFragment()).toMatchSnapshot(); + const brandImg = screen.getByRole('img', { name: 'PatternFly logo' }); + expect(brandImg).toHaveAttribute('src', 'Brand src'); + expect(brandImg).toHaveAttribute('alt', 'Pf-logo'); + expect(brandImg).toHaveAttribute('aria-label', 'PatternFly logo'); + expect(brandImg).toHaveClass('custom-class'); +}); + +test('Brand is rendered correctly with both brandImgSrc and brandImgProps, prioritizing brandImgProps.src', () => { + render( + + ); + const brandImg = screen.getByRole('img', { name: 'Pf-logo from props' }); + expect(brandImg).toHaveAttribute('src', 'Brand-src-from-props'); + expect(brandImg).toHaveAttribute('alt', 'Pf-logo from props'); }); diff --git a/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap b/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap index 452e58d96c8..f17fadf07a7 100644 --- a/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap +++ b/packages/react-core/src/components/LoginPage/__tests__/__snapshots__/LoginPage.test.tsx.snap @@ -92,55 +92,6 @@ exports[`brand is present with brandImgSrc prop 1`] = ` `; -exports[`brandImgProps successfully renders brand with props 1`] = ` - - - -`; - exports[`check loginpage example against snapshot 1`] = `
Date: Sat, 10 Jan 2026 07:27:45 +0000 Subject: [PATCH 4/4] fix(LoginPage): update examples to include new brandImgProps for Brand customization Signed-off-by: Mohamed Fall --- .../react-core/src/components/LoginPage/examples/LoginPage.md | 2 ++ .../src/components/LoginPage/examples/LoginPageBasic.tsx | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/react-core/src/components/LoginPage/examples/LoginPage.md b/packages/react-core/src/components/LoginPage/examples/LoginPage.md index 50a24f6be00..7973498ca12 100644 --- a/packages/react-core/src/components/LoginPage/examples/LoginPage.md +++ b/packages/react-core/src/components/LoginPage/examples/LoginPage.md @@ -32,6 +32,8 @@ import GitlabIcon from '@patternfly/react-icons/dist/esm/icons/gitlab-icon'; ### Basic By default, a login page requires users to enter both a username and a password into their respective fields. The username must always be a required field, but you can make the password optional by passing the `isPasswordRequired` property to the ``. + +This example uses `brandImgProps` to pass the brand image source, alt text, and an extra class, which will be preferred over `brandImgSrc` when both are provided. ```ts file='./LoginPageBasic.tsx' isFullscreen ``` diff --git a/packages/react-core/src/components/LoginPage/examples/LoginPageBasic.tsx b/packages/react-core/src/components/LoginPage/examples/LoginPageBasic.tsx index 8d8ee40e7bf..a518ff41ff1 100644 --- a/packages/react-core/src/components/LoginPage/examples/LoginPageBasic.tsx +++ b/packages/react-core/src/components/LoginPage/examples/LoginPageBasic.tsx @@ -114,8 +114,7 @@ export const SimpleLoginPage: React.FunctionComponent = () => { return (