import React from 'react'; import type { Router as RemixRouter } from '@remix-run/router'; import { screen, waitFor, waitForElementToBeRemoved, within, } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { http, HttpResponse } from 'msw'; import { enterBlueprintName, openAndDismissSaveAndBuildModal, } from './wizardTestUtils'; import CreateImageWizard from '../../../Components/CreateImageWizard/CreateImageWizard'; import ShareImageModal from '../../../Components/ShareImageModal/ShareImageModal'; import { PROVISIONING_API, RHSM_API } from '../../../constants'; import { server } from '../../mocks/server'; import { clickBack, clickNext, getNextButton, renderCustomRoutesWithReduxRouter, verifyCancelButton, } from '../../testUtils'; const routes = [ { path: 'insights/image-builder/*', element:
, }, { path: 'insights/image-builder/imagewizard/:composeId?', element: , }, { path: 'insights/image-builder/share /:composeId', element: , }, ]; let router: RemixRouter | undefined = undefined; vi.mock('@redhat-cloud-services/frontend-components/useChrome', () => ({ useChrome: () => ({ auth: { getUser: () => { return { identity: { internal: { org_id: 5, }, }, }; }, }, isBeta: () => true, isProd: () => true, getEnvironment: () => 'prod', }), })); vi.mock('@unleash/proxy-client-react', () => ({ useUnleashContext: () => vi.fn(), useFlag: vi.fn(() => false), })); const switchToAWSManual = async () => { const user = userEvent.setup(); const manualRadio = await screen.findByRole('radio', { name: /manually enter an account id\./i, }); await waitFor(() => user.click(manualRadio)); return manualRadio; }; const getSourceDropdown = async () => { const sourceDropdown = await screen.findByRole('textbox', { name: /select source/i, }); await waitFor(() => expect(sourceDropdown).toBeEnabled()); return sourceDropdown; }; const clickFromImageOutputToFsc = async () => { const user = userEvent.setup(); await clickNext(); const registerLater = await screen.findByText(/Register later/); await waitFor(async () => user.click(registerLater)); await clickNext(); await clickNext(); // skip OSCAP }; describe('Create Image Wizard', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); test('renders component', async () => { renderCustomRoutesWithReduxRouter('imagewizard', {}, routes); // check heading await screen.findByRole('heading', { name: /Images/ }); await screen.findByRole('button', { name: 'Image output' }); await screen.findByRole('button', { name: 'Register' }); await screen.findByRole('button', { name: 'File system configuration' }); await screen.findByRole('button', { name: 'Content' }); await screen.findByRole('button', { name: 'Custom repositories' }); await screen.findByRole('button', { name: 'Additional packages' }); await screen.findByRole('button', { name: 'Details' }); await screen.findByRole('button', { name: 'Review' }); }); }); describe('Step Image output', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); const user = userEvent.setup(); const setUp = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); // select aws as upload destination const uploadAws = await screen.findByTestId('upload-aws'); user.click(uploadAws); await screen.findByRole('heading', { name: 'Image output' }); }; test('clicking Next loads Upload to AWS', async () => { await setUp(); await clickNext(); await switchToAWSManual(); await screen.findByText('AWS account ID'); }); test('clicking Cancel loads landing page', async () => { await setUp(); await clickNext(); await verifyCancelButton(router); }); test('target environment is required', async () => { await setUp(); const destination = await screen.findByTestId('target-select'); const required = await within(destination).findByText('*'); expect(destination).toBeEnabled(); expect(destination).toContainElement(required); }); test('selecting and deselecting a tile disables the next button', async () => { await setUp(); const nextButton = await getNextButton(); const awsTile = await screen.findByTestId('upload-aws'); // this has already been clicked once in the setup function user.click(awsTile); // deselect const googleTile = await screen.findByTestId('upload-google'); user.click(googleTile); // select user.click(googleTile); // deselect const azureTile = await screen.findByTestId('upload-azure'); user.click(azureTile); // select user.click(azureTile); // deselect await waitFor(() => expect(nextButton).toBeDisabled()); }); test('expect only RHEL releases before expansion', async () => { await setUp(); const releaseMenu = screen.getAllByRole('button', { name: /options menu/i, })[0]; user.click(releaseMenu); await screen.findByRole('option', { name: /Red Hat Enterprise Linux \(RHEL\) 8/, }); await screen.findByRole('option', { name: /Red Hat Enterprise Linux \(RHEL\) 9/, }); await screen.findByRole('button', { name: 'Show options for further development of RHEL', }); user.click(releaseMenu); }); test('expect all releases after expansion', async () => { await setUp(); const releaseMenu = screen.getAllByRole('button', { name: /options menu/i, })[0]; user.click(releaseMenu); const showOptionsButton = await screen.findByRole('button', { name: 'Show options for further development of RHEL', }); user.click(showOptionsButton); await screen.findByRole('option', { name: /Red Hat Enterprise Linux \(RHEL\) 8/, }); await screen.findByRole('option', { name: /Red Hat Enterprise Linux \(RHEL\) 9/, }); await screen.findByRole('option', { name: 'CentOS Stream 9', }); expect(showOptionsButton).not.toBeInTheDocument(); user.click(releaseMenu); }); test('release lifecycle chart appears only when RHEL 8 is chosen', async () => { await setUp(); const releaseMenu = await screen.findAllByRole('button', { name: /options menu/i, }); user.click(releaseMenu[0]); const rhel8Option = await screen.findByRole('option', { name: /Red Hat Enterprise Linux \(RHEL\) 8/, }); user.click(rhel8Option); await screen.findByTestId('release-lifecycle-chart'); user.click(releaseMenu[0]); const rhel9Option = await screen.findByRole('option', { name: /Red Hat Enterprise Linux \(RHEL\) 9/, }); user.click(rhel9Option); await waitFor(() => expect( screen.queryByTestId('release-lifecycle-chart') ).not.toBeInTheDocument() ); }); test('CentOS acknowledgement appears', async () => { await setUp(); const releaseMenu = screen.getAllByRole('button', { name: /options menu/i, })[0]; user.click(releaseMenu); const showOptionsButton = await screen.findByRole('button', { name: 'Show options for further development of RHEL', }); user.click(showOptionsButton); const centOSButton = await screen.findByRole('option', { name: 'CentOS Stream 9', }); user.click(centOSButton); await screen.findByText( 'CentOS Stream builds are intended for the development of future versions of RHEL and are not supported for production workloads or other use cases.' ); }); }); describe('Step Upload to AWS', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); const user = userEvent.setup(); const setUp = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); // select aws as upload destination const uploadAws = await screen.findByTestId('upload-aws'); user.click(uploadAws); await clickNext(); await screen.findByRole('heading', { name: 'Target environment - Amazon Web Services', }); }; test('clicking Next loads Registration', async () => { await setUp(); await switchToAWSManual(); const awsAccountId = await screen.findByRole('textbox', { name: 'aws account id', }); await waitFor(async () => user.type(awsAccountId, '012345678901')); await clickNext(); await screen.findByRole('textbox', { name: 'Select activation key', }); await screen.findByText( 'Automatically register and enable advanced capabilities' ); }); test('clicking Back loads Release', async () => { await setUp(); await clickBack(); await screen.findByTestId('upload-aws'); }); test('clicking Cancel loads landing page', async () => { await setUp(); await verifyCancelButton(router); }); test('component renders error state correctly', async () => { server.use( http.get(`${PROVISIONING_API}/sources`, () => { return new HttpResponse(null, { status: 500 }); }) ); await setUp(); await screen.findByText( /sources cannot be reached, try again later or enter an aws account id manually\./i ); }); test('validation works', async () => { await setUp(); const nextButton = await getNextButton(); expect(nextButton).toHaveClass('pf-m-disabled'); const manualOption = await screen.findByRole('radio', { name: /manually enter an account id\./i, }); await waitFor(async () => user.click(manualOption)); expect(nextButton).toHaveClass('pf-m-disabled'); const awsAccId = await screen.findByRole('textbox', { name: 'aws account id', }); expect(awsAccId).toHaveValue(''); expect(awsAccId).toBeEnabled(); await waitFor(() => user.type(awsAccId, '012345678901')); expect(nextButton).not.toHaveClass('pf-m-disabled'); const sourceRadio = await screen.findByRole('radio', { name: /use an account configured from sources\./i, }); user.click(sourceRadio); await waitFor(() => expect(nextButton).toHaveClass('pf-m-disabled')); const sourceDropdown = await getSourceDropdown(); user.click(sourceDropdown); const source = await screen.findByRole('option', { name: /my_source/i, }); user.click(source); await waitFor(() => expect(nextButton).not.toHaveClass('pf-m-disabled')); }); test('compose request share_with_sources field is correct', async () => { await setUp(); const sourceDropdown = await getSourceDropdown(); user.click(sourceDropdown); const source = await screen.findByRole('option', { name: /my_source/i, }); user.click(source); await clickNext(); // registration await screen.findByRole('textbox', { name: 'Select activation key', }); const registerLaterRadio = await screen.findByLabelText('Register later'); user.click(registerLaterRadio); // click through to review step await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await enterBlueprintName(); await clickNext(); // informational modal pops up in the first test only as it's tied // to a 'imageBuilder.saveAndBuildModalSeen' variable in localStorage await openAndDismissSaveAndBuildModal(); const createBlueprintBtn = await screen.findByRole('button', { name: /Create blueprint/, }); user.click(createBlueprintBtn); // returns back to the landing page await waitFor(() => expect(router?.state.location.pathname).toBe('/insights/image-builder') ); // set test timeout of 10 seconds }, 10000); }); describe('Step Upload to Google', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); const user = userEvent.setup(); const setUp = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); // select gcp as upload destination const uploadGcp = await screen.findByTestId('upload-google'); user.click(uploadGcp); await clickNext(); await screen.findByRole('heading', { name: 'Target environment - Google Cloud Platform', }); }; test('clicking Next loads Registration', async () => { await setUp(); const shareRadioButton = await screen.findByText( /share image with a google account/i ); user.click(shareRadioButton); const googleEmailInput = await screen.findByTestId('principal'); await waitFor(() => user.type(googleEmailInput, 'test@test.com')); await clickNext(); await screen.findByRole('textbox', { name: 'Select activation key', }); await screen.findByText( 'Automatically register and enable advanced capabilities' ); }); test('clicking Back loads Release', async () => { await setUp(); await clickBack(); await screen.findByTestId('upload-google'); }); test('clicking Cancel loads landing page', async () => { await setUp(); await verifyCancelButton(router); }); test('the google account id field is shown and required', async () => { await setUp(); const principalInput = await screen.findByTestId('principal'); expect(principalInput).toHaveValue(''); expect(principalInput).toBeEnabled(); }); test('the google email field must be a valid email', async () => { await setUp(); await waitFor(async () => user.type(await screen.findByTestId('principal'), 'a') ); expect(await getNextButton()).toHaveClass('pf-m-disabled'); expect(await getNextButton()).toBeDisabled(); await waitFor(async () => user.type(await screen.findByTestId('principal'), 'test@test.com') ); expect(await getNextButton()).not.toHaveClass('pf-m-disabled'); expect(await getNextButton()).toBeEnabled(); }); }); describe('Step Registration', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); const user = userEvent.setup(); const setUp = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); // select aws as upload destination const uploadAws = await screen.findByTestId('upload-aws'); user.click(uploadAws); await clickNext(); const manualOption = await screen.findByRole('radio', { name: /manually enter an account id\./i, }); await waitFor(async () => user.click(manualOption)); await waitFor(async () => user.type( await screen.findByRole('textbox', { name: 'aws account id', }), '012345678901' ) ); await clickNext(); await screen.findByRole('textbox', { name: 'Select activation key', }); }; test('clicking Next loads file system configuration', async () => { await setUp(); const registerLaterRadio = await screen.findByTestId( 'registration-radio-later' ); user.click(registerLaterRadio); await clickNext(); await clickNext(); await screen.findByRole('heading', { name: 'File system configuration', }); }); test('clicking Back loads Upload to AWS', async () => { await setUp(); await clickBack(); const manualOption = await screen.findByRole('radio', { name: /manually enter an account id\./i, }); await waitFor(async () => user.click(manualOption)); await screen.findByText('AWS account ID'); }); test('clicking Cancel loads landing page', async () => { await setUp(); await verifyCancelButton(router); }); test('activation key dropdown empty state', async () => { server.use( http.get(`${RHSM_API}/activation_keys`, () => HttpResponse.json({ body: [] }) ) ); await setUp(); const activationKeyDropdown = await screen.findByRole('textbox', { name: 'Select activation key', }); user.click(activationKeyDropdown); await screen.findByText('No activation keys found'); }); test('should allow registering with rhc', async () => { await setUp(); const activationKeyDropdown = await screen.findByRole('textbox', { name: 'Select activation key', }); user.click(activationKeyDropdown); const activationKey = await screen.findByRole('option', { name: 'name0', }); user.click(activationKey); await screen.findByDisplayValue('name0'); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await enterBlueprintName(); await clickNext(); const review = await screen.findByTestId('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 rhc', async () => { await setUp(); const showOptions = await screen.findByTestId( 'registration-additional-options' ); user.click(showOptions); const rhcCheckbox = await screen.findByTestId('registration-checkbox-rhc'); await waitFor(async () => user.click(rhcCheckbox)); // going back and forward when rhc isn't selected should keep additional options shown await clickBack(); await screen.findByRole('textbox', { name: 'aws account id', }); await clickNext(); await screen.findByTestId('registration-checkbox-insights'); await screen.findByTestId('registration-checkbox-rhc'); const activationKeyDropdown = await screen.findByRole('textbox', { name: 'Select activation key', }); user.click(activationKeyDropdown); const activationKey = await screen.findByRole('option', { name: 'name0', }); user.click(activationKey); await screen.findByDisplayValue('name0'); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await enterBlueprintName(); await clickNext(); const review = await screen.findByTestId('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(); const showOptions = await screen.findByTestId( 'registration-additional-options' ); user.click(showOptions); const insightsCheckbox = await screen.findByTestId( 'registration-checkbox-insights' ); user.click(insightsCheckbox); // going back and forward when neither rhc or insights is selected should keep additional options shown await clickBack(); await screen.findByRole('textbox', { name: 'aws account id', }); await clickNext(); await screen.findByTestId('registration-checkbox-insights'); await screen.findByTestId('registration-checkbox-rhc'); const activationKeyDropdown = await screen.findByRole('textbox', { name: 'Select activation key', }); user.click(activationKeyDropdown); const activationKey = await screen.findByRole('option', { name: 'name0', }); user.click(activationKey); await screen.findByDisplayValue('name0'); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await enterBlueprintName(); await clickNext(); const review = await screen.findByTestId('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(); const removeKeyInformation = waitForElementToBeRemoved(() => [ screen.getByTestId('subscription-activation-key'), ]); // click the later radio button which should remove any input fields const manualOption = await screen.findByTestId('registration-radio-later'); await waitFor(async () => user.click(manualOption)); await removeKeyInformation; await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await clickNext(); await enterBlueprintName(); await clickNext(); await screen.findByText('Register the system later'); }); test('registering with rhc implies registering with insights', async () => { await setUp(); const showOptions = await screen.findByTestId( 'registration-additional-options' ); user.click(showOptions); const insightsCheckbox = await screen.findByTestId( 'registration-checkbox-insights' ); user.click(insightsCheckbox); await waitFor(async () => expect( await screen.findByTestId('registration-checkbox-rhc') ).not.toBeChecked() ); const rhcCheckbox = await screen.findByTestId('registration-checkbox-rhc'); user.click(rhcCheckbox); await waitFor(async () => expect( await screen.findByTestId('registration-checkbox-insights') ).toBeChecked() ); }); }); describe('Step File system configuration', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); const user = userEvent.setup(); const setUp = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); // select aws as upload destination const uploadAws = await screen.findByTestId('upload-aws'); user.click(uploadAws); await clickNext(); // aws step await switchToAWSManual(); await waitFor(() => user.type( screen.getByRole('textbox', { name: /aws account id/i, }), '012345678901' ) ); await clickNext(); // skip registration await screen.findByRole('textbox', { name: 'Select activation key', }); const registerLaterRadio = await screen.findByTestId( 'registration-radio-later' ); user.click(registerLaterRadio); await clickNext(); await clickNext(); }; test('Error validation occurs upon clicking next button', async () => { await setUp(); const manuallyConfigurePartitions = await screen.findByText( /manually configure partitions/i ); user.click(manuallyConfigurePartitions); const addPartition = await screen.findByTestId('file-system-add-partition'); // Create duplicate partitions user.click(addPartition); user.click(addPartition); // Clicking next causes errors to appear await clickNext(); expect(await getNextButton()).toBeDisabled(); const mountPointAlerts = screen.getAllByRole('heading', { name: /danger alert: duplicate mount point/i, }); const tbody = await screen.findByTestId('file-system-configuration-tbody'); const rows = within(tbody).getAllByRole('row'); expect(rows).toHaveLength(3); //Change mountpoint of final row to /var, resolving errors const mountPointOptions = within(rows[2]).getAllByRole('button', { name: 'Options menu', })[0]; user.click(mountPointOptions); const varButton = await within(rows[2]).findByRole('option', { name: '/var', }); user.click(varButton); await waitFor(() => expect(mountPointAlerts[0]).not.toBeInTheDocument()); await waitFor(() => expect(mountPointAlerts[1]).not.toBeInTheDocument()); expect(await getNextButton()).toBeEnabled(); }); test('Manual partitioning is hidden for ISO targets only', async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); const imageInstallerCheckbox = await screen.findByTestId( 'checkbox-image-installer' ); user.click(imageInstallerCheckbox); await clickFromImageOutputToFsc(); expect( screen.queryByText(/manually configure partitions/i) ).not.toBeInTheDocument(); }); test('Manual partitioning is shown for ISO target and other target', async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); const imageInstallerCheckbox = await screen.findByTestId( 'checkbox-image-installer' ); user.click(imageInstallerCheckbox); const guestImageCheckBox = await screen.findByTestId( 'checkbox-guest-image' ); user.click(guestImageCheckBox); await clickFromImageOutputToFsc(); const manualOption = await screen.findByText( /manually configure partitions/i ); user.click(manualOption); await screen.findByText('Configure partitions'); }); }); //describe('Step Details', () => { // beforeEach(() => { // vi.clearAllMocks(); // router = undefined; // }); // // const user = userEvent.setup(); // const setUp = async () => { // ({ router } = await renderCustomRoutesWithReduxRouter( // 'imagewizard', // {}, // routes // )); // // // select aws as upload destination // const uploadAws = await screen.findByTestId('upload-aws'); // user.click(uploadAws); // await clickNext(); // // // aws step // await switchToAWSManual(); // const awsAccountId = await screen.findByRole('textbox', { // name: 'aws account id', // }); // // await waitFor(() => user.type(awsAccountId, '012345678901')); // // await clickNext(); // // skip registration // await screen.findByRole('textbox', { // name: 'Select activation key', // }); // // const registerLaterRadio = screen.getByTestId('registration-radio-later'); // user.click(registerLaterRadio); // await clickNext(); // // skip oscap // await clickNext(); // // skip repositories // await clickNext(); // // skip packages // await clickNext(); // // skip fsc // await clickNext(); // // skip snapshot // await clickNext(); // //skip firstBoot // await clickNext(); // }; // // test('image name invalid for more than 100 chars and description for 250', async () => { // await setUp(); // // // Enter image name // const invalidName = 'a'.repeat(101); // await enterBlueprintName(invalidName); // expect(await getNextButton()).toHaveClass('pf-m-disabled'); // expect(await getNextButton()).toBeDisabled(); // const nameInput = await screen.findByRole('textbox', { // name: /blueprint name/i, // }); // await waitFor(() => user.clear(nameInput)); // // await enterBlueprintName(); // // expect(await getNextButton()).not.toHaveClass('pf-m-disabled'); // expect(await getNextButton()).toBeEnabled(); // // // Enter description image // const descriptionInput = await screen.findByRole('textbox', { // name: /description/i, // }); // // const invalidDescription = 'a'.repeat(251); // await waitFor(() => user.type(descriptionInput, invalidDescription)); // // expect(await getNextButton()).toHaveClass('pf-m-disabled'); // expect(await getNextButton()).toBeDisabled(); // await waitFor(() => user.clear(descriptionInput)); // await waitFor(() => user.type(descriptionInput, 'valid-description')); // // expect(await getNextButton()).not.toHaveClass('pf-m-disabled'); // expect(await getNextButton()).toBeEnabled(); // }, 20000); //}); describe('Step Review', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); const user = userEvent.setup(); const setUp = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); // select aws as upload destination await waitFor( async () => await user.click(await screen.findByTestId('upload-aws')) ); await clickNext(); // aws step await switchToAWSManual(); await waitFor(async () => user.type( await screen.findByRole('textbox', { name: 'aws account id', }), '012345678901' ) ); await clickNext(); await screen.findByRole('textbox', { name: 'Select activation key', }); // skip registration const registerLaterRadio = await screen.findByTestId( 'registration-radio-later' ); await waitFor(() => user.click(registerLaterRadio)); await clickNext(); // skip OpenScap await clickNext(); // skip snpashotstep await clickNext(); // skip repositories await clickNext(); // skip packages await clickNext(); await clickNext(); // skip firstboot await clickNext(); // skip Details await enterBlueprintName(); await clickNext(); }; const setUpCentOS = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); const releaseMenu = screen.getAllByRole('button', { name: /options menu/i, })[0]; await waitFor(() => user.click(releaseMenu)); const showOptionsButton = await screen.findByRole('button', { name: 'Show options for further development of RHEL', }); await waitFor(() => user.click(showOptionsButton)); const centos = await screen.findByRole('option', { name: 'CentOS Stream 9', }); await waitFor(() => user.click(centos)); // select aws as upload destination await waitFor( async () => await user.click(await screen.findByTestId('upload-aws')) ); await clickNext(); // aws step await switchToAWSManual(); await waitFor(async () => user.type( await screen.findByRole('textbox', { name: 'aws account id', }), '012345678901' ) ); await clickNext(); await screen.findByRole('textbox', { name: 'Select activation key', }); // skip registration const registerLaterRadio = await screen.findByTestId( 'registration-radio-later' ); await waitFor(() => user.click(registerLaterRadio)); await clickNext(); // skip Oscap await clickNext(); // skip snpashotstep await clickNext(); // skip packages await clickNext(); // skip repositories await clickNext(); await clickNext(); // skip First boot await clickNext(); await enterBlueprintName(); await clickNext(); }; test('has 3 buttons', async () => { await setUp(); await screen.findByRole('button', { name: /Create blueprint/ }); await screen.findByRole('button', { name: /Back/ }); await screen.findByRole('button', { name: /Cancel/ }); }); test('clicking Back loads Image name', async () => { await setUp(); await clickBack(); await screen.findByRole('heading', { name: 'Details', }); }); test('clicking Cancel loads landing page', async () => { await setUp(); await verifyCancelButton(router); }); test('has Registration expandable section for rhel', async () => { await setUp(); const targetExpandable = await screen.findByTestId( 'target-environments-expandable' ); const contentExpandable = await screen.findByTestId('content-expandable'); const fscExpandable = await screen.findByTestId( 'file-system-configuration-expandable' ); await within(targetExpandable).findByText('Amazon Web Services'); await within(contentExpandable).findByText('Custom repositories'); await within(contentExpandable).findByText('Additional packages'); await within(fscExpandable).findByText('Configuration type'); }); test('has no Registration expandable for centos', async () => { await setUpCentOS(); const targetExpandable = await screen.findByTestId( 'target-environments-expandable' ); const contentExpandable = await screen.findByTestId('content-expandable'); const fscExpandable = await screen.findByTestId( 'file-system-configuration-expandable' ); expect( screen.queryByTestId('registration-expandable') ).not.toBeInTheDocument(); await within(targetExpandable).findByText('Amazon Web Services'); await within(contentExpandable).findByText('Custom repositories'); await within(contentExpandable).findByText('Additional packages'); await within(fscExpandable).findByText('Configuration type'); }); }); describe('Keyboard accessibility', () => { beforeEach(() => { vi.clearAllMocks(); router = undefined; }); const user = userEvent.setup(); const setUp = async () => { ({ router } = await renderCustomRoutesWithReduxRouter( 'imagewizard', {}, routes )); await clickNext(); }; const selectAllEnvironments = async () => { await waitFor( async () => await user.click(await screen.findByTestId('upload-aws')) ); await waitFor(async () => user.click(await screen.findByTestId('upload-google')) ); await waitFor(async () => user.click(await screen.findByTestId('upload-azure')) ); await waitFor(async () => user.click( await screen.findByRole('checkbox', { name: /virtualization guest image checkbox/i, }) ) ); }; test('autofocus on each step first input element', async () => { await setUp(); // Image output await selectAllEnvironments(); await clickNext(); // Target environment aws expect( await screen.findByRole('radio', { name: /use an account configured from sources\./i, }) ).toHaveFocus(); const awsSourceDropdown = await getSourceDropdown(); await waitFor(() => user.click(awsSourceDropdown)); const awsSource = await screen.findByRole('option', { name: /my_source/i, }); await waitFor(() => user.click(awsSource)); await clickNext(); // Target environment google expect( await screen.findByRole('radio', { name: /share image with a google account/i, }) ).toHaveFocus(); await waitFor(async () => user.type( await screen.findByRole('textbox', { name: /google principal/i }), 'test@test.com' ) ); await clickNext(); // Target environment azure expect( await screen.findByRole('radio', { name: /use an account configured from sources\./i, }) ).toHaveFocus(); const azureSourceDropdown = await getSourceDropdown(); await waitFor(() => user.click(azureSourceDropdown)); const azureSource = await screen.findByRole('option', { name: /azureSource1/i, }); await waitFor(() => user.click(azureSource)); const resourceGroupDropdown = await screen.findByRole('textbox', { name: /select resource group/i, }); await waitFor(() => user.click(resourceGroupDropdown)); await waitFor(async () => user.click( await screen.findByLabelText('Resource group myResourceGroup1') ) ); await clickNext(); // Registration await screen.findByText( 'Automatically register and enable advanced capabilities' ); const registerRadio = await screen.findByTestId('registration-radio-now'); expect(registerRadio).toHaveFocus(); await screen.findByRole('textbox', { name: 'Select activation key', }); // skip registration const registerLaterRadio = await screen.findByTestId( 'registration-radio-later' ); await waitFor(() => user.click(registerLaterRadio)); await clickNext(); // TODO: Focus on textbox on OpenSCAP step await clickNext(); //File system configuration await clickNext(); // TODO: Focus on textbox on Custom Repos step await clickNext(); // TODO: Focus on textbox on Packages step await clickNext(); await clickNext(); // TODO: Focus on textbox on Details step await clickNext(); }, 20000); test('pressing Enter does not advance the wizard', async () => { await setUp(); await waitFor( async () => await user.click(await screen.findByTestId('upload-aws')) ); await waitFor(() => user.keyboard('{enter}')); await screen.findByRole('heading', { name: /image output/i, }); }); // test('target environment tiles are keyboard selectable', async () => { // const testTile = async (tile: HTMLElement) => { // tile.focus(); // await user.keyboard('{space}'); // expect(tile).toHaveClass('pf-m-selected'); // await user.keyboard('{space}'); // expect(tile).not.toHaveClass('pf-m-selected'); // }; // // await setUp(); // await clickNext(); // // await waitFor(() => screen.findByTestId('upload-aws')); // testTile(await screen.findByTestId('upload-aws')); // testTile(await screen.findByTestId('upload-google')); // testTile(await screen.findByTestId('upload-azure')); // }); });