CreateImageWizard: rhc support

This commit is contained in:
Sanne Raymaekers 2023-02-17 17:27:06 +01:00
parent 60a6021585
commit 9e6d951641
8 changed files with 467 additions and 94 deletions

View file

@ -50,7 +50,16 @@ const onSave = (values) => {
customizations['payload_repositories'] = [...values['custom-repositories']];
}
if (values['register-system'] === 'register-now-insights') {
if (values['register-system'] === 'register-now-rhc') {
customizations.subscription = {
'activation-key': values['subscription-activation-key'],
insights: true,
rhc: true,
organization: Number(values['subscription-organization-id']),
'server-url': values['subscription-server-url'],
'base-url': values['subscription-base-url'],
};
} else if (values['register-system'] === 'register-now-insights') {
customizations.subscription = {
'activation-key': values['subscription-activation-key'],
insights: true,
@ -423,7 +432,9 @@ const requestToState = (composeRequest) => {
// subscription
const subscription = composeRequest?.customizations?.subscription;
if (subscription) {
if (subscription.insights) {
if (subscription.rhc) {
formState['register-system'] = 'register-now-rhc';
} else if (subscription.insights) {
formState['register-system'] = 'register-now-insights';
} else {
formState['register-system'] = 'register-now';

View file

@ -52,3 +52,9 @@
.pf-u-max-width {
--pf-u-max-width--MaxWidth: 26rem;
}
.pf-m-plain {
list-style: none;
padding-left: 0;
margin-left: 0;
}

View file

@ -20,6 +20,7 @@ import {
RedHatPackages,
} from './formComponents/Packages';
import RadioWithPopover from './formComponents/RadioWithPopover';
import Registration from './formComponents/Registration';
import RegistrationKeyInformation from './formComponents/RegistrationKeyInformation';
import Repositories from './formComponents/Repositories';
import Review from './formComponents/ReviewStep';
@ -69,6 +70,7 @@ const ImageCreator = ({
'aws-sources-select': AWSSourcesSelect,
'gallery-layout': GalleryLayout,
'field-listener': FieldListenerWrapper,
registration: Registration,
...customComponentMapper,
}}
onCancel={onClose}

View file

@ -0,0 +1,278 @@
import React, { useEffect, useState } from 'react';
import { FormSpy } from '@data-driven-forms/react-form-renderer';
import useFieldApi from '@data-driven-forms/react-form-renderer/use-field-api';
import useFormApi from '@data-driven-forms/react-form-renderer/use-form-api';
import {
Button,
Checkbox,
FormGroup,
Popover,
Radio,
Text,
TextContent,
} from '@patternfly/react-core';
import { HelpIcon, ExternalLinkAltIcon } from '@patternfly/react-icons';
import PropTypes from 'prop-types';
const RHSMPopover = () => {
return (
<Popover
headerContent="About Red Hat Subscription Management"
position="right"
minWidth="25rem"
bodyContent={
<TextContent>
<Text>
Registered systems are entitled to support services, as well as
errata, patches, and upgrades.
</Text>
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href="https://access.redhat.com/products/red-hat-subscription-management"
>
Read more
</Button>
</TextContent>
}
>
<Button
variant="plain"
className="pf-c-form__group-label-help"
aria-label="About Remote Host Configuration (RHC)"
isInline
>
<HelpIcon />
</Button>
</Popover>
);
};
const InsightsPopover = () => {
return (
<Popover
headerContent="About Red Hat Insights"
position="right"
minWidth="25rem"
bodyContent={
<TextContent>
<Text>
Insights client is a tool which provides actionable intelligence
about your Red Hat Enterprise Linux environments, helping to
identify and address operational and vulnerability risks before an
issue results in downtime.
</Text>
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href="https://access.redhat.com/products/red-hat-insights"
>
Read more
</Button>
</TextContent>
}
>
<Button
variant="plain"
className="pf-c-form__group-label-help"
aria-label="About Remote Host Configuration (RHC)"
isInline
>
<HelpIcon />
</Button>
</Popover>
);
};
const RHCPopover = () => {
return (
<Popover
headerContent="About Remote Host Configuration (RHC)"
position="right"
minWidth="25rem"
bodyContent={
<TextContent>
<Text>
RHC is a tool that allows RHEL hosts to connect to the Insights
services. It is required for the Insights Remediations service.
</Text>
<Button
component="a"
target="_blank"
variant="link"
icon={<ExternalLinkAltIcon />}
iconPosition="right"
isInline
href="https://access.redhat.com/articles/rhc"
>
Read more
</Button>
</TextContent>
}
>
<Button
variant="plain"
className="pf-c-form__group-label-help"
aria-label="About Remote Host Configuration (RHC)"
isInline
>
<HelpIcon />
</Button>
</Popover>
);
};
const Registration = ({ label, ...props }) => {
const { change, getState } = useFormApi();
const { input } = useFieldApi(props);
const [showOptions, setShowOptions] = useState(false);
const [insights, setInsights] = useState(true);
const [rhc, setRhc] = useState(true);
const registerSystem = getState()?.values?.['register-system'];
useEffect(() => {
if (registerSystem === 'register-now-insights') {
setShowOptions(true);
setInsights(true);
setRhc(false);
}
if (registerSystem === 'register-now') {
setShowOptions(true);
setInsights(false);
setRhc(false);
}
}, []);
useEffect(() => {
if (insights && rhc) {
change(input.name, 'register-now-rhc');
} else if (insights && !rhc) {
change(input.name, 'register-now-insights');
} else if (!insights && !rhc) {
change(input.name, 'register-now');
}
}, [insights, rhc]);
return (
<FormSpy>
{() => (
<FormGroup label={label}>
<Radio
autoFocus
label={
(!showOptions &&
'Automatically register and enable advanced capabilities') || (
<>
Monitor & manage subscriptions and access to Red Hat content
<RHSMPopover />
</>
)
}
data-testid="registration-radio-now"
name="register-system"
id="register-system-now"
checked={registerSystem.startsWith('register-now')}
onChange={() => {
// If rhc (or insights) was disabled previously, enable them again
if (!rhc) {
setInsights(true);
setRhc(true);
} else {
// useEffect[insights, rhc] won't be triggered if both insights and rhc were enabled
change(input.name, 'register-now-rhc');
}
}}
description={
!showOptions && (
<Button
component="a"
data-testid="registration-additional-options"
variant="link"
isDisabled={!registerSystem.startsWith('register-now')}
isInline
onClick={() => setShowOptions(!showOptions)}
>
Show additional connection options
</Button>
)
}
body={
showOptions && (
<Checkbox
className="pf-u-ml-lg"
label={
<>
Enable predictive analytics and management capabilities
<InsightsPopover />
</>
}
data-testid="registration-checkbox-insights"
isChecked={insights}
onChange={(checked) => {
setInsights(checked);
// Uncheck rhc if insights is being unchecked
if (!checked) {
setRhc(!insights);
}
}}
id="register-system-now-insights"
name="register-system-insights"
body={
<Checkbox
label={
<>
Enable remote remediations and system management with
automation
<RHCPopover />
</>
}
data-testid="registration-checkbox-rhc"
isChecked={rhc}
onChange={(checked) => {
setRhc(checked);
// Enable insights if not already enabled
if (!insights) {
setInsights(true);
}
}}
id="register-system-now-rhc"
name="register-system-rhc"
/>
}
/>
)
}
/>
<Radio
name="register-system"
className="pf-u-mt-md"
data-testid="registration-radio-later"
id="register-system-later"
label="Register later"
checked={registerSystem === 'register-later'}
onChange={() => {
setShowOptions(false);
change(input.name, 'register-later');
}}
/>
</FormGroup>
)}
</FormSpy>
);
};
Registration.propTypes = {
label: PropTypes.node,
};
export default Registration;

View file

@ -87,10 +87,7 @@ const ReviewStep = () => {
useEffect(() => {
const registerSystem = getState()?.values?.['register-system'];
if (
registerSystem === 'register-now' ||
registerSystem === 'register-now-insights'
) {
if (registerSystem?.startsWith('register-now')) {
(async () => {
const userData = await insights?.chrome?.auth?.getUser();
const id = userData?.identity?.internal?.org_id;
@ -324,20 +321,44 @@ const ReviewStep = () => {
</TextList>
</TextContent>
)}
{(getState()?.values?.['register-system'] === 'register-now' ||
getState()?.values?.['register-system'] ===
'register-now-insights') && (
{getState()?.values?.['register-system']?.startsWith(
'register-now'
) && (
<TextContent>
<TextList component={TextListVariants.dl}>
<TextListItem component={TextListItemVariants.dt}>
Registration type
</TextListItem>
<TextListItem component={TextListItemVariants.dd}>
{getState()?.values?.['register-system'] ===
'register-now-insights' &&
'Register with Subscriptions and Red Hat Insights'}
{getState()?.values?.['register-system'] ===
'register-now' && 'Register with Subscriptions'}
<TextListItem
component={TextListItemVariants.dd}
data-testid="review-registration"
>
<TextList isPlain>
{getState()?.values?.['register-system']?.startsWith(
'register-now'
) && (
<TextListItem>
Register with Red Hat Subscription Manager (RHSM)
<br />
</TextListItem>
)}
{(getState()?.values?.['register-system'] ===
'register-now-insights' ||
getState()?.values?.['register-system'] ===
'register-now-rhc') && (
<TextListItem>
Connect to Red Hat Insights
<br />
</TextListItem>
)}
{getState()?.values?.['register-system'] ===
'register-now-rhc' && (
<TextListItem>
Use remote host configuration (RHC) utility
<br />
</TextListItem>
)}
</TextList>
</TextListItem>
<TextListItem component={TextListItemVariants.dt}>
Activation key

View file

@ -8,6 +8,7 @@ import {
Text,
TextContent,
TextVariants,
Title,
} from '@patternfly/react-core';
import { ExternalLinkAltIcon, HelpIcon } from '@patternfly/react-icons';
@ -48,38 +49,27 @@ const PopoverActivation = () => {
export default {
StepTemplate,
id: 'wizard-registration',
title: 'Registration',
title: 'Register',
customTitle: (
<Title headingLevel="h1" size="xl">
Register systems using this image
</Title>
),
name: 'registration',
nextStep: 'File system configuration',
buttons: CustomButtons,
fields: [
{
component: componentTypes.RADIO,
label: 'Register images with Red Hat',
component: componentTypes.PLAIN_TEXT,
name: 'registration-general-description',
label:
'Automatically Register your systems with Red Hat to enhance security and track your spending.',
},
{
name: 'register-system',
initialValue: 'register-now-insights',
options: [
{
label: 'Register and connect image instances with Red Hat',
description: 'Includes Subscriptions and Red Hat Insights',
value: 'register-now-insights',
'data-testid': 'radio-register-now-insights',
autoFocus: true,
},
{
label: 'Register image instances only',
description: 'Includes Subscriptions only',
value: 'register-now',
className: 'pf-u-mt-sm',
'data-testid': 'radio-register-now',
},
{
label: 'Register later',
value: 'register-later',
className: 'pf-u-mt-sm',
'data-testid': 'radio-register-later',
},
],
component: 'registration',
label: 'Registration method',
initialValue: 'register-now-rhc',
},
{
component: 'activation-keys',
@ -93,6 +83,7 @@ export default {
),
condition: {
or: [
{ when: 'register-system', is: 'register-now-rhc' },
{ when: 'register-system', is: 'register-now-insights' },
{ when: 'register-system', is: 'register-now' },
],
@ -122,6 +113,7 @@ export default {
),
condition: {
or: [
{ when: 'register-system', is: 'register-now-rhc' },
{ when: 'register-system', is: 'register-now-insights' },
{ when: 'register-system', is: 'register-now' },
],
@ -149,6 +141,13 @@ export default {
name: 'subscription-activation-key-information',
label: 'Selected activation key',
valueReference: 'subscription-activation-key',
condition: {
or: [
{ when: 'register-system', is: 'register-now-rhc' },
{ when: 'register-system', is: 'register-now-insights' },
{ when: 'register-system', is: 'register-now' },
],
},
},
],
};

View file

@ -564,7 +564,7 @@ describe('Create Image Wizard', () => {
screen.getByRole('heading', { name: /Create image/ });
screen.getByRole('button', { name: 'Image output' });
screen.getByRole('button', { name: 'Registration' });
screen.getByRole('button', { name: 'Register' });
screen.getByRole('button', { name: 'File system configuration' });
screen.getByRole('button', { name: 'Content' });
screen.getByRole('button', { name: 'Additional Red Hat packages' });
@ -737,7 +737,7 @@ describe('Step Packages', () => {
name: 'Select activation key',
});
const registerLaterRadio = screen.getByLabelText('Register later');
const registerLaterRadio = screen.getByTestId('registration-radio-later');
userEvent.click(registerLaterRadio);
getNextButton().click();
@ -1216,11 +1216,6 @@ describe('Click through all steps', () => {
return Promise.resolve(mockActivationKey[name]);
});
const registrationRadio = screen.getByLabelText(
'Register and connect image instances with Red Hat'
);
userEvent.click(registrationRadio);
const activationKeyDropdown = await screen.findByRole('textbox', {
name: 'Select activation key',
});
@ -1306,7 +1301,10 @@ describe('Click through all steps', () => {
await screen.findByText('VMWare');
await screen.findByText('Virtualization - Guest image');
await screen.findByText('Bare metal - Installer');
await screen.findByText('Register with Subscriptions and Red Hat Insights');
const review = screen.getByTestId('review-registration');
expect(review).toHaveTextContent(
'Use remote host configuration (RHC) utility'
);
await screen.findByText('MyImageName');
screen.getByTestId('tab-registration').click();
@ -1361,6 +1359,7 @@ describe('Click through all steps', () => {
subscription: {
'activation-key': 'name0',
insights: true,
rhc: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',

View file

@ -159,7 +159,7 @@ describe('Create Image Wizard', () => {
screen.getByRole('heading', { name: /Create image/ });
screen.getByRole('button', { name: 'Image output' });
screen.getByRole('button', { name: 'Registration' });
screen.getByRole('button', { name: 'Register' });
screen.getByRole('button', { name: 'File system configuration' });
screen.getByRole('button', { name: 'Content' });
screen.getByRole('button', { name: 'Additional Red Hat packages' });
@ -327,7 +327,7 @@ describe('Step Upload to AWS', () => {
name: 'Select activation key',
});
screen.getByText('Register images with Red Hat');
screen.getByText('Automatically register and enable advanced capabilities');
});
test('clicking Back loads Release', () => {
@ -380,7 +380,7 @@ describe('Step Upload to Google', () => {
name: 'Select activation key',
});
screen.getByText('Register images with Red Hat');
screen.getByText('Automatically register and enable advanced capabilities');
});
test('clicking Back loads Release', () => {
@ -455,7 +455,7 @@ describe('Step Upload to Azure', () => {
name: 'Select activation key',
});
screen.getByText('Register images with Red Hat');
screen.getByText('Automatically register and enable advanced capabilities');
});
test('clicking Back loads Release', () => {
@ -514,7 +514,7 @@ describe('Step Registration', () => {
test('clicking Next loads file system configuration', async () => {
await setUp();
const registerLaterRadio = screen.getByLabelText('Register later');
const registerLaterRadio = screen.getByTestId('registration-radio-later');
userEvent.click(registerLaterRadio);
getNextButton().click();
@ -537,14 +537,9 @@ describe('Step Registration', () => {
verifyCancelButton(cancel, history);
});
test('should allow registering with insights', async () => {
test('should allow registering with rhc', async () => {
await setUp();
const registrationRadio = screen.getByLabelText(
'Register and connect image instances with Red Hat'
);
userEvent.click(registrationRadio);
const activationKeyDropdown = await screen.findByRole('textbox', {
name: 'Select activation key',
});
@ -559,19 +554,29 @@ describe('Step Registration', () => {
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
await waitFor(() => {
screen.getByText('Register with Subscriptions and Red Hat Insights');
screen.getAllByText('012345678901');
});
const review = screen.getByTestId('review-registration');
expect(review).toHaveTextContent(
'Register with Red Hat Subscription Manager (RHSM)'
);
expect(review).toHaveTextContent('Connect to Red Hat Insights');
expect(review).toHaveTextContent(
'Use remote host configuration (RHC) utility'
);
screen.getAllByText('012345678901');
});
test('should allow registering without insights', async () => {
test('should allow registering without rhc', async () => {
await setUp();
const registrationRadio = screen.getByLabelText(
'Register image instances only'
);
userEvent.click(registrationRadio);
userEvent.click(screen.getByTestId('registration-additional-options'));
userEvent.click(screen.getByTestId('registration-checkbox-rhc'));
// going back and forward when rhc isn't selected should keep additional options shown
screen.getByRole('button', { name: /Back/ }).click();
await screen.findByTestId('aws-account-id');
screen.getByRole('button', { name: /Next/ }).click();
screen.getByTestId('registration-checkbox-insights');
screen.getByTestId('registration-checkbox-rhc');
const activationKeyDropdown = await screen.findByRole('textbox', {
name: 'Select activation key',
@ -587,27 +592,64 @@ describe('Step Registration', () => {
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
await waitFor(() => {
screen.getByText('Register with Subscriptions');
screen.getAllByText('012345678901');
const review = screen.getByTestId('review-registration');
expect(review).toHaveTextContent(
'Register with Red Hat Subscription Manager (RHSM)'
);
expect(review).toHaveTextContent('Connect to Red Hat Insights');
screen.getAllByText('012345678901');
expect(review).not.toHaveTextContent(
'Use remote host configuration (RHC) utility'
);
});
test('should allow registering without insights or rhc', async () => {
await setUp();
userEvent.click(screen.getByTestId('registration-additional-options'));
userEvent.click(screen.getByTestId('registration-checkbox-insights'));
// going back and forward when neither rhc or insights is selected should keep additional options shown
screen.getByRole('button', { name: /Back/ }).click();
await screen.findByTestId('aws-account-id');
screen.getByRole('button', { name: /Next/ }).click();
screen.getByTestId('registration-checkbox-insights');
screen.getByTestId('registration-checkbox-rhc');
const activationKeyDropdown = await screen.findByRole('textbox', {
name: 'Select activation key',
});
userEvent.click(activationKeyDropdown);
const activationKey = await screen.findByRole('option', {
name: 'name0',
});
userEvent.click(activationKey);
screen.getByDisplayValue('name0');
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
screen.getByTestId('tab-registration').click();
const review = screen.getByTestId('review-registration');
expect(review).toHaveTextContent(
'Register with Red Hat Subscription Manager (RHSM)'
);
screen.getAllByText('012345678901');
expect(review).not.toHaveTextContent('Connect to Red Hat Insights');
expect(review).not.toHaveTextContent(
'Use remote host configuration (RHC) utility'
);
});
test('should hide input fields when clicking Register the system later', async () => {
await setUp();
// first check the other radio button which causes extra widgets to be shown
const registrationRadio = screen.getByLabelText(
'Register and connect image instances with Red Hat'
);
userEvent.click(registrationRadio);
const p1 = waitForElementToBeRemoved(() => [
screen.getByTestId('subscription-activation-key'),
]);
// then click the later radio button which should remove any input fields
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
// click the later radio button which should remove any input fields
screen.getByTestId('registration-radio-later').click();
await p1;
@ -617,6 +659,17 @@ describe('Step Registration', () => {
screen.getByRole('button', { name: /Next/ }).click();
screen.getByText('Register the system later');
});
test('registering with rhc implies registering with insights', async () => {
await setUp();
userEvent.click(screen.getByTestId('registration-additional-options'));
userEvent.click(screen.getByTestId('registration-checkbox-insights'));
expect(screen.getByTestId('registration-checkbox-rhc')).not.toBeChecked();
userEvent.click(screen.getByTestId('registration-checkbox-rhc'));
expect(screen.getByTestId('registration-checkbox-insights')).toBeChecked();
});
});
describe('Step File system configuration', () => {
@ -636,7 +689,7 @@ describe('Step File system configuration', () => {
name: 'Select activation key',
});
const registerLaterRadio = screen.getByLabelText('Register later');
const registerLaterRadio = screen.getByTestId('registration-radio-later');
userEvent.click(registerLaterRadio);
getNextButton().click();
};
@ -703,7 +756,7 @@ describe('Step Packages', () => {
name: 'Select activation key',
});
const registerLaterRadio = screen.getByLabelText('Register later');
const registerLaterRadio = screen.getByTestId('registration-radio-later');
userEvent.click(registerLaterRadio);
getNextButton().click();
@ -1061,7 +1114,7 @@ describe('Step Details', () => {
name: 'Select activation key',
});
const registerLaterRadio = screen.getByLabelText('Register later');
const registerLaterRadio = screen.getByTestId('registration-radio-later');
userEvent.click(registerLaterRadio);
getNextButton().click();
@ -1108,7 +1161,7 @@ describe('Step Review', () => {
});
// skip registration
const registerLaterRadio = screen.getByLabelText('Register later');
const registerLaterRadio = screen.getByTestId('registration-radio-later');
userEvent.click(registerLaterRadio);
getNextButton().click();
@ -1362,9 +1415,7 @@ describe('Click through all steps', () => {
return Promise.resolve(mockActivationKey[name]);
});
const registrationRadio = screen.getByLabelText(
'Register and connect image instances with Red Hat'
);
const registrationRadio = screen.getByTestId('registration-radio-now');
userEvent.click(registrationRadio);
const activationKeyDropdown = await screen.findByRole('textbox', {
@ -1447,14 +1498,16 @@ describe('Click through all steps', () => {
await screen.findByText('VMWare');
await screen.findByText('Virtualization - Guest image');
await screen.findByText('Bare metal - Installer');
await screen.findByText('Register with Subscriptions and Red Hat Insights');
await screen.findByText('MyImageName');
screen.getByTestId('tab-registration').click();
await screen.findByText('name0');
await screen.findByText('Self-Support');
await screen.findByText('Production');
const review = screen.getByTestId('review-registration');
expect(review).toHaveTextContent(
'Use remote host configuration (RHC) utility'
);
screen.getByTestId('repositories-popover-button').click();
const repotbody = await screen.findByTestId(
'additional-repositories-table'
@ -1508,6 +1561,7 @@ describe('Click through all steps', () => {
subscription: {
'activation-key': 'name0',
insights: true,
rhc: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
@ -1550,6 +1604,7 @@ describe('Click through all steps', () => {
subscription: {
'activation-key': 'name0',
insights: true,
rhc: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
@ -1594,6 +1649,7 @@ describe('Click through all steps', () => {
subscription: {
'activation-key': 'name0',
insights: true,
rhc: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
@ -1634,6 +1690,7 @@ describe('Click through all steps', () => {
subscription: {
'activation-key': 'name0',
insights: true,
rhc: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
@ -1674,6 +1731,7 @@ describe('Click through all steps', () => {
subscription: {
'activation-key': 'name0',
insights: true,
rhc: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
@ -1714,6 +1772,7 @@ describe('Click through all steps', () => {
subscription: {
'activation-key': 'name0',
insights: true,
rhc: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
@ -1813,15 +1872,13 @@ describe('Keyboard accessibility', () => {
clickNext();
// Registration
const registerRadio = screen.getByRole('radio', {
name: /register and connect image instances with red hat/i,
});
const registerRadio = screen.getByTestId('registration-radio-now');
expect(registerRadio).toHaveFocus();
await screen.findByRole('textbox', {
name: 'Select activation key',
});
// skip registration
const registerLaterRadio = screen.getByLabelText('Register later');
const registerLaterRadio = screen.getByTestId('registration-radio-later');
userEvent.click(registerLaterRadio);
clickNext();