Skip to content
Snippets Groups Projects
Unverified Commit b3fa0168 authored by janainaCoelhoRocketchat's avatar janainaCoelhoRocketchat Committed by GitHub
Browse files

test: create non private team and readonly team (#30371)

parent 3677cc5a
No related branches found
No related tags found
No related merge requests found
import { Box, Modal, Button, TextInput, Field, ToggleSwitch, FieldGroup, Icon } from '@rocket.chat/fuselage'; import { Box, Button, Field, FieldGroup, Icon, Modal, TextInput, ToggleSwitch } from '@rocket.chat/fuselage';
import { useUniqueId } from '@rocket.chat/fuselage-hooks';
import { import {
useTranslation,
useSetting,
usePermission,
useEndpoint, useEndpoint,
useToastMessageDispatch, usePermission,
usePermissionWithScopedRoles, usePermissionWithScopedRoles,
useSetting,
useToastMessageDispatch,
useTranslation,
} from '@rocket.chat/ui-contexts'; } from '@rocket.chat/ui-contexts';
import type { ComponentProps, ReactElement } from 'react'; import type { ComponentProps, ReactElement } from 'react';
import React, { memo, useMemo, useEffect } from 'react'; import React, { memo, useEffect, useMemo } from 'react';
import { useForm, Controller } from 'react-hook-form'; import { Controller, useForm } from 'react-hook-form';
import UserAutoCompleteMultiple from '../../../components/UserAutoCompleteMultiple'; import UserAutoCompleteMultiple from '../../../components/UserAutoCompleteMultiple';
import { goToRoomById } from '../../../lib/utils/goToRoomById'; import { goToRoomById } from '../../../lib/utils/goToRoomById';
...@@ -129,18 +130,35 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -129,18 +130,35 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
} }
}; };
const createTeamFormId = useUniqueId();
const nameId = useUniqueId();
const topicId = useUniqueId();
const privateId = useUniqueId();
const readOnlyId = useUniqueId();
const encryptedId = useUniqueId();
const broadcastId = useUniqueId();
const addMembersId = useUniqueId();
return ( return (
<Modal wrapperFunction={(props: ComponentProps<typeof Box>) => <Box is='form' onSubmit={handleSubmit(handleCreateTeam)} {...props} />}> <Modal
aria-labelledby={`${createTeamFormId}-title`}
wrapperFunction={(props: ComponentProps<typeof Box>) => (
<Box is='form' id={createTeamFormId} onSubmit={handleSubmit(handleCreateTeam)} {...props} />
)}
>
<Modal.Header> <Modal.Header>
<Modal.Title>{t('Teams_New_Title')}</Modal.Title> <Modal.Title id={`${createTeamFormId}-title`}>{t('Teams_New_Title')}</Modal.Title>
<Modal.Close title={t('Close')} onClick={onClose} tabIndex={-1} /> <Modal.Close title={t('Close')} onClick={onClose} tabIndex={-1} />
</Modal.Header> </Modal.Header>
<Modal.Content mbe={2}> <Modal.Content mbe={2}>
<FieldGroup> <FieldGroup>
<Field> <Field>
<Field.Label>{t('Teams_New_Name_Label')}</Field.Label> <Field.Label required htmlFor={nameId}>
{t('Teams_New_Name_Label')}
</Field.Label>
<Field.Row> <Field.Row>
<TextInput <TextInput
id={nameId}
aria-invalid={errors.name ? 'true' : 'false'} aria-invalid={errors.name ? 'true' : 'false'}
{...register('name', { {...register('name', {
required: t('error-the-field-is-required', { field: t('Name') }), required: t('error-the-field-is-required', { field: t('Name') }),
...@@ -149,26 +167,37 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -149,26 +167,37 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
placeholder={t('Team_Name')} placeholder={t('Team_Name')}
addon={<Icon size='x20' name={isPrivate ? 'team-lock' : 'team'} />} addon={<Icon size='x20' name={isPrivate ? 'team-lock' : 'team'} />}
error={errors.name?.message} error={errors.name?.message}
aria-describedby={`${nameId}-error`}
aria-required='true'
/> />
</Field.Row> </Field.Row>
{errors?.name && <Field.Error>{errors.name.message}</Field.Error>} {errors?.name && (
<Field.Error aria-live='assertive' id={`${nameId}-error`}>
{errors.name.message}
</Field.Error>
)}
</Field> </Field>
<Field> <Field>
<Field.Label> <Field.Label htmlFor={topicId}>
{t('Teams_New_Description_Label')}{' '} {t('Teams_New_Description_Label')}{' '}
<Box is='span' color='annotation'> <Box is='span' color='annotation'>
({t('optional')}) ({t('optional')})
</Box> </Box>
</Field.Label> </Field.Label>
<Field.Row> <Field.Row>
<TextInput {...register('topic')} placeholder={t('Teams_New_Description_Placeholder')} /> <TextInput
id={topicId}
aria-describedby={`${topicId}-hint`}
{...register('topic')}
placeholder={t('Teams_New_Description_Placeholder')}
/>
</Field.Row> </Field.Row>
</Field> </Field>
<Field> <Field>
<Box display='flex' justifyContent='space-between' alignItems='start'> <Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'> <Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Private_Label')}</Field.Label> <Field.Label htmlFor={privateId}>{t('Teams_New_Private_Label')}</Field.Label>
<Field.Description> <Field.Description id={`${privateId}-hint`}>
{isPrivate ? t('Teams_New_Private_Description_Enabled') : t('Teams_New_Private_Description_Disabled')} {isPrivate ? t('Teams_New_Private_Description_Enabled') : t('Teams_New_Private_Description_Disabled')}
</Field.Description> </Field.Description>
</Box> </Box>
...@@ -176,7 +205,7 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -176,7 +205,7 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
control={control} control={control}
name='isPrivate' name='isPrivate'
render={({ field: { onChange, value, ref } }): ReactElement => ( render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch onChange={onChange} checked={value} ref={ref} /> <ToggleSwitch id={privateId} aria-describedby={`${privateId}-hint`} onChange={onChange} checked={value} ref={ref} />
)} )}
/> />
</Box> </Box>
...@@ -184,8 +213,8 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -184,8 +213,8 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
<Field> <Field>
<Box display='flex' justifyContent='space-between' alignItems='start'> <Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'> <Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Read_only_Label')}</Field.Label> <Field.Label htmlFor={readOnlyId}>{t('Teams_New_Read_only_Label')}</Field.Label>
<Field.Description> <Field.Description id={`${readOnlyId}-hint`}>
{readOnly ? t('Only_authorized_users_can_write_new_messages') : t('Teams_New_Read_only_Description')} {readOnly ? t('Only_authorized_users_can_write_new_messages') : t('Teams_New_Read_only_Description')}
</Field.Description> </Field.Description>
</Box> </Box>
...@@ -193,7 +222,14 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -193,7 +222,14 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
control={control} control={control}
name='readOnly' name='readOnly'
render={({ field: { onChange, value, ref } }): ReactElement => ( render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch disabled={!canChangeReadOnly} onChange={onChange} checked={value} ref={ref} /> <ToggleSwitch
id={readOnlyId}
aria-describedby={`${readOnlyId}-hint`}
disabled={!canChangeReadOnly}
onChange={onChange}
checked={value}
ref={ref}
/>
)} )}
/> />
</Box> </Box>
...@@ -201,8 +237,8 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -201,8 +237,8 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
<Field> <Field>
<Box display='flex' justifyContent='space-between' alignItems='start'> <Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'> <Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Encrypted_Label')}</Field.Label> <Field.Label htmlFor={encryptedId}>{t('Teams_New_Encrypted_Label')}</Field.Label>
<Field.Description> <Field.Description id={`${encryptedId}-hint`}>
{isPrivate ? t('Teams_New_Encrypted_Description_Enabled') : t('Teams_New_Encrypted_Description_Disabled')} {isPrivate ? t('Teams_New_Encrypted_Description_Enabled') : t('Teams_New_Encrypted_Description_Disabled')}
</Field.Description> </Field.Description>
</Box> </Box>
...@@ -210,7 +246,14 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -210,7 +246,14 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
control={control} control={control}
name='encrypted' name='encrypted'
render={({ field: { onChange, value, ref } }): ReactElement => ( render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch disabled={!canSetReadOnly || !canChangeEncrypted} onChange={onChange} checked={value} ref={ref} /> <ToggleSwitch
id={encryptedId}
disabled={!canSetReadOnly || !canChangeEncrypted}
onChange={onChange}
aria-describedby={`${encryptedId}-hint`}
checked={value}
ref={ref}
/>
)} )}
/> />
</Box> </Box>
...@@ -218,20 +261,20 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement => ...@@ -218,20 +261,20 @@ const CreateTeamModal = ({ onClose }: { onClose: () => void }): ReactElement =>
<Field> <Field>
<Box display='flex' justifyContent='space-between' alignItems='start'> <Box display='flex' justifyContent='space-between' alignItems='start'>
<Box display='flex' flexDirection='column' width='full'> <Box display='flex' flexDirection='column' width='full'>
<Field.Label>{t('Teams_New_Broadcast_Label')}</Field.Label> <Field.Label htmlFor={broadcastId}>{t('Teams_New_Broadcast_Label')}</Field.Label>
<Field.Description>{t('Teams_New_Broadcast_Description')}</Field.Description> <Field.Description d={`${broadcastId}-hint`}>{t('Teams_New_Broadcast_Description')}</Field.Description>
</Box> </Box>
<Controller <Controller
control={control} control={control}
name='broadcast' name='broadcast'
render={({ field: { onChange, value, ref } }): ReactElement => ( render={({ field: { onChange, value, ref } }): ReactElement => (
<ToggleSwitch onChange={onChange} checked={value} ref={ref} /> <ToggleSwitch aria-describedby={`${broadcastId}-hint`} id={broadcastId} onChange={onChange} checked={value} ref={ref} />
)} )}
/> />
</Box> </Box>
</Field> </Field>
<Field> <Field>
<Field.Label> <Field.Label htmlFor={addMembersId}>
{t('Teams_New_Add_members_Label')}{' '} {t('Teams_New_Add_members_Label')}{' '}
<Box is='span' color='annotation'> <Box is='span' color='annotation'>
({t('optional')}) ({t('optional')})
......
import type { Locator, Page } from '@playwright/test'; import type { Locator, Page } from '@playwright/test';
import { HomeContent, HomeSidenav, HomeFlextab } from './fragments'; import { HomeContent, HomeFlextab, HomeSidenav } from './fragments';
export class HomeTeam { export class HomeTeam {
private readonly page: Page; private readonly page: Page;
...@@ -30,4 +30,12 @@ export class HomeTeam { ...@@ -30,4 +30,12 @@ export class HomeTeam {
get btnTeamCreate(): Locator { get btnTeamCreate(): Locator {
return this.page.locator('role=dialog >> role=group >> role=button[name=Create]'); return this.page.locator('role=dialog >> role=group >> role=button[name=Create]');
} }
get textPrivate(): Locator {
return this.page.locator('role=dialog[name="Create Team"] >> label >> text="Private"');
}
get textReadOnly(): Locator {
return this.page.locator('role=dialog[name="Create Team"] >> label >> text="Read Only"');
}
} }
...@@ -3,7 +3,7 @@ import { faker } from '@faker-js/faker'; ...@@ -3,7 +3,7 @@ import { faker } from '@faker-js/faker';
import { Users } from './fixtures/userStates'; import { Users } from './fixtures/userStates';
import { HomeTeam } from './page-objects'; import { HomeTeam } from './page-objects';
import { createTargetChannel } from './utils'; import { createTargetChannel } from './utils';
import { test, expect } from './utils/test'; import { expect, test } from './utils/test';
test.use({ storageState: Users.admin.state }); test.use({ storageState: Users.admin.state });
...@@ -11,6 +11,8 @@ test.describe.serial('teams-management', () => { ...@@ -11,6 +11,8 @@ test.describe.serial('teams-management', () => {
let poHomeTeam: HomeTeam; let poHomeTeam: HomeTeam;
let targetChannel: string; let targetChannel: string;
const targetTeam = faker.string.uuid(); const targetTeam = faker.string.uuid();
const targetTeamNonPrivate = faker.string.uuid();
const targetTeamReadOnly = faker.string.uuid();
test.beforeAll(async ({ api }) => { test.beforeAll(async ({ api }) => {
targetChannel = await createTargetChannel(api); targetChannel = await createTargetChannel(api);
...@@ -22,7 +24,7 @@ test.describe.serial('teams-management', () => { ...@@ -22,7 +24,7 @@ test.describe.serial('teams-management', () => {
await page.goto('/home'); await page.goto('/home');
}); });
test('expect create "targetTeam"', async ({ page }) => { test('expect create "targetTeam" private', async ({ page }) => {
await poHomeTeam.sidenav.openNewByLabel('Team'); await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeam); await poHomeTeam.inputTeamName.type(targetTeam);
await poHomeTeam.addMember('user1'); await poHomeTeam.addMember('user1');
...@@ -31,6 +33,26 @@ test.describe.serial('teams-management', () => { ...@@ -31,6 +33,26 @@ test.describe.serial('teams-management', () => {
await expect(page).toHaveURL(`/group/${targetTeam}`); await expect(page).toHaveURL(`/group/${targetTeam}`);
}); });
test('expect create "targetTeamNonPrivate" non private', async ({ page }) => {
await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeamNonPrivate);
await poHomeTeam.textPrivate.click();
await poHomeTeam.addMember('user1');
await poHomeTeam.btnTeamCreate.click();
await expect(page).toHaveURL(`/channel/${targetTeamNonPrivate}`);
});
test('expect create "targetTeamReadOnly" readonly', async ({ page }) => {
await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeamReadOnly);
await poHomeTeam.textReadOnly.click();
await poHomeTeam.addMember('user1');
await poHomeTeam.btnTeamCreate.click();
await expect(page).toHaveURL(`/group/${targetTeamReadOnly}`);
});
test('expect throw validation error if team name already exists', async () => { test('expect throw validation error if team name already exists', async () => {
await poHomeTeam.sidenav.openNewByLabel('Team'); await poHomeTeam.sidenav.openNewByLabel('Team');
await poHomeTeam.inputTeamName.type(targetTeam); await poHomeTeam.inputTeamName.type(targetTeam);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment