From e16f51ca2062d1e849309ddb9f194268733ec6f3 Mon Sep 17 00:00:00 2001 From: Anthony LC Date: Thu, 29 Feb 2024 15:59:10 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8(app-desk)=20integrate=20member=20list?= =?UTF-8?q?=20design?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Integrate the member list design in the team page based on the mockup. --- docker/auth/realm.json | 9 ++ src/frontend/apps/desk/cunningham.ts | 32 +++++-- .../apps/desk/src/assets/icons/icon-user.svg | 6 ++ src/frontend/apps/desk/src/components/Box.tsx | 2 + .../apps/desk/src/components/index.ts | 1 + .../desk/src/cunningham/cunningham-style.css | 67 +++++++++++--- .../desk/src/cunningham/cunningham-tokens.css | 37 ++++++-- .../desk/src/cunningham/cunningham-tokens.ts | 34 +++++-- .../teams/components/Member/MemberGrid.tsx | 89 +++++++++++++++++++ .../src/features/teams/components/index.ts | 1 + .../apps/desk/src/i18n/translations.json | 9 ++ .../apps/desk/src/pages/teams/[id].tsx | 9 +- .../apps/e2e/__tests__/app-desk/common.ts | 28 +++++- .../apps/e2e/__tests__/app-desk/menu.spec.ts | 5 +- .../apps/e2e/__tests__/app-desk/team.spec.ts | 43 +++++++-- .../__tests__/app-desk/teams-panel.spec.ts | 30 +------ 16 files changed, 334 insertions(+), 68 deletions(-) create mode 100644 src/frontend/apps/desk/src/assets/icons/icon-user.svg create mode 100644 src/frontend/apps/desk/src/features/teams/components/Member/MemberGrid.tsx diff --git a/docker/auth/realm.json b/docker/auth/realm.json index 05defbb..a1d16ea 100644 --- a/docker/auth/realm.json +++ b/docker/auth/realm.json @@ -60,6 +60,9 @@ }, { "username": "user-e2e-chromium", + "email": "user@chromium.e2e", + "firstName": "E2E", + "lastName": "Chromium", "enabled": true, "credentials": [ { @@ -71,6 +74,9 @@ }, { "username": "user-e2e-webkit", + "email": "user@webkit.e2e", + "firstName": "E2E", + "lastName": "Webkit", "enabled": true, "credentials": [ { @@ -82,6 +88,9 @@ }, { "username": "user-e2e-firefox", + "email": "user@firefox.e2e", + "firstName": "E2E", + "lastName": "Firefox", "enabled": true, "credentials": [ { diff --git a/src/frontend/apps/desk/cunningham.ts b/src/frontend/apps/desk/cunningham.ts index ffff175..5fbdcde 100644 --- a/src/frontend/apps/desk/cunningham.ts +++ b/src/frontend/apps/desk/cunningham.ts @@ -78,6 +78,7 @@ const config = { 'forms-labelledbox': { 'label-color': { small: 'var(--c--theme--colors--primary-500)', + 'small-disabled': 'var(--c--theme--colors--greyscale-400)', big: { disabled: 'var(--c--theme--colors--greyscale-400)', }, @@ -85,6 +86,8 @@ const config = { }, 'forms-select': { 'border-color': 'var(--c--theme--colors--primary-500)', + 'border-color-disabled-hover': + 'var(--c--theme--colors--greyscale-200)', 'border-radius': { hover: 'var(--c--components--forms-select--border-radius)', focus: 'var(--c--components--forms-select--border-radius)', @@ -199,10 +202,10 @@ const config = { 'secondary-800': '#341f1f', 'secondary-900': '#2b1919', 'greyscale-text': '#303C4B', - 'greyscale-000': '#cecece', - 'greyscale-100': '#f6f6f6', - 'greyscale-200': '#eeeeee', - 'greyscale-300': '#e5e5e5', + 'greyscale-000': '#f6f6f6', + 'greyscale-100': '#eeeeee', + 'greyscale-200': '#e5e5e5', + 'greyscale-300': '#e1e1e1', 'greyscale-400': '#dddddd', 'greyscale-500': '#cecece', 'greyscale-600': '#7b7b7b', @@ -284,6 +287,20 @@ const config = { color: 'var(--c--theme--colors--primary-text)', }, }, + datagrid: { + header: { + color: 'var(--c--theme--colors--primary-text)', + size: 'var(--c--theme--font--sizes--s)', + }, + body: { + 'background-color': 'transparent', + 'background-color-hover': '#F4F4FD', + }, + pagination: { + 'background-color': 'transparent', + 'background-color-active': 'var(--c--theme--colors--primary-300)', + }, + }, 'forms-checkbox': { 'border-radius': '0', }, @@ -305,7 +322,12 @@ const config = { }, }, 'forms-select': { - 'border-radius': '0', + 'border-radius': '4px', + 'border-radius-hover': '4px', + 'background-color': '#ffffff', + 'border-color': 'var(--c--theme--colors--primary-text)', + 'border-color-hover': 'var(--c--theme--colors--primary-text)', + 'box-shadow-color': 'var(--c--theme--colors--primary-text)', }, 'forms-switch': { 'handle-border-radius': '2px', diff --git a/src/frontend/apps/desk/src/assets/icons/icon-user.svg b/src/frontend/apps/desk/src/assets/icons/icon-user.svg new file mode 100644 index 0000000..ff518b5 --- /dev/null +++ b/src/frontend/apps/desk/src/assets/icons/icon-user.svg @@ -0,0 +1,6 @@ + + + diff --git a/src/frontend/apps/desk/src/components/Box.tsx b/src/frontend/apps/desk/src/components/Box.tsx index 2f2cd0e..dd82c5f 100644 --- a/src/frontend/apps/desk/src/components/Box.tsx +++ b/src/frontend/apps/desk/src/components/Box.tsx @@ -14,6 +14,7 @@ export interface BoxProps { $gap?: CSSProperties['gap']; $height?: CSSProperties['height']; $justify?: CSSProperties['justifyContent']; + $overflow?: CSSProperties['overflow']; $position?: CSSProperties['position']; $radius?: CSSProperties['borderRadius']; $width?: CSSProperties['width']; @@ -35,6 +36,7 @@ export const Box = styled('div')` ${({ $gap }) => $gap && `gap: ${$gap};`} ${({ $height }) => $height && `height: ${$height};`} ${({ $justify }) => $justify && `justify-content: ${$justify};`} + ${({ $overflow }) => $overflow && `overflow: ${$overflow};`} ${({ $position }) => $position && `position: ${$position};`} ${({ $radius }) => $radius && `border-radius: ${$radius};`} ${({ $width }) => $width && `width: ${$width};`} diff --git a/src/frontend/apps/desk/src/components/index.ts b/src/frontend/apps/desk/src/components/index.ts index ee27428..cd0c64b 100644 --- a/src/frontend/apps/desk/src/components/index.ts +++ b/src/frontend/apps/desk/src/components/index.ts @@ -1,4 +1,5 @@ export * from './Box'; export * from './Text'; export * from './Link'; +export * from './TextErrors'; export * from './Card'; diff --git a/src/frontend/apps/desk/src/cunningham/cunningham-style.css b/src/frontend/apps/desk/src/cunningham/cunningham-style.css index b4f8b01..53ac88b 100644 --- a/src/frontend/apps/desk/src/cunningham/cunningham-style.css +++ b/src/frontend/apps/desk/src/cunningham/cunningham-style.css @@ -21,7 +21,7 @@ } .labelled-box--disabled label { - color: var(--c--components--forms-labelledbox--label-color--small--disabled); + color: var(--c--components--forms-labelledbox--label-color--small-disabled); } .c__field :not(.c__textarea__wrapper, div) .labelled-box label.placeholder { @@ -120,7 +120,16 @@ input:-webkit-autofill:focus { } .c__select:not(.c__select--disabled) .c__select__wrapper:hover { - box-shadow: var(--c--theme--colors--primary-500) 0 0 0 2px; + box-shadow: var(--c--components--forms-input--box-shadow-color) 0 0 0 2px; +} + +.c__select__wrapper:hover { + border-radius: var(--c--components--forms-select--border-radius-hover); + border-color: var(--c--components--forms-select--border-color-hover); +} + +.c__select--disabled .c__select__wrapper:hover { + border-color: var(--c--components--forms-select--border-color-disabled-hover); } .c__select__menu__item { @@ -135,7 +144,7 @@ input:-webkit-autofill:focus { } .c__select__wrapper:focus-within .labelled-box--disabled label { - color: var(--c--components--forms-labelledbox--label-color--small--disabled); + color: var(--c--components--forms-labelledbox--label-color--small-disabled); } .c__select__wrapper .labelled-box { @@ -173,28 +182,60 @@ input:-webkit-autofill:focus { /** * DataGrid */ -.c__datagrid > table td { - max-width: 10rem; - white-space: normal; - color: var(--c--components--datagrid--cell--color); - font-size: var(--c--components--datagrid--cell--size); +.c__datagrid__table__container { + overflow: auto; } -.c__datagrid > table th .c__datagrid__header { - color: var(--c--theme--colors--primary-500); +.c__datagrid__table__container > table th .c__datagrid__header { + color: var(--c--components--datagrid--header--color); font-weight: var(--c--components--datagrid--header--weight); font-size: var(--c--components--datagrid--header--size); + padding-block: 2rem; } -.c__datagrid > table tbody tr { - border: 1px var(--c--theme--colors--primary-100) solid; +.c__datagrid__table__container > table tbody tr { + border: none; + border-top: 1px var(--c--theme--colors--greyscale-300) solid; + border-bottom: 1px var(--c--theme--colors--greyscale-300) solid; +} + +.c__datagrid__table__container > table tbody { + background-color: var(--c--components--datagrid--body--background-color); +} + +.c__datagrid__table__container > table tbody tr:hover { + background-color: var( + --c--components--datagrid--body--background-color-hover + ); +} + +.c__datagrid__table__container > table th:first-child, +.c__datagrid__table__container > table td:first-child { + padding-left: 2rem; } .c__datagrid > .c__pagination { - padding-top: 1rem; + padding-right: 1rem; justify-content: flex-end; } +.c__pagination__list { + gap: 3px; + border-radius: 4px; + background: var(--c--components--datagrid--pagination--background-color); +} + +.c__pagination__list .c__button--tertiary.c__button--active { + background-color: var( + --c--components--datagrid--pagination--background-color-active + ); + color: var(--c--theme--colors--greyscale-800); +} + +.c__pagination__list .c__button--tertiary:disabled { + display: none; +} + @media (width <= 380px) { .c__datagrid > .c__pagination { flex-direction: column; diff --git a/src/frontend/apps/desk/src/cunningham/cunningham-tokens.css b/src/frontend/apps/desk/src/cunningham/cunningham-tokens.css index 2fd8f3d..27f38ee 100644 --- a/src/frontend/apps/desk/src/cunningham/cunningham-tokens.css +++ b/src/frontend/apps/desk/src/cunningham/cunningham-tokens.css @@ -160,12 +160,18 @@ --c--components--forms-labelledbox--label-color--small: var( --c--theme--colors--primary-500 ); + --c--components--forms-labelledbox--label-color--small-disabled: var( + --c--theme--colors--greyscale-400 + ); --c--components--forms-labelledbox--label-color--big--disabled: var( --c--theme--colors--greyscale-400 ); --c--components--forms-select--border-color: var( --c--theme--colors--primary-500 ); + --c--components--forms-select--border-color-disabled-hover: var( + --c--theme--colors--greyscale-200 + ); --c--components--forms-select--border-radius--hover: var( --c--components--forms-select--border-radius ); @@ -337,10 +343,10 @@ --c--theme--colors--secondary-800: #341f1f; --c--theme--colors--secondary-900: #2b1919; --c--theme--colors--greyscale-text: #303c4b; - --c--theme--colors--greyscale-000: #cecece; - --c--theme--colors--greyscale-100: #f6f6f6; - --c--theme--colors--greyscale-200: #eee; - --c--theme--colors--greyscale-300: #e5e5e5; + --c--theme--colors--greyscale-000: #f6f6f6; + --c--theme--colors--greyscale-100: #eee; + --c--theme--colors--greyscale-200: #e5e5e5; + --c--theme--colors--greyscale-300: #e1e1e1; --c--theme--colors--greyscale-400: #ddd; --c--theme--colors--greyscale-500: #cecece; --c--theme--colors--greyscale-600: #7b7b7b; @@ -415,6 +421,16 @@ --c--components--button--secondary--color: var( --c--theme--colors--primary-text ); + --c--components--datagrid--header--color: var( + --c--theme--colors--primary-text + ); + --c--components--datagrid--header--size: var(--c--theme--font--sizes--s); + --c--components--datagrid--body--background-color: transparent; + --c--components--datagrid--body--background-color-hover: #f4f4fd; + --c--components--datagrid--pagination--background-color: transparent; + --c--components--datagrid--pagination--background-color-active: var( + --c--theme--colors--primary-300 + ); --c--components--forms-checkbox--border-radius: 0; --c--components--forms-datepicker--border-radius: 0; --c--components--forms-fileuploader--border-radius: 0; @@ -429,7 +445,18 @@ --c--components--forms-labelledbox--label-color--big: var( --c--theme--colors--primary-text ); - --c--components--forms-select--border-radius: 0; + --c--components--forms-select--border-radius: 4px; + --c--components--forms-select--border-radius-hover: 4px; + --c--components--forms-select--background-color: #fff; + --c--components--forms-select--border-color: var( + --c--theme--colors--primary-text + ); + --c--components--forms-select--border-color-hover: var( + --c--theme--colors--primary-text + ); + --c--components--forms-select--box-shadow-color: var( + --c--theme--colors--primary-text + ); --c--components--forms-switch--handle-border-radius: 2px; --c--components--forms-switch--rail-border-radius: 4px; --c--components--forms-textarea--border-radius: 0; diff --git a/src/frontend/apps/desk/src/cunningham/cunningham-tokens.ts b/src/frontend/apps/desk/src/cunningham/cunningham-tokens.ts index 3c8e64f..7b5a926 100644 --- a/src/frontend/apps/desk/src/cunningham/cunningham-tokens.ts +++ b/src/frontend/apps/desk/src/cunningham/cunningham-tokens.ts @@ -183,11 +183,14 @@ export const tokens = { 'forms-labelledbox': { 'label-color': { small: 'var(--c--theme--colors--primary-500)', + 'small-disabled': 'var(--c--theme--colors--greyscale-400)', big: { disabled: 'var(--c--theme--colors--greyscale-400)' }, }, }, 'forms-select': { 'border-color': 'var(--c--theme--colors--primary-500)', + 'border-color-disabled-hover': + 'var(--c--theme--colors--greyscale-200)', 'border-radius': { hover: 'var(--c--components--forms-select--border-radius)', focus: 'var(--c--components--forms-select--border-radius)', @@ -345,10 +348,10 @@ export const tokens = { 'secondary-800': '#341f1f', 'secondary-900': '#2b1919', 'greyscale-text': '#303C4B', - 'greyscale-000': '#cecece', - 'greyscale-100': '#f6f6f6', - 'greyscale-200': '#eeeeee', - 'greyscale-300': '#e5e5e5', + 'greyscale-000': '#f6f6f6', + 'greyscale-100': '#eeeeee', + 'greyscale-200': '#e5e5e5', + 'greyscale-300': '#e1e1e1', 'greyscale-400': '#dddddd', 'greyscale-500': '#cecece', 'greyscale-600': '#7b7b7b', @@ -421,6 +424,20 @@ export const tokens = { color: 'var(--c--theme--colors--primary-text)', }, }, + datagrid: { + header: { + color: 'var(--c--theme--colors--primary-text)', + size: 'var(--c--theme--font--sizes--s)', + }, + body: { + 'background-color': 'transparent', + 'background-color-hover': '#F4F4FD', + }, + pagination: { + 'background-color': 'transparent', + 'background-color-active': 'var(--c--theme--colors--primary-300)', + }, + }, 'forms-checkbox': { 'border-radius': '0' }, 'forms-datepicker': { 'border-radius': '0' }, 'forms-fileuploader': { 'border-radius': '0' }, @@ -433,7 +450,14 @@ export const tokens = { 'forms-labelledbox': { 'label-color': { big: 'var(--c--theme--colors--primary-text)' }, }, - 'forms-select': { 'border-radius': '0' }, + 'forms-select': { + 'border-radius': '4px', + 'border-radius-hover': '4px', + 'background-color': '#ffffff', + 'border-color': 'var(--c--theme--colors--primary-text)', + 'border-color-hover': 'var(--c--theme--colors--primary-text)', + 'box-shadow-color': 'var(--c--theme--colors--primary-text)', + }, 'forms-switch': { 'handle-border-radius': '2px', 'rail-border-radius': '4px', diff --git a/src/frontend/apps/desk/src/features/teams/components/Member/MemberGrid.tsx b/src/frontend/apps/desk/src/features/teams/components/Member/MemberGrid.tsx new file mode 100644 index 0000000..615c0a5 --- /dev/null +++ b/src/frontend/apps/desk/src/features/teams/components/Member/MemberGrid.tsx @@ -0,0 +1,89 @@ +import { DataGrid, usePagination } from '@openfun/cunningham-react'; +import React, { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; + +import IconUser from '@/assets/icons/icon-user.svg'; +import { Box, Card, TextErrors } from '@/components'; +import { useCunninghamTheme } from '@/cunningham'; +import { Team, useTeamAccesses } from '@/features/teams/api/'; +import { PAGE_SIZE } from '@/features/teams/conf'; + +interface MemberGridProps { + team: Team; +} + +export const MemberGrid = ({ team }: MemberGridProps) => { + const { t } = useTranslation(); + const { colorsTokens } = useCunninghamTheme(); + + const pagination = usePagination({ + pageSize: PAGE_SIZE, + }); + const { page, pageSize, setPagesCount } = pagination; + const { data, isLoading, error } = useTeamAccesses({ + teamId: team.id, + page, + }); + + const accesses = data?.results; + + useEffect(() => { + setPagesCount(data?.count ? Math.ceil(data.count / pageSize) : 0); + }, [data?.count, pageSize, setPagesCount]); + + return ( + + {error && } + + + + + ); + }, + }, + { + headerName: t('Names'), + field: 'user.name', + }, + { + field: 'user.email', + headerName: t('Emails'), + }, + { + field: 'role', + headerName: t('Roles'), + }, + ]} + rows={accesses || []} + isLoading={isLoading} + pagination={pagination} + /> + + ); +}; diff --git a/src/frontend/apps/desk/src/features/teams/components/index.ts b/src/frontend/apps/desk/src/features/teams/components/index.ts index 38dec09..dc884d9 100644 --- a/src/frontend/apps/desk/src/features/teams/components/index.ts +++ b/src/frontend/apps/desk/src/features/teams/components/index.ts @@ -1,2 +1,3 @@ export * from './Panel/Panel'; export * from './TeamInfo'; +export * from './Member/MemberGrid'; diff --git a/src/frontend/apps/desk/src/i18n/translations.json b/src/frontend/apps/desk/src/i18n/translations.json index 3a7d4b7..f6069e8 100644 --- a/src/frontend/apps/desk/src/i18n/translations.json +++ b/src/frontend/apps/desk/src/i18n/translations.json @@ -19,6 +19,15 @@ "{{label}} button": "Bouton {{label}}", "{{label}} icon": "Icône {{label}}", "Recents": "Récents", + "Admin": "Admin", + "Member": "Membre", + "Owner": "Propriétaire", + "Select a role": "Choisir un rôle", + "List members card": "Carte liste des membres", + "Member icon": "Icône de membre", + "Names": "Noms", + "Emails": "Emails", + "Roles": "Rôles", "Sort the teams": "Trier les groupes", "Sort teams icon": "Icône trier les groupes", "Add a team": "Ajouter un groupe", diff --git a/src/frontend/apps/desk/src/pages/teams/[id].tsx b/src/frontend/apps/desk/src/pages/teams/[id].tsx index f664193..8bbdee7 100644 --- a/src/frontend/apps/desk/src/pages/teams/[id].tsx +++ b/src/frontend/apps/desk/src/pages/teams/[id].tsx @@ -5,7 +5,7 @@ import { ReactElement } from 'react'; import { Box } from '@/components'; import { TextErrors } from '@/components/TextErrors'; -import { TeamInfo, useTeam } from '@/features/teams/'; +import { MemberGrid, TeamInfo, useTeam } from '@/features/teams/'; import { NextPageWithLayout } from '@/types/next'; import TeamLayout from './TeamLayout'; @@ -47,7 +47,12 @@ const Team = ({ id }: TeamProps) => { ); } - return ; + return ( + <> + + + + ); }; Page.getLayout = function getLayout(page: ReactElement) { diff --git a/src/frontend/apps/e2e/__tests__/app-desk/common.ts b/src/frontend/apps/e2e/__tests__/app-desk/common.ts index 4dc16d2..bc34179 100644 --- a/src/frontend/apps/e2e/__tests__/app-desk/common.ts +++ b/src/frontend/apps/e2e/__tests__/app-desk/common.ts @@ -1,4 +1,4 @@ -import { Page } from '@playwright/test'; +import { Page, expect } from '@playwright/test'; export const keyCloakSignIn = async (page: Page, browserName: string) => { const title = await page.locator('h1').first().textContent({ @@ -17,3 +17,29 @@ export const keyCloakSignIn = async (page: Page, browserName: string) => { await page.click('input[type="submit"]', { force: true }); } }; + +export const createTeam = async ( + page: Page, + teamName: string, + browserName: string, + length: number, +) => { + const panel = page.getByLabel('Teams panel').first(); + const buttonCreate = page.getByRole('button', { name: 'Create the team' }); + + const randomTeams = Array.from({ length }, (_el, index) => { + return `${teamName}-${browserName}-${Math.floor(Math.random() * 10000)}-${index}`; + }); + + for (let i = 0; i < randomTeams.length; i++) { + await panel.getByRole('button', { name: 'Add a team' }).click(); + await page.getByText('Team name').fill(randomTeams[i]); + await expect(buttonCreate).toBeEnabled(); + await buttonCreate.click(); + await expect( + panel.locator('li').nth(0).getByText(randomTeams[i]), + ).toBeVisible(); + } + + return randomTeams; +}; diff --git a/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts b/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts index 8c80a45..d03892a 100644 --- a/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-desk/menu.spec.ts @@ -56,7 +56,8 @@ test.describe('Menu', () => { const buttonMenu = menu.getByLabel(`${name} button`); await buttonMenu.click(); - // eslint-disable-next-line playwright/no-conditional-in-test + /* eslint-disable playwright/no-conditional-expect */ + /* eslint-disable playwright/no-conditional-in-test */ if (isDefault) { await expect( page.getByRole('button', { @@ -73,6 +74,8 @@ test.describe('Menu', () => { const reg = new RegExp(name.toLowerCase()); await expect(page).toHaveURL(reg); } + /* eslint-enable playwright/no-conditional-expect */ + /* eslint-enable playwright/no-conditional-in-test */ }); } }); diff --git a/src/frontend/apps/e2e/__tests__/app-desk/team.spec.ts b/src/frontend/apps/e2e/__tests__/app-desk/team.spec.ts index 73c779c..dec9a51 100644 --- a/src/frontend/apps/e2e/__tests__/app-desk/team.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-desk/team.spec.ts @@ -1,6 +1,6 @@ import { expect, test } from '@playwright/test'; -import { keyCloakSignIn } from './common'; +import { createTeam, keyCloakSignIn } from './common'; test.beforeEach(async ({ page, browserName }) => { await page.goto('/'); @@ -12,13 +12,9 @@ test.describe('Team', () => { page, browserName, }) => { - const panel = page.getByLabel('Teams panel').first(); - - await panel.getByRole('button', { name: 'Add a team' }).click(); - - const teamName = `My new team ${browserName}-${Math.floor(Math.random() * 1000)}`; - await page.getByText('Team name').fill(teamName); - await page.getByRole('button', { name: 'Create the team' }).click(); + const teamName = ( + await createTeam(page, 'team-top-box', browserName, 1) + ).shift(); await expect(page.getByLabel('icon group')).toBeVisible(); await expect( @@ -44,4 +40,35 @@ test.describe('Team', () => { page.getByText(`Last update at ${todayFormated}`), ).toBeVisible(); }); + + test('checks the datagrid members', async ({ page, browserName }) => { + await createTeam(page, 'team-admin', browserName, 1); + + const table = page.getByLabel('List members card').getByRole('table'); + + const thead = table.locator('thead'); + await expect(thead.getByText(/Names/i)).toBeVisible(); + await expect(thead.getByText(/Emails/i)).toBeVisible(); + await expect(thead.getByText(/Roles/i)).toBeVisible(); + + const rows = table.getByRole('row'); + expect(await rows.count()).toBe(21); + + await expect( + rows.nth(1).getByRole('cell').nth(0).getByLabel('Member icon'), + ).toBeVisible(); + + const textCellName = await rows + .nth(1) + .getByRole('cell') + .nth(1) + .textContent(); + expect(textCellName).toEqual(expect.any(String)); + await expect(rows.nth(1).getByRole('cell').nth(2)).toContainText('@'); + expect( + ['owner', 'member', 'admin'].includes( + (await rows.nth(1).getByRole('cell').nth(3).textContent()) as string, + ), + ).toBeTruthy(); + }); }); diff --git a/src/frontend/apps/e2e/__tests__/app-desk/teams-panel.spec.ts b/src/frontend/apps/e2e/__tests__/app-desk/teams-panel.spec.ts index f3f76f2..d664e90 100644 --- a/src/frontend/apps/e2e/__tests__/app-desk/teams-panel.spec.ts +++ b/src/frontend/apps/e2e/__tests__/app-desk/teams-panel.spec.ts @@ -1,34 +1,8 @@ -import { Page, expect, test } from '@playwright/test'; +import { expect, test } from '@playwright/test'; import { waitForElementCount } from '../helpers'; -import { keyCloakSignIn } from './common'; - -const createTeam = async ( - page: Page, - teamName: string, - browserName: string, - length: number, -) => { - const panel = page.getByLabel('Teams panel').first(); - const buttonCreate = page.getByRole('button', { name: 'Create the team' }); - - const randomTeams = Array.from({ length }, (_el, index) => { - return `${teamName}-${browserName}-${Math.floor(Math.random() * 10000)}-${index}`; - }); - - for (let i = 0; i < randomTeams.length; i++) { - await panel.getByRole('button', { name: 'Add a team' }).click(); - await page.getByText('Team name').fill(randomTeams[i]); - await expect(buttonCreate).toBeEnabled(); - await buttonCreate.click(); - await expect( - panel.locator('li').nth(0).getByText(randomTeams[i]), - ).toBeVisible(); - } - - return randomTeams; -}; +import { createTeam, keyCloakSignIn } from './common'; test.beforeEach(async ({ page, browserName }) => { await page.goto('/');