From 4748e271af544889308565ff4ae11819a36cc3bc Mon Sep 17 00:00:00 2001 From: Rishi <148757583+rishirishhh@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:17:52 +0530 Subject: [PATCH 1/2] enhancement: added shimmer effect (#884) * enhancement: added shimmer effect * added e2e tests * removed comments from style.css * Update tests.yml This will be removed eventually * Update tests.yml * added uniform design to the card * fixed small error --- .../extension-requests.test.js | 100 +++++++ extension-requests/script.js | 272 ++++++++++++++---- extension-requests/style.css | 33 +++ 3 files changed, 349 insertions(+), 56 deletions(-) diff --git a/__tests__/extension-requests/extension-requests.test.js b/__tests__/extension-requests/extension-requests.test.js index b9ffc5a2..b8d50c5e 100644 --- a/__tests__/extension-requests/extension-requests.test.js +++ b/__tests__/extension-requests/extension-requests.test.js @@ -640,6 +640,106 @@ describe('Tests the Extension Requests Screen', () => { expect(cardCount === 3 || cardCount === 7).toBe(true); }); + it('checks whether the shimmer effect is visible under dev flag only for the assignee image element', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const assignImageSelector = await page.$$( + '[data-testid="assignee-image skeleton"]', + ); + expect(assignImageSelector).toBeTruthy(); + + await page.waitForTimeout(5000); + const hasSkeletonClassAfter = await page.$eval('.assignee-image', (el) => + el.classList.contains('skeleton'), + ); + expect(hasSkeletonClassAfter).toBe(false); + }); + + it('checks whether the shimmer effect is visible under dev flag only for the assignee name element', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const assignNameSelector = await page.$$( + '[data-testid="assignee-name skeleton-text"]', + ); + expect(assignNameSelector).toBeTruthy(); + await page.waitForTimeout(5000); + const hasSkeletonClassAfter = await page.$eval('.assignee-name', (el) => + el.classList.contains('skeleton-text'), + ); + expect(hasSkeletonClassAfter).toBe(false); + }); + + it('checks whether the shimmer effect is working for deadlineValue element under feature flag', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const deadlineValueSelector = await page.$$( + '[data-testid="skeleton-span"]', + ); + expect(deadlineValueSelector).toBeTruthy(); + await page.waitForTimeout(5000); + const hasSkeletonClassAfter = await page.$eval('.tooltip-container', (el) => + el.classList.contains('skeleton-span'), + ); + expect(hasSkeletonClassAfter).toBe(false); + }); + + it('checks whether the shimmer effect is working for requestedValue element under feature flag', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const requestedValueSelector = await page.$$( + '[data-testid="skeleton-text"]', + ); + expect(requestedValueSelector).toBeTruthy(); + await page.waitForTimeout(5000); + const hasSkeletonClassAfter = await page.$eval('.requested-day', (el) => + el.classList.contains('skeleton-text'), + ); + expect(hasSkeletonClassAfter).toBe(false); + }); + it('checks whether the shimmer effect is working for newDeadlineValue element under feature flag', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const newDeadlineValueSelector = await page.$$( + '[data-testid="skeleton-span"]', + ); + expect(newDeadlineValueSelector).toBeTruthy(); + await page.waitForTimeout(5000); + const hasSkeletonClassAfter = await page.$eval('.requested-day', (el) => + el.classList.contains('skeleton-span'), + ); + expect(hasSkeletonClassAfter).toBe(false); + }); + + it('checks whether the shimmer effect is working for extensionRequestNumberValue element under feature flag', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const extensionRequestNumberValueSelector = await page.$$( + '[data-testid="skeleton-span"]', + ); + expect(extensionRequestNumberValueSelector).toBeTruthy(); + await page.waitForTimeout(5000); + const hasSkeletonClassAfter = await page.$eval( + '.extension-request-number', + (el) => el.classList.contains('skeleton-span'), + ); + expect(hasSkeletonClassAfter).toBe(false); + }); + + it('checks whether the shimmer effect is visible under dev flag only for the statusSiteLink element', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const statusSiteLinkSelector = await page.$$( + '[data-testid="external-link skeleton-link"]', + ); + expect(statusSiteLinkSelector).toBeTruthy(); + await page.waitForTimeout(5000); + const hasSkeletonClassAfter = await page.$eval('.external-link', (el) => + el.classList.contains('skeleton-link'), + ); + expect(hasSkeletonClassAfter).toBe(false); + }); + + it('checks whether the shimmer effect is visible under dev flag only for the taskStatusValue element', async () => { + await page.goto(`${baseUrl}/?dev=true`); + const taskStatusValueElement = await page.$$( + '[data-testid="skeleton-span"]', + ); + expect(taskStatusValueElement).toBeTruthy(); + }); + it('Checks whether the card is not removed from display when api call is unsuccessful', async () => { const extensionCards = await page.$$('.extension-card'); diff --git a/extension-requests/script.js b/extension-requests/script.js index c2b5f3a8..dfe1818b 100644 --- a/extension-requests/script.js +++ b/extension-requests/script.js @@ -240,7 +240,11 @@ async function populateExtensionRequests(query = {}, newLink) { return; } for (let data of allExtensionRequests) { - createExtensionCard(data); + if (query.dev) { + createExtensionCard(data, true); + } else { + createExtensionCard(data); + } } initializeAccordions(); } catch (error) { @@ -260,7 +264,11 @@ const intersectionObserver = new IntersectionObserver(async (entries) => { return; } if (entries[0].isIntersecting && !isDataLoading) { - await populateExtensionRequests({}, nextLink); + if (isDev) { + await populateExtensionRequests({ dev: true }, nextLink); + } else { + await populateExtensionRequests({}, nextLink); + } } }); @@ -462,7 +470,7 @@ const handleFormPropagation = async (event) => { event.preventDefault(); }; -async function createExtensionCard(data) { +async function createExtensionCard(data, dev) { renderLogRecord[data.id] = []; //Create card element const rootElement = createElement({ @@ -470,8 +478,12 @@ async function createExtensionCard(data) { attributes: { class: 'extension-card' }, }); extensionRequestsContainer.appendChild(rootElement); - const removeSpinner = addSpinner(rootElement); - rootElement.classList.add('disabled'); + let removeSpinner; + if (!dev) { + removeSpinner = addSpinner(rootElement); + rootElement.classList.add('disabled'); + } + //Api calls const userDataPromise = getUser(data.assignee); const taskDataPromise = getTaskDetails(data.taskId); @@ -569,12 +581,24 @@ async function createExtensionCard(data) { type: 'div', attributes: { class: 'details-container' }, }); - const statusSiteLink = createElement({ - type: 'a', - attributes: { - class: 'external-link', - }, - }); + + let statusSiteLink; + if (dev) { + statusSiteLink = createElement({ + type: 'a', + attributes: { + class: 'external-link skeleton-link', + 'data-testid': 'external-link skeleton-link', + }, + }); + } else { + statusSiteLink = createElement({ + type: 'a', + attributes: { + class: 'external-link', + }, + }); + } const taskTitle = createElement({ type: 'span', attributes: { class: 'task-title' }, @@ -598,15 +622,27 @@ async function createExtensionCard(data) { innerText: `Deadline${isDeadLineCrossed ? ' ' : ' in '}`, }); deadlineContainer.appendChild(deadlineText); - const deadlineValue = createElement({ - type: 'span', - innerText: `${deadlineDays}`, - attributes: { - class: `tooltip-container ${ - isDeadLineCrossed && isStatusPending ? 'red-text' : '' - }`, - }, - }); + + let deadlineValue; + if (dev) { + deadlineValue = createElement({ + type: 'span', + attributes: { + class: 'skeleton-span', + 'data-testid': 'skeleton-span', + }, + }); + } else { + deadlineValue = createElement({ + type: 'span', + innerText: `${deadlineDays}`, + attributes: { + class: `tooltip-container ${ + isDeadLineCrossed && isStatusPending ? 'red-text' : '' + }`, + }, + }); + } deadlineContainer.appendChild(deadlineValue); const deadlineTooltip = createElement({ type: 'span', @@ -625,13 +661,25 @@ async function createExtensionCard(data) { innerText: 'Requested ', }); requestedContainer.appendChild(requestedText); - const requestedValue = createElement({ - type: 'span', - attributes: { - class: `requested-day tooltip-container ${requestedDaysTextColor}`, - }, - innerText: ` ${requestedDaysAgo}`, - }); + + let requestedValue; + if (dev) { + requestedValue = createElement({ + type: 'span', + attributes: { + class: 'skeleton-text', + 'data-testid': 'skeleton-text', + }, + }); + } else { + requestedValue = createElement({ + type: 'span', + attributes: { + class: `requested-day tooltip-container ${requestedDaysTextColor}`, + }, + innerText: `${requestedDaysAgo}`, + }); + } const requestedToolTip = createElement({ type: 'span', attributes: { class: 'tooltip' }, @@ -647,9 +695,21 @@ async function createExtensionCard(data) { innerText: 'Task status ', }); taskStatusContainer.appendChild(taskStatusText); - const taskStatusValue = createElement({ - type: 'span', - }); + + let taskStatusValue; + if (dev) { + taskStatusValue = createElement({ + type: 'span', + attributes: { + class: 'skeleton-span', + 'data-testid': 'skeleton-span', + }, + }); + } else { + taskStatusValue = createElement({ + type: 'span', + }); + } taskStatusContainer.appendChild(taskStatusValue); const datesContainer = createElement({ type: 'div', @@ -683,11 +743,20 @@ async function createExtensionCard(data) { innerText: `New deadline${isNewDeadLineCrossed ? ' ' : ' in '}`, }); newDeadlineContainer.appendChild(newDeadlineText); - const newDeadlineValue = createElement({ - type: 'span', - attributes: { class: 'requested-day tooltip-container' }, - innerText: ` ${newDeadlineDays}`, - }); + + let newDeadlineValue; + if (dev) { + newDeadlineValue = createElement({ + type: 'span', + attributes: { class: 'skeleton-span', 'data-testid': 'skeleton-span' }, + }); + } else { + newDeadlineValue = createElement({ + type: 'span', + attributes: { class: 'requested-day tooltip-container' }, + innerText: ` ${newDeadlineDays}`, + }); + } const newDeadlineToolTip = createElement({ type: 'span', attributes: { class: 'tooltip' }, @@ -707,11 +776,19 @@ async function createExtensionCard(data) { }); extensionForContainer.appendChild(extensionForText); - const extensionForValue = createElement({ - type: 'span', - attributes: { class: 'tooltip-container' }, - innerText: ` +${extensionDays}`, - }); + let extensionForValue; + if (dev) { + extensionForValue = createElement({ + type: 'span', + attributes: { class: 'skeleton-span' }, + }); + } else { + extensionForValue = createElement({ + type: 'span', + attributes: { class: 'tooltip-container' }, + innerText: ` +${extensionDays}`, + }); + } const extensionToolTip = createElement({ type: 'span', attributes: { class: 'tooltip' }, @@ -744,11 +821,19 @@ async function createExtensionCard(data) { const requestNumber = data.requestNumber || 1; - const extensionRequestNumberValue = createElement({ - type: 'span', - attributes: { class: 'extension-request-number' }, - innerText: `#${requestNumber}`, - }); + let extensionRequestNumberValue; + if (dev) { + extensionRequestNumberValue = createElement({ + type: 'span', + attributes: { class: 'skeleton-span', 'data-testid': 'skeleton-span' }, + }); + } else { + extensionRequestNumberValue = createElement({ + type: 'span', + attributes: { class: 'extension-request-number' }, + innerText: `#${requestNumber}`, + }); + } extensionRequestNumberContainer.appendChild(extensionRequestNumberValue); const cardAssigneeButtonContainer = createElement({ type: 'div', @@ -765,16 +850,40 @@ async function createExtensionCard(data) { innerText: 'Assigned to', }); assigneeContainer.appendChild(assigneeText); - const assigneeImage = createElement({ - type: 'img', - attributes: { class: 'assignee-image' }, - }); + let assigneeImage; + if (dev) { + assigneeImage = createElement({ + type: 'img', + attributes: { + class: 'assignee-image skeleton', + 'data-testid': 'assignee-image skeleton', + }, + }); + } else { + assigneeImage = createElement({ + type: 'img', + attributes: { class: 'assignee-image' }, + }); + } assigneeContainer.appendChild(assigneeImage); - const assigneeNameElement = createElement({ - type: 'span', - attributes: { class: 'assignee-name' }, - }); + + let assigneeNameElement; + if (dev) { + assigneeNameElement = createElement({ + type: 'span', + attributes: { + class: 'assignee-name skeleton-text', + 'data-testid': 'assignee-name skeleton-text', + }, + }); + } else { + assigneeNameElement = createElement({ + type: 'span', + attributes: { class: 'assignee-name' }, + }); + } assigneeContainer.appendChild(assigneeNameElement); + const extensionCardButtons = createElement({ type: 'div', attributes: { class: 'extension-card-buttons' }, @@ -1198,10 +1307,22 @@ async function createExtensionCard(data) { userFirstName = userFirstName ?? ''; statusSiteLink.href = `${STATUS_BASE_URL}/tasks/${data.taskId}`; statusSiteLink.innerText = taskData.title; + if (dev) { + statusSiteLink.classList.remove('skeleton-link'); + } assigneeImage.src = userImage; + if (dev) { + assigneeImage.classList.remove('skeleton'); + } assigneeImage.alt = userFirstName; assigneeNameElement.innerText = userFirstName; + if (dev) { + assigneeNameElement.classList.remove('skeleton-text'); + } taskStatusValue.innerText = ` ${taskStatus}`; + if (dev) { + taskStatusValue.classList.remove('skeleton-span'); + } CommitedHourslabel.innerText = 'Commited Hours:'; if (comittedHours) { CommitedHoursContent.innerText = `${comittedHours / 4} hrs / week`; @@ -1209,10 +1330,49 @@ async function createExtensionCard(data) { CommitedHoursContent.innerText = 'Missing'; CommitedHoursContent.classList.add('label-content-missing'); } + if (dev) { + deadlineValue.classList.remove('skeleton-span'); + deadlineValue.innerText = `${deadlineDays}`; - removeSpinner(); - renderExtensionCreatedLog(); - rootElement.classList.remove('disabled'); + deadlineValue.classList.add('tooltip-container'); + if (isDeadLineCrossed && isStatusPending) { + deadlineValue.classList.add('red-text'); + } + } + + if (dev) { + requestedValue.classList.remove('skeleton-text'); + requestedValue.innerText = `${requestedDaysAgo}`; + + requestedValue.classList.add( + 'requested-day', + 'tooltip-container', + requestedDaysTextColor, + ); + } + + if (dev) { + newDeadlineValue.classList.remove('skeleton-span'); + newDeadlineValue.innerText = ` ${newDeadlineDays}`; + newDeadlineValue.classList.add('requested-day', 'tooltip-container'); + } + + if (dev) { + extensionForValue.classList.remove('skeleton-span'); + extensionForValue.innerText = ` +${extensionDays}`; + extensionForValue.classList.add('tooltip-container'); + } + + if (dev) { + extensionRequestNumberValue.classList.remove('skeleton-span'); + extensionRequestNumberValue.innerText = `#${requestNumber}`; + extensionRequestNumberValue.classList.add('extension-request-number'); + } + if (!dev) { + removeSpinner(); + renderExtensionCreatedLog(); + rootElement.classList.remove('disabled'); + } }); return rootElement; diff --git a/extension-requests/style.css b/extension-requests/style.css index 50d70d1b..bfcafebe 100644 --- a/extension-requests/style.css +++ b/extension-requests/style.css @@ -165,6 +165,39 @@ .approve-button:hover { background-color: var(--green500); } +.skeleton { + width: 1.5rem; + height: 1.5rem; + border-radius: 50%; + animation: skeleton-loading 1s linear infinite alternate; +} + +.skeleton-text, +.skeleton-link, +.skeleton-span { + width: 3rem; + height: 1rem; + background-color: hsl(200, 20%, 70%); + animation: skeleton-loading 1s linear infinite alternate; +} + +.skeleton-link, +.skeleton-span, +.skeleton-text { + width: 8rem; + display: inline-flex; + border-radius: 0.125rem; + line-height: 3rem; +} + +@keyframes skeleton-loading { + 0% { + background-color: hsl(200, 20%, 70%); + } + 100% { + background-color: hsl(200, 20%, 80%); + } +} .edit-button { background: none; From 74765818572c1ed7a43d9400d3a9522f250b6b13 Mon Sep 17 00:00:00 2001 From: shantanu-02 <126399165+shantanu-02@users.noreply.github.com> Date: Thu, 17 Oct 2024 01:55:32 +0530 Subject: [PATCH 2/2] Feature/repository links for webpages (#863) * fix: Added footer contaning repo link for every webpage * fix: Added footer contaning repo link for every webpage * Enhancement: Added tests for new URLs * Enhancement: Added tests for new URLs * Fix: Removed Live URLs which do not have footer from testing * Enhancement: Fixed position for footer * fix: removed commented content * Enhancement: Used adata-test-id instead of class/id * Fix: footer position styling * Fix: changes using data-test-id * Fix: Prettier changes * Fix: minor bug fixes * Enhancement: Made reusable footer component * Enhancement: Replaced footer of webpages with footer component * Fix: Minor fixes * Fix: Removed additional footers * Fix: Removed additional footers * Fix: Removed additional footers * Fix: Added styles in global stylesheet * Fix: Minor fix of stylesheet * Fix: Test timeout error * Fix: Using data-test-id instead of classes --------- Co-authored-by: Vinit khandal <111434418+vinit717@users.noreply.github.com> --- __tests__/applications/applications.test.js | 31 +++++++++ __tests__/groups/group.test.js | 31 +++++++++ __tests__/users/App.test.js | 9 ++- applications/index.html | 7 ++ footer/footerComponent.js | 19 ++++++ global.css | 7 ++ groups/index.html | 10 ++- users/discord/components/TabsSection.js | 6 +- .../discord/components/UserDetailsSection.js | 65 ++++++++++--------- users/discord/components/UsersSection.js | 9 ++- users/discord/index.html | 8 ++- 11 files changed, 166 insertions(+), 36 deletions(-) create mode 100644 footer/footerComponent.js diff --git a/__tests__/applications/applications.test.js b/__tests__/applications/applications.test.js index a8ead04f..e0081e76 100644 --- a/__tests__/applications/applications.test.js +++ b/__tests__/applications/applications.test.js @@ -295,4 +295,35 @@ describe('Applications page', () => { ); await page.waitForNetworkIdle(); }); + + it('should display the footer with the correct repo link', async () => { + const footer = await page.$('[data-test-id="footer"]'); + expect(footer).toBeTruthy(); + + const infoRepo = await footer.$('[data-test-id="info-repo"]'); + expect(infoRepo).toBeTruthy(); + + const repoLink = await infoRepo.$('[data-test-id="repo-link"]'); + expect(repoLink).toBeTruthy(); + + const repoLinkHref = await page.evaluate((el) => el.href, repoLink); + expect(repoLinkHref).toBe( + 'https://github.com/Real-Dev-Squad/website-dashboard', + ); + + const repoLinkTarget = await page.evaluate((el) => el.target, repoLink); + expect(repoLinkTarget).toBe('_blank'); + + const repoLinkRel = await page.evaluate((el) => el.rel, repoLink); + expect(repoLinkRel).toBe('noopener noreferrer'); + + const repoLinkText = await page.evaluate((el) => el.innerText, repoLink); + expect(repoLinkText).toBe('open sourced repo'); + + const repoLinkClass = await page.evaluate((el) => el.className, repoLink); + expect(repoLinkClass).toBe(''); + + const repoLinkStyle = await page.evaluate((el) => el.style, repoLink); + expect(repoLinkStyle).toBeTruthy(); + }); }); diff --git a/__tests__/groups/group.test.js b/__tests__/groups/group.test.js index 4400450f..a158810f 100644 --- a/__tests__/groups/group.test.js +++ b/__tests__/groups/group.test.js @@ -266,4 +266,35 @@ describe('Discord Groups Page', () => { expect(noGroupDiv).toBeTruthy(); }); + + it('should display the footer with the correct repo link', async () => { + const footer = await page.$('[data-test-id="footer"]'); + expect(footer).toBeTruthy(); + + const infoRepo = await footer.$('[data-test-id="info-repo"]'); + expect(infoRepo).toBeTruthy(); + + const repoLink = await infoRepo.$('[data-test-id="repo-link"]'); + expect(repoLink).toBeTruthy(); + + const repoLinkHref = await page.evaluate((el) => el.href, repoLink); + expect(repoLinkHref).toBe( + 'https://github.com/Real-Dev-Squad/website-dashboard', + ); + + const repoLinkTarget = await page.evaluate((el) => el.target, repoLink); + expect(repoLinkTarget).toBe('_blank'); + + const repoLinkRel = await page.evaluate((el) => el.rel, repoLink); + expect(repoLinkRel).toBe('noopener noreferrer'); + + const repoLinkText = await page.evaluate((el) => el.innerText, repoLink); + expect(repoLinkText).toBe('open sourced repo'); + + const repoLinkClass = await page.evaluate((el) => el.className, repoLink); + expect(repoLinkClass).toBe(''); + + const repoLinkStyle = await page.evaluate((el) => el.style, repoLink); + expect(repoLinkStyle).toBeTruthy(); + }); }); diff --git a/__tests__/users/App.test.js b/__tests__/users/App.test.js index b612408f..05b36b53 100644 --- a/__tests__/users/App.test.js +++ b/__tests__/users/App.test.js @@ -6,7 +6,7 @@ const API_BASE_URL = 'https://staging-api.realdevsquad.com'; describe('App Component', () => { let browser; let page; - jest.setTimeout(60000); + jest.setTimeout(90000); let config = { launchOptions: { headless: 'new', @@ -68,6 +68,11 @@ describe('App Component', () => { }); it('should render all sections', async () => { + await page.waitForSelector('.tabs_section'); + await page.waitForSelector('.users_section'); + await page.waitForSelector('.user_card'); + await page.waitForSelector('.user_details_section'); + let tabsSection = await page.$('.tabs_section'); let usersSection = await page.$('.users_section'); let firstUser = await page.$('.user_card'); @@ -82,6 +87,8 @@ describe('App Component', () => { }); it('should update the URL query string and re-render the app', async () => { + await page.waitForSelector('[data_key="verified"]'); + // Click on the "Linked Accounts" tab await page.click('[data_key="verified"]'); diff --git a/applications/index.html b/applications/index.html index 8ab396b0..b37d33da 100644 --- a/applications/index.html +++ b/applications/index.html @@ -4,6 +4,7 @@ + Applications @@ -121,5 +122,11 @@

Status

+ + diff --git a/footer/footerComponent.js b/footer/footerComponent.js new file mode 100644 index 00000000..a92fe3c6 --- /dev/null +++ b/footer/footerComponent.js @@ -0,0 +1,19 @@ +function loadFooter() { + const footerHTML = ` + + `; + + document.body.insertAdjacentHTML('beforeend', footerHTML); +} diff --git a/global.css b/global.css index 54d386d2..70d6bbae 100644 --- a/global.css +++ b/global.css @@ -173,6 +173,13 @@ body { border-radius: 100%; } +.footer { + width: 100vw; + text-align: center; + position: fixed; + bottom: 4px; +} + @media screen and (max-width: 970px) { #tasksNav { justify-content: space-between; diff --git a/groups/index.html b/groups/index.html index e354491b..b58fcdcf 100644 --- a/groups/index.html +++ b/groups/index.html @@ -6,7 +6,7 @@ Discord Groups | Real Dev Squad - + @@ -38,12 +38,18 @@
+ +
diff --git a/users/discord/components/TabsSection.js b/users/discord/components/TabsSection.js index 15c69408..57dd4416 100644 --- a/users/discord/components/TabsSection.js +++ b/users/discord/components/TabsSection.js @@ -3,7 +3,11 @@ const { createElement } = react; export const TabsSection = ({ tabs, activeTab, handleTabNavigation }) => { return createElement( 'div', - { class: 'tabs_section', onclick: handleTabNavigation }, + { + class: 'tabs_section', + onclick: handleTabNavigation, + 'data-testid': 'tabs-section', + }, tabs.map((tabItem) => { return createElement( 'span', diff --git a/users/discord/components/UserDetailsSection.js b/users/discord/components/UserDetailsSection.js index 419d3ee5..655c19bc 100644 --- a/users/discord/components/UserDetailsSection.js +++ b/users/discord/components/UserDetailsSection.js @@ -4,33 +4,40 @@ const { createElement } = react; export const UserDetailsSection = ({ user: { first_name, username, discordId, discordJoinedAt }, }) => { - return createElement('section', { class: 'user_details_section' }, [ - createElement('div', { class: 'user_details_field' }, [ - createElement('span', {}, ['Name: ']), - createElement('span', {}, [first_name]), - ]), - createElement('div', { class: 'user_details_field' }, [ - createElement('span', {}, ['Username: ']), - createElement('span', {}, [username]), - ]), - createElement('div', { class: 'user_details_field' }, [ - createElement('span', {}, ['Discord ID: ']), - createElement('span', {}, [discordId]), - ]), - createElement('div', { class: 'user_details_field' }, [ - createElement('span', {}, ['Joined RDS server on: ']), - createElement('span', {}, [new Date(discordJoinedAt).toUTCString()]), - ]), - createElement('div', { class: 'user_details_field' }, [ - createElement('span', {}, ['User Management: ']), - createElement( - 'a', - { - target: '_bllank', - href: `${USER_MANAGEMENT_URL}${username}`, - }, - [`${USER_MANAGEMENT_URL}${username}`], - ), - ]), - ]); + return createElement( + 'section', + { + class: 'user_details_section', + 'data-testid': 'user-details-section', + }, + [ + createElement('div', { class: 'user_details_field' }, [ + createElement('span', {}, ['Name: ']), + createElement('span', {}, [first_name]), + ]), + createElement('div', { class: 'user_details_field' }, [ + createElement('span', {}, ['Username: ']), + createElement('span', {}, [username]), + ]), + createElement('div', { class: 'user_details_field' }, [ + createElement('span', {}, ['Discord ID: ']), + createElement('span', {}, [discordId]), + ]), + createElement('div', { class: 'user_details_field' }, [ + createElement('span', {}, ['Joined RDS server on: ']), + createElement('span', {}, [new Date(discordJoinedAt).toUTCString()]), + ]), + createElement('div', { class: 'user_details_field' }, [ + createElement('span', {}, ['User Management: ']), + createElement( + 'a', + { + target: '_bllank', + href: `${USER_MANAGEMENT_URL}${username}`, + }, + [`${USER_MANAGEMENT_URL}${username}`], + ), + ]), + ], + ); }; diff --git a/users/discord/components/UsersSection.js b/users/discord/components/UsersSection.js index bc07cdaa..4d0ac94b 100644 --- a/users/discord/components/UsersSection.js +++ b/users/discord/components/UsersSection.js @@ -3,7 +3,11 @@ const { createElement } = react; export const UsersSection = ({ users, showUser, handleUserSelected }) => { return createElement( 'aside', - { class: 'users_section', onclick: handleUserSelected }, + { + class: 'users_section', + onClick: handleUserSelected, + 'data-testid': 'users-section', + }, users?.map((user) => { return createElement( 'div', @@ -11,7 +15,8 @@ export const UsersSection = ({ users, showUser, handleUserSelected }) => { class: `user_card ${ users[showUser].id === user.id ? 'active_tab' : '' }`, - data_key: user.id, + 'data-testid': `user-card-${user.id}`, + 'data-key': user.id, }, [ createElement('img', { diff --git a/users/discord/index.html b/users/discord/index.html index a3dd743f..7300e0ec 100644 --- a/users/discord/index.html +++ b/users/discord/index.html @@ -4,8 +4,8 @@ + - Discord Users | Real Dev Squad @@ -16,6 +16,12 @@

Discord Users

+ +