components: Moves wizard steps into separate files

Replaces the flex layout in Review step with more semantic `<dl>`
elements.

Be more compliant with designs.
This commit is contained in:
Jenn Giardino 2020-11-28 19:00:21 -05:00 committed by Sanne Raymaekers
parent 31eef3b83e
commit 142674b43b
7 changed files with 311 additions and 282 deletions

View file

@ -0,0 +1,40 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Form, FormGroup, FormSelect, FormSelectOption, Title } from '@patternfly/react-core';
const WizardStepImageOutput = (props) => {
const releaseOptions = [
{ value: 'rhel-8', label: 'Red Hat Enterprise Linux (RHEL) 8.2' },
];
const uploadOptions = [
{ value: 'aws', label: 'Amazon Web Services' },
];
return (
<Form>
<Title headingLevel="h2" size="xl">Image output</Title>
<FormGroup isRequired label="Release" fieldId="release-select">
<FormSelect value={ props.value } onChange={ value => props.setRelease(value) } isRequired
aria-label="Select release input" id="release-select" data-testid="release-select">
{ releaseOptions.map(option => <FormSelectOption key={ option.value } value={ option.value } label={ option.label } />) }
</FormSelect>
</FormGroup>
<FormGroup isRequired label="Target environment" fieldId="upload-destination">
<FormSelect value={ props.upload.type || '' } id="upload-destination"
data-testid="upload-destination" isRequired
onChange={ value => props.setUpload({ type: value, options: props.upload.options }) } aria-label="Select upload destination">
{ uploadOptions.map(option => <FormSelectOption key={ option.value } value={ option.value } label={ option.label } />) }
</FormSelect>
</FormGroup>
</Form>
);
};
WizardStepImageOutput.propTypes = {
setRelease: PropTypes.func,
value: PropTypes.string,
upload: PropTypes.object,
setUpload: PropTypes.func,
};
export default WizardStepImageOutput;

View file

@ -0,0 +1,48 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Form, FormGroup, TextInput, Radio, Title } from '@patternfly/react-core';
const WizardStepRegistration = (props) => {
return (
<Form>
<Title headingLevel="h2" size="xl">Registration</Title>
<FormGroup isRequired label="Register the system">
<Radio name="subscribe-now-radio" isChecked={ props.subscribeNow } id="subscribe-now-radio"
label="Embed an activation key and register systems on first boot"
onChange={ () => props.setSubscribeNow(true) }
data-testid="register-now-radio-button" />
<Radio name="subscribe-later-radio" isChecked={ !props.subscribeNow }
label="Register the system later" id="subscribe-later-radio"
onChange={ () => props.setSubscribeNow(false) }
data-testid="register-later-radio-button" />
</FormGroup>
{ props.subscribeNow &&
<>
<FormGroup label="Organization ID" fieldId="subscription-organization">
<TextInput isDisabled value={ props.subscription.organization || '' } type="text"
id="subscription-organization" aria-label="Subscription organization ID"
data-testid="organization-id" />
</FormGroup>
<FormGroup isRequired label="Activation key" fieldId="subscription-activation"
helperTextInvalid={ (props.errors['subscription-activation'] && props.errors['subscription-activation'].value) || '' }
validated={ (props.errors['subscription-activation'] && 'error') || 'default' }>
<TextInput value={ props.subscription['activation-key'] || '' } type="password"
data-testid="subscription-activation" isRequired
id="subscription-activation" aria-label="Subscription activation key"
onChange={ value => props.setSubscription(Object.assign(props.subscription, { 'activation-key': value })) } />
</FormGroup>
</> }
</Form>
);
};
WizardStepRegistration.propTypes = {
setSubscription: PropTypes.func,
setSubscribeNow: PropTypes.func,
subscription: PropTypes.object,
subscribeNow: PropTypes.bool,
errors: PropTypes.object,
};
export default WizardStepRegistration;

View file

@ -0,0 +1,95 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Alert, TextContent, Title } from '@patternfly/react-core';
import { ExclamationCircleIcon } from '@patternfly/react-icons';
import './WizardStepReview.scss';
const WizardStepReview = (props) => {
const releaseOptions = {
'rhel-8': 'Red Hat Enterprise Linux (RHEL) 8.2'
};
const uploadOptions = {
aws: 'Amazon Web Services'
};
return (
<>
{ (Object.keys(props.uploadErrors).length > 0 ||
Object.keys(props.subscriptionErrors).length > 0) &&
<Alert variant="danger" className="pf-u-mb-xl" isInline title="Required information is missing" /> }
<Title headingLevel="h2" size="xl">Create image</Title>
<TextContent>
<small>
Review the information and click Create image
to create the image using the following criteria.
</small>
<h3>Image output</h3>
<dl>
<dt>
Release
</dt>
<dd>
{ releaseOptions[props.release]}
</dd>
<dt>
Target environment
</dt>
<dd>
{ props.upload && <>{ uploadOptions[props.upload.type] }</> }
</dd>
</dl>
{ Object.entries(props.uploadErrors).length > 0 && (
<h3>Upload to AWS</h3>
)}
<dl>
{ Object.entries(props.uploadErrors).map(([ key, error ]) => {
return (<React.Fragment key={ key }>
<dt>
{ error.label }
</dt>
<dd>
<ExclamationCircleIcon className="error" /> { error.value }
</dd>
</React.Fragment>);
})}
</dl>
<h3>Registration</h3>
<dl>
<dt>
Subscription
</dt>
{ !props.subscribeNow &&
<dd>
Register the system later
</dd> }
{ props.subscribeNow &&
<dd>
Register the system on first boot
</dd> }
{ Object.entries(props.subscriptionErrors).map(([ key, error ]) => {
return (<React.Fragment key={ key }>
<dt>
{ error.label }
</dt>
<dd>
<ExclamationCircleIcon className="error" /> { error.value }
</dd>
</React.Fragment>);
})}
</dl>
</TextContent>
</>
);
};
WizardStepReview.propTypes = {
release: PropTypes.string,
upload: PropTypes.object,
subscription: PropTypes.object,
subscribeNow: PropTypes.bool,
uploadErrors: PropTypes.object,
subscriptionErrors: PropTypes.object,
};
export default WizardStepReview;

View file

@ -0,0 +1,17 @@
.error {
color: var(--pf-global--danger-color--100);
}
// Increasing margins for h3 for better spacing and readability
.pf-c-content h3 {
margin-top: var(--pf-global--spacer--xl);
margin-bottom: var(--pf-global--spacer--md);
}
// Decreasing gap between dl items for better spacing and readability
// Also setting a first column width to 25% instead of auto,
// to guarantee the same width for each section.
@media screen and (min-width: 576px) {
.pf-c-content dl {
grid-template: 1fr / 25% 1fr;
grid-gap: var(--pf-global--spacer--sm);
}
}

View file

@ -0,0 +1,63 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Form, FormGroup, FormSelect, TextInput, FormSelectOption, Title } from '@patternfly/react-core';
const WizardStepUploadAWS = (props) => {
const serviceOptions = [
{ value: 'ec2', label: 'Amazon Elastic Compute Cloud (ec2)' },
{ value: 's3', label: 'Amazon Simple Storage Service (s3)' },
];
return (
<Form>
<Title headingLevel="h2" size="xl">Upload to AWS</Title>
<FormGroup isRequired label="Access key ID" fieldId="amazon-access-id"
helperTextInvalid={ (props.errors['amazon-access-id'] && props.errors['amazon-access-id'].value) || '' }
validated={ (props.errors['amazon-access-id'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.access_key_id || '' }
type="text" aria-label="amazon access key ID" id="amazon-access-id"
data-testid="aws-access-key" isRequired
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { access_key_id: value })) } />
</FormGroup>
<FormGroup isRequired label="Secret access key" fieldId="amazon-access-secret"
helperTextInvalid={ (props.errors['amazon-access-secret'] && props.errors['amazon-access-secret'].value) || '' }
validated={ (props.errors['amazon-access-secret'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.secret_access_key || '' }
data-testid="aws-secret-access-key" isRequired
type="password" aria-label="amazon secret access key" id="amazon-access-secret"
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { secret_access_key: value })) } />
</FormGroup>
<FormGroup isRequired label="Service" fieldId="amazon-service">
<FormSelect value={ props.upload.options.service } aria-label="Select amazon service" id="amazon-service"
data-testid="aws-service-select"
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { service: value })) }>
{ serviceOptions.map(option => <FormSelectOption key={ option.value } value={ option.value } label={ option.label } />) }
</FormSelect>
</FormGroup>
<FormGroup isRequired label="Region" fieldId="amazon-region"
helperTextInvalid={ (props.errors['amazon-region'] && props.errors['amazon-region'].value) || '' }
validated={ (props.errors['amazon-region'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.region } type="text" aria-label="amazon region" id="amazon-region"
data-testid="aws-region" isRequired
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { region: value })) } />
</FormGroup>
{ props.upload.options.service === 's3' &&
<FormGroup isRequired label="Bucket" fieldId="amazon-bucket"
helperTextInvalid={ (props.errors['amazon-bucket'] && props.errors['amazon-bucket'].value) || '' }
validated={ (props.errors['amazon-bucket'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.bucket || '' } type="text" aria-label="amazon bucket" id="amazon-bucket"
data-testid="aws-bucket" isRequired
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { bucket: value })) } />
</FormGroup> }
</Form>
);
};
WizardStepUploadAWS.propTypes = {
setUploadOptions: PropTypes.func,
upload: PropTypes.object,
errors: PropTypes.object,
};
export default WizardStepUploadAWS;

View file

@ -5,249 +5,15 @@ import { connect } from 'react-redux';
import { actions } from '../redux';
import { PageHeader, PageHeaderTitle } from '@redhat-cloud-services/frontend-components';
import {
Alert,
Flex,
FlexItem,
Form,
FormGroup,
FormSelect,
FormSelectOption,
Radio,
TextContent,
TextInput,
Wizard,
} from '@patternfly/react-core';
import { Wizard } from '@patternfly/react-core';
import { ExclamationCircleIcon } from '@patternfly/react-icons';
import WizardStepImageOutput from '../../PresentationalComponents/CreateImageWizard/WizardStepImageOutput';
import WizardStepUploadAWS from '../../PresentationalComponents/CreateImageWizard/WizardStepUploadAWS';
import WizardStepRegistration from '../../PresentationalComponents/CreateImageWizard/WizardStepRegistration';
import WizardStepReview from '../../PresentationalComponents/CreateImageWizard/WizardStepReview';
import api from './../../api.js';
const ReleaseComponent = (props) => {
const options = [
{ value: 'rhel-8', label: 'Red Hat Enterprise Linux (RHEL) 8.2' },
];
return (
<Form isHorizontal>
<FormGroup label="Release" fieldId="release-select">
<FormSelect value={ props.value } onChange={ value => props.setRelease(value) }
aria-label="Select release input" id="release-select" data-testid="release-select">
{ options.map(option => <FormSelectOption key={ option.value } value={ option.value } label={ option.label } />) }
</FormSelect>
</FormGroup>
</Form>
);
};
ReleaseComponent.propTypes = {
setRelease: PropTypes.func,
value: PropTypes.string,
};
const AmazonUploadComponent = (props) => {
const serviceOptions = [
{ value: 'ec2', label: 'Amazon Elastic Compute Cloud (ec2)' },
{ value: 's3', label: 'Amazon Simple Storage Service (s3)' },
];
return (
<>
<FormGroup isRequired label="Access key ID" fieldId="amazon-access-id"
helperTextInvalid={ (props.errors['amazon-access-id'] && props.errors['amazon-access-id'].value) || '' }
validated={ (props.errors['amazon-access-id'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.access_key_id || '' }
type="text" aria-label="amazon access key ID" id="amazon-access-id"
data-testid="aws-access-key" isRequired
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { access_key_id: value })) } />
</FormGroup>
<FormGroup isRequired label="Secret access key" fieldId="amazon-access-secret"
helperTextInvalid={ (props.errors['amazon-access-secret'] && props.errors['amazon-access-secret'].value) || '' }
validated={ (props.errors['amazon-access-secret'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.secret_access_key || '' }
data-testid="aws-secret-access-key" isRequired
type="password" aria-label="amazon secret access key" id="amazon-access-secret"
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { secret_access_key: value })) } />
</FormGroup>
<FormGroup isRequired label="Service" fieldId="amazon-service">
<FormSelect value={ props.upload.options.service } aria-label="Select amazon service" id="amazon-service"
data-testid="aws-service-select"
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { service: value })) }>
{ serviceOptions.map(option => <FormSelectOption key={ option.value } value={ option.value } label={ option.label } />) }
</FormSelect>
</FormGroup>
<FormGroup isRequired label="Region" fieldId="amazon-region"
helperTextInvalid={ (props.errors['amazon-region'] && props.errors['amazon-region'].value) || '' }
validated={ (props.errors['amazon-region'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.region } type="text" aria-label="amazon region" id="amazon-region"
data-testid="aws-region" isRequired
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { region: value })) } />
</FormGroup>
{ props.upload.options.service === 's3' &&
<FormGroup isRequired label="Bucket" fieldId="amazon-bucket"
helperTextInvalid={ (props.errors['amazon-bucket'] && props.errors['amazon-bucket'].value) || '' }
validated={ (props.errors['amazon-bucket'] && 'error') || 'default' }>
<TextInput value={ props.upload.options.bucket || '' } type="text" aria-label="amazon bucket" id="amazon-bucket"
data-testid="aws-bucket" isRequired
onChange={ value => props.setUploadOptions(Object.assign(props.upload.options, { bucket: value })) } />
</FormGroup> }
</>
);
};
AmazonUploadComponent.propTypes = {
setUploadOptions: PropTypes.func,
upload: PropTypes.object,
errors: PropTypes.object,
};
const UploadComponent = (props) => {
const uploadTypes = [
{ value: 'aws', label: 'Amazon Machine Image (.raw)' },
];
return (
<>
<Form isHorizontal>
<FormGroup isRequired label="Destination" fieldId="upload-destination">
<FormSelect value={ props.upload.type || '' } id="upload-destination"
data-testid="upload-destination" isRequired
onChange={ value => props.setUpload({ type: value, options: props.upload.options }) } aria-label="Select upload destination">
{ uploadTypes.map(type => <FormSelectOption key={ type.value } value={ type.value } label={ type.label } />) }
</FormSelect>
</FormGroup>
{ props.upload.type === 'aws' &&
<AmazonUploadComponent upload={ props.upload } setUploadOptions={ props.setUploadOptions } errors={ props.errors } /> }
</Form>
</>
);
};
UploadComponent.propTypes = {
setUpload: PropTypes.func,
setUploadOptions: PropTypes.func,
upload: PropTypes.object,
errors: PropTypes.object,
};
const SubscriptionComponent = (props) => {
return (
<Form>
<FormGroup isRequired label="Register the system" fieldId="subscribe-radio">
<Radio name="subscribe-radio" isChecked={ props.subscribeNow } id="subscribe-radio"
label="Embed an activation key and register systems on first boot"
onChange={ () => props.setSubscribeNow(true) }
data-testid="register-now-radio-button" />
<Radio name="subscribe-radio" isChecked={ !props.subscribeNow }
label="Register the system later" id="subscribe-radio"
onChange={ () => props.setSubscribeNow(false) }
data-testid="register-later-radio-button" />
</FormGroup>
{ props.subscribeNow &&
<>
<FormGroup label="Organization ID" fieldId="subscription-organization">
<TextInput isDisabled value={ props.subscription.organization || '' } type="text"
id="subscription-organization" aria-label="Subscription organization ID"
data-testid="organization-id" />
</FormGroup>
<FormGroup isRequired label="Activation key" fieldId="subscription-activation"
helperTextInvalid={ (props.errors['subscription-activation'] && props.errors['subscription-activation'].value) || '' }
validated={ (props.errors['subscription-activation'] && 'error') || 'default' }>
<TextInput value={ props.subscription['activation-key'] || '' } type="password"
data-testid="subscription-activation" isRequired
id="subscription-activation" aria-label="Subscription activation key"
onChange={ value => props.setSubscription(Object.assign(props.subscription, { 'activation-key': value })) } />
</FormGroup>
</> }
</Form>
);
};
SubscriptionComponent.propTypes = {
setSubscription: PropTypes.func,
setSubscribeNow: PropTypes.func,
subscription: PropTypes.object,
subscribeNow: PropTypes.bool,
errors: PropTypes.object,
};
const ReviewComponent = (props) => {
return (
<>
{ (Object.keys(props.uploadErrors).length > 0 ||
Object.keys(props.subscriptionErrors).length > 0) &&
<Alert variant="danger" isInline title="Required information is missing" /> }
<TextContent>
<h2>Create image</h2>
<small>
Review the information and click Create image
to create the image using the following criteria.
</small>
<h3>Release</h3>
<Flex>
<FlexItem flex={ { default: 'flex_1' } }>
Release
</FlexItem>
<FlexItem flex={ { default: 'flex_2' } }>
{ props.release }
</FlexItem>
</Flex>
<h3>Image output</h3>
<Flex>
<FlexItem flex={ { default: 'flex_1' } }>
Destination
</FlexItem>
<FlexItem flex={ { default: 'flex_2' } }>
{ props.upload && <>{ props.upload.type }</> }
</FlexItem>
</Flex>
{ Object.entries(props.uploadErrors).map(([ key, error ]) => {
return (<Flex key={ key }>
<FlexItem flex={ { default: 'flex_1' } }>
{ error.label }
</FlexItem>
<FlexItem flex={ { default: 'flex_2' } }>
<ExclamationCircleIcon className="error" /> { error.value }
</FlexItem>
</Flex>);
})}
<h3>Registration</h3>
<Flex>
<FlexItem flex={ { default: 'flex_1' } }>
Subscription
</FlexItem>
{ !props.subscribeNow &&
<FlexItem flex={ { default: 'flex_2' } }>
Register the system later
</FlexItem> }
{ props.subscribeNow &&
<FlexItem flex={ { default: 'flex_2' } }>
Register the system on first boot
</FlexItem> }
</Flex>
{ Object.entries(props.subscriptionErrors).map(([ key, error ]) => {
return (<Flex key={ key }>
<FlexItem flex={ { default: 'flex_1' } }>
{ error.label }
</FlexItem>
<FlexItem flex={ { default: 'flex_2' } }>
<ExclamationCircleIcon className="error" /> { error.value }
</FlexItem>
</Flex>);
})}
</TextContent>
</>
);
};
ReviewComponent.propTypes = {
release: PropTypes.string,
upload: PropTypes.object,
subscription: PropTypes.object,
subscribeNow: PropTypes.bool,
uploadErrors: PropTypes.object,
subscriptionErrors: PropTypes.object,
};
class CreateImageWizard extends Component {
constructor(props) {
super(props);
@ -283,7 +49,7 @@ class CreateImageWizard extends Component {
'base-url': 'https://cdn.redhat.com/',
insights: true
},
subscribeNow: false,
subscribeNow: true,
/* errors take form of $fieldId: error */
uploadErrors: {},
subscriptionErrors: {},
@ -431,22 +197,28 @@ class CreateImageWizard extends Component {
}
render() {
const StepImageOutput = {
name: 'Image output',
component: <WizardStepImageOutput
value={ this.state.release }
upload={ this.state.upload }
setRelease={ this.setRelease }
setUpload={ this.setUpload } />
};
const StepUploadAWS = {
name: 'Upload to AWS',
component: <WizardStepUploadAWS
upload={ this.state.upload }
setUploadOptions={ this.setUploadOptions }
errors={ this.state.uploadErrors } />
};
const steps = [
{
name: 'Release',
component: <ReleaseComponent
value={ this.state.release }
setRelease={ this.setRelease } /> },
{
name: 'Target environment',
component: <UploadComponent
upload={ this.state.upload }
setUpload={ this.setUpload }
setUploadOptions={ this.setUploadOptions }
errors={ this.state.uploadErrors } /> },
StepImageOutput,
...(this.state.upload.type === 'aws' ? [ StepUploadAWS ] : []),
{
name: 'Registration',
component: <SubscriptionComponent
component: <WizardStepRegistration
subscription={ this.state.subscription }
subscribeNow={ this.state.subscribeNow }
setSubscription={ this.setSubscription }
@ -454,7 +226,7 @@ class CreateImageWizard extends Component {
errors={ this.state.subscriptionErrors } /> },
{
name: 'Review',
component: <ReviewComponent
component: <WizardStepReview
release={ this.state.release }
upload={ this.state.upload }
subscription={ this.state.subscription }

View file

@ -68,31 +68,30 @@ describe('Create Image Wizard', () => {
// left sidebar navigation
const sidebar = screen.getByRole('navigation');
getByText(sidebar, 'Release');
getByText(sidebar, 'Target environment');
getByText(sidebar, 'Image output');
getByText(sidebar, 'Registration');
getByText(sidebar, 'Review');
});
});
describe('Step Release', () => {
describe('Step Image output', () => {
beforeEach(() => {
const { _component, history } = renderWithReduxRouter(<CreateImageWizard />);
historySpy = jest.spyOn(history, 'push');
// left sidebar navigation
const sidebar = screen.getByRole('navigation');
const anchor = getByText(sidebar, 'Release');
const anchor = getByText(sidebar, 'Image output');
screen.getByTestId('upload-destination');
// load from sidebar
anchor.click();
});
test('clicking Next loads Target environment', () => {
test('clicking Next loads Upload to AWS', () => {
const [ next, , ] = verifyButtons();
next.click();
screen.getByText('Destination');
screen.getByText('Secret access key');
});
@ -115,16 +114,22 @@ describe('Step Release', () => {
userEvent.selectOptions(release, [ 'rhel-8' ]);
});
test('target environment is required', () => {
const destination = screen.getByTestId('upload-destination');
expect(destination).toBeEnabled();
expect(destination).toBeRequired();
});
});
describe('Step Target environment', () => {
describe('Step Upload to AWS', () => {
beforeEach(() => {
const { _component, history } = renderWithReduxRouter(<CreateImageWizard />);
historySpy = jest.spyOn(history, 'push');
// left sidebar navigation
const sidebar = screen.getByRole('navigation');
const anchor = getByText(sidebar, 'Target environment');
const anchor = getByText(sidebar, 'Upload to AWS');
// load from sidebar
anchor.click();
@ -153,10 +158,6 @@ describe('Step Target environment', () => {
// change the select to enable the bucket field
userEvent.selectOptions(screen.getByTestId('aws-service-select'), [ 's3' ]);
const destination = screen.getByTestId('upload-destination');
expect(destination).toBeEnabled();
expect(destination).toBeRequired();
const accessKeyId = screen.getByTestId('aws-access-key');
expect(accessKeyId).toHaveValue('');
expect(accessKeyId).toBeEnabled();
@ -182,10 +183,6 @@ describe('Step Target environment', () => {
// change the select to enable the bucket field
userEvent.selectOptions(screen.getByTestId('aws-service-select'), [ 's3' ]);
const destination = screen.getByTestId('upload-destination');
expect(destination).toBeEnabled();
expect(destination).toBeRequired();
const accessKeyId = screen.getByTestId('aws-access-key');
expect(accessKeyId).toHaveValue('');
expect(accessKeyId).toBeEnabled();
@ -229,11 +226,11 @@ describe('Step Registration', () => {
screen.getByText('Review the information and click Create image to create the image using the following criteria.');
});
test('clicking Back loads Target environment', () => {
test('clicking Back loads Upload to AWS', () => {
const [ , back, ] = verifyButtons();
back.click();
screen.getByText('Destination');
screen.getByText('Access key ID');
screen.getByText('Secret access key');
});
@ -320,13 +317,13 @@ describe('Click through all steps', () => {
test('with valid values', async () => {
const next = screen.getByRole('button', { name: /Next/ });
// select release
// select image output
userEvent.selectOptions(screen.getByTestId('release-select'), [ 'rhel-8' ]);
userEvent.selectOptions(screen.getByTestId('upload-destination'), [ 'aws' ]);
next.click();
// select upload target
await screen.findByTestId('upload-destination');
userEvent.selectOptions(screen.getByTestId('upload-destination'), [ 'aws' ]);
await screen.findByTestId('aws-access-key');
userEvent.type(screen.getByTestId('aws-access-key'), 'key');
userEvent.type(screen.getByTestId('aws-secret-access-key'), 'secret');
userEvent.selectOptions(screen.getByTestId('aws-service-select'), [ 's3' ]);
@ -342,10 +339,10 @@ describe('Click through all steps', () => {
userEvent.type(screen.getByTestId('subscription-activation'), '1234567890');
next.click();
// review
await screen.
findByText('Review the information and click Create image to create the image using the following criteria.');
await screen.findByText('rhel-8');
await screen.findByText('aws');
await screen.findByText('Amazon Web Services');
await screen.findByText('Register the system on first boot');
// mock the backend API
@ -369,11 +366,9 @@ describe('Click through all steps', () => {
// select release
userEvent.selectOptions(screen.getByTestId('release-select'), [ 'rhel-8' ]);
userEvent.selectOptions(screen.getByTestId('upload-destination'), [ 'aws' ]);
next.click();
// select upload target
await screen.findByTestId('upload-destination');
userEvent.selectOptions(screen.getByTestId('upload-destination'), [ 'aws' ]);
// leave AWS access keys empty
userEvent.selectOptions(screen.getByTestId('aws-service-select'), [ 's3' ]);
userEvent.clear(screen.getByTestId('aws-region'));
@ -389,8 +384,7 @@ describe('Click through all steps', () => {
await screen.
findByText('Review the information and click Create image to create the image using the following criteria.');
await screen.findByText('rhel-8');
await screen.findByText('aws');
await screen.findByText('Amazon Web Services');
await screen.findByText('Register the system on first boot');
const errorMessages = await screen.findAllByText('A value is required');