test: Update tests
This updates the tests to reflect changes made to the new registration step.
This commit is contained in:
parent
2caddb66c7
commit
0dea61bf00
11 changed files with 87 additions and 209 deletions
|
|
@ -43,7 +43,7 @@ const clickFromImageOutputToOpenScap = async () => {
|
|||
const user = userEvent.setup();
|
||||
await clickNext();
|
||||
await waitFor(async () =>
|
||||
user.click(await screen.findByLabelText('Register later'))
|
||||
user.click(await screen.findByTestId('automatically-register-checkbox'))
|
||||
);
|
||||
await clickNext(); // skip registration
|
||||
};
|
||||
|
|
@ -77,9 +77,11 @@ describe('Step Compliance', () => {
|
|||
|
||||
await clickNext();
|
||||
// skip registration
|
||||
const registerLater = await screen.findByLabelText('Register later');
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
|
||||
user.click(registerLater);
|
||||
user.click(registrationCheckbox);
|
||||
await clickNext();
|
||||
|
||||
// Now we should be in the Compliance step
|
||||
|
|
@ -141,9 +143,11 @@ describe('Step Compliance', () => {
|
|||
);
|
||||
await clickNext();
|
||||
// skip registration
|
||||
const registerLater = await screen.findByLabelText('Register later');
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
|
||||
user.click(registerLater);
|
||||
user.click(registrationCheckbox);
|
||||
await clickNext();
|
||||
|
||||
// Now we should be at the OpenSCAP step
|
||||
|
|
|
|||
|
|
@ -107,8 +107,10 @@ describe('Step Packages', () => {
|
|||
name: 'Select activation key',
|
||||
});
|
||||
|
||||
const registerLater = await screen.findByTestId('registration-radio-later');
|
||||
user.click(registerLater);
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
user.click(registrationCheckbox);
|
||||
|
||||
await clickNext();
|
||||
// skip OpenSCAP
|
||||
|
|
@ -402,9 +404,11 @@ describe('Step Custom repositories', () => {
|
|||
name: 'Select activation key',
|
||||
});
|
||||
|
||||
const registerLater = await screen.findByLabelText('Register later');
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
|
||||
user.click(registerLater);
|
||||
user.click(registrationCheckbox);
|
||||
await clickNext();
|
||||
// skip OpenSCAP
|
||||
await clickNext();
|
||||
|
|
|
|||
|
|
@ -194,10 +194,10 @@ describe('Step Review', () => {
|
|||
});
|
||||
|
||||
// skip registration
|
||||
const registerLaterRadio = await screen.findByTestId(
|
||||
'registration-radio-later'
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
await waitFor(() => user.click(registerLaterRadio));
|
||||
await waitFor(() => user.click(registrationCheckbox));
|
||||
|
||||
await clickNext();
|
||||
// skip OpenScap
|
||||
|
|
@ -258,10 +258,10 @@ describe('Step Review', () => {
|
|||
name: 'Select activation key',
|
||||
});
|
||||
// skip registration
|
||||
const registerLaterRadio = await screen.findByTestId(
|
||||
'registration-radio-later'
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
await waitFor(() => user.click(registerLaterRadio));
|
||||
await waitFor(() => user.click(registrationCheckbox));
|
||||
await clickNext();
|
||||
|
||||
// skip Oscap
|
||||
|
|
@ -437,16 +437,13 @@ describe('Keyboard accessibility', () => {
|
|||
await screen.findByText(
|
||||
'Automatically register and enable advanced capabilities'
|
||||
);
|
||||
const registerRadio = await screen.findByTestId('registration-radio-now');
|
||||
expect(registerRadio).toHaveFocus();
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
expect(registrationCheckbox).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
|
||||
|
|
|
|||
|
|
@ -134,8 +134,10 @@ const switchToAWSManual = async () => {
|
|||
const clickFromImageOutputToFsc = async () => {
|
||||
const user = userEvent.setup();
|
||||
await clickNext();
|
||||
const registerLater = await screen.findByText(/Register later/);
|
||||
await waitFor(async () => user.click(registerLater));
|
||||
const registerLaterCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
await waitFor(async () => user.click(registerLaterCheckbox));
|
||||
await clickNext();
|
||||
await clickNext(); // skip OSCAP
|
||||
};
|
||||
|
|
@ -167,10 +169,10 @@ describe('Step File system configuration', () => {
|
|||
await screen.findByRole('textbox', {
|
||||
name: 'Select activation key',
|
||||
});
|
||||
const registerLaterRadio = await screen.findByTestId(
|
||||
'registration-radio-later'
|
||||
const registerLaterCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
user.click(registerLaterRadio);
|
||||
user.click(registerLaterCheckbox);
|
||||
await clickNext();
|
||||
await clickNext();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ const goToFirstBootStep = async (): Promise<void> => {
|
|||
name: /virtualization guest image checkbox/i,
|
||||
});
|
||||
await waitFor(() => user.click(guestImageCheckBox));
|
||||
await clickNext();
|
||||
await clickNext(); // Registration
|
||||
await clickRegisterLater();
|
||||
await clickNext(); // OpenSCAP
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Router as RemixRouter } from '@remix-run/router/dist/router';
|
||||
import type { Router as RemixRouter } from '@remix-run/router';
|
||||
import { screen, waitFor, within } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
|
||||
|
|
@ -128,7 +128,6 @@ const selectAarch64 = async () => {
|
|||
};
|
||||
|
||||
const goToReviewStep = async () => {
|
||||
await clickNext(); // Register
|
||||
await clickRegisterLater();
|
||||
await clickNext(); // OpenSCAP
|
||||
await clickNext(); // File system customization
|
||||
|
|
@ -622,6 +621,7 @@ describe('set target using query parameter', () => {
|
|||
test('image-installer (query parameter provided)', async () => {
|
||||
await renderCreateMode({ target: 'iso' });
|
||||
expect(await screen.findByTestId('checkbox-image-installer')).toBeChecked();
|
||||
await clickNext();
|
||||
await goToReviewStep();
|
||||
const targetExpandable = await screen.findByTestId(
|
||||
'target-environments-expandable'
|
||||
|
|
@ -633,6 +633,7 @@ describe('set target using query parameter', () => {
|
|||
test('guest-image (query parameter provided)', async () => {
|
||||
await renderCreateMode({ target: 'qcow2' });
|
||||
expect(await screen.findByTestId('checkbox-guest-image')).toBeChecked();
|
||||
await clickNext();
|
||||
await goToReviewStep();
|
||||
const targetExpandable = await screen.findByTestId(
|
||||
'target-environments-expandable'
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Router as RemixRouter } from '@remix-run/router/dist/router';
|
||||
import type { Router as RemixRouter } from '@remix-run/router';
|
||||
import {
|
||||
screen,
|
||||
waitFor,
|
||||
waitForElementToBeRemoved,
|
||||
} from '@testing-library/react';
|
||||
import { userEvent } from '@testing-library/user-event';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
|
||||
import CreateImageWizard from '../../../../../Components/CreateImageWizard/CreateImageWizard';
|
||||
import ShareImageModal from '../../../../../Components/ShareImageModal/ShareImageModal';
|
||||
|
|
@ -15,7 +14,6 @@ import {
|
|||
CREATE_BLUEPRINT,
|
||||
EDIT_BLUEPRINT,
|
||||
RHEL_9,
|
||||
RHSM_API,
|
||||
} from '../../../../../constants';
|
||||
import {
|
||||
CreateBlueprintRequest,
|
||||
|
|
@ -23,7 +21,6 @@ import {
|
|||
} from '../../../../../store/imageBuilderApi';
|
||||
import { mockBlueprintIds } from '../../../../fixtures/blueprints';
|
||||
import { registrationCreateBlueprintRequest } from '../../../../fixtures/editMode';
|
||||
import { server } from '../../../../mocks/server';
|
||||
import { renderCustomRoutesWithReduxRouter } from '../../../../testUtils';
|
||||
import {
|
||||
clickBack,
|
||||
|
|
@ -36,23 +33,11 @@ import {
|
|||
interceptBlueprintRequest,
|
||||
goToRegistrationStep,
|
||||
clickRegisterLater,
|
||||
openAndDismissSaveAndBuildModal,
|
||||
renderEditMode,
|
||||
interceptEditBlueprintRequest,
|
||||
openAndDismissSaveAndBuildModal,
|
||||
} from '../../wizardTestUtils';
|
||||
|
||||
const selectActivationKey = async () => {
|
||||
const user = userEvent.setup();
|
||||
const activationKeyDropdown = await screen.findByRole('textbox', {
|
||||
name: 'Select activation key',
|
||||
});
|
||||
await waitFor(() => user.click(activationKeyDropdown));
|
||||
const activationKey = await screen.findByRole('option', {
|
||||
name: 'name0',
|
||||
});
|
||||
await waitFor(() => user.click(activationKey));
|
||||
};
|
||||
|
||||
const clickShowAdditionalConnectionOptions = async () => {
|
||||
const user = userEvent.setup();
|
||||
const link = await screen.findByText('Show additional connection options');
|
||||
|
|
@ -145,10 +130,10 @@ describe('Step Registration', () => {
|
|||
test('clicking Next loads file system configuration', async () => {
|
||||
await setUp();
|
||||
|
||||
const registerLaterRadio = await screen.findByTestId(
|
||||
'registration-radio-later'
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
user.click(registerLaterRadio);
|
||||
user.click(registrationCheckbox);
|
||||
|
||||
await clickNext();
|
||||
await clickNext();
|
||||
|
|
@ -176,21 +161,7 @@ describe('Step Registration', () => {
|
|||
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 () => {
|
||||
test('register now includes rhsm, rhc and insights', async () => {
|
||||
await setUp();
|
||||
|
||||
const activationKeyDropdown = await screen.findByRole('textbox', {
|
||||
|
|
@ -203,7 +174,15 @@ describe('Step Registration', () => {
|
|||
user.click(activationKey);
|
||||
await screen.findByDisplayValue('name0');
|
||||
|
||||
await goToReviewStep();
|
||||
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)'
|
||||
|
|
@ -215,137 +194,39 @@ describe('Step Registration', () => {
|
|||
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 goToReviewStep();
|
||||
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 goToReviewStep();
|
||||
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 () => {
|
||||
test('should disable dropdown when clicking Register the system later', async () => {
|
||||
await setUp();
|
||||
const removeKeyInformation = waitForElementToBeRemoved(() => [
|
||||
screen.getByTestId('subscription-activation-key'),
|
||||
screen.getByTestId('selected-activation-key'),
|
||||
]);
|
||||
|
||||
await screen.findByTestId('selected-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));
|
||||
const registrationCheckbox = await screen.findByTestId(
|
||||
'automatically-register-checkbox'
|
||||
);
|
||||
await waitFor(async () => user.click(registrationCheckbox));
|
||||
|
||||
await removeKeyInformation;
|
||||
await waitFor(async () =>
|
||||
expect(
|
||||
await screen.findByRole('button', { name: /options menu/i })
|
||||
).toBeDisabled()
|
||||
);
|
||||
|
||||
await goToReviewStep();
|
||||
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('registration request generated correctly', () => {
|
||||
|
|
@ -373,7 +254,6 @@ describe('registration request generated correctly', () => {
|
|||
test('register + insights + rhc', async () => {
|
||||
await renderCreateMode();
|
||||
await goToRegistrationStep();
|
||||
await selectActivationKey();
|
||||
await goToReviewStep();
|
||||
// informational modal pops up in the first test only as it's tied
|
||||
// to a 'imageBuilder.saveAndBuildModalSeen' variable in localStorage
|
||||
|
|
@ -401,7 +281,6 @@ describe('registration request generated correctly', () => {
|
|||
await goToRegistrationStep();
|
||||
await clickShowAdditionalConnectionOptions();
|
||||
await deselectEnableRemoteRemediations();
|
||||
await selectActivationKey();
|
||||
await goToReviewStep();
|
||||
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
|
||||
|
||||
|
|
@ -421,13 +300,14 @@ describe('registration request generated correctly', () => {
|
|||
expect(receivedRequest).toEqual(expectedRequest);
|
||||
});
|
||||
|
||||
test('register', async () => {
|
||||
test('register now', async () => {
|
||||
await renderCreateMode();
|
||||
await goToRegistrationStep();
|
||||
await clickShowAdditionalConnectionOptions();
|
||||
await deselectPredictiveAnalytics();
|
||||
await selectActivationKey();
|
||||
await goToReviewStep();
|
||||
// informational modal pops up in the first test only as it's tied
|
||||
// to a 'imageBuilder.saveAndBuildModalSeen' variable in localStorage
|
||||
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
|
||||
|
||||
const expectedSubscription = {
|
||||
|
|
@ -443,13 +323,14 @@ describe('registration request generated correctly', () => {
|
|||
customizations: { subscription: expectedSubscription },
|
||||
};
|
||||
|
||||
expect(receivedRequest).toEqual(expectedRequest);
|
||||
await waitFor(() => {
|
||||
expect(receivedRequest).toEqual(expectedRequest);
|
||||
});
|
||||
});
|
||||
|
||||
test('register Later', async () => {
|
||||
test('register later', async () => {
|
||||
await renderCreateMode();
|
||||
await goToRegistrationStep();
|
||||
await clickShowAdditionalConnectionOptions();
|
||||
await clickRegisterLater();
|
||||
await goToReviewStep();
|
||||
const receivedRequest = await interceptBlueprintRequest(CREATE_BLUEPRINT);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Router as RemixRouter } from '@remix-run/router/dist/router';
|
||||
import type { Router as RemixRouter } from '@remix-run/router';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { userEvent } from '@testing-library/user-event';
|
||||
import { http, HttpResponse } from 'msw';
|
||||
|
|
@ -70,7 +70,6 @@ const deselectAwsAndSelectGuestImage = async () => {
|
|||
name: /virtualization guest image checkbox/i,
|
||||
});
|
||||
await waitFor(async () => user.click(guestImageCheckbox));
|
||||
await clickNext();
|
||||
};
|
||||
|
||||
const selectSource = async () => {
|
||||
|
|
@ -251,13 +250,6 @@ describe('Step Upload to AWS', () => {
|
|||
});
|
||||
user.click(source);
|
||||
|
||||
await clickNext();
|
||||
|
||||
// registration
|
||||
await screen.findByRole('textbox', {
|
||||
name: 'Select activation key',
|
||||
});
|
||||
|
||||
// click through to review step
|
||||
await goToReview();
|
||||
// informational modal pops up in the first test only as it's tied
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ const deselectAzureAndSelectGuestImage = async () => {
|
|||
name: /virtualization guest image checkbox/i,
|
||||
});
|
||||
await waitFor(async () => user.click(guestImageCheckbox));
|
||||
await clickNext();
|
||||
};
|
||||
|
||||
const selectSource = async () => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
|
||||
import { Router as RemixRouter } from '@remix-run/router/dist/router';
|
||||
import type { Router as RemixRouter } from '@remix-run/router';
|
||||
import { screen, waitFor } from '@testing-library/react';
|
||||
import { userEvent } from '@testing-library/user-event';
|
||||
|
||||
|
|
@ -79,7 +79,6 @@ const deselectGcpAndSelectGuestImage = async () => {
|
|||
name: /virtualization guest image checkbox/i,
|
||||
});
|
||||
await waitFor(async () => user.click(guestImageCheckbox));
|
||||
await clickNext();
|
||||
};
|
||||
|
||||
const selectGoogleAccount = async (optionId: string) => {
|
||||
|
|
|
|||
|
|
@ -101,10 +101,10 @@ export const clickRegisterLater = async () => {
|
|||
await screen.findByRole('heading', {
|
||||
name: /Register systems using this image/,
|
||||
});
|
||||
const radioButton = await screen.findByRole('radio', {
|
||||
name: 'Register later',
|
||||
const registrationCheckbox = await screen.findByRole('checkbox', {
|
||||
name: /automatically register and enable advanced capabilities/i,
|
||||
});
|
||||
await waitFor(() => user.click(radioButton));
|
||||
await waitFor(() => user.click(registrationCheckbox));
|
||||
};
|
||||
|
||||
export const selectCustomRepo = async () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue