1
0
mirror of https://github.com/Unleash/unleash.git synced 2025-01-20 00:08:02 +01:00

Cypress test for importing (#3058)

This commit is contained in:
Jaanus Sellin 2023-02-08 11:16:38 +02:00 committed by GitHub
parent a2ce8455de
commit 9f93f78fcc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 154 additions and 0 deletions

View File

@ -11,6 +11,7 @@ jobs:
- groups/groups.spec.ts
- projects/access.spec.ts
- segments/segments.spec.ts
- import/import.spec.ts
steps:
- name: Dump GitHub context
env:

View File

@ -0,0 +1,125 @@
/// <reference types="cypress" />
const baseUrl = Cypress.config().baseUrl;
const randomSeed = String(Math.random()).split('.')[1];
const randomFeatureName = `cypress-features${randomSeed}`;
const userIds: any[] = [];
// Disable all active splash pages by visiting them.
const disableActiveSplashScreens = () => {
cy.visit(`/splash/operators`);
};
describe('imports', () => {
before(() => {
disableActiveSplashScreens();
cy.login();
for (let i = 1; i <= 2; i++) {
cy.request('POST', `${baseUrl}/api/admin/user-admin`, {
name: `unleash-e2e-user${i}-${randomFeatureName}`,
email: `unleash-e2e-user${i}-${randomFeatureName}@test.com`,
sendEmail: false,
rootRole: 3,
}).then(response => userIds.push(response.body.id));
}
});
after(() => {
userIds.forEach(id =>
cy.request('DELETE', `${baseUrl}/api/admin/user-admin/${id}`)
);
});
beforeEach(() => {
cy.login();
if (document.querySelector("[data-testid='CLOSE_SPLASH']")) {
cy.get("[data-testid='CLOSE_SPLASH']").click();
}
});
it('can import data', () => {
cy.visit('/projects/default');
cy.get("[data-testid='IMPORT_BUTTON']").click();
const exportText = {
features: [
{
name: randomFeatureName,
description: '',
type: 'release',
project: 'default',
stale: false,
impressionData: false,
archived: false,
},
],
featureStrategies: [
{
name: 'flexibleRollout',
id: '14a0d9dd-2b5d-4a21-98fd-ede72bda0328',
featureName: randomFeatureName,
parameters: {
groupId: randomFeatureName,
rollout: '50',
stickiness: 'default',
},
constraints: [],
segments: [],
},
],
featureEnvironments: [
{
enabled: true,
featureName: randomFeatureName,
environment: 'test',
variants: [],
name: randomFeatureName,
},
],
contextFields: [],
featureTags: [
{
featureName: randomFeatureName,
tagType: 'simple',
tagValue: 'best-tag',
},
{
featureName: randomFeatureName,
tagType: 'simple',
tagValue: 'rserw',
},
{
featureName: randomFeatureName,
tagType: 'simple',
tagValue: 'FARO',
},
],
segments: [],
tagTypes: [
{
name: 'simple',
description: 'Used to simplify filtering of features',
icon: '#',
},
],
};
cy.get("[data-testid='VALIDATE_BUTTON']").should('be.disabled');
// cypress can only work with input@file that is visible
cy.get('input[type=file]')
.invoke('attr', 'style', 'display: block')
.selectFile({
contents: Cypress.Buffer.from(JSON.stringify(exportText)),
fileName: 'upload.json',
lastModified: Date.now(),
});
cy.get("[data-testid='VALIDATE_BUTTON']").click();
cy.get("[data-testid='IMPORT_CONFIGURATION_BUTTON']").click();
// cy.contains('Import completed');
cy.visit(`/projects/default/features/${randomFeatureName}`);
cy.contains('enabled in development');
cy.contains('50%');
});
});

View File

@ -14,6 +14,11 @@ import {
import { ValidationStage } from './validate/ValidationStage';
import { ImportStage } from './import/ImportStage';
import { ImportOptions } from './configure/ImportOptions';
import {
IMPORT_BUTTON,
IMPORT_CONFIGURATION_BUTTON,
VALIDATE_BUTTON,
} from '../../../../utils/testIds';
const ModalContentContainer = styled('div')(({ theme }) => ({
minHeight: '100vh',

View File

@ -16,6 +16,11 @@ import React, { FC, ReactNode, useState } from 'react';
import useToast from 'hooks/useToast';
import { ImportLayoutContainer } from '../ImportLayoutContainer';
import { ActionsContainer } from '../ActionsContainer';
import {
CODE_EDITOR_TAB,
CODE_TEXT_FIELD,
VALIDATE_BUTTON,
} from 'utils/testIds';
const StyledTextField = styled(TextField)(({ theme }) => ({
width: '100%',
@ -58,6 +63,7 @@ export const ConfigurationTabs: FC<{
<Tab
label="Code editor"
value="code"
data-testid={CODE_EDITOR_TAB}
onClick={() => setActiveTab('code')}
/>
</Tabs>
@ -119,6 +125,7 @@ export const ImportArea: FC<{
variant="outlined"
onChange={event => setImportPayload(event.target.value)}
value={importPayload}
data-testid={CODE_TEXT_FIELD}
multiline
minRows={13}
maxRows={13}
@ -139,6 +146,7 @@ export const Actions: FC<{
variant="contained"
type="submit"
onClick={onSubmit}
data-testid={VALIDATE_BUTTON}
disabled={disabled}
>
Validate

View File

@ -3,6 +3,7 @@ import { KeyboardArrowDownOutlined } from '@mui/icons-material';
import React, { FC, useEffect } from 'react';
import { useProjectEnvironments } from 'hooks/api/getters/useProjectEnvironments/useProjectEnvironments';
import { Box, styled, Typography } from '@mui/material';
import { IMPORT_ENVIRONMENT } from 'utils/testIds';
const ImportOptionsContainer = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.secondaryContainer,
@ -57,6 +58,7 @@ export const ImportOptions: FC<IImportOptionsProps> = ({
onChange={onChange}
label={'Environment'}
value={environment}
data-testid={IMPORT_ENVIRONMENT}
IconComponent={KeyboardArrowDownOutlined}
fullWidth
/>

View File

@ -9,6 +9,7 @@ import { ConditionallyRender } from 'component/common/ConditionallyRender/Condit
import useToast from 'hooks/useToast';
import { formatUnknownError } from 'utils/formatUnknownError';
import { ActionsContainer } from '../ActionsContainer';
import { IMPORT_CONFIGURATION_BUTTON } from 'utils/testIds';
const ImportInfoContainer = styled(Box)(({ theme }) => ({
backgroundColor: theme.palette.secondaryContainer,
@ -191,6 +192,7 @@ export const ValidationStage: FC<{
variant="contained"
type="submit"
onClick={onSubmit}
data-testid={IMPORT_CONFIGURATION_BUTTON}
disabled={validationResult.errors.length > 0 || !validJSON}
>
Import configuration

View File

@ -41,6 +41,7 @@ import { ProjectChangeRequests } from '../../changeRequest/ProjectChangeRequests
import { ProjectSettings } from './ProjectSettings/ProjectSettings';
import { useFavoriteProjectsApi } from 'hooks/api/actions/useFavoriteProjectsApi/useFavoriteProjectsApi';
import { ImportModal } from './Import/ImportModal';
import { IMPORT_BUTTON } from 'utils/testIds';
export const Project = () => {
const projectId = useRequiredPathParam('projectId');
@ -150,6 +151,7 @@ export const Project = () => {
}}
onClick={() => setModalOpen(true)}
tooltipProps={{ title: 'Import' }}
data-testid={IMPORT_BUTTON}
data-loading
>
<FileUpload />

View File

@ -75,3 +75,12 @@ export const ANNOUNCER_ELEMENT_TEST_ID = 'ANNOUNCER_ELEMENT_TEST_ID';
export const INSTANCE_STATUS_BAR_ID = 'INSTANCE_STATUS_BAR_ID';
export const TOAST_TEXT = 'TOAST_TEXT';
export const LARGE_NUMBER_PRETTIFIED = 'LARGE_NUMBER_PRETTIFIED';
/* EXPORT/IMPORT FEATURES */
export const IMPORT_BUTTON = 'IMPORT_BUTTON';
export const CODE_EDITOR_TAB = 'CODE_EDITOR_TAB';
export const IMPORT_ENVIRONMENT = 'IMPORT_ENVIRONMENT';
export const CODE_TEXT_FIELD = 'CODE_TEXT_FIELD';
export const VALIDATE_BUTTON = 'VALIDATE_BUTTON';
export const IMPORT_CONFIGURATION_BUTTON = 'IMPORT_CONFIGURATION_BUTTON';