test(user-interface-configuration): write initial tests (#1242)

* test(user-interface): add tests with playwright

* test: refactor UI configuration tests

---------

Co-authored-by: Ali BARIN <ali.barin53@gmail.com>
This commit is contained in:
Rıdvan Akca
2023-08-25 22:31:02 +03:00
committed by GitHub
parent ddeb18f626
commit a3b3038709
20 changed files with 389 additions and 69 deletions

View File

@@ -42,6 +42,7 @@ function createDrawerLinks({
Icon: GroupIcon,
primary: 'adminSettingsDrawer.users',
to: URLS.USERS,
dataTest: 'users-drawer-link',
}
: null,
canReadRole
@@ -49,6 +50,7 @@ function createDrawerLinks({
Icon: GroupsIcon,
primary: 'adminSettingsDrawer.roles',
to: URLS.ROLES,
dataTest: 'roles-drawer-link',
}
: null,
canUpdateConfig
@@ -56,6 +58,7 @@ function createDrawerLinks({
Icon: BrushIcon,
primary: 'adminSettingsDrawer.userInterface',
to: URLS.USER_INTERFACE,
dataTest: 'user-interface-drawer-link',
}
: null,
canManageSamlAuthProvider
@@ -63,6 +66,7 @@ function createDrawerLinks({
Icon: LockIcon,
primary: 'adminSettingsDrawer.authentication',
to: URLS.AUTHENTICATION,
dataTest: 'authentication-drawer-link',
}
: null,
].filter(Boolean) as DrawerLink[];
@@ -75,6 +79,7 @@ const drawerBottomLinks = [
Icon: ArrowBackIosNewIcon,
primary: 'adminSettingsDrawer.goBack',
to: '/',
dataTest: 'go-back-drawer-link',
},
];

View File

@@ -46,7 +46,7 @@ export default function AppBar(props: AppBarProps): React.ReactElement {
};
return (
<MuiAppBar>
<MuiAppBar data-test="app-bar">
<Container maxWidth={maxWidth} disableGutters>
<Toolbar>
<IconButton

View File

@@ -0,0 +1,40 @@
import React from 'react';
import { ButtonProps } from '@mui/material/Button';
import { Button } from './style';
const BG_IMAGE_FALLBACK =
'linear-gradient(45deg, #ccc 25%, transparent 25%), linear-gradient(135deg, #ccc 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #ccc 75%), linear-gradient(135deg, transparent 75%, #ccc 75%) /*! @noflip */';
export type ColorButtonProps = Omit<ButtonProps, 'children'> & {
bgColor: string;
isBgColorValid: boolean;
disablePopover: boolean;
};
export type ColorButtonElement = (props: ColorButtonProps) => JSX.Element;
const ColorButton = (props: ColorButtonProps) => {
const {
bgColor,
className,
disablePopover,
isBgColorValid,
...restButtonProps
} = props;
return (
<Button
data-test="color-button"
disableTouchRipple
style={{
backgroundColor: isBgColorValid ? bgColor : undefined,
backgroundImage: isBgColorValid ? undefined : BG_IMAGE_FALLBACK,
cursor: disablePopover ? 'default' : undefined,
}}
className={`MuiColorInput-Button ${className || ''}`}
{...restButtonProps}
/>
);
};
export default ColorButton;

View File

@@ -0,0 +1,15 @@
import MuiButton from '@mui/material/Button';
import { styled } from '@mui/material/styles';
export const Button = styled(MuiButton)(() => ({
backgroundSize: '8px 8px',
backgroundPosition: '0 0, 4px 0, 4px -4px, 0px 4px',
transition: 'none',
boxShadow: '0 4px 6px rgba(50, 50, 93, 0.11), 0 1px 3px rgba(0, 0, 0, 0.08)',
border: 0,
borderRadius: 4,
width: '24px',
aspectRatio: '1 / 1',
height: '24px',
minWidth: 0,
})) as typeof MuiButton;

View File

@@ -1,6 +1,7 @@
import * as React from 'react';
import { Controller, useFormContext } from 'react-hook-form';
import { MuiColorInput, MuiColorInputProps } from 'mui-color-input';
import ColorButton from './ColorButton';
type ColorInputProps = {
shouldUnregister?: boolean;
@@ -15,7 +16,6 @@ export default function ColorInput(props: ColorInputProps): React.ReactElement {
name,
shouldUnregister = false,
disabled = false,
'data-test': dataTest,
...textFieldProps
} = props;
@@ -27,12 +27,13 @@ export default function ColorInput(props: ColorInputProps): React.ReactElement {
shouldUnregister={shouldUnregister}
render={({ field }) => (
<MuiColorInput
Adornment={ColorButton}
format="hex"
{...textFieldProps}
{...field}
disabled={disabled}
inputProps={{
'data-test': dataTest,
'data-test': 'color-text-field',
}}
/>
)}

View File

@@ -8,7 +8,10 @@ const CustomLogo = () => {
const logoSvgData = config['logo.svgData'] as string;
return (
<img src={`data:image/svg+xml;utf8,${encodeURIComponent(logoSvgData)}`} />
<img
data-test="custom-logo"
src={`data:image/svg+xml;utf8,${encodeURIComponent(logoSvgData)}`}
/>
);
};

View File

@@ -68,19 +68,22 @@ export default function Drawer(props: DrawerProps): React.ReactElement {
</div>
<List sx={{ py: 0, mt: 3 }}>
{bottomLinks.map(({ Icon, badgeContent, primary, to }, index) => (
<ListItemLink
key={`${to}-${index}`}
icon={
<Badge badgeContent={badgeContent} color="secondary" max={99}>
<Icon htmlColor={theme.palette.primary.main} />
</Badge>
}
primary={formatMessage(primary)}
to={to}
onClick={closeOnClick}
/>
))}
{bottomLinks.map(
({ Icon, badgeContent, primary, to, dataTest }, index) => (
<ListItemLink
key={`${to}-${index}`}
icon={
<Badge badgeContent={badgeContent} color="secondary" max={99}>
<Icon htmlColor={theme.palette.primary.main} />
</Badge>
}
primary={formatMessage(primary)}
to={to}
onClick={closeOnClick}
data-test={dataTest}
/>
)
)}
</List>
</BaseDrawer>
);

View File

@@ -18,7 +18,7 @@ type FlowRowProps = {
flow: IFlow;
};
function getFlowStatusTranslationKey(status: IFlow["status"]): string {
function getFlowStatusTranslationKey(status: IFlow['status']): string {
if (status === 'published') {
return 'flow.published';
} else if (status === 'paused') {
@@ -28,7 +28,16 @@ function getFlowStatusTranslationKey(status: IFlow["status"]): string {
return 'flow.draft';
}
function getFlowStatusColor(status: IFlow["status"]): 'default' | 'primary' | 'secondary' | 'error' | 'info' | 'success' | 'warning' {
function getFlowStatusColor(
status: IFlow['status']
):
| 'default'
| 'primary'
| 'secondary'
| 'error'
| 'info'
| 'success'
| 'warning' {
if (status === 'published') {
return 'success';
} else if (status === 'paused') {
@@ -64,8 +73,12 @@ export default function FlowRow(props: FlowRowProps): React.ReactElement {
return (
<>
<Card sx={{ mb: 1 }}>
<CardActionArea component={Link} to={URLS.FLOW(flow.id)}>
<Card sx={{ mb: 1 }} data-test="flow-row">
<CardActionArea
component={Link}
to={URLS.FLOW(flow.id)}
data-test="card-action-area"
>
<CardContent>
<Apps direction="row" gap={1} sx={{ gridArea: 'apps' }}>
<FlowAppIcons steps={flow.steps} />
@@ -98,9 +111,7 @@ export default function FlowRow(props: FlowRowProps): React.ReactElement {
size="small"
color={getFlowStatusColor(flow?.status)}
variant={flow?.active ? 'filled' : 'outlined'}
label={formatMessage(
getFlowStatusTranslationKey(flow?.status)
)}
label={formatMessage(getFlowStatusTranslationKey(flow?.status))}
/>
<IconButton

View File

@@ -9,12 +9,12 @@ const Logo = () => {
const { config, loading } = useConfig(['logo.svgData']);
const logoSvgData = config?.['logo.svgData'] as string;
if (loading && !logoSvgData) return (<React.Fragment />);
if (loading && !logoSvgData) return <React.Fragment />;
if (logoSvgData) return <CustomLogo />;
return (
<Typography variant="h6" component="h1" noWrap>
<Typography variant="h6" component="h1" data-test="typography-logo" noWrap>
<FormattedMessage id="brandText" />
</Typography>
);