debian-image-builder-frontend/src/test/Components/CreateImageWizard/CreateImageWizard.test.js
Sanne Raymaekers cb8ab9347e CreateImageWizard: use non-deprecated image type aliases
'ami' was deprecated a while ago, and is kept around as an alias of
'aws'. Same with 'vhd' and 'azure', and 'vhd' and 'gcp'.

This maintains support for the old aliases where necessary.
2022-12-06 15:14:53 +01:00

2027 lines
60 KiB
JavaScript

import '@testing-library/jest-dom';
import React from 'react';
import {
act,
screen,
waitFor,
waitForElementToBeRemoved,
within,
} from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import api from '../../../api.js';
import CreateImageWizard from '../../../Components/CreateImageWizard/CreateImageWizard';
import { RHEL_8 } from '../../../constants.js';
import { renderWithReduxRouter } from '../../testUtils';
let history = undefined;
let store = undefined;
function getBackButton() {
const back = screen.getByRole('button', { name: /Back/ });
return back;
}
function getNextButton() {
const next = screen.getByRole('button', { name: /Next/ });
return next;
}
function getCancelButton() {
const cancel = screen.getByRole('button', { name: /Cancel/ });
return cancel;
}
function verifyCancelButton(cancel, history) {
cancel.click();
expect(history.location.pathname).toBe('/insights/image-builder/');
}
// packages
const mockPkgResult = {
meta: { count: 3 },
links: { first: '', last: '' },
data: [
{
name: 'testPkg',
summary: 'test package summary',
version: '1.0',
},
{
name: 'lib-test',
summary: 'lib-test package summary',
version: '1.0',
},
{
name: 'test',
summary: 'summary for test package',
version: '1.0',
},
],
};
const mockPkgResultAlpha = {
meta: { count: 3 },
links: { first: '', last: '' },
data: [
{
name: 'lib-test',
summary: 'lib-test package summary',
version: '1.0',
},
{
name: 'Z-test',
summary: 'Z-test package summary',
version: '1.0',
},
{
name: 'test',
summary: 'summary for test package',
version: '1.0',
},
],
};
const mockPkgResultPartial = {
meta: { count: 132 },
links: { first: '', last: '' },
data: new Array(100).fill().map((_, i) => {
return {
name: 'testPkg-' + i,
summary: 'test package summary',
version: '1.0',
};
}),
};
const mockPkgResultAll = {
meta: { count: 132 },
links: { first: '', last: '' },
data: new Array(132).fill().map((_, i) => {
return {
name: 'testPkg-' + i,
summary: 'test package summary',
version: '1.0',
};
}),
};
const mockPkgResultEmpty = {
meta: { count: 0 },
links: { first: '', last: '' },
data: null,
};
const searchForAvailablePackages = async (searchbox, searchTerm) => {
userEvent.type(searchbox, searchTerm);
await act(async () => {
screen
.getByRole('button', { name: /search button for available packages/i })
.click();
});
};
const searchForChosenPackages = async (searchbox, searchTerm) => {
if (!searchTerm) {
userEvent.clear(searchbox);
} else {
userEvent.type(searchbox, searchTerm);
}
};
// mock the insights dependency
beforeAll(() => {
// scrollTo is not defined in jsdom
window.HTMLElement.prototype.scrollTo = function () {};
// mock the activation key api call
const mockActivationKeys = [{ name: 'name0' }, { name: 'name1' }];
jest
.spyOn(api, 'getActivationKeys')
.mockImplementation(() => Promise.resolve(mockActivationKeys));
const mockActivationKey = { body: [{ name: 'name0' }, { name: 'name1' }] };
jest.spyOn(api, 'getActivationKey').mockImplementation((name) => {
return Promise.resolve(mockActivationKey[name]);
});
global.insights = {
chrome: {
auth: {
getUser: () => {
return {
identity: {
internal: {
org_id: 5,
},
},
};
},
},
isBeta: () => {
return true;
},
isProd: () => {
return true;
},
},
};
});
afterEach(() => {
jest.clearAllMocks();
history = undefined;
});
// restore global mock
afterAll(() => {
global.insights = undefined;
});
describe('Create Image Wizard', () => {
test('renders component', () => {
renderWithReduxRouter(<CreateImageWizard />);
// check heading
screen.getByRole('heading', { name: /Create image/ });
screen.getByRole('button', { name: 'Image output' });
screen.getByRole('button', { name: 'Additional packages' });
screen.getByRole('button', { name: 'Name image' });
screen.getByRole('button', { name: 'Review' });
});
});
describe('Step Image output', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const imageOutputLink = screen.getByRole('button', {
name: 'Image output',
});
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
// load from sidebar
imageOutputLink.click();
};
test('clicking Next loads Upload to AWS', () => {
setUp();
getNextButton().click();
screen.getByText('AWS account ID');
});
test('clicking Cancel loads landing page', () => {
setUp();
const cancel = getCancelButton();
verifyCancelButton(cancel, history);
});
test('target environment is required', () => {
setUp();
const destination = screen.getByTestId('target-select');
const required = within(destination).getByText('*');
expect(destination).toBeEnabled();
expect(destination).toContainElement(required);
});
test('selecting and deselecting a tile disables the next button', () => {
setUp();
const awsTile = screen.getByTestId('upload-aws');
// this has already been clicked once in the setup function
awsTile.click(); // deselect
const googleTile = screen.getByTestId('upload-google');
googleTile.click(); // select
googleTile.click(); // deselect
const azureTile = screen.getByTestId('upload-azure');
azureTile.click(); // select
azureTile.click(); // deselect
expect(getNextButton()).toBeDisabled();
});
test('expect only RHEL releases before expansion', async () => {
setUp();
const releaseMenu = screen.getByRole('button', {
name: /options menu/i,
});
userEvent.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',
});
userEvent.click(releaseMenu);
});
test('expect all releases after expansion', async () => {
setUp();
const releaseMenu = screen.getByRole('button', {
name: /options menu/i,
});
userEvent.click(releaseMenu);
const showOptionsButton = screen.getByRole('button', {
name: 'Show options for further development of RHEL',
});
userEvent.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 8',
});
await screen.findByRole('option', {
name: 'CentOS Stream 9',
});
expect(showOptionsButton).not.toBeInTheDocument();
userEvent.click(releaseMenu);
});
test('clear button resets to initial state (unexpanded)', async () => {
setUp();
const releaseMenu = screen.getByRole('button', {
name: /options menu/i,
});
userEvent.click(releaseMenu);
const showOptionsButton = screen.getByRole('button', {
name: 'Show options for further development of RHEL',
});
userEvent.click(showOptionsButton);
const clearAllButton = screen.getByRole('button', {
name: /clear all/i,
});
userEvent.click(clearAllButton);
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',
});
userEvent.click(releaseMenu);
});
test('CentOS acknowledgement appears', async () => {
setUp();
const releaseMenu = screen.getByRole('button', {
name: /options menu/i,
});
userEvent.click(releaseMenu);
const showOptionsButton = screen.getByRole('button', {
name: 'Show options for further development of RHEL',
});
userEvent.click(showOptionsButton);
const centOSButton = screen.getByRole('option', {
name: 'CentOS Stream 9',
});
userEvent.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', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
getNextButton().click();
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
'Target environment - Amazon Web Services'
);
};
test('clicking Next loads Registration', async () => {
setUp();
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
getNextButton().click();
await screen.findByRole('textbox', {
name: 'Select activation key',
});
screen.getByText('Register images with Red Hat');
});
test('clicking Back loads Release', () => {
setUp();
getBackButton().click();
screen.getByTestId('upload-aws');
});
test('clicking Cancel loads landing page', () => {
setUp();
const cancel = getCancelButton();
verifyCancelButton(cancel, history);
});
test('the aws account id fieldis shown and required', () => {
setUp();
const accessKeyId = screen.getByTestId('aws-account-id');
expect(accessKeyId).toHaveValue('');
expect(accessKeyId).toBeEnabled();
// expect(accessKeyId).toBeRequired(); // DDf does not support required value
});
});
describe('Step Upload to Google', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-google');
awsTile.click();
getNextButton().click();
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
'Target environment - Google Cloud Platform'
);
};
test('clicking Next loads Registration', async () => {
setUp();
userEvent.type(screen.getByTestId('input-google-email'), 'test@test.com');
getNextButton().click();
await screen.findByRole('textbox', {
name: 'Select activation key',
});
screen.getByText('Register images with Red Hat');
});
test('clicking Back loads Release', () => {
setUp();
getBackButton().click();
screen.getByTestId('upload-google');
});
test('clicking Cancel loads landing page', () => {
setUp();
const cancel = getCancelButton();
verifyCancelButton(cancel, history);
});
test('the google account id field is shown and required', () => {
setUp();
const accessKeyId = screen.getByTestId('input-google-email');
expect(accessKeyId).toHaveValue('');
expect(accessKeyId).toBeEnabled();
// expect(accessKeyId).toBeRequired(); // DDf does not support required value
});
test('the google email field must be a valid email', () => {
setUp();
userEvent.type(screen.getByTestId('input-google-email'), 'a');
expect(getNextButton()).toHaveClass('pf-m-disabled');
expect(getNextButton()).toBeDisabled();
userEvent.type(screen.getByTestId('input-google-email'), 'test@test.com');
expect(getNextButton()).not.toHaveClass('pf-m-disabled');
expect(getNextButton()).toBeEnabled();
});
});
describe('Step Upload to Azure', () => {
const setUp = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-azure');
awsTile.click();
getNextButton().click();
expect(screen.getByRole('heading', { level: 1 })).toHaveTextContent(
'Target environment - Microsoft Azure'
);
};
test('clicking Next loads Registration', async () => {
setUp();
// Randomly generated GUID
userEvent.type(
screen.getByTestId('azure-tenant-id'),
'b8f86d22-4371-46ce-95e7-65c415f3b1e2'
);
userEvent.type(
screen.getByTestId('azure-subscription-id'),
'60631143-a7dc-4d15-988b-ba83f3c99711'
);
userEvent.type(
screen.getByTestId('azure-resource-group'),
'testResourceGroup'
);
getNextButton().click();
await screen.findByRole('textbox', {
name: 'Select activation key',
});
screen.getByText('Register images with Red Hat');
});
test('clicking Back loads Release', () => {
setUp();
getBackButton().click();
screen.getByTestId('upload-azure');
});
test('clicking Cancel loads landing page', () => {
setUp();
const cancel = getCancelButton();
verifyCancelButton(cancel, history);
});
test('the azure upload fields are shown and required', () => {
setUp();
const tenantId = screen.getByTestId('azure-tenant-id');
expect(tenantId).toHaveValue('');
expect(tenantId).toBeEnabled();
// expect(tenantId).toBeRequired(); // DDf does not support required value
const subscription = screen.getByTestId('azure-subscription-id');
expect(subscription).toHaveValue('');
expect(subscription).toBeEnabled();
// expect(subscription).toBeRequired(); // DDf does not support required value
const resourceGroup = screen.getByTestId('azure-resource-group');
expect(resourceGroup).toHaveValue('');
expect(resourceGroup).toBeEnabled();
// expect(resourceGroup).toBeRequired(); // DDf does not support required value
});
});
describe('Step Registration', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
getNextButton().click();
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
getNextButton().click();
await screen.findByRole('textbox', {
name: 'Select activation key',
});
};
test('clicking Next loads file system configuration', async () => {
await setUp();
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
getNextButton().click();
screen.getByTestId('fsc-paritioning-toggle');
});
test('clicking Back loads Upload to AWS', async () => {
await setUp();
getBackButton().click();
screen.getByText('AWS account ID');
});
test('clicking Cancel loads landing page', async () => {
await setUp();
const cancel = getCancelButton();
verifyCancelButton(cancel, history);
});
test('should allow registering with insights', 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',
});
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();
await waitFor(() => {
screen.getByText('Register with Subscriptions and Red Hat Insights');
screen.getAllByText('012345678901');
});
});
test('should allow registering without insights', async () => {
await setUp();
const registrationRadio = screen.getByLabelText(
'Register image instances only'
);
userEvent.click(registrationRadio);
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();
await waitFor(() => {
screen.getByText('Register with Subscriptions');
screen.getAllByText('012345678901');
});
});
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);
await p1;
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.getByText('Register the system later');
});
});
describe('Step File system configuration', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
getNextButton().click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
getNextButton().click();
// skip registration
await screen.findByRole('textbox', {
name: 'Select activation key',
});
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
getNextButton().click();
};
test('Error validation occurs upon clicking next button', async () => {
await setUp();
const nextButton = getNextButton();
const manuallyConfigurePartitions = screen.getByText(
/manually configure partitions/i
);
manuallyConfigurePartitions.click();
const addPartition = await screen.findByTestId('file-system-add-partition');
// Create duplicate partitions
addPartition.click();
addPartition.click();
expect(nextButton).toBeEnabled();
// Clicking next causes errors to appear
nextButton.click();
const mountPointWarning = screen.getByRole('heading', {
name: /danger alert: duplicate mount points: all mount points must be unique\. remove the duplicate or choose a new mount point\./i,
hidden: true,
});
const mountPointAlerts = screen.getAllByRole('heading', {
name: /danger alert: duplicate mount point\./i,
});
const tbody = screen.getByTestId('file-system-configuration-tbody');
const rows = within(tbody).getAllByRole('row');
expect(rows).toHaveLength(3);
// Change mountpoint of final row to /var, resolving errors
within(rows[2]).getAllByRole('button', { name: 'Options menu' })[0].click();
within(rows[2]).getByRole('option', { name: '/var' }).click();
await waitFor(() => expect(mountPointWarning).not.toBeInTheDocument());
await waitFor(() => expect(mountPointAlerts[0]).not.toBeInTheDocument());
await waitFor(() => expect(mountPointAlerts[1]).not.toBeInTheDocument());
await waitFor(() => expect(nextButton).toBeEnabled());
});
});
describe('Step Packages', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
getNextButton().click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
getNextButton().click();
// skip registration
await screen.findByRole('textbox', {
name: 'Select activation key',
});
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
getNextButton().click();
// skip fsc
getNextButton().click();
};
test('clicking Next loads Image name', async () => {
await setUp();
getNextButton().click();
screen.getByRole('heading', {
name: 'Name image',
});
});
test('clicking Back loads file system configuration', async () => {
await setUp();
const back = screen.getByRole('button', { name: /Back/ });
back.click();
screen.getByTestId('fsc-paritioning-toggle');
});
test('clicking Cancel loads landing page', async () => {
await setUp();
const cancel = getCancelButton();
verifyCancelButton(cancel, history);
});
test('should display search bar and button', async () => {
await setUp();
userEvent.type(screen.getByTestId('search-available-pkgs-input'), 'test');
screen.getByRole('button', {
name: 'Search button for available packages',
});
});
test('should display default state', async () => {
await setUp();
screen.getByText('Search above to add additionalpackages to your image');
screen.getByText('No packages added');
});
test('search results should be sorted with most relevant results first', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(searchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(3);
const [firstItem, secondItem, thirdItem] = availablePackagesItems;
expect(firstItem).toHaveTextContent('testsummary for test package');
expect(secondItem).toHaveTextContent('testPkgtest package summary');
expect(thirdItem).toHaveTextContent('lib-testlib-test package summary');
});
test('search results should be sorted after selecting them and then deselecting them', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(searchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
screen
.getByRole('option', { name: /testPkg test package summary/ })
.click();
screen.getByRole('button', { name: /Add selected/ }).click();
screen
.getByRole('option', { name: /testPkg test package summary/ })
.click();
screen.getByRole('button', { name: /Remove selected/ }).click();
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(3);
const [firstItem, secondItem, thirdItem] = availablePackagesItems;
expect(firstItem).toHaveTextContent('testsummary for test package');
expect(secondItem).toHaveTextContent('testPkgtest package summary');
expect(thirdItem).toHaveTextContent('lib-testlib-test package summary');
});
test('search results should be sorted after adding and then removing all packages', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(searchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
screen.getByRole('button', { name: /Add all/ }).click();
screen.getByRole('button', { name: /Remove all/ }).click();
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(3);
const [firstItem, secondItem, thirdItem] = availablePackagesItems;
expect(firstItem).toHaveTextContent('testsummary for test package');
expect(secondItem).toHaveTextContent('testPkgtest package summary');
expect(thirdItem).toHaveTextContent('lib-testlib-test package summary');
});
test('removing a single package updates the state correctly', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(searchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
screen.getByRole('button', { name: /Add all/ }).click();
// remove a single package
screen
.getByRole('option', { name: /lib-test lib-test package summary/ })
.click();
screen.getByRole('button', { name: /Remove selected/ }).click();
// skip name page
screen.getByRole('button', { name: /Next/ }).click();
// review page
screen.getByRole('button', { name: /Next/ }).click();
// await screen.findByTestId('chosen-packages-count');
let chosen = await screen.findByTestId('chosen-packages-count');
expect(chosen).toHaveTextContent('2');
// remove another package
screen.getByRole('button', { name: /Back/ }).click();
screen.getByRole('button', { name: /Back/ }).click();
await screen.findByTestId('search-available-pkgs-input');
screen.getByRole('option', { name: /summary for test package/ }).click();
screen.getByRole('button', { name: /Remove selected/ }).click();
// review page
screen.getByRole('button', { name: /Next/ }).click();
screen.getByRole('button', { name: /Next/ }).click();
// await screen.findByTestId('chosen-packages-count');
chosen = await screen.findByTestId('chosen-packages-count');
expect(chosen).toHaveTextContent('1');
});
test('should display empty available state on failed search', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResultEmpty));
await searchForAvailablePackages(searchbox, 'asdf');
expect(getPackages).toHaveBeenCalledTimes(1);
screen.getByText('No packages found');
});
test('should display empty available state on failed search after a successful search', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
let getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(searchbox, 'test');
getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResultEmpty));
await searchForAvailablePackages(searchbox, 'asdf');
expect(getPackages).toHaveBeenCalledTimes(2);
screen.getByText('No packages found');
});
test('should display empty chosen state on failed search', async () => {
await setUp();
const searchboxAvailable = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
const searchboxChosen = screen.getAllByRole('textbox')[1];
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
searchboxAvailable.click();
await searchForAvailablePackages(searchboxAvailable, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
screen.getByRole('button', { name: /Add all/ }).click();
searchboxChosen.click();
userEvent.type(searchboxChosen, 'asdf');
expect(screen.getAllByText('No packages found').length === 2);
// We need to clear this input in order to not have sideeffects on other tests
await searchForChosenPackages(searchboxChosen, '');
});
test('should filter chosen packages from available list', async () => {
await setUp();
const searchboxAvailable = screen.getAllByRole('textbox')[0];
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const chosenPackagesList = screen.getByTestId('chosen-pkgs-list');
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
searchboxAvailable.click();
await searchForAvailablePackages(searchboxAvailable, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
let availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(3);
screen
.getByRole('option', { name: /testPkg test package summary/ })
.click();
screen.getByRole('button', { name: /Add selected/ }).click();
availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(2);
let chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
// Knowing if it is in document isn't enough. We want a specific length of 1 so ignore rule.
// eslint-disable-next-line jest-dom/prefer-in-document
expect(chosenPackagesItems).toHaveLength(1);
searchboxAvailable.click();
await searchForAvailablePackages(searchboxAvailable, 'test');
expect(getPackages).toHaveBeenCalledTimes(2);
availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
expect(availablePackagesItems).toHaveLength(2);
// Knowing if it is in document isn't enough. We want a specific length of 1 so ignore rule.
// eslint-disable-next-line jest-dom/prefer-in-document
expect(chosenPackagesItems).toHaveLength(1);
within(chosenPackagesList).getByRole('option', {
name: /testPkg test package summary/,
});
});
test('should get all packages, regardless of api default limit', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation((distribution, architecture, search, limit) => {
return limit
? Promise.resolve(mockPkgResultAll)
: Promise.resolve(mockPkgResultPartial);
});
await searchForAvailablePackages(searchbox, 'testPkg');
expect(getPackages).toHaveBeenCalledTimes(2);
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(132);
});
test('search results should be sorted alphabetically', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0]; // searching by id doesn't update the input ref
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResultAlpha));
await searchForAvailablePackages(searchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(3);
const [firstItem, secondItem, thirdItem] = availablePackagesItems;
expect(firstItem).toHaveTextContent('testsummary for test package');
expect(secondItem).toHaveTextContent('lib-testlib-test package summary');
expect(thirdItem).toHaveTextContent('Z-testZ-test package summary');
});
test('available packages can be reset', async () => {
await setUp();
const searchbox = screen.getAllByRole('textbox')[0];
searchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(searchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(3);
screen
.getByRole('button', { name: /clear available packages search/i })
.click();
screen.getByText('Search above to add additionalpackages to your image');
});
test('chosen packages can be reset after filtering', async () => {
await setUp();
const availableSearchbox = screen.getAllByRole('textbox')[0];
availableSearchbox.click();
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
await searchForAvailablePackages(availableSearchbox, 'test');
expect(getPackages).toHaveBeenCalledTimes(1);
const availablePackagesList = screen.getByTestId('available-pkgs-list');
const availablePackagesItems = within(availablePackagesList).getAllByRole(
'option'
);
expect(availablePackagesItems).toHaveLength(3);
screen.getByRole('button', { name: /Add all/ }).click();
const chosenPackagesList = screen.getByTestId('chosen-pkgs-list');
let chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
expect(chosenPackagesItems).toHaveLength(3);
const chosenSearchbox = screen.getAllByRole('textbox')[1];
chosenSearchbox.click();
await searchForChosenPackages(chosenSearchbox, 'Pkg');
chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
// eslint-disable-next-line jest-dom/prefer-in-document
expect(chosenPackagesItems).toHaveLength(1);
screen
.getByRole('button', { name: /clear chosen packages search/i })
.click();
chosenPackagesItems = within(chosenPackagesList).getAllByRole('option');
expect(chosenPackagesItems).toHaveLength(3);
});
});
describe('Step Details', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
getNextButton().click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
getNextButton().click();
// skip registration
await screen.findByRole('textbox', {
name: 'Select activation key',
});
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
getNextButton().click();
// skip fsc
getNextButton().click();
// skip packages
getNextButton().click();
};
test('image name invalid for more than 100 chars', async () => {
await setUp();
// Enter image name
const nameInput = screen.getByRole('textbox', {
name: 'Image name',
});
// 101 character name
const invalidName = 'a'.repeat(101);
userEvent.type(nameInput, invalidName);
expect(getNextButton()).toHaveClass('pf-m-disabled');
expect(getNextButton()).toBeDisabled();
userEvent.clear(nameInput);
userEvent.type(nameInput, 'validName');
expect(getNextButton()).not.toHaveClass('pf-m-disabled');
expect(getNextButton()).toBeEnabled();
});
});
describe('Step Review', () => {
const setUp = async () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
getNextButton().click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
getNextButton().click();
await screen.findByRole('textbox', {
name: 'Select activation key',
});
// skip registration
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
getNextButton().click();
// skip fsc
getNextButton().click();
// skip packages
getNextButton().click();
// skip name
getNextButton().click();
};
// eslint-disable-next-line no-unused-vars
const setUpCentOS = () => {
history = renderWithReduxRouter(<CreateImageWizard />).history;
const releaseMenu = screen.getByRole('button', {
name: /options menu/i,
});
userEvent.click(releaseMenu);
const showOptionsButton = screen.getByRole('button', {
name: 'Show options for further development of RHEL',
});
userEvent.click(showOptionsButton);
const centos = screen.getByRole('option', {
name: 'CentOS Stream 8',
});
userEvent.click(centos);
// select aws as upload destination
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
getNextButton().click();
// aws step
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
getNextButton().click();
// skip fsc
getNextButton().click();
// skip packages
getNextButton().click();
// skip name
getNextButton().click();
};
test('has 3 buttons', async () => {
await setUp();
screen.getByRole('button', { name: /Create/ });
screen.getByRole('button', { name: /Back/ });
screen.getByRole('button', { name: /Cancel/ });
});
test('clicking Back loads Image name', async () => {
await setUp();
const back = screen.getByRole('button', { name: /Back/ });
back.click();
screen.getByRole('heading', {
name: 'Name image',
});
});
test('clicking Cancel loads landing page', async () => {
await setUp();
const cancel = screen.getByRole('button', { name: /Cancel/ });
verifyCancelButton(cancel, history);
});
test('has three tabs for rhel', async () => {
await setUp();
const buttonTarget = screen.getByTestId('tab-target');
const buttonRegistration = screen.getByTestId('tab-registration');
const buttonSystem = screen.getByTestId('tab-system');
userEvent.click(buttonTarget);
screen.getByRole('heading', {
name: 'Amazon Web Services',
});
userEvent.click(buttonRegistration);
screen.getByText('Register the system later');
userEvent.click(buttonSystem);
screen.getByRole('heading', {
name: 'Additional packages',
});
screen.getByRole('heading', {
name: 'File system configuration',
});
});
test('has two tabs for centos', () => {
setUpCentOS();
const buttonTarget = screen.getByTestId('tab-target');
const buttonSystem = screen.getByTestId('tab-system');
expect(screen.queryByTestId('tab-registration')).not.toBeInTheDocument();
userEvent.click(buttonTarget);
screen.getByRole('heading', {
name: 'Amazon Web Services',
});
userEvent.click(buttonSystem);
screen.getByRole('heading', {
name: 'Additional packages',
});
screen.getByRole('heading', {
name: 'File system configuration',
});
});
test('can pass location to recreate on review step', () => {
const initialLocation = {
state: {
composeRequest: {
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [
{
architecture: 'x86_64',
image_type: 'guest-image',
upload_request: {
type: 'aws.s3',
options: {},
},
},
],
customizations: {},
},
initialStep: 'review',
},
};
history = renderWithReduxRouter(
<CreateImageWizard />,
{},
initialLocation
).history;
screen.getByText(
'Review the information and click "Create image" to create the image using the following criteria.'
);
screen.getByText('Virtualization - Guest image');
screen.getByText('Register the system later');
screen.getByText('MyImageName');
});
});
describe('Click through all steps', () => {
const setUp = async () => {
const view = renderWithReduxRouter(<CreateImageWizard />);
history = view.history;
store = view.store;
};
test('with valid values', async () => {
await setUp();
// select image output
const releaseMenu = screen.getByRole('button', {
name: /options menu/i,
});
userEvent.click(releaseMenu);
const releaseOption = screen.getByRole('option', {
name: 'Red Hat Enterprise Linux (RHEL) 8',
});
userEvent.click(releaseOption);
userEvent.click(screen.getByTestId('upload-aws'));
userEvent.click(screen.getByTestId('upload-azure'));
userEvent.click(screen.getByTestId('upload-google'));
userEvent.click(screen.getByTestId('checkbox-vmware'));
userEvent.click(screen.getByTestId('checkbox-guest-image'));
userEvent.click(screen.getByTestId('checkbox-image-installer'));
screen.getByRole('button', { name: /Next/ }).click();
userEvent.type(screen.getByTestId('aws-account-id'), '012345678901');
screen.getByRole('button', { name: /Next/ }).click();
userEvent.type(screen.getByTestId('input-google-email'), 'test@test.com');
screen.getByRole('button', { name: /Next/ }).click();
// Randomly generated GUID
userEvent.type(
screen.getByTestId('azure-tenant-id'),
'b8f86d22-4371-46ce-95e7-65c415f3b1e2'
);
userEvent.type(
screen.getByTestId('azure-subscription-id'),
'60631143-a7dc-4d15-988b-ba83f3c99711'
);
userEvent.type(
screen.getByTestId('azure-resource-group'),
'testResourceGroup'
);
screen.getByRole('button', { name: /Next/ }).click();
// registration
const mockActivationKeys = [
{ id: '0', name: 'name0' },
{ id: 1, name: 'name1' },
];
jest
.spyOn(api, 'getActivationKeys')
.mockImplementation(() => Promise.resolve(mockActivationKeys));
const mockActivationKey = {
name0: {
additionalRepositories: [
{
repositoryLabel: 'repository0',
},
{
repositoryLabel: 'repository1',
},
{
repositoryLabel: 'repository2',
},
],
id: '0',
name: 'name0',
releaseVersion: '',
role: '',
serviceLevel: 'Self-Support',
usage: 'Production',
},
name1: {
additionalRepositories: [
{
repositoryLabel: 'repository3',
},
{
repositoryLabel: 'repository4',
},
{
repositoryLabel: 'repository5',
},
],
id: '1',
name: 'name1',
releaseVersion: '',
role: '',
serviceLevel: 'Premium',
usage: 'Production',
},
};
jest.spyOn(api, 'getActivationKey').mockImplementation((name) => {
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',
});
userEvent.click(activationKeyDropdown);
const activationKey = await screen.findByRole('option', {
name: 'name0',
});
userEvent.click(activationKey);
screen.getByDisplayValue('name0');
getNextButton().click();
// fsc
const toggle = await screen.findByTestId(
'file-system-config-toggle-manual'
);
within(toggle).getByRole('button').click();
const ap = await screen.findByTestId('file-system-add-partition');
ap.click();
ap.click();
const tbody = screen.getByTestId('file-system-configuration-tbody');
const rows = within(tbody).getAllByRole('row');
expect(rows).toHaveLength(3);
getNextButton().click();
// set mountpoint of final row to /var/tmp
within(rows[2]).getAllByRole('button', { name: 'Options menu' })[0].click();
within(rows[2]).getByRole('option', { name: '/var' }).click();
await waitForElementToBeRemoved(() =>
screen.queryAllByRole('heading', {
name: 'Danger alert: Duplicate mount point.',
})
);
userEvent.type(
within(rows[2]).getByRole('textbox', {
name: 'Mount point suffix text input',
}),
'/tmp'
);
// set size of the final row to 100 MiB
userEvent.type(
within(rows[2]).getByRole('textbox', { name: 'Size text input' }),
'{backspace}100'
);
within(rows[2]).getAllByRole('button', { name: 'Options menu' })[1].click();
within(rows[2]).getByRole('option', { name: 'MiB' }).click();
getNextButton().click();
// packages
const getPackages = jest
.spyOn(api, 'getPackages')
.mockImplementation(() => Promise.resolve(mockPkgResult));
screen.getByText(
/Images built with Image Builder include all required packages/i
);
await searchForAvailablePackages(
screen.getByTestId('search-available-pkgs-input'),
'test'
);
expect(getPackages).toHaveBeenCalledTimes(1);
screen
.getByRole('option', { name: /testPkg test package summary/ })
.click();
screen.getByRole('button', { name: /Add selected/ }).click();
getNextButton().click();
// Enter image name
const nameInput = screen.getByRole('textbox', {
name: 'Image name',
});
userEvent.type(nameInput, 'MyImageName');
getNextButton().click();
// review
await screen.findByText(
'Review the information and click "Create image" to create the image using the following criteria.'
);
await screen.findAllByText('Amazon Web Services');
await screen.findAllByText('Google Cloud Platform');
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');
screen.getByTestId('repositories-popover-button').click();
const repotbody = await screen.findByTestId(
'additional-repositories-table'
);
expect(within(repotbody).getAllByRole('row')).toHaveLength(3);
screen.getByTestId('file-system-configuration-popover').click();
const revtbody = await screen.findByTestId(
'file-system-configuration-tbody-review'
);
expect(within(revtbody).getAllByRole('row')).toHaveLength(3);
// mock the backend API
let ids = [];
const composeImage = jest
.spyOn(api, 'composeImage')
.mockImplementation((body) => {
let id;
if (body.image_requests[0].upload_request.type === 'aws') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [
{
architecture: 'x86_64',
image_type: 'aws',
upload_request: {
type: 'aws',
options: {
share_with_accounts: ['012345678901'],
},
},
},
],
customizations: {
filesystem: [
{
mountpoint: '/',
min_size: 10737418240,
},
{
mountpoint: '/home',
min_size: 1073741824,
},
{
mountpoint: '/var/tmp',
min_size: 104857600,
},
],
packages: ['testPkg'],
subscription: {
'activation-key': 'name0',
insights: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f56';
} else if (body.image_requests[0].upload_request.type === 'gcp') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [
{
architecture: 'x86_64',
image_type: 'gcp',
upload_request: {
type: 'gcp',
options: {
share_with_accounts: ['user:test@test.com'],
},
},
},
],
customizations: {
filesystem: [
{
mountpoint: '/',
min_size: 10737418240,
},
{
mountpoint: '/home',
min_size: 1073741824,
},
{
mountpoint: '/var/tmp',
min_size: 104857600,
},
],
packages: ['testPkg'],
subscription: {
'activation-key': 'name0',
insights: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f57';
} else if (body.image_requests[0].upload_request.type === 'azure') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [
{
architecture: 'x86_64',
image_type: 'azure',
upload_request: {
type: 'azure',
options: {
tenant_id: 'b8f86d22-4371-46ce-95e7-65c415f3b1e2',
subscription_id: '60631143-a7dc-4d15-988b-ba83f3c99711',
resource_group: 'testResourceGroup',
},
},
},
],
customizations: {
filesystem: [
{
mountpoint: '/',
min_size: 10737418240,
},
{
mountpoint: '/home',
min_size: 1073741824,
},
{
mountpoint: '/var/tmp',
min_size: 104857600,
},
],
packages: ['testPkg'],
subscription: {
'activation-key': 'name0',
insights: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f58';
} else if (body.image_requests[0].image_type === 'vsphere') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [
{
architecture: 'x86_64',
image_type: 'vsphere',
upload_request: {
type: 'aws.s3',
options: {},
},
},
],
customizations: {
filesystem: [
{
mountpoint: '/',
min_size: 10737418240,
},
{
mountpoint: '/home',
min_size: 1073741824,
},
{
mountpoint: '/var/tmp',
min_size: 104857600,
},
],
packages: ['testPkg'],
subscription: {
'activation-key': 'name0',
insights: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f59';
} else if (body.image_requests[0].image_type === 'guest-image') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [
{
architecture: 'x86_64',
image_type: 'guest-image',
upload_request: {
type: 'aws.s3',
options: {},
},
},
],
customizations: {
filesystem: [
{
mountpoint: '/',
min_size: 10737418240,
},
{
mountpoint: '/home',
min_size: 1073741824,
},
{
mountpoint: '/var/tmp',
min_size: 104857600,
},
],
packages: ['testPkg'],
subscription: {
'activation-key': 'name0',
insights: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f5a';
} else if (body.image_requests[0].image_type === 'image-installer') {
expect(body).toEqual({
distribution: RHEL_8,
image_name: 'MyImageName',
image_requests: [
{
architecture: 'x86_64',
image_type: 'image-installer',
upload_request: {
type: 'aws.s3',
options: {},
},
},
],
customizations: {
filesystem: [
{
mountpoint: '/',
min_size: 10737418240,
},
{
mountpoint: '/home',
min_size: 1073741824,
},
{
mountpoint: '/var/tmp',
min_size: 104857600,
},
],
packages: ['testPkg'],
subscription: {
'activation-key': 'name0',
insights: true,
organization: 5,
'server-url': 'subscription.rhsm.redhat.com',
'base-url': 'https://cdn.redhat.com/',
},
},
});
id = 'edbae1c2-62bc-42c1-ae0c-3110ab718f5b';
}
ids.unshift(id);
return Promise.resolve({ id });
});
const create = screen.getByRole('button', { name: /Create/ });
create.click();
// API request sent to backend
await expect(composeImage).toHaveBeenCalledTimes(6);
// returns back to the landing page
await waitFor(() =>
expect(history.location.pathname).toBe('/insights/image-builder/')
);
expect(store.getState().composes.allIds).toEqual(ids);
// set test timeout of 10 seconds
}, 10000);
});
describe('Keyboard accessibility', () => {
const setUp = async () => {
const view = renderWithReduxRouter(
<CreateImageWizard />,
{},
'/imagewizard'
);
history = view.history;
};
const clickNext = () => {
const next = screen.getByRole('button', { name: /Next/ });
next.click();
};
const selectAllEnvironments = () => {
const awsTile = screen.getByTestId('upload-aws');
awsTile.click();
const googleTile = screen.getByTestId('upload-google');
googleTile.click();
const azureTile = screen.getByTestId('upload-azure');
azureTile.click();
const virtualizationCheckbox = screen.getByRole('checkbox', {
name: /virtualization guest image checkbox/i,
});
virtualizationCheckbox.click();
};
const fillAzureInputs = () => {
userEvent.type(
screen.getByTestId('azure-tenant-id'),
'b8f86d22-4371-46ce-95e7-65c415f3b1e2'
);
userEvent.type(
screen.getByTestId('azure-subscription-id'),
'60631143-a7dc-4d15-988b-ba83f3c99711'
);
userEvent.type(
screen.getByTestId('azure-resource-group'),
'testResourceGroup'
);
};
test('autofocus on each step first input element', async () => {
setUp();
// Image output
selectAllEnvironments();
clickNext();
// Target environment aws
const awsInput = screen.getByRole('textbox', { name: /aws account id/i });
expect(awsInput).toHaveFocus();
userEvent.type(awsInput, '012345678901');
clickNext();
// Target environment google
const googleAccountRadio = screen.getByRole('radio', {
name: /google account/i,
});
expect(googleAccountRadio).toHaveFocus();
userEvent.type(screen.getByTestId('input-google-email'), 'test@test.com');
clickNext();
// Target environment azure
const tenantIDInput = screen.getByTestId('azure-tenant-id');
expect(tenantIDInput).toHaveFocus();
fillAzureInputs();
clickNext();
// Registration
const registerRadio = screen.getByRole('radio', {
name: /register and connect image instances with red hat/i,
});
expect(registerRadio).toHaveFocus();
await screen.findByRole('textbox', {
name: 'Select activation key',
});
// skip registration
const registerLaterRadio = screen.getByLabelText('Register later');
userEvent.click(registerLaterRadio);
clickNext();
// File system configuration
clickNext();
// Packages
let availablePackagesInput;
// eslint-disable-next-line testing-library/no-unnecessary-act
await act(async () => {
const view = screen.getByTestId('search-available-pkgs-input');
availablePackagesInput = within(view).getByRole('textbox', {
name: /search input/i,
});
});
expect(availablePackagesInput).toHaveFocus();
clickNext();
// Name
const nameInput = screen.getByRole('textbox', { name: /image name/i });
expect(nameInput).toHaveFocus();
clickNext();
// Review
const targetEnvironmentTab = screen.getByTestId('tab-target');
expect(targetEnvironmentTab).toHaveFocus();
});
test('pressing Esc closes the wizard', async () => {
setUp();
// wizard needs to be interacted with for the esc key to work
const awsTile = screen.getByTestId('upload-aws');
userEvent.click(awsTile);
userEvent.keyboard('{esc}');
expect(history.location.pathname).toBe('/insights/image-builder/');
});
test('pressing Enter does not advance the wizard', async () => {
setUp();
const awsTile = screen.getByTestId('upload-aws');
userEvent.click(awsTile);
userEvent.keyboard('{enter}');
screen.getByRole('heading', {
name: /image output/i,
});
});
test('target environment tiles are keyboard selectable', async () => {
const testTile = (tile) => {
tile.focus();
userEvent.keyboard('{space}');
expect(tile).toHaveClass('pf-m-selected');
userEvent.keyboard('{space}');
expect(tile).not.toHaveClass('pf-m-selected');
};
setUp();
clickNext();
testTile(screen.getByTestId('upload-aws'));
testTile(screen.getByTestId('upload-google'));
testTile(screen.getByTestId('upload-azure'));
});
});