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:
parent
a2ce8455de
commit
9f93f78fcc
1
.github/workflows/e2e.frontend.yaml
vendored
1
.github/workflows/e2e.frontend.yaml
vendored
@ -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:
|
||||
|
125
frontend/cypress/integration/import/import.spec.ts
Normal file
125
frontend/cypress/integration/import/import.spec.ts
Normal 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%');
|
||||
});
|
||||
});
|
@ -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',
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
/>
|
||||
|
@ -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
|
||||
|
@ -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 />
|
||||
|
@ -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';
|
||||
|
Loading…
Reference in New Issue
Block a user