Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const EditControllerTransferNetwork: FC = () => {
blankOption={{
name: t('None'),
}}
testId="controller-transfer-network-select"
/>
)}
/>
Expand Down
2 changes: 2 additions & 0 deletions src/overview/tabs/Settings/components/SettingsCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const SettingsCard: FC<SettingsCardProps> = ({ obj }) => {
}}
className="pf-v6-u-mb-md"
headingLevel="h3"
data-testid="settings-edit-button"
/>
<DescriptionList>
<DetailsItem
Expand Down Expand Up @@ -107,6 +108,7 @@ const SettingsCard: FC<SettingsCardProps> = ({ obj }) => {
helpContent={<SnapshotPoolingIntervalHelpContent />}
/>
<DetailsItem
testId="settings-controller-transfer-network"
content={
spec?.[SettingsFields.ControllerTransferNetwork] ??
defaultValuesMap[SettingsFields.ControllerTransferNetwork]
Expand Down
1 change: 1 addition & 0 deletions src/overview/tabs/Settings/components/SettingsEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const SettingsEdit: ModalComponent<SettingsEditProps> = ({ closeModal, controlle
closeModal={closeModal}
variant={ModalVariant.medium}
isDisabled={!isDirty}
testId="settings-edit-modal"
>
<Form>
{t(
Expand Down
12 changes: 11 additions & 1 deletion src/overview/tabs/Settings/components/SettingsSelectInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ type BlankOption = {
* @property {(value: string) => void} onChange - Function to call when the value changes
* @property {Option[]} options - The options to present to the user
* @property {BlankOption} [blankOption] - Optional blank option that passes an empty value when selected
* @property {string} [testId] - Test ID for the select component
*/
type SettingsSelectInputProps = {
value: number | string;
onChange: (value: number | string) => void;
options: Option[];
blankOption?: BlankOption;
showKeyAsSelected?: boolean; // a flag to show selected value that's based on option key and not name
testId?: string;
};

const BLANK_OPTION_KEY = '__blank__';
Expand All @@ -57,6 +59,7 @@ const SettingsSelectInput: FC<SettingsSelectInputProps> = ({
onChange,
options,
showKeyAsSelected = false,
testId,
value,
}) => {
const { t } = useForkliftTranslation();
Expand Down Expand Up @@ -100,14 +103,20 @@ const SettingsSelectInput: FC<SettingsSelectInputProps> = ({
onClick={onToggleClick}
isExpanded={isOpen}
className="forklift-overview__settings-select"
data-testid={testId}
>
<Truncate content={String(selected) || t('Select an option')} />
</MenuToggle>
);

const renderOptions = () => {
const optionElements = options?.map(({ description, key, name }) => (
<SelectOption key={key} value={showKeyAsSelected ? key : name} description={description}>
<SelectOption
key={key}
value={showKeyAsSelected ? key : name}
description={description}
data-testid={testId ? `${testId}-option-${key}` : undefined}
>
{name}
</SelectOption>
));
Expand All @@ -118,6 +127,7 @@ const SettingsSelectInput: FC<SettingsSelectInputProps> = ({
key={BLANK_OPTION_KEY}
value={blankOption.name}
description={blankOption.description}
data-testid={testId ? `${testId}-option-none` : undefined}
>
{blankOption.name}
</SelectOption>,
Expand Down
44 changes: 44 additions & 0 deletions testing/playwright/e2e/downstream/overview-page.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { expect, test } from '@playwright/test';

import { createTestNad } from '../../fixtures/helpers/resourceCreationHelpers';
import { TIPS_AND_TRICKS_TOPICS } from '../../fixtures/overview-page-topics';
import { OverviewPage } from '../../page-objects/OverviewPage';
import { MTV_NAMESPACE } from '../../utils/resource-manager/constants';
import { ResourceManager } from '../../utils/resource-manager/ResourceManager';

test.describe(
'Overview Page - Tips and Tricks',
Expand Down Expand Up @@ -47,3 +50,44 @@ test.describe(
});
},
);

test.describe(
'Overview Page - Settings',
{
tag: '@downstream',
},
() => {
const resourceManager = new ResourceManager();

test.beforeAll(async ({ browser }) => {
const context = await browser.newContext({ ignoreHTTPSErrors: true });
const page = await context.newPage();

await createTestNad(page, resourceManager, {
namespace: MTV_NAMESPACE,
});

await context.close();
});

test.afterAll(async () => {
await resourceManager.instantCleanup();
});

test('should edit controller transfer network and verify save', async ({ page }) => {
const overviewPage = new OverviewPage(page);

await test.step('Navigate to Settings tab', async () => {
await overviewPage.navigateToSettings();
});

await test.step('Verify transfer network field is visible', async () => {
await overviewPage.verifyTransferNetworkFieldVisible();
});

await test.step('Edit and save transfer network', async () => {
await overviewPage.editAndSaveTransferNetwork();
});
});
},
);
61 changes: 57 additions & 4 deletions testing/playwright/fixtures/helpers/resourceCreationHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,19 @@ import { CreateProviderPage } from '../../page-objects/CreateProviderPage';
import { PlanDetailsPage } from '../../page-objects/PlanDetailsPage/PlanDetailsPage';
import { EndpointType, ProviderType } from '../../types/enums';
import { createPlanTestData, type ProviderData } from '../../types/test-data';
import { NavigationHelper } from '../../utils/NavigationHelper';
import { getProviderConfig } from '../../utils/providers';
import { MTV_NAMESPACE } from '../../utils/resource-manager/constants';
import {
MTV_NAMESPACE,
NAD_API_VERSION,
RESOURCE_KINDS,
} from '../../utils/resource-manager/constants';
import {
createNad as createNadApi,
createProvider as createProviderApi,
createSecret as createSecretApi,
type V1NetworkAttachmentDefinition,
} from '../../utils/resource-manager/ResourceCreator';
import type { ResourceManager } from '../../utils/resource-manager/ResourceManager';

export const createSecretObject = (
Expand Down Expand Up @@ -78,10 +89,11 @@ const createOvaProviderViaApi = async (
const secretName = `${providerData.name}-secret`;
const secret = createSecretObject(secretName, MTV_NAMESPACE, { url: providerData.hostname });

const createdSecret = await resourceManager.createSecret(page, secret);
const createdSecret = await createSecretApi(page, secret, MTV_NAMESPACE);
if (!createdSecret) {
throw new Error(`Failed to create secret for OVA provider ${providerData.name}`);
}
resourceManager.addSecret(secretName, MTV_NAMESPACE);

const provider = createProviderObject(providerData.name, MTV_NAMESPACE, {
type: ProviderType.OVA,
Expand All @@ -90,11 +102,10 @@ const createOvaProviderViaApi = async (
settings: { applianceManagement: 'true' },
});

const createdProvider = await resourceManager.createProvider(page, provider);
const createdProvider = await createProviderApi(page, provider, MTV_NAMESPACE);
if (!createdProvider) {
throw new Error(`Failed to create OVA provider ${providerData.name}`);
}

resourceManager.addProvider(providerData.name, MTV_NAMESPACE);
};

Expand Down Expand Up @@ -207,3 +218,45 @@ export const createPlan = async (

return buildTestPlanResult(testPlanData);
};

export const createTestNad = async (
page: Page,
resourceManager: ResourceManager,
options: {
name?: string;
namespace: string;
bridgeName?: string;
},
): Promise<V1NetworkAttachmentDefinition> => {
const { namespace, bridgeName = 'br0' } = options;
const nadName = options.name ?? `nad-test-${crypto.randomUUID().slice(0, 8)}`;

const navigationHelper = new NavigationHelper(page);
await navigationHelper.navigateToConsole();

const nadConfig = {
cniVersion: '0.3.1',
name: nadName,
type: 'bridge',
bridge: bridgeName,
ipam: {},
};

const nad: V1NetworkAttachmentDefinition = {
apiVersion: NAD_API_VERSION,
kind: RESOURCE_KINDS.NETWORK_ATTACHMENT_DEFINITION,
metadata: { name: nadName, namespace },
spec: { config: JSON.stringify(nadConfig) },
};

const createdNad = await createNadApi(page, nad, namespace);
if (!createdNad) {
throw new Error(`Failed to create NAD ${nadName}`);
}
resourceManager.addNad(nadName, namespace);

return {
...createdNad,
metadata: { ...createdNad.metadata, name: nadName, namespace },
};
};
Loading